- 一、Ingress簡介
- 二、Ingress組成
- 三、Ingress工作原理
- 四、部署nginx-ingress-controller
- 五、ingress暴露服務的方式
- 六、采用方式二:DaemonSet+HostNetwork+nodeselector
- 七、采用方式三:Deployment+NodePort模式的Service
- 八、ingress http代理訪問虛擬主機
- 九、ingress https代理訪問
- 十、nginx進行BasicAuth(訪問前輸入用戶和密碼)
- 十一、nginx進行重寫
一、Ingress簡介
1.1 service的作用
1.對集群內部,它不斷跟蹤pod的變化,更新endpoint中對應pod的對象,提供了ip不斷變化的pod的服務發現機制
2.對集群外部,他類似負載均衡器,可以在集群內外部對pod進行訪問
1.2 外部訪問k8s集群內的服務
1.NodePort:測試環境使用還行,當有幾十上百的服務在集群中運行時,NodePort的端口管理就是個災難
2.LoadBalancer:受限於雲平台,且通常在雲平台部署LoadBalancer還需要額外的費用
3.Ingress:可以簡單理解為service的service,它其實就是一組基於域名和URL路徑,把用戶的請求轉發到一個或多個service的規則
二、Ingress組成
2.1 ingress
1.ingress是一個APr對象,通過yaml文件來配置,ingress對象的作用是定義請求如何轉發到service的規則,可以理解為配置模板
2.ingress通過http或https暴露集群內部service,給service提供外部URL、負載均衡、SSL/TLs能力以及基於域名的反向代理。ingress要依靠ingress-controller來具體實現以上功能
2.2 ingress-controller
1.ingress-controller是具體實現反向代理及負載均衡的程序,對ingress定義的規則進行解析,根據配置的規則來實現請求轉發
2.ingress -controller並不是kes自帶的組件,實際上ingress-controller只是一個統稱,用戶可以選擇不同的ingress-controller實現,目前,由k8s維護的ingress-controller只有google雲的ccz與ingress-nginx兩個,其他還有很多第三方維護的ingres-controller,具體可以參考官方文檔。但是不管哪一種ingress-controller,實現的機制都大同小異,只是在具體配置上有差異
3.一般來說,ingress-controller的形式都是一個pod,里面跑着daemon程序和反向代理程序。daemcn負責不斷監控集群的變化,根據ingress對象生成配置並應用新配置到反向代理,比如ingress -nginx就是動態生成nginx配置,動態更新upstrea,並在需要的時候reloada程序應用新配置。為了方便,后面的例子都以k8s官方維護的ingress-nginx為例
4.Ingress-Nginx github 地址:https://github.com/kubernetes/ingress-nginx
Ingress-Nginx官方網站:https:/kubernetes.github.io/ingress-nginx/
5.總結: ingress-controller才是負責具體轉發的組件,通過各種方式將它暴露在集群入口,外部對集群的請求流量會先到
三、Ingress工作原理
1.ingress-controller通過和 kubernetes APIServer 交互,動態的去感知集群中ingress規則變化
2.然后讀取它,按照自定義的規則,規則就是寫明了哪個域名對應哪個service,生成一段nginx配置
3.再寫到nginx-ingress-controller的pod里,這個ingress-controller的pod里運行着一個nginx服務,控制器會把生成的nginx配置寫入/etc/nginx.conf文件中
4.然后reload一下使配置生效。以此達到域名區分配置和動態更新的作用
四、部署nginx-ingress-controller
4.1 部署ingress-controller pod及相關資源
1.mkdir /opt/ingress
2.cd /opt/ingress
==========================================================
官方下載地址:
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.25.0/deploy/static/mandatory.yaml
上面可能無法下載,可用國內的gitee
3.wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.25.0/deploy/static/mandatory.yaml
wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/mandatory.yaml
#mandatory.yaml文件中包含了很多資源的創建,包括namespace、configMap、role,ServiceAccount等等所有部署ingress-controller需要的資源

4.2 修改clusterRole資源配置
vim mandatory.yaml
....
- apiGroups:
- ""
resources:
-services
verbs:
- get
- list
- watch
- apiGroups:
- "extensions"
- "networking.k8s.io"#增加(0.25版本)
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- apiGroups:
- "extensions"
- "networking.k8s.io"#增加(o.25版本)
resources:
- ingresses/ status
verbs:
- update

