Kubernetes CoreDNS pods 不断重启
Kubernetes CoreDNS pods are endlessly restarting
我正在使用 flannel 在 CentOS 7 上安装三节点 kubernetes 集群一段时间,但是 CoreDNS pods 无法连接到 API 服务器并不断重启。
我遵循的参考 HowTo 文档是 here。
到目前为止我做了什么?
- 禁用 SELinux,
- 禁用
firewalld
,
- 已启用
br_netfilter
、bridge-nf-call-iptables
、
- 在三个节点上安装了 kubernetes,使用 flannel 默认网络设置 master 的 pod 网络 (
10.244.0.0/16
),
- 安装了其他两个节点,并加入了master。
- 已部署法兰绒,
- 配置 Docker 的 BIP 以使用法兰绒默认的每个节点子网和网络。
当前状态
- kubelet 工作并且集群报告节点准备就绪。
- Cluster 可以调度和迁移 pods,因此 CoreDNS 在节点上生成。
- Flannel 网络已连接。容器中没有日志,我可以从一个节点到另一个节点 ping
10.244.0.0/24
个网络。
- Kubernetes 可以部署和 运行 任意 pods(已尝试 shell demo,并且可以通过
kubectl
访问它的 shell 即使容器在不同的节点。
- 但是,由于 DNS 不工作,他们无法解析任何 IP 地址。
问题是什么?
CoreDNS pods 报告他们无法连接到 API 服务器并出现错误:
Failed to list *v1.Namespace: Get https://10.96.0.1:443/api/v1/namespaces?limit=500&resourceVersion=0: dial tcp 10.96.0.1:443: connect: no route to host
我在路由表中看不到 10.96.0.0
路由:
default via 172.16.0.1 dev eth0 proto static metric 100
10.1.0.0/24 dev eth1 proto kernel scope link src 10.1.0.202 metric 101
10.244.0.0/24 via 10.244.0.0 dev flannel.1 onlink
10.244.1.0/24 dev docker0 proto kernel scope link src 10.244.1.1
10.244.1.0/24 dev cni0 proto kernel scope link src 10.244.1.1
10.244.2.0/24 via 10.244.2.0 dev flannel.1 onlink
172.16.0.0/16 dev eth0 proto kernel scope link src 172.16.0.202 metric 100
附加信息
- 使用命令
kubeadm init --apiserver-advertise-address=172.16.0.201 --pod-network-cidr=10.244.0.0/16
. 完成集群初始化
- 我已经拆除集群并用 1.12.0 重建了问题仍然存在。
- Kubernetes documentation 中的解决方法不起作用。
- 问题存在并且与
1.11-3
和 1.12-0
CentOS7 软件包相同。
到目前为止的进展
- 已将 Kubernetes 降级为
1.11.3-0
。
- 使用
kubeadm init --apiserver-advertise-address=172.16.0.201 --pod-network-cidr=10.244.0.0/16
重新初始化 Kubernetes,因为服务器有另一个无法通过其他主机访问的外部 IP,并且 Kubernetes 倾向于 select 该 IP 作为 API 服务器 IP . --pod-network-cidr
由 flannel 授权。
初始化后的结果 iptables -L
输出 没有加入节点
Chain INPUT (policy ACCEPT)
target prot opt source destination
KUBE-EXTERNAL-SERVICES all -- anywhere anywhere ctstate NEW /* kubernetes externally-visible service portals */
KUBE-FIREWALL all -- anywhere anywhere
Chain FORWARD (policy ACCEPT)
target prot opt source destination
KUBE-FORWARD all -- anywhere anywhere /* kubernetes forwarding rules */
DOCKER-USER all -- anywhere anywhere
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
KUBE-SERVICES all -- anywhere anywhere ctstate NEW /* kubernetes service portals */
KUBE-FIREWALL all -- anywhere anywhere
Chain DOCKER-USER (1 references)
target prot opt source destination
RETURN all -- anywhere anywhere
Chain KUBE-EXTERNAL-SERVICES (1 references)
target prot opt source destination
Chain KUBE-FIREWALL (2 references)
target prot opt source destination
DROP all -- anywhere anywhere /* kubernetes firewall for dropping marked packets */ mark match 0x8000/0x8000
Chain KUBE-FORWARD (1 references)
target prot opt source destination
ACCEPT all -- anywhere anywhere /* kubernetes forwarding rules */ mark match 0x4000/0x4000
Chain KUBE-SERVICES (1 references)
target prot opt source destination
REJECT udp -- anywhere 10.96.0.10 /* kube-system/kube-dns:dns has no endpoints */ udp dpt:domain reject-with icmp-port-unreachable
REJECT tcp -- anywhere 10.96.0.10 /* kube-system/kube-dns:dns-tcp has no endpoints */ tcp dpt:domain reject-with icmp-port-unreachable
看起来 API 服务器已按预期部署
$ kubectl get svc kubernetes -o=yaml
apiVersion: v1
kind: Service
metadata:
creationTimestamp: 2018-10-25T06:58:46Z
labels:
component: apiserver
provider: kubernetes
name: kubernetes
namespace: default
resourceVersion: "6"
selfLink: /api/v1/namespaces/default/services/kubernetes
uid: 6b3e4099-d823-11e8-8264-a6f3f1f622f3
spec:
clusterIP: 10.96.0.1
ports:
- name: https
port: 443
protocol: TCP
targetPort: 6443
sessionAffinity: None
type: ClusterIP
status:
loadBalancer: {}
然后我用
应用了 flannel 网络 pod
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
我一应用flannel网络,CoreDNSpods启动,开始报同样的错误:
Failed to list *v1.Endpoints: Get https://10.96.0.1:443/api/v1/endpoints?limit=500\u0026resourceVersion=0: dial tcp 10.96.0.1:443: connect: no route to host
我发现 flanneld
使用了错误的网络接口,并在部署前在 kube-flannel.yml
文件中进行了更改。然而结果还是一样
非常感谢任何帮助。
这基本上是说您的 coredns pod 无法与 kube-apiserver 通信。 kube-apiserver 通过这些环境变量暴露在 pod 中:KUBERNETES_SERVICE_HOST=10.96.0.1
和 KUBERNETES_SERVICE_PORT_HTTPS=443
我相信您发布的路由是主机上的路由,因为这是您在 pod 容器中 运行 ip routes
时得到的路由:
root@xxxx-xxxxxxxxxx-xxxxx:/# ip route
default via 169.254.1.1 dev eth0
169.254.1.1 dev eth0 scope link
root@xxxx-xxxxxxxxxx-xxxxx:/#
在任何情况下,您都不会看到 10.96.0.1
,因为它是使用 iptables 在集群中公开的。那么那个地址是什么?碰巧是默认命名空间中的一个 service
,名为 kubernetes
。该服务的 ClusterIP
是 10.96.0.1
,它正在侦听端口 443
,它还映射到 targetPort
6443
,这是您的 kube-apiserver 运行宁.
因为你可以部署 pods,等等。看起来 kube-apiserver 没有关闭,那不是你的问题。所以很可能你错过了那个服务(或者有一些 iptable 规则不允许你连接到它)。你可以在这里看到它,例如:
$ kubectl get svc kubernetes
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 92d
完整的输出是这样的:
$ kubectl get svc kubernetes -o=yaml
apiVersion: v1
kind: Service
metadata:
creationTimestamp: 2018-07-23T21:10:22Z
labels:
component: apiserver
provider: kubernetes
name: kubernetes
namespace: default
resourceVersion: "24"
selfLink: /api/v1/namespaces/default/services/kubernetes
uid: xxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx
spec:
clusterIP: 10.96.0.1
ports:
- name: https
port: 443
protocol: TCP
targetPort: 6443
sessionAffinity: None
type: ClusterIP
status:
loadBalancer: {}
所以如果你遗漏了它,你可以这样创建它:
cat <<EOF
apiVersion: v1
kind: Service
metadata:
labels:
component: apiserver
provider: kubernetes
name: kubernetes
namespace: default
spec:
clusterIP: 10.96.0.1
ports:
- name: https
port: 443
protocol: TCP
targetPort: 6443
sessionAffinity: None
type: ClusterIP
EOF | kubectl apply -f -
我已经解决了这个问题。原因是缺乏经验、缺乏文档和一些旧的、不再正确的信息。
将要使用安装的人告诉我 Docker 的网桥需要与 Flannel 网络在同一子网中,因此我编辑了 Docker 的网桥。
然而,当 Kubernetes 开始使用 CNI 时,这个要求不仅变得不必要,而且完全错误。 cni0
和 docker0
在同一个网络上使用相同的 IP 地址总是感觉不对,但由于我是 Kubernetes 的完全初学者,我忽略了我的直觉。
因此,我将 Docker 的网络重置为默认值,拆除集群并重建它。现在一切正常。
TL;DR: 如果您正在设置最新的 Kubernetes 版本,则永远不要触摸 Docker 的网络参数。只需安装 Docker,初始化 Kubernetes 并部署 Flannel。 Kubernetes 和 CNI 将负责容器到 Flannel 的传输。
我以前遇到过这个。 Firewalld 已将端口 6443 打开到我的真实 LAN IP,但它仍然禁用其他端口,因此我尝试通过 CMD 关闭防火墙:
systemctl stop firewalld
它有效并且来自 kubectl 日志的所有异常都消失了,所以根本原因是您的 linux 服务器的防火墙规则。
此步骤解决了我的问题:
systemctl stop kubelet
systemctl stop docker
iptables --flush
iptables -tnat --flush
systemctl start kubelet
systemctl start docker
我正在使用 flannel 在 CentOS 7 上安装三节点 kubernetes 集群一段时间,但是 CoreDNS pods 无法连接到 API 服务器并不断重启。
我遵循的参考 HowTo 文档是 here。
到目前为止我做了什么?
- 禁用 SELinux,
- 禁用
firewalld
, - 已启用
br_netfilter
、bridge-nf-call-iptables
、 - 在三个节点上安装了 kubernetes,使用 flannel 默认网络设置 master 的 pod 网络 (
10.244.0.0/16
), - 安装了其他两个节点,并加入了master。
- 已部署法兰绒,
- 配置 Docker 的 BIP 以使用法兰绒默认的每个节点子网和网络。
当前状态
- kubelet 工作并且集群报告节点准备就绪。
- Cluster 可以调度和迁移 pods,因此 CoreDNS 在节点上生成。
- Flannel 网络已连接。容器中没有日志,我可以从一个节点到另一个节点 ping
10.244.0.0/24
个网络。 - Kubernetes 可以部署和 运行 任意 pods(已尝试 shell demo,并且可以通过
kubectl
访问它的 shell 即使容器在不同的节点。- 但是,由于 DNS 不工作,他们无法解析任何 IP 地址。
问题是什么?
CoreDNS pods 报告他们无法连接到 API 服务器并出现错误:
Failed to list *v1.Namespace: Get https://10.96.0.1:443/api/v1/namespaces?limit=500&resourceVersion=0: dial tcp 10.96.0.1:443: connect: no route to host
我在路由表中看不到
10.96.0.0
路由:default via 172.16.0.1 dev eth0 proto static metric 100 10.1.0.0/24 dev eth1 proto kernel scope link src 10.1.0.202 metric 101 10.244.0.0/24 via 10.244.0.0 dev flannel.1 onlink 10.244.1.0/24 dev docker0 proto kernel scope link src 10.244.1.1 10.244.1.0/24 dev cni0 proto kernel scope link src 10.244.1.1 10.244.2.0/24 via 10.244.2.0 dev flannel.1 onlink 172.16.0.0/16 dev eth0 proto kernel scope link src 172.16.0.202 metric 100
附加信息
- 使用命令
kubeadm init --apiserver-advertise-address=172.16.0.201 --pod-network-cidr=10.244.0.0/16
. 完成集群初始化
- 我已经拆除集群并用 1.12.0 重建了问题仍然存在。
- Kubernetes documentation 中的解决方法不起作用。
- 问题存在并且与
1.11-3
和1.12-0
CentOS7 软件包相同。
到目前为止的进展
- 已将 Kubernetes 降级为
1.11.3-0
。 - 使用
kubeadm init --apiserver-advertise-address=172.16.0.201 --pod-network-cidr=10.244.0.0/16
重新初始化 Kubernetes,因为服务器有另一个无法通过其他主机访问的外部 IP,并且 Kubernetes 倾向于 select 该 IP 作为 API 服务器 IP .--pod-network-cidr
由 flannel 授权。 初始化后的结果
iptables -L
输出 没有加入节点Chain INPUT (policy ACCEPT) target prot opt source destination KUBE-EXTERNAL-SERVICES all -- anywhere anywhere ctstate NEW /* kubernetes externally-visible service portals */ KUBE-FIREWALL all -- anywhere anywhere Chain FORWARD (policy ACCEPT) target prot opt source destination KUBE-FORWARD all -- anywhere anywhere /* kubernetes forwarding rules */ DOCKER-USER all -- anywhere anywhere Chain OUTPUT (policy ACCEPT) target prot opt source destination KUBE-SERVICES all -- anywhere anywhere ctstate NEW /* kubernetes service portals */ KUBE-FIREWALL all -- anywhere anywhere Chain DOCKER-USER (1 references) target prot opt source destination RETURN all -- anywhere anywhere Chain KUBE-EXTERNAL-SERVICES (1 references) target prot opt source destination Chain KUBE-FIREWALL (2 references) target prot opt source destination DROP all -- anywhere anywhere /* kubernetes firewall for dropping marked packets */ mark match 0x8000/0x8000 Chain KUBE-FORWARD (1 references) target prot opt source destination ACCEPT all -- anywhere anywhere /* kubernetes forwarding rules */ mark match 0x4000/0x4000 Chain KUBE-SERVICES (1 references) target prot opt source destination REJECT udp -- anywhere 10.96.0.10 /* kube-system/kube-dns:dns has no endpoints */ udp dpt:domain reject-with icmp-port-unreachable REJECT tcp -- anywhere 10.96.0.10 /* kube-system/kube-dns:dns-tcp has no endpoints */ tcp dpt:domain reject-with icmp-port-unreachable
看起来 API 服务器已按预期部署
$ kubectl get svc kubernetes -o=yaml apiVersion: v1 kind: Service metadata: creationTimestamp: 2018-10-25T06:58:46Z labels: component: apiserver provider: kubernetes name: kubernetes namespace: default resourceVersion: "6" selfLink: /api/v1/namespaces/default/services/kubernetes uid: 6b3e4099-d823-11e8-8264-a6f3f1f622f3 spec: clusterIP: 10.96.0.1 ports: - name: https port: 443 protocol: TCP targetPort: 6443 sessionAffinity: None type: ClusterIP status: loadBalancer: {}
然后我用
应用了 flannel 网络 podkubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
我一应用flannel网络,CoreDNSpods启动,开始报同样的错误:
Failed to list *v1.Endpoints: Get https://10.96.0.1:443/api/v1/endpoints?limit=500\u0026resourceVersion=0: dial tcp 10.96.0.1:443: connect: no route to host
我发现
flanneld
使用了错误的网络接口,并在部署前在kube-flannel.yml
文件中进行了更改。然而结果还是一样
非常感谢任何帮助。
这基本上是说您的 coredns pod 无法与 kube-apiserver 通信。 kube-apiserver 通过这些环境变量暴露在 pod 中:KUBERNETES_SERVICE_HOST=10.96.0.1
和 KUBERNETES_SERVICE_PORT_HTTPS=443
我相信您发布的路由是主机上的路由,因为这是您在 pod 容器中 运行 ip routes
时得到的路由:
root@xxxx-xxxxxxxxxx-xxxxx:/# ip route
default via 169.254.1.1 dev eth0
169.254.1.1 dev eth0 scope link
root@xxxx-xxxxxxxxxx-xxxxx:/#
在任何情况下,您都不会看到 10.96.0.1
,因为它是使用 iptables 在集群中公开的。那么那个地址是什么?碰巧是默认命名空间中的一个 service
,名为 kubernetes
。该服务的 ClusterIP
是 10.96.0.1
,它正在侦听端口 443
,它还映射到 targetPort
6443
,这是您的 kube-apiserver 运行宁.
因为你可以部署 pods,等等。看起来 kube-apiserver 没有关闭,那不是你的问题。所以很可能你错过了那个服务(或者有一些 iptable 规则不允许你连接到它)。你可以在这里看到它,例如:
$ kubectl get svc kubernetes
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 92d
完整的输出是这样的:
$ kubectl get svc kubernetes -o=yaml
apiVersion: v1
kind: Service
metadata:
creationTimestamp: 2018-07-23T21:10:22Z
labels:
component: apiserver
provider: kubernetes
name: kubernetes
namespace: default
resourceVersion: "24"
selfLink: /api/v1/namespaces/default/services/kubernetes
uid: xxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx
spec:
clusterIP: 10.96.0.1
ports:
- name: https
port: 443
protocol: TCP
targetPort: 6443
sessionAffinity: None
type: ClusterIP
status:
loadBalancer: {}
所以如果你遗漏了它,你可以这样创建它:
cat <<EOF
apiVersion: v1
kind: Service
metadata:
labels:
component: apiserver
provider: kubernetes
name: kubernetes
namespace: default
spec:
clusterIP: 10.96.0.1
ports:
- name: https
port: 443
protocol: TCP
targetPort: 6443
sessionAffinity: None
type: ClusterIP
EOF | kubectl apply -f -
我已经解决了这个问题。原因是缺乏经验、缺乏文档和一些旧的、不再正确的信息。
将要使用安装的人告诉我 Docker 的网桥需要与 Flannel 网络在同一子网中,因此我编辑了 Docker 的网桥。
然而,当 Kubernetes 开始使用 CNI 时,这个要求不仅变得不必要,而且完全错误。 cni0
和 docker0
在同一个网络上使用相同的 IP 地址总是感觉不对,但由于我是 Kubernetes 的完全初学者,我忽略了我的直觉。
因此,我将 Docker 的网络重置为默认值,拆除集群并重建它。现在一切正常。
TL;DR: 如果您正在设置最新的 Kubernetes 版本,则永远不要触摸 Docker 的网络参数。只需安装 Docker,初始化 Kubernetes 并部署 Flannel。 Kubernetes 和 CNI 将负责容器到 Flannel 的传输。
我以前遇到过这个。 Firewalld 已将端口 6443 打开到我的真实 LAN IP,但它仍然禁用其他端口,因此我尝试通过 CMD 关闭防火墙:
systemctl stop firewalld
它有效并且来自 kubectl 日志的所有异常都消失了,所以根本原因是您的 linux 服务器的防火墙规则。
此步骤解决了我的问题:
systemctl stop kubelet
systemctl stop docker
iptables --flush
iptables -tnat --flush
systemctl start kubelet
systemctl start docker