15 TKE中实现ingress服务暴露

unlisted · suofeiya's blog


Table of Contents

写在前面 #

上一篇文章中介绍了基于Nginx实现Ingress Controller的实现,介绍了Nginx Ingress Controller安装、相关功能,TLS,高级特性等介绍,本章开始介绍基于腾讯云TKE实现ingress服务暴露。

1. TKE ingress #

1.1 TKE ingress架构 #

TKE是Tencent Kubernetes Engine即腾讯云基于kubernetes提供的公有云上容器云服务TKE提供了两种暴露服务的方式:service和ingress。

TKE service和ingress

要使用TKE的ingress功能,需要了解一下相关的组件内容:

由于nginx ingress controller是直接以Pod的形势部署在kubernetes集群中,借助于service的服务发现可直接实现和pod通讯,而TKE中ingress controller未直接部署在k8s集群中,网络的接入需借助于service的NodePort实现接入,其数据流如下图:

TKE ingress数据流走向

1.2 ingress虚拟主机 #

环境说明: 创建两个Deployment并以NodePort方式暴露服务,www1.happylau.cn对应tke-app-1服务,同理www2.happylau.cn对应tke-app-2服务,如下演示操作过程:

1、创建两个Deployments

1[root@VM_10_2_centos ingress]# kubectl create deployment tke-app-1 --image=nginx:1.7.9
2[root@VM_10_2_centos ingress]# kubectl create deployment tke-app-2 --image=nginx:1.7.9

2、 将两个Deployment以NodePort的方式暴露服务

1[root@VM_10_2_centos ~]# kubectl expose deployment tke-app-1 --port=80 --type=NodePort
2[root@VM_10_2_centos ~]# kubectl expose deployment tke-app-2 --port=80 --type=NodePort
3
4查看服务列表
5[root@VM_10_2_centos ~]# kubectl get services 
6NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
7kubernetes   ClusterIP   172.16.255.1     <none>        443/TCP        83d
8tke-app-1    NodePort    172.16.255.91    <none>        80:30597/TCP   2s
9tke-app-2    NodePort    172.16.255.236   <none>        80:31674/TCP   73s

3、定义ingress规则,定义两个host将不同主机转发至backend不同的service

 1apiVersion: extensions/v1beta1
 2kind: Ingress
 3metadata:
 4  name: tke-ingress-demo
 5  annotations:
 6    kubernetes.io/ingress.class: qcloud
 7spec:
 8  rules:
 9  - host: www1.happylau.cn 
10    http:
11      paths:
12      - path: /
13        backend:
14          serviceName: tke-app-1 
15          servicePort: 80 
16  - host: www2.happylau.cn 
17    http:
18      paths:
19      - path: /
20        backend:
21          serviceName: tke-app-2 
22          servicePort: 80 

4、 应用ingress规则,并查看ingress详情,可以看到ingress创建了一个公网CLB实例

 1#应用ingress规则
 2[root@VM_10_2_centos ingress]# kubectl apply -f tke-ingress-demo.yaml 
 3ingress.extensions/tke-ingress-demo created
 4
 5#查看ingress列表
 6[root@VM_10_2_centos ingress]# kubectl get ingresses 
 7NAME               HOSTS                               ADDRESS         PORTS   AGE
 8tke-ingress-demo   www1.happylau.cn,www2.happylau.cn   140.143.84.xxx   80      67s
 9
10#查看 ingress详情
11[root@VM_10_2_centos ingress]# kubectl describe ingresses tke-ingress-demo 
12Name:             tke-ingress-demo
13Namespace:        default
14Address:          140.143.84.xxx
15Default backend:  default-http-backend:80 (<none>)
16Rules:
17  Host              Path  Backends
18  ----              ----  --------
19  www1.happylau.cn  
20                    /   tke-app-1:80 (172.16.1.15:80)
21  www2.happylau.cn  
22                    /   tke-app-2:80 (172.16.2.17:80)
23Annotations:
24  kubectl.kubernetes.io/last-applied-configuration:  {"apiVersion":"extensions/v1beta1","kind":"Ingress","metadata":{"annotations":{"kubernetes.io/ingress.class":"qcloud"},"name":"tke-ingress-demo","namespace":"default"},"spec":{"rules":[{"host":"www1.happylau.cn","http":{"paths":[{"backend":{"serviceName":"tke-app-1","servicePort":80},"path":"/"}]}},{"host":"www2.happylau.cn","http":{"paths":[{"backend":{"serviceName":"tke-app-2","servicePort":80},"path":"/"}]}}]}}
25
26  kubernetes.io/ingress.class:                  qcloud
27  kubernetes.io/ingress.qcloud-loadbalance-id:  lb-a0xwhcx3
28Events:
29  Type    Reason           Age                From                     Message
30  ----    ------           ----               ----                     -------
31  Normal  EnsuringIngress  69s (x3 over 89s)  loadbalancer-controller  Ensuring ingress
32  Normal  CREATE           69s (x2 over 70s)  loadbalancer-controller  create loadbalancer succ
33  Normal  EnsuredIngress   68s (x3 over 70s)  loadbalancer-controller  Ensured ingress

