問題解決の概要
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`では表示されない場合があります。