一, 背景
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 环境介绍
我们是采用了三台服务器的一个集群, 部署文档请查看我之前的博文 http://blog.51cto.com/wzlinux/2322616 .
IP | 角色 |
---|---|
192.168.1.200 | k8s-master |
192.168.1.201 | k8s-node01 |
192.168.1.202 | k8s-node02 |
- [root@master ~]# kubectl get nodes
- NAME STATUS ROLES AGE VERSION
- master Ready master 117s v1.13.0
- node01 Ready <none> 52s v1.13.0
- node02 Ready <none> 42s v1.13.0
二, 安装部署
我们这里只针对上面架构图中的域名 www.wzlinux.com 改造成 https.
我们将以官方的标准脚本为基础进行搭建, 参考请戳官方文档 https://kubernetes.github.io/ingress-nginx/deploy/ . 官方文档中要求执行如下命令:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/mandatory.yaml
2.1, 创建后端 Pod 应用
我们创建一个控制器 wzlinux-deploy.YAML, 内容如下:
- apiVersion: extensions/v1beta1
- kind: Deployment
- metadata:
- name: wzlinux-dep
- spec:
- replicas: 3
- template:
- metadata:
- labels:
- run: wzlinux
- spec:
- containers:
- - name: wzlinux
- image: wangzan18/mytest:v1
- ports:
- - containerPort: 8080
创建好之后查看如下:
- [root@master ingress]# kubectl get pod
- NAME READY STATUS RESTARTS AGE
- wzlinux-dep-78d5d86c7c-fj8f5 1/1 Running 0 53m
- wzlinux-dep-78d5d86c7c-hr6gd 1/1 Running 0 53m
- wzlinux-dep-78d5d86c7c-jqf59 1/1 Running 0 53m
2.2 创建后端 Pod Service
测试好 Pod 一些正常之后, 我们为这一组 Pod 创建一个 Service, 文件 wzlinux-svc.YAML 内容如下:
- apiVersion: v1
- kind: Service
- metadata:
- name: wzlinux-svc
- spec:
- selector:
- run: wzlinux
- ports:
- - port: 80
- targetPort: 8080
这个 Service 并不是我们用了代理访问 Pod 的, 只是用来 ingress-controller 来进行选择控制使用的, 所以上图描述为虚线.
- [root@master ingress]# kubectl get svc
- NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
- kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 58m
- wzlinux-svc ClusterIP 10.106.219.230 <none> 8080/TCP 50m
- [root@master ingress]# curl 10.106.219.230:8080
- Hello Kubernetes bootcamp! | Running on: wzlinux-dep-78d5d86c7c-fj8f5 | v=1
2.3, 创建 ingress 资源
为了实现过滤以及 https 功能, 我们需要创建 ingress 资源文件, ingress controller 把其中的资源加载到 nginx 里面, 资源文件 wzlinux-ingress.YAML 文件内容如下:
- apiVersion: extensions/v1beta1
- kind: Ingress
- metadata:
- name: wzlinux-ingress
- spec:
- rules:
- - host: www.wzlinux.com
- http:
- paths:
- - path:
- backend:
- serviceName: wzlinux-svc
- servicePort: 8080
我们这里先不改为 https, 先使用虚拟主机域名过滤模式, 创建好资源之后查看
- [root@master ingress]# kubectl get ingress
- NAME HOSTS ADDRESS PORTS AGE
- wzlinux-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-nginx
- NAME READY STATUS RESTARTS AGE
- nginx-ingress-controller-766c77b7d4-dlcpf 1/1 Running 0 31m
为了是外网可以访问到这个 Nginx Pod, 我们需要为其再创建一个 Service, 文件 ingress-nginx.YAML, 文件内容如下:
- apiVersion: v1
- kind: Service
- metadata:
- name: ingress-nginx
- namespace: ingress-nginx
- spec:
- 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:30080
- Hello 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: v1
- kind: Secret
- data:
- tls.crt: base64 encoded cert
- tls.key: base64 encoded key
- metadata:
- name: wzlinux-secret
- namespace: default
- type: Opaque
因为编码的密码太长, 我们这里直接使用命令行进行创建吧, 操作比较简单.
kubectl create secret tls wzlinux-secret --cert=wzlinux.crt --key=wzlinux.key
查看创建好的 secret.
- [root@master ingress]# kubectl describe secret wzlinux-secret
- Name: wzlinux-secret
- Namespace: default
- Labels: <none>
- Annotations: <none>
- Type: kubernetes.io/tls
- Data
- ====
- tls.crt: 1996 bytes
- tls.key: 1675 bytes
3.3 更改 ingress 资源
重新编辑 wzlinux-ingress.YAML, 增加一个 tls 字段:
- apiVersion: extensions/v1beta1
- kind: Ingress
- metadata:
- name: wzlinux-ingress
- spec:
- 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/v1beta1
- kind: Ingress
- metadata:
- 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/v1beta1
- kind: Ingress
- metadata:
- name: name-virtual-host-ingress
- spec:
- 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/v1beta1
- kind: Ingress
- metadata:
- name: tls-example-ingress
- spec:
- tls:
- - hosts:
- - sslexample.foo.com
- secretName: testsecret-tls
- rules:
- - host: sslexample.foo.com
- http:
- paths:
- - path: /
- backend:
- serviceName: service1
- servicePort: 80
来源: http://www.bubuko.com/infodetail-2890238.html