初めに
本記事は、 kubeadm
によるkubernetesのシングルクラスタ(Master1台、Worker1台)の環境構築について記載します。Proxy環境下で、sudo
をつけてコマンド実行する方向けです。
シングルクラスタ環境を作るための手順は、大きく4つあります:
- 事前準備(Master, Worker)
- kubeadm による kubernetes(v1.14)環境構築(Master、 Worker)
- CNI(Container Network Interface)のインストール(Master)
- Worker nodeの登録(Worker)
今回のベースとなる環境(Master, Worker):
lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 16.04.6 LTS
Release: 16.04
Codename: xenial
- 2cores
- 8GB RAM
- 40GB HDD
1. 事前準備(Master, Worker)
-
Proxyの設定
command
export http_proxy='http://your_proxy:password@hogehogeproxy.com'
export https_proxy='http://your_proxy:password@hogehogeproxy.com'
```
* /etc/apt/apt.conf.d/01proxy
を用意しても良いですが、今回は 不要 です:
```bash:/etc/apt/apt.conf.d/01proxyを用意するcommand
echo "Acquire::http::Proxy "http://your_proxy.pass@hogehogeproxy.com"" | sudo tee /etc/apt/apt.conf.d/01proxy
echo "Acquire::https::Proxy "http://your_proxy.pass@hogehogeproxy.com"" | sudo tee -a /etc/apt/apt.conf.d/01proxy
```
-
dockerのインストール
-
dockerの公式ページに沿ってインストール
- あるある: 公式ドキュメント通りにコマンド実行しても、社内Proxy環境下ではうまくいかないケースが多い
command -
dockerの公式ページに沿ってインストール
sudo -E apt remove docker docker-engine docker.io containerd runc -y
sudo -E apt update
sudo -E apt install apt-transport-https ca-certificates curl gnupg-agent software-properties-common -y
sudo -E bash -c "curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -"
sudo -E apt-key fingerprint 0EBFCD88
sudo -E add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo -E apt update
sudo -E apt install docker-ce docker-ce-cli containerd.io -y
sudo systemctl start docker
sudo mkdir -p /etc/systemd/system/docker.service.d
...(snip)...
Found linux image: /boot/vmlinuz-4.4.0-145-generic
Found initrd image: /boot/initrd.img-4.4.0-145-generic
Found linux image: /boot/vmlinuz-4.4.0-143-generic
Found initrd image: /boot/initrd.img-4.4.0-143-generic
Found memtest86+ image: /boot/memtest86+.elf
Found memtest86+ image: /boot/memtest86+.bin
done
```
-
DockerのProxy設定
-
docker公式のProxy設定に加えて、CNIで利用するサブネットを考慮した
NO_PROXY
設定を施します。
command(Proxyの値は適宜書き換えてください) -
docker公式のProxy設定に加えて、CNIで利用するサブネットを考慮した
sudo bash -c "echo -e "[Service]\nEnvironment="HTTP_PROXY=http://proxy_user:proxy_pass@your_proxy.com"\nEnvironment="HTTPS_PROXY=http://proxy_user:proxy_pass@your_proxy.com"\nEnvironment="NO_PROXY=localhost,127.0.0.1,192.168.122.33,192.168.0.0/16,10.96.0.0/16,10.244.0.0/16,111.111.0.0/16"" | tee vi /etc/systemd/system/docker.service.d/http-proxy.conf"
sudo systemctl daemon-reload
sudo systemctl restart docker
systemctl show --property=Environment docker
...(snip)...
Environment=HTTP_PROXY=http://proxy_user:proxy_pass@your_proxy.com HTTPS_PROXY=http://proxy_user:proxy_pass@your_proxy.com NO_PROXY=localhost,127.0.0.1,192.168.122.33
```
* NO_PROXY には、MasterのIPを指定
* (追記)ごめんなさい以下の書き方は間違っていました。no_proxy
にCIDRを指定しても効いていないとのことでした:
* ``NO_PROXY=localhost,127.0.0.1,192.168.122.33,192.168.0.0/16,10.96.0.0/16,10.244.0.0/16,111.111.0.0/16``
-
kubeadm, kubelet, kubectlのインストール
command
sudo -E apt update; sudo -E apt install -y apt-transport-https curl
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo -E apt-key add -
echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo -E apt update
sudo -E apt install -y kubelet kubeadm kubectl
sudo -E apt-mark hold kubelet kubeadm kubectl
...(snip)...
Unpacking kubeadm (1.14.0-00) ...
Setting up cri-tools (1.12.0-00) ...
Setting up kubernetes-cni (0.7.5-00) ...
Setting up kubelet (1.14.0-00) ...
Setting up kubectl (1.14.0-00) ...
Setting up kubeadm (1.14.0-00) ...
```
-
kubelet
の起動時引数に--fail-swap-on=false
を追加後デーモンの再起動&kubelet
が起動時に立ち上がる設定command
sudo sed -i "/^[Service]$/a Environment="KUBELET_EXTRA_ARGS=--fail-swap-on=false"" /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
sudo systemctl daemon-reload; sudo systemctl stop kubelet
sudo systemctl enable kubelet; sudo systemctl start kubelet
```
* あるある: --fail-swap-on=false
を付け忘れると ``kubelet``が起動しないことが多い。 v1.9のときもそうでした。
- この時点で、screenや別ウィンドウを使って、下記のコマンドの出力結果を出して続けておく。
-
この先、コンテナが起動したかどうかの確認が楽になります。
command
watch -d kubectl get pods --all-namespaces -o wide
a:この時点ではこんな出力ですが、気にせず先に進みます
Every 2.0s: kubectl get pods --all-namespaces -o wide Sat Apr 6 xx:xx:2019
.
The connection to the server localhost:8080 was refused - did you specify the right host or port?
```
2. kubernetes の構築(Masterのみ)
-
kubeadm init
を実行して kubernetes環境をデプロイ- 本手順書では、 Canal をインストールします
command
sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --ignore-preflight-errors=swap
..(snip)...
[preflight] This might take a minute or two, depending on the speed of your internet connection
[preflight] You can also perform this action in beforehand using 'kubeadm config images pull'
...(体感3分くらい)...
Your Kubernetes control-plane has initialized successfully!
...(snip)...
```
* Your Kubernetes control-plane has initialized successfully!
があれば成功です
* 下記のようなエラーになったため、``--ignore-preflight-errors=swap`` オプションをつけて実行しています
* あとWARNINGも出ていますが 面倒なので今回は スルーします
```
...(snip)...
[init] Using Kubernetes version: v1.14.0
[preflight] Running pre-flight checks
[WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd". Please follow the guide at https://kubernetes.io/docs/setup/cri/
error execution phase preflight: [preflight] Some fatal errors occurred:
[ERROR Swap]: running with swap on is not supported. Please disable swap
[preflight] If you know what you are doing, you can make a check non-fatal with --ignore-preflight-errors=...
```
-
To start using your cluster, you need to run the following as a regular user
に従って、コマンド実行command
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
```
-
上記コマンド実行後、
watch -d
を実行していた画面に下記のような状態が出力されることを確認。
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
kube-system coredns-fb8b8dccf-sj9fb 0/1 Pending 0 3m14s
kube-system coredns-fb8b8dccf-tx8pn 0/1 Pending 0 3m14s
kube-system etcd-compute 1/1 Running 0 2m27s 192.168.123.236 compute
kube-system kube-apiserver-compute 1/1 Running 0 2m35s 192.168.123.236 compute
kube-system kube-controller-manager-compute 1/1 Running 0 2m11s 192.168.123.236 compute
kube-system kube-proxy-8dvn6 1/1 Running 0 3m14s 192.168.123.236 compute
kube-system kube-scheduler-compute 1/1 Running 0 2m15s 192.168.123.236 compute
```
* coredns-なんちゃら
が ``Pending`` の状態ですが、ここでは放置して次に進みます。
3. CNIのインストール(Masterのみ)
Canalの場合
-
こちらを参考に下記のコマンドを実行
command
kubectl apply -f https://docs.projectcalico.org/v3.3/getting-started/kubernetes/installation/hosted/canal/rbac.yaml
kubectl apply -f https://docs.projectcalico.org/v3.3/getting-started/kubernetes/installation/hosted/canal/canal.yaml
clusterrole.rbac.authorization.k8s.io/calico created
clusterrole.rbac.authorization.k8s.io/flannel created
clusterrolebinding.rbac.authorization.k8s.io/canal-flannel created
clusterrolebinding.rbac.authorization.k8s.io/canal-calico created
configmap/canal-config created
daemonset.extensions/canal created
serviceaccount/canal created
...(snip)...
customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created
```
* 本コマンド実行後、canal-なんたら
というPodの作成が始まります。
* ``coredns`` と上記Podを含む全てのPodが ``Running`` になることを確認しましょう
* 体感2分30秒くらい
4. Worker nodeの登録(Workerのみ)
-
Worker node にSSHでログイン後、sudoになります(公式ドキュメント通りに)
command
sudo su -
```
-
kubeadm init
の出力結果に表示されたkubeadm join
を実行しますcommand
kubeadm join 192.168.122.33:6443 --token miserarenaiyo --discovery-token-ca-cert-hash sha256:kottimoyapparimiserarenaiyo --ignore-preflight-errors=swap
```
* あるある: UbuntuでSwapをオフにする設定をあとで調べようと思っていても、忘れる(揮発性)
```
...(snip)...
This node has joined the cluster:
- Certificate signing request was sent to apiserver and a response was received.
- The Kubelet was informed of the new secure connection details.
Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
```
-
Master上でノード一覧を表示して、Workerが追加されていることを確認します
command
kubectl get nodes
NAME STATUS ROLES AGE VERSION
k-master Ready master 157m v1.14.0
k-worker Ready 87s v1.14.0
```
* STATUS
が ``Ready`` になれば登録成功です。お疲れ様でした。
トラシュー
実際に遭遇したエラーの対処について記載します。
kubeadm init
がコケる
-
kubeletの状況確認
command
journalctl -f -e -u kubelet.service
```
-
docker の Proxy設定状況の確認
command
systemctl show --property=Environment docker
```
* ここの設定が抜けていたので、Proxy設定後、docker-daemonをリロード
-
kubeadm init
を再度実行するため、作成したPodを全て削除command
kubectl delete -f
```
-
kubeadm reset
後、$HOME
ディレクトリの.kube/
を削除command
sudo kubeadm reset
rm -rf ~/.kube
```
- 上記実行後、
kubeadm init
を再度実行-
.kube/
を消さない場合、kubectl
コマンドが実行できなくなりました(証明書関係のエラーでしたが、ログを取り忘れました...)
-
Worker Nodeの STATUS
が一生 NotReady
Worker側の kubelet
がエラーを吐いている可能性があります。私は下記の2つの現象が発生していました:
(A) Worker Node上の docker-daemonがProxy設定を認知していない
(B) CNIの設定ファイル、ディレクトリがWorkerノードに存在しない
いずれの場合においても、 まずはWorker nodeの登録解除をする必要があります。
-
(Master) Worker nodeの登録を解除
command
kubectl delete node
```
-
(Worker) joinの状態を解除する(rootで実行)
command
kubeadm reset
iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X
```
(A) Worker Node上の docker-daemonがProxy設定を認知していない
-
kubelet
の状態を確認command
journalctl -f -e -u kubelet.service
...(snip)...
Apr 01 19:24:56 k-worker kubelet[9131]: E0401 19:24:56.331896 9131 pod_workers.go:190] Error syncing pod
836c281a-5465-11e9-8b12-5254007d68f0 ("canal-jwfln_kube-system(836c281a-5465-11e9-8b12-5254007d68f0)"),
skipping: failed to "CreatePodSandbox" for "canal-jwfln_kube-system(836c281a-5465-11e9-8b12-5254007d68f0)"
with CreatePodSandboxError: "CreatePodSandbox for pod "canal-jwfln_kube-system(836c281a-
5465-11e9-8b12-5254007d68f0)" failed: rpc error: code = Unknown desc = failed pulling image
"k8s.gcr.io/pause:3.1": Error response from daemon: Get https://k8s.gcr.io/v2/: dial tcp:
lookup k8s.gcr.io on 192.168.122.1:53: no such host"
```
* CanalのPodを作る際の docker pull
にコケているように見えます
* このエラーが出ているときは、まずはProxy設定を確認してみましょう
-
Proxyの設定状況を確認(DockerのProxy設定 参照)
command
systemctl show --property=Environment docker
```
-
Proxy定義ファイル(
/etc/systemd/system/docker.service.d/http-proxy.conf
)はあるのにデーモン側で設定されていない場合、デーモンの再起動忘れの可能性があるため、docker-daemon
を再起動command
sudo systemctl daemon-reload
sudo systemctl restart docker
```
* その他の見直しポイント
* http_proxy, https_proxy にはそれぞれ、適切なproxyが設定されているか?
* http
のproxy しか存在しない状態で ``https`` 、あるいはその逆を指定していないか?
* no_proxyに下記のアドレスはセットされているか?
* flannel, calico, canalが使うサブネット
* Master, Worker のIPアドレス
- 再度 worker側から
kubeadm join
コマンドを実行
(B) CNIの設定ファイル、ディレクトリがWorkerノードに存在しない
下記のようなエラーメッセージが確認できます
journalctl -f -e -u kubelet.service
...(snip)...
Apr 01 19:24:56 k-worker kubelet[9131]: W0401 19:24:56.395397 9131 cni.go:213] Unable to update
cni config: No networks found in /etc/cni/net.d
Apr 01 19:24:57 k-worker kubelet[9131]: E0401 19:24:57.187390 9131 kubelet.go:2170] Container runtime
network not ready: NetworkReady=false reason:NetworkPluginNotReady
message:docker: network plugin is not ready: cni config uninitialized
/etc/cni/net.d
が見つからない、 NetworkPluginNotReady だよ、ということで、えいやで試してみたところ Ready
になりました。ここは「えいや」ですので、この状況に陥らないことを祈ります。
-
(Worker)
kubeadm reset
を実行(rootで実行)command
kubeadm reset
iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X
```
-
(Worker)下記のディレクトリ(/etc/cni/net.d/)を作成
command
mkdir -p /etc/cni/net.d
```
-
(Master)同じフォルダ上(
/etc/cni/net.d/
)にあるファイルをWorkerへコピー(Canalの場合は以下)- 10-canal.conflis
- calico-kubeconfig
-
10-canal.conflist は、node情報がベタ書きされているため、Worker node名に変更
"type": "calico", "log_level": "info", "datastore_type": "kubernetes",
-
"nodename": "k-master",
-
"nodename": "k-worker", "ipam": {
- 再度 Worker側からjoinコマンドを実行
以上です。ここまで読んでくださってありがとうございました。
次は metalkubeの環境構築を目指しまっす。