Kubernetes(正確にはクラスタネットワーク)はデフォルト設定はIPv4のアドレスのみを利用するようです。 とある案件で必要になったため、KubernetesのIPv6周りを調べることにしました。 今回の内容は3回に分けてブログにしようと思います。
内容
- KubernetesクラスターでIPv4/IPv6 Dual-stackサポートを有効にする(←今回の内容)
- IPv6チェック用のイメージを作成する
- IPv4/IPv6でサービスを動かすコンテナイメージを使ってKubernetesで実行
要件
今回は手元の環境の次の構成でテストしました。
Ubuntu Server 22.04 LTS
- Kubernetes 1.25.0
- CRI: containerd 1.5.9
- CNI: Calico
- IPv4/IPv6 Dual-stack
Fedora 36
- Kubernetes 1.25.0
- CRI: CRI-O 1.24
- CNI: Calico
- IPv4/IPv6 Dual-stack
kubeadmで構築するKubernetesのデフォルト構成ではIPv4アドレスがデフォルトで使われます(実際はCNIプラグインの実装、設定も絡む)。今回のような方法でIPv4/IPv6 Dual-stackなクラスターとしてセットアップできます。
ちなみに、IPv6 Onlyについてはやり方はあるようですが、IPv6 Onlyのクラスターの実用上はどうかと言われると微妙なのかなと思います。
kubeadmによるクラスタ作成
- https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/dual-stack-support/
- https://projectcalico.docs.tigera.io/getting-started/kubernetes/quickstart
- https://projectcalico.docs.tigera.io/networking/ipv6
IPアドレスを確認します。
$ ip addr show enp0s6 inet 192.168.205.111/24 brd 192.168.205.255 scope global dynamic noprefixroute enp0s6 valid_lft 85665sec preferred_lft 85665sec inet6 fd7e:8daa:f56:3f94:ac5e:d2ff:fe71:ee0e/64 scope global dynamic noprefixroute valid_lft 2591996sec preferred_lft 604796sec inet6 fe80::ac5e:d2ff:fe71:ee0e/64 scope link noprefixroute valid_lft forever preferred_lft forever
自宅環境ではIPv6アドレスをインターネットアクセスでは使っていない(インターネットサービスがIPv6を提供していない)ため、以下ではすべてリンクローカルユニキャストアドレスを使っています。この手順に従いIPv4/IPv6 DualStackなKubernetesクラスターを構築できますが、結局IPv6経由でインターネット側に出られない格好になるので、ご注意ください(IPv6 Readyなネットワークにいればグローバルユニキャストアドレスが割り振られているはずですから、それを使えばテストできるでしょう)。
hostsに調べたアドレスをそれぞれ書いておきます(当然ながら本番ではDNSで名前解決できるように設定します)。
$ sudo vi /etc/hosts ... 192.168.205.111 k8s.example.com fd7e:8daa:f56:3f94:ac5e:d2ff:fe71:ee0e k8s.example.com
OS、コンテナランタイムの設定、kubeadm,kubeletツールのインストールと設定は通常通り実施します。 Firewallでポートが閉じられている場合は、最低限次のポートは開放する必要があります。
- 6443/tcp
- 10250/tcp
- 30000-32767/tcp
クラスターの作成はCreating a cluster with kubeadmに従って、CIDRをIPv4とIPv6のアドレスを指定します。
control-plane-endpointは今回はhostsに書いたIPv4/IPv6アドレスの関連付けしたドメインを記述します。
$ sudo kubeadm init --pod-network-cidr=10.244.0.0/16,2001:db8:42:0::/56 --service-cidr=10.96.0.0/16,2001:db8:42:1::/112 --control-plane-endpoint=k8s.example.com
Calicoをインストール
Quickstart for Calico on Kubernetesを開いて、それぞれダウンロードします。カスタムリソースの方はダウンロードしたあと、IPv6周りの設定の追記をします。
執筆日(2022年9月6日)時点では3.24.1が最新の安定版のようです。
$ wget https://raw.githubusercontent.com/projectcalico/calico/v3.24.1/manifests/tigera-operator.yaml $ wget https://raw.githubusercontent.com/projectcalico/calico/v3.24.1/manifests/custom-resources.yaml
custom-resources.yamlの変更内容
IPv4のCIDRのレンジの修正とIPv6のCIDRの追記を行います。記述するのはkubeadm init
で指定したものを記述します。
IPv4のCIDRはデフォルトが「192.168.0.0/16」が設定されているため、同様に指定したCIDRに書き換えます。
それ以外の部分は触らずにエディタを終了します。
$ cat custom-resources.yaml # This section includes base Calico installation configuration. # For more information, see: https://projectcalico.docs.tigera.io/master/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: 10.244.0.0/16 encapsulation: VXLANCrossSubnet natOutgoing: Enabled nodeSelector: all() - blockSize: 122 cidr: 2001:db8:42:0::/56 encapsulation: None natOutgoing: Enabled nodeSelector: all() --- # This section configures the Calico API server. # For more information, see: https://projectcalico.docs.tigera.io/master/reference/installation/api#operator.tigera.io/v1.APIServer apiVersion: operator.tigera.io/v1 kind: APIServer metadata: name: default spec: {}
設定をクラスターに適用します。
$ kubectl create -f tigera-operator.yaml $ kubectl create -f custom-resources.yaml
動作確認
自宅はIPv6 Readyではないので、VMでLinuxを動かしてホストのIPv6アドレスはユニキャストアドレスを使っています。クラスターに割り当てているIPv6アドレスは実行例そのままです(ちなみに2022年中に新たにIPv6サービスを提供するとか聞いているので楽しみだったりします)。
ノードにPod CIDRとして、IPv4とIPv6レンジが設定されているのを確認します。
$ kubectl get node fedora -o go-template --template='{{range .spec.podCIDRs}}{{printf "%s\n" .}}{{end}}' 10.244.0.0/24 2001:db8:42::/64
試しにPodを作成します。
$ cat testpod.yaml apiVersion: v1 kind: Pod metadata: name: hello-rhubi9 spec: containers: - name: ubi9 image: docker.io/redhat/ubi9:latest tty: true $ kubectl create -f testpod.yaml
作成したPodにもIPv4とIPv6のアドレスが割り当てられます。
$ kubectl get -f testpod.yaml -o go-template --template='{{range .status.podIPs}}{{printf "%s\n" .ip}}{{end}}' 10.244.78.142 2001:db8:42:c5:45e3:dcb6:dab7:e24d
とりあえず、Podを作成すると、PodにIPv4とIPv6のアドレスが割り当てられました。 今回はここまでです。次回に続きます。