作为服务发现机制的基本功能,在集群内需要能够通过服务名对服务进行访问,这就是需要一个集群范围内的DNS服务来完成从服务名到ClusterIP 地址的解析。DNS服务在Kubernetes 的发展中经历了3个阶段,这里我只讲以CoreDNS 为例,说明KUbernetes 集群DNS 服务的搭建过程。
1. 修改每个Node 上Kubelet 的DNS 启动参数
修改每个Node 上kubelet 的启动参数,在其中加上以下两个参数。
(1)–cluster-dns=169.169.0.100 : 为DNS 服务的CLusterIP 地址 (2)–cluster-domain=cluster.local: 为在DNS 服务中设置的域名
然后重启kubelet 服务。
2. 部署CoreDNS服务
部署CoreDNS 服务时需要创建3个资源对象: 1个ConfigMap,1个Deployment 和 1个Service 。在启用了RBAC 的集群中,还可以设置ServiceAccount ,ClusterRole,ClusterRoleBinding 对CoreDNS 容器进行权限设置。
ConfigMap “coredns” 主要设置CoreDNS 的主要配置文件Corefile 的内容,其中可以定义各种域名的解析方式和使用的插件,示例如下:
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
labels:
addonmanager.kubernetes.io/mode: EnsureExists
data:
Corefile: |
cluster.local {
errors
health {
lameduck 5s
}
ready
kubernetes cluster.local 169.169.0.0/16 {
fallthrouth in-addr.arpa ip6.arpa
}
prometheus :9153
forward . /etc/resolv.conf
cache 30
loop
reload
loadbalance
}
. {
cache 30
loadbalance
forward . /etc/resolv.conf
}
Deployment “coredns” 主要设置CoreDNS 容器应用的内容,其中,replicas 副本的数量通常应该根据集群的规模和服务数量确定,如果单个CoreDNS 进程不足以支撑整个集群的DNS 查询,则可以通过水平扩展提高查询能力。由于DNS服务是Kubernetes 集群的关键核心服务,所以建议为其Deployment 设置自动扩缩控制器,自动管理其副本数量。
另外,对资源限制部分(CPU 限制和内存限制)的设置也应该根据实际环境进行调整:
apiVersion: v1
kind: Deployment
metadata:
name: coredns
namespace: kube-system
labels:
k8s-app: kube-dns
kubernetes.io/name: "CoreDNS"
spec:
replicas: 1
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
selector:
matchLabels:
k8s-app: kube-dns
template:
metadata:
labels:
k8s-app: kube-dns
spec:
priorityClassName: system-cluster-critical
tolerations:
- key: "CriticalAddonsOnly"
operator: "Exists"
nodeSelector:
kubernetes.io/os: linux
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: k8s-app
operator: In
values: ["kube-dns"]
topologyKey: kubernetes.io/hostname
containers:
- name: coredns
image: coredns/coredns:1.7.0
imagePullPolicy: IfNotPresent
resources:
limits:
memory: 170Mi
requests:
cpu: 100m
memory: 70Mi
args: ["-conf","/etc/coredns/Corefile"]
volumeMounts:
- name: config-volume
mountPath: /etc/coredns
readOnly: true
ports:
- containerPort: 53
name: dns
protocol: UDP
- containerPort: 53
name: dns-tcp
protocol: TCP
- containerPort: 9153
name: metrics
protocol: TCP
securityContext:
allowPrivilegeEscalation: false
capabilities:
add:
- NET_BIND_SERVICE
drop:
- all
readOnlyRootFilesystem: true
livenessProbe:
httpGet:
path: /health
port: 8080
scheme: HTTP
initialDeplaySeconds: 60
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 5
readinessProbe:
httpGet:
path: /ready
port: 8181
scheme: HTTP
dnsPolicy: Default
volumes:
- name: config-volume
configMap:
name: coredns
items:
- key: Corefile
path: Corefile
Serive “kube-dns” 是DNS 服务的配置,这个服务需要设置固定的CLusterIP地址,也需要将所有Node 上的kubelet 启动参数 --cluster-dns 都设置为这个CLusterIP地址:
apiVersion: v1
kind: Service
metadata:
name: kube-dns
namespace: kube-system
annotations:
prometheus.io/port: "9153"
prometheus.io/scrape: "true"
labels:
k8s-app: kube-dns
kubernetes.io/cluster-service: "true"
kubernetes.io/name: "CoreDNS"
spec:
selector:
k8s-app: kube-dns
clusterIP: 169.169.0.100
ports:
- name: dns
port: 53
protocol: UDP
- name: dns-tcp
port: 53
protocol: TCP
- name: metrics
port: 9153
protocol: TCP
通过kubectl create 命令完成CoreDNS 服务的创建:
$ kubectl create -f coredns.yaml
$ kubectl get deployment --namespace=kube-system
NAME READY UP-TO-DATE AVAILABLE AGE
coredns 1/1 1 1 33h
$ kubectl get pods --namespace=kube-system
NAME READY STATUS RESTARTS AGE
coredns-98fasdff0-vcdnh 1/1 Running 2 33h
$ kubectl get service --namespace=kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP. 169.169.0.100 <none>. 53/UDP,53/TCP,9153/TCP 33h
3. 服务名的DNS 解析
接下来使用一个带有nslookup 工具来验证DNS 服务能否正常工作:
apiVersion: v1
kind: Pod
metadata:
name: busybox
namespace: default
spec:
containers:
- name: busybox
image: gcr.io/google_containers/busybox
command:
- sleep
- "3600"
运行kubectl create -f busbox.yaml 即可完成创建。
在盖容器成功启动后,通过kubectl exec <container_id>. – nslookup 进行测试:
$ kubectl exec busybox -- nslookup redis-master
Service: 169.169.0.100
Address 1: 169.169.0.100
Name: redis-master
Address 1: 169.169.8.10
可以看到,通过DNS 服务器169.169.0.100 成功解析了redis-master.服务的IP地址 169.169.8.10。
如果某个Service 属于不同的命名空间,那么在进行Service 查找时,需要补充Namespace 的名称,将其组合成完整的域名,下面以查找kube-dns 服务为例,将其所在Namespace “kube-system” 补充在服务名之后 ,用“. ” 连接为"kube-dns.kube-system",即可查询成功:
$ kubectl exec busybox -- nslookup kube-dns.kube-system
Server: 169.169.0.100
Address 1: 169.169.0.100
Name: kube-dns.kube-system
Address 1: 169.169.0.100
如果仅使用“kube-dns” 进行查找则会失败:
nslookup: can't resolve 'kube-dns'
|