Kubernetes Serrvice名称解析逻辑
Service & Cluster DNS
Cluster DNS (CoreDNS)是Kubernetes集群的必备附件,负责为Kubernetes提供名称解析和服务发现
每个Service资源对象,在CoreDNS上都会自动生成一个遵循“<service>.<ns>.svc.<zone>”格式的名称
<service>:当前Service对象的名称
<ns>:当前Service对象所属的名称空间
<zone>:当前Kubernetes集祥使用的域名后缀,默认为“cluster.local
CoreDNS 会持续监视API Server上的Service资源对象的变动,并实时反映到相关的DNS资源记录中
Pod中各容器默认会在/etc/resolv.conf中,将nameserver指向CoreDNS相关的Service的ClusterIP
由kubelet创建Pod时根据指定的配置自动注入
Service在Cluster DNS上的资源记录
每个Service,在CoreDNS上都会有A/AAAA、SRV和PTR资源记录
#A/AAAA资源记录
<service>.<ns>.svc.<zone>.<ttl> IN A <cluster-ip>
<service>.<ns>.svc.<zone>. <ttl> IN AAAA <cluster-ip>
#为每个定义了名称的端口生成一个SRV记录,以支持服务发现
<port>.<proto>.<service>.<ns>syc.<zone>, <tl> IN SRV <weight> <priority> <port-number><service>.<ns>.svc.<zone>
#为每个A记录(例如a.b.c.d) 或AAAA记录生成对应的PTR记录,例如
<d>.<c>.<b>.<a>.in-addr.arpa. <ttl> IN PT <service>.<ns>.svc.<zone>.
h4.h3.h2.h1.g4,g3.g2.g1.f4.f3.f2.f1.c4.e3.e2.e1.d4.d3.d2.d1.c4.c3,c2.c1 b4.3.b2.b1.a.a3.a2.a1.ip6.arpa <tt> IN PTR<service>.<ns>.svc.<zone>
Pod可基于Service的DNS名称向其发起服务访问请求
Pod上的DNS解析策略
Kubernetes支持在单个Pod资源规范上自定义DNS解析策略和配置,并组合生效
#spec.dnsPolicy: 解析策略
#spec.dnsConfig: 名称解析机制
DNS解析策略
#Default: 从运行在的节点继承DNS名称解析相关的配置
#CusterFirst: 于集群DNS服务上解析集群域内的名称,其他域名的解析则交由从节点继承而来的上游名称服务器
#ClusterFirstWithHostNet: 专用于在设置了hostNetwork的;Pod对象上使用的ClusterFirst策略
#None: 用于忽略Kubernetes集群的默认设定,而仅使用出dnsConfig自定义的配置
DNS解析机制
#nameservers <Istring: DNS名称服务器列表,附加于由dnsPolicy生成的DNS名称服务器之后
#searches <Istring>: DNS名称解析时的搜索域,附加由FdnsPolicv生成的搜索域之后
#options <lObject>: DNS解析选项列表,同dnsPolicy生成的解析选项合并成最终生效的定义
[root@k8s-master01 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
adminbox-5ccff58646-vclm2 0/1 CrashLoopBackOff 641 (2m55s ago) 2d6h
client-10961 0/1 Error 0 2d2h
client-2933 0/1 Error 0 3d3h
demoapp-8f996d868-c4lpt 1/1 Running 0 87m
dowardapi-pod 1/1 Running 2 (2d7h ago) 5d1h
nginx-test-566dbd78d4-72vgg 1/1 Running 0 118m
nginx-test-566dbd78d4-cm8fh 1/1 Running 0 118m
nginx-test-566dbd78d4-cwlmw 1/1 Running 0 118m
nginx-test-566dbd78d4-ht5sf 1/1 Running 1 (2d7h ago) 3d21h
nginx-test-566dbd78d4-mkmnf 1/1 Running 0 118m
[root@k8s-master01 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 5d5h
nginx-loadbalancer-server LoadBalancer 10.110.35.224 192.168.40.51 80:31238/TCP 3d20h
#可查询A记录
[root@k8s-master01 ~]# kubectl exec -it demoapp-8f996d868-c4lpt /bin/sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
[root@demoapp-8f996d868-c4lpt /]# nslookup -query=A nginx-loadbalancer-server.default.svc.cluster.local
Server: 10.96.0.10
Address: 10.96.0.10#53
Name: nginx-loadbalancer-server.default.svc.cluster.local
Address: 10.110.35.224
#可查询PTR记录
[root@demoapp-8f996d868-c4lpt /]# nslookup -query=PTR 224.35.110.10.in-addr.arpa
Server: 10.96.0.10
Address: 10.96.0.10#53
224.35.110.10.in-addr.arpa name = nginx-loadbalancer-server.default.svc.cluster.local.
[root@demoapp-8f996d868-c4lpt /]# cat /etc/resolv.conf
search default.svc.cluster.local svc.cluster.local cluster.local
nameserver 10.96.0.10
options ndots:5
dnsPolicy
# 默认是ClusterFirst
[root@k8s-master01 coredns]# kubectl get pods demoapp-8f996d868-c4lpt -o jsonpath={.spec.dnsPolicy}
ClusterFirst
dnsConfig
vim pod-with-dnspolicy.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-with-dnspolicy
namespace: default
spec:
containers:
- name: demo
image: ikubernetes/demoapp:v1.0
imagePullPolicy: IfNotPresent
dnsPolicy: None
dnsConfig:
nameservers:
- 10.96.0.10
- 223.5.5.5
- 223.6.6.6
searches:
- svc.cluster.local
- cluster.local
- ilinux.io
options:
- name: ndots
value: "5"
[root@k8s-master01 coredns]# kubectl apply -f pod-with-dnspolicy.yaml
pod/pod-with-dnspolicy created
[root@k8s-master01 coredns]# kubectl get pods
NAME READY STATUS RESTARTS AGE
pod-with-dnspolicy 1/1 Running 0 6s
[root@k8s-master01 coredns]# kubectl exec -it pod-with-dnspolicy /bin/sh -- cat /etc/resolv.conf
search svc.cluster.local cluster.local ilinux.io
nameserver 10.96.0.10
nameserver 223.5.5.5
nameserver 223.6.6.6
options ndots:5
External Service - ExternalName
内部客户端流量通过ServiceName发现并访问外部服务
#externalName: redis.ik8s.io
[root@k8s-master01 coredns]# cat externalname-redis-svc.yaml
kind: Service
apiVersion: v1
metadata:
name: externalname-redis-svc
namespace: default
spec:
type: ExternalName
externalName: redis.ik8s.io
ports:
- protocol: TCP
port: 6379
targetPort: 6379
nodePort: 0
selector: {}
[root@k8s-master01 coredns]# kubectl apply -f externalname-redis-svc.yaml
service/externalname-redis-svc created
[root@k8s-master01 coredns]# kubectl get pods
NAME READY STATUS RESTARTS AGE
demoapp-8f996d868-c4lpt 1/1 Running 0 116m
[root@k8s-master01 coredns]# kubectl exec -it demoapp-8f996d868-c4lpt /bin/sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
[root@demoapp-8f996d868-c4lpt /]# nslookup -query=A externalname-redis-svc.default.svc.cluster.local
Server: 10.96.0.10
Address: 10.96.0.10#53
externalname-redis-svc.default.svc.cluster.local canonical name = redis.ik8s.io.
Name: redis.ik8s.io
Address: 1.2.3.4
[root@demoapp-8f996d868-c4lpt /]# nslookup -query=CNAME externalname-redis-svc.default.svc.cluster.local
Server: 10.96.0.10
Address: 10.96.0.10#53
externalname-redis-svc.default.svc.cluster.local canonical name = redis.ik8s.io.