5、测试验证,将IP和域名写入到hosts文件中,访问域名测试验证,如下通过curl解析的方式测试验证

ingress测试验证

6、ingress会创建一个CLB,并在CLB中创建监听器、设置转发规则、绑定后端RS,下图是CLB上自动生成的规则

CLB规则

通过上面演示可知:

1.3 ingress证书加密 #

TKE支持将在CLB中加载证书实现https加密传输,证书是经过第三方认证的CA签名过的证书,需要先购买好证书,通过Secrets对象在kubernetes集群中定义,如下演示https的实现。

1、 通过Secrets创建证书,先获取到证书的id,如果没有则先创建证书,证书管理,本文以证书id TKPmsWb3 为例,通过stringData能实现base64自动加密

 1apiVersion: v1
 2kind: Secret
 3metadata:
 4  name: ingress-ssl-key
 5stringData:
 6  qcloud_cert_id: TKPmsWb3 
 7type: Opaque
 8
 9#生成Secrets对象
10[root@VM_10_2_centos ingress]# kubectl apply -f ingress-secret.yaml 
11secret/ingress-ssl-key created
12[root@VM_10_2_centos ingress]# kubectl get secrets ingress-ssl-key 
13NAME              TYPE     DATA   AGE
14ingress-ssl-key   Opaque   1      7s
15
16#查看secrets详情可得知VEtQbXNXYjM= 已自动通过base64加密
17[root@VM_10_2_centos ingress]# kubectl get secrets ingress-ssl-key -o yaml
18apiVersion: v1
19data:
20  qcloud_cert_id: VEtQbXNXYjM=  
21kind: Secret
22metadata:
23  annotations:
24    kubectl.kubernetes.io/last-applied-configuration: |
25      {"apiVersion":"v1","kind":"Secret","metadata":{"annotations":{},"name":"ingress-ssl-key","namespace":"default"},"stringData":{"qcloud_cert_id":"TKPmsWb3"},"type":"Opaque"}
26  creationTimestamp: "2020-01-03T11:53:33Z"
27  name: ingress-ssl-key
28  namespace: default
29  resourceVersion: "7083702418"
30  selfLink: /api/v1/namespaces/default/secrets/ingress-ssl-key
31  uid: aaea4a86-2e1f-11ea-a618-ae9224ffad1a
32type: Opaque
33
34#可以通过base64查看解密后的内容和配置文件中定义的id一致
35[root@VM_10_2_centos ingress]# echo VEtQbXNXYjM= | base64 -d
36TKPmsWb3

2、准备环境,创建一个nginx的Deployment

1[root@VM_10_2_centos ~]# kubectl create deployment tke-ingress-ssl-demo --image=nginx:1.7.9
2deployment.apps/tke-ingress-ssl-demo created
3[root@VM_10_2_centos ~]# kubectl get deployments 
4NAME                   READY   UP-TO-DATE   AVAILABLE   AGE
5tke-ingress-ssl-demo   1/1     1            1           6s

3、将Deployment暴露以NodePort类型暴露service

 1[root@VM_10_2_centos ~]# kubectl expose deployment tke-ingress-ssl-demo --port=80 --type=NodePort
 2service/tke-ingress-ssl-demo exposed
 3[root@VM_10_2_centos ~]# kubectl get service tke-ingress-ssl-demo -o yaml
 4apiVersion: v1
 5kind: Service
 6metadata:
 7  creationTimestamp: "2020-01-03T12:00:05Z"
 8  labels:
 9    app: tke-ingress-ssl-demo
10  name: tke-ingress-ssl-demo
11  namespace: default
12  resourceVersion: "7083890283"
13  selfLink: /api/v1/namespaces/default/services/tke-ingress-ssl-demo
14  uid: 94659f42-2e20-11ea-a618-ae9224ffad1a
15spec:
16  clusterIP: 172.16.255.64
17  externalTrafficPolicy: Cluster
18  ports:
19  - nodePort: 30324
20    port: 80
21    protocol: TCP
22    targetPort: 80
23  selector:
24    app: tke-ingress-ssl-demo
25  sessionAffinity: None
26  type: NodePort    #类型为NodePort
27status:
28  loadBalancer: {}

4、定义ingress规则,加载证书实现https转发

 1apiVersion: extensions/v1beta1
 2kind: Ingress
 3metadata:
 4  name: tke-ingress-ssl
 5  annotations:
 6    kubernetes.io/ingress.class: qcloud
 7    qcloud_cert_id: TKPmsWb3
 8spec:
 9  rules:
10  - host: www.happylauliu.cn
11    http:
12      paths:
13      - path: /
14        backend:
15          serviceName: tke-ingress-ssl-demo 
16          servicePort: 80
17  tls:
18  - hosts:
19    - www.happylauliu.cn
20    secretName: ingress-ssl-key

