查找镜像解决问题

docker pull quay.io/coreos/flannel
quay.io/coreos/flannel:v0.10.0-arm

kubectl describe pod kube-flannel-ds-7r68t -n kube-system

docker pull quay.io/kubespray/flannel-cni-plugin
https://quay.io/kubespray/flannel-cni-plugin?spm=5176.28103460.0.0.40f7451e5gF1b9&tab=tags
https://quay.io/repository/chengyuzhu6/rancher/mirrored-flannelcni-flannel-cni-plugin?spm=5176.28103460.0.0.40f7451e5gF1b9&tab=tags
v1.1.0
sudo yum install -y skopeo # CentOS/RHEL

https://quay.io/repository/coreos/flannel?spm=5176.28103460.0.0.40f7451e5gF1b9&tab=tags

https://quay.io/kubespray/flannel-cni-plugin?spm=5176.28103460.0.0.40f7451e5gF1b9&tab=tags

docker pull quay.io/coreos/flannel:v0.15.1

是node3节点 对应公网的ip 是192.168.1.116(zerotier组网分配)
是node4节点 对应公网的ip 是192.168.1.117(zerotier组网分配)

/etc/hosts

本地回环地址

127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6

主节点本地IP与主机名映射

192.168.242.128 k8s-master

工作节点本地IP与主机名映射

192.168.242.129 k8s-node-1
192.168.242.130 k8s-node-2
192.168.242.131 k8s-node-3 # 假设Node3的本地IP为192.168.242.131
192.168.242.132 k8s-node-4 # 假设Node4的本地IP为192.168.242.132

ZeroTier公网IP与主机名映射

192.168.1.146 k8s-master
192.168.1.232 k8s-node-1
192.168.1.115 k8s-node-2
192.168.1.116 k8s-node-3
192.168.1.117 k8s-node-4

sudo kubeadm init
–kubernetes-version=v1.18.8
–apiserver-advertise-address=192.168.1.146 \ # ZeroTier公网IP(主节点)
–pod-network-cidr=10.244.0.0/16
–apiserver-cert-extra-sans=
192.168.1.146, \ # 主节点的公网IP
192.168.242.128, \ # 主节点本地IP
k8s-master, \ # 主节点主机名
127.0.0.1, \ # 默认项
kubernetes.default, \ # 默认项
192.168.1.232, \ # Node1的公网IP
192.168.1.115, \ # Node2的公网IP
192.168.1.116, \ # Node3的公网IP
192.168.1.117 # Node4的公网IP

你的观察是正确的,在某些情况下,仅配置主节点的本地IP和公网IP(即 --apiserver-cert-extra-sans 中仅包含主节点的IP)可能也能成功启动集群。但需要明确以下几点:


1. 为什么可能成功?

场景分析
  • 节点通过主节点的公网IP连接 API Server

    • 当节点执行 kubeadm join 时,会通过主节点的公网IP(如 192.168.1.146)连接 API Server。
    • 只要主节点的公网IP和本地IP被包含在证书的 SAN 列表中,节点就能通过主节点的 IP 成功连接,无需其他节点的公网IP。
  • 节点之间通过本地网络通信

    • 节点的本地IP(如 192.168.242.129)用于集群内部通信(如 Pod 网络、kubelet 通信),这些 IP 通常不需要包含在 API Server 的证书中,因为它们不直接用于连接 API Server。

2. 为什么需要包含其他节点的公网IP?

关键场景
  • 节点需要通过自己的公网IP连接 API Server

    • 如果节点尝试通过自己的公网IP(如 192.168.1.232)连接 API Server,则证书必须包含该 IP,否则会因证书验证失败而无法连接。
    • 例如,如果节点的防火墙或网络配置强制要求通过自己的公网IP访问 API Server,则必须包含该 IP。
  • 高可用集群(HA)或多网络环境

    • 在高可用集群中,API Server 可能部署在多个节点上,每个节点的公网IP都需要包含在证书中。
    • 如果节点分布在不同网络或需要通过多个入口访问 API Server,则必须将所有相关 IP 加入证书。

3. 你的配置中是否需要其他节点的公网IP?

根据你的描述
  • 当前配置
    • 主节点的公网IP是 192.168.1.146,且所有节点通过该 IP 加入集群。
    • 其他节点的公网IP(如 192.168.1.232192.168.1.115 等)未被包含在证书的 SAN 列表中。
