githubixx.flanneld
ansible-role-flanneld
这个 Ansible playbook 用于 用 Ansible 轻松部署 Kubernetes - Worker。它安装和配置 flanneld
二进制文件。Flannel 负责为集群中的多个节点提供一个层 3 的 IPv4 网络。Flannel 不控制容器如何连接到主机,仅控制主机之间的流量传输。此外,Flannel 还为 Kubernetes 提供 CNI 插件,并指导如何与 Docker 集成。
版本
我为每个发布版本打标签,并尽量遵循 语义版本控制。如果您想使用这个角色,建议查看最新的标签。主分支主要用于开发,而标签标记着稳定的发布版本。比如标签 8.0.0+0.16.1
表示这是该角色的版本 8.0.0
,并且是为了与 Flannel 版本 0.16.1
一起使用(但可能也适用于更新的版本)。如果角色本身发生变化,X.Y.Z
在 +
之前会增加;如果 Flannel 版本变化,X.Y.Z
在 +
之后会增加。这使得在为特定的 Flannel 版本开发时可以标记错误修复和新主版本。
要求
- 必须有一个正在运行的
etcd
集群(见 ansible-role-etcd)。该角色将连接到 Ansible 的k8s_etcd
组中的第一个节点,并在那里执行etcdctl
以添加一个新条目到etcd
。该条目包含 Flannel 网络配置,位于 "flannel_etcd_prefix
/config"。 - CNI 插件(见 ansible-role-cni)
更新日志
角色变量
# K8s 服务监听的接口。所有集群
# 通信应该使用 VPN 接口,所以接口名通常是
# "wg0", "tap0" 或 "peervpn0"。
k8s_interface: "tap0"
# Kubernetes 主机上存储 K8s 证书和其他配置的目录。
k8s_conf_dir: "/var/lib/kubernetes"
# CNI 网络插件目录
k8s_cni_conf_dir: "/etc/cni/net.d"
# 复制 K8s 证书的目录。默认情况下,这
# 将展开为运行 "ansible-playbook ..."
# 的用户的本地 $HOME,并加上 "/k8s/certs"。这意味着如果用户的 $HOME 目录是
# "/home/da_user",那么 "k8s_ca_conf_directory" 的值将是
# "/home/da_user/k8s/certs"。
k8s_ca_conf_directory: "{{ '~/k8s/certs' | expanduser }}"
etcd_bin_dir: "/usr/local/bin"
etcd_client_port: 2379
etcd_certificates:
- ca-etcd.pem
- ca-etcd-key.pem
- cert-etcd.pem
- cert-etcd-key.pem
flannel_version: "v0.16.1"
flannel_etcd_prefix: "/kubernetes-cluster/network"
flannel_ip_range: "10.200.0.0/16"
flannel_backend_type: "vxlan"
flannel_cni_interface: "cni0"
flannel_subnet_file_dir: "/run/flannel"
flannel_options_dir: "/etc/flannel"
flannel_bin_dir: "/usr/local/sbin"
flannel_cni_conf_file: "10-flannel"
flannel_cni_spec_version: "0.3.1"
flannel_systemd_restartsec: "5"
flannel_systemd_limitnofile: "40000"
flannel_systemd_limitnproc: "1048576"
# Flannel 的 systemd 服务文件中的 "ExecStartPre" 指令。该命令
# 在 Flannel 服务启动之前执行。
flannel_systemd_execstartpre: "/bin/mkdir -p {{flannel_subnet_file_dir}}"
# Flannel 的 systemd 服务文件中的 "ExecStartPost" 指令。该命令
# 在 Flannel 服务启动后执行。如果您在 Hetzner 云上运行,
# 这可能很重要。在这种情况下,它会更改 "flannel.1" 接口的 TX 校验和卸载
# 参数。似乎有一个 (内核/驱动程序) 校验和卸载 bug,导致 Flannel vxlan 封装
# (都在 UDP 内) 在 WireGuard 封装中出现问题。
# flannel_systemd_execstartpost: "/sbin/ethtool -K flannel.1 tx off"
flannel_settings:
"etcd-cafile": "{{k8s_conf_dir}}/ca-etcd.pem"
"etcd-certfile": "{{k8s_conf_dir}}/cert-etcd.pem"
"etcd-keyfile": "{{k8s_conf_dir}}/cert-etcd-key.pem"
"etcd-prefix": "{{flannel_etcd_prefix}}"
"iface": "{{k8s_interface}}"
"public-ip": "{{hostvars[inventory_hostname]['ansible_' + k8s_interface].ipv4.address}}"
"subnet-file": "{{flannel_subnet_file_dir}}/subnet.env"
"ip-masq": "true"
"healthz-ip": "0.0.0.0"
"healthz-port": "0" # 0 = 禁用
flannel_cni_conf: |
{
"name": "{{flannel_cni_interface}}",
"cniVersion": "{{flannel_cni_spec_version}}",
"plugins": [
{
"type": "flannel",
"delegate": {
"hairpinMode": true,
"isDefaultGateway": true
}
},
{
"type": "portmap",
"capabilities": {
"portMappings": true
}
}
]
}
flannel_settings
中定义的 Flannel 守护进程设置可以通过定义名为 flannel_settings_user
的变量进行覆盖。您也可以使用该变量添加附加设置。例如,若要覆盖 healthz-ip
默认值并添加 kubeconfig-file
设置,可以将以下设置添加到 group_vars/all.yml
或您认为合适的地方:
flannel_settings_user:
"healthz-ip": "1.2.3.4"
"kubeconfig-file": "/etc/k8s/k8s.cfg"
关于 flannel_systemd_execstartpost: "/sbin/ethtool -K flannel.1 tx off"
的说明,默认情况下它被注释掉。如果 Pod 到 Pod 的通信在您这里正常(跨主机),但 Pod 到 Service 或 Node 到 Service 却不正常(同样跨主机),则设置此变量及其内容可能会有所帮助。至少在 Hetzner 云中通过 WireGuard VPN 运行 Flannel 流量时,它是有效的。在这种情况下,TX 卸载可能不起作用,这会导致校验和错误。您可以通过以下方式识别此问题。通过 SSH 登录两个工作节点。识别一个在例如 worker01
上运行的服务,并尝试在 worker02
上访问它。例如,kube-dns
或 coredns
pod 是不错的候选,因为它在每个 Kubernetes 集群中基本上都在运行。尽管 DNS 查询通常是通过 UDP 协议发送的,但 DNS 也可以通过 TCP 工作。因此假设 kube-dns
在 worker01
上运行,而您在 worker02
上尝试通过以下方式连接到 DNS 服务:
telnet 10.32.0.254 53
Trying 10.32.0.254...
但是正如您所见,没有任何响应。所以让我们在 worker01
上运行 tcpdump
,例如 tcpdump -nnvvvS -i any src host <ip_of_worker02>
。现在我们捕获来自 worker02
的所有流量。再次在 worker02
上执行 telnet 10.32.0.254 53
,您可能会看到如下内容:
22:17:18.500515 IP (tos 0x0, ttl 64, id 32604, offset 0, flags [none], proto UDP (17), length 110)
10.8.0.112.43977 > 10.8.0.111.8472: [udp sum ok] OTV, flags [I] (0x08), overlay 0, instance 1
IP (tos 0x10, ttl 63, id 10853, offset 0, flags [DF], proto TCP (6), length 60)
10.200.94.0.40912 > 10.200.1.37.53: Flags [S], cksum 0x74e3 (incorrect -> 0x890f), seq 3891002740, win 43690, options [mss 65495,sackOK,TS val 2436992709 ecr 0,nop,wscale 7], length 0
...
如果您仔细查看最后一行,您会在本示例中看到 cksum 0x74e3 (incorrect -> 0x890f)
,这就是问题所在。由于校验和错误,SYN
数据包被丢弃。现在如果您在所有主机上(至少在 Hetzner 云上)禁用 flannel.1
接口的校验和卸载,问题就解决了:
telnet 10.32.0.254 53
Trying 10.32.0.254...
Connected to 10.32.0.254.
Escape character is '^]'.
...
而如果现在查看 tcpdump
的输出:
22:34:26.605677 IP (tos 0x0, ttl 64, id 794, offset 0, flags [none], proto UDP (17), length 110)
10.8.0.112.59225 > 10.8.0.111.8472: [udp sum ok] OTV, flags [I] (0x08), overlay 0, instance 1
IP (tos 0x10, ttl 63, id 16989, offset 0, flags [DF], proto TCP (6), length 60)
10.200.94.0.42152 > 10.200.1.37.53: Flags [S], cksum 0xd49b (correct), seq 1673757006, win 43690, options [mss 65495,sackOK,TS val 2438020768 ecr 0,nop,wscale 7], length 0
...
您会在最后一行看到校验和是正确的。您可以使用 ethtool -k flannel.1
检查 Flannel 接口的协议卸载状态和其他功能。
依赖项
etcd
(见 ansible-role-etcd)CNI 插件
(见 ansible-role-cni 或任何其他安装 CNI 插件 的角色)
示例 Playbook
- hosts: flannel
roles:
- githubixx.flanneld
许可证
GNU 通用公共许可证 第 3 版