(k8s)Flannel Error问题解决!
1.问题描述
书接上回,我们在解决kubectl不断重启的时候引入了Flannel 网络插件,但是一上来就报错,
2.问题解决
自己的思路:照例开始检查
1.先检查一下目前Flannel的pod
kubectl get pods --all-namespaces
2.检查 Flannel的pod的日志
kubectl describe pod kube-flannel-ds-4d456 -n kube-flannel
kubectl logs kube-flannel-ds-4d456 -c kube-flannel -n kube-flannel
找到了主要的问题所在,提示我们Error registering network: failed to acquire lease: node "master" pod cidr not assigned
3.分析问题
Error registering network: failed to acquire lease: node "master" pod cidr not assigned
这表明 Kubernetes 的控制平面(包括 kube-controller-manager
)无法为节点分配 Pod CIDR。需要确保 kube-controller-manager
能够获取到正确的 Pod CIDR。
解决方法
1. 为 kube-controller-manager
设置 Pod CIDR
你可以通过编辑 kube-controller-manager
的 kubeadm
配置来确保 Pod CIDR 正确设置。具体步骤如下:
-
检查
kubeadm
配置:确保在kubeadm
初始化时已经指定了--pod-network-cidr
参数。如果没有指定 Pod CIDR,可以通过以下方式为kubeadm
初始化指定该参数:kubeadm init --pod-network-cidr=10.244.0.0/16
这会为 Kubernetes 集群中的 Pod 分配一个 CIDR 范围。根据网络环境,CIDR 范围可能会有所不同。
-
修改 Kubernetes 控制平面节点的配置: 如果集群已经初始化并运行,可以手动编辑
kube-controller-manager
配置,使其能够与网络插件正确交互。通过以下方式编辑
kube-controller-manager.yaml
文件:- 找到
--allocate-node-cidrs=true
这一项,确保它被启用。 - 如果没有,手动在
command
中添加--allocate-node-cidrs=true
和--cluster-cidr=10.244.0.0/16
(与网络插件的配置一致)。
修改后的部分应该类似于:
- --allocate-node-cidrs=true
- --cluster-cidr=10.244.0.0/16
- 找到
在这里加上我们需要的两段话,重启,成功!!!!!!!!!!!
4.总结
- 确保
kube-controller-manager
的配置中指定了正确的--cluster-cidr
。 - 检查
kube-flannel
配置,确保其与kube-controller-manager
中的 CIDR 匹配。 - 验证节点的 Pod CIDR 是否已经正确分配。
- 如果仍然存在问题,尝试重新初始化
kubeadm
集群,确保指定了--pod-network-cidr
参数。
5.没有提到的地方
在此之前我们还尝试了一下几个地方,但一开始并没有奏效
这些命令主要是与 Linux 网络配置 和 Kubernetes 集群中的网络流量 管理相关的。它们涉及到桥接网络、IP 转发和防火墙规则。下面是每个命令的详细解释:
1. modprobe br_netfilter
- 这条命令加载了
br_netfilter
模块。br_netfilter
是一个内核模块,用于启用 Linux 内核对桥接网络接口的过滤能力。它允许在桥接网络中处理 IP 和 IP6 的防火墙规则,通常用于 Docker 和 Kubernetes 等容器化平台。 - 启用该模块后,容器之间的网络流量可以通过 iptables 进行过滤。
2. lsmod | grep br_netfilter
lsmod
命令列出当前加载的所有内核模块。grep br_netfilter
是通过管道将输出过滤,只显示br_netfilter
模块的状态。- 如果该模块已成功加载,你会看到类似于
br_netfilter 32768 0
的输出,表示br_netfilter
模块已加载并且未被其他模块使用。
3. sysctl -w net.bridge.bridge-nf-call-iptables=1
sysctl
用于查看或修改内核参数。这个命令修改了net.bridge.bridge-nf-call-iptables
参数,将其设置为1
,表示启用桥接网络接口(例如 Docker 或 Kubernetes 使用的桥接网络)上数据包的iptables
过滤。- 默认情况下,Linux 桥接网络会直接转发数据包,不经过防火墙规则。通过启用
bridge-nf-call-iptables
,数据包会先通过iptables
进行过滤。
4. sysctl -w net.bridge.bridge-nf-call-ip6tables=1
- 这条命令与上面的命令类似,只是它启用了对 IPv6 数据包的过滤。它会让桥接网络上的 IPv6 数据包也经过
ip6tables
(IPv6 防火墙)进行处理。
5. sysctl -w net.ipv4.ip_forward=1
- 这个命令启用了 IP 转发(
ip_forward
),即允许系统转发通过它的网络接口接收到的 IP 数据包。这对于路由器、网关以及容器环境中的节点间通信(比如 Kubernetes 集群中的 Pod 之间)是必须的。 - 启用 IP 转发后,系统会将网络包从一个接口转发到另一个接口,从而实现容器或虚拟机之间的通信。
6. sysctl -p
- 这个命令会加载和应用
/etc/sysctl.conf
文件中的配置或系统中当前尚未应用的参数。这是一个全局的配置更新命令,确保之前使用sysctl -w
修改的参数永久生效。
7. sysctl
命令输出:
net.ipv4.tcp_max_tw_buckets = 4096 net.core.somaxconn = 4096 net.ipv4.tcp_slow_start_after_idle = 0 kernel.sysrq = 1 net.ipv6.conf.all.disable_ipv6 = 0 net.ipv6.conf.default.disable_ipv6 = 0 net.ipv6.conf.lo.disable_ipv6 = 0 kernel.printk = 5
net.ipv4.tcp_max_tw_buckets = 4096
:设置最大 TCPTIME_WAIT
状态的连接数。这个参数控制 TCP 协议栈中TIME_WAIT
状态的连接桶的数量,避免因为过多的连接导致资源耗尽。net.core.somaxconn = 4096
:调整系统可以为每个监听套接字队列分配的最大连接数。增加该值可以允许更多的并发连接。net.ipv4.tcp_slow_start_after_idle = 0
:禁用 TCP 空闲后慢启动的机制。正常情况下,TCP 会在连接空闲后进入慢启动阶段,但设置为 0 会禁用这一行为,从而加速连接恢复。kernel.sysrq = 1
:启用 SysRq 键的功能,允许在系统发生故障时进行紧急操作,如重启、查看堆栈等。net.ipv6.conf.all.disable_ipv6 = 0
、net.ipv6.conf.default.disable_ipv6 = 0
、net.ipv6.conf.lo.disable_ipv6 = 0
:这些参数确保启用 IPv6 支持,不会禁用全局、默认和回环接口的 IPv6 地址。kernel.printk = 5
:调整内核日志打印级别,5
表示内核打印日志的级别,较低的级别会显示更多的调试信息。
6.为什么?
在 Kubernetes 集群中,Flannel 是一个常用的网络插件,用于提供容器之间的网络连接。Flannel 通过为每个节点分配一个子网并配置网络地址转换(NAT)来实现容器网络的隔离和通信。
当你在 Kubernetes 控制平面节点上修改 kube-controller-manager
配置,确保启用了 --allocate-node-cidrs=true
和 --cluster-cidr=10.244.0.0/16
,这对 Flannel 的成功运行至关重要。以下是详细的原因和解释:
1. --allocate-node-cidrs=true
- 这个参数告诉 Kubernetes 控制平面节点(特别是
kube-controller-manager
)启用自动为每个节点分配 CIDR(子网)块的功能。 --allocate-node-cidrs=true
启用后,Kubernetes 会在集群初始化时为每个节点分配一个专用的 IP 子网。这个子网会被分配给该节点上所有运行的 Pod。- Flannel 作为网络插件,会使用这些子网来为容器分配 IP 地址。Flannel 会确保每个 Pod 获得唯一的 IP 地址,避免与其他 Pod 或节点的 IP 地址冲突。
2. --cluster-cidr=10.244.0.0/16
--cluster-cidr
设置 Kubernetes 集群的 Pod 网络地址范围。在你的例子中,--cluster-cidr=10.244.0.0/16
设置了集群的 Pod 网络地址池为10.244.0.0/16
。这意味着所有的 Pod 地址将从这个范围内分配。- Flannel 需要知道这个地址范围,以便能够正确地为每个节点分配子网。每个节点的子网必须来自这个范围,Flannel 会确保每个节点的 IP 地址分配不会冲突。
- 如果
--cluster-cidr
设置不正确,Flannel 无法为 Pod 正确分配 IP 地址,导致 Pod 无法通信。
3. Flannel 与 Kubernetes 配合
- Flannel 使用了 Subnet 模式,其中每个节点都有一个 CIDR 子网,并且每个 Pod 都会获得该子网内的 IP 地址。
--allocate-node-cidrs=true
和--cluster-cidr=10.244.0.0/16
配置启用后,kube-controller-manager
会自动为每个节点分配一个子网(例如:10.244.1.0/24
、10.244.2.0/24
等),然后 Flannel 会为每个节点上的 Pod 分配一个独立的 IP 地址,这些地址会在节点的子网范围内。
4. 为什么需要这两项配置?
- 如果
--allocate-node-cidrs=true
被禁用,Kubernetes 不会自动分配节点的子网,Flannel 就无法为每个节点分配唯一的子网。结果,Flannel 无法正确配置每个节点的网络,从而无法为 Pod 分配 IP 地址。 - 如果没有正确设置
--cluster-cidr
,Flannel 就无法知道应该从哪个地址池中选择子网来分配给每个节点。这会导致 Pod 无法连接,或者多个节点之间的 IP 地址发生冲突。
5. Flannel 启动时如何工作
- Flannel 启动时会通过 API Server 获取集群的 CIDR 范围(即
--cluster-cidr
配置的值)。 - 它会为每个节点分配一个子网,并将该子网中的 IP 地址分配给该节点上的 Pod。Flannel 会通过 VXLAN、host-gw 或其他后端方式将这些网络连接起来,确保集群内的 Pod 可以跨节点通信。
总结
通过确保在 kube-controller-manager
配置中启用 --allocate-node-cidrs=true
和设置合适的 --cluster-cidr=10.244.0.0/16
,你告诉 Kubernetes 和 Flannel 网络插件如何分配 Pod 的 IP 地址。这样,Flannel 可以正确地为每个节点分配一个子网,并通过 Flannel 网络来连接各个节点的 Pod。这个配置是 Flannel 成功运行和集群内容器之间正常通信的关键。
要注意10.244.0.0/16!!!!这个是我现在的子网ip范围!!要根据自己的来调整,
但是这样我的也是可以加入的,真酷!,下一节总结一下这段时间使用的命令!