kubestronautへの道 ~CKS編 その2 killer coda「Apiserver Crash」~

tech article

今日覚えて帰ること

このシナリオはpod, containerやkubeletのログの確認方法を覚えよう!の回です。

podのログ

/var/log/pods 配下を確認

containerのログ

/var/log/containers 配下を確認
crictl ps で対象となるコンテナのIDを確認 + crictl logs <containerID>

kubeletのログ

/var/log/syslog 配下を確認
journalctl コマンドで確認

Apiserver Crash

今回のシナリオは「Apiserver Crash」です。

Killer Shell CKS | Killercoda
These scenarios can be used standalone for CKS preparation or Kubernetes security studies. They can also be used in conjunction with the full course on Youtube:

kube-apiserverを壊してみましょう。

Configure a wrong argument

The idea here is to misconfigure the Apiserver in different ways, then check possible log locations for errors.

You should be very comfortable with situations where the Apiserver is not coming back up.

Configure the Apiserver manifest with a new argument --this-is-very-wrong .

Check if the Pod comes back up and what logs this causes.

Fix the Apiserver again.

kube-apiserverのマニフェストファイルをいじって誤作動を起こし、ログを確認してみようというシナリオです。
実際にやってみます。

kube-apiserverのマニフェストファイルを書き換える

# always make a backup !
cp /etc/kubernetes/manifests/kube-apiserver.yaml ~/kube-apiserver.yaml.ori

# make the change
vim /etc/kubernetes/manifests/kube-apiserver.yaml

# wait till container restarts
watch crictl ps

# check for apiserver pod
k -n kube-system get pod

kube-apiserverのマニフェストファイルが存在するディレクトリは/etc/kubernetes/manifestsです。

Implementation details
FEATURE STATE: Kubernetes v1.10 kubeadm init and kubeadm join together provide a nice user experience for creating a bare Kubernetes cluster from scratch, that ...

このパスにはstatic podのマニフェストファイルが配置されます。
static podとは、APIサーバーが監視しない、特定のノード上のkubeletデーモンによって直接管理されるPodです。
kubeletが直接管理しているため、マニフェストファイルを編集して保存すればkubectl applyをしなくてもpodには修正が反映されます。

ちなみに、kube-apiserverはcontroleplane上に存在するstatic podです。
ということは、kubeletがcontroleplaneにも存在する、ということです。
kubeletがsystemdで動いていることも、controleplaneにkubeletがいることも知りませんでした。

# always make a backup !
cp /etc/kubernetes/manifests/kube-apiserver.yaml ~/kube-apiserver.yaml.ori

ここではkube-apiserverのマニフェストファイルのバックアップを取っています。
こいつはkubernetesクラスターでもかなり重要なコンポーネントなので編集する際は絶対にバックアップを取りましょう。

# make the change
vim /etc/kubernetes/manifests/kube-apiserver.yaml

ここでファイルを編集します。

# wait till container restarts
watch crictl ps

ここでkube-apiserverが動かなくなるまでwatchします。
crictlコマンドは基本的にdockerコマンドと同じようなものかと思います。
現在Kubernetesで使用するコンテナランタイムとしてdockerは非推奨となっているのでcrictlで慣れておくのがよさそうです。

# check for apiserver pod
k -n kube-system get pod

api-server podが動かなくなっていることを確認します。


ログを確認する

# check pod logs
cat /var/log/pods/kube-system_kube-apiserver-controlplane_a3a455d471f833137588e71658e739da/kube-apiserver/X.log
> 2022-01-26T10:41:12.401641185Z stderr F Error: unknown flag: --this-is-very-wrong
ロギングのアーキテクチャ
アプリケーションログは、アプリケーション内で何が起こっているかを理解するのに役立ちます。ログは、問題のデバッグとクラスターアクティビティの監視に特に役立ちます。最近のほとんどのアプリケーションには、何らかのロギングメカニズムがあります。同様に、コンテナエンジンはロギングをサポートするように設計されています。コンテナ化さ...

ログを確認します。
今回確認したいのは、kube-apiserverというpodに対する変更のログです。
ということで、kubeletのログを確認します。
podのログはノードの/var/log/pods配下に保存されるらしいです・

kube-apiserverとハッシュ値っぽいのが付いたディレクトリがあるので探索します。

7という数字はログをローテーションしていてインクリメントしているっぽさがあります。
よくわからないフラグがあると怒られています。

元の状態に戻す

# smart people use a backup
cp ~/kube-apiserver.yaml.ori /etc/kubernetes/manifests/kube-apiserver.yaml

# wait till container restarts
watch crictl ps

# check for apiserver pod
k -n kube-system get pod

元通りに戻します。

Misconfigure ETCD connection

Change the existing Apiserver manifest argument to: --etcd-servers=this-is-very-wrong .

Check what the logs say, without using anything in /var .

Fix the Apiserver again.

今度はログを別の方法で見てみようという問題ですね。
ログを見る方法以外は特に特筆する点がないので、ログの見方だけチェックしていきます。

kube-apiserverのマニフェストファイルを書き換える

# always make a backup !
cp /etc/kubernetes/manifests/kube-apiserver.yaml ~/kube-apiserver.yaml.ori

# make the change
vim /etc/kubernetes/manifests/kube-apiserver.yaml

# wait till container restarts
watch crictl ps

# check for apiserver pod
k -n kube-system get pod

先ほどと同じようにバックアップを取ってファイルを編集します。
先ほどの問題でバックアップを取っていればバックアップは不要です。
今回はetcd-serverの指定先を変更します。

ログを確認する

# 1) if we would check the /var directory
cat /var/log/pods/kube-system_kube-apiserver-controlplane_e24b3821e9bdc47a91209bfb04056993/kube-apiserver/X.log
> Err: connection error: desc = "transport: Error while dialing dial tcp: address this-is-very-wrong: missing port in address". Reconnecting...

# 2) but here we want to find other ways, so we check the container logs
crictl ps # maybe run a few times, because the apiserver container get's restarted
crictl logs f669a6f3afda2
> Error while dialing dial tcp: address this-is-very-wrong: missing port in address. Reconnecting...

# 3) what about syslogs
journalctl | grep apiserver # nothing specific
cat /var/log/syslog | grep apiserver # nothing specific

しばらくしてkube-apiserverが動かなくなったのを確認した後、ログを確認します。
先ほどは/var/log/pods配下に格納されているログを見ました。
今回は別の方法でログを確認します。

crictl ps コマンドでkube-apiserverのコンテナIDを確認します。

crictl logs <CONTAINR ID>でログを確認します。
–etcd-server=this-is-very-wrongの箇所でエラーを起こしていることがわかります。

kubeletが出力するログは journalctl または cat /var/log/syslog で確認することが出来ます。
解答としてはそれらの出力を grep api-serverで検索してもログが出てこない想定みたいですが、めちゃくちゃログが出てきました。
コマンドを叩くタイミングの問題かもしれません。

元の状態に戻す

# smart people use a backup
cp ~/kube-apiserver.yaml.ori /etc/kubernetes/manifests/kube-apiserver.yaml

# wait till container restarts
watch crictl ps

# check for apiserver pod
k -n kube-system get pod

元通りに戻します。

Invalid Apiserver Manifest YAML

Change the Apiserver manifest and add invalid YAML, something like this:

apiVersionTHIS IS VERY ::::: WRONG v1
kind: Pod
metadata:

Check what the logs say, and fix again.

Fix the Apiserver again.

この問題も結局ログ確認の方法を学ぶだけのものなので、こちらは省略します。

タイトルとURLをコピーしました