kubectl get all -A ? 查看全部名稱空間的pod,找控制器下的pod
負載均衡是什么?
負載均衡是由多臺服務(wù)器以對稱的方式組成一個服務(wù)器集合,每臺服務(wù)器都具有等價的地位,都可以 單獨對外提供服務(wù)而無需其他服務(wù)器的輔助。通過某種負載分擔(dān)技術(shù),將外部發(fā)送來的請求按照某種策略 分配到服務(wù)器集合的某一臺服務(wù)器上,而接收到請求的服務(wù)器獨立地回應(yīng)客戶的請求。負載均衡解決了大 量并發(fā)訪問服務(wù)問題,其目的就是用最少的投資獲得接近于大型主機的性能。
四層負載均衡:lvs(軟件層面)、f5(硬件層面)
缺點:對網(wǎng)絡(luò)依賴較大,負載智能化方面沒有?7?層負載好(比如不支持對?url?個性化負載),F(xiàn)5?硬件 性能很高但成本也高,需要人民幣幾十萬,對于小公司就望而卻步了。
常見的七層負載均衡:nginx、apache
優(yōu)點:對網(wǎng)絡(luò)依賴少,負載智能方案多(比如可根據(jù)不同的?url?進行負載)
在?k8s?中為什么要做負載均衡?
Pod?漂移問題
Kubernetes?具有強大的副本控制能力,能保證在任意副本(Pod)掛掉時自動從其他機器啟動一個新的,還可以動態(tài)擴容等。通俗地說,這個?Pod?可能在任何時刻出現(xiàn)在任何節(jié)點上,也可能在任何時刻 死在任何節(jié)點上;那么自然隨著?Pod?的創(chuàng)建和銷毀,Pod IP?肯定會動態(tài)變化;那么如何把這個動態(tài)的?Pod IP?暴露出去?這里借助于?Kubernetes?的?Service?機制,Service?可以以標簽的形式選定一組帶 有指定標簽的?Pod,并監(jiān)控和自動負載他們的?Pod IP,那么我們向外暴露只暴露?Service IP?就行了;這 就是?NodePort?模式:即在每個節(jié)點上開起一個端口,然后轉(zhuǎn)發(fā)到內(nèi)部?Pod IP?上。
使用?service?做四層負載均衡
在?kubernetes?中,Pod?是有生命周期的,如果?Pod?重啟?IP?很有可能會發(fā)生變化。如果我們的服 務(wù)都是將?Pod?的?IP?地址寫死,Pod?的掛掉或者重啟,和剛才重啟的?pod?相關(guān)聯(lián)的其他服務(wù)將會找不到 它所關(guān)聯(lián)的?Pod,為了解決這個問題,在?kubernetes?中定義了?service?資源對象,Service?定義了一 個服務(wù)訪問的入口,客戶端通過這個入口即可訪問服務(wù)背后的應(yīng)用集群實例,service?是一組?Pod?的邏 輯集合,這一組?Pod?能夠被?Service?訪問到,通常是通過?Label Selector?實現(xiàn)的。
通過?Service?訪問?k8s?內(nèi)部應(yīng)用的時候數(shù)據(jù)包走向是什么樣?
此時的數(shù)據(jù)包流向如下:
客戶端請求-->node?節(jié)點的?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?為什么要引入七層負載均衡?
端口管理問題采用?service?的?NodePort?方式暴露服務(wù)面臨的問題是,服務(wù)一旦多起來,NodePort?在每個節(jié)點 上開啟的端口會及其龐大,而且難以維護。
四層負載均衡和七層負載均衡對比分析
1)四層的負載均衡就是基于?IP+端口的負載均衡:在三層負載均衡的基礎(chǔ)上,通過發(fā)布三層的?IP?地 址(VIP),然后加四層的端口號,來決定哪些流量需要做負載均衡,對需要處理的流量進行?NAT?處理, 轉(zhuǎn)發(fā)至后臺服務(wù)器,并記錄下這個?TCP?或者?UDP?的流量是由哪臺服務(wù)器處理的,后續(xù)這個連接的所有流 量都同樣轉(zhuǎn)發(fā)到同一臺服務(wù)器處理。
2)七層的負載均衡就是基于虛擬的?URL?或主機?IP?的負載均衡:在四層負載均衡的基礎(chǔ)上(沒有四 層是絕對不可能有七層的),再考慮應(yīng)用層的特征,比如同一個?Web?服務(wù)器的負載均衡,除了根據(jù)?VIP?加?80?端口辨別是否需要處理的流量,還可根據(jù)七層的?URL、瀏覽器類別、語言來決定是否要進行負載均 衡。舉個例子,如果你的?Web?服務(wù)器分成兩組,一組是中文語言的,一組是英文語言的,那么七層負載 均衡就可以當用戶來訪問你的域名時,自動辨別用戶語言,然后選擇對應(yīng)的語言服務(wù)器組進行負載均衡處 理。
?Ingress?和?Ingress Controller 解讀
Ingress?官網(wǎng)定義:Ingress?可以把進入到集群內(nèi)部的請求轉(zhuǎn)發(fā)到集群中的一些服務(wù)上,從而可以把 服務(wù)映射到集群外部。Ingress?能把集群內(nèi)?Service?配置成外網(wǎng)能夠訪問的?URL,流量負載均衡,提供 基于域名訪問的虛擬主機等。
Ingress?簡單的理解就是你原來需要改?Nginx?配置,然后配置各種域名對應(yīng)哪個?Service,現(xiàn)在把 這個動作抽象出來,變成一個?Ingress?對象,你可以用?yaml?創(chuàng)建,每次不要去改?Nginx?了,直接改?yaml?然后創(chuàng)建/更新就行了;那么問題來了:”Nginx?該怎么處理?”
Ingress Controller?這東西就是解決?“Nginx?的處理方式”?的;Ingress Controller?通過與?Kubernetes API?交互,動態(tài)的去感知集群中?Ingress?規(guī)則變化,然后讀取他,按照他自己模板生成一 段?Nginx?配置,再寫到?Ingress Controller Nginx?里,最后?reload?一下,工作流程如下圖:
實際上?Ingress?也是?Kubernetes API?的標準資源類型之一,它其實就是一組基于?DNS?名稱 (host)或?URL?路徑把請求轉(zhuǎn)發(fā)到指定的?Service?資源的規(guī)則。用于將集群外部的請求流量轉(zhuǎn)發(fā)到集群 內(nèi)部完成的服務(wù)發(fā)布。我們需要明白的是,Ingress?資源自身不能進行“流量穿透”,僅僅是一組規(guī)則的集 合,這些集合規(guī)則還需要其他功能的輔助,比如監(jiān)聽某套接字,然后根據(jù)這些規(guī)則的匹配進行路由轉(zhuǎn)發(fā), 這些能夠為?Ingress?資源監(jiān)聽套接字并將流量轉(zhuǎn)發(fā)的組件就是?Ingress Controller。
注:Ingress?控制器不同于?Deployment?控制器的是,Ingress?控制器不直接運行為?kube- controller-manager?的一部分,它僅僅是?Kubernetes?集群的一個附件,類似于?CoreDNS,需要 在集群上單獨部署。
Ingress Controller?介紹
Ingress Controller?是一個七層負載均衡調(diào)度器,客戶端的請求先到達這個七層負載均衡調(diào)度器,
由七層負載均衡器在反向代理到后端?pod,常見的七層負載均衡器有?nginx、traefik,以我們熟悉的?nginx?為例,假如請求到達?nginx,會通過?upstream?反向代理到后端?pod?應(yīng)用,但是后端?pod?的?ip?地址是一直在變化的,因此在后端?pod?前需要加一個?service,這個?service?只是起到分組的作用,那 么我們?upstream?只需要填寫?service?地址即可
Ingress?和?Ingress Controller?總結(jié)
Ingress Controller
Ingress Controller?
可以理解為控制器,它通過不斷的跟?Kubernetes API?交互,實時獲取后端Service、Pod?的變化,比如新增、刪除等,結(jié)合?Ingress?定義的規(guī)則生成配置,然后動態(tài)更新上邊的?Nginx?或者?trafik?負載均衡器,并刷新使配置生效,來達到服務(wù)自動發(fā)現(xiàn)的作用。
Ingress?則是定義規(guī)則,通過它定義某個域名的請求過來之后轉(zhuǎn)發(fā)到集群中指定的?Service。它可 以通過?Yaml?文件定義,可以給一個或多個?Service?定義一個或多個?Ingress?規(guī)則。
使用?Ingress Controller?代理?k8s?內(nèi)部應(yīng)用的流程
(1)部署?Ingress controller,我們?ingress controller?使用的是?nginx
(2)創(chuàng)建?Pod?應(yīng)用,可以通過控制器創(chuàng)建?pod
(3)創(chuàng)建?Service,用來分組?pod
(4)創(chuàng)建?Ingress http,測試通過?http?訪問應(yīng)用
(5)創(chuàng)建?Ingress https,測試通過?https?訪問應(yīng)用
客戶端通過七層調(diào)度器訪問后端?pod?的方式
使用七層負載均衡調(diào)度器?
ingress controller?時,當客戶端訪問?kubernetes?集群內(nèi)部的應(yīng)用時, 數(shù)據(jù)包走向如下圖流程所示:
安裝?Nginx Ingress Controller
#把?defaultbackend.tar.gz?和?nginx-ingress-controller.tar.gz?鏡像上傳到工作節(jié)點
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? #這個URI是 nginx-ingress-controller中nginx里配置好的localtion
? ? ? ? ? ? port: 8080
? ? ? ? ? ? scheme: HTTP
? ? ? ? ? initialDelaySeconds: 30? #30s檢測一次/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)建一個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 #注釋表示不使用宿主機的80口,
? ? ? terminationGracePeriodSeconds: 60
? ? ? hostNetwork: true? #表示容器使用和宿主機一樣的網(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:? #啟動這個服務(wù)時要驗證/healthz 端口10254會在運行的node上監(jiān)聽。
? ? ? ? ? httpGet: ? ? ? ? ? ? ? ? ?#就緒型探測
? ? ? ? ? ? path: /healthz
? ? ? ? ? ? port: 10254
? ? ? ? ? ? scheme: HTTP
? ? ? ? livenessProbe: ? ? ??#存活性探測
? ? ? ? ? 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時用的
#? ? ? nodeSelector:? #指明運行在哪,此IP要和default backend是同一個IP
#? ? ? ? kubernetes.io/hostname: 10.3.1.17? #上面映射到了hostport80,確保此IP80,443沒有占用.
#
? ? ? nodeName: god62
cat ??nginx-ingress-controller-rbac.yml
#apiVersion: v1
#kind: Namespace
#metadata:? #這里是創(chuàng)建一個namespace,因為此namespace早有了就不用再創(chuàng)建了
#? name: kube-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
? name: nginx-ingress-serviceaccount #創(chuàng)建一個serveerAcount
? namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
? name: nginx-ingress-clusterrole? #這個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é)點,大家的?node?節(jié)點 如果主機名不是 god62,需要自行修改成自己的主機名,這樣才會調(diào)度成功,一定要讓?default- http-backend?和?nginx-ingress-controller?這兩個?pod?在一個節(jié)點上。
default-backend.yaml:這是官方要求必須要給的默認后端,提供?404?頁面的。它還提供了一個?http?檢測功能,檢測?nginx-ingress-controll?健康狀態(tài)的,通過每隔一定時間訪問?nginx-ingress- controll?的/healthz?頁面,如是沒有響應(yīng)就返回?404?之類的錯誤碼。
測試?Ingress HTTP?代理?k8s?內(nèi)部站點
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
#編寫?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? ? ? #通過域名進行轉(zhuǎn)發(fā)
? ? http:
? ? ? paths:
? ? ? - path:? ? ? ? ? #配置訪問路徑,如果通過url進行轉(zhuǎn)發(fā),需要修改,空默認認為訪問的路徑為"/"
? ? ? ? backend:? ? ? ? #配置后端服務(wù)
? ? ? ? ? serviceName: tomcat
? ? ? ? ? servicePort: 8080
kubectl apply -f ingress-myapp.yaml
#查看?ingress-myapp?的詳細信息
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é)點?ip 192.168.172.62 tomcat.lucky.com
瀏覽器訪問?tomcat.lucky.com,出現(xiàn)tomcat首頁
測試?Ingress HTTPS?代理?tomcat
1、構(gòu)建?TLS?站點
1)準備證書,在 god63?節(jié)點操作
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é)點操作
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?詳細信息
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
瀏覽器訪問?https://tomcat.lucky.com
通過?Ingress-nginx?實現(xiàn)灰度發(fā)布
Ingress-Nginx?支持配置?Ingress Annotations?來實現(xiàn)不同場景下的灰度發(fā)布和測試。?Nginx
Annotations?支持以下幾種?Canary?規(guī)則:
假設(shè)我們現(xiàn)在部署了兩個版本的服務(wù),老版本和?canary?版本
nginx.ingress.kubernetes.io/canary-by-header:基于?Request Header?的流量切分,適用于 灰度發(fā)布以及?A/B?測試。當?Request Header?設(shè)置為?always?時,請求將會被一直發(fā)送到?Canary?版 本;當?Request Header?設(shè)置為?never?時,請求不會被發(fā)送到?Canary?入口。
nginx.ingress.kubernetes.io/canary-by-header-value:要匹配的?Request Header?的值, 用于通知?Ingress?將請求路由到?Canary Ingress?中指定的服務(wù)。當?Request Header?設(shè)置為此值 時,它將被路由到?Canary?入口。
nginx.ingress.kubernetes.io/canary-weight:基于服務(wù)權(quán)重的流量切分,適用于藍綠部署,權(quán) 重范圍?0 - 100?按百分比將請求路由到?Canary Ingress?中指定的服務(wù)。權(quán)重為?0?意味著該金絲雀規(guī) 則不會向?Canary?入口的服務(wù)發(fā)送任何請求。權(quán)重為?60?意味著?60%流量轉(zhuǎn)到?canary。權(quán)重為?100?意 味著所有請求都將被發(fā)送到?Canary?入口。
nginx.ingress.kubernetes.io/canary-by-cookie:基于?Cookie?的流量切分,適用于灰度發(fā)布 與?A/B?測試。用于通知?Ingress?將請求路由到?Canary Ingress?中指定的服務(wù)的?cookie。當?cookie?值設(shè)置為?always?時,它將被路由到?Canary?入口;當?cookie?值設(shè)置為?never?時,請求不會 被發(fā)送到?Canary?入口。
部署服務(wù):
我們服務(wù)的 deployment 就不展示了,service 配置如下:
#?測試版本
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ù)請求頭轉(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"
測試結(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?來進行流量管理的場景比較適合用于?A/B test,比如用戶的請求?cookie?中含有特殊的標簽,那么我們可以把這部分用戶的請求轉(zhuǎn)發(fā)到特定的服務(wù)進行處理。
annotation。配置如下
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/canary: "true"?
nginx.ingress.kubernetes.io/canary-by-cookie: "like_music"
測試結(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