结论
  • 如果节点仅通过主节点的公网IP连接 API Server,则无需包含其他节点的公网IP,集群仍可正常运行。
  • 但存在潜在风险
    • 如果后续需要通过其他节点的公网IP直接访问 API Server(例如,某些特定网络策略或故障转移场景),则证书会因缺少这些 IP 而导致连接失败。

4. 完整的证书配置建议

最小必要配置
sudo kubeadm init \
  --apiserver-cert-extra-sans= \
    192.168.1.146, \  # 主节点的公网IP
    192.168.242.128, \  # 主节点的本地IP
    k8s-master, \      # 主节点的主机名(可选,但推荐)
    127.0.0.1, \       # 默认项
    kubernetes.default  # 默认项
推荐配置(覆盖所有可能性)
sudo kubeadm init \
  --apiserver-cert-extra-sans= \
    192.168.1.146, \  # 主节点的公网IP
    192.168.242.128, \  # 主节点的本地IP
    k8s-master, \      # 主节点的主机名
    127.0.0.1, \       # 默认项
    kubernetes.default, \  # 默认项
    192.168.1.232, \   # Node1的公网IP(可选,按需添加)
    192.168.1.115, \   # Node2的公网IP(可选,按需添加)
    192.168.1.116, \   # Node3的公网IP(可选,按需添加)
    192.168.1.117      # Node4的公网IP(可选,按需添加)

5. 具体场景下的建议

场景1:仅通过主节点公网IP连接
  • 配置:仅包含主节点的公网IP和本地IP。
  • 适用情况:所有节点通过主节点的公网IP加入集群,且后续无需直接通过其他节点的公网IP访问 API Server。
  • 潜在风险:如果后续需要直接通过其他节点的公网IP访问 API Server(例如跨网络故障转移),会导致证书错误。
场景2:需要多入口访问
  • 配置:包含所有节点的公网IP。
  • 适用情况:集群需要高可用性,或节点可能通过多个公网IP访问 API Server(例如分布式网络)。
  • 优势:避免因证书 SAN 列表不足导致的连接问题。

6. 验证证书的 SAN 列表

执行以下命令检查证书是否包含必要的 IP:

sudo openssl x509 -in /etc/kubernetes/pki/apiserver.crt -text -noout | grep "X509v3 Subject Alternative Name"

预期输出示例

X509v3 Subject Alternative Name:
  DNS:kubernetes.default, DNS:kubernetes.default.svc, DNS:kubernetes.default.svc.cluster.local, 
  IP Address:127.0.0.1, IP Address:192.168.1.146, IP Address:192.168.242.128, 
  DNS:k8s-master

7. 总结

  • 最小必要配置:只需包含主节点的公网IP和本地IP即可启动集群。
  • 推荐配置:包含所有节点的公网IP以覆盖所有可能的连接场景,避免未来扩展时出现证书问题。
  • 实际需求决定配置:根据你的网络拓扑和访问方式选择配置,但建议覆盖所有可能的 IP 以确保可靠性。

如果当前集群运行正常且无扩展需求,可以暂时仅配置主节点的 IP。但若未来需要通过其他节点的公网IP访问 API Server,需重新初始化集群并更新证书。

