kubernetes:部署Ingress Controller
kubernetes:部署Ingress Controller
大概分为三个部分
- Pod与Ingress的关系
- Ingress Controller
- Ingress 实现HTTP与HTTPS
在上面接触到了NodePort
和LoadBalancer
可以把应用暴露给外界进行访问,能感觉到需要提前规划端口,应用越来越多就会变得很麻烦,并且每个Service
都会给你创建一个负载均衡,维护成本有点高,Ingress
就是一个全局的负载均衡器,能提供统一的访问入口,他可以通过域名或URL
将请求转发到不同的Service
,他支持七层的负载均衡,而之前提到的那些都是四层的,Ingress
是授权请求入站访问到集群的规则集合,具体的实现是由Ingress Controller
来完成的,先了解一下Pod
和Ingress
的关系。
Pod与Ingress的关系
Ingress
是通过Service
来关联Pod
的,通过你指定的Service
来绑定一组pod
,通过Ingress Controller
来实现Pod
的负载均衡,Ingress
只是定义了规则,负载均衡是由控制器(Controller)来完成的,他支持四层和七层的转发
Ingress Controller
具体帮你提供全局负载均衡,了解一下访问流程,用户会先访问Ingress
控制器定义的规则,这个规则你可以理解为nginx
配置文件写的各个虚拟主机,用户请求会先到达Ingress
控制器,控制器是在node
上运行的,然后再到具体的pod
,我们用的是Ingress-nginx
,这个官方维护的,其实还有很多,具体还有哪些可以看一下官方文档,下面部署一下Ingress-nginx
https://github.com/kubernetes/ingress-nginx/blob/nginx-0.30.0/deploy/static/mandatory.yaml
需要改两处,一处是镜像地址,默认的下载特别慢,慢到你无法想象,第二个就是要使用主机网络,所以我改了这些。
[root@k8s01 yml]# egrep -i "image|hostNetwork" -C 1 mandatory.yaml
spec:
hostNetwork: true
# wait up to five minutes for the drain of connections
--
- name: nginx-ingress-controller
image: registry.cn-shenzhen.aliyuncs.com/google_containers_hw/nginx-ingress-controller:0.30.0
args:
生产环境下建议指定一下服务约束,测试无所谓了
[root@k8s01 yml]# kubectl create -f mandatory.yaml
[root@k8s01 yml]# kubectl get pods -n ingress-nginx
NAME READY STATUS RESTARTS AGE
nginx-ingress-controller-775bfffd-22jmz 1/1 Running 0 95s
[root@k8s01 yml]#
好了,运行状态,这个控制器就能帮你实现全局的负载均衡,下面开始定义Ingress
的规则了
Ingress定义HTTP
想通过Ingress
暴露你的服务你必须是使用域名的,这个就比较蛋疼了,像是我们这里暴露接口出去都是没有域名的,而且暴露端口出去的时候比较多,后期真的用K8S
考虑加域名吧,下面是一个实例,直接在官网扒过来的,顺便改了改。
[root@k8s01 yml]# cat ingress_http.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: www.opesn.com
spec:
rules:
- host: www.opesn.com
http:
paths:
- path: /
backend:
serviceName: nginx-service
servicePort: 80
[root@k8s01 yml]#
host
那一行改成你的域名,serviceName
也就是你要通过这个Ingress
把哪个Service
暴露出去,我写的就是nginx-service
,我之前创建的,servicePort
就是Service
内部端口,也就是80
,看一下这个Service
。
[root@k8s01 yml]# kubectl get service nginx-service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-service NodePort 10.0.0.169 <none> 80:30010/TCP 2d22h
[root@k8s01 yml]#
直接创建
[root@k8s01 yml]# kubectl create -f ingress_http.yaml
ingress.extensions/www.opesn.com created
[root@k8s01 yml]# kubectl get ingresses.extensions
NAME HOSTS ADDRESS PORTS AGE
www.opesn.com www.opesn.com 80 17s
[root@k8s01 yml]#
[root@k8s01 yml]# echo '192.168.10.92 www.opesn.com' >>/etc/hosts
[root@k8s01 yml]# curl -I www.opesn.com
HTTP/1.1 200 OK
Server: nginx/1.17.8
Date: Mon, 01 Jun 2020 08:32:50 GMT
Content-Type: text/html
Content-Length: 612
Connection: keep-alive
Vary: Accept-Encoding
Last-Modified: Tue, 14 Apr 2020 14:19:26 GMT
ETag: "5e95c66e-264"
Accept-Ranges: bytes
[root@k8s01 yml]#
说白了这就是一个nginx
的容器,你操作Ingress
控制器他就会创建相对应的upsteam
配置,不过这个upstream
地址池是动态的,配置不是写在文件里的,而是写在了内存里,原理就是这样,如果还有别的域名继续写配置文件创建规则就行了,下面看看https
的。
Ingress 定义HTTPS
既然是https
了,就需要有证书了,我刚刚创建的域名是www.opesn.com
,所以我直接用我的证书了,而且是可信任的撒,需要创建一个secret
来保存tls
证书信息,下面开始吧。
[root@k8s01 opesn]# ll
total 8
-rw-r--r-- 1 root root 1675 Jun 1 16:38 2536473_www.opesn.com.key
-rw-r--r-- 1 root root 3667 Jun 1 16:38 2536473_www.opesn.com.pem
[root@k8s01 opesn]# kubectl create secret tls opesn.com --cert=2536473_www.opesn.com.pem --key=2536473_www.opesn.com.key
secret/opesn.com created
[root@k8s01 opesn]# kubectl get secrets opesn.com
NAME TYPE DATA AGE
opesn.com kubernetes.io/tls 2 16s
[root@k8s01 opesn]#
这就创建完了,在secrets
里也阔以看到了,有两个数字信息,下面编写一下Ingress
规则。
[root@k8s01 yml]# cat ingress_ssl.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: www.opesn.com-ssl
spec:
tls:
- hosts:
- www.opesn.com
secretName: opesn.com
rules:
- host: www.opesn.com
http:
paths:
- path: /
backend:
serviceName: nginx-service
servicePort: 80
注意一下tls
那里的配置,别的就和上面一样了,在创建之前先把之前的删了,
[root@k8s01 yml]# kubectl delete -f ingress_http.yaml
ingress.extensions "www.opesn.com" deleted
[root@k8s01 yml]# kubectl create -f ingress_ssl.yaml
ingress.extensions/www.opesn.com-ssl created
[root@k8s01 yml]# kubectl get ingresses.extensions
NAME HOSTS ADDRESS PORTS AGE
www.opesn.com-ssl www.opesn.com 80, 443 2m54s
[root@k8s01 yml]#
[root@k8s01 yml]# curl -I www.opesn.com
HTTP/1.1 308 Permanent Redirect
Server: nginx/1.17.8
Date: Mon, 01 Jun 2020 08:52:34 GMT
Content-Type: text/html
Content-Length: 171
Connection: keep-alive
Location: https://www.opesn.com/
[root@k8s01 yml]# curl -I https://www.opesn.com
HTTP/1.1 200 OK
Server: nginx/1.17.8
Date: Mon, 01 Jun 2020 08:49:35 GMT
Content-Type: text/html
Content-Length: 612
Connection: keep-alive
Vary: Accept-Encoding
Last-Modified: Tue, 14 Apr 2020 14:19:26 GMT
ETag: "5e95c66e-264"
Accept-Ranges: bytes
Strict-Transport-Security: max-age=15724800; includeSubDomains
[root@k8s01 yml]#
可以看到以非https
方式访问他帮你重定向到https
了,重定向状态码为308
,事实证明没问题,如果你的证书是自签的,使用curl -k
参数可以忽略证书问题,如果证书指定错了,k8s
就是用默认的证书了。
总结一下Ingress
支持四层七层负载均衡转发,支持自定义Service
访问策略,支持TLS
,但是只支持基于域名的网站访问,所以还是建议用这种方式去暴露你的服务