docker - 从基于 Alpine 的 k8s pod 访问服务会引发 DNS 解析错误
问题描述
我有 pod A(它实际上是 kube-scheduler pod)和 pod B(一个具有 REST API 的 pod,它将由 pod A 调用)。
为此,我创建了一个 ClusterIP 服务。
现在,当我执行到 pod A 以执行对 pod B 的 API 调用时,我得到:
curl: (6) Could not resolve host: my-svc.default.svc.cluster.local
我尝试按照此处提到的调试说明进行操作:
kubectl exec -i -t dnsutils -- nslookup my-svc.default
Server: 10.96.0.10
Address: 10.96.0.10#53
Name: my-svc.default.svc.cluster.local
Address: 10.111.181.13
还:
kubectl exec -i -t dnsutils -- nslookup kubernetes.default
Server: 10.96.0.10
Address: 10.96.0.10#53
Name: kubernetes.default.svc.cluster.local
Address: 10.96.0.1
这似乎按预期工作。但是,当我执行到 pod A 时,我得到:
kubectl exec -it kube-scheduler -n kube-system -- sh
/bin # nslookup kubernetes.default
Server: 8.8.8.8
Address: 8.8.8.8:53
** server can't find kubernetes.default: NXDOMAIN
** server can't find kubernetes.default: NXDOMAIN
其他调试步骤(在 pod A 内)包括:
/bin # cat /etc/resolv.conf
nameserver 8.8.8.8
nameserver 172.30.0.1
和:
/bin # cat /etc/*-release
3.12.8
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.12.8
PRETTY_NAME="Alpine Linux v3.12"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://bugs.alpinelinux.org/"
coredns pod 也没有有用的日志。
kubectl logs --namespace=kube-system -l k8s-app=kube-dns
.:53
[INFO] plugin/reload: Running configuration MD5 = db32ca3650231d74073ff4cf814959a7
CoreDNS-1.7.0
linux/amd64, go1.14.4, f59c03d
.:53
[INFO] plugin/reload: Running configuration MD5 = db32ca3650231d74073ff4cf814959a7
CoreDNS-1.7.0
linux/amd64, go1.14.4, f59c03d
从文档来看,Alpine 和 DNS 解析似乎存在一个已知问题(即使我拥有的版本高于他们提到的版本)。
是否有解决方法可以从 Alpine pod 正确访问服务?
编辑提供 pod A 清单:
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
component: kube-scheduler
tier: control-plane
name: kube-scheduler
namespace: kube-system
spec:
containers:
- command:
- kube-scheduler
- --authentication-kubeconfig=/etc/kubernetes/scheduler.conf
- --authorization-kubeconfig=/etc/kubernetes/scheduler.conf
- --bind-address=127.0.0.1
- --config=/etc/kubernetes/sched-cs.yaml
- --port=0
image: localhost:5000/scheduler-plugins/kube-scheduler:latest
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 8
httpGet:
host: 127.0.0.1
path: /healthz
port: 10259
scheme: HTTPS
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 15
name: kube-scheduler
resources:
requests:
cpu: 100m
startupProbe:
failureThreshold: 24
httpGet:
host: 127.0.0.1
path: /healthz
port: 10259
scheme: HTTPS
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 15
volumeMounts:
- mountPath: /etc/kubernetes/scheduler.conf
name: kubeconfig
readOnly: true
- mountPath: /etc/kubernetes/sched-cs.yaml
name: sched-cs
readOnly: true
hostNetwork: true
priorityClassName: system-node-critical
volumes:
- hostPath:
path: /etc/kubernetes/scheduler.conf
type: FileOrCreate
name: kubeconfig
- hostPath:
path: /etc/kubernetes/sched-cs.yaml
type: FileOrCreate
name: sched-cs
status: {}
编辑 2:手动添加以下行到/etc/resolv.conf
Pod A 允许我成功执行 curl 请求。
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5
难道没有更清洁/更少手动的方法来实现相同的结果吗?
解决方案
尝试将DNSPolicy
for pod A(或任何部署、statefulset 等)定义其模板设置为ClusterFirst
or ClusterFirstWithHostNet
。
此设置的行为取决于您的集群和 kubelet 的设置方式,但在大多数默认配置中,这将使 pod 内的 kubelet 设置 resolv.conf 以使用您在编辑中手动设置的 kube-dns 服务 (10.96. 0.10),它将集群外部的查找转发到主机的名称服务器。
推荐阅读
- javascript - Firebase Firestore 仅允许用户在有过滤器的情况下查询集合
- pytorch - torch.autograd.profiler.profile 中每个条目的含义
- python - 重新编号一维数组的元素
- c - st_mode 未返回 S_IXXX 比较的预期值
- python-3.x - 错误:无法创建'/usr/local/lib/python3.9/site-packages/_portaudio.cpython-39-x86_64-linux-gnu.so':权限被拒绝
- python-3.x - 我最后一个密集的 keras 层有什么问题?
- javascript - 有没有一种方法可以在点击一定次数后禁用 ReactJS 中的按钮?
- android - 通过命令行混淆 Android 源文件并生成 APK
- node.js - 全局 Knex.raw 已弃用,使用 knex.raw (链接一个初始化的 knex 对象)
- amazon-web-services - AWS ELB - SSL/TLS 终止混淆