【问题标题】:How can I get CoreDNS to resolve on my Raspberry Pi Kubernetes cluster?如何让 CoreDNS 在我的 Raspberry Pi Kubernetes 集群上解析?
【发布时间】:2021-02-24 11:46:40
【问题描述】:

我遵循了许多在线教程,在四个 Raspberry Pi 4 上设置了 Kubernetes 集群。我最终使用 Flannel 作为网络插件,因为它似乎是唯一可以在 RPi 上实际运行的插件,Pod 网络 CIDR 为 10.244.0.0/16,每 this guide from 2017。大多数一切都在工作...... kube-system 命名空间中的所有基本 pod 都在运行/健康,我可以拉下图像并启动新容器。起初我无法获取任何 pod 日志,但通过在每个节点上打开端口 10250 很快就解决了这个问题。

但似乎仍然存在 DNS 解析问题。我应该澄清一下,主机上的 DNS 解析确实有效,因为集群能够下载我指定的任何容器映像。但是一旦容器运行,它就不能“拨出”任何东西。作为测试,我在 pod 中运行 arm32v7/buildpack-deps:latest 容器。它可以很好地从 Docker 集线器中提取图像。但是当我进入它并简单地输入curl https://www.google.com 时,它会在最终超时之前挂起。我启动的任何需要与外部 Internet 交互的 pod 也是如此:它们挂起、挂起、挂起。

以下是我已经在每个节点上运行的所有与网络相关的命令:

sudo iptables -P FORWARD ACCEPT
sudo iptables -A FORWARD -i cni0 -j ACCEPT
sudo iptables -A FORWARD -o cni0 -j ACCEPT
sudo ufw allow ssh
sudo ufw allow 443  # can't remember why i ran this one
sudo ufw allow 6443
sudo ufw allow 8080 # this one might not be strictly necessary, either
sudo ufw allow 10250
sudo ufw default allow routed
sudo ufw enable

我不完全确定最后两个iptables 命令有什么作用;我从the comment section of that guide I linked to earlier 抓到了它们。我知道该指南假设一个人使用的是 kube-dns,但它也有 3 年的历史,所以我使用的是(较新的)默认值 coredns。

我错过了什么?我觉得我已经接近让这个集群完全运行,但显然我需要正常运行的 DNS!

更新:我知道这是一个 DNS 问题,而不是一般的 Internet 连接问题,原因有两个:(1) 集群本身可以从 Dockerhub 中提取我指定的任何图像,以及 (2) 当我进入一个正在运行的容器时具有 curl 并执行 curl -H "Host: www.google.com" 142.250.73.206 的,它成功返回了 Google 主页 HTML。但如前所述,如果我尝试使用主机名执行之前的 curl 命令,则会超时。

【问题讨论】:

  • 这个讨论可能会有所帮助:github.com/kubernetes/kubernetes/issues/44833
  • 这很有趣/很有希望!当我在一个正在运行的容器上查看 /etc/resolv.conf 的内容时,它确实指向 10.96.0.10。我最初用来启动集群的命令是这个:sudo kubeadm init --token-ttl=0 --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=192.168.1.194(因为 192.168.1.194 是我的主节点 RPI 的本地 IP)。根据该评论的内容,听起来我需要为此添加一个额外的选项:--cluster-dns=100.64.0.10。这听起来对你@ofirule 正确吗?还是应该改用我的 192.168.1.194 IP?
  • 根据github.com/kubernetes/kubernetes/issues/33881,kube-dns 服务是network-cidr 的一部分,可能会转到 10.244.0.10 ,但这是您必须检查的内容。
  • 我不这么认为。当我进入一个正在运行的容器并输入 dig @10.244.0.10 google.com 时,它仍然超时。
  • 我猜cluster-dns=8.8.8.8 会起作用。但这不是 Kubernetes 的方式

标签: kubernetes coredns ufw


【解决方案1】:
  1. 创建一个简单的 Pod 用作 DNS 诊断的测试环境:
apiVersion: v1
kind: Pod
metadata:
  name: dnsutils
  namespace: default
spec:
  containers:
  - name: dnsutils
    image: gcr.io/kubernetes-e2e-test-images/dnsutils:1.3
    command:
      - sleep
      - "3600"
    imagePullPolicy: IfNotPresent
  restartPolicy: Always
kubectl apply -f dnsutils.yaml
  1. 检查 Pod 的状态
$ kubectl get pods dnsutils
NAME      READY     STATUS    RESTARTS   AGE
dnsutils   1/1       Running   0          <some-time>

Pod 运行后,您可以在该环境中执行 nslookup。如果您看到类似以下内容,则表明 DNS 工作正常。

$ kubectl exec -i -t dnsutils -- nslookup kubernetes.default

Server:    10.0.0.10
Address 1: 10.0.0.10

Name:      kubernetes.default
Address 1: 10.0.0.1

如果 nslookup 命令失败,请检查以下内容:

  1. 查看 resolv.conf 文件的内部。
kubectl exec -ti dnsutils -- cat /etc/resolv.conf

验证搜索路径和名称服务器是否设置如下(注意搜索路径可能因不同的云提供商而异):

search default.svc.cluster.local svc.cluster.local cluster.local google.internal c.gce_project_id.internal
nameserver 10.0.0.10
options ndots:5

以下错误表明 CoreDNS(或 kube-dns)插件或相关服务存在问题:

$ kubectl exec -i -t dnsutils -- nslookup kubernetes.default

