IPv4/IPv6 Dual stack な Kubernetes 1.26 クラスターを kubeadm で作った
kubeadm で Kubernetes クラスターを作るための下準備を Ansible でまとめてみた の続きです。
kubeadm のコンフィグを用意する
Dual-stack support with kubeadm のドキュメントの流れに従ってシンプルにやってみました。
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
networking:
podSubnet: 172.24.0.0/16,fd8e:a2c3:ca45::/64
serviceSubnet: 172.25.0.0/16,fd8e:a2c3:ca45:feed::/112
IPv6 のアドレス空間は ULA Prefix を IPv6のUnique Local Addressを生成する のページの手順に従って実際のネットワークインターフェースの MAC アドレスから生成したものを使っています。
serviceSubnet
の CIDR はホストアドレス部が 20 bit が上限になるので注意して下さい。(コンフィグ例だと IPv4 も IPv6 もどっちも 16 bit になるように揃えています)
また IPv6 Only stack だと API Endpoint も IPv6 に揃えたりしてますが、Dual stack で既存のツール群が IPv4 前提だったりするものが多いので、いったんはデフォルトの IPv4 アドレスを使い回しするような感じにしてます。
kubeadm init でコントロールプレーンを起動する
先ほど作製したコンフィグファイルを元に kubeadm でクラスターを初期化します。
$ sudo kubeadm init --config kubeadm-config.yaml
クラスターの初期化が終わったら表示されるメッセージに従って .kube/config を設定しておきます。
$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config
Calico をデプロイする
CNI として Calico をデプロイします。Flannel 等もありますが、自分が慣れているので。。。
まずは Calico の Manifest をダウンロードしてきます。
$ curl -O https://raw.githubusercontent.com/projectcalico/calico/v3.24.5/manifests/calico.yaml
次に Dual stack にするために IPv6 関連の設定を追記しています。
ref. Configure dual stack or IPv6 only
--- calico.yaml.orig 2023-01-05 08:32:04.773243390 +0000
+++ calico.yaml 2023-01-05 11:02:01.860067201 +0000
@@ -62,7 +62,9 @@
"nodename": "__KUBERNETES_NODE_NAME__",
"mtu": __CNI_MTU__,
"ipam": {
- "type": "calico-ipam"
+ "type": "calico-ipam",
+ "assign_ipv4": "true",
+ "assign_ipv6": "true"
},
"policy": {
"type": "k8s"
@@ -4518,6 +4520,14 @@
# Auto-detect the BGP IP address.
- name: IP
value: "autodetect"
+ - name: IP_AUTODETECTION_METHOD
+ value: "cidr=192.168.XXX.0/24"
+ - name: IP6
+ value: "autodetect"
+ - name: IP6_AUTODETECTION_METHOD
+ value: "cidr=XXXX:XXX:XXXX:XXXX::/64"
+ - name: CALICO_IPV6POOL_NAT_OUTGOING
+ value: "true"
# Enable IPIP
- name: CALICO_IPV4POOL_IPIP
value: "Always"
@@ -4558,7 +4568,7 @@
value: "ACCEPT"
# Disable IPv6 on Kubernetes.
- name: FELIX_IPV6SUPPORT
- value: "false"
+ value: "true"
- name: FELIX_HEALTHENABLED
value: "true"
securityContext:
重要なのは CALICO_IPV6POOL_NAT_OUTGOING = true
です。この設定がないと Pod が持っている IPv6 アドレスのまま外向き通信 (Egress) が流れてしまって BGP でルーティング可能でないネットワークの場合は通信に失敗します。そのため、この NAT 設定をすることでホストが持っている IPv6 アドレスでクラスターの外に出て行くようになります。
ファイルを保存したあとに kubectl で Calico をデプロイしていきます。
$ kubectl apply -f calico.yaml
ワーカーノードを参加させる
ワーカーノードの参加用コマンドは kubeadm コマンドの実行後のメッセージも表示されていますが時間が経ったりしたときは以下のようにして再表示することが出来ます。
$ kubeadm token create --print-join-command
Pod に IPv4 だけでなく IPv6 のアドレスが付いたことを確認する
試しに Ubuntu コンテナを作ってみます。
apiVersion: v1
kind: Pod
metadata:
name: ubuntu
spec:
containers:
- name: ubuntu
image: ubuntu
command: [ 'sleep', 'infinity' ]
$ kubectl apply -f ubuntu.yml
$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ubuntu 1/1 Running 0 60m 172.24.2.130 dsk8snode1 <none> <none>
$ kubectl get pod ubuntu -o json | jq .status.podIPs
[
{
"ip": "172.24.2.130"
},
{
"ip": "fd8e:a2c3:ca45:0:f4ee:f9a1:1545:9a41"
}
]
ちゃんと IPv4 + IPv6 のアドレスが付与されています。
試しに Pod の中に入って外向き通信をテストしてみます。
$ kubectl exec -it ubuntu -- bash
root@ubuntu:/# curl -4 ifconfig.io
XX.XX.93.205
root@ubuntu:/# curl -6 ifconfig.io
XXXX:XXX:XXXX:XXXX:215:5dff:fe01:ed05
ちゃんと Internet と IPv4 + IPv6 で通信できています。ヽ(^。^)丿
Discussion