はじめに
Oracle Cloud Infrastructure Container Engine for Kubernetes(以下OKE)でarm64アーキテクチャのワーカーノードを利用して作成したクラスタでistioを利用しようとしたところ、sidecarのinitコンテナがエラーになってしまいpodが起動できませんでした。原因と実施した対応を残したいと思います。
利用環境
- OKEを利用して作成したマネージドのクラスター
- インスタンスのシェイプはVM.Standard.A1.Flex
※(数バージョン前までistioはarm64をサポートしていませんでしたので)arm64なのが悪いのかと思いamd64なシェイプを選択してノードに追加してみましたが同様のエラーとなりました。 - ワーカーのイメージはOracle-Linux-8.7-aarch64-2023.01.31-3-OKE-1.25.4-549を利用
※ OKEワーカーノードイメージでなく、プラットフォームイメージ(Oracle-Linux-8.7-aarch64-2023.02.28-1)を利用した場合でも同様のエラーとなりました。 - kubernetesのバージョンはv1.25.4
- istioctl(1.17.2)を利用してistioをインストール
発生した状態
namespaceに対してistio-injection=enabledのラベルを付与してsidecarのinjectionを有効にしたところ、podがInit:CrashLoopBackOffの状態になっていました。
kubectl logs my-podname -c istio-init
を実行しログを確認したところ以下のようになっていました。
(省略)
2023-04-15T02:33:07.240933Z info Running command: iptables-restore --noflush /tmp/iptables-rules-1681525987240733799.txt650228252
2023-04-15T02:33:07.245568Z error Command error output: xtables parameter problem: iptables-restore: unable to initialize table 'nat'
Error occurred at line: 1
Try `iptables-restore -h' or 'iptables-restore --help' for more information.
2023-04-15T02:33:07.245590Z error Failed to execute: iptables-restore --noflush /tmp/iptables-rules-1681525987240733799.txt650228252, exit status 2
なにやらenvoy-proxy用のiptablesの設定実行が失敗しているようです。
原因
OKEが自動構築したワーカーノードで必要なカーネルモジュールが読み込まれていないためでした。
lsmodした結果は以下の状態でした。
Module Size Used by
xt_nat 16384 2
xt_addrtype 16384 10
ipt_REJECT 16384 54
nf_reject_ipv4 20480 1 ipt_REJECT
ip6table_filter 16384 1
ip6table_mangle 16384 1
ip6table_nat 16384 1
ip6_tables 40960 3 ip6table_filter,ip6table_nat,ip6table_mangle
ip_set 65536 0
ip_vs_sh 20480 0
ip_vs_wrr 20480 0
ip_vs_rr 20480 0
ip_vs 229376 6 ip_vs_rr,ip_vs_sh,ip_vs_wrr
xt_MASQUERADE 20480 3
xt_mark 16384 15
xt_conntrack 16384 19
xt_comment 16384 102
nft_compat 20480 235
nft_counter 16384 97
nft_chain_nat 16384 8
nf_nat 61440 4 ip6table_nat,xt_nat,nft_chain_nat,xt_MASQUERADE
nf_conntrack 221184 5 xt_conntrack,nf_nat,xt_nat,xt_MASQUERADE,ip_vs
nf_defrag_ipv6 28672 2 nf_conntrack,ip_vs
nf_defrag_ipv4 16384 1 nf_conntrack
overlay 196608 10
rfkill 45056 1
cuse 20480 1
vfat 28672 1
fat 110592 1 vfat
aes_ce_blk 45056 0
crypto_simd 28672 1 aes_ce_blk
cryptd 32768 1 crypto_simd
virtio_gpu 90112 0
aes_ce_cipher 20480 1 aes_ce_blk
crct10dif_ce 20480 1
virtio_dma_buf 16384 1 virtio_gpu
ghash_ce 28672 0
sha1_ce 20480 0
drm_kms_helper 372736 3 virtio_gpu
cec 69632 1 drm_kms_helper
drm 811008 3 drm_kms_helper,virtio_gpu
joydev 36864 0
fb_sys_fops 20480 1 drm_kms_helper
syscopyarea 16384 1 drm_kms_helper
sysfillrect 16384 1 drm_kms_helper
sysimgblt 16384 1 drm_kms_helper
button 24576 0
sch_fq_codel 28672 1
fuse 184320 2 cuse
br_netfilter 32768 0
xfs 2199552 3
iscsi_tcp 32768 0
libiscsi_tcp 40960 1 iscsi_tcp
libiscsi 98304 2 libiscsi_tcp,iscsi_tcp
nvme_tcp 57344 0
nvme_fabrics 40960 1 nvme_tcp
nvme 61440 0
nvme_core 180224 3 nvme_tcp,nvme,nvme_fabrics
dm_multipath 53248 0
sha2_ce 24576 0
virtio_net 69632 0
virtio_scsi 32768 3
net_failover 24576 1 virtio_net
failover 20480 1 net_failover
sha256_arm64 32768 1 sha2_ce
qemu_fw_cfg 28672 0
virtio_pci 32768 0
virtio_pci_legacy_dev 16384 1 virtio_pci
virtio_pci_modern_dev 24576 1 virtio_pci
sunrpc 794624 1
scsi_transport_iscsi 188416 4 libiscsi_tcp,iscsi_tcp,libiscsi
以下のistioのドキュメントに必要となるカーネルモジュールの一覧が記載されています。
https://istio.io/latest/docs/ops/deployment/platform-requirements/
仮対応
ワーカーノードのipアドレスを確認しsshします。
以下を実行しカーネルモジュールを読み込ませます。
sudo modprobe -a br_netfilter ip6table_mangle ip6table_nat ip6table_raw iptable_mangle iptable_nat iptable_raw xt_REDIRECT xt_connmark xt_conntrack xt_mark xt_owner xt_tcpudp bridge ip6_tables ip_tables nf_conntrack nf_conntrack_ipv4 nf_conntrack_ipv6 nf_nat nf_nat_ipv4 nf_nat_ipv6 nf_nat_redirect x_tables
これでistio-initのiptables実行が成功するようになりpodにsidecarがinjectされて正常に上がった状態になりました。
しかしこれではワーカーノードが再起動した場合にカーネルモジュールの読み込み設定が揮発してしまいますので、その対応をしたいと思います。
※一部のものがないと言われましたが、存在するものだけ対応するだけでもとりあえずsidecarのinitは動くようにはなったのでひとまず以下のものは無視して進めることとします。
modprobe: module 'xt_tcpudp' not found
modprobe: module 'bridge' not found
modprobe: module 'nf_conntrack_ipv4' not found
modprobe: module 'nf_conntrack_ipv6' not found
modprobe: module 'nf_nat_ipv4' not found
modprobe: module 'nf_nat_ipv6' not found
modprobe: module 'nf_nat_redirect' not found
modprobe: module 'x_tables' not found
恒久対応1
ワーカーノードのipアドレスを確認しsshします。
以下を実行し、起動時にカーネルモジュールの読み込みを自動で行うように設定します。
echo "br_netfilter
ip6table_mangle
ip6table_nat
ip6table_raw
iptable_mangle
iptable_nat
iptable_raw
xt_REDIRECT
xt_connmark
xt_conntrack
xt_mark
xt_owner
ip6_tables
ip_tables
nf_conntrack
nf_nat" | sudo tee /etc/modules-load.d/istio.conf
ワーカーをrebootして確認しましたが、必要なカーネルモジュールが自動で読み込まれていることが確認できました。(lsmodで確認できます。)
この対応でもいいのですが、ワーカーをスケールして増やしたり再構築した際に毎回手動でsshして、この設定して回るのは面倒です。そもそもマネージドで作成されたワーカーに対して直接sshして設定をいじくり回すのもなにか違う気がします。
そこでkubenetes側から自動で何とかする方法を考えることにしました。
恒久対応2
以下をkubernetesにデプロイし、特権状態のpodからホストのワーカーにカーネルモジュールを読み込ませる設定をすることにしました。DaemonSetなので各ノードにPodを一つずつ配置してくれますので、新規にワーカーが増えた場合でも自動で設定してくれます。ワーカー再起動時もpodが再作成される手続きの中で設定が行われます。(/etc/modules-load.d/istio.confに設定を書き込む処理を入れても良いのですが、読み込まれるし良いかと思いmodprobeだけを実行しています。)
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: modprobe-istio
namespace: kube-system
spec:
selector:
matchLabels:
app: modprobe-istio
template:
metadata:
labels:
app: modprobe-istio
spec:
containers:
- name: modprobe-istio-sleeper
image: busybox:1.36
command: ['sh', '-c', 'echo I keep pod running! && sleep 3600']
initContainers:
- name: modprobe-istio-init
image: busybox:1.36
securityContext:
privileged: true
command: ['sh', '-c', 'echo br_netfilter ip6table_mangle ip6table_nat ip6table_raw iptable_mangle iptable_nat iptable_raw xt_REDIRECT xt_connmark xt_conntrack xt_mark xt_owner ip6_tables ip_tables nf_nat | xargs -n 1 modprobe']
volumeMounts:
- name: lib-modules
mountPath: /lib/modules
volumes:
- name: lib-modules
hostPath:
path: /lib/modules
さいごに
以上の方法で対応を行い問題を解決できましたが、マネージドkubernetesならistioくらい入れれば動く状態にしておいて欲しいものです。
OCIのドキュメントにもOKEにistioを導入する記載があるくらいなので( https://docs.oracle.com/ja-jp/iaas/Content/ContEng/Tasks/contengistio-intro-topic.htm )Oracleさん的にもこんな手続きが必要な想定ではなさそうで一時的な問題なのかもしれません。そのうちOracleさんがOKEのワーカー作成処理を直してくれることに期待したいと思います。