提升CKA認證成功率:Kubernetes Ingress七層代理商全攻略!
一、Ingress介紹
Ingress是Kubernetes中負責將外部請求引導到叢集內部服務的機制,透過將服務對應到叢集外的URL,實現服務的外部可存取性。Ingress支援配置叢集內的Service,使其可以透過外部URL訪問,同時提供流量負載平衡和基於網域的虛擬主機等功能。
簡單理解Ingress就是將原本需要手動修改Nginx配置、配置網域名稱與服務對映的繁瑣步驟,抽象化成一個Ingress物件。透過使用YAML檔案建立和更新Ingress對象,我們不再需要手動操作Nginx設定文件,而是透過更方便的方式管理網域名稱與服務的關係。
然而,這引發了一個問題:「Nginx該如何處理這些變化?」這時候,Ingress Controller登場,專門解決Nginx處理方式的問題。Ingress Controller與Kubernetes API進行交互,即時感知叢集中Ingress規則的變化。一旦有變化,Ingress Controller會讀取這些規則,並根據自己的模板產生相應的Nginx配置。隨後,它將這段設定寫入Nginx Pod,最後觸發Nginx的重載操作,確保設定的生效。
透過Ingress和Ingress Controller的配合,我們在管理外部存取時變得更加靈活和便捷,擺脫了手動修改Nginx配置的煩惱,讓我們能夠更專注於服務與域名的映射關係,提升了Kubernetes集群的可維護性。
1.Ingress Controller介紹
Ingress Controller是一種七層負載平衡調度器,它作為客戶端請求的第一站,接收並處理所有外部請求。在這個七層負載平衡調度器的作用下,請求會經過反向代理,最後被路由到後端的Pod。常見的七層負載平衡器包括nginx、traefik等。以我們熟悉的nginx為例,當請求到達nginx時,nginx會透過upstream設定反向代理到後端Pod應用。
Ingress Controller
然而,後端Pod的IP位址是動態變化的,為了解決這個問題,我們引入了Service。這個Service並非實際的服務,而是扮演了後端Pod的分組角色。因此,在設定upstream時,我們只需要填入Service的位址即可,而不需要關心後端Pod的特定IP位址。
透過這樣的設計,Ingress Controller能夠靈活處理後端Pod的變化,保證請求能夠正確地路由到叢集中的服務。這種模式使得我們能夠更方便地管理後端服務的變化,而不必擔心Pod的IP位址的不斷變化所帶來的問題。
2.Ingress資源
一個最小的Ingress 資源範例:
apiVersion:networking.k8s.io/v1
kind:Ingress
metadata:
name:minimal-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target:/
spec:
ingressClassName:nginx-example
rules:
-http:
paths:
-path:/testpath
pathType:Prefix
backend:
service:
name:test
port:
number:80
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
Ingress 需要指定apiVersion、kind、 metadata和spec 欄位。Ingress 物件的命名必須是合法的 DNS 子網域名稱[1]。
3.Ingress Controller代理k8s內部應用的流程
- 部署Ingress controller,我們ingress controller使用的是nginx
- 建立Pod應用,可以透過控制器建立pod
- 建立Service,用來分組pod
- 建立Ingress http,測試透過http存取應用
- 建立Ingress https,測試透過https存取應用
必須具有ingress 控制器,才能滿足Ingress 的要求。僅建立Ingress 資源無效。
Ingress
(1) 部署ingress-nginx
這裡同樣使用killercoda平台進行測試,該平台部署的是最新版V1.29.0的K8S環境。
由於該環境沒有部署Ingress。以下透過部署ingress-nginx[2]為例。透過查閱ingress-nginx官方,了解V1.29.0對應的是Ingress-NGINX 的V1.10.0或v1.9.6。如下:
Ingress-NGINX的版本列表
透過執行以下指令部署Ingress-NGINX 的V1.10.0。
kubectl apply -f \
https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.10.0/deploy/static/provider/cloud/deploy.yaml
- 1.
- 2.
執行完上述指令,輸出如下結果:
透過以下命令查看部署情況:
controlplane $ kubectl get pod -n ingress-nginx
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-d69wp 0/1 Completed 0 102s
ingress-nginx-admission-patch-hkv66 0/1 Completed 0 102s
ingress-nginx-controller-7dcdbcff84-gfqcs 1/1 Running 0 102s
controlplane $ kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller LoadBalancer 10.98.23.38 <pending> 80:30770/TCP,443:31444/TCP 3m57s
ingress-nginx-controller-admission ClusterIP 10.102.219.183 <none> 443/TCP 3m57s
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
(2) 部署後端tomcat服務
透過部署tomcat服務測試Ingress HTTP代理k8s內部站點,編寫以下資源清單:
apiVersion:v1
kind:Service
metadata:
name:tomcat
namespace:default
spec:
selector:
app:tomcat
release:canary
ports:
-name:scport
targetPort:8080
port:8009
---
apiVersion:apps/v1
kind:Deployment
metadata:
name:tomcat-deploy
namespace:default
spec:
replicas:2
selector:
matchLabels:
app:tomcat
release:canary
template:
metadata:
labels:
app:tomcat
release:canary
spec:
containers:
-name:tomcat
image:tomcat:8.5.34-jre8-alpine
imagePullPolicy:IfNotPresent
ports:
-name:containerport
containerPort:8080
name:ajp
containerPort:8009
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
查看pod是否部署成功:
controlplane $ kubectl apply -f ingress-demo.yaml
service/tomcat created
deployment.apps/tomcat-deploy created
controlplane $ kubectl get pod
NAME READY STATUS RESTARTS AGE
tomcat-deploy-7c67c4d459-5s859 1/1 Running 0 11m
tomcat-deploy-7c67c4d459-bvp2k 1/1 Running 0 11m
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
(3) 撰寫Ingress規則
apiVersion:networking.k8s.io/v1
kind:Ingress
metadata:
name:ingress-myapp
namespace:default
annotations:
nginx.ingress.kubernetes.io/rewrite-target:/
spec:
ingressClassName:nginx
rules:# 定义后端的转发规则
-host:tomcat.test.com# 通过域名进行转发
http:
paths:
-path:/#配置访问路径,如果通过url进行转发。需要修改,空的默认访问路径是"/"
pathType:Prefix
backend:# 配置后端服务
service:
name:tomcat# 配置关联的serverce
port:
number:8080# service暴露的端口
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
ingressClassName:這個值可以透過kubectl get ingressclasses。
查看ingress-myapp的詳細資訊:
controlplane $ kubectl apply -f ingress-myapp.yaml
ingress.networking.k8s.io/ingress-myapp created
controlplane $ kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress-myapp nginx tomcat.test.com 80 8s
controlplane $ kubectl describe ingress ingress-myapp
Name: ingress-myapp
Labels: <none>
Namespace: default
Address:
Ingress Class: nginx
Default backend: <default>
Rules:
Host Path Backends
---- ---- --------
tomcat.test.com
/ tomcat:8080 ()
Annotations: nginx.ingress.kubernetes.io/rewrite-target: /
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Sync 62s nginx-ingress-controller Scheduled for sync
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
查看ingress-nginx部署到那個節點上,如下圖:
通上圖可知ingress-nginx部署到node1上,且SVC方式是透過LoadBalancer方式部署。如果,要存取到這個後端tomcat服務,就需要做網域的解析。如下:
...省略..
172.30.2.2 tomcat.test.com
- 1.
- 2.
正常訪問如下:
4.CKA真題
(1) 真題截圖
(2) 中文解析
切換k8s 叢集環境:kubectl config use-context k8s
Task:
如下建立一個新的nginx lngress資源:
名稱:pong Namespace:ing-internal
使用服務埠5678 在路徑/hi 上公開服務hi
可以使用以下命令檢查服務hi 的可用性,該命令應返回hi, curl -kL/hi
(3) 官方參考文檔
Ingress[3]
(4) 解題作答
切換k8s 叢集環境:
kubectl config use-context k8s
- 1.
建立一個名為pong.yaml。資源內容如下:
apiVersion:networking.k8s.io/v1
kind:Ingress
metadata:
name:pong
namespace:ing-internal
annotations:
nginx.ingress.kubernetes.io/rewrite-target:/
spec:
ingressClassName:nginx-example
rules:
-http:
paths:
-path:/hi
pathType:Prefix
backend:
service:
name:hi
port:
number:5678
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- ingressClassName的值,建議在考試的時候通過kubectl get ingressclasses
- service.name的值,題目中沒有告訴,建議考試時間可以用kubectl get svc 查看
提交資源清單:
kubectl apply -f pong.yaml
- 1.
透過curl -kL<INTERNAL_IP>/hi驗證,看是否返回hi。
參考資料:
- [1]DNS 子網域名稱: https://kubernetes.io/zh-cn/docs/concepts/overview/working-with-objects/names#dns-subdomain-names
- [2]ingress-nginx: https://github.com/kubernetes/ingress-nginx
- [3]Ingress: https://kubernetes.io/zh-cn/docs/concepts/services-networking/ingress/