Kubernetes kubeadm デプロイ時のトラブルシューティング問題集

問題解決の概要

kubeadmを使用してKubernetesクラスターをデプロイする際、様々な技術的な問題に直面することがあります。この記事では、よくある問題とその解決策を体系的に整理し、問題解決の方向性を示します。

よくある問題と解決策

エラー: The connection to the server localhost:8080 was refused - did you specify the right host or port?

このエラーはkubectlが正しい設定ファイルを使用していない場合に発生します。

# rootユーザーの場合
export KUBECONFIG=/etc/kubernetes/admin.conf

# 非rootユーザーの場合
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

kubectl get csでUnhealthyが表示される

スケジューラーコントローラーマネージャーの状態がUnhealthyになる問題です。

解決策:

# 以下のファイルを編集します
/etc/kubernetes/manifests/kube-scheduler.yaml
/etc/kubernetes/manifests/kube-controller-manager.yaml

# 両方のファイルから以下の行をコメントアウトします
# - --port=0

Kubeletエラー: cgroup driverの不一致

「failed to run Kubelet: misconfiguration: kubelet cgroup driver: "systemd" is different from docker」というエラーは、Dockerとkubeletのcgroupドライバが異なる場合に発生します。

解決策:

# /etc/docker/daemon.jsonを以下のように編集
{
  "exec-opts": ["native.cgroupdriver=systemd"], 
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2",
  "storage-opts": [
    "overlay2.override_kernel_check=true"
  ]
}

# 設定を適用
systemctl daemon-reload
systemctl restart docker

証明書エラー: Unable to connect to the server: x509: certificate signed by unknown authority

証明書検証エラーが発生する場合の解決策です。

# 管理者証明書をコピー
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
kubectl get nodes

# またはkubelet証明書を使用
export KUBECONFIG=/etc/kubernetes/kubelet.conf
kubectl get node

スケジューラーとコントローラーマネージャーのUnhealthy状態

kubectl get csでschedulerとcontroller-managerがUnhealthyと表示される問題です。

解決策:

# rootユーザーの場合
# 設定ファイルパス:
/etc/kubernetes/manifests/kube-scheduler.yaml
/etc/kubernetes/manifests/kube-controller-manager.yaml

# 一般ユーザーの場合
# 設定ファイルパス:
$HOME/.kube/

# 両方の設定ファイルで--portオプションをコメントアウト

Kubeletのcgroup取得エラー

Kubeletコンポーネントが「failed to get cgroup」エラーを報告する問題です。

解決策:

# kubeletサービスを再起動
systemctl restart kubelet

# cgroup設定を確認
cat /proc/cgroups

# 必要に応じてcgroup v2に移行
# (システムに応じて手順が異なります)

ブリッジアドレス競合エラー

「failed to set bridge addr: "cni0" already has an IP address different from 10.244.1.1/24」というエラーの解決策です。

解決策:

# CNIネットワークインターフェースを再設定
ifconfig cni0 down
ip link delete cni0

# kubeletログを確認
journalctl -xeu kubelet

CoreDNSによるドメイン名解決の問題

CoreDNSがドメイン名を解決できない場合のトラブルシューティング方法です。

解決策:

アプローチ: Pod内でping/digを使用してテストします。クラスターはフラットネットワークであるため、ノード間は相互に通信可能です。そのため、CoreDNSのIPを使用してテストできます。

# CoreDNS IPを使用したdigコマンド
dig @ example.com +trace

# テスト用Podの作成
kubectl run -it --rm --restart=Never --image=busybox dns-test -- dig @ kubernetes.default.svc.cluster.local

クラスター証明書の有効期限切れ

Kubernetesクラスターの証明書が期限切れになった場合の更新手順です。

解決策:

# 証明書の更新
kubeadm certs renew all # kubelet証明書は更新されないことに注意

# kubelet証明書の更新
# デフォルトでは証明書のローテーションによる自動更新が有効ですが、
# 期限切れの場合はkubelet.confを再生成する必要があります

mv /etc/kubernetes/kubelet.conf .
mv /var/lib/kubelet/pki/kubelet-client* .

# ノード名をNODEに置き換える必要がある場合があります
# --config kubeadm.confが必要な場合もあります
kubeadm config print init-defaults > kubeadm.conf
kubeadm kubeconfig user --org system:nodes --client-name system:node:$NODE --config /root/kubeadm.conf > kubelet.conf

# kubelet.confを更新
cp kubelet.conf /etc/kubernetes/kubelet.conf
systemctl restart kubelet

HAProxyを使用した高可用性のデプロイ

HAProxyの設定

複数のマスターノード間で負荷分散を実現するためのHAProxy設定です。

haproxy.cfg設定ファイルの表示
global
    log 127.0.0.1 local0
    log 127.0.0.1 local1 notice
    maxconn 4096
    stats socket /var/lib/haproxy/stats

defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    option forwardfor       except 127.0.0.0/8
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 3000

frontend kube-apiserver
    bind *:6444
    mode tcp
    timeout client 1h
    log global
    option tcplog

    default_backend kube-apiserver

backend kube-apiserver
    option httpchk GET /healthz
    http-check expect status 200
    mode tcp
    option ssl-hello-chk
    balance     roundrobin
    server k8s-master-01 192.168.4.41:6443 check
    server k8s-master-02 192.168.4.42:6443 check
    server k8s-master-03 172.17.0.66:6443 check
# HAProxyコンテナの起動
docker run -d --restart=always --name haproxy -p 6444:6444 \
    -v ~/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg \
    haproxy

Keepalivedの設定

HAProxyの冗長化を実現するためのKeepalived設定です。

問題: ip address associated with VRID 160 not present in MASTER advert

原因: Keepalived masterのvirtual_router_idが、LAN内の他のKeepalived masterと競合している可能性があります。

解決策:

# /etc/keepalived/keepalived.confのvirtual_router_idを変更
# その後サービスを再起動

Keepalivedコンテナのデプロイ

#!/bin/bash
VIRTUAL_IP=192.168.4.200 # 仮想IPアドレスの設定
INTERFACE=eth0 # 使用するネットワークインターフェース
NETMASK_BIT=24
CHECK_PORT=6444
RID=10
VRID=160 # 仮想ルータID - 一意である必要があります
MCAST_GROUP=224.0.0.18

# Keepalivedコンテナの起動
docker run -itd --restart=always --name=Keepalived-K8S \
        --net=host --cap-add=NET_ADMIN \
        -e VIRTUAL_IP=$VIRTUAL_IP \
        -e INTERFACE=$INTERFACE \
        -e CHECK_PORT=$CHECK_PORT \
        -e RID=$RID \
        -e VRID=$VRID \
        -e NETMASK_BIT=$NETMASK_BIT \
        -e MCAST_GROUP=$MCAST_GROUP \
        wise2c/keepalived-k8s

# 仮想IPの確認
ip addr

注: 仮想IPは`ip addr`コマンドで確認できますが、`ifconfig`では表示されない場合があります。

タグ: Kubernetes kubeadm トラブルシューティング HAProxy Keepalived

6月10日 18:06 投稿