提升CKA認證成功率:Kubernetes Ingress七層代理全攻略!
一、Ingress介紹
Ingress是Kubernetes中負責(zé)將外部請求引導(dǎo)到集群內(nèi)部服務(wù)的機制,通過將服務(wù)映射到集群外的URL,實現(xiàn)服務(wù)的外部可訪問性。Ingress支持配置集群內(nèi)的Service,使其可以通過外部URL訪問,同時提供流量負載均衡和基于域名的虛擬主機等功能。
簡單理解Ingress就是將原本需要手動修改Nginx配置、配置域名與服務(wù)映射的繁瑣步驟,抽象成一個Ingress對象。通過使用YAML文件創(chuàng)建和更新Ingress對象,我們不再需要手動操作Nginx配置文件,而是通過更方便的方式管理域名與服務(wù)的關(guān)系。
然而,這引發(fā)了一個問題:“Nginx應(yīng)該如何處理這些變化?”這時候,Ingress Controller登場,專門解決Nginx處理方式的問題。Ingress Controller與Kubernetes API進行交互,實時感知集群中Ingress規(guī)則的變化。一旦有變化,Ingress Controller會讀取這些規(guī)則,并根據(jù)自己的模板生成相應(yīng)的Nginx配置。隨后,它將這段配置寫入Nginx Pod,最后觸發(fā)Nginx的重載操作,確保配置的生效。
通過Ingress和Ingress Controller的配合,我們在管理外部訪問時變得更加靈活和便捷,擺脫了手動修改Nginx配置的煩惱,讓我們能夠更專注于服務(wù)與域名的映射關(guān)系,提升了Kubernetes集群的可維護性。
1.Ingress Controller介紹
Ingress Controller是一種七層負載均衡調(diào)度器,它作為客戶端請求的第一站,接收并處理所有外部請求。在這個七層負載均衡調(diào)度器的作用下,請求會經(jīng)過反向代理,最終被路由到后端的Pod。常見的七層負載均衡器包括nginx、traefik等。以我們熟悉的nginx為例,當(dāng)請求到達nginx時,nginx會通過upstream配置反向代理到后端Pod應(yīng)用。
Ingress Controller
然而,后端Pod的IP地址是動態(tài)變化的,為了解決這個問題,我們引入了Service。這個Service并非實際的服務(wù),而是起到了對后端Pod的分組作用。因此,在配置upstream時,我們只需要填寫Service的地址即可,而不需要關(guān)心后端Pod的具體IP地址。
通過這樣的設(shè)計,Ingress Controller能夠靈活處理后端Pod的變化,保證請求能夠正確地路由到集群中的服務(wù)。這種模式使得我們能夠更方便地管理后端服務(wù)的變化,而不必擔(dān)心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
Ingress 需要指定 apiVersion、kind、 metadata和 spec 字段。Ingress 對象的命名必須是合法的 DNS 子域名名稱[1]。
3.Ingress Controller代理k8s內(nèi)部應(yīng)用的流程
- 部署Ingress controller,我們ingress controller使用的是nginx
- 創(chuàng)建Pod應(yīng)用,可以通過控制器創(chuàng)建pod
- 創(chuàng)建Service,用來分組pod
- 創(chuàng)建Ingress http,測試通過http訪問應(yīng)用
- 創(chuàng)建Ingress https,測試通過https訪問應(yīng)用
必須具有 ingress 控制器,才能滿足 Ingress 的要求。僅創(chuàng)建 Ingress 資源無效。
Ingress
(1) 部署ingress-nginx
這里同樣使用killercoda平臺進行測試,該平臺部署的是最新版V1.29.0的K8S環(huán)境。
由于該環(huán)境沒有部署Ingress。以下通過部署ingress-nginx[2]為例。通過查閱ingress-nginx官方,了解V1.29.0對應(yīng)的是Ingress-NGINX 的V1.10.0或v1.9.6。如下:
Ingress-NGINX的版本列表
通過執(zhí)行如下命令部署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
執(zhí)行完上述命令,輸出如下結(jié)果:
通過如下命令查看部署情況:
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
(2) 部署后端tomcat服務(wù)
通過部署tomcat服務(wù)測試Ingress HTTP代理k8s內(nèi)部站點,編寫如下資源清單:
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
查看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
(3) 編寫Ingress規(guī)則
apiVersion:networking.k8s.io/v1
kind:Ingress
metadata:
name:ingress-myapp
namespace:default
annotations:
nginx.ingress.kubernetes.io/rewrite-target:/
spec:
ingressClassName:nginx
rules:# 定義后端的轉(zhuǎn)發(fā)規(guī)則
-host:tomcat.test.com# 通過域名進行轉(zhuǎn)發(fā)
http:
paths:
-path:/#配置訪問路徑,如果通過url進行轉(zhuǎn)發(fā)。需要修改,空的默認訪問路徑是"/"
pathType:Prefix
backend:# 配置后端服務(wù)
service:
name:tomcat# 配置關(guān)聯(lián)的serverce
port:
number:8080# service暴露的端口
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
查看ingress-nginx部署到那個節(jié)點上,如下圖:
通上圖可知ingress-nginx部署到node1上,并且SVC方式是通過LoadBalancer方式部署。如果,要訪問到這個后端tomcat服務(wù),需要做域名的解析。如下:
...省略..
172.30.2.2 tomcat.test.com
正常訪問如下:
4.CKA真題
(1) 真題截圖
(2) 中文解析
切換 k8s 集群環(huán)境:kubectl config use-context k8s
Task:
如下創(chuàng)建一個新的 nginx lngress資源:
名稱:pong Namespace:ing-internal
使用服務(wù)端口 5678 在路徑 /hi 上公開服務(wù)hi
可以使用以下命令檢查服務(wù) hi 的可用性,該命令應(yīng)返回 hi, curl -kL/hi
(3) 官方參考文檔
Ingress[3]
(4) 解題作答
切換 k8s 集群環(huán)境:
kubectl config use-context k8s
創(chuàng)建一個名為pong.yaml。資源內(nèi)容如下:
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
- ingressClassName的值,建議在考試的時候通過kubectl get ingressclasses
- service.name的值,題目中沒有告訴,建議在考試時候可以通過kubectl get svc 查看
提交資源清單:
kubectl apply -f pong.yaml
通過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/