此文为学习《Kubernetes权威指南》和阿里云原生公开课的相关笔记
一、集群范围内的DNS服务:coreDNS
作为服务发现机制的基本功能,在集群内需要能够通过服务名对服务进行访问,这就需要一个进群范围内的DNS服务来完成从服务到ClusterIP的解析。DNS服务在K8s上经历3个阶段的发展,从SkyDNS到KubeDNS,从1.11版本开始来到了coreDNS。
CoreDNS作为K8s集群中的一个容器来提供服务,从K8s Master节点上获取服务信息,建立DNS记录,等待其他Pod查询服务名,解析出服务IP返回给Pod。
下面将尝试新建一个coreDNS服务并作为默认DNS服务器供集群其他Pod使用。
1、新建ConfigMap设置CoreDNS的主配置文件Corefile
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns-test
namespace: kube-system
labels:
addonmanager.kubernetes.io/mode: EnsureExists
data: #Corefile配置内容
Corefile: |
cluster.local {
errors #对错误信息进行日志记录
health #对Endpoint进行健康检查#为域名 cluster.local设置插件
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
upstream
fallthrough in-addr.arpa ip6.arpa
}
prometheus :9153 #为Prometheus系统提供彩金性能指标数据的URL
forward . /etc/resolv.conf
cache 30
loop #检测在DNS解析过程中出现的循环问题
reload #定时重新加载Corefile配置文件的内容
loadbalance #提供基于DNS的负载均衡功能
}
. {
cache 30
loadbalance
forward . /etc/resolv.conf
}
2、新建Deployment配置CoreDNS容器应用
apiVersion: apps/v1
kind: Deployment
metadata:
name: coredns-test
namespace: kube-system
labels:
k8s-app: kube-dns-test
kubernetes.io/cluster-service: "true"
addonmanager.kubernetes.io/mode: Reconcile
kubernetes.io/name: "CoreDns"
spec:
replicas: 1
selector:
matchLabels:
k8s-app: kube-dns-test
strategy: #滚动升级策略
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
template:
metadata:
labels:
k8s-app: kube-dns-test
annotations:
seccomp.security.alpha.kubernetes.io/pod: 'docker/default'
spec:
priorityClassName: system-cluster-critical
tolerations: #容忍定义
- key: "CriticalAddonesOnly"
operator: "Exists"
nodeSelector: #节点选择器
beta.kubernetes.io/os: linux
containers:
- name: coredns
image: coredns/coredns:1.3.1
imagePullPolicy: IfNotPresent
resources: #资源限制
requests:
memory: 70Mi
cpu: 100m
limits:
memory: 170Mi
args: ["-conf","/etc/coredns/Corefile"] #使用挂载文件卷config-volume中的配置文件Corefile
volumeMounts: #将config-volume挂载到容器中
- name: config-volume
mountPath: /etc/coredns
readOnly: true
ports: #开放53端口作为DNS查询入口,9153端口作为衡量指标
- containerPort: 53
name: dns
protocol: UDP
- containerPort: 53
name: dns-tcp
protocol: TCP
- containerPort: 9153
name: metrics
protocol: TCP
livenessProbe: #探针定义
httpGet:
path: /health
port: 8080
scheme: HTTP
initialDelaySeconds: 60
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 5
securityContext:
allowPrivilegeEscalation: false
capabilities:
add:
- NET_BIND_SERVICE
drop:
- all
readOnlyRootFilesystem: true
dnsPolicy: Default
volumes: #将configMap中的Corefile作为文件卷
- name: config-volume
configMap:
name: coredns-test
items:
- key: Corefile
path: Corefile
3、定义Service对外提供DNS服务入口
apiVersion: v1
kind: Service
metadata:
name: kube-dns-test
namespace: kube-system
labels:
k8s-app: kube-dns-test
kubernetes.io/cluster-service: "true"
addonmanager.kubernetes.io/mode: Reconcile
kubernetes.io/name: "CoreDNS"
annotations:
promethus.io/port: "9153"
promethus.io/scrape: "true"
spec:
selector:
k8s-app: kube-dns-test
clusterIP: 10.96.100.100 #定义一个固定的Cluster IP作为服务入口
ports:#将Pod的端口映射到Service,值得注意的是,可以看到,在没有提供targetPort时,默认targetPort与port值相同
- name: dns
port: 53
protocol: UDP
- name: dns-tcp
port: 53
protocol: TCP
- name: metrics
port: 9153
protocol: TCP
4、查看运行情况
可以看到新建的DNS服务kube-dns-test 已经存在于服务列表中,对外开放2个端口,53号端口用于DNS查询
同时可以看到集群中原有的默认dns服务
[root@MiWiFi-R4CM-srv learn-service]# kubectl get svc -A
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
......
kube-system kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 19d
kube-system kube-dns-test ClusterIP 10.96.100.100 <none> 53/UDP,53/TCP,9153/TCP 10h
该服务的后台有一个Pod正在运行
# kubectl get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
default cassandra-b2lbj 1/1 Running 1 7h35m
kube-system coredns-5644d7b6d9-49v79 1/1 Running 16 18d
kube-system coredns-5644d7b6d9-w7fd5 1/1 Running 16 18d
kube-system coredns-test-664f8d9768-5sqjt 1/1 Running 0 4m
......
正如配置的一样,该服务具有三个端点
# kubectl get endpoints -A
NAMESPACE NAME ENDPOINTS AGE
......
kube-system kube-dns 10.32.0.2:53,10.32.0.3:53,10.32.0.2:53 + 3 more... 18d
kube-system kube-dns-test 10.44.0.2:53,10.44.0.2:53,10.44.0.2:9153 67s
......
在节点上可以直接使用该coredns服务进行域名解析
# nslookup cassandra.default.svc.cluster.local 10.96.100.100
Server: 10.96.100.100
Address: 10.96.100.100#53Name: cassandra.default.svc.cluster.local
Address: 10.97.200.71
5、下面将该coredns作为集群的默认dns服务,在Pod内部使用
对kubelet启动配置做出修改:/usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf
添加参数:
- --cluster-dns=<dns-svc-ip>:当前簇dns服务进程的ip地址
- --cluster-domain=cluster.local:在dns服务中设置的域名
需要注意的是,默认DNS这一配置仅限于节点范围,若想修改,应当为每个节点的kubelet都做出上述修改,于此同时,只有修改后建立的Pod才会使用新设置的dns服务器。
修改完成后执行systemctl daemon-reload和systemctl restart kubelet
设置带有nslookup工具的Pod用作测试
apiVersion: v1
kind: Pod
metadata:
name: util-pod
spec:
containers:
- name: util-pod
image: busybox:1.28.3
imagePullPolicy: IfNotPresent
command:
- sleep
- "3600"
尝试使用nslookup通过服务名查询该服务的IP地址
# kubectl exec -it util-pod /bin/sh
/ # nslookup cassandra
Server: 10.96.100.100
Address 1: 10.96.100.100Name: cassandra
Address 1: 10.97.200.71
可以看到,这个Pod已经在使用我们的新coredns服务进行域名解析了。
在测试过程中出现了节点域名解析成功,但在pod内部不成功的情况,解决如下:
https://blog.csdn.net/qq_38093301/article/details/103678396
二、Pod级别的DNS服务配置
在Pod级别上,DNS的策略和配置通过spec.dsnPolicy字段设置,可以设置的策略如下:
- Default:继承Pod所在宿主机的DNS设置。
- ClusterFirst:优先使用K8s环境的DNS服务(如CoreDNS),将无法解析的域名转发到从宿主机继承的DNS服务器。
- ClusterFirstWithHostNet:与ClusterFirst策略相同,以hostNetwork模式运行的Pod应指明该策略。
- None:忽略K8s环境的DNS配置,通过spec.dnsConfig自定义配置。
其中,spec.dnsConfig可以自定义下列DNS信息:
- nameservers:一组DNS服务器列表。
- searches:一组用于域名搜索的DNS域名后缀。
- options:其他DNS参数,如:ndots、timeout。
测试None策略如下:
apiVersion: v1
kind: Pod
metadata:
name: dns-example
spec:
containers:
- name: test
image: nginx
imagePullPolicy: Never
ports:
- containerPort: 80
dnsConfig: #通过spec.dnsConfig自定义DNS信息
nameservers:
- 1.2.3.4
searches:
- nsl.svc.cluster.local
- my.dns.search.suffix
options:
- name: ndots
value: "2"
- name: edns0
与教程不同的时,在None策略下,K8s同样为Pod给出了集群中默认的DNS服务地址
# kubectl exec -it dns-example /bin/sh
# cat /etc/resolv.conf
nameserver 10.96.0.10
nameserver 1.2.3.4
search default.svc.cluster.local svc.cluster.local cluster.local Node1 nsl.svc.cluster.local my.dns.search.suffix
options ndots:2 edns0