kubectl get all -A ? 查看全部名稱空間的pod枷餐,找控制器下的pod
負(fù)載均衡是什么?
負(fù)載均衡是由多臺(tái)服務(wù)器以對(duì)稱的方式組成一個(gè)服務(wù)器集合鸿秆,每臺(tái)服務(wù)器都具有等價(jià)的地位,都可以 單獨(dú)對(duì)外提供服務(wù)而無(wú)需其他服務(wù)器的輔助捺疼。通過(guò)某種負(fù)載分擔(dān)技術(shù)女揭,將外部發(fā)送來(lái)的請(qǐng)求按照某種策略 分配到服務(wù)器集合的某一臺(tái)服務(wù)器上屏鳍,而接收到請(qǐng)求的服務(wù)器獨(dú)立地回應(yīng)客戶的請(qǐng)求。負(fù)載均衡解決了大 量并發(fā)訪問(wèn)服務(wù)問(wèn)題挖函,其目的就是用最少的投資獲得接近于大型主機(jī)的性能状植。
四層負(fù)載均衡:lvs(軟件層面)、f5(硬件層面)
缺點(diǎn):對(duì)網(wǎng)絡(luò)依賴較大怨喘,負(fù)載智能化方面沒(méi)有?7?層負(fù)載好(比如不支持對(duì)?url?個(gè)性化負(fù)載)津畸,F(xiàn)5?硬件 性能很高但成本也高,需要人民幣幾十萬(wàn)必怜,對(duì)于小公司就望而卻步了肉拓。
常見(jiàn)的七層負(fù)載均衡:nginx、apache
優(yōu)點(diǎn):對(duì)網(wǎng)絡(luò)依賴少梳庆,負(fù)載智能方案多(比如可根據(jù)不同的?url?進(jìn)行負(fù)載)
在?k8s?中為什么要做負(fù)載均衡?
Pod?漂移問(wèn)題
Kubernetes?具有強(qiáng)大的副本控制能力暖途,能保證在任意副本(Pod)掛掉時(shí)自動(dòng)從其他機(jī)器啟動(dòng)一個(gè)新的,還可以動(dòng)態(tài)擴(kuò)容等膏执。通俗地說(shuō)驻售,這個(gè)?Pod?可能在任何時(shí)刻出現(xiàn)在任何節(jié)點(diǎn)上,也可能在任何時(shí)刻 死在任何節(jié)點(diǎn)上;那么自然隨著?Pod?的創(chuàng)建和銷毀更米,Pod IP?肯定會(huì)動(dòng)態(tài)變化;那么如何把這個(gè)動(dòng)態(tài)的?Pod IP?暴露出去?這里借助于?Kubernetes?的?Service?機(jī)制欺栗,Service?可以以標(biāo)簽的形式選定一組帶 有指定標(biāo)簽的?Pod,并監(jiān)控和自動(dòng)負(fù)載他們的?Pod IP征峦,那么我們向外暴露只暴露?Service IP?就行了;這 就是?NodePort?模式:即在每個(gè)節(jié)點(diǎn)上開(kāi)起一個(gè)端口迟几,然后轉(zhuǎn)發(fā)到內(nèi)部?Pod IP?上。
使用?service?做四層負(fù)載均衡
在?kubernetes?中栏笆,Pod?是有生命周期的类腮,如果?Pod?重啟?IP?很有可能會(huì)發(fā)生變化。如果我們的服 務(wù)都是將?Pod?的?IP?地址寫(xiě)死竖伯,Pod?的掛掉或者重啟存哲,和剛才重啟的?pod?相關(guān)聯(lián)的其他服務(wù)將會(huì)找不到 它所關(guān)聯(lián)的?Pod,為了解決這個(gè)問(wèn)題七婴,在?kubernetes?中定義了?service?資源對(duì)象祟偷,Service?定義了一 個(gè)服務(wù)訪問(wèn)的入口,客戶端通過(guò)這個(gè)入口即可訪問(wèn)服務(wù)背后的應(yīng)用集群實(shí)例打厘,service?是一組?Pod?的邏 輯集合修肠,這一組?Pod?能夠被?Service?訪問(wèn)到,通常是通過(guò)?Label Selector?實(shí)現(xiàn)的户盯。
通過(guò)?Service?訪問(wèn)?k8s?內(nèi)部應(yīng)用的時(shí)候數(shù)據(jù)包走向是什么樣嵌施?
此時(shí)的數(shù)據(jù)包流向如下:
客戶端請(qǐng)求-->node?節(jié)點(diǎn)的?ip:端口--->service?的?ip:端口--->pod?的?ip:端口 案例演示:
cat pod_test.yaml
apiVersion: apps/v1
kind:? Deployment
metadata:
? name: my-nginx
spec:
? selector:
? ? matchLabels:
? ? ? run: my-nginx
? replicas: 2
? template:
? ? metadata:
? ? ? labels:
? ? ? ? run: my-nginx
? ? spec:
? ? ? containers:
? ? ? - image: nginx
? ? ? ? name: my-nginx
? ? ? ? ports:
? ? ? ? - containerPort: 80? #pod容器中暴露的端口
vim service.yaml
apiVersion: v1
kind: Service
metadata:
? name: my-nginx
? labels:
? ? run: my-nginx
spec:
? ports:
? - port: 80
? ? protocol: TCP
? selector:
? ? run: my-nginx
在?k8s?為什么要引入七層負(fù)載均衡?
端口管理問(wèn)題采用?service?的?NodePort?方式暴露服務(wù)面臨的問(wèn)題是饲化,服務(wù)一旦多起來(lái),NodePort?在每個(gè)節(jié)點(diǎn) 上開(kāi)啟的端口會(huì)及其龐大吗伤,而且難以維護(hù)吃靠。
四層負(fù)載均衡和七層負(fù)載均衡對(duì)比分析
1)四層的負(fù)載均衡就是基于?IP+端口的負(fù)載均衡:在三層負(fù)載均衡的基礎(chǔ)上,通過(guò)發(fā)布三層的?IP?地 址(VIP)足淆,然后加四層的端口號(hào)巢块,來(lái)決定哪些流量需要做負(fù)載均衡,對(duì)需要處理的流量進(jìn)行?NAT?處理巧号, 轉(zhuǎn)發(fā)至后臺(tái)服務(wù)器族奢,并記錄下這個(gè)?TCP?或者?UDP?的流量是由哪臺(tái)服務(wù)器處理的,后續(xù)這個(gè)連接的所有流 量都同樣轉(zhuǎn)發(fā)到同一臺(tái)服務(wù)器處理丹鸿。
2)七層的負(fù)載均衡就是基于虛擬的?URL?或主機(jī)?IP?的負(fù)載均衡:在四層負(fù)載均衡的基礎(chǔ)上(沒(méi)有四 層是絕對(duì)不可能有七層的)越走,再考慮應(yīng)用層的特征,比如同一個(gè)?Web?服務(wù)器的負(fù)載均衡靠欢,除了根據(jù)?VIP?加?80?端口辨別是否需要處理的流量廊敌,還可根據(jù)七層的?URL、瀏覽器類別掺涛、語(yǔ)言來(lái)決定是否要進(jìn)行負(fù)載均 衡庭敦。舉個(gè)例子,如果你的?Web?服務(wù)器分成兩組薪缆,一組是中文語(yǔ)言的秧廉,一組是英文語(yǔ)言的,那么七層負(fù)載 均衡就可以當(dāng)用戶來(lái)訪問(wèn)你的域名時(shí)拣帽,自動(dòng)辨別用戶語(yǔ)言疼电,然后選擇對(duì)應(yīng)的語(yǔ)言服務(wù)器組進(jìn)行負(fù)載均衡處 理。
?Ingress?和?Ingress Controller 解讀
Ingress?官網(wǎng)定義:Ingress?可以把進(jìn)入到集群內(nèi)部的請(qǐng)求轉(zhuǎn)發(fā)到集群中的一些服務(wù)上减拭,從而可以把 服務(wù)映射到集群外部蔽豺。Ingress?能把集群內(nèi)?Service?配置成外網(wǎng)能夠訪問(wèn)的?URL,流量負(fù)載均衡拧粪,提供 基于域名訪問(wèn)的虛擬主機(jī)等修陡。
Ingress?簡(jiǎn)單的理解就是你原來(lái)需要改?Nginx?配置,然后配置各種域名對(duì)應(yīng)哪個(gè)?Service可霎,現(xiàn)在把 這個(gè)動(dòng)作抽象出來(lái)魄鸦,變成一個(gè)?Ingress?對(duì)象,你可以用?yaml?創(chuàng)建癣朗,每次不要去改?Nginx?了拾因,直接改?yaml?然后創(chuàng)建/更新就行了;那么問(wèn)題來(lái)了:”Nginx?該怎么處理?”
Ingress Controller?這東西就是解決?“Nginx?的處理方式”?的;Ingress Controller?通過(guò)與?Kubernetes API?交互,動(dòng)態(tài)的去感知集群中?Ingress?規(guī)則變化,然后讀取他绢记,按照他自己模板生成一 段?Nginx?配置扁达,再寫(xiě)到?Ingress Controller Nginx?里,最后?reload?一下蠢熄,工作流程如下圖:
實(shí)際上?Ingress?也是?Kubernetes API?的標(biāo)準(zhǔn)資源類型之一跪解,它其實(shí)就是一組基于?DNS?名稱 (host)或?URL?路徑把請(qǐng)求轉(zhuǎn)發(fā)到指定的?Service?資源的規(guī)則。用于將集群外部的請(qǐng)求流量轉(zhuǎn)發(fā)到集群 內(nèi)部完成的服務(wù)發(fā)布签孔。我們需要明白的是惠遏,Ingress?資源自身不能進(jìn)行“流量穿透”,僅僅是一組規(guī)則的集 合骏啰,這些集合規(guī)則還需要其他功能的輔助,比如監(jiān)聽(tīng)某套接字抽高,然后根據(jù)這些規(guī)則的匹配進(jìn)行路由轉(zhuǎn)發(fā)判耕, 這些能夠?yàn)?Ingress?資源監(jiān)聽(tīng)套接字并將流量轉(zhuǎn)發(fā)的組件就是?Ingress Controller。
注:Ingress?控制器不同于?Deployment?控制器的是翘骂,Ingress?控制器不直接運(yùn)行為?kube- controller-manager?的一部分壁熄,它僅僅是?Kubernetes?集群的一個(gè)附件,類似于?CoreDNS碳竟,需要 在集群上單獨(dú)部署草丧。
Ingress Controller?介紹
Ingress Controller?是一個(gè)七層負(fù)載均衡調(diào)度器,客戶端的請(qǐng)求先到達(dá)這個(gè)七層負(fù)載均衡調(diào)度器莹桅,
由七層負(fù)載均衡器在反向代理到后端?pod昌执,常見(jiàn)的七層負(fù)載均衡器有?nginx、traefik诈泼,以我們熟悉的?nginx?為例懂拾,假如請(qǐng)求到達(dá)?nginx,會(huì)通過(guò)?upstream?反向代理到后端?pod?應(yīng)用铐达,但是后端?pod?的?ip?地址是一直在變化的岖赋,因此在后端?pod?前需要加一個(gè)?service,這個(gè)?service?只是起到分組的作用瓮孙,那 么我們?upstream?只需要填寫(xiě)?service?地址即可
Ingress?和?Ingress Controller?總結(jié)
Ingress Controller
Ingress Controller?
可以理解為控制器唐断,它通過(guò)不斷的跟?Kubernetes API?交互,實(shí)時(shí)獲取后端Service杭抠、Pod?的變化脸甘,比如新增、刪除等祈争,結(jié)合?Ingress?定義的規(guī)則生成配置斤程,然后動(dòng)態(tài)更新上邊的?Nginx?或者?trafik?負(fù)載均衡器,并刷新使配置生效,來(lái)達(dá)到服務(wù)自動(dòng)發(fā)現(xiàn)的作用忿墅。
Ingress?則是定義規(guī)則扁藕,通過(guò)它定義某個(gè)域名的請(qǐng)求過(guò)來(lái)之后轉(zhuǎn)發(fā)到集群中指定的?Service。它可 以通過(guò)?Yaml?文件定義疚脐,可以給一個(gè)或多個(gè)?Service?定義一個(gè)或多個(gè)?Ingress?規(guī)則亿柑。
使用?Ingress Controller?代理?k8s?內(nèi)部應(yīng)用的流程
(1)部署?Ingress controller,我們?ingress controller?使用的是?nginx
(2)創(chuàng)建?Pod?應(yīng)用棍弄,可以通過(guò)控制器創(chuàng)建?pod
(3)創(chuàng)建?Service望薄,用來(lái)分組?pod
(4)創(chuàng)建?Ingress http,測(cè)試通過(guò)?http?訪問(wèn)應(yīng)用
(5)創(chuàng)建?Ingress https呼畸,測(cè)試通過(guò)?https?訪問(wèn)應(yīng)用
客戶端通過(guò)七層調(diào)度器訪問(wèn)后端?pod?的方式
使用七層負(fù)載均衡調(diào)度器?
ingress controller?時(shí)痕支,當(dāng)客戶端訪問(wèn)?kubernetes?集群內(nèi)部的應(yīng)用時(shí), 數(shù)據(jù)包走向如下圖流程所示:
安裝?Nginx Ingress Controller
#把?defaultbackend.tar.gz?和?nginx-ingress-controller.tar.gz?鏡像上傳到工作節(jié)點(diǎn)
cat default-backend.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
? name: default-http-backend
? labels:
? ? k8s-app: default-http-backend
? namespace: kube-system
spec:
? replicas: 1
? selector:
? matchLabels:
? ? k8s-app: default-http-backend
? template:
? ? metadata:
? ? ? labels:
? ? ? ? k8s-app: default-http-backend
? ? spec:
? ? ? terminationGracePeriodSeconds: 60
? ? ? containers:
? ? ? - name: default-http-backend
? ? ? ? # Any image is permissable as long as:
? ? ? ? # 1. It serves a 404 page at /
? ? ? ? # 2. It serves 200 on a /healthz endpoint
? ? ? ? image: registry.cn-hangzhou.aliyuncs.com/hachikou/defaultbackend:1.0
? ? ? ? livenessProbe:
? ? ? ? ? httpGet:
? ? ? ? ? ? path: /healthz? #這個(gè)URI是 nginx-ingress-controller中nginx里配置好的localtion
? ? ? ? ? ? port: 8080
? ? ? ? ? ? scheme: HTTP
? ? ? ? ? initialDelaySeconds: 30? #30s檢測(cè)一次/healthz
? ? ? ? ? timeoutSeconds: 5
? ? ? ? ports:
? ? ? ? - containerPort: 8080
#? ? ? ? resources:
#? ? ? ? ? limits:
#? ? ? ? ? ? cpu: 10m
#? ? ? ? ? ? memory: 20Mi
#? ? ? ? ? requests:
#? ? ? ? ? ? cpu: 10m
#? ? ? ? ? ? memory: 20Mi
? ? ? nodeName: god62
---
apiVersion: v1
kind: Service? ? #為default backend 創(chuàng)建一個(gè)service
metadata:
? name: default-http-backend
? namespace: kube-system
? labels:
? ? k8s-app: default-http-backend
spec:
? ports:
? - port: 80
? ? targetPort: 8080
? selector:
? ? k8s-app: default-http-backend
cat nginx-ingress-controller.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
? name: nginx-ingress-controller
? labels:
? ? k8s-app: nginx-ingress-controller
? namespace: kube-system
spec:
? replicas: 1
? selector:
? ? matchLabels:
? ? ? k8s-app: nginx-ingress-controller
? template:
? ? metadata:
? ? ? labels:
? ? ? ? k8s-app: nginx-ingress-controller
? ? spec:
? ? ? # hostNetwork makes it possible to use ipv6 and to preserve the source IP correctly regardless of docker configuration
? ? ? # however, it is not a hard dependency of the nginx-ingress-controller itself and it may cause issues if port 10254 already is taken on the host
? ? ? # that said, since hostPort is broken on CNI (https://github.com/kubernetes/kubernetes/issues/31307) we have to use hostNetwork where CNI is used
? ? ? # like with kubeadm
? ? ? # hostNetwork: true #注釋表示不使用宿主機(jī)的80口蛮原,
? ? ? terminationGracePeriodSeconds: 60
? ? ? hostNetwork: true? #表示容器使用和宿主機(jī)一樣的網(wǎng)絡(luò)
? ? ? serviceAccountName: nginx-ingress-serviceaccount #引用前面創(chuàng)建的serviceacount
? ? ? containers:?
? ? ? - image: registry.cn-hangzhou.aliyuncs.com/peter1009/nginx-ingress-controller:0.20.0? ? ? #容器使用的鏡像
? ? ? ? name: nginx-ingress-controller? #容器名
? ? ? ? readinessProbe:? #啟動(dòng)這個(gè)服務(wù)時(shí)要驗(yàn)證/healthz 端口10254會(huì)在運(yùn)行的node上監(jiān)聽(tīng)卧须。
? ? ? ? ? httpGet: ? ? ? ? ? ? ? ? ?#就緒型探測(cè)
? ? ? ? ? ? path: /healthz
? ? ? ? ? ? port: 10254
? ? ? ? ? ? scheme: HTTP
? ? ? ? livenessProbe: ? ? ??#存活性探測(cè)
? ? ? ? ? httpGet:
? ? ? ? ? ? path: /healthz
? ? ? ? ? ? port: 10254
? ? ? ? ? ? scheme: HTTP
? ? ? ? ? initialDelaySeconds: 10? #每隔10做健康檢查
? ? ? ? ? timeoutSeconds: 1
? ? ? ? ports:
? ? ? ? - containerPort: 80?
? ? ? ? ? hostPort: 80? ? #80映射到80
#? ? ? ? - containerPort: 443
#? ? ? ? ? hostPort: 443
? ? ? ? env:
? ? ? ? ? - name: POD_NAME
? ? ? ? ? ? valueFrom:
? ? ? ? ? ? ? fieldRef:
? ? ? ? ? ? ? ? fieldPath: metadata.name
? ? ? ? ? - name: POD_NAMESPACE
? ? ? ? ? ? valueFrom:
? ? ? ? ? ? ? fieldRef:
? ? ? ? ? ? ? ? fieldPath: metadata.namespace
? ? ? ? args:
? ? ? ? - /nginx-ingress-controller
? ? ? ? - --default-backend-service=$(POD_NAMESPACE)/default-http-backend
#? ? ? ? - --default-ssl-certificate=$(POD_NAMESPACE)/ingress-secret? ? #這是啟用Https時(shí)用的
#? ? ? nodeSelector:? #指明運(yùn)行在哪,此IP要和default backend是同一個(gè)IP
#? ? ? ? kubernetes.io/hostname: 10.3.1.17? #上面映射到了hostport80儒陨,確保此IP80花嘶,443沒(méi)有占用.
#
? ? ? nodeName: god62
cat ??nginx-ingress-controller-rbac.yml
#apiVersion: v1
#kind: Namespace
#metadata:? #這里是創(chuàng)建一個(gè)namespace,因?yàn)榇薾amespace早有了就不用再創(chuàng)建了
#? name: kube-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
? name: nginx-ingress-serviceaccount #創(chuàng)建一個(gè)serveerAcount
? namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
? name: nginx-ingress-clusterrole? #這個(gè)ServiceAcount所綁定的集群角色
rules:
? - apiGroups:
? ? ? - ""
? ? resources:? ? #此集群角色的權(quán)限蹦漠,它能操作的API資源
? ? ? - configmaps
? ? ? - endpoints
? ? ? - nodes
? ? ? - pods
? ? ? - secrets
? ? verbs:
? ? ? - list
? ? ? - watch
? - apiGroups:
? ? ? - ""
? ? resources:
? ? ? - nodes
? ? verbs:
? ? ? - get
? - apiGroups:
? ? ? - ""
? ? resources:
? ? ? - services
? ? verbs:
? ? ? - get
? ? ? - list
? ? ? - watch
? - apiGroups:
? ? ? - "extensions"
? ? resources:
? ? ? - ingresses
? ? verbs:
? ? ? - get
? ? ? - list
? ? ? - watch
? - apiGroups:
? ? ? - ""
? ? resources:
? ? ? ? - events
? ? verbs:
? ? ? ? - create
#更新?yaml?文件椭员,
kubectl apply -f nginx-ingress-controller-rbac.yml
kubectl apply -f default-backend.yaml
kubectl apply -f nginx-ingress-controller.yaml
安裝?Ingress conrtroller?需要的?yaml?
所在的?github?地址:?https://github.com/kubernetes/ingress-nginx/
https://github.com/kubernetes/ingress/tree/master/examples/deployment
#查看是否部署成功
kubectl get pods -n kube-system | grep ingress
nginx-ingress-controller-657d9c6d5f-2qwzw 1/1 Running 0 4m30s
default-backend.yaml?和?nginx-ingress-controller.yaml?文件指定了?nodeName: god62,表示?default?和?nginx-ingress-controller?部署在 god62?節(jié)點(diǎn)笛园,大家的?node?節(jié)點(diǎn) 如果主機(jī)名不是 god62隘击,需要自行修改成自己的主機(jī)名,這樣才會(huì)調(diào)度成功研铆,一定要讓?default- http-backend?和?nginx-ingress-controller?這兩個(gè)?pod?在一個(gè)節(jié)點(diǎn)上闸度。
default-backend.yaml:這是官方要求必須要給的默認(rèn)后端,提供?404?頁(yè)面的蚜印。它還提供了一個(gè)?http?檢測(cè)功能莺禁,檢測(cè)?nginx-ingress-controll?健康狀態(tài)的,通過(guò)每隔一定時(shí)間訪問(wèn)?nginx-ingress- controll?的/healthz?頁(yè)面窄赋,如是沒(méi)有響應(yīng)就返回?404?之類的錯(cuò)誤碼哟冬。
測(cè)試?Ingress HTTP?代理?k8s?內(nèi)部站點(diǎn)
docker load -i tomcat-8-5.tar.gz
cat ingress-demo.yaml
apiVersion: v1
kind: Service
metadata:
? name: tomcat
? namespace: default
spec:
? selector:
? ? app: tomcat
? ? release: canary
? ports:
? - name: http
? ? port: 8080
? ? targetPort: 8080
? - name: ajp
? ? targetPort: 8009
? ? 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
? ? ? ? ports:
? ? ? ? - name: http
? ? ? ? ? containerPort: 8080
? ? ? ? ? name: ajp
? ? ? ? ? containerPort: 8009
#查看?pod?是否部署成功
kubectl get pods -l app=tomcat
kubectl get sac
#編寫(xiě)?ingress?的配置清單
vim ingress-myapp.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress? ? ? ? ? ? ? ? ? #清單類型
metadata:? ? ? ? ? ? ? ? ? ? ? #元數(shù)據(jù)
? name: ingress-myapp? ? ? ? #ingress的名稱
? namespace: ingress-myapp? #所屬名稱空間
? annotations:? ? #注解信息
? ? kubernetes.io/ingress.class: "nginx"
spec:? ? ? ? #規(guī)格
? rules:? ? #定義后端轉(zhuǎn)發(fā)的規(guī)則
? - host: tomcat.lucky.com? ? ? #通過(guò)域名進(jìn)行轉(zhuǎn)發(fā)
? ? http:
? ? ? paths:
? ? ? - path:? ? ? ? ? #配置訪問(wèn)路徑,如果通過(guò)url進(jìn)行轉(zhuǎn)發(fā)忆绰,需要修改浩峡,空默認(rèn)認(rèn)為訪問(wèn)的路徑為"/"
? ? ? ? backend:? ? ? ? #配置后端服務(wù)
? ? ? ? ? serviceName: tomcat
? ? ? ? ? servicePort: 8080
kubectl apply -f ingress-myapp.yaml
#查看?ingress-myapp?的詳細(xì)信息
kubectl describe ingress ingress-myappName: ingress-myapp
Namespace:? ? ? ? default
Address:? ? ? ? ?
Default backend:? default-http-backend:80 (10.244.187.70:8080)
Rules:
? Host? ? ? ? ? ? ? Path? Backends
? ----? ? ? ? ? ? ? ----? --------
? tomcat.lucky.com?
? ? ? ? ? ? ? ? ? ? ? tomcat:8080 (10.244.209.130:8080,10.244.209.131:8080)
Annotations:? ? ? ? kubernetes.io/ingress.class: nginx
Events:? ? ? ? ? ? <none>
#修改電腦本地的?host?文件,增加如下一行错敢,下面的?ip?是 god62?節(jié)點(diǎn)?ip 192.168.172.62 tomcat.lucky.com
瀏覽器訪問(wèn)?tomcat.lucky.com翰灾,出現(xiàn)tomcat首頁(yè)
測(cè)試?Ingress HTTPS?代理?tomcat
1缕粹、構(gòu)建?TLS?站點(diǎn)
1)準(zhǔn)備證書(shū),在 god63?節(jié)點(diǎn)操作
openssl genrsa -out tls.key 2048
openssl req -new -x509 -key tls.key -out tls.crt -subj /C=CN/ST=Beijing/L=Beijing/O=DevOps/CN=tomcat.lucky.com
(2)生成?secret纸淮,在 god63?節(jié)點(diǎn)操作
kubectl create secret tls tomcat-ingress-secret --cert=tls.crt -- key=tls.key
(3)查看?secret
kubectl get secret
NAME? ? ? ? ? ? ? ? ? ? TYPE? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? DATA? AGE
default-token-gp8bp? ? kubernetes.io/service-account-token? 3? ? ? 33d
tomcat-ingress-secret? kubernetes.io/tls? ? ? ? ? ? ? ? ? ? 2? ? ? 5s
(4)查看?tomcat-ingress-secret?詳細(xì)信息
kubectl describe secret tomcat-ingress-secret
Name:? ? ? ? tomcat-ingress-secret
Namespace:? ? default
Labels:? ? ? <none>
Annotations:? <none>
Type:? kubernetes.io/tls
Data
====
tls.key:? 1679 bytes
tls.crt:? 1294 bytes
2平斩、創(chuàng)建?Ingress
Ingress?規(guī)則可以參考官方:
https://kubernetes.io/zh/docs/concepts/services-networking/ingress/
kubectl explain?ingress.spec.rules.http.paths.backend.service
cat ingress-tomcat-tls.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
? name: ingress-tomcat-tls
? namespace: default
? annotations:
? ? kubernetes.io/ingress.class: "nginx"
spec:
? tls:
? - hosts:
? ? - tomcat.lucky.com
? ? secretName: tomcat-ingress-secret
? rules:
? - host: tomcat.lucky.com
? ? http:
? ? ? paths:
? ? ? - path: /
? ? ? ? pathType: Prefix
? ? ? ? backend:
? ? ? ? ? service:
? ? ? ? ? ? name: tomcat
? ? ? ? ? ? port:
? ? ? ? ? ? ? number: 8080
kubectl apply -f ingress-tomcat-tls.yaml
瀏覽器訪問(wèn)?https://tomcat.lucky.com
通過(guò)?Ingress-nginx?實(shí)現(xiàn)灰度發(fā)布
Ingress-Nginx?支持配置?Ingress Annotations?來(lái)實(shí)現(xiàn)不同場(chǎng)景下的灰度發(fā)布和測(cè)試。?Nginx
Annotations?支持以下幾種?Canary?規(guī)則:
假設(shè)我們現(xiàn)在部署了兩個(gè)版本的服務(wù)咽块,老版本和?canary?版本
nginx.ingress.kubernetes.io/canary-by-header:基于?Request Header?的流量切分绘面,適用于 灰度發(fā)布以及?A/B?測(cè)試。當(dāng)?Request Header?設(shè)置為?always?時(shí)侈沪,請(qǐng)求將會(huì)被一直發(fā)送到?Canary?版 本;當(dāng)?Request Header?設(shè)置為?never?時(shí)揭璃,請(qǐng)求不會(huì)被發(fā)送到?Canary?入口。
nginx.ingress.kubernetes.io/canary-by-header-value:要匹配的?Request Header?的值亭罪, 用于通知?Ingress?將請(qǐng)求路由到?Canary Ingress?中指定的服務(wù)瘦馍。當(dāng)?Request Header?設(shè)置為此值 時(shí),它將被路由到?Canary?入口应役。
nginx.ingress.kubernetes.io/canary-weight:基于服務(wù)權(quán)重的流量切分扣墩,適用于藍(lán)綠部署,權(quán) 重范圍?0 - 100?按百分比將請(qǐng)求路由到?Canary Ingress?中指定的服務(wù)扛吞。權(quán)重為?0?意味著該金絲雀規(guī) 則不會(huì)向?Canary?入口的服務(wù)發(fā)送任何請(qǐng)求。權(quán)重為?60?意味著?60%流量轉(zhuǎn)到?canary荆责。權(quán)重為?100?意 味著所有請(qǐng)求都將被發(fā)送到?Canary?入口滥比。
nginx.ingress.kubernetes.io/canary-by-cookie:基于?Cookie?的流量切分,適用于灰度發(fā)布 與?A/B?測(cè)試做院。用于通知?Ingress?將請(qǐng)求路由到?Canary Ingress?中指定的服務(wù)的?cookie盲泛。當(dāng)?cookie?值設(shè)置為?always?時(shí),它將被路由到?Canary?入口;當(dāng)?cookie?值設(shè)置為?never?時(shí)键耕,請(qǐng)求不會(huì) 被發(fā)送到?Canary?入口寺滚。
部署服務(wù):
我們服務(wù)的 deployment 就不展示了,service 配置如下:
#?測(cè)試版本
vim hello-service.yaml
apiVersion: v1
kind: Service
metadata:
? name: hello-service
? labels:
? ? app: hello-service
spec:
? ports:
? - port: 80
? ? protocol: TCP
? selector:
? ? app: hello-service
# canary?版本
vim canary-hello-service.yaml
apiVersion: v1
kind: Service
metadata:
? name: canary-hello-service
? labels:
? ? app: canary-hello-service
spec:
? ports:
? - port: 80
? ? protocol: TCP
? selector:
? ? app: canary-hello-service
根據(jù)權(quán)重轉(zhuǎn)發(fā):
ingress 配置如下:
vim ingress-weight.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
? name: canary
? annotations:
? ? kubernetes.io/ingress.class: nginx
? ? nginx.ingress.kubernetes.io/canary: "true"
? ? nginx.ingress.kubernetes.io/canary-weight: "30"
spec:
? rules:
? - host: canary-service.abc.com
? ? ? http:
? ? ? paths:
? ? ? - path: /
? ? ? ? pathType: Prefix
? ? ? ? backend:
? ? ? ? ? service:
? ? ? ? ? ? name: canary-hello-service
? ? ? ? ? ? port:
? ? ? ? ? ? ? number: 80
$ for i in $(seq 1 10); do curl http://canary-service.abc.com; echo '\n'; done
hello world-version1 hello world-version1 hello world-version2 hello world-version2 hello world-version1 hello world-version1 hello world-version1 hello world-version1 hello world-version1 hello world-version1
根據(jù)請(qǐng)求頭轉(zhuǎn)發(fā):
annotation?配置如下(ingress?其余部分省略)?annotations:
kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/canary: "true" nginx.ingress.kubernetes.io/canary-by-header: "test"
測(cè)試結(jié)果如下:
$ for i in $(seq 1 5); do curl -H 'test:always' http://canary-service.abc.com; echo '\n'; done
hello world-version1
hello world-version1
hello world-version1
hello world-version1
hello world-version1
$ for i in $(seq 1 5); do curl -H 'test:abc' http://canary-service.abc.com; echo '\n';
done
hello world-version2
hello world-version2 hello world-version2 hello world-version2 hello world-version2
根據(jù)?cookie?轉(zhuǎn)發(fā):
使用?cookie?來(lái)進(jìn)行流量管理的場(chǎng)景比較適合用于?A/B test屈雄,比如用戶的請(qǐng)求?cookie?中含有特殊的標(biāo)簽村视,那么我們可以把這部分用戶的請(qǐng)求轉(zhuǎn)發(fā)到特定的服務(wù)進(jìn)行處理。
annotation酒奶。配置如下
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/canary: "true"?
nginx.ingress.kubernetes.io/canary-by-cookie: "like_music"
測(cè)試結(jié)果如下:
$ for i in $(seq 1 5); do curl -b 'like_music=1' http://canary-service.abc.com; echo '\n'; done
hello world-version1
hello world-version1
hello world-version1
hello world-version1
hello world-version1
$ for i in $(seq 1 5); do curl -b 'like_music=always' http://canary-service.abc.com;
echo '\n'; done
hello world-version2
hello world-version2 hello world-version2 hello world-version2 hello world-version2
三種?annotation?按如下順序匹配
canary-by-header > canary-by-cookie > canary-weight