五、ingress暴露服務的方式
1.Deployment+LoadBalancer模式的Service
如果要把ingress部署在公有雲,那用這種方式比較合適。用Deployment部署ingress-controller,創建一個type為 LoadBalancer的 service關聯這組pod。大部分公有雲,都會為 LoadBalancer的 service自動創建一個負載均衡器,通常還綁定了公網地址。只要把域名解析指向該地址,就實現了集群服務的對外暴露
2.DaemonSet+HostNetwork+nodeselector
用DaemonSet結合nodeselector來部署ingress-controller到特定的node 上,然后使用Hostiletwork直接把該pod與宿主機node的網絡打通,直接使用宿主機的80/433端口就能訪問服務。這時,ingress-controller所在的node機器就很類似傳統架構的邊緣節點,比如機房入口的nginx服務器。該方式整個請求鏈路最簡單,性能相對NodePort模式更好。缺點是由於直接利用宿主機節點的網絡和端口,一個node只能部署一個ingress-controller pod。比較適合大並發的生產環境使用
3.Deployment+NodePort模式的Service
1)同樣用deployment模式部署ingres-controller,並創建對應的服務,但是type為NodePort。這樣,ingress就會暴露在集群節點ip的特定端口上
2)由於nodeport暴露的端口是隨機端口,一般會在前面再搭建一套負載均衡器來轉發請求。該方式一般用於宿主機是相對固定的環境ip地址不變的場景
3)NodePort方式暴露ingress雖然簡單方便,但是NodePort多了一層NAT,在請求量級很大時可能對性能會有一定影響
六、采用方式二:DaemonSet+HostNetwork+nodeselector
6.1 指定nginx-ingress-controller運行在node02節點
kubectl label node node02 ingress=true
kubectl get nodes --show-labels

6.2 修改Deployment為Daemonset,指定節點運行,並開啟 hostNetwork
vim mandatory.yaml
...
apiversion: apps/vl
kind: Daemonset #修改kind
...
hostNetwork: true #使用主機網絡
nodeSelector:
ingress: "true" #選擇節點運行
...


6.3 所有node節點上傳nginx-ingress-controller鏡像壓縮包ingree.contro.tar.gz.到/opt/ingress目錄,並解壓和加載鏡像
mkdir /opt/ingress
cd /opt/ingress
tar zxvf ingree.contro.tar.gz
docker load -i ingree.contro.tar

6.4 啟動nginx-ingress-controller
#主節點
kubectl apply -f mandatory.yaml
kubectl get pod -n ingress-nginx -o wide

到node02節點查看
netstat -natp | grep nginx
==========================================================
由於配置了hostnetwork, nginx已經在 node主機本地監聽團/443/8181端口。其中 8181 是nginx-controller默認配置的一個defaultbackend (Ingress資源沒有匹配的 rule 對象時,流量就會被導向這個default backend)
這樣,只要訪問 node主機有公網 TP,就可以直接映射域名來對外網暴露服務了。如果要nginx高可用的話,可以在多個node39上部署,並在前面再搭建一套LVS+keepalive做負載均衡。

6.5 創建ingress規則
6.5.1 創建一個deployment和svc
在主節點創建
vim service-nginx.yaml
==========================================================
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
run: nginx-app
name: nginx-app
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx-app
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata :
name: nginx-service
spec:
type: ClusterIP
ports :
- port: 7777
targetPort: 80
selector :
app: nginx
==========================================================
kubectl apply -f service-nginx.yaml
kubectl get pod,svc

6.5.2 創建ingress
vim ingress-1.yaml
==========================================================
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-ingress
spec:
rules:
- host: www.gxd.com
http:
paths:
- path: /
backend:
serviceName: nginx-service #指定你創建的svc的名稱
servicePort: 80
==========================================================
kubectl apply -f ingress-1.yaml
kubectl get pod,svc,ingress

6.6 做端口映射並訪問測試
echo '192.168.10.30 www.gxd.com' >> /etc/hosts
curl www.gxd.com

6.7 查看nginx-ingress-controller
kubectl get pod -n ingress-nginx -o wide
kubectl exec -it nginx-ingress-controller-k5vvf -n ingress-nginx bash



七、采用方式三:Deployment+NodePort模式的Service
7.1 下載nginx-ingress-controller和ingress-nginx暴露端口配置文件
在主節點
mkdir /opt/ingress-nodeport
cd /opt/ingress-nodeport
官方下載地址:
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml
國內 gitee 資源地址:
wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/mandatory.yaml
wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml

7.2 在所有node節點上傳鏡像包ingress-controller-0.30.0.tar到/opt/ingress-nodeport目錄,並加載鏡像
在所有node節點
mkdir /opt/ingress-nodeport
cd /opt/ingress-nodeport
tar zxvf ingree.contro-0.30.0.tar.gz
docker load -i ingree.contro-0.30.0.tar

7.3 啟動nginx-ingress-controller
kubectl apply -f mandatory.yaml
kubectl apply -f service-nodeport.yaml

7.4 創建deployment、service和ingress的yaml資源
vim ingress-nginx.yaml
==========================================================
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-app
spec:
replicas: 2
template:
metadata:
labels:
name: nginx
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
name: nginx
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-test
spec:
rules:
- host: www.gxd111.com
http:
paths:
- path: /
backend:
serviceName: nginx-svc
servicePort: 80
==========================================================kubectl apply -f ingress-nginx.yaml
kubectl get pod,svc,ingress -owide

7.5 做端口映射並訪問測試
echo '192.168.10.30 www.gxd111.com' >> /etc/hosts
curl www.gxd111.com

