2022年12月27日
プロキシ環境でKubernetes構築(Containerd+Calico)
同期と一緒にトラシュしたので、プロキシ環境下で kubeadm + Containerd + Calico の Kubernetes クラスターを構築する方法について記録を残します。
環境
- Ubuntu 22.04
- サーバーはニフクラを利用(e-medium4 2vCPU/4GB)
- Kubernetes v1.26.0
- kubeadm v1.26.0
- Containerd v1.6.14
- Calico v3.24.5
コントロールプレーン、ノード1台ずつの構成とします。プロキシを経由しなければインターネットに出られないようになっています。
プライベートネットワークの CIDR は 172.31.0.0/16
、プロキシは http://172.31.0.1:3128
として進めます。
Service CIDR はデフォルトの 10.96.0.0/12
を、Pod Network CIDR は Calico のデフォルトである 192.168.0.0/16
を使います。
💡 筆者の環境ではこの記事で紹介する内容で構築できましたが、環境によって状況が異なる可能性があります。プロキシ配下での構築に挑戦する前に、まずは似た環境のインターネット接続があるサーバーで試すことをおすすめします。
プロキシの設定が必要な箇所
環境変数(~/.bashrc
)
コントロールプレーン
export HTTP_PROXY=http://172.31.0.1:3128 export HTTPS_PROXY=http://172.31.0.1:3128 export NO_PROXY=localhost,127.0.0.1,172.31.0.0/16,10.96.0.0/12,192.168.0.0/16
コントロールプレーンでは NO_PROXY
に Sercice CIDR の IP レンジ(デフォルトは 10.96.0.0/12
)と Pod Network CIDR の IP レンジを設定しておくことで kubeadm init
時の preflight check の WARNING を抑えることができます1。
反映するには source ~/.bashrc
します。
ノード
export HTTP_PROXY=http://172.31.0.1:3128 export HTTPS_PROXY=http://172.31.0.1:3128 export NO_PROXY=localhost,127.0.0.1,172.31.0.0/16
ノードでは kubeadm init
を実行しないのでこれだけで OK。
/etc/apt/apt.conf
各種ライブラリのインストールのために必要です。
Acquire::http::proxy "http://172.31.0.1:3128"; Acquire::https::proxy "http://172.31.0.1:3128";
/etc/systemd/system/containerd.service.d/http-proxy.conf
[Service] Environment="HTTP_PROXY=http://172.31.0.1:3128" Environment="HTTPS_PROXY=http://172.31.0.1:3128" Environment="NO_PROXY=localhost,127.0.0.1,172.31.0.0/16,10.96.0.0/12"
NO_PROXY
に Pod Network CIDR の IP レンジも追加しようかと思ったのですが、ノードを跨いだ Pod 間の通信など試した範囲では追加しなくても異常がなかったので追加していません。
筆者の Kubernetes の知識が浅いだけかもしれないので、検証不足でしたら教えていただけるとありがたいです。🙇
このファイルを変更したら Containerd の再起動が必要です。
systemctl daemon-reload systemctl restart containerd
構築手順
上記のプロキシ設定以外は通常の手順と同じです。
Ubuntu 22.04 で構築する際の注意点については Ubuntu 22.04でのKubernetesクラスター構築(ContainerdとSystemdCgroup) をご参照ください。
kubeadm init --pod-network-cidr 192.168.0.0/16
ネットワークプラグインの適用
構築が完了したらネットワークプラグインを適用します。以下は Calico を使う場合のコマンドです。
curl https://raw.githubusercontent.com/projectcalico/calico/v3.24.5/manifests/calico.yaml -O kubectl apply -f calico.yaml
kubectl -n kube-system get po -w
して、1つの calico-kube-controllers
とノード数分の calico-node
Pod が Running なら問題ありません。CoreDNS がクラッシュするバグを踏んだら KubernetesでCoreDNSがループしてしまう問題への対処 の記事を参考にしてみてください。
動作確認
簡単な動作確認をしてみます。
kubectl create deployment nginx --image=nginx
POD_NAME=$(kubectl get pods -l app=nginx -o jsonpath="{.items[0].metadata.name}")
別のシェルを開き、curl localhost:8080
を試してみます。
kubectl port-forward $POD_NAME 8080:80
ログを見てみます。
kubectl logs $POD_NAME
exec を試します。
kubectl exec -ti $POD_NAME -- nginx -v
NodePort Service を試します。
kubectl expose deployment nginx --port 80 --type NodePort
NODE_PORT=$(kubectl get svc nginx \ --output=jsonpath='{range .spec.ports[0]}{.nodePort}')
curl 127.0.0.1:$NODE_PORT
kubectl delete svc nginx
次に Cluster IP Service を試します。
kubectl expose deployment nginx --port 80 --type ClusterIP
クライアントを想定した Pod を建てます(nginx ですが)。
kubectl create deployment client --image=nginx
POD_NAME_CLIENT=$(kubectl get pods -l app=client -o jsonpath="{.items[0].metadata.name}")
Pod 内で curl nginx
を実行します。
kubectl exec -ti $POD_NAME_CLIENT -- curl nginx
>Welcome to nginx!
の HTML が返ってこれば OK!
トラブルシューティング集
FailedCreatePodSandBox
- ホストのプライベート IP にアクセス不可
calico-kube-controllers
が ContainerCreating で止まってしまう問題が発生しました。
Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 115s default-scheduler 0/1 nodes are available: 1 node(s) had untolerated taint {node.kubernetes.io/not-ready: }. preemption: 0/1 nodes are available: 1 Preemption is not helpful for scheduling.. Normal Scheduled 104s default-scheduler Successfully assigned kube-system/calico-kube-controllers-7bdbfc669-97wdp to controlplane Warning FailedCreatePodSandBox 103s kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox "6a029253befac6840d358f8f78b865510bb3874b971fc7241d4ded6b1e92ce2d": plugin type="calico" failed (add): stat /var/lib/calico/nodename: no such file or directory: check that the calico/node container is running and has mounted /var/lib/calico/ Normal SandboxChanged 16s (x3 over 103s) kubelet Pod sandbox changed, it will be killed and re-created.
stat /var/lib/calico/nodename: no such file or directory: check that the calico/node container is running and has mounted /var/lib/calico/
のエラーメッセージが出ていますが、実際にはマウントはできていました。
「マウントはできて nodename(ホスト名)は取得できているが、プロキシに阻まれて通信できていないのでは?」と考え、Containerd の NO_PROXY の設定にホストのプライベートネットワークの CIDR を追記したら 172.31.0.0/16
たらこの問題は解決しました。
# vim /etc/systemd/system/containerd.service.d/http-proxy.conf
172.31.0.0/16
を追記。
[Service] Environment="HTTP_PROXY=http://172.31.0.1:3128" Environment="HTTPS_PROXY=http://172.31.0.1:3128" Environment="NO_PROXY=localhost,127.0.0.1,172.31.0.0/16"
# systemctl daemon-reload # systemctl restart containerd # kubectl -n kube-system delete po calico-kube-controllers-7bdbfc669-97wdp --force Warning: Immediate deletion does not wait for confirmation that the running resource has been terminated. The resource may continue to run on the cluster indefinitely. pod "calico-kube-controllers-7bdbfc669-97wdp" force deleted
FailedCreatePodSandBox
- Service の IP にアクセス不可
状況は変わったものの、こちらも calico-kube-controllers
が ContainerCreating で止まってしまう問題です。
Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 3m12s default-scheduler Successfully assigned kube-system/calico-kube-controllers-7bdbfc669-9gltp to controlplane Warning FailedCreatePodSandBox 72s kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox "68070146a6bd3c3a3044cbe84495c39ef3abafd069f171db2a185c8925aee2d1": plugin type="calico" failed (add): error getting ClusterInformation: Get "https://10.96.0.1:443/apis/crd.projectcalico.org/v1/clusterinformations/default": Service Unavailable Normal SandboxChanged 12s (x2 over 72s) kubelet Pod sandbox changed, it will be killed and re-created.
こちらはエラーメッセージの通りなので、Service CIDR を Containerd の NO_PROXY に追加します。
# vim /etc/systemd/system/containerd.service.d/http-proxy.conf
10.96.0.0/12
を追記。
[Service] Environment="HTTP_PROXY=http://172.31.0.1:3128" Environment="HTTPS_PROXY=http://172.31.0.1:3128" Environment="NO_PROXY=localhost,127.0.0.1,172.31.0.0/16,10.96.0.0/12"
先ほどと同じように daemon-reload, restart containerd, Pod の強制削除をします。
まとめ
最後までお読みいただきありがとうございます。
プロキシ環境での Kubernetes クラスター構築は、通常のクラスター構築よりも Kubernetes のネットワーク周りの知識が要求されるので少しハードルが上がります。
冒頭にも書きましたが、まずはインターネットに直接繋がる環境で構築を試してみて、その後にプロキシ環境での構築を実施すると原因の切り分けがスムーズになると思います。
参考文献
- Installing kubernetes behind a corporate proxy
- kubeadmを使用したクラスターの作成
- kubeadmのインストール
- CRIのインストール
- Install Calico networking and network policy for on-premises deployments
Footnotes
-
以前は IP レンジを指定できなかったようですが、今は問題なく使えます。https://github.com/kubernetes/kubeadm/issues/324#issuecomment-331483277 ↩