带你玩转kubernetes-k8s(第32篇:k8s-深入掌握Service:DNS服务详细讲解第二部分)

释放双眼,带上耳机,听听看~!

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的内容将被系统设置:

带你玩转kubernetes-k8s(第32篇:k8s-深入掌握Service:DNS服务详细讲解第二部分)

表示该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提供的是对外服务,则实际上实现的是边缘路由器的功能。

带你玩转kubernetes-k8s(第32篇:k8s-深入掌握Service:DNS服务详细讲解第二部分)

其中:

为使用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服务;

带你玩转kubernetes-k8s(第32篇:k8s-深入掌握Service:DNS服务详细讲解第二部分)

创建nginx-ingress-controller;

带你玩转kubernetes-k8s(第32篇:k8s-深入掌握Service:DNS服务详细讲解第二部分)

在此处出现了问题,目前没有解决,

报错如下:(有能力解决的小伙伴,可以解决哦)

带你玩转kubernetes-k8s(第32篇:k8s-深入掌握Service:DNS服务详细讲解第二部分)

定义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。

带你玩转kubernetes-k8s(第32篇:k8s-深入掌握Service:DNS服务详细讲解第二部分)

    在成功创建该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提供的服务了。

 

 

小结:

         本节内容到此结束

         虽然很多实例没有做,当时后续会补充说明的,谢谢大家的支持!

给TA打赏
共{{data.count}}人
人已打赏
安全运维

故障复盘的简洁框架-黄金三问

2021-9-30 19:18:23

安全运维

OpenSSH-8.7p1离线升级修复安全漏洞

2021-10-23 10:13:25

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索