一.ingress是什么
背景:
NodePort存在的不足,測試環境用用還行,當有成百上千上萬個服務在集群總運行時,端口管理將是災難:
端口有限,一個端口只能一個服務使用,需要提前規划
只支持4層負載均衡(ipvs和iptables)
ClusterIp只能集群內部訪問
LoadBalance方式受限於雲平台支,且通常在雲平台部署ELB還需要額外的費用
Ingress可以簡單理解為service的service。它通過獨立的Ingress對象來制定轉發規則,把客戶端請求轉發到一個或多個service中,這樣就把請求與服務解耦了,可以從業務維度統一考慮業務的暴露,而不用為每個service單獨考慮
Ingress對象:
指的是k8s中的一個api對象,一般用yaml配置。作用是定義請求如何轉發service的規則。可以理解為配置模板
Ingress Controller:
具體實現反向代理的及負載均衡的程序,對ingress定義的規則進行解析,根據配置的規則把請求轉發到對應的service上
市面上大多數廠商都提供了ingress controller,具體參考官方說明https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/
二.部署Ingress Controller
Ingress Controller有很多實現,我們這里采用官方維護的Nginx控制器 項目地址:https://github.com/kubernetes/ingress-nginx 部署:kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
注意:
ingress controller的鏡像倉庫在國外:quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0,國內訪問不穩定
ingress默認沒配置暴露:一般使用宿主機網絡(hostNetwork: true)或者使用NodePort
hostNetwork: true
containers:
- name: nginx-ingress-controller
三、使用ingress-nginx暴露一個service
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: web1 namespace: web # 注意此處配置:service和ingress必須在同一個namespace spec: rules: - host: web1.k8s.com # 前端請求域名 http: paths: - path: / # 訪問的路徑 pathType: Prefix # 路徑類型 匹配/所有的路徑 backend: # 后端service service: name: web1 # service-name port: number: 8080 # service-port 即service里配置的port的參數
# 查看已創建的ingress kubectl get ingress -n namespace-name [root@k8s-master yaml]# kubectl get ingress -n web Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress NAME CLASS HOSTS ADDRESS PORTS AGE web1 <none> web1.k8s.com 80 23m
以上配置類似nginx里配置如下
server { listen 80; server_name web1.k8s.com; location / { root ; proxy_pass http://ClusterIP(此處是service的name):8080; } }
三.基於URL路由多個服務
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: web2 namespace: web annotations: nginx.ingress.kubernetes.io/rewrite-target: /$2 # 轉發到主頁資源 spec: rules: - host: kubernetes.gameoo.com http: paths: - path: /foo(/|$)(.*) pathType: Prefix backend: service: name: web1 port: number: 80 - path: /bar(/|$)(.*) # 匹配/或者具體路徑的所有資源 /bar/xxx 或者 /bar/xxx/xxx pathType: Prefix backend: service: name: java-daemon port: number: 8080
# 如果不使用annotation,轉發不到對應的后端service資源,如下
當訪問http://kubernetes.gameoo.com/foo時,ingress是這樣轉發的:service/foo。實際后端就沒有foo這個資源,所有會報404
加了annotation,就是這樣轉發的:http://kubernetes.gameoo.com/foo 把這個url的整體轉發給后端service,從而實現多url路由
四.重定向規則的實現
接第三章,只是實現了主頁資源的路由,但實際項目中不僅僅只有主頁資源,還有css js image等資源,這些資源也需要被路由到
所以自帶的 nginx.ingress.kubernetes.io/rewrite-target就不能實現,此時需要我們自定義重定向規則
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: web2 namespace: web annotations: nginx.ingress.kubernetes.io/rewrite-target: /$2 # 轉發到主頁資源 nginx.ingress.kubernetes.io/server-snippet: | # |可以匹配多條自定義規則 rewrite ^/css/(.*)$ /bar/css/$1 redirect; #當客戶端請求/css/的資源時,重定向到/bar/css 使用臨時重定向 rewrite ^/js/(.*)$ /bar/js/$1 redirect; rewrite ^/images/(.*)$ /bar/images/$1 redirect;
##### 實際項目中有多少資源就在這里添加 spec: rules: - host: kubernetes.gameoo.com http: paths: - path: /foo(/|$)(.*) pathType: Prefix backend: service: name: web1 port: number: 80 - path: /bar(/|$)(.*) # 匹配/或者具體路徑的所有資源 /bar/xxx 或者 /bar/xxx/xxx pathType: Prefix backend: service: name: java-daemon port: number: 8080
######nginx正則方式
五、基於名稱的虛擬主機
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: web3 namespace: web spec: rules: - host: kubernetes.gameoo.com http: paths: - path: "/" pathType: Prefix backend: service: name: web1 port: number: 80 - host: java-demo.gameoo.com http: paths: - path: "/" pathType: Prefix backend: service: name: java-daemon port: number: 8080
#### 與nginx的虛擬主機配置方式類似
六.更多ingress使用方法
七.配置https訪問
1.准備證書(測試可以自簽,線上最好是權威機構頒發) 2.將證書文件保存到 secret kubectl create secret tls NAME --cert=path/to/cert/file --key=path/to/key/file -n namespace
[root@k8s-master yaml]# kubectl create secret tls kubernetes.gameoo.com --cert=ssl/kubernetes.gameoo.com.pem --key=ssl/kubernetes.gameoo.com.key -n web secret/kubernetes.gameoo.com created [root@k8s-master yaml]# kubectl get secret -n web NAME TYPE DATA AGE default-token-bk4x4 kubernetes.io/service-account-token 3 14d kubernetes.gameoo.com kubernetes.io/tls 2 3s
3.ingress配置規則
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: web4 namespace: web spec: tls: - hosts: - kubernetes.gameoo.com secretName: kubernetes.gameoo.com #create secret時指定的NAME 注意create時如果項目不在default命名空間,必須指定-n namespace rules: - host: kubernetes.gameoo.com http: paths: - path: "/" pathType: Prefix backend: service: name: java-daemon port: number: 8080
八.Ingress Controller
Ingress Contronler通過與 Kubernetes API 交互,動態的去感知集群中 Ingress 規則變化,然后讀取它,
按照自定義的規則,規則就是寫明了哪個域名對應哪個service,生成一段 Nginx 配置,應用到管理的
Nginx服務,然后熱加載生效。
以此來達到Nginx負載均衡器配置及動態更新的問題。
流量包流程:客戶端 ->Ingress Controller( nginx) -> 分布在各節點Pod
九.Ingress Controller高可用方案