/cni/net.d/*
sudo ip link delete cni0
sudo ip link delete flannel.1
rm -rf $HOME/.kube/
sudo netstat -tuln | grep -E ‘6443|10259|10257|10250|2379|2380’
kubeadm init --kubernetes-version=v1.18.8 --apiserver-advertise-address=192.168.1.146 --pod-network-cidr=10.244.0.0/16 --apiserver-cert-extra-sans=192.168.1.146【这里只是指定公网的ip 太少了 通过master本地假如的话认证就有问题 所以后面需要加入本地的ip】

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown ( i d − u ) : (id -u): (idu):(id -g) $HOME/.kube/config

[root@k8s-master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master NotReady master 65s v1.18.8
[root@k8s-master ~]#
sudo vim /etc/hosts

185.199

EXTRA GROUPS

odc9wj.7x4p14dkhyzd2xml 21h 2025-03-28T09:21:01-07:00 authentication,signing The default bootstrap token generated by ‘kubeadm init’. system:bootstrappers:kubeadm:default-node-token
[root@k8s-master ~]#
[root@k8s-master ~]# openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed ‘s/^.* //’
a18443cf1099c9d705a5cc4d4e17da2722d23e1f2696324f6d9c740791d583ce
[root@k8s-master ~]#

kubeadm join 192.168.242.128:6443
–token odc9wj.7x4p14dkhyzd2xml
–discovery-token-ca-cert-hash sha256:a18443cf1099c9d705a5cc4d4e17da2722d23e1f2696324f6d9c740791d583ce

  1. 当前
    kubeadm join 192.168.242.128:6443
    –token odc9wj.7x4p14dkhyzd2xml
    –discovery-token-ca-cert-hash sha256:a18443cf1099c9d705a5cc4d4e17da2722d23e1f2696324f6d9c740791d583ce
  2. 当前证书配置
    从你的命令来看,API Server 的证书只包含了 192.168.1.146(通过 --apiserver-cert-extra-sans 参数指定)。因此,工作节点通过 192.168.242.128 连接时会报错:

Plaintext
深色版本
x509: certificate is valid for 10.96.0.1, 192.168.1.146, not 192.168.242.128

[root@k8s-master ~]# vi kubeadm-config.yaml
[root@k8s-master ~]# mv /etc/kubernetes/pki/apiserver.{crt,key} /tmp/
[root@k8s-master ~]# kubeadm init phase certs apiserver --config kubeadm-config.yaml
W0327 11:51:16.022367 19024 configset.go:202] WARNING: kubeadm cannot validate component configs for API groups [kubelet.config.k8s.io kubeproxy.config.k8s.io]
[certs] Generating “apiserver” certificate and key
[certs] apiserver serving cert is signed for DNS names [k8s-master kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 192.168.242.128 192.168.1.146 192.168.242.128]
[root@k8s-master ~]#
[root@k8s-master ~]# docker ps | grep kube-apiserver | awk ‘{print $1}’ | xargs docker restart
e72be5dffe52
96beb2e6b323
[root@k8s-master ~]#
[root@k8s-master ~]# openssl s_client -connect 192.168.242.128:6443 -showcerts </dev/null 2>/dev/null | openssl x509 -text -noout | grep DNS
DNS:k8s-master, DNS:kubernetes, DNS:kubernetes.default, DNS:kubernetes.default.svc, DNS:kubernetes.default.svc.cluster.local, IP Address:10.96.0.1, IP Address:192.168.242.128, IP Address:192.168.1.146, IP Address:192.168.242.128
[root@k8s-master ~]#

[root@k8s-node-2 ~]# kubeadm join 192.168.242.128:6443 \

–token odc9wj.7x4p14dkhyzd2xml
–discovery-token-ca-cert-hash sha256:a18443cf1099c9d705a5cc4d4e17da2722d23e1f2696324f6d9c740791d583ce
W0327 11:53:09.577643 11207 join.go:346] [preflight] WARNING: JoinControlPane.controlPlane settings will be ignored when control-plane flag is not set.
[preflight] Running pre-flight checks
[preflight] Reading configuration from the cluster…
[preflight] FYI: You can look at this config file with ‘kubectl -n kube-system get cm kubeadm-config -oyaml’
[kubelet-start] Downloading configuration for the kubelet from the “kubelet-config-1.18” ConfigMap in the kube-system namespace
[kubelet-start] Writing kubelet configuration to file “/var/lib/kubelet/config.yaml”
[kubelet-start] Writing kubelet environment file with flags to file “/var/lib/kubelet/kubeadm-flags.env”
[kubelet-start] Starting the kubelet
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap…

This node has joined the cluster:

  • Certificate signing request was sent to apiserver and a response was received.
  • The Kubelet was informed of the new secure connection details.

Run ‘kubectl get nodes’ on the control-plane to see this node join the cluster.

[root@k8s-node-2 ~]#

[root@k8s-master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master Ready master 153m v1.18.8
k8s-node-1 Ready 38s v1.18.8
k8s-node-2 Ready 53s v1.18.8
[root@k8s-master ~]# [root@k8s-master ~]# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-66bff467f8-8pv4g 1/1 Running 0 153m
coredns-66bff467f8-98vzg 1/1 Running 0 153m
etcd-k8s-master 1/1 Running 0 153m
kube-apiserver-k8s-master 1/1 Running 0 153m
kube-controller-manager-k8s-master 1/1 Running 0 153m
kube-flannel-ds-drdr4 1/1 Running 0 84s
kube-flannel-ds-gxz8l 1/1 Running 0 99s
kube-flannel-ds-q7pz5 1/1 Running 0 41m
kube-proxy-gjwrk 1/1 Running 0 99s
kube-proxy-mcpwp 1/1 Running 0 84s
kube-proxy-xhfdg 1/1 Running 0 153m
kube-scheduler-k8s-master 1/1 Running 0 153m
[root@k8s-master ~]#

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值