k8s的疑难杂症
简介
这里记录处理 k8s 的常见问题.
排错路线
错误合集
metrics-server
doesn’t contain any IP SANs
在 metrics-server 启动的 yml 文件中, 添加启动参数
command:
- /metrics-server
- --kubelet-insecure-tls
kubectl top pod 报错 error: Metrics API not available
当你使用 kubectl top pod
来查看信息的时候, 需要安装 Metrics-server
, 参考链接
下载下来
curl https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml -o metrics-server.yaml
因为多数都是自签名证书, 所以添加启动参数
--kubelet-insecure-tls
... apiVersion: apps/v1 kind: Deployment metadata: labels: k8s-app: metrics-server name: metrics-server namespace: kube-system spec: selector: matchLabels: k8s-app: metrics-server strategy: rollingUpdate: maxUnavailable: 0 template: metadata: labels: k8s-app: metrics-server spec: containers: - args: - --cert-dir=/tmp - --secure-port=4443 - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname - --kubelet-use-node-status-port - --metric-resolution=15s - --kubelet-insecure-tls # 添加此行 ...
too many pods 容器启动失败
发现 kubesphere 的 cicd 容器无法启动, 于是排查容器 kubectl describe pod/cicdrfbh9-pay-h5-35-gn0rf-pl1sr-g8tpr -n kubesphere-devops-worker
提示 too many pods
, 下面是操作方法.
完整顺序应该是
- 先排水
- 不可调度
- 改配置, 重启
- 重新调度
Kubelet 的启动配置通常是这样, 我们加上 --max-pods=300
然后重启 kubelet 服务即可.
Environment="KUBELET_EXTRA_ARGS=--node-ip=10.30.1.127 --hostname-override=node1 --max-pods=300"
ExecStart=/usr/local/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS
清理残存的容器
证书
# 查找证书
find / -name apiserver.crt
/etc/kubernetes/pki/apiserver.crt
# 查看证书过期时间
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -dates
notBefore=Apr 22 06:54:59 2022 GMT
notAfter=Apr 1 19:00:00 2024 GMT
# kuadm查看证书状态
kubeadm certs check-expiration
网络插件错误
Multus
网络插件的报错, 会出现如下的关键字:
network: Multus
… KillPodSandbox
… Unauthorized
… networkPlugin cni failed
我们在安装网络插件的时候, 只不过是通过 kubectl create/edit
操作了一些资源, 所以我们重启等操作不会造成其他的影响. 在官方也有不少这样的骚操作, 比如 这个帖子的答案推荐直接尝试重启 ….
操作流程
# 查找插件calico,flannal之类的
kubectl get all -A |grep cali
# 杀死重启
kubectl delete pod/calico-node-xxx -n 命名空间
kubectl delete pod/kube-multus-ds-xxx -n 命名空间
BGP
网络插件的报错类似于
calico/node is not ready:
BIRD is not ready:BGP not established with 192.168.200.129,192.168.200.130
Number of node(s)with BGP peering established =0
calico
通常会根据第一个网卡来配置信息. 而出现上面的报错, 就说明我们没有找到正确的网卡, 没有配置正确的 ip 信息.
解决:
ip a
查看我们需要用到的网卡名称. 例如eth0
,ens33
等等修改
vim calico.yaml
# 增加内容 - name: IP_AUTODETECTION_METHOD value: "interface=en*" # 也可以写死 "interface=eth0" # 下面是原文件内容 - name: CLUSTER_TYPE value: "k8s,bgp" - name: IP value: "autodetect" - name: CALICO_IPV4POOL_IPIP value: "Always"
重新部署
kubectl apply -f calico.yaml
cri-dockerd
validate CRI v 1 runtime API for endpoint
情景:
kubeadm init
或 crictl ps
的时候报错:
validate CRI v1 runtime API for endpoint "unix:///var/run/cri-dockerd.sock"
解答:
- 网上很多的教程都有一定的滞后性。如果无法保证所有组件的版本,架构一致,可能会出现问题。包括但不限于:k8s 版本,cni 版本,docker 版本,containerd 版本,arm 架构, x 86 架构等等。
- cri-dockerd 是为了不停兼容 cri 标准。所以 cri-dockerd 和 k8s 的版本兼容性比较好。而 dockerd 的内部 api 可能会经常变动,比如下图 cri-dockerd 的
v0.3.8
开始兼容 docker 的v24.0.7
版本
处理:
建议下载最新的 cri-dockerd 版本,配置 cri-dockerd:
# 获取软件 mkdir /data/softs && cd /data/softs wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.2.1/cri-dockerd-0.3.8.amd64.tgz # 解压软件 tar xf cri-dockerd-0.3.8.amd64.tgz mv cri-dockerd/cri-dockerd /usr/local/bin/ # 检查效果 cri-dockerd --version # 守护进程 vim /etc/systemd/system/cri-dockerd.service [Unit] Description=CRI Interface for Docker Application Container Engine Documentation=https://docs.mirantis.com After=network-online.target firewalld.service docker.service Wants=network-online.target [Service] Type=notify ExecStart=/usr/local/bin/cri-dockerd --network-plugin=cni --cni-conf-dir=/etc/cni/net.d --cni-bin-dir=/opt/cni/bin --container-runtime-endpoint=unix:///var/run/cri-dockerd.sock --image-pull-progress-deadline=30s --pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.6 --cri-dockerd-root-directory=/var/lib/dockershim --docker-endpoint=unix:///var/run/docker.sock --cri-dockerd-root-directory=/var/lib/docker ExecReload=/bin/kill -s HUP $MAINPID TimeoutSec=0 RestartSec=2 Restart=always StartLimitBurst=3 StartLimitInterval=60s LimitNOFILE=infinity LimitNPROC=infinity LimitCORE=infinity TasksMax=infinity Delegate=yes KillMode=process [Install] WantedBy=multi-user.target vim /usr/lib/systemd/system/cri-dockerd.socket [Unit] Description=CRI Docker Socket for the API PartOf=cri-docker.service [Socket] ListenStream=/var/run/cri-dockerd.sock SocketMode=0660 SocketUser=root SocketGroup=docker [Install] WantedBy=sockets.target # 启动服务 systemctl daemon-reload systemctl enable cri-dockerd.service systemctl restart cri-dockerd.service # 检测效果 crictl --runtime-endpoint /var/run/cri-dockerd.sock ps
vim /etc/containerd/config.toml
去除disabled_plugins = ["cri"]
. 重启 Containerdsystemctl restart containerd
测试是否可以通过 cri-dockerd 联通 docker
# cat /etc/crictl.yaml runtime-endpoint: "unix:///var/run/cri-dockerd.sock" image-endpoint: "unix:///var/run/cri-dockerd.sock" timeout: 10 debug: false pull-image-on-create: true disable-pull-on-run: false # 测试效果 crictl ps
kubeadm 无法指定 –cri-socket
准备一个配置文件 kube-init.yaml
apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
nodeRegistration:
criSocket: unix:///var/run/cri-dockerd.sock
引入配置文件即可:
kubeadm init phase upload-certs --upload-certs --config kube-init.yml