什么是Ingress
阿里雲稱之為ingress路由!在Kubernetes集群中,主要用於接入外部請求到k8s內部,Ingress是授權入站連接到達集群服務的規則集合,為您提供七層負載均衡能力。您可以給 Ingress 配置提供外部可訪問的URL、負載均衡、SSL、基於名稱的虛擬主機等。
Service缺點
定義service以后,尤其是NodePort集群訪問,需要經過2級轉換調度,而且是4層調度,無論是iptables還是ipvs。4調度自身無法實現卸載https會話。
ingress----k8s還有一種引入集群外部流量的方式,叫ingress。基於7層調度器。利用7層pod,將外部流量引入到內部。
回顧-Service:
工作三種方式模型:
- userspace(效率低、各種空間轉換)
- iptables
- ipvs (1.11版之后,部署時需要額外配置先關參數)
Service集群類型:
- ClusterIP (集群內部通信)
- NodePort (集群內外互通,工作邏輯:client-->nodeip:nodeport-->clusterip:serviceip--->podiip:containerport),可以在前面加個nginx,代理后端各個nodeport的時候,壓力得到釋放。
- LoadBalancer
- ExternerName
Ingress支持的調度方式
- url路徑映射調度: location /aa ; location /bb。可以參考nginx。
- 主機調度:l例如server aaa; server bbb
Ingress類型:
- url映射
- 虛擬主機
Ingress-controller: (提供特定功能的pod,nginx-ingress-controller-pod):提供接入外部流量的特定pod。例如有3個節點,在這3個節點打上污點,在每個上面運行特定的daemonset pod,實現外部流量接入,為后面pod提供7層調度。眾多控制器都是master節點的controllermanager的子件運行的。而ingree controller自己獨立運行,通常是一組pod資源。具有7層代理功能。
支持的代理工具: nginx、Traefik、Evoy(微服務)、HAproxy
watch: Service始終watch着后端pod變化。只要pod發生變化,api-server立刻檢測到
Ingress實現原理
- 正常是用service去調度后面的適配label的pods,當pods增加,因為有labels,會自動識別后端添加的pods,如果用nginx怎么實現?把nginx運行在pod里面,配置文件在pod內部。這種pod叫ingress controller隨時觀察着后端的pod的改變。ingress controler自己沒有這種能力,借助於service去實現。所以nginx-ingress-controller后端還得建立service。這種service僅僅幫忙分類后端的pods資源。pods的配置在nignx里upstream面。service不會進行調度,僅僅分組。因此可以使用headless service,直接調度至后端pods。關鍵pods變化,怎么自動nginx的upstream以及其他配置,這種就通過ingress路由實現!
- ingress需要建一個前端接入層,前端有可能是虛擬主機nginx配置的server,或者是location url映射,同時也要定義一個后端upstream-server。 upstream有幾個主機。通過service來獲取的。
- ingress有個特點:作為資源來講,直接通過編輯注入到nginx-ingress-controller,並保存為nginx的配置文件。而且ingress一旦發現service 后端的pods改變,ingress直接注入更新nginx配置文件,而且需要重載配置文件(traefik支持自動重載)。
實現ingress步驟(7層調度):
- 部署一個nginx-ingress-controller-pod。部署一個特殊pod。
- 給nginx-ingress-controller-pod創建前端service1。用來接入外部請求!
- 創建nginx-ingress-controller-pod后端service2,以及service關聯的pods。
- 創建ingress、自動實現路由規則,自動實現service2自動注入到nginx-ingress-controller-pod規則(nginx.conf)
- 總結就是首先部署外部請求<------ingress-service<-----nginx-ingress-controller-pod<--------ingress<------service(headless、daemonset)<------pods
Ingress原理圖
原理:外部負載均衡器externalLB請求調至到 nodeport 里面service服務--->調度到內部pod(ingress controller里面)----->根據ingree定義,是虛擬主機,還是url代理---->假設是主機名,一組主機名對應后端的pod資源pod1,pod2,pod3。pod怎么分組通過service進行分組。才能被ingress引用。
先安裝ingress controller pod。然后定義ingress。再定義pod生成service。
動態生效:pod一變化,service就變化,service一變化,ingress就變化,ingreess一變化就注入到ingress controller里面。實時動態。 
部署Ingress-Nginx
git地址:https://github.com/kubernetes/Ingress-nginx
官方網站:https://kubernetes.github.io/ingress-nginx
安裝
//下載ingress-nginx yaml初始化安裝模板
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.33.0/deploy/static/provider/cloud/deploy.yaml //編輯文件修改Controller的下載地址到國內
vim deploy.yaml containers: - name: controller image: registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:0.33.0 imagePullPolicy: IfNotPresent //使用kubectl apply安裝 kubectl apply -f deploy.yaml //ingress默認安裝在ingress-nginx名稱空間內 [root@k8s-master ingress]# kubectl get pod -n ingress-nginx NAME READY STATUS RESTARTS AGE ingress-nginx-admission-create-45qcs 0/1 Completed 0 4m12s ingress-nginx-admission-patch-z52jg 0/1 Completed 1 4m12s ingress-nginx-controller-5858f5cdf8-kxfwm 1/1 Running 0 4m12s
通過nodeport方式暴露ingress
//官網下載所需要的yaml文件 wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.33.0/deploy/static/provider/baremetal/deploy.yaml mv deploy.yaml service-nodeport.yaml //修改Controller的下載地址到國內。同ingress-controller //安裝 kubectl apply -f service-nodeport.yaml //查看結果 kubectl get svc -n ingress-nginx [root@k8s-master ingress]# kubectl get svc -n ingress-nginx NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ingress-nginx-controller NodePort 10.103.86.19 <none> 80:30367/TCP,443:30621/TCP 21m ingress-nginx-controller-admission ClusterIP 10.103.210.91 <none> 443/TCP 21m
創建http的 nginx-ingress
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: nginx-ingress // name spec: rules: - host: www.xhyan.com //domain http: paths: - path: / //path backend: serviceName: ngx-svc //svc name servicePort: 80 //svc port
創建的ingress規則生成對應的nginx配置嵌入到nginx-controller中
通過進入ingress controller容器中查看
//查看ingress-controllerpod名稱 [root@k8s-master ingress]# kubectl get pod -n ingress-nginx NAME READY STATUS RESTARTS AGE ingress-nginx-admission-create-45qcs 0/1 Completed 0 101m ingress-nginx-admission-patch-z52jg 0/1 Completed 1 101m ingress-nginx-controller-6995cf966b-qs8rc 1/1 Running 0 80m //進入容器 [root@k8s-master ingress]# kubectl exec -it ingress-nginx-controller-6995cf966b-qs8rc -n ingress-nginx -- /bin/bash //容器中查看配置 bash-5.0$cat nginx.conf
創建https的 nginx-ingress
- 將申請好的https證書放在指定目錄
- 通過kubectl create secret將證書加入到ingress中
//kubectl create secret將證書加入到ingress中 kubectl create tls tls-secret --key tls.key --cert tls.crt //證書名為tls-secret //https ingress apiVersion: extensions/v1beta1 kind: Ingress metadata: name: nginx-ingress // name spec: tls: - hosts: - www.xhyan.com secretName: tls-secret //對應kubectl create創建的tls證書名稱 rules: - host: www.xhyan.com //domain http: paths: - path: / //path backend: serviceName: ngx-svc //svc name servicePort: 80 //svc port
更新Ingress
假如你想要向已有的ingress中增加一個新的Host,你可以編輯和更新該ingress:
$ kubectl get ing NAME RULE BACKEND ADDRESS test - 178.91.123.132 foo.bar.com /foo s1:80 $ kubectl edit ing test //使用kubectl edit更新 //這會彈出一個包含已有的yaml文件的編輯器,修改它,增加新的Host配置。 spec: rules: - host: foo.bar.com http: paths: - backend: serviceName: s1 servicePort: 80 path: /foo - host: bar.baz.com http: paths: - backend: serviceName: s2 servicePort: 80 path: /foo ..
保存它會更新API server中的資源,會觸發ingress controller重新配置loadbalancer。
$ kubectl get ing NAME RULE BACKEND ADDRESS test - 178.91.123.132 foo.bar.com /foo s1:80 bar.baz.com /foo s2:80
在一個修改過的ingress yaml文件上調用kubectl replace -f命令一樣可以達到同樣的效果。
