目的
- kube-apiserverトラブルシュート手順を整理する
手段
- killercoda 環境で手を動かす
トラブルシュート手順
- ログ調査
- /var/log/pods
- /var/log/containers
- crictl ps + crictl logs
- kubelet logs: /var/log/syslog or journalctl
kube-system_calico-kube-controllers-94fb6bc47-4wx95_882bd272-cd0e-4a50-be8c-e9d6e6007e0d
kube-system_canal-b9w57_361028af-6efa-4805-8d6e-aa7100a9ed71
kube-system_coredns-57888bfdc7-g2dbp_9eee60a1-16b2-4cf2-b4fc-cbcdd291773a
kube-system_coredns-57888bfdc7-nms5t_fdfbf480-f3c8-4734-aaf1-9ae6a2d4b02a
kube-system_etcd-controlplane_4fb3015641784f175e793600c1e22e8c
kube-system_kube-apiserver-controlplane_53ebb29699412c968f4d993ced098d57
kube-system_kube-controller-manager-controlplane_a55d9c391dc5f492555b54cdef44652d
kube-system_kube-proxy-sqc72_36d52577-5a97-4750-9479-e9b6d562142a
kube-system_kube-scheduler-controlplane_0cfa7f19a2c8cf4c1add14122593c823
local-path-storage_local-path-provisioner-6c5cff8948-tmf26_66648569-53fa-488e-943c-1f910c0a09e1
# pod 単位でフォルダが存在する
# kube-apiserver フォルダ内のログを確認する。
# 連続出力しているログ、ERROR、STDERROR あたりを grep
calico-kube-controllers-94fb6bc47-4wx95_kube-system_calico-kube-controllers-cbe49e7bbba2e58678e8d60741997354b4fe95da7f4920c4c2620a5875eacea4.log
calico-kube-controllers-94fb6bc47-4wx95_kube-system_calico-kube-controllers-e0a02f0388b8ba7fe9e1bb7bd24c3fbf341497910ce8a56d61aac84af4098c57.log
canal-b9w57_kube-system_calico-node-94afbc4803c29d28e0dde526297af5b63af4d56b5e017ee372717e3b06dd948b.log
canal-b9w57_kube-system_calico-node-d6e06f3a5672258d08545021e9b21b5d797a14b8cc2a22d5f7f14082048b9822.log
canal-b9w57_kube-system_install-cni-81d8ac98e91144291a3e7b2ff5bd8c9125d6b68fb07a184c1c2493feb18a2138.log
canal-b9w57_kube-system_kube-flannel-7fc352d07387c79f0718c9c0863796d8454a4924d3f55834fbd3889c88ba7d23.log
canal-b9w57_kube-system_kube-flannel-f67a491d23bf0662734963a1b1228be947c37d2574b40fa52b9dd0fd5e50b085.log
canal-b9w57_kube-system_mount-bpffs-c6268539785280596b658229fae4bdac6ec59175489a9a48ac450f5fd137418c.log
coredns-57888bfdc7-g2dbp_kube-system_coredns-69d2530a1916831ba78ab07e2b5d1d5aaa4652c2e5efe56b1d408f03d959be4b.log
coredns-57888bfdc7-g2dbp_kube-system_coredns-e47e13162d0cdddabedddaf1a138447eccfce6c003dc6afd4a04b42cdb06fae1.log
coredns-57888bfdc7-nms5t_kube-system_coredns-1dcaf6a77fd7490c5727d77e6cc84179449dca3d06ecbb18701356b0d6eec3ef.log
coredns-57888bfdc7-nms5t_kube-system_coredns-d38cae2c4384e291906069b33b5d0daa42c92f909ff7574dfe2fa769aef56513.log
etcd-controlplane_kube-system_etcd-1d47f96e65a91113f154f18895cc3ce3484a3cc26b37bd38167aa745c302f30d.log
etcd-controlplane_kube-system_etcd-cb9a58d7b12c5399cc6650a4edad0f155de2bbe77c95a5ab904e40d2d70b8f6f.log
kube-apiserver-controlplane_kube-system_kube-apiserver-e6367f81ddd17db7884fdc6d8d085a87186f0e88622c0efb531cddca6003b1b8.log
kube-controller-manager-controlplane_kube-system_kube-controller-manager-91685a56d80747b03922bb509f6296806b79d66d06a6a028821e2850e12cf0c1.log
kube-controller-manager-controlplane_kube-system_kube-controller-manager-a111e6fdab5c1846830ec90623d627bdcebcdb4038734fc853ab859db0bafe2d.log
kube-proxy-sqc72_kube-system_kube-proxy-72a4de6ab9c220ba719ca43437d4061679cba6edad55cc5393121a3a6a865d35.log
kube-proxy-sqc72_kube-system_kube-proxy-8b1b8fad648f780df98f35d00d3bad185ec61c4d8decfba1a74f7837aa871f5f.log
kube-scheduler-controlplane_kube-system_kube-scheduler-aecb0893555df4abf562f97dfb26cc56e5a72491e322bb0c035820b533a16b55.log
kube-scheduler-controlplane_kube-system_kube-scheduler-b505cc8b63d3cdbf62e61cc92d6c2ef03bb86a315cf1b2e802b40e6fa6b1c59f.log
local-path-provisioner-6c5cff8948-tmf26_local-path-storage_local-path-provisioner-314f66daa8fd4118c454670e62eff79f917b038666ca9b31b3211a5b000a19a7.log
local-path-provisioner-6c5cff8948-tmf26_local-path-storage_local-path-provisioner-f8851c2a0595417fa8e5fd16dadeb4301101ee063b9066ff3523cd30741976cb.log
# container 単位でログが存在する
controlplane $ ls -la |grep kube-api
lrwxrwxrwx 1 root root 107 Jan 21 10:48 kube-apiserver-controlplane_kube-system_kube-apiserver-e6367f81ddd17db7884fdc6d8d085a87186f0e88622c0efb531cddca6003b1b8.log -> /var/log/pods/kube-system_kube-apiserver-controlplane_53ebb29699412c968f4d993ced098d57/kube-apiserver/0.log
# /var/log/pod/...にシンボリックリンクしている
# kubelet logs コマンドは kube-apiserver 自体が起動しない時は使えない
# /var/log/syslog は kube-apiserver.yaml 内に構文エラー等が存在するときにエラー出力あり
# journalctl は `journalctl |grep kube-apiserver` などで利用する
2.コンテナランタイム調査
crictl コマンドでコンテナランタイム側の調査を実施する。
- watch crictl ps
- crictl logs [containerID]
Every 2.0s: crictl ps controlplane: Tue Jan 21 11:03:49 2025
CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID POD
cbe49e7bbba2e f9c3c1813269c 14 minutes ago Running calico-kube-controllers 7 07fbe57b89ab1 calico-kube-contro
llers-94fb6bc47-4wx95
e6367f81ddd17 604f5db92eaa8 15 minutes ago Running kube-apiserver 0 93c924f4cd744 kube-apiserver-con
trolplane
b505cc8b63d3c 1766f54c897f0 18 minutes ago Running kube-scheduler 4 5f38ffd4159a6 kube-scheduler-con
trolplane
91685a56d8074 045733566833c 18 minutes ago Running kube-controller-manager 4 90af4775ef0e1 kube-controller-ma
nager-controlplane
f8851c2a05954 95fef08b8bf89 36 minutes ago Running local-path-provisioner 1 dffddfa11e19e local-path-provisi
oner-6c5cff8948-tmf26
e47e13162d0cd cbb01a7bd410d 36 minutes ago Running coredns 1 2d7613359bcee coredns-57888bfdc7
-g2dbp
1dcaf6a77fd74 cbb01a7bd410d 36 minutes ago Running coredns 1 6900cf74ce539 coredns-57888bfdc7
-nms5t
f67a491d23bf0 e6ea68648f0cd 36 minutes ago Running kube-flannel 1 6dd8835e73dc7 canal-b9w57
94afbc4803c29 75392e3500e36 36 minutes ago Running calico-node 1 6dd8835e73dc7 canal-b9w57
8b1b8fad648f7 ad83b2ca7b09e 37 minutes ago Running kube-proxy 1 0793bccc6e512 kube-proxy-sqc72
cb9a58d7b12c5 2e96e5913fc06 37 minutes ago Running etcd 1 5d364a510c02e etcd-controlplane
# watch コマンドで kube-apiserver コンテナの起動確認を実施
# crictl ps コマンドで kube-apiserver の containerIDを確認後、crictl logs コマンドで対象コンテナのログを確認する。
controlplane $ crictl ps |grep kube-apiserver
e6367f81ddd17 604f5db92eaa8 17 minutes ago Running kube-apiserver 0 93c924f4cd744 kube-apiserver-controlplane
controlplane $ crictl logs -f e6367f81ddd17
# --follow オプション等で最新ログを確認
3.noderestriction
kubeapiserver にアクセス可能な node の制限設定について説明します。
export KUBECONFIG=/etc/kubernetes/kubelet.conf
# KUBECONFIG に kubelet.conf ファイルをアサインすれば kubectl コマンド実行可能となる
なぜ KUBECONFIG に kubeletl.conf ファイルをアサインすれば kubectl コマンド実行可能となるのだろうか?一つずつ理解してきます。
node01 $ ps -aux |grep kubelet
root 1097 1.1 4.2 1904504 86372 ? Ssl 10:53 0:09 /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --config=/var/lib/kubelet/config.yaml --container-runtime-endpoint=unix:///var/run/containerd/containerd.sock --pod-infra-container-image=registry.k8s.io/pause:3.10 --container-runtime-endpoint unix:///run/containerd/containerd.sock --cgroup-driver=systemd --eviction-hard imagefs.available<5%,memory.available<100Mi,nodefs.available<5% --fail-swap-on=false
# node 上で apiserver と通信するデーモンは kubelet になる
# kubelt はいくつかの設定ファイルを渡して実行している
/var/lib/kubelet/cofnig.yamlの中身を確認する。
node01 $ cat /var/lib/kubelet/config.yaml
apiVersion: kubelet.config.k8s.io/v1beta1
authentication:
anonymous:
enabled: false
webhook:
cacheTTL: 0s
enabled: true
x509:
clientCAFile: /etc/kubernetes/pki/ca.crt
authorization:
mode: Webhook
webhook:
cacheAuthorizedTTL: 0s
cacheUnauthorizedTTL: 0s
cgroupDriver: systemd
clusterDNS:
- 10.96.0.10
clusterDomain: cluster.local
containerRuntimeEndpoint: ""
cpuManagerReconcilePeriod: 0s
evictionPressureTransitionPeriod: 0s
fileCheckFrequency: 0s
healthzBindAddress: 127.0.0.1
healthzPort: 10248
httpCheckFrequency: 0s
imageMaximumGCAge: 0s
imageMinimumGCAge: 0s
kind: KubeletConfiguration
logging:
flushFrequency: 0
options:
json:
infoBufferSize: "0"
text:
infoBufferSize: "0"
verbosity: 0
memorySwap: {}
nodeStatusReportFrequency: 0s
nodeStatusUpdateFrequency: 0s
resolvConf: /run/systemd/resolve/resolv.conf
rotateCertificates: true
runtimeRequestTimeout: 0s
shutdownGracePeriod: 0s
shutdownGracePeriodCriticalPods: 0s
staticPodPath: /etc/kubernetes/manifests
streamingConnectionIdleTimeout: 0s
syncFrequency: 0s
volumeStatsAggPeriod: 0s
# むむむ、直接的な記述は見当たらない
通常 kubelet は ~/.kube/config
を設定ファイルとして利用する。KUBECOFNIG 変数を設定することで、kubelet が参照する設定ファイルを変更できます。
続いて、kubelet.conf は特定の node が apiserver と通信するための設定が含まれています。言い換えると、~/.kube/config
に通信したい apiserver の設定ファイルが記述されていないため、KUBECONFIG で kubelet が利用する設定ファイルを切り替える必要があるということになります。
kubectlは、デフォルトで~/.kube/config
ファイルを参照しますが、KUBECONFIG環境変数が設定されている場合は、その変数に指定されたファイルを優先して使用します。kubectlの設定ファイル参照順序は以下の通りです。
- KUBECONFIG(環境変数)を参照
-
~/.kube/config
を参照
nodeRestriction(Admission Controllerの機能)は node に対する Label 操作を制限する機能です。例えば、自 node は OK、他 node からの label 編集は NG など、Label 操作に制限を設けることができます。一部(node-restriction.kubernetes.io/
) システム用途として操作可能な Label も存在します。編集可能な Lable の一覧は公式 doc(nodeRestriction)を参照しましょう。
noteRestriction は kube-apiserver 側で有効化します。
controlplane $ diff ~/kube-apiserver.yaml /etc/kubernetes/manifests/kube-apiserver.yaml
20a21
> - --enable-admission-plugins=NodeRestriction
# --enable-admission-plugins で note Restriction を有効化
node01 $ k label node controlplane killercoda/two=123
Error from server (Forbidden): nodes "controlplane" is forbidden: node "node01" is not allowed to modify node "controlplane"
# node01 から controleplane 上の label 変更不可
node01 $ k label node node01 node-restriction.kubernetes.io/two=123
Error from server (Forbidden): nodes "node01" is forbidden: is not allowed to modify labels: node-restriction.kubernetes.io/two
# 自 node に対する `node-restriction.kubernetes.io/` label の変更不可
node01 $ k label node node01 test/two=123
node/node01 labeled
# 自 node に対する label 追加は成功