Mac mini に CoreOS をインストールして、kubernetes を立ち上げて自宅サーバーを運用するまでの話です。
「Go言語でスヌーズ機能付きリマインダーLINE botを実装した」で作ったLINE bot のサーバーを heroku で運用していたのですが毎月700円の出費が痛いので、なんとか安い運用方法がないかを検討した結果、自宅で眠っていた Mac mini
を自宅サーバーとして運用することにしました。
動機と OS の選択
- お金をかけずに運用したい。
- Docker が好きなので kubernetes を触ってみたい
この2つが僕のマストの要求です。
まず思い浮かぶのが GCP
の無料枠での運用ですが、GKE を無料枠の f1-micro
インスタンスを1つ立ち上げて試してみたところ kubernetes の管理アプリケーションだけで、0.6GB
のメモリのほとんどを食い尽くし、アプリケーションのデプロイは望めなさそうだったので、クラウドでの運用は諦めました。
参考: 貧者の GKE / 無料枠だけでクラスタを作ろう
1年ほど前に自宅サーバーで遊ぶためにメルカリで2万円で買って、すぐ飽きて放置していた Mac mini
があったのでそれを使うことにしました。
kubernetes を動かすためには Linux が必要ですが、自動で OS をアップデートしてくれて、Docker を動かす以外のことをしない最小の構成でセキュリティのリスクが少ない CoreOS
を採用しました。継続的な運用の手間をなるべくかけたくなかったのでその負荷を下げてくれることを期待しています。
Mac mini での運用では、Mac mini の中に VM
を Vagrant
などで立てて運用している記事を多く見かけましたが、Mac のホストのポートを VM のポートにいちいちフォワーディングしないといけないのがめんどくさいので、ディスクにインストールして起動する方式にしました。
また、いざという時は macOS を使いたいので OS は、macOS と CoreOS のデュアルブートをすることにしました。
kubernetes の立ち上げ方
kubernetes の立ち上げは、Rancher
と kubeadm
を試して kubeadm
を採用することにしました。kubeadm
はまだベータ版ですが、kubernetes のオフィシャルで作られており、シンプルでいい感じだったので採用しました。
Rancher は、マシンの 80番ポート
を管理ページのために占有されてしまうため採用を見送りました。管理ページは https での閲覧しかできないのですが、SSL証明書を let's encrypt
を利用して取得するオプションを用意しています。しかしそのためには、マシンの 80番ポート
をインターネットに公開する必要があり、Rancher の管理プロセスと kubernetes は同じマシンで動かすため、kubernetes で動かすサービスが 80番ポート を使うことができなくなります。kubernetes 上のサービスで let's encrypt を利用することができなくなってしまうため、採用を見送りました。
固定IP 問題
自宅は DHCP により動的にパブリックIPアドレスが割り当てられ、ルーターの再起動などで IPアドレス が変わってしまう可能性があります。運用中のサービスのIPアドレスが変わったら、即サービスダウンです。
解決策としては、以下の3通りが考えられます。
- 固定IP を割り当てる
- DDNS (
Dynamic DNS
) を利用する - ルーターの設定されたIPアドレスを監視し、変更されたら DNS のレコードを更新する
固定IP を割り当てる場合は、プロバイダーによるとは思いますが、申請が必要でさらに有料です。お金がかかるので今回は採用しませんでした。
DDNS を利用する方法は、自分が使っているソフトバンク光から支給されたルーターが対応していないため断念しました。普通のバッファローのルーターなどでは対応しているみたいなので、ルーターを変えるという選択肢もあります。しかしソフトバンク光は、支給されたルーター以外では IPv6 での通信をさせない仕様になっており、IPv6 が使えないと普段使いに支障をきたすレベルでネットが遅くなるので断念しました。
消去法的に、ルーターから パブリックIPアドレス
をなんらかの方法で取得するのを一定時間で取得して、DNS のレコードを更新する方針を取ることになりました。ルーターからIPアドレスをぶっこ抜くAPIなどは提供されていないのですが、ソフトバンク光から支給された EWMTA2.1 の設定管理画面の HTML と javascript を眺めていると、 http://172.16.255.254/GetWanIP.html
でパブリックIPアドレスをぶっこぬけることを発見し、利用することにしました。
wanpoll
という、一定間隔で管理ページから IPアドレス をぶっこぬいて監視し、変更されたら Route53 のDNSレコードを更新する簡単なツールをGoで作成しました。詳しくは、https://github.com/kawasin73/wanpoll のgithubページを参照してください。wanpoll
自体は、HTTPで取得したテキストの中で最初に現れる IPv4
のアドレスを正規表現でぶっこぬきます。ソフトバンク光のルーター以外でもルーターの管理ページに IPv4 アドレスを一つだけ掲載しているページがあれば利用できます。
インストールと起動と試行錯誤
インストールに成功するまでに色々試行錯誤しました。この章では、その試行錯誤を紹介します。実際の手順は次の章で説明します。
試行錯誤1 : macOS で coreos-install
を行う。
CoreOS のディスクへのインストールは、coreos-install
という「こちら」のBashスクリプトが用意されています。
しかし、このスクリプトは Linux で実行することが前提とされているため、 macOS では動きません!!!!!! lsblk
というマウントされたディスクを調べるコマンドが macOS にはないため実行時にエラーになります。
coreos-install
自体はただの Bash スクリプトで、やってることは 環境のチェック
と、OSイメージのダウンロード
、ディスクへの dd での書き込み
だけなので、書き換えれば macOS でも動かすことはできるとは思いますが、そこまでの気力はなかったので macOS でインストールスクリプトを実行させることは諦めました。
参考URL: Installing CoreOS Container Linux to disk
試行錯誤2 : パーティショニングした Mac mini の HDD にインストールする
それであればと、転がっていた 8GB のUSBメモリに「このページ」からダウンロードした ISO イメージを書き込んで rEFInd で CoreOS を起動し、パーティショニングした Mac mini の HDD に対して、coreos-install
を実行してみましたが、以下のエラーが出てインストールに失敗しました。
$0: Target block device (${DEVICE}) is not a full disk.
パーティショニングされているディスクへの CoreOS のインストールはできず、インストールするときはディスクを丸々使うようです。Mac mini のディスクを全て消去して CoreOS を入れるのは怖かったので、HDD にインストールすることは諦めました。
参考URL: Booting CoreOS Container Linux from an ISO
試行錯誤3 : Docker for Mac で USBメモリ に対して coreos-install
を行う
そのため、家に転がっていた 32GB
の USBメモリ に CoreOS をインストールして、USB OS として起動することにしました。
それであるなら、Mac mini 1台で作業を完結させたいと思い、Mac mini 上の Docker for Mac
で Linux を実行して CoreOS のインストールをしようと考えました。しかし、中古の Mac mini では homebrew でインストールした Docker for Mac
が、CPU のバージョンが古いというエラーメッセージを吐いて起動できませんでした。
やむをえず、Macbook Pro で動いている Docker for Mac
で Linux を実行してインストールすることにしました。この記事 を参考に、USBメモリを Docker コンテナ上にマウントして、coreos-install
を実行しましたが、coreos-install
はディスクが /dev/
ディレクトリ上にマウントされていることを要求するため、インストールに失敗しました。macOS の上にある、Docker VM へのメモリのマウント方法を模索するのはめんどくさいですし、Docker for Mac
の環境を壊したくなかったので、Docker for Mac
で CoreOS をインストールすることは諦めました。
参考記事: Mount a USB drive in a Docker container
試行錯誤4: USBメモリにインストールして、rEFInd でデュアルブートする
USBメモリ に CoreOS のISOイメージをコピーして起動し、別のUSBメモリに CoreOS をインストールして rEFInd を使ってデュアルブートする方法で CoreOS のインストールができましたが、運用して数日でサーバーが落ちるという事象にぶち当たりました。
ディスプレイを繋げてみるとなぜか macOS のログイン画面が表示されます。これは、CoreOS の自動OSアップデートによって再起動されたものの、rEFInd によって長時間レスポンスがなかったため自動で macOS が優先的に起動されてしまったものだと考えられます。調べてみると、運用をしていた数日の間に CoreOS の新しいバージョンがリリースされていました。
そのため、rEFInd の起動の優先度を変更することで対応しました。
最終的に採用した CoreOS のインストール方法
紆余曲折をへて、ディスクに macOS を残したまま、CoreOS を USBメモリ にインストールし、rEFInd でデュアルブートする方式を取ることにしました。
CoreOS は Ignition
という仕組みを使うことで、OSのインストール時に設定した JSON 設定ファイルの内容を、起動時に実行して OS の設定をすることができます。設定ファイルは、yaml
形式で書き、それを Container Linux Config Transpiler というツールを使って JSON ファイルに変換して使います。
設定ファイルは 8GB
のUSBメモリの CoreOS から、DropBox に一時的に公開した設定ファイルを curl
コマンドでダウンロードして用意するようにしました。JSON ファイルの内容を全てキーボードで叩く気にはなれないですし、設定ファイルには秘匿情報が含まれているため、インターネットへの公開もできません。また、CoreOS のまっさらなイメージには、curl
と wget
くらいしかダウンロードコマンドがなく、S3 のAPIを使ったりするのは、コマンドのダウンロードと認証情報の入力が必要になり、とてもめんどくさいです。https に対応して、Basic 認証でファイルのダウンロードができる簡単な無料サービスがあると curl
コマンドで安全にダウンロードできて便利なのですが、そんなサービスを知らなかったので Dropbox を使うことにしました。
では、いかに手順をまとめていきます。
0. ルーターの設定
事前に自宅ルーターの設定を行います。
- LAN 内のプライベートIPアドレスの固定アドレスの割り振り
- 固定IP である方が扱いやすいため、プライベートIP の固定アドレスの設定を行いました。
- 外部からのアクセスのポートフォワーディング
- 僕は、
80
番と443
番を Mac mini に転送するように設定しました。
- 僕は、
1. Mac mini への rEFInd のインストール
rEFInd
は、デュアルブートを簡単にGUIから行えるようにするソフトウェアです。El capitan 以降の macOS を使っている場合は、System Integrity Protection(SIP) を無効化してから出ないとインストールできないため注意が必要です。
-
Mac mini をシャットダウンした後に、
Command + R
を押しながら起動しリカバリーモードに入ります。 -
ユーティリティからターミナルを立ち上げ、以下のコマンドを実行して SIP を無効化します。
csrutil disable
-
Mac mini をシャットダウンした後に通常モードで起動して、rEFInd の ダウンロードページ の、
A binary zip file
リンクをクリックして、zip
ファイルをダウンロードします。 -
zip
ファイルを解凍して、内包されていたrefind-install
コマンドを実行します。これで、rEFInd がインストールされました。cd ~/Downloads/refind-bin-0.11.3/ ./refind-install
-
最後に、Mac mini をシャットダウンした後に再度リカバリーモードで起動し、ターミナルで以下のコマンドを実行することで、SIP を有効化します。
csrutil enable
参考URL: El capitanにrEFIndを導入するとき
2. rEFInd の優先度の変更
rEFInd は、デフォルトの状態では、起動して操作をせずに 20 秒経つと自動で macOS のディスクを起動します。このままでは、CoreOS の自動OSアップデートが実行されて再起動されると macOS が立ち上がってしまうことになります。そのため、rEFInd の設定を変更して、最後に起動したディスクが優先的に起動されるように変更します。
起動ディスクの優先度は、設定ファイルの default_selection
で設定できます。これに、+
を指定すると最後に起動したディスクが優先的に起動されます。
- macOS を起動してターミナルを起動します。
- EFI ディスクの場所を調べます。この場合は、
/dev/disk0s1
です。
$ diskutil list
/dev/disk0 (internal, physical):
#: TYPE NAME SIZE IDENTIFIER
0: GUID_partition_scheme *500.3 GB disk0
1: EFI EFI 209.7 MB disk0s1
2: Apple_CoreStorage Macintosh HD 499.4 GB disk0s2
3: Apple_Boot Recovery HD 650.0 MB disk0s3
/dev/disk1 (internal, virtual):
#: TYPE NAME SIZE IDENTIFIER
0: Apple_HFS Macintosh HD +499.1 GB disk1
Logical Volume on disk0s2
A3EFDCC4-52BE-4DA6-8AD2-E47995C8C94F
Unlocked Encrypted
- EFI ディスクをマウントします。ここでは、
/Volumes/EFI
にマウントします。
sudo mkdir /Volumes/EFI
sudo diskutil mount -mountPoint /Volumes/EFI /dev/disk0s1
-
/Volumes/EFI/EFI/refind/refind.conf
を修正します。
$ vi /Volumes/EFI/EFI/refind/refind.conf
# 以下を追加
# default_selection +
3. 暫定USBメモリへの CoreOS ISOイメージの書き込み
次に、coreos-install
を実行する Linux 環境を手に入れるために、8GB
のUSBメモリへ CoreOS の ISOイメージ を焼き付けます。Linux 環境があればいいので、CoreOS 以外でも可能ですし、メモリの容量もイメージが入りきれば指定はありません。
-
まず、USBメモリを初期化します。macOS のデフォルトでインストールされている
ディスクユーティリティ
を開き、指した USB メモリを選択して消去
ボタンをクリックします。 -
名前を適当に入力し、フォーマットに
MS-DOS(FAT)
を選択して消去
ボタンをクリックします。これで USBメモリ の消去が完了しました。 -
この ダウンロードページ から CoreOS の ISOイメージをダウンロードします。
-
ISO イメージを
dd
コマンドを使ってコピーして USBOS の完成です。詳しくは、参考URL をみてください。ただ、このサイトでは、bs
を4028
に設定していますが、これだとすごい時間がかかるので、32m
くらいに設定して実行します。# disk4 に USBメモリがあるとする。 diskutil unmountDisk /dev/disk4 sudo dd if=./Downloads/coreos_production_iso_image.iso of=/dev/disk4 bs=32m diskutil eject /dev/disk4
参考URL: Mac OSX上でISOイメージからBootable USBを作成する
4. Ignition ファイルの用意
Ignition は、起動時に CoreOS の設定をする仕組みです。yaml ファイルで設定しますが、このテンプレートは、この記事 を参考にして作りました。
追加したテンプレートに追加した点としては、SSH の設定と、wanpoll
の設定です。利用するときは、ssh_authorized_keys
を自分の PC の ssh の公開鍵に変更し、/opt/wanpoll/env
の内容を書き換えてください。
yaml ファイルは、Container Linux Config Transpiler を使って、JSON にトランスパイルします。
brew install coreos-ct
ct -out-file ignition.json -platform custom < ignition.yml
Container Linux Config のテンプレート yaml ファイルは以下の通りです。
# FROM URL: https://vadosware.io/post/yet-another-cluster-reinstall-back-to-container-linux/
# This config is meant to be consumed by the config transpiler, which will
# generate the corresponding Ignition config. Do not pass this config directly
# to instances of Container Linux.
# NOTE: This configuration is meant to work with Config Transpiler v0.8.0
# The spec is available at (https://github.com/coreos/container-linux-config-transpiler/blob/v0.8.0/doc/configuration.md)
passwd:
users:
- name: core
ssh_authorized_keys:
- ssh-rsa xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxx@example.com
systemd:
units:
# Docker will be configured initially but we'll be using containerd exclusively and will disable it after containerd setup
- name: docker.service
enabled: true
# containerd without docker as a shim, thanks to containerd.service.d/ overrides
- name: containerd.service
enabled: true
- name: sshd.socket
dropins:
- name: 10-sshd-port.conf
contents: |
[Socket]
ListenStream=
ListenStream=2222
- name: k8s-install.service
enabled: true
contents: |
[Install]
WantedBy=multi-user.target
[Unit]
Description=k8s installation script
Wants=network-online.target
After=network.target network-online.target
[Service]
Type=oneshot
ExecStart=/ignition/init/k8s/install.sh
- name: cni-install.service
enabled: true
contents: |
[Install]
WantedBy=multi-user.target
[Unit]
Description=cni plugin installation script
Requires=k8s-install.service
After=k8s-install.service
[Service]
Type=oneshot
ExecStart=/ignition/init/cni/install.sh
- name: containerd-install.service
enabled: true
contents: |
[Install]
WantedBy=multi-user.target
[Unit]
Description=containerd installation script
Requires=cni-install.service
After=cni-install.service
[Service]
Type=oneshot
ExecStart=/ignition/init/cri-containerd/install.sh
- name: kubeadm-install.service
enabled: true
contents: |
[Install]
WantedBy=multi-user.target
[Unit]
Description=kubeadm installation script
Requires=containerd-install.service
After=containerd-install.service
[Service]
Type=oneshot
Environment="PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/opt/bin"
ExecStart=/ignition/init/kubeadm/kubeadm-install.sh
- name: k8s-setup.service
enabled: true
contents: |
[Install]
WantedBy=multi-user.target
[Unit]
Description=kubernetes setup script
Requires=kubeadm-install.service
After=kubeadm-install.service
[Service]
Type=oneshot
User=core
Environment="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/opt/bin"
ExecStart=/ignition/init/k8s/setup.sh
- name: wanpoll.service
enabled: true
contents: |
[Install]
WantedBy=multi-user.target
[Unit]
Description=wanpoll service
Documentation=https://github.com/kawasin73/wanpoll
[Service]
Type=idle
EnvironmentFile=/opt/wanpoll/env
ExecStart=/opt/bin/wanpoll -hz=${HZ} \
-name=${NAME} \
-user=${USER} \
-password=${PASSWORD} \
-interval=${INTERVAL} \
-ttl=${INTERVAL}
storage:
filesystems:
- mount:
device: /dev/disk/by-label/ROOT
format: xfs
wipe_filesystem: true
label: ROOT
files:
- path: /opt/bin/kubeadm
filesystem: root
mode: 493 # 0755
contents:
remote:
url: https://storage.googleapis.com/kubernetes-release/release/v1.10.2/bin/linux/amd64/kubeadm
- path: /opt/bin/kubelet
filesystem: root
mode: 493 # 0755
contents:
remote:
url: https://storage.googleapis.com/kubernetes-release/release/v1.10.2/bin/linux/amd64/kubelet
- path: /opt/bin/kubectl
filesystem: root
mode: 511 # 0777
contents:
remote:
url: https://storage.googleapis.com/kubernetes-release/release/v1.10.2/bin/linux/amd64/kubectl
- path: /opt/bin/wanpoll
filesystem: root
mode: 0755
contents:
remote:
url: https://github.com/kawasin73/wanpoll/releases/download/v0.1.0/wanpoll-linux-amd64
- path: /etc/systemd/system/kubelet.service
filesystem: root
mode: 420 # 0644
contents:
remote:
url: https://raw.githubusercontent.com/kubernetes/kubernetes/v1.10.2/build/debs/kubelet.service
- path: /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
filesystem: root
mode: 420 # 0644
contents:
remote:
url: https://raw.githubusercontent.com/kubernetes/kubernetes/v1.10.2/build/debs/10-kubeadm.conf
- path: /ignition/init/cri-containerd/cri-containerd-1.1.0.linux-amd64.tar.gz
filesystem: root
mode: 420 # 0644
contents:
remote:
url: https://storage.googleapis.com/cri-containerd-release/cri-containerd-1.1.0.linux-amd64.tar.gz
- path: /ignition/init/cni/cni-plugins-v0.7.1.tgz
filesystem: root
mode: 420 # 0644
contents:
remote:
url: https://github.com/containernetworking/plugins/releases/download/v0.7.1/cni-plugins-amd64-v0.7.1.tgz
- path: /ignition/init/canal/rbac.yaml
filesystem: root
mode: 493 # 0755
contents:
remote:
url: https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/hosted/canal/rbac.yaml
- path: /ignition/init/canal/canal.yaml
filesystem: root
mode: 493 # 0755
contents:
remote:
url: https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/hosted/canal/canal.yaml
- path: /opt/wanpoll/env
filesystem: root
mode: 0600
contents:
inline: |
USER=xxxxxxxxxxxxx
PASSWORD=xxxxxxxxxxxx
INTERVAL=5
NAME=xxxxx.example.com,xxxxx.example.com
HZ=ZZZZZZZZZZZZ
AWS_ACCESS_KEY_ID=XXXXXXXXXXXXX
AWS_SECRET_ACCESS_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
- path: /ignition/init/k8s/install.sh
filesystem: root
mode: 480 # 740
contents:
inline: |
#!/bin/bash
# Unzip the kubernetes binaries if not already present
test -d /opt/bin/kubeadm && echo "k8s binaries (kubeadm) already installed" && exit 0
# NOTE: If RELEASE is updated, the SHA512 SUMs will need to be as well
echo -e "=> Installing k8s v1.10.2"
echo "=> Cusomizing kubelet.service..."
sed -i "s:/usr/bin:/opt/bin:g" /etc/systemd/system/kubelet.service
sed -i "s:/usr/bin:/opt/bin:g" /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
systemctl daemon-reload
systemctl enable kubelet
systemctl start kubelet
- filesystem: root
path: /ignition/init/cri-containerd/install.sh
mode: 480 # 740
contents:
inline: |
#!/bin/bash
# Unzip the kubernetes binaries if not already present
test -d /opt/containerd && echo "containerd binaries already installed" && exit 0
VERSION=1.1.0
echo -e "=> Installing containerd v${VERSION}"
echo "=> Installing containerd...."
cd /ignition/init/cri-containerd
tar -C / -k -xzf cri-containerd-${VERSION}.linux-amd64.tar.gz
echo "=> Copying /usr/local binaries to /opt/bin ...."
mkdir -p /ignition/init/cri-containerd/unzipped
tar -C unzipped -k -xzf cri-containerd-${VERSION}.linux-amd64.tar.gz
cp -r unzipped/usr/local/bin/* /opt/bin
systemctl start containerd
echo "=> Adding dropins...."
cat > /etc/systemd/system/kubelet.service.d/0-containerd.conf <<EOF
[Service]
Environment="KUBELET_EXTRA_ARGS=--container-runtime=remote --runtime-request-timeout=15m --container-runtime-endpoint=unix:///run/containerd/containerd.sock --volume-plugin-dir=/var/lib/kubelet/volumeplugins"
EOF
mkdir -p /etc/systemd/system/containerd.service.d/
cat > /etc/systemd/system/containerd.service.d/0-direct-containerd.conf <<EOF
[Service]
ExecStart=
ExecStart=/opt/bin/containerd
EOF
echo "=> Triggering systemctl daemon-reload...."
systemctl daemon-reload
systemctl restart containerd
- filesystem: root
path: /ignition/init/cni/install.sh
mode: 480 # 740
contents:
inline: |
#!/bin/bash
# Unzip the kubernetes binaries if not already present
test -d /opt/cni/bin && echo "CNI binaries already installed" && exit 0
VERSION=0.7.1
echo -e "=> Installing CNI (v${VERSION}) binaries to /opt/cni/bin"
cd /ignition/init/cni
mkdir -p /opt/cni/bin
tar -C /opt/cni/bin -k -xzf cni-plugins-v${VERSION}.tgz
- filesystem: root
path: /ignition/init/kubeadm/kubeadm-install.sh
mode: 480 # 740
contents:
inline: |
#!/bin/bash
# Ensure kubeadm binary is present
test -f /opt/bin/kubeadm || (echo "Failed to find kubeadm binary" && exit 1)
# Exit if kubeadm has already been run (/etc/kubernetes folder would have been created)
test -d /etc/kubernetes && echo "/etc/kubernetes is present, kubeadm should have already been run once" && exit 0
echo "=> Running kubeadm init..."
/opt/bin/kubeadm init --cri-socket "/run/containerd/containerd.sock" --pod-network-cidr "10.244.0.0/16"
# Disable docker (kubelet will use containerd runtime directly)
sudo systemctl stop docker
sudo systemctl disable docker
echo "=> Running kubeadm post-install set up for user 'core'"
mkdir -p /home/core/.kube
cp -i /etc/kubernetes/admin.conf /home/core/.kube/config
chown $(id -u core):$(id -g core) /home/core/.kube/config
- filesystem: root
path: /ignition/init/k8s/setup.sh
mode: 493 # 0755
contents:
inline: |
#!/bin/bash
# Ensure /etc/kubernetes is present (created by kubeadm)
test -d /etc/kubernetes || (echo "/etc/kubernetes not present, ensure kubeadm has run properly" && exit 1)
echo "=> Enabling workload running on the master node"
kubectl taint nodes --all node-role.kubernetes.io/master-
echo "=> Installing canal"
kubectl apply -f /ignition/init/canal/rbac.yaml
kubectl apply -f /ignition/init/canal/canal.yaml
- path: /etc/ssh/sshd_config
filesystem: root
mode: 0600
contents:
inline: |
# Use most defaults for sshd configuration.
UsePrivilegeSeparation sandbox
Subsystem sftp internal-sftp
UseDNS no
PasswordAuthentication no
PermitRootLogin no
AllowUsers core
AuthenticationMethods publickey
参考URL: YET ANOTHER CLUSTER RE-INSTALL AFTER SWITCHING BACK TO CONTAINER LINUX
5. 本番USBメモリへの CoreOS のインストール
ここまできたらようやく本番の USB メモリへ CoreOS のインストールができます。
-
本番用の USBメモリ を初期化します。初期化は、
暫定USBメモリへの CoreOS ISOイメージの書き込み
の時と同じ手順で中身を消去します。今回は、32GB
の USBメモリ を使いました。 -
前段階で作成した
ignition.json
を Dropbox にアップロードし、共有リンクを作成して控えておきます。 -
Mac mini を終了して起動すると、rEFInd による OS の選択画面が現れます。USB メモリの CoreOS を選びましょう。確か、Custom イメージみたいな感じで表示されたような気がしますが、それが CoreOS です。
-
CoreOS が起動します。起動するまでには時間がかかりますが少し待ちます。
-
起動に成功したら、Dropbox から
ignition.json
をダウンロードします。CoreOS にはcurl
とwget
がインストールされているのでどちらかを使ってダウンロードします。 -
lsblk
コマンドを実行して、USBメモリがマウントされている場所を特定します。ここでは、/dev/sbc
とします。 -
coreos-install
を実行して CoreOS をインストールします。CoreOS の場合はすでに用意されているので以下のコマンドを実行します。coreos-install -d /dev/sbc -i ignition.json -C stable
-
CoreOS 以外の Linux の場合は、以下のコマンドでインストールします。
curl https://raw.githubusercontent.com/coreos/init/master/bin/coreos-install | bash -s -- -d /dev/sbc -i ignition.json -C stable
-
以上でインストールは完了です。CoreOS を終了しましょう。
shutdown
6. 起動
インストールが成功したら、起動をします。8GB
の USBメモリ は必要ないので、Mac mini から抜いておきます。
Mac mini を起動すると、rEFInd で起動ディスクを選びます。なぜか CoreOS の起動ディスクが4つくらい表示されるのですが、左のほうのペンギンのアイコンを選択すると起動できます。
バイナリのダウンロードや kubernetes のセットアップが実行されるため起動には時間がかかりますが、待っていれば起動に成功します。
別の端末から、ssh でログインしてログインできることを確かめてください。
まとめ
長くなりましたが、CoreOS + kubernetes の環境の立ち上げができました。
CoreOS の Ignition の設定はあまり深く練っていないのでアドバイスなどがあれば教えていただきたいです。
次回は、kubernetes にアプリケーションをデプロイし、複数サービスが同時に運用できるようにプロキシの設定をしていきます。