k8sにおけるトラブルシューティング実例

# k8sにおけるトラブルシューティング実例
実例を交えてトラブルシューティングの流れを見ていきたいです。

## トラブル1 
セクション1: 問題の特定

1.1 ノードの状態確認:
まず、ノードの状態を把握しましょう。以下のコマンドで各ノードの状態を確認できます。

```shell
kubectl get nodes
```

出力例:
```
NAME        STATUS     ROLES    AGE    VERSION
worker-01   Ready      <none>   1d     v1.22
worker-02   NotReady   <none>   1d     v1.22
```

ここで、`worker-02`が`NotReady`状態であることがわかります。

1.2 kubeletのログ確認:
問題のあるノード（ここでは`worker-02`）にSSH接続し、kubeletのログを調査します。

```shell
journalctl -u kubelet
```

出力から、例えば`Failed to connect to API Server "<apiserver-ip>:6443"`のようなエラーメッセージが見つかる場合があります。これはkubeletがKubernetes APIサーバーに接続できないことを示しています。

セクション2: ネットワークのトラブルシューティング

2.1 疎通テスト:
問題のあるノードからAPIサーバーへの接続をテストします。

```shell
nc -vz <apiserver-ip> 6443
```

もし接続が失敗した場合、ネットワークレベルでの障害や設定の問題が疑われます。

2.2 ネットワーク設定の確認:
ファイアウォールのルール、セキュリティグループ、ネットワークポリシー、およびルーティングテーブルの設定を見直します。これらの設定に誤りがないか、また期待する通りの流れになっているかを確認する必要があります。

セクション3: 解決策と回復

3.1 ネットワーク設定の修正:
発見されたネットワークの問題（例: ファイアウォールのルール、ルーティングの誤りなど）を修正します。設定を更新し、再び疎通テストを行って問題が解決したことを確認します。

3.2 kubeletの再起動:
場合によっては、設定の変更後にkubeletを再起動する必要があります。

```shell
systemctl restart kubelet
```

3.3 ノードの状態の再確認:
最後に、ノードの状態が`Ready`に戻ったかどうかを確認します。

```shell
kubectl get nodes
```

出力例:
```
NAME        STATUS   ROLES    AGE    VERSION
worker-01   Ready    <none>   1d     v1.22
worker-02   Ready    <none>   1d     v1.22
```

## トラブル2: CoreDNSの問題解析と解決策
### 1. 背景

Kubernetesクラスター内でサービスが名前解決できない問題が発生しました。ポッド間の通信は問題ないようですが、特定の外部ドメインに対する解決ができていない状況です。

### 2. 問題の特定

2.1 初めに、問題が発生しているCoreDNSの状態を確認します。

```bash
kubectl -n kube-system get pods -l k8s-app=kube-dns
```

2.2 次に、CoreDNSのログを確認して、エラーや警告がないかをチェックします。

```bash
kubectl -n kube-system logs $(kubectl -n kube-system get pods -l k8s-app=kube-dns -o jsonpath='{.items[0].metadata.name}')
```

ログには特にエラーが見当たらないため、設定に問題がある可能性を考え、CoreDNSのConfigMapを検証します。

```bash
kubectl -n kube-system get configmap coredns -o yaml
```

### 3. 問題の解析

ConfigMapの中身を確認すると、`forward`の項目が怪しいことがわかります。例えば、次のような設定が見られる場合があります。

```yaml
.:53 {
    errors
    health
    forward . /etc/resolv.conf
    cache 30
    loop
    reload
    loadbalance
}
```

この設定では、CoreDNSはすべてのリクエストをローカルの`/etc/resolv.conf`にフォワーディングしていますが、ここに問題がある可能性があります。例えば、外部のDNSサーバーへのフォワーディングが正しく設定されていない、または`resolv.conf`に不適切なエントリがある場合です。

### 4. 解決策の実施

4.1 **CoreDNSの設定の調整:**
   不適切なフォワード設定を修正します。直接外部の信頼できるDNSサーバーにリクエストをフォワーディングするよう設定を変更します。以下はその例です。

```yaml
forward . 8.8.8.8 8.8.4.4
```

この変更をConfigMapに適用した後、CoreDNSの設定が自動的にリロードされるのを待ちます。

4.2 **ネットワークポリシーの変更:**
   必要に応じて、CoreDNSが外部のDNSサーバーに到達可能であることを保証するためのネットワークポリシーを調整します。

4.3 **CoreDNSの再起動:**
   設定の変更を確実に反映させるために、CoreDNSのPodを再起動します。

```bash
kubectl -n kube-system rollout restart deployment coredns
```

## トラブル3: KubernetesのCoreDNSループ問題の解決

**問題の概要**:
Kubernetesクラスター内で動作するCoreDNSは、サービスの名前解決を担当しますが、設定の不整合により、自己参照ループに陥ることがあります。結果として、DNSクエリは適切に解決されず、クラスタ内のサービスに影響を及ぼします。

**根本的な原因の解説と実例**:
問題の背景には、コンテナが自身のループバックインターフェース（127.0.0.1）を参照する設定があります。通常、このアドレスはCoreDNS自身を指し示しているため、クエリは外部のDNSサーバーに到達せず、代わりに無限ループを引き起こします。

具体的な症状を確認するには、以下のコマンドを使用してCoreDNSのログを調査します。

```bash
kubectl logs -n kube-system -l k8s-app=kube-dns
```

問題が発生している場合、ログには繰り返しエラーメッセージが表示されます。

**解決策と具体的な手順**:
この問題にはいくつかのアプローチがありますが、ここではCoreDNSの設定をカスタマイズする方法を紹介します。

1. **CoreDNSの設定のカスタマイズ**:
   
   最初に、CoreDNSの現在のConfigMapを確認します。

   ```bash
   kubectl get configmap coredns -n kube-system -o yaml
   ```

   次に、ConfigMapを編集します。`forward`セクションに外部DNSサーバー（例：8.8.8.8）を指定してください。

   ```yaml
   apiVersion: v1
   kind: ConfigMap
   metadata:
     name: coredns
     namespace: kube-system
   data:
     Corefile: |
       .:53 {
           errors
           health
           ready
           kubernetes cluster.local in-addr.arpa ip6.arpa {
             pods insecure
             fallthrough in-addr.arpa ip6.arpa
           }
           prometheus :9153
           forward . 8.8.8.8
           cache 30
           loop
           reload
           loadbalance
       }
   ```

   変更を加えたら、CoreDNSのPodを再起動して変更を適用します。

   ```bash
   kubectl rollout restart deployment coredns -n kube-system
   ```

   これで、CoreDNSは外部のDNSリクエストをGoogleのパブリックDNSサーバーにフォワードします。

2. **疎通テスト**:
   
   変更が効果をもたらしたかを確認するために、クラスタ内から外部ホストへのDNSルックアップをテストします。

   ```bash
   kubectl run --generator=run-pod/v1 -it --rm --restart=Never dns-test --image=busybox:1.28 -- nslookup example.com
   ```

   このコマンドは、一時的なPodを使用して`example.com`の名前解決を試みます。成功した場合、応答には正しいIPアドレスが含まれます。