service name 和service ip之间的解析
Cluster DNS 监视api server上对所有service资源的创建、删除、变更操作
例如service的ip变动, 在内部生成新的 DNS和IP的记录
DNS的三种记录
- servicename --> serviceip
- PTR serviceip --> servicename
- service name ---> service Port
Cluster DNS
Cluster DNS(CoreDNS)是Kubernetes集群的必备附件,负责为Kubernetes提供名称解析和服务发现
-
每个Service资源对象,在CoreDNS上都会自动生成一个遵循格式的名称
<service>.<ns>.svc.<zone>- 当前Service对象的名称
- 当前Service对象所属的名称空间
- 当前Kubernetes集群使用的域名后缀,默认为“cluster.local”
-
围绕该名称会生成一些DNS格式的资源记录
举例
nfs namespace下部署了一个nfs-server
DNS为
nfs-server.nfs.svc.cluster.local
DNS搜索域
Cluster DNS 监听apiserver上所有服务的创建 变更
Pod中各容器默认会在/etc/resolv.conf中,将nameserver指向CoreDNS相关的Service的ClusterIP
由kubelet创建Pod时根据指定的配置自动注入
pod中会自动配置 /etc/resolv.conf
cat /etc/resolv.conf
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local
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记录
为每个定义了名称的端口生成一个SRV记录,以支持服务发现
_<port>._<proto>.<service>.<ns>.svc.<zone>. <ttl> IN SRV <weight> <priority> <port-number> <service>.<ns>.svc.<zone>.
PTR资源记录
为每个A记录(例如a.b.c.d)或AAAA记录生成对应的PTR记录,例如
<d>.<c>.<b>.<a>.in-addr.arpa. <ttl> IN PTR <service>.<ns>.svc.<zone>.
h4.h3.h2.h1.g4.g3.g2.g1.f4.f3.f2.f1.e4.e3.e2.e1.d4.d3.d2.d1.c4.c3.c2.c1.b4.b3.b2.b1.a4.a3.a2.a1.ip6.arpa <ttl> IN PTR <service>.<ns>.svc.<zone>.
Pod可基于Service的DNS名称向其发起服务访问请求
特殊类型的除外
- externalname
- 静态endpoint
- headless service
Pod上的DNS解析策略
两个特殊的svc
kubernetes 使用service网络的第一个地址
kube-dns 使用service网络的第10个地址
Kubernetes支持在单个Pod资源规范上自定义DNS解析策略和配置,并组合生效
- spec.dnsPolicy:DNS解析策略
- spec.dnsConfig:名称解析机制
DNS解析策略 参数解释
- Default
- 一律交给节点上的DNS 运行的节点继承DNS解析相关的配置
- ClusterFirst
- pod默认的解析策略
- coredns先解析优先
- 于集群DNS服务上 解析集群域内的名称
- 其他域名的解析则交由从节点继承而来的上游名称服务器
- ClusterFirstWithHostNet
- 特殊的场景
- 集群内部的coredns先解析 然后再交给节点上的DNS
- 专用于在设置了hostNetwork的Pod对象上 使用的ClusterFirst策略
- None
- 不使用自动配置功能了 需要手工配置
- 用于忽略Kubernetes集群的默认设定,而仅使用由dnsConfig自定义的配置
DNS解析机制
-
nameservers <[]string>:DNS名称服务器列表,附加于由dnsPolicy生成的DNS名称服务器之后
-
searches <[]string>:DNS名称解析时的搜索域,附加由于dnsPolicy生成的搜索域之后
-
options <[]Object>:DNS解析选项列表,同dnsPolicy生成的解析选项合并成最终生效的定义
自定义配置示例
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"
创建 ExternalName 示例
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: {}
pod中解析的情况
创建 headless 示例
yml配置
# Maintainer: MageEdu <mage@magedu.com>
# URL: http://www.magedu.com
---
kind: Service
apiVersion: v1
metadata:
name: demoapp-headless-svc
spec:
clusterIP: None
selector:
app: demoapp
ports:
- port: 80
targetPort: 80
name: http
kubectl get svc demoapp-headless-svc -o yaml
root@k8s-node01:~/learning-k8s/examples/services# kubectl get svc demoapp-headless-svc -o yaml
apiVersion: v1
kind: Service
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"demoapp-headless-svc","namespace":"default"},"spec":{"clusterIP":"None","ports":[{"name":"http","port":80,"targetPort":80}],"selector":{"app":"demoapp"}}}
creationTimestamp: "2023-10-24T07:32:50Z"
name: demoapp-headless-svc
namespace: default
resourceVersion: "245102"
uid: db844a61-45fe-4061-bd85-8dc0ba75ff26
spec:
clusterIP: None
clusterIPs:
- None
internalTrafficPolicy: Cluster
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
app: demoapp
sessionAffinity: None
type: ClusterIP
status:
loadBalancer: {}
root@k8s-node01:~/learning-k8s/examples/services#
kubectl describe svc demoapp-headless-svc
root@k8s-node01:~/learning-k8s/examples/services# kubectl describe svc demoapp-headless-svc
Name: demoapp-headless-svc
Namespace: default
Labels: <none>
Annotations: <none>
Selector: app=demoapp
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: None
IPs: None
Port: http 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.1.14:80,10.244.1.15:80,10.244.2.19:80
Session Affinity: None
Events: <none>
手工创建endpoint示例
apiVersion: discovery.k8s.io/v1beta1
kind: EndpointSlice
metadata:
name: demoapp-01
labels:
kubernetes.io/service-name: demoapp
addressType: IPv4
ports:
- name: http
protocol: TCP
port: 80
endpoints:
- addresses:
- "10.244.1.111"
conditions:
ready: true
- addresses:
- "10.244.1.222"
conditions:
ready: true
pod中 /etc/resolv.conf 配置的nameserver 是dns的ENDPOINTS
kubelet的配置文件中也需要配置正确的clusterDNS