Server:    10.0.0.10
Address 1: 10.0.0.10

nslookup: can't resolve 'kubernetes.default'

OR

Server:    10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local

nslookup: can't resolve 'kubernetes.default'
  1. 检查 DNS pod 是否正在运行
$ kubectl get pods --namespace=kube-system -l k8s-app=kube-dns

NAME                       READY     STATUS    RESTARTS   AGE
...
coredns-7b96bf9f76-5hsxb   1/1       Running   0           1h
coredns-7b96bf9f76-mvmmt   1/1       Running   0           1h
...
  1. 检查 DNS pod 中的错误 下面是一个健康的 CoreDNS 日志示例:
$ kubectl logs --namespace=kube-system -l k8s-app=kube-dns

.:53
2018/08/15 14:37:17 [INFO] CoreDNS-1.2.2
2018/08/15 14:37:17 [INFO] linux/amd64, go1.10.3, 2e322f6
CoreDNS-1.2.2
linux/amd64, go1.10.3, 2e322f6
2018/08/15 14:37:17 [INFO] plugin/reload: Running configuration MD5 = 24e6c59e83ce706f07bcc82c31b1ea1c
  1. 使用 kubectl get service 命令验证 DNS 服务是否已启动。
$ kubectl get svc --namespace=kube-system

NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)             AGE
...
kube-dns     ClusterIP   10.0.0.10      <none>        53/UDP,53/TCP        1h
...
  1. 您可以使用 kubectl get endpoints 命令验证 DNS 端点是否已公开。
$ kubectl get endpoints kube-dns --namespace=kube-system

NAME       ENDPOINTS                       AGE
kube-dns   10.180.3.17:53,10.180.3.17:53    1h
  1. 您可以通过将日志插件添加到 CoreDNS 配置(又名 Corefile)来验证 CoreDNS 是否接收到查询。 CoreDNS 核心文件保存在名为 coredns 的 ConfigMap 中。要对其进行编辑,请使用以下命令:
$ kubectl -n kube-system edit configmap coredns

然后按照以下示例在 Corefile 部分添加日志:

apiVersion: v1
kind: ConfigMap
metadata:
  name: coredns
  namespace: kube-system
data:
  Corefile: |
    .:53 {
        log
        errors
        health
        kubernetes cluster.local in-addr.arpa ip6.arpa {
          pods insecure
          upstream
          fallthrough in-addr.arpa ip6.arpa
        }
        prometheus :9153
        forward . /etc/resolv.conf
        cache 30
        loop
        reload
        loadbalance
    }

保存更改后,Kubernetes 可能需要一两分钟才能将这些更改传播到 CoreDNS pod。 接下来,根据本文档的上述部分进行一些查询并查看日志。如果 CoreDNS pod 正在接收查询,您应该会在日志中看到它们。

以下是日志中的查询示例:

.:53
2018/08/15 14:37:15 [INFO] CoreDNS-1.2.0
2018/08/15 14:37:15 [INFO] linux/amd64, go1.10.3, 2e322f6
CoreDNS-1.2.0
linux/amd64, go1.10.3, 2e322f6
2018/09/07 15:29:04 [INFO] plugin/reload: Running configuration MD5 = 162475cdf272d8aa601e6fe67a6ad42f
2018/09/07 15:29:04 [INFO] Reloading complete
172.17.0.18:41675 - [07/Sep/2018:15:29:11 +0000] 59925 "A IN kubernetes.default.svc.cluster.local. udp 54 false 512" NOERROR qr,aa,rd,ra 106 0.000066649s

【讨论】:

  • 伊朗 IT 怎么了?您应该能够使用1 [dot] "." 空格、2.3.、...、8.,所以列出的逐项列出的项目只需编号点空格或#.
  • 在第 2 步失败,来自 nslookup 命令的响应:;; connection timed out; no servers could be reached
  • 这是 /etc/resolv.conf 的样子:nameserver 10.96.0.10search default.svc.cluster.local svc.cluster.local cluster.localoptions ndots:5
  • 我的 coredns pod 日志有多个对“Reflector ListAndWatch”的引用。最近的日志消息是这样写的:pkg/mod/k8s.io/client-go@v0.18.3/tools/cache/reflector.go:125: Failed to list *v1.Service: Get "https://10.96.0.1:443/api/v1/services?limit=500&amp;resourceVersion=0": net/http: TLS handshake timeoutplugin/ready: Still waiting on: "kubernetes"
  • 事实上,有很多“无法列出...”的日志都引用了 10.96.0.1 并超时。我猜它指向一个无效的IP或什么?我不确定 10.96.0.xx 范围内的任何内容应该是什么。
【解决方案2】:

正如 cmets 中指出的:kubeadm 的配置似乎很好。
您的 pod 具有正确的 /etc/resolv.conf,它们应该可以工作。

很难清楚地确定问题所在 - 这里可能会发生很多事情。
我的猜测:ufw 有问题。
您可以轻松证明:在所有节点上禁用ufw(使用ufw disable)。

我不确定需要哪些端口。我将iptables 用于我的单节点k8s,一开始我遇到了很多FORWARDINPUT 规则的问题。在 docker 中,所有端口都被转发。
所以我猜FORWARD-rules 和/或 dns-ports(53/udp53/tcp)有问题。

祝你好运。

【讨论】:

    猜你喜欢
    • 2019-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-19
    • 2020-11-06
    • 2018-12-25
    • 2019-09-30
    • 2021-03-09
    相关资源
    最近更新 更多