CoreDNS的配置说明
CoreDNS的主要功能是通过插件系统实现的。CoreDNS实现了一种链式插件结构,将DNS的逻辑抽象成了一个个插件,能够灵活的组合使用。
常用的插件如下:
◎ loadbalance:提供基于DNS的负载均衡功能。
◎ loop:检测在DNS解析过程中出现的简单循环问题。
◎ cache:提供前端缓存功能。
◎ health:对Endpoint进行健康检查。
◎ kubernetes:从Kubernetes中读取zone数据。
◎ etcd:从etcd读取zone数据,可以用于自定义域名记录。
◎ file:从RFC1035格式文件中读取zone数据。
◎ hosts:使用/etc/hosts文件或者其他文件读取zone数据,可以用于自定义域名记录。
◎ auto:从磁盘中自动加载区域文件。
◎ reload:定时自动重新加载Corefile配置文件的内容。
◎ forward:转发域名查询到上游DNS服务器。
◎ proxy:转发特定的域名查询到多个其他DNS服务器,同时提供到多个DNS服务器的负载均衡功能。
◎ prometheus:为Prometheus系统提供采集性能指标数据的URL。
◎ pprof:在URL路径/debug/pprof下提供运行时的性能数据。
◎ log:对DNS查询进行日志记录。
◎ errors:对错误信息进行日志记录。
在下面的示例中为域名“cluster.local“设置了一些列插件,包括errors、health、kubernetes、prometheus、forward、cache、loop、reload和loadbalance,在进行域名解析时,这些插件将以从上到下的顺序依次执行:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 1cluster.local{
2 errors
3 health
4 kubernetes cluster.local in-addr.arpa ip6.arpa {
5 pods insecure
6 upstream
7 fallthrough in-addr.arpa ip6.arpa
8
9 }
10 prometheus :9153
11 forward ./etc/resolov.conf
12 cache 30
13 loop
14 reload
15 loadbalance
16}
17
另外,etcd和hosts插件都可以用于用户自定义域名的记录。
下面是使用etcd插件的配置示例,将以 “.com” 结尾的域名记录配置为从etcd中获取,并将域名记录保存在/skydns路径下:
1
2
3
4
5
6
7
8
9
10
11
12
13 1{
2 etcd com{
3 path /skydns
4 endpoint https://20.0.40.51:2379
5 upstreamm /etc/resolv.conf
6
7 }
8 cache 160 com
9 loadbalance
10 proxy . /etc/resolv.cof
11
12}
13
如果用户在etcd中插入一条“10.1.1.1 mycompany.com”DNS记录:
1
2 1etcdctl put /skydns/com/mycompany '{"host": "10.1.1.1", "ttl":60}'
2
库护短应用就能访问域名 “mycompany.com”了:
1
2 1nslookup mycompany.com
2
foreard和proxy插件都可以用于配置上游DNS服务器,当CoreDNS中查询不到域名时,会到其他DNS服务器上进行查询。在实际环境中,可以将kubernetes集群外部的dns纳入CoreDNS,进行统一的DNS管理。
此处实验可以先行了解(没有ca认证不能做成),后面讲到ca认证会详细讲解。
Pod级别的DNS配置说明
除了使用集群范围的DNS服务(如CoreDNS),在Pod级别也能设置DNS相关策略和配置。
在Pod的YAML配置文件中通过spec.dnsPolicy字段设置DNS策略,例如:
1
2
3
4
5
6
7
8
9
10 1apiVersion: v1
2kind: Pod
3metadata:
4 name: nginx
5spec:
6 containers:
7 - name: nginx
8 image: nginx
9 dnsPolicy: Default
10
目前可以设置的DNS策略如下。
◎ Default:继承Pod所在宿主机的DNS设置。
◎ ClusterFirst:优先使用Kubernetes环境的DNS服务(如CoreDNS提供的域名解析服务),将无法解析的域名转发到从宿主机继承的DNS服务器。
◎ ClusterFirstWithHostNet:与ClusterFirst相同,对于以hostNetwork模式运行的Pod,应明确指定使用该策略。
◎ None:忽略Kubernetes环境的DNS配置,通过spec.dnsConfig自定义DNS配置。这个选项从Kubernetes 1.9版本开始引入,到Kubernetes 1.10版本升级为Beta版,到Kubernetes 1.14版本升级为稳定版。
自定义DNS配置可以通过spec.dnsConfig字段进行设置,可以设置下列信息。
◎ nameservers:一组DNS服务器的列表,最多可以设置3个。
◎ searches:一组用于域名搜索的DNS域名后缀,最多可以设置6个。
◎ options:配置其他可选DNS参数,例如ndots、timeout等,以name或name/value对的形式表示。
以下面的dnsConfig为例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 1apiVersion: v1
2kind: Pod
3metadata:
4 namespace: default
5 name: dns-example
6spec:
7 containers:
8 - name: test
9 image: nginx
10 dnsPolicy: "None"
11 dnsConfig:
12 nameservers:
13 - 1.2.3.4
14 searches:
15 - ns1.svc.cluster.local
16 - my.dns.search.suffix
17 options:
18 - name: ndots
19 value: "2"
20 - name: edns0
21
该Pod被成功创建之后,容器内的DNS配置文件/etc/resolv.confg的内容将被系统设置:
表示该Pod完全使用自定义的DNS配置,不再使用kubernetes环境的DNS服务。
Ingress:HTTP7成路由机制
根据前面的Service的使用说明,我们知道Service的表现形式为IP:Port,即工作在TCP/IP层。而对于基于HTTP的服务来说,不同的URL地址经常对应到不同的后端服务或者虚拟服务器(Virtual Host),这些应用层的转发机制仅通过Kubernetes的Service机制是无法实现的。
从Kubernetes1.1版本开始新增Ingress资源对象,用于将不同URL的访问请求转发到后端不同的Service,以实现HTTP层的业务路由机制。Kubernetes使用了一个Ingress策略定义和一个具体的Ingress Controller,两者结合并实现了一个完整的Ingress负载均衡器。
使用Ingress进行负载分发时,Ingress Controller基于Ingress规则将客户端请求直接转发到Service对应的后端Endpoint(Pod)上,这样会跳过kube-proxy的转发功能,kube-proxy不在其作用。如果Ingress Controller提供的是对外服务,则实际上实现的是边缘路由器的功能。
其中:
- ◎ 对http://mywebsite.com/api的访问将被路由到后端名为api的Service;
- ◎ 对http://mywebsite.com/web的访问将被路由到后端名为web的Service;
- ◎ 对http://mywebsite.com/docs的访问将被路由到后端名为docs的Service。
为使用Ingress,需要创建Ingress Controller(带一个默认backend服务)和Ingress策略设置来共同完成。
创建Ingress Controller和默认的Backend服务
在定义Ingress策略之前,需要先部署Ingress Controller,以实现为所有后端Service都提供一个统一的入口。Ingress Controller需要实现基于不同HTTP URL向后转发的负载分发规则,并可以灵活设置7层负载分发策略。如同公有云服务商能够提供该类型的HTTP路由LoadBalancer,则也可设置其他Ingress Controller。
在Kubernetes中,Ingress Controller将以Pod的形式运行,监控API Server的/ingress接口后端的backend services,如果Service 发生变化,则Ingress Controller应自动更新其转发规则。
下面的例子使用Nginx来实现一个Ingress Controller,需要实现的基本逻辑如下。
(1)监听API Server,获取全部Ingress的定义。
(2)基于Ingress的定义,生成Nginx所需的配置文件/etc/nginx/nginx.conf。
(3)执行nginx -s reload命令,重新加载nginx.conf配置文件的内容。
本例使用谷歌提供的nginx-ingress-controller镜像来创建Ingress Controller该Ingress Controller以daemonset的形式进行创建,在每个Node上都将启动一个Nginx服务。
这里为Nginx容器设置了hostPort,将容器应用监听的80和443端口映射到物理机上,是的客户端应用可以通过URL地址“http://物理机:80” 或“https://物理机:443” 来访问该Ingress Controller。这使得Nginx类似于通过NodePort映射到物理机的Service,成为代替Kube-proxy的HTTP层的Load Balancer:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 1apiVersion: extensions/v1beta1
2kind: DaemonSet
3metadata:
4 name: nginx-ingress-lb
5 labels:
6 name: nginx-ingress-lb
7 namespace: kube-system
8spec:
9 template:
10 metadata:
11 labels:
12 name: nginx-ingress-lb
13 spec:
14 terminationGracePeriodSeconds: 60
15 containers:
16 - image: registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:0.9.0-beta.2
17 name: nginx-ingress-lb
18 readinessProbe:
19 httpGet:
20 path: /healthz
21 port: 10254
22 scheme: HTTP
23 livenessProbe:
24 httpGet:
25 path: /healthz
26 port: 10254
27 scheme: HTTP
28 initialDelaySeconds: 10
29 timeoutSeconds: 1
30 ports:
31 - containerPort: 80
32 hostPort: 80
33 - containerPort: 443
34 hostPort: 443
35 env:
36 - name: POD_NAME
37 valueFrom:
38 fieldRef:
39 fieldPath: metadata.name
40 - name: POD_NAMESPACE
41 valueFrom:
42 fieldRef:
43 fieldPath: metadata.namespace
44 args:
45 - /nginx-ingress-controller
46 - --default-backend-service=${POD_NAMESPACE}/default-http-backend
47
48
为了让Ingress Controller正常启动,还需要为它配置一个默认的backend,用于在客户端访问的URL地址不存在时,返回一个正确的404应答。这个backend服务用任何应用实现都可以,只要满足对根路径“/”的访问返回404应答,并且提供/healthz路径以使kubelet完成对它的健康检查。另外,由于Nginx通过default-backend-service的服务名称(Service Name)去访问它,所以需要DNS服务正确运行:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 1apiVersion: extensions/v1beta1
2kind: Deployment
3metadata:
4 name: default-http-backend
5 labels:
6 k8s-app: default-http-backend
7 namespace: kube-system
8spec:
9 replicas: 1
10 template:
11 metadata:
12 labels:
13 k8s-app: default-http-backend
14 spec:
15 terminationGracePeriodSeconds: 60
16 containers:
17 - name: default-http-backedn
18 image: registry.cn-hangzhou.aliyuncs.com/google_containers/defaultbackend:1.0
19 livenessProbe:
20 httpGet:
21 path: /healthz
22 port: 8080
23 scheme: HTTP
24 initialDelaySeconds: 30
25 timeoutSeconds: 5
26 ports:
27 - containerPort: 8080
28 resources:
29 limits:
30 cpu: 10m
31 memory: 20Mi
32 requests:
33 cpu: 10m
34 memory: 20Mi
35---
36apiVersion: v1
37kind: Service
38metadata:
39 name: default-http-backend
40 namespace: kube-system
41 labels:
42 k8s-app: default-http-backend
43spec:
44 ports:
45 - port: 80
46 targetPort: 8080
47 selector:
48 k8s-app: default-http-backend
49
50
通过Kubectel create命令创建backend服务;
创建nginx-ingress-controller;
在此处出现了问题,目前没有解决,
报错如下:(有能力解决的小伙伴,可以解决哦)
定义Ingress策略
本例对mywebsite.com网站的访问设置Ingress策略,定义对其/demo路径的访问转发到后端webapp Service的规则:
1
2
3
4
5
6
7
8
9
10
11
12
13
14 1apiVersion: extensions/v1beta1
2kind: Ingress
3metadata:
4 name: mywebsite-ingress
5spec:
6 rules:
7 - host: mywebsite.com
8 http:
9 paths:
10 - path: /demo
11 backend:
12 serviceName: webapp
13 servicePort: 8080
14
这个Ingress的定义,说明对目标地址http://mywebsite.com/demo的访问将被转发到集群中的Service webapp即webapp:8080/demo上。
在Ingress生效之前,需要先将webapp服务部署完成。同时需要注意Ingress中path的定义,需要与后端真实Service提供的path一致,否则将被转发到一个不存在的path上,引发错误。这里以webapp例子为例,假设myweb服务已经部署完毕并正常运行,myweb提供的Web服务的路径也为/demo。
在成功创建该Ingress后,查看其ADDRESS列,如果显示了所有nginx-ingress-controller Pod的IP地址,则表示Nginx已经设置好后端Service的Endpoint,该Ingress可以正常工如果ADDRESS列为空,则通常说明Nginx未能正确连接到后端Service,需要排错。
登录任一nginx-ingress-controller Pod,查看其自动生成的nginx.conf配置文件的内容,可以看到对mywebsite.com/demo的转发
规则的正确配置。
客服端访问http://mywebsite.com/demo
由于Ingress Controller容器通过hostPort将服务端口号80映射到了所有Node上,所以客户端可以通过任意Node访问mywebsite.com提供的服务。
需要说明的是,客户端只能通过域名mywebsite.com访问服务,这时要求客服端或者DNS将mywebsite.com域名解析到后端多个Node的真实IP低智商。
通过curl访问mywebsite.com提供的服务(可以用-resolve参数模拟DNS解析,目标地址为域名;也可以用-H‘Host:mywebsit.com’参数设置HTTP头中要访问的域名,目标地址为IP地址),可以得到myweb返回的网页内容。
1
2 1curl --resolve mywebsite.com:80:192.168.18.3 http://mywebsite.com/demon/
2
1
2 1curl -H 'Host:mywebsite.com' http://192.168.18.3/demo/
2
如果通过浏览器访问,那么需要先在本机上设置域名mywebsite.com对应的IP地址,再到浏览器上进行访问。以Windows为例,修改hosts文件,加入一行记录
1
2 1192.168.18.3 mywebsie.com
2
然后在浏览器的地址栏输入http://mywebsite.com/demo/,就能够访问Ingress提供的服务了。
小结:
本节内容到此结束
虽然很多实例没有做,当时后续会补充说明的,谢谢大家的支持!