八、ingress http代理訪問虛擬主機
mkdir /opt/ingress-nodeport/vhost
cd /opt/ingress-nodeport/vhost
==========================================================
#創建虛擬主機1資源
vim demo1.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: deployment1
spec:
replicas: 2
template:
metadata:
labels:
name: nginx1
spec:
containers:
- name: nginx1
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: svc-1
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
name: nginx1
type: ClusterIP
==========================================================
#創建虛擬主機2資源
vim demo2.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: deployment2
spec:
replicas: 2
template:
metadata:
labels:
name: nginx2
spec:
containers:
- name: nginx2
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: svc-2
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
name: nginx2
type: ClusterIP
==========================================================
創建ingress資源
vim ingress-nginx.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress1
spec:
rules:
- host: www1.gxd.com
http:
paths:
- path: /
backend:
serviceName: svc-1
servicePort: 80
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress2
spec:
rules:
- host: www2.gxd.com
http:
paths:
- path: /
backend:
serviceName: svc-2
servicePort: 80
==========================================================
kubectl apply -f demo1.yaml
kubectl apply -f demo2.yaml
kubectl apply -f ingress-nginx.yaml
kubectl get pod,svc,ingress

echo '192.168.10.30 www1.gxd.com ' >> /etc/hosts
echo '192.168.10.30 www2.gxd.com ' >> /etc/hosts
curl www1.gxd.com:31396
curl www2.gxd.com:31396

九、ingress https代理訪問
9.1 創建工作目錄
mkdir /opt/ingress-nodeport/https
cd /opt/ingress-nodeport/https
9.2 創建ssl證書
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginXsvc/O=nginxsvc"

9.3 創建secret資源進行存儲
kubectl create secret tls tls-secret --key tls.key --cert tls.crt
kubectl get secret
kubectl describe secret tls-secret

9.4 創建deployment、service和ingress的yaml資源
vim demo3.yaml
==========================================================
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-app
spec:
replicas: 2
template:
metadata:
labels:
name: nginx
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: svc-3
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
name: nginx
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress3
spec:
tls:
- hosts:
- www.gxd222.com
secretName: tls-secret
rules:
- host: www.gxd222.com
http:
paths:
- path: /
backend:
serviceName: svc-3
servicePort: 80
==========================================================kubectl apply -f demo3.yaml
kubectl get pod,svc,ingress

9.5 做端口映射並訪問測試
echo '192.168.10.30 www.gxd222.com' >> /etc/hosts
在瀏覽器訪問 https://www.gxd222.com:31067
點擊高級選項,確認安全例外即可

十、nginx進行BasicAuth(訪問前輸入用戶和密碼)
10.1 創建工作目錄
mkdir /opt/ingress-nodeport/basic-auth
cd /opt/ingress-nodeport/basic-auth
10.2 生成用戶密碼文件,創建secret資源進行存儲
yum install -y httpd
htpasswd -c auth gxd
kubectl create secret generic basic-auth --from-file=auth
kubectl get secret
kubectl describe secret basic-auth

10.3 創建ingress資源
//具體詳細設置方法可參考官網https://kubernetes.github.io/ingress-nginx/examples/auth/basic/
vim ingress-auth.yaml
==========================================================
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-auth
annotations:
#設置認證類型basic
nginx.ingress.kubernetes.io/auth-type: basic
#設置secret資源名稱basic-auth
nginx.ingress.kubernetes.io/auth-secret: basic-auth
#設置認證窗口提示信息
nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - gxd'
spec:
rules:
- host: auth.gxd.com
http:
paths:
- path: /
backend:
serviceName: svc-2 #之前指定創建過的svc
servicePort: 80
==========================================================
kubectl apply -f ingress-auth.yaml
kubectl get ingress

10.4 做端口映射並訪問測試
echo '192.168.10.30 auth.gxd.com' >> /etc/hosts
在瀏覽器訪問 http://auth.gxd.com:31396


十一、nginx進行重寫
11.1 配置說明
nginx.ingress.kubernetes.io/rewrite-target:<字符串>#必須重定向流量的目標URI
nginx.ingress . kubernetes.io/ssl-redirect:<布爾值>指示位置部分是否僅可訪問sSL(當Ingress包含證書時,默認為true)nginx.ingress . kubernetes.io/force-ssl-redirect:<布爾值>#即使Ingress未啟用rLS,也強制重定向到HTTPS
nginx.ingress .kubernetes.io/app-root:<字符串>#定義controller必須重定向的應用程序根,如果它在'/'上下文中·nginx.ingress, kubernetes.io/use-regex:<布爾值>#指示Ingress.上定義的路徑是否使用正則表達式
11.2 編寫yaml文件
vim ingress-rewrite.yaml
==========================================================
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-rewrite
annotations:
nginx.ingress.kubernetes.io/rewrite-target: http://auth.gxd.com:31396
spec:
rules:
- host: rewrite.gxd.com
http:
paths:
- path: /
backend:
serviceName: ggggg #由於rewrite.gxd.com只是用於跳轉不需要真實站點存在,因此svc資源名稱可隨意定義
servicePort: 1111
==========================================================
kubectl apply -f ingress-rewrite.yaml
kubectl get ingress

11.3 做端口映射並訪問測試
echo '192.168.10.30 rewrite.gxd.com' >> /etc/hosts
在瀏覽器訪問 http://rewrite.gxd.com


