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
,但是只支持基於域名的網站訪問,所以還是建議用這種方式去暴露你的服務