概要
KubernetesのMasterノードをクラウド上に作り、Workerノードを自宅LAN内にあるLinuxマシンに構築できたので、その方法を紹介。
前回の記事でMasterとWorkerの2ノードを作成して、各ノードのPodにkubectl execコマンドでアクセスできることは確認できたが、Pod間で通信を行うためのCNI(Container Network Interface)の設定は未完了であった。
そこで今回、Pod間のネットワークをつなぐツールの一つであるCalicoを使って前回のやり残し部分を完成させる。
実現したい構成
下図のように、予め定義したIPアドレス範囲(図の例では10.128.0.0/16)でPod間通信できるようにする。ちなみにk8sクラスターをkubeadmで構築する場合、Podで利用するアドレス範囲はkubeadm initコマンドの引数--pod-network-cidrで指定が必要。
前回記事の手順で、既に2つのノードをクラスターに追加済。
$ kubectl get node -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE ...
k8s-master Ready master 8d v1.18.8 20.30.40.50 <none> Ubuntu 18.04.3 LTS ...
k8s-worker Ready <none> 23h v1.18.8 192.168.1.4 <none> Debian GNU/Linux 9 (stretch) ...
k8s-workerマシンのIP192.168.1.4は自宅LAN内のプライベートIPになってしまっているので、自宅外のネットワークからkubectl exec等でWorkerノードのPodにアクセスする場合は、192.168.1.4を60.70.80.90にNATする設定が必要。何でプライベートIPになってしまうのかは、前回記事を参照いただきたい。
(今回Calicoを使ってPod間ネットワークを構築する場合も、WorkerノードのIPがデフォルトではプライベートIPとして認識されてしまい、対処が必要となる。)
Calicoのデプロイ
(1) 開放が必要なポート
以下サイトに記載があるが、
https://docs.projectcalico.org/getting-started/kubernetes/requirements
CalicoのデフォルトではBGP(Border Gateway Protocol)を使ってノードをまだいだPod間通信を実現するようなので、各ノードでポート番号179(TCP)のインバウンド方向の通信を許可する必要あり。自宅LAN側は前回記事と同様に、ルーターのポート開放、およびWorkerノードへのポート転送設定が必要。
(2) マニフェストのダウンロードと設定
ポートが開放できたら、Calicoのマニフェストをダウンロード。
$ wget https://docs.projectcalico.org/manifests/calico.yaml
ダウンロードしたcalico.yamlで、下記の行(3674行目あたり)の#を外して、value:に予め定めたPodのアドレス範囲(本例では10.128.0.0./16)を記入。
(省略)
# - name: CALICO_IPV4POOL_CIDR
# value: "192.168.0.0/16" # -> "10.128.0.0./16"に変更
(省略)
Calicoのリソースを下記コマンドで作成。
$ kubectl apply -f calico.yaml
普通のクラスター構成だったらこれだけやればあっさりとPod間通信できるようになるのだが、今回はネットワーク構成が特殊なために上手く行かない。以下のように、calico-nodeのPodがReadyになってくれない…。
$ kubectl get pod -n kube-system -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
calico-kube-controllers-8586758878-jzdlw 1/1 Running 0 104s 10.128.75.0 k8s-worker <none> <none>
calico-node-79zbk 0/1 Running 0 105s 20.30.40.50 k8s-master <none> <none>
calico-node-n5nqf 0/1 Running 0 105s 192.168.1.4 k8s-worker <none> <none>
coredns-66bff467f8-djn4w 1/1 Running 0 9d 10.128.117.2 k8s-master <none> <none>
coredns-66bff467f8-gf842 1/1 Running 0 9d 10.128.117.3 k8s-master <none> <none>
etcd-k8s-master 1/1 Running 0 9d 20.30.40.50 k8s-master <none> <none>
kube-apiserver-k8s-master 1/1 Running 0 9d 20.30.40.50 k8s-master <none> <none>
kube-controller-manager-k8s-master 1/1 Running 5 9d 20.30.40.50 k8s-master <none> <none>
kube-proxy-p6bwq 1/1 Running 1 2d 192.168.1.4 k8s-worker <none> <none>
kube-proxy-xdtzc 1/1 Running 0 9d 20.30.40.50 k8s-master <none> <none>
kube-scheduler-k8s-master 1/1 Running 5 9d 20.30.40.50 k8s-master <none> <none>
calico-nodeがReadyとならない原因を先に言ってしまうと、Pod間通信を実現するための各ノードのBGPピアのIPアドレスがプライベートIPになっているためである。2つのノードはインターネット経由で通信する必要があり、BGPピアのIPアドレスは公開IPにする必要がある。
今回はCalicoの設定確認や変更が可能な「calicoctl」を使ってこの問題を解決する。
calicoctlのインストール&BGPピアIP設定
まずは、以下サイトのcalicoctlをインストールする。
現時点の最新バージョンはv3.17.1で、以下の手順でcalicoctlを使えるようにする。
$ curl -O -L https://github.com/projectcalico/calicoctl/releases/download/v3.17.1/calicoctl
$ sudo mv calicoctl /usr/local/bin/
$ sudo chown root:root calicoctl
$ sudo chmod a+x calicoctl
設定後、次のようにしてBGPピアのIPアドレスを確認すると、2つのノードともプライベートIPになっていることがわかる。
$ calicoctl get node -o wide
NAME ASN IPV4 IPV6
k8s-master (64512) 10.0.0.4/24
k8s-worker (64512) 192.168.1.4/24
BGPピアのIPの変更は、calicoctl patchコマンドでspec.bgp.ipv4Addressを変更することで実現可能。
$ calicoctl patch node k8s-master -p '{"spec": {"bgp": {"ipv4Address": "20.30.40.50/24"}}}'
$ calicoctl patch node k8s-master -p '{"spec": {"bgp": {"ipv4Address": "60.70.80.90/24"}}}'
しばらく(30秒〜1分程度)待ってCalicoのPodの状態を確認すると、無事にReadyになっている。
$ kubectl get pod -n kube-system -o wide | grep ^calico
calico-kube-controllers-8586758878-jzdlw 1/1 Running 0 33m 10.128.75.0 k8s-worker <none> <none>
calico-node-79zbk 1/1 Running 0 33m 20.30.40.50 k8s-master <none> <none>
calico-node-n5nqf 1/1 Running 0 33m 192.168.1.4 k8s-worker <none> <none>
おわりに
ネットワーク部分を手動で色々と設定してようやく、クラウドサーバーと自宅のマシンでk8sクラスターを構築できたのだが、こんな七面倒臭いことをやらなくてもスマートにつなげられる方法はきっとあるのだと思う。例えばk8sクラスターを作る前に、予めクラウドサーバーと自宅のマシンで「擬似的なプライベートネットワーク」を作り、そのプライベートネットワーク内でMasterノード、Workerノードを追加していけばすんなり作れるはず。
自分自身、BGPあたりの知識が浅いので(名前は知っていたが、今回構築してみて初めて機能の一部を知ることができた)、その辺を勉強していけばもう少し可能性は見えてくるのかも。
