Ingress 實現(xiàn) k8s 七層調(diào)度和負載均衡

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,533評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,055評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,365評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,561評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,346評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,889評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,978評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,118評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,637評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,558評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,739評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,246評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 43,980評論 3 346
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,362評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,619評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,347評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,702評論 2 370

推薦閱讀更多精彩內(nèi)容