關(guān)于 K8s中SVC實(shí)現(xiàn)Ingress負(fù)載均衡器Demo
寫(xiě)在前面
學(xué)習(xí)K8s中Service遇到,單獨(dú)整理分享給小伙伴
博文內(nèi)容涉及:
ingress-nginx-controller的創(chuàng)建
基于ingress-nginx-controller的Ingress的創(chuàng)建
基于Ingress的服務(wù)發(fā)布,SVC負(fù)載
食用方式:
時(shí)間關(guān)系,關(guān)于Ingresshttp路由負(fù)載本文沒(méi)有涉及
部分地方使用ansible,不影響閱讀
「 每天起床的第一句話,告訴自己,沉淪的小酒館已經(jīng)打烊了啦!要好好愛(ài)護(hù)自己的身體 ---山河已無(wú)恙」
ingress
「Service的表現(xiàn)形式為IP:Port,即工作在TCP/IP層?!?對(duì)于基于HTTP的服務(wù)來(lái)說(shuō),不同的URL地址經(jīng)常對(duì)應(yīng)到不同的后端服務(wù)或者虛擬服務(wù)器(Virtual Host)這些應(yīng)用層的轉(zhuǎn)發(fā)機(jī)制僅通過(guò)Kubernetes的Service機(jī)制是無(wú)法實(shí)現(xiàn)的。
從Kubernetes 1.1版本開(kāi)始新增Ingress資源對(duì)象,用于將不同URL的訪問(wèn)請(qǐng)求轉(zhuǎn)發(fā)到后端不同的Service,以實(shí)現(xiàn)HTTP層的業(yè)務(wù)路由機(jī)制。但是并不是說(shuō)只能做7層路由,四層負(fù)載也可以
「Kubernetes使用了一個(gè)Ingress策略定義和一個(gè)具體的Ingress Controller,兩者結(jié)合并實(shí)現(xiàn)了一個(gè)完整的Ingress負(fù)載均衡器?!?br>
?
使用Ingress進(jìn)行負(fù)載分發(fā)時(shí)是不是和kube-proxy沒(méi)啥關(guān)系,直接分發(fā)到pod上了,使用Load Balancer和nodeport才會(huì)使用kube-proxy ?
?
使用Ingress進(jìn)行負(fù)載分發(fā)時(shí), Ingress Controller基于Ingress規(guī)則將客戶端請(qǐng)求直接轉(zhuǎn)發(fā)到Service對(duì)應(yīng)的后端Endpoint (Pod)上,這樣會(huì)跳過(guò)kube-proxy的轉(zhuǎn)發(fā)功能, kube-proxy不再起作用。如果IngressController提供的是對(duì)外服務(wù),則實(shí)際上實(shí)現(xiàn)的是邊緣路由器的功能。
「控制器通過(guò)svc獲取endpoints并獲取對(duì)應(yīng)的pod信息,然后通過(guò)nginx內(nèi)部的lua代碼進(jìn)行處理」
官網(wǎng)中的一些描述
Ingress
Ingress 是對(duì)集群中服務(wù)的外部訪問(wèn)進(jìn)行管理的 API 對(duì)象,典型的訪問(wèn)方式是 HTTP。
Ingress 可以提供負(fù)載均衡、SSL 終結(jié)和基于名稱的虛擬托管。
Ingress 公開(kāi)了從集群外部到集群內(nèi)服務(wù)的 HTTP 和 HTTPS 路由。 流量路由由 Ingress 資源上定義的規(guī)則控制。
個(gè)人理解,就是實(shí)現(xiàn)了一個(gè)Ngixn功能,可以更具路由規(guī)則分配流量等
命名空間里配置ingress規(guī)則,嵌入到控制器nginx-反向代理的方式(ingress-nginx-controller)
可以將 Ingress 配置為服務(wù)提供外部可訪問(wèn)的 URL、負(fù)載均衡流量、終止 SSL/TLS,以及提供基于名稱的虛擬主機(jī)等能力。 Ingress 控制器 通常負(fù)責(zé)通過(guò)負(fù)載均衡器來(lái)實(shí)現(xiàn) Ingress,盡管它也可以配置邊緣路由器或其他前端來(lái)幫助處理流量。
Ingress 不會(huì)公開(kāi)任意端口或協(xié)議。 將 HTTP 和 HTTPS 以外的服務(wù)公開(kāi)到 Internet 時(shí),通常使用 Service.Type=NodePort 或 Service.Type=LoadBalancer 類型的服務(wù)
為使用Ingress,需要?jiǎng)?chuàng)建Ingress Controller(帶一個(gè)默認(rèn)backend服務(wù))和Ingress策略設(shè)置來(lái)共同完成。
在定義Ingress策略之前,需要先部署Ingress Controller,以實(shí)現(xiàn)為所有后端Service都提供一個(gè)統(tǒng)一的入口。Ingress Controller需要實(shí)現(xiàn)基于不同HTTP URL向后轉(zhuǎn)發(fā)的負(fù)載分發(fā)規(guī)則,并可以靈活設(shè)置7層負(fù)載分發(fā)策略。
如果公有云服務(wù)商能夠提供該類型的HTTP路由LoadBalancer,則也可設(shè)置其為Ingress Controller。在Kubernetes中, Ingress Controller將以Pod的形式運(yùn)行,監(jiān)控APIServer的/ingress接口后端的backend services,如果Service發(fā)生變化,則Ingress Controller應(yīng)自動(dòng)更新其轉(zhuǎn)發(fā)規(guī)則。
下面的例子使用Nginx來(lái)實(shí)現(xiàn)一個(gè)Ingress Controller,正常情況下ingress-nginx-controller 會(huì)作為一個(gè)deamonSet,即位于沒(méi)一個(gè)Node上。這里我們?yōu)榱朔奖?,只是在一個(gè)node上配置,同時(shí)寫(xiě)如NDS映射
ingress-nginx-controller 部署
「需要的鏡像,相關(guān)的資源文件,小伙伴可以在k8s官網(wǎng)獲取」
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$grep image nginx-controller.yaml
image: docker.io/liangjw/ingress-nginx-controller:v1.0.1
imagePullPolicy: IfNotPresent
image: docker.io/liangjw/kube-webhook-certgen:v1.1.1
imagePullPolicy: IfNotPresent
image: docker.io/liangjw/kube-webhook-certgen:v1.1.1
imagePullPolicy: IfNotPresent
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$
「準(zhǔn)備工作,鏡像上傳,導(dǎo)入」
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$ansible node -m copy -a "dest=/root/ src=./../ingress-nginx-controller-img.tar"
192.168.26.82 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "a3c2f87fd640c0bfecebeab24369c7ca8d6f0fa0",
"dest": "/root/ingress-nginx-controller-img.tar",
"gid": 0,
"group": "root",
"md5sum": "d5bf7924cb3c61104f7a07189a2e6ebd",
"mode": "0644",
"owner": "root",
"size": 334879744,
"src": "/root/.ansible/tmp/ansible-tmp-1640207772.53-9140-99388332454846/source",
"state": "file",
"uid": 0
}
192.168.26.83 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "a3c2f87fd640c0bfecebeab24369c7ca8d6f0fa0",
"dest": "/root/ingress-nginx-controller-img.tar",
"gid": 0,
"group": "root",
"md5sum": "d5bf7924cb3c61104f7a07189a2e6ebd",
"mode": "0644",
"owner": "root",
"size": 334879744,
"src": "/root/.ansible/tmp/ansible-tmp-1640207772.55-9142-78097462005167/source",
"state": "file",
"uid": 0
}
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$ansible node -m shell -a "docker load -i /root/ingress-nginx-controller-img.tar"
「創(chuàng)建ingress控制器ingress-nginx-controller」
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$kubectl apply -f nginx-controller.yaml
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$kubectl get pods -n ingress-nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ingress-nginx-admission-create--1-hvvxd 0/1 Completed 0 89s 10.244.171.171 vms82.liruilongs.github.io <none> <none>
ingress-nginx-admission-patch--1-g4ffs 0/1 Completed 0 89s 10.244.70.7 vms83.liruilongs.github.io <none> <none>
ingress-nginx-controller-744d4fc6b7-7fcfj 1/1 Running 0 90s 192.168.26.83 vms83.liruilongs.github.io <none> <none>
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$
我們這里只是在192.168.26.83上創(chuàng)建了一個(gè)ingress控制器pod,生產(chǎn)環(huán)境一般需要每個(gè)節(jié)點(diǎn)上存在一個(gè),即通過(guò)deamonset的方式「DNS解析的地址為控制器的地址,這里控制器使用的是docker內(nèi)部網(wǎng)絡(luò)的方式,即直接把端口映射宿主機(jī)了」
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$grep -i hostN nginx-controller.yaml
hostNetwork: true
「因?yàn)閜od是在192.168.26.83節(jié)點(diǎn),所以我們需要 配置DNS」 「創(chuàng)建域名到服務(wù)的映射」
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$ansible 192.168.26.83 -m shell -a "echo -e '192.168.26.83 liruilongs.nginx1\n192.168.26.83 liruilongs.nginx2\n192.168.26.83 liruilongs.nginx3' >> /etc/hosts"
192.168.26.83 | CHANGED | rc=0 >>
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$ansible 192.168.26.83 -m shell -a "cat /etc/hosts"
192.168.26.83 | CHANGED | rc=0 >>
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.26.81 vms81.liruilongs.github.io vms81
192.168.26.82 vms82.liruilongs.github.io vms82
192.168.26.83 vms83.liruilongs.github.io vms83
192.168.26.83 liruilongs.nginx1
192.168.26.83 liruilongs.nginx2
192.168.26.83 liruilongs.nginx3
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$
「服務(wù)模擬,創(chuàng)建三個(gè)pod做為SVC提供能力」
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$cat pod.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod-svc
name: pod-svc
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: pod-svc
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$kubectl apply -f pod.yaml
pod/pod-svc created
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$sed 's/pod-svc/pod-svc-1/' pod.yaml > pod-1.yaml
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$sed 's/pod-svc/pod-svc-2/' pod.yaml > pod-2.yaml
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$kubectl apply -f pod-1.yaml
pod/pod-svc-1 created
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$kubectl apply -f pod-2.yaml
pod/pod-svc-2 created
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-svc 1/1 Running 0 2m42s 10.244.171.174 vms82.liruilongs.github.io <none> <none>
pod-svc-1 1/1 Running 0 80s 10.244.171.175 vms82.liruilongs.github.io <none> <none>
pod-svc-2 1/1 Running 0 70s 10.244.171.176 vms82.liruilongs.github.io <none> <none>
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$
「修改Nginx的主頁(yè),區(qū)分訪問(wèn)的pod,根據(jù)pod創(chuàng)建三個(gè)服務(wù)SVC」
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
pod-svc 1/1 Running 0 3m7s run=pod-svc
pod-svc-1 1/1 Running 0 105s run=pod-svc-1
pod-svc-2 1/1 Running 0 95s run=pod-svc-2
「這個(gè)創(chuàng)建SVC通過(guò) selector的方式」
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$serve=pod-svc
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$kubectl exec -it $serve -- sh -c "echo $serve > /usr/share/nginx/html/index.html"
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$kubectl expose --name=$serve-svc pod $serve --port=80
service/pod-svc-svc exposed
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$serve=pod-svc-1
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$kubectl exec -it $serve -- sh -c "echo $serve > /usr/share/nginx/html/index.html"
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$kubectl expose --name=$serve-svc pod $serve --port=80
service/pod-svc-1-svc exposed
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$serve=pod-svc-2
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$kubectl exec -it $serve -- sh -c "echo $serve > /usr/share/nginx/html/index.html"
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$kubectl expose --name=$serve-svc pod $serve --port=80
service/pod-svc-2-svc exposed
「創(chuàng)建了三個(gè)SVC做負(fù)載模擬」
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$kubectl get svc -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
pod-svc-1-svc ClusterIP 10.99.80.121 <none> 80/TCP 94s run=pod-svc-1
pod-svc-2-svc ClusterIP 10.110.40.30 <none> 80/TCP 107s run=pod-svc-2
pod-svc-svc ClusterIP 10.96.152.5 <none> 80/TCP 85s run=pod-svc
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$kubectl get ing
No resources found in liruilong-svc-create namespace.
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$vim ingress.yaml
「創(chuàng)建 Ingress,當(dāng)然這里只是簡(jiǎn)單測(cè)試,可以更具具體業(yè)務(wù)情況配置復(fù)雜的路由策略」「ingress.yaml,訪問(wèn)"/"的時(shí)候,會(huì)調(diào)度到三個(gè)SVC里,這里需要注意的是和kube-proxy沒(méi)啥關(guān)系,Ngixn控制器內(nèi)部的負(fù)載」
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
kubernetes.io/ingress.class: "nginx" #必須要加
spec:
rules:
- host: liruilongs.nginx1
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: pod-svc-svc
port:
number: 80
- host: liruilongs.nginx2
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: pod-svc-1-svc
port:
number: 80
- host: liruilongs.nginx3
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: pod-svc-2-svc
port:
number: 80
「創(chuàng)建查看Ingress。hsots中會(huì)列出所以的負(fù)載域名」
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$kubectl apply -f ingress.yaml
ingress.networking.k8s.io/my-ingress created
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$kubectl get ing
NAME CLASS HOSTS ADDRESS PORTS AGE
my-ingress <none> liruilongs.nginx1,liruilongs.nginx2,liruilongs.nginx3 80 17s
「負(fù)載測(cè)試」
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$ansible 192.168.26.83 -m shell -a "curl liruilongs.nginx1"
192.168.26.83 | CHANGED | rc=0 >>
pod-svc
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$ansible 192.168.26.83 -m shell -a "curl liruilongs.nginx2"
192.168.26.83 | CHANGED | rc=0 >>
pod-svc-1
?
這只是一個(gè)Ingress做SVC負(fù)載的一個(gè)Demo,時(shí)間關(guān)系,關(guān)于使用Ingree 做HTTP路由負(fù)載的Demo之后有時(shí)間和小伙伴分享,生活加油
?
作者:山河已無(wú)恙
歡迎關(guān)注微信公眾號(hào) :山河已無(wú)恙