はじめに
以前、KubernetesをDocker for Macを使って構築してみました。(下の記事)
今回は、Ubuntu環境にKubernetesクラスタを構築したいと思います。
Ubuntu16.04, 18.04どちらも構築できることを確認済みです。
なお、クラウドのマネジメントサービスは使わず、手動で構築する手順になっており、master01
およびnode01
というホスト名の2台のUbuntu環境にて構築します。
1. Masterの構築
1-1. 環境のクリーンアップ
クリーンな環境でインストールするためにまずは下記を実施します。
- dockerをアンインストール
sudo apt purge docker-ce docker-ce-cli docker
- etcdをアンインストール
インストールされているかを確認し、あればアンインストールを実行します。
dpkg -l | grep etcd
sudo apt purge etcd
/var/lib/etcd
の削除
中身を削除します。ない場合はスキップでOKです。
1-2. Dockerのインストールと初期設定
docker-ceをインストールします。
sudo apt install docker-ce=18.06.2~ce~3-0~ubuntu
docker --version # インストールされたことの確認
注意)Dockerのバージョンが新しすぎると、Kubernetesが対応していないため、エラーになります。公式ページで対応しているバージョンを確認してください。
[https://kubernetes.io/:title]
上記のバージョンでインストールした場合は下記の出力になります。
Docker version 18.06.2-ce, build 6d37f41
次にcgroupの設定を確認します。
/etc/docker/daemon.json
のファイルが下記のようになっていることを確認し、なっていなければ編集して合わせます。
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
編集した場合は、設定を反映させるために、dockerデーモンを再起動します。
sudo systemctl daemon-reload
sudo systemctl restart docker
1-3. Kubernetesに必要なライブラリのインストール
まずは、必要なライブラリをインストールします。
sudo apt update && sudo apt install -y apt-transport-https curl
Kubernetesのリポジトリ取得し、kubeadm, kubelet, kubectlをインストールします。
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
sudo su -
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main
EOF
exit
sudo apt update && sudo apt install -y kubelet kubeadm kubectl
これでKubernetesクラスタを構築するための準備が整いました。
1-4. Kubernetesクラスタの構築
まずは、メモリのswap機能をoffにします。これを実行しないとkubeletを起動できません。
sudo swapoff -a
swap onの状態でkubeletを起動しようとすると下記のようなエラーが発生します。kubeletはswap機能をサポートしていないそうです。
error: failed to run Kubelet: Running with swap on is not supported, please disable swap! or set --fail-swap-on flag to false.
swapをoffにしたら、いよいよクラスタの構築です。
下記のコマンドを実行します。ネットワークも自動で設定するためにflannelを考慮したオプションを指定しています。
sudo kubeadm init --pod-network-cidr=10.244.0.0/16
このコマンドの実行完了には時間がかかります。下記の出力が表示されたら、問題なく初期化が完了した合図です。
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.xxx.xxx:6443 --token XXXXXX.XXXXXXXXXXXX \
--discovery-token-ca-cert-hash sha256:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
上記の出力の通り、kubernetesの設定ファイルをコピーし、権限を設定します。
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
これを実行しないとkubectlコマンドが使えないので注意してください。
また、出力の最後の部分(kubeadm join xxx.xxx.xxx.xxx:6443 ~
)をメモっておいてください。node追加時に必要になります。
下記のコマンドでmasterとして追加されたことを確認できます。
kubectl get nodes
出力は下記のようになるかと思います。
NAME STATUS ROLES AGE VERSION
master01 NotReady master 15m v1.16.1
この時、STATUSはNotReady
のままになっていますが、これからネットワーク設定をしてReady
にしていきます。
1-5. flannelを使ったネットワーク設定
上述の通り、この時点ではmasterの状態はNotReady
のままであるため、ネットワークの設定を実施する必要があります。
まずは、ネットワークファイルを設定します。
sudo su -
echo '1' > /proc/sys/net/bridge/bridge-nf-call-iptables
exit
そしてインターネット経由でflannelのyamlファイルを取得し、kubernetes環境に適用します。
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
1分以内にはPodの起動が完了し、Ready
状態になるはずです。
NAME STATUS ROLES AGE VERSION
master01 Ready master 17m v1.15.0
以上でMasterの設定は完了です。次は実際のコンテナが動くNodesの設定です。
2. Nodeの構築
途中まではMasterと同じです。
2-1. 環境のクリーンアップ
# dockerをアンインストール
sudo apt purge docker-ce docker-ce-cli docker
# etcdをアンインストール
dpkg -l | grep etcd
sudo apt purge etcd
# `/var/lib/etcd` の削除
2-2. Dockerのインストールと初期設定
# dockerのインストール
sudo apt install docker-ce=18.06.2~ce~3-0~ubuntu
docker --version # インストールされたことの確認
# daemon.jsonの確認
cat /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
# 必要であればdockerの再起動
sudo systemctl daemon-reload
sudo systemctl restart docker
2-3. Kubernetesに必要なライブラリのインストール
sudo apt update && sudo apt install -y apt-transport-https curl
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
sudo su -
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main
EOF
exit
sudo apt update && sudo apt install -y kubelet kubeadm kubectl
2-4. Nodeの追加
ここもMasterと同じく、まずメモリのswap機能をoffにします。
sudo swapoff -a
また、一度でもnode追加をしたことがある機器を再利用している場合は、下記のコマンドでリセットしておかないと正常に稼働しません。
sudo kubeadm reset
その後、Masterのkubeadm initコマンドの最後に出力されたkubeadm join
コマンドでnodeの追加を実施します。
sudo kubeadm join 192.168.xxx.xxx:6443 --token xxxxxx.xxxxxxxxxxxx --discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxx
上記はxxxで記載していますが、実際には英数字が入ります。
注意)上記のコマンドはmasterのtokenを利用しています。そのため、Masterの設定から時間が立っている場合は、tokenが期限切れになっていることがあります。その場合はMasterにて以下を実行してtokenを再発行してください。
kubeadm token create
発行されたtokenにコマンドを書き換えて実行します。
問題なくkubeadm join
コマンドが完了したら、Masterにて追加されていることが確認できます。
kubectl get nodes
コマンドを実行して結果を確認してみてください。
NAME STATUS ROLES AGE VERSION
node01 Ready <none> 4m23s v1.15.0
master01 Ready master 124m v1.15.0
もしSTATUSがNotReadyになっていた場合は、Nodeの/etc/hosts
ファイルに自身のIPアドレスとホスト名が記載されていない可能性があります。
記載されていなかった場合は、追加して、再度STATUSを確認するとReadyになっているはずです。
これでNodeの追加が完了しました。
2-5. 「network plugin is not ready: cni config uninitialized」というエラーが出た場合には
Node追加時に上記のエラーが出た場合は、flannelの設定ファイルを編集する必要があります。CNIプラグインのバグだそうです。
参考URL:
sudo systemctl status kubelet
を実行することでより詳細なエラーを確認できます。
対応としては、/etc/cni/net.d/10-flannel.conflist
のファイルに"cniVersion": "0.3.1"
を追加すれば、数秒でエラーが解消されます。
ファイル全体は下記のようになります。
{
"name": "cbr0",
"cniVersion": "0.3.1",
"plugins": [
{
"type": "flannel",
"delegate": {
"hairpinMode": true,
"isDefaultGateway": true
}
},
{
"type": "portmap",
"capabilities": {
"portMappings": true
}
}
]
}
3. クラスタの確認
3-1. 補完機能の追加
確認していく前に、コマンドを楽に打てるように補完機能を追加します。
下記のコマンドを実行することで、kubectlコマンドの様々な指定を補完してくれるようになります。
sudo apt install bash-completion
echo "source <(kubectl completion bash)" >> ~/.bashrc
3-2. MasterやNodeを確認
kubectlコマンドで追加したMasterやNodeの状態を確認していきます。
下記のコマンドは今までも出現してきましたが、Masterを含む物理ホストの情報を表示できます。
kubectl get nodes -o=wide
オプションを付けることで、より詳細な情報を確認できます。
出力は下記のようになります。
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
node01 NotReady <none> 11m v1.15.0 192.168.xxx.xxx <none> Ubuntu 16.04 LTS 4.4.0-21-generic docker://18.9.0
node02 NotReady <none> 15m v1.15.0 192.168.xxx.xxx <none> Ubuntu 16.04.6 LTS 4.4.0-21-generic docker://18.9.7
master01 Ready master 42m v1.15.2 192.168.xxx.xxx <none> Ubuntu 18.04.2 LTS 4.15.0-43-generic docker://18.9.7
クラスタの基本情報を表示するには、下記のコマンドを使います。
kubectl cluster-info
出力は下記のようになります。
Kubernetes master is running at https://192.168.xxx.xxx:6443
KubeDNS is running at https://192.168.xxx.xxx:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
それぞれのNodeの詳細を確認するには、下記のコマンドを使います。
kubectl describe nodes node01
出力は長いので割愛します。
おまけ:Nodeを削除するには
Nodeを削除するには、正しい手順を踏む必要があります。
無闇にコンテナを削除したり、ネットワークから切り離したりすると、クラスタ全体が正常に稼働しなくなる可能性があります。
手順としてはkubectl drain
コマンドでスケジューリングの対象から外した後に、kubectl delete
を実行して削除します。
# 対象のNodeをDrainする
kubectl drain node01
# ShedulingDisabledになっていることを確認する
kubectl get nodes
# 削除する
kubectl delete node node01
# nodeが表示されなくなっていることを確認する
kubectl get nodes
※コマンドは全てMasterで実行します。
まとめ
以上が、オンプレミス環境のUbuntu環境にKubernetesクラスタを構築する方法です。
合わせてクラスタの確認方法やNodeの削除方法も載せておきました。
次は、このKubernetesの環境をRancherで管理する方法を書き残しておこうと思います。(2019/10/13追記 書き残しました。下記です。)
参考文献
- 作者: 山田明憲
- 出版社/メーカー: 技術評論社
- 発売日: 2018/08/25
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (1件) を見る
こちらの本は、KubernetesだけではなくDockerについての説明もあります。Dockerをこれから学ぶ人はもちろん、すでに習得している人の復習としても使えます。Kubernetesの部分は、細かく詳細を説明しているのではなく、まずは触って実際に構築してみて理解していく内容になっているため、初学者にとって進めやすく、おすすめです。
しくみがわかるKubernetes Azureで動かしながら学ぶコンセプトと実践知識
- 作者: 阿佐志保,真壁徹
- 出版社/メーカー: 翔泳社
- 発売日: 2019/01/23
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る