22/07/24 : Calicoのv3.23.3での設定手順に従って記事を更新
概要
複数のノード(マシン)でKubernetesによるコンテナオーケストレーションをする際に、異なるノードに配置されたPodをつなぐためのネットワーク構築が必要となる。Pod間のネットワークを構築するツールはFlannelをはじめとして多くあるが、今回Calicoを使ってみたら結構便利だったのでご紹介する。
例えばVirtualBoxのVMがノードに含まれていたりすると、ネットワークインターフェースが特殊なために、マニュアルや書籍に書かれている通りにやっても上手く行かないことが多い。Flannelのサンプルyamlファイルを適切に修正することでホストOSのネットワークが複雑な場合でも対応はできるのだが、ネットワークインターフェース名を追記したり、ノードにラベルをつけてラベル毎の条件をマニフェストに反映したりする必要がある。マニフェストの書き方に関する知識もそれなりに必要で、一年ほど前にKubernetes初心者だった筆者はかなり手こずった…。
しかし改めて同じことをCalicoでやってみたら、サンプルのマニフェストを2行ほど修正するだけで、Pod間通信をあっさりと実現できたので、ここで共有する。
※といいつつも補足すると、Flannelの設定で苦労したのは2019年頃の話。現状のFlannelのドキュメント(下記)を見ると、Calicoと同じ感じで設定しやすくなっている可能性が高い。
動作確認バージョン
- Kubernetes : v1.24.3
- Calico : v3.23.3
試した構成
下図のように、WindowsのVirtualBox上にLinuxの仮想マシンをインストールしており、ブリッジ接続でVirtualBoxの外のネットワークからも直接アクセス可能な状態になっている。さらにもう一つ、同じネットワーク上にLinuxOSのPCが繋がっている状態。
上の構成において、VirtualBoxのLinux仮想マシンとLinuxPCにそれぞれKubernetesをインストールして、MasterノードとWorkerノード、およびPod間ネットワークが下図の状態になるようにしたい。
ちなみにVirtualBoxのLinux仮想マシンについては、ネットワークインターフェースが下記のように複数あり、後でノードのネットワークを構築する際に注意が必要。
$ ip a
...
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> ...
...
inet 10.0.2.15/24 brd 10.0.2.255 ...
...
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> ...
...
inet 192.168.1.3/24 brd 192.168.1.255 ...
...
必要なツール
-
Docker等のコンテナ構築ツール
-
kubeadm(Kubernetes環境を簡単に構築するためのツール)
- 基本的には公式サイトの手順にしたがってインストールすればOK。
- ただしVirtualBoxの仮想マシンに関しては、何も設定しないとKubernetesのノードをeth0のIPアドレス(10.0.2.15/24)と関連づけてしまうので、
/etc/default/kubelet
(CentOS、RHEL、Fedoraでは/etc/sysconfig/kubelet
)を作成して、下記のようにeth1のIPアドレス(192.168.1.3/24)をノードIPとするように指定する必要あり。今回に限らず、ネットワークインターフェースが複数あるマシンには意図しないIPアドレスにノードが紐付けられてしまう可能性があるので(おそらく優先順位が最も高いネットワークのIPとなる?)、念のため以下を設定していた方が良いはず。
/etc/default/kubeletKUBELET_EXTRA_ARGS=--node-ip=192.168.1.3
Kubernetesノードの作成
-
マスターノード(VirtualBoxの仮想マシン)で
kubeadm init
コマンドを実行- 引数にPod間ネットワークのサブネット
192.168.2.0/24
が必要(今回の構成例での設定値であり、各ネットワーク構成に応じて任意の値を指定可能)。また、KubernetesのAPIサーバのアドレスとして192.168.1.3
(VirtualBoxの仮想マシンのIPアドレス)を指定する必要があることに注意。
$ sudo kubeadm init \ --pod-network-cidr=192.168.2.0/24 \ --apiserver-advertise-address=192.168.1.3
- 最後に下記のようなメッセージが出てきたら成功
... 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.1.3:6443 --token xxxxxxxx... \ --discovery-token-ca-cert-hash sha256:yyyyyyyy...
- 出力結果にも書かれているように、下記コマンドで設定ファイルをユーザディレクトリにコピーして、Kubernetesのクラスターにユーザ権限でアクセスできるようにする。
$ mkdir -p $HOME/.kube $ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config $ sudo chown $(id -u):$(id -g) $HOME/.kube/config
- 余談だが、マスターノードにもPodなどのリソースを作れるようにするには、下記コマンドで
master:NoSchedule
のtaint(痕跡?)を外してあげる必要あり。
$ kubectl taint nodes $(hostname) node-role.kubernetes.io/master:NoSchedule-
- 引数にPod間ネットワークのサブネット
-
ワーカーノード(LinuxOSの物理マシン)で
kubeadm join
コマンドを実行- マスターノードで
kubeadm join
した時に出力されたコマンドを素直に実行する。
$ sudo kubeadm join 192.168.1.3:6443 --token xxxxxxxx... \ --discovery-token-ca-cert-hash sha256:yyyyyyyy...
- マスターノード(VirtualBoxの仮想マシン)で、以下のように2つのノードが表示されたらOK(以下の出力は全設定が既に完了してから出力したものなので、実際にこの時点で確認したらSTATUSがReadyにはなっていなかったかも…)
$ kubectl get node NAME STATUS ROLES AGE VERSION virtualbox Ready master 3d1h v1.24.3 linux-pc Ready <none> 3d1h v1.24.3
- マスターノードで
Calicoをデプロイ
ようやく本題のCalicoの話。
下記サイトの「Install Calico」の手順に従って進めていく。
まずは以下のコマンドで、Calicoのオペレーターやカスタム定義をインストールする。
$ kubectl create -f https://projectcalico.docs.tigera.io/manifests/tigera-operator.yaml
続いて、Calicoのリソースをデプロイするためのマニフェストをダウンロード
$ wget https://projectcalico.docs.tigera.io/manifests/custom-resources.yaml
ダウンロードしたcustom-resources.yaml
で、spec.calicoNetwork.ipPoolsのパラメータの一つ、cidr:
を192.168.2.0/24
(kubeadm init
で指定した引数--pod-network-cidr
と同じもの)に変更。(公式サイトの手順の場合、PodネットワークのCIDRが192.168.0.0/16
であることが前提になっているので注意!)
# This section includes base Calico installation configuration.
# For more information, see: https://projectcalico.docs.tigera.io/v3.23/reference/installation/api#operator.tigera.io/v1.Installation
apiVersion: operator.tigera.io/v1
kind: Installation
metadata:
name: default
spec:
# Configures Calico networking.
calicoNetwork:
# Note: The ipPools section cannot be modified post-install.
ipPools:
- blockSize: 26
cidr: 192.168.0.0/16 # ここを「192.168.2.0/24」に変更!
encapsulation: VXLANCrossSubnet
natOutgoing: Enabled
nodeSelector: all()
...
Calicoのリソースを下記コマンドで作成
$ kubectl apply -f custom-resources.yaml
数分程度待って、Calicoのリソースが動いていることを確認。新たなネームスペースcalico-systemにPodがデプロイされる。
$ kubectl get pod -n calico-system -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
calico-kube-controllers-657d56796-d5mgd 1/1 Running 0 15m 192.168.2.197 linux-pc <none> <none>
calico-node-5nk2v 1/1 Running 0 15m 192.168.1.2 linux-pc <none> <none>
calico-node-9zx4f 1/1 Running 0 15m 192.168.1.3 virtualbox <none> <none>
calico-typha-5fb5c59b98-pwdl2 1/1 Running 0 15m 192.168.1.3 linux-pc <none> <none>
念のため、kube-systemのPodの動作状況も確認
$ kubectl get pods -n kube-system -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
coredns-f9fd979d6-7rrvh 1/1 Running 0 22m 192.168.2.2 linux-pc <none> <none>
coredns-f9fd979d6-tlb82 1/1 Running 0 22m 192.168.2.3 linux-pc <none> <none>
etcd-kube-master 1/1 Running 0 22m 192.168.1.3 virtualbox <none> <none>
kube-apiserver-virtualbox 1/1 Running 0 22m 192.168.1.3 virtualbox <none> <none>
kube-controller-manager-virtualbox 1/1 Running 0 22m 192.168.1.3 virtualbox <none> <none>
kube-proxy-dtcsk 1/1 Running 0 19m 192.168.1.4 linux-pc <none> <none>
kube-proxy-htk75 1/1 Running 0 22m 192.168.1.3 virtualbox <none> <none>
kube-scheduler-virtualbox 1/1 Running 0 22m 192.168.1.3 virtualbox <none> <none>
Pod間ネットワークの疎通確認
試しに、nginxのコンテナをレプリカ3の冗長構成で動かしてみる
$ kubectl create deployment nginx --image=nginx --replicas=3
起動後しばらくして確認すると、事前に定義したPodネットワーク192.168.2.0/24
内で動いていることを確認
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-6799fc88d8-8jjl9 1/1 Running 0 11s 192.168.2.194 virtualbox <none> <none>
nginx-6799fc88d8-fzg2h 1/1 Running 0 11s 192.168.2.131 linux-pc <none> <none>
nginx-6799fc88d8-kj44h 1/1 Running 0 11s 192.168.2.132 linux-pc <none> <none>
あるPodからcurlを実行し、他のPodのwebサーバにアクセスできることを確認!
$ kubectl exec nginx-6799fc88d8-8jjl9 -- curl 192.168.2.131
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
(以後の出力省略)