1.1 需求
我们有这样的一个需求,就是把 Pod 集群升级为 https,目前的办法就是要么每个容器配置 https,然后前端通过 Service 进行调度,但是这样配置起来会比较麻烦,以及每个容器的建立都通过 https ,也增加了建立连接的负担。
我们需要一种这样的改造,就是客户端连接到 Service 是通过 https,而 Service 向后端 Pod 的调度通过 http,这样可以极大的优化我们的集群,这里我们就需要用到 Kubernetes 的另外一种资源 Ingress。
1.2 Ingress
Ingress 就是一个负载均衡的应用,它和 Service 的不同之处在于,Service 只可以支持 4 层的负载均衡,而 Ingress 是支持 7 层的负载均衡,支持 http 和 https,包括通过主机名的访问已经路径访问的过滤。
那为什么不直接使用 Nginx?这是因为在 K8S 集群中,如果每加入一个服务,我们都在 Nginx 中添加一个配置,其实是一个重复性的体力活,只要是重复性的体力活,我们都应该通过技术将它干掉。
Ingress就可以解决上面的问题,其包含两个组件Ingress Controller
和Ingress
:
- Ingress:将Nginx的配置抽象成一个Ingress对象,每添加一个新的服务只需写一个新的Ingress的yaml文件即可;
- Ingress Controller:将新加入的 Ingress 转化成 Nginx 的配置文件并使之生效,包含 Contour、F5、HAProxy、Istio、Kong、Nginx、Traefik,官方推荐我们使用 Nginx。
1.3 环境介绍
我们是采用了三台服务器的一个集群,部署文档请查看我之前的博文。
IP | 角色 |
---|---|
192.168.1.200 | k8s-master |
192.168.1.201 | k8s-node01 |
192.168.1.202 | k8s-node02 |
[root@master ~]# kubectl get nodesNAME ????STATUS ??ROLES ???AGE ???VERSIONmaster ??Ready ???master ??117s ??v1.13.0node01 ??Ready ???<none> ??52s ???v1.13.0node02 ??Ready ???<none> ??42s ???v1.13.0
二、安装部署
我们这里只针对上面架构图中的域名www.wzlinux.com
改造成https。
我们将以官方的标准脚本为基础进行搭建,参考请戳官方文档。官方文档中要求执行如下命令:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/mandatory.yaml
2.1、创建后端 Pod 应用
我们创建一个控制器wzlinux-deploy.yaml
,内容如下:
apiVersion: extensions/v1beta1kind: Deploymentmetadata: ?name: wzlinux-depspec: ?replicas: 3 ?template: ???metadata: ?????labels: ???????run: wzlinux ???spec: ?????containers: ?????- name: wzlinux ???????image: wangzan18/mytest:v1 ???????ports: ???????- containerPort: 8080
创建好之后查看如下:
[root@master ingress]# kubectl get podNAME ??????????????????????????READY ??STATUS ???RESTARTS ??AGEwzlinux-dep-78d5d86c7c-fj8f5 ??1/1 ????Running ??0 ?????????53mwzlinux-dep-78d5d86c7c-hr6gd ??1/1 ????Running ??0 ?????????53mwzlinux-dep-78d5d86c7c-jqf59 ??1/1 ????Running ??0 ?????????53m
2.2 创建后端 Pod Service
测试好 Pod 一些正常之后,我们为这一组 Pod 创建一个 Service,文件wzlinux-svc.yaml
内容如下:
apiVersion: v1kind: Servicemetadata: ?name: wzlinux-svcspec: ?selector: ???run: wzlinux ?ports: ?- port: 80 ???targetPort: 8080
这个 Service 并不是我们用了代理访问 Pod 的,只是用来ingress-controller
来进行选择控制使用的,所以上图描述为虚线。
[root@master ingress]# kubectl get svcNAME ?????????TYPE ???????CLUSTER-IP ??????EXTERNAL-IP ??PORT(S) ???AGEkubernetes ???ClusterIP ??10.96.0.1 ???????<none> ???????443/TCP ???58mwzlinux-svc ??ClusterIP ??10.106.219.230 ??<none> ???????8080/TCP ??50m[root@master ingress]# curl 10.106.219.230:8080Hello Kubernetes bootcamp! | Running on: wzlinux-dep-78d5d86c7c-fj8f5 | v=1
2.3、创建 ingress 资源
为了实现过滤以及 https 功能,我们需要创建 ingress 资源文件,ingress controller 把其中的资源加载到 nginx 里面,资源文件wzlinux-ingress.yaml
文件内容如下:
apiVersion: extensions/v1beta1kind: Ingressmetadata: ?name: wzlinux-ingressspec: ?rules: ?- host: www.wzlinux.com ???http: ?????paths: ?????- path: ???????backend: ?????????serviceName: wzlinux-svc ?????????servicePort: 8080
我们这里先不改为 https,先使用虚拟主机域名过滤模式,创建好资源之后查看
[root@master ingress]# kubectl get ingressNAME ?????????????HOSTS ????????????ADDRESS ??PORTS ??AGEwzlinux-ingress ??www.wzlinux.com ????????????80 ?????37m
可以看到配置了域名www.wzlinux.com
,其他地址访问将返回404。
2.4、为 Nginx Pod 创建 Service
我们可以查看部署的 Nginx Pod 容器,我们设定的 ingress 资源会被 controller 更新到里面,我们可以查看如下:
[root@master ingress]# kubectl get pod -n ingress-nginxNAME ???????????????????????????????????????READY ??STATUS ???RESTARTS ??AGEnginx-ingress-controller-766c77b7d4-dlcpf ??1/1 ????Running ??0 ?????????31m
为了是外网可以访问到这个 Nginx Pod,我们需要为其再创建一个 Service,文件ingress-nginx.yaml
,文件内容如下:
apiVersion: v1kind: Servicemetadata: ?name: ingress-nginx ?namespace: ingress-nginxspec: ?type: NodePort ?ports: ?- name: http ???port: 80 ???targetPort: 80 ???nodePort: 30080 ?- name: https ???port: 443 ???targetPort: 443 ???nodePort: 30443 ?selector: ???app.kubernetes.io/name: ingress-nginx
测试是否正常,记得在/etc/hosts
中把域名执行的IP改为node节点的地址。
[root@master ~]# curl 192.168.1.200:30080<html><head><title>404 Not Found</title></head><body><center><h1>404 Not Found</h1></center><hr><center>nginx/1.15.6</center></body></html>[root@master ~]# curl www.wzlinux.com:30080Hello Kubernetes bootcamp! | Running on: wzlinux-dep-78d5d86c7c-hr6gd | v=1
可以看到通过域名访问正常调度到后端,其他地址访问返回404,目前整个流程已经测试完成,下面我们升级为 https。
三、升级为 https
3.1 首先我们要制作证书
关于证书大家可以使用 openssl 制作,创建私有:
openssl genrsa -out wzlinux.key 2048
制作自签证书。
openssl req -new -x509 -key wzlinux.key -out wzlinux.crt -subj /C=CN/ST=Shanghai/L=Shanghai/O=DevOps/CN=www.wzlinux.com
不过我这里使用阿里云的官方免费证书,大家可以到阿里云进行申请。
制作好证书之后下载即可,里面包含公钥和私钥。
3.2、创建 secret 资源
可以使用 yaml 文件创建,文件名称wzlinux-secret.yaml
内容如下:
apiVersion: v1kind: Secretdata: ?tls.crt: base64 encoded cert ?tls.key: base64 encoded keymetadata: ?name: wzlinux-secret ?namespace: defaulttype: Opaque
因为编码的密码太长,我们这里直接使用命令行进行创建吧,操作比较简单。
kubectl create secret tls wzlinux-secret --cert=wzlinux.crt --key=wzlinux.key
查看创建好的 secret。
[root@master ingress]# kubectl describe secret wzlinux-secretName: ????????wzlinux-secretNamespace: ???defaultLabels: ??????<none>Annotations: ?<none>Type: ?kubernetes.io/tlsData====tls.crt: ?1996 bytestls.key: ?1675 bytes
3.3 更改 ingress 资源
重新编辑wzlinux-ingress.yaml
,增加一个 tls 字段:
apiVersion: extensions/v1beta1kind: Ingressmetadata: ?name: wzlinux-ingressspec: ?tls: ?- hosts: ???- www.wzlinux.com ???secretName: wzlinux-secret ?rules: ?- host: www.wzlinux.com ???http: ?????paths: ?????- path: ???????backend: ?????????serviceName: wzlinux-svc ?????????servicePort: 8080
3.4 浏览器访问验证
打开浏览器,记得修改好 hosts 域名解析。
四、ingress 资源介绍
4.1、通过访问路径过滤
foo.bar.com -> 178.91.123.132 -> / foo ???service1:4200 ????????????????????????????????/ bar ???service2:8080
配置文件我们设置为如下:
apiVersion: extensions/v1beta1kind: Ingressmetadata: ?name: simple-fanout-example ?annotations: ???nginx.ingress.kubernetes.io/rewrite-target: /spec: ?rules: ?- host: foo.bar.com ???http: ?????paths: ?????- path: /foo ???????backend: ?????????serviceName: service1 ?????????servicePort: 4200 ?????- path: /bar ???????backend: ?????????serviceName: service2 ?????????servicePort: 8080
4.2、基于名称解析的虚拟主机
foo.bar.com --| ????????????????|-> foo.bar.com s1:80 ?????????????| 178.91.123.132 ?|bar.foo.com --| ????????????????|-> bar.foo.com s2:80
配置文件内容格式如下:
apiVersion: extensions/v1beta1kind: Ingressmetadata: ?name: name-virtual-host-ingressspec: ?rules: ?- host: first.bar.com ???http: ?????paths: ?????- backend: ?????????serviceName: service1 ?????????servicePort: 80 ?- host: second.foo.com ???http: ?????paths: ?????- backend: ?????????serviceName: service2 ?????????servicePort: 80 ?- http: ?????paths: ?????- backend: ?????????serviceName: service3 ?????????servicePort: 80
4.3、https
apiVersion: extensions/v1beta1kind: Ingressmetadata: ?name: tls-example-ingressspec: ?tls: ?- hosts: ???- sslexample.foo.com ???secretName: testsecret-tls ?rules: ???- host: sslexample.foo.com ?????http: ???????paths: ???????- path: / ?????????backend: ???????????serviceName: service1 ???????????servicePort: 80
Kubernetes 使用 ingress 配置 https 集群(十五)
原文地址:http://blog.51cto.com/wzlinux/2332908