5、应用ingress规则,并查看详情,此时已正常创建CLB并配置规则

 1[root@VM_10_2_centos ingress]# kubectl apply -f ingress-demo.yaml 
 2ingress.extensions/tke-ingress-ssl created
 3
 4#查看ingress详情
 5[root@VM_10_2_centos ingress]# kubectl describe ingresses tke-ingress-ssl 
 6Name:             tke-ingress-ssl
 7Namespace:        default
 8Address:          140.143.83.xxx    #CLB的外网IP
 9Default backend:  default-http-backend:80 (<none>)
10TLS:
11  ingress-ssl-key terminates www.happylauliu.cn
12Rules:
13  Host                Path  Backends
14  ----                ----  --------
15  www.happylauliu.cn  
16                      /   tke-ingress-ssl-demo:80 (172.16.0.25:80)
17Annotations:
18  qcloud_cert_id:                                    TKPmsWb3
19  kubectl.kubernetes.io/last-applied-configuration:  {"apiVersion":"extensions/v1beta1","kind":"Ingress","metadata":{"annotations":{"kubernetes.io/ingress.class":"qcloud","qcloud_cert_id":"TKPmsWb3"},"name":"tke-ingress-ssl","namespace":"default"},"spec":{"rules":[{"host":"www.happylauliu.cn","http":{"paths":[{"backend":{"serviceName":"tke-ingress-ssl-demo","servicePort":80},"path":"/"}]}}],"tls":[{"hosts":["www.happylauliu.cn"],"secretName":"ingress-ssl-key"}]}}
20
21  kubernetes.io/ingress.class:                  qcloud
22  kubernetes.io/ingress.qcloud-loadbalance-id:  lb-2kcrtwbn  #CLB的实例id
23Events:
24  Type    Reason           Age                From                     Message
25  ----    ------           ----               ----                     -------
26  Normal  EnsuringIngress  51s (x3 over 73s)  loadbalancer-controller  Ensuring ingress
27  Normal  CREATE           51s (x2 over 52s)  loadbalancer-controller  create loadbalancer succ
28  Normal  EnsuredIngress   49s (x3 over 52s)  loadbalancer-controller  Ensured ingress

6、测试验证,hosts文件中解析www.happylauliu.cn到CLB的VIP,或者DNS解析,打开浏览器访问站点,由于是经过CA认证签名的证书,因此没有提示告警信息,查看证书的详情信息

tke ingress ssl验证

7、查看CLB的配置可得知,CLB上配置了443的监听端口,并关联了证书,采用单向认证方式

tke ingres ssl配置规则

通过CLB的配置规则可知,CLB配置了监听443的监听器,80端口并未设置规则,因此此时无法访问http,如何实现在TKE使用ingress实现http和https共存呢,可以通过定义kubernetes.io/ingress.http-rules和

kubernetes.io/ingress.https-rules实现

 1apiVersion: extensions/v1beta1
 2kind: Ingress
 3metadata:
 4  name: tke-ingress-ssl
 5  annotations:
 6    kubernetes.io/ingress.class: qcloud
 7    kubernetes.io/ingress.rule-mix: "true"  #开启混合规则配置kubernetes.io/ingress.http-rules配置规则
 8    kubernetes.io/ingress.http-rules: '[{"host":"www.happylauliu.cn","path":"/","backend":{"serviceName":"tke-ingress-ssl-demo","servicePort":"80"}}]'
 9    qcloud_cert_id: TKPmsWb3
10spec:
11  rules:
12  - host: www.happylauliu.cn
13    http:
14      paths:
15      - path: /
16        backend:
17          serviceName: tke-ingress-ssl-demo 
18          servicePort: 80
19  tls:
20  - hosts:
21    - www.happylauliu.cn
22    secretName: ingress-ssl-key

设置ingress.http-rules和ingress.https-rules注解之后,会在监听器中创建http和https的转发规则,并绑定RS,此时访问http和https均能实现站点访问,CLB对应的规则内容如下图:

http和https规则混合使用

通过测试访问http://www.happylauliu.cn/和https://www.happylauliu.cn/均能正常访问,如果要实现访问http自动跳转到https,则可以在控制台开启自动跳转的功能,如下图:

开启http自动重定向功能

开启重定向功能后再次访问http站点后此时会自动跳转到https,如下图所示location已经跳转至https://www.happylauliu.cn/

http自动跳转测试

写在最后 #

通过上述的演示在腾讯云公有云环境下ingress controller的实现,腾讯云TKE通过使用CLB实现和kubernetes ingress集成,借助于service的NodePort实现转发,通过公有云专用的CLB能够最大程度保障ingress接入性能。同时,ingress能够使用腾讯云上的证书实现https加密功能。

参考文献 #

Ingress配置:https://kubernetes.io/docs/concepts/services-networking/ingress/

Ingress控制器:https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/

ingress基本配置:https://cloud.tencent.com/document/product/457/31711

ingress证书:https://cloud.tencent.com/document/product/457/40538

CLB配置http自动跳转:[https://cloud.tencent.com/document/product/214/8839

『 转载 』该文章来源于网络,侵删。