複数NICを持つノードで、特定NICを使ってk8sクラスタを構成する
この記事は何?
下図のように、各マシンで2つのNIC(eth0
とeth1
)が使用されているケースを考えます。
(node0
の3つめのNICeth2
には実験用機器がありますが、この記事には関係ない…はずでした)
普段インターネットへの接続等に使用しているのはeth0
の先の赤色のネットワーク。でもkubernetesのノード間通信には、eth1
の先の紫色のネットワークを使ってほしく、各ノードのIPもeth1
のものであってほしいとします。
(状況としては、紫のネットワークが赤より高速な場合など)
この要件を満たしたkubernetesクラスタを構築しようとしたものの、意外とハマったので備忘録を残します。
前提条件
- 各ノード、各NICのIPは固定済、
10.0.0.0/24
のIPレンジで紫色のネットワークに到達するよう、ルーティングも行っていること。 - 全てのノードでkubeadmのインストールに従い
-
kubeadm
、kubelet
、kubectl
がインストールされていること (バージョンは1.16.15-00
を使用) - ファイアウォール(
UFW
)が適切に設定済みであること
-
- (決め事)
node0
をマスターノード、node1
をワーカーノードとする、シングルコントロールプレーンクラスタを構築する - (決め事) CNIプラグインには
calico
を使用する
普通にクラスタ構築し、問題発生するまで
公式ドキュメントを参考に、クラスタ構築を進めます。
# 初期化
# (心の声) --apiserver-advertise-addressをnode0のeth1のIPにしたから、あとはいい感じに紫色ネットワーク使ってくれるよね
# kubectl join用の認証情報はメモっておく
sudo kubeadm init --control-plane-endpoint=10.0.0.100:6443 \
--apiserver-advertise-address=10.0.0.100 \
--pod-network-cidr=10.1.0.0/16
# kubectl で操作できるように
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
# calico インストール
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
# masterノードでもpodを動かせるように
kubectl taint nodes --all node-role.kubernetes.io/master-
# node1をクラスタに追加
# **node1で下記を実行**
node1> sudo kubeadm join 10.0.0.100:6443 --token <token> \
--discovery-token-ca-cert-hash sha256:<hash>
これでクラスタ構築はおしまい。kubectl init
時に--apiserver-advertise-address
をnode0のeth1のIPにしたから、あとはいい感じに紫色ネットワーク使ってくれるよね、と思っていました。
あとはkubernetes-dashboard
入れて、他にもアプリケーションデプロイ…と色々設定進めていたところ、問題に気づきました
問題の発覚
kubernetes-dashboard
アクセス時にネットワークエラー発生(失念しましたが、503 Bad Gateway
だったかな...?)。
更に調査をすすめると、ノード間の通信が成立していなさそうな雰囲気。
もしやと思って、ノードIPを下記で取得
# -o wide オプションを付けないと、ノードIPは表示されない
> kubectl get node -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP (略)
node0 Ready master 12m v1.16.15 172.16.0.4 (略)
node1 Ready <none> 5m v1.16.15 192.168.1.21 (略)
INTERNAL-IP
が想定と違う。
node0
は、全然関係ないはずの実験用機器向けのIPを、node1
は赤色ネットワークのIPを使っていた。
対処
色々試したところ、下記2つの施策により、
- ノード(の
INTERNAL-IP
)をeth1
のアドレスにする -
eth1
の紫色ネットワークでpod間通信を行う
を実現出来ました
INTERNAL-IP
の変更
1.ノードこちらの記事を参考に、kubecel
起動時の引数を変更してINTERNAL-IP
を変更(明示的に指定)します
# kubeletのservice設定ファイルを編集
sudo vim /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
設定ファイル内のEnvironment
変数(の中のKUBELET_CONFIG_ARGS
)を下記のように変更します
# 変更前
Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml"
# 変更後
Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml --node-ip=10.0.0.100"
## node1の場合、10.0.0.101
変更後は下記でサービスを再起動します
sudo systemctl daemon-reload
sudo systemctl restart kubelet
INTERNAL-IP
が適切に変更されていることを確認します
> kubectl get node -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP (略)
node0 Ready master 17m v1.16.15 10.0.0.100 (略)
node1 Ready <none> 12m v1.16.15 10.0.0.101 (略)
2.calicoのBGP Networking設定変更
こちらのドキュメントを参考に、calicoのルーティング設定を変更します。
kubectl set env daemonset/calico-node -n kube-system IP_AUTODETECTION_METHOD=interface=eth1
これで、紫色ネットワークを使用してルーティングを行ってくれます。
所感
(自前でのクラスタ運用、やっぱ面倒…マネージド使いたい)
Discussion