本篇內(nèi)容介紹了“如何在K8S集群中部署Traefik Ingress Controller”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
創(chuàng)新互聯(lián)專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都做網(wǎng)站、成都網(wǎng)站建設(shè)、神農(nóng)架林區(qū)網(wǎng)絡(luò)推廣、成都小程序開(kāi)發(fā)、神農(nóng)架林區(qū)網(wǎng)絡(luò)營(yíng)銷、神農(nóng)架林區(qū)企業(yè)策劃、神農(nóng)架林區(qū)品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營(yíng)等,從售前售中售后,我們都將竭誠(chéng)為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);創(chuàng)新互聯(lián)為所有大學(xué)生創(chuàng)業(yè)者提供神農(nóng)架林區(qū)建站搭建服務(wù),24小時(shí)服務(wù)熱線:18980820575,官方網(wǎng)址:www.cdcxhl.com
注:本文使用的Traefik為1.x的版本
在生產(chǎn)環(huán)境中,我們常常需要控制來(lái)自互聯(lián)網(wǎng)的外部進(jìn)入集群中,而這恰巧是Ingress的職責(zé)。
Ingress的主要目的是將HTTP和HTTPS從集群外部暴露給該集群中運(yùn)行的服務(wù)。這與Ingress控制如何將外部流量路由到集群有異曲同工之妙。接下來(lái),我們舉一個(gè)實(shí)際的例子來(lái)更清楚的說(shuō)明Ingress的概念。
首先,想象一下在你的Kubernetes集群中有若干個(gè)微服務(wù)(小型應(yīng)用程序之間彼此通信)。這些服務(wù)能夠在集群內(nèi)部被訪問(wèn),但我們想讓我們的用戶從集群外部也能夠訪問(wèn)它們。因此,我們需要做的是使用反向代理將每個(gè)HTTP(S)(例如,service.yourdomain.com
)路由與相應(yīng)的后端關(guān)聯(lián),并在該服務(wù)的不同實(shí)例之間(如,pod)進(jìn)行負(fù)載均衡。與此同時(shí),由于Kubernetes的性質(zhì)會(huì)不斷發(fā)生變化,因此我們希望跟蹤服務(wù)后端的更改,以便能夠在添加或刪除新Pod時(shí)將這些HTTP路由重新關(guān)聯(lián)到新Pod實(shí)例。
使用Ingress資源和關(guān)聯(lián)的Ingress Controller,你可以實(shí)現(xiàn)以下目標(biāo):
將你的域app.domain.com
指向你的私有網(wǎng)絡(luò)中的微服務(wù)應(yīng)用程序
將路徑domain.com/web
指向你的私有網(wǎng)絡(luò)中的微服務(wù)web
將你的域backend.domain.com
指向你的私有網(wǎng)絡(luò)中的微服務(wù)后端,并在該微服務(wù)的多個(gè)實(shí)例之間(Pod)進(jìn)行負(fù)載均衡
現(xiàn)在,你理解了Ingress的重要性。它能夠幫助將HTTP路由指向在Kubernetes集群中特定的微服務(wù)。
但是,流量路由并不是Ingress在Kubernetes中的唯一功能。例如,還可以將Ingress配置為負(fù)載均衡流量到你的應(yīng)用程序、終止SSL、執(zhí)行基于名稱的虛擬主機(jī)、在不同服務(wù)之間分配流量、設(shè)置服務(wù)訪問(wèn)規(guī)則等。
Kubernetes有一個(gè)特別的Ingress API資源,它能夠支持上述所有功能。但是,簡(jiǎn)單地創(chuàng)建一個(gè)Ingress API資源是沒(méi)有作用的。你還需要一個(gè)Ingress Controller。目前,Kubernetes支持許多Ingress controller,如Contour、HAProxy、NGINX以及Traefik。
在本文中,我將使用Traefik Ingress Controller創(chuàng)建Ingress。它能夠?qū)崿F(xiàn)現(xiàn)代HTTP反向代理和負(fù)載均衡器的功能,從而簡(jiǎn)化了微服務(wù)的部署。此外,Traefik對(duì)Docker、Marathon、Consul、Kubernetes、Amazon ECS等系統(tǒng)和環(huán)境都提供了強(qiáng)大的支持。
Traefik對(duì)于諸如Kubernetes之類的靈活性較強(qiáng)的系統(tǒng)十分有用。在Kubernetes中,每天需要多次添加、刪除或升級(jí)服務(wù),而Traefik可以監(jiān)聽(tīng)服務(wù)鏡像倉(cāng)庫(kù)/編排器 API并立即生成或更新路由,因此你的微服務(wù)無(wú)需手動(dòng)配置即可與外界連接。
除此之外,Traefik支持多個(gè)負(fù)載均衡算法、Let’s Encrypt的HTTPS(支持通配證書(shū))、斷路器、WebSoket、GRPC和多個(gè)監(jiān)控程序(Rest、Prometheus、Statsd、Datadog、InfluxDB等)。有關(guān)Traefik中可用功能的更多信息,請(qǐng)參考其官方文檔:
https://docs.traefik.cn/
在教程開(kāi)始之前,我們先來(lái)簡(jiǎn)單地討論一下Ingress資源是如何工作的。以下是隱式使用Nginx Ingress Controller的Ingress示例。
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: ingress-example annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - http: paths: - path: /microservice1 backend: serviceName: test servicePort: 80
以上Ingress manifest 包含了一系列HTTP規(guī)則,它們用于規(guī)定controller如何路由流量。
可選主機(jī)。如果未指定主機(jī)(如上所示),則該規(guī)則適用于通過(guò)指定IP地址的所有入站HTTP流量。如果提供了主機(jī)(如yourhost.com
),則該規(guī)則僅適用于該主機(jī)。
一個(gè)路徑列表(如,/microservice1
),它指向由serviceName
和servicePort
定義的關(guān)聯(lián)后端。
一個(gè)后端。向Ingress發(fā)出的HTTP(和HTTPS)請(qǐng)求將與給定規(guī)則的主機(jī)和路徑匹配,然后將其路由到該規(guī)則中指定的后端服務(wù)。
在以上例子中,我們配置了一個(gè)名為”test“的后端,它將接收所有來(lái)自/microservice
路徑的流量。然而,我們也可以配置一個(gè)默認(rèn)后端,它將將為任何不符合規(guī)范中路徑的用戶請(qǐng)求提供服務(wù)。同時(shí),如果不定義任何規(guī)則,Ingress將路由所有流量到默認(rèn)后端。例如:
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: test-ingress spec: backend: serviceName: defaultbackend servicePort: 80
在本例中,所有流量都被轉(zhuǎn)發(fā)到默認(rèn)后端中defaultbackend
。現(xiàn)在,我們理解了Ingress 資源的基本概念,接下來(lái)我們來(lái)看看一些具體的例子。
如上文我們所說(shuō)的,定義一個(gè)Ingress資源沒(méi)有任何作用,除非你使用了Ingress Controller。在本教程中,我們?cè)贙ubernetes集群中將Traefik設(shè)置為Ingress Controller。
要完成教程,你需要進(jìn)行以下準(zhǔn)備:
一個(gè)正在運(yùn)行的Kubernetes集群。
一個(gè)安裝好的命令行工具,kubectl。并配置為與集群通信。
請(qǐng)注意:以下示例均假設(shè)你在本地計(jì)算上使用Minikube運(yùn)行Kubernetes集群。
首先,我們需要向Traefik授予一些權(quán)限,以訪問(wèn)集群中運(yùn)行的Pod、endpoint和服務(wù)。為此,我們將使用ClusterRole
和ClusterRoleBinding
資源。但是,你也可以對(duì)命名空間范圍內(nèi)的RoleBindings
使用最小特權(quán)方法。通常,如果集群的命名空間不會(huì)動(dòng)態(tài)更改,并且Traefik無(wú)法監(jiān)視所有集群的命名空間,那么這是首選的方法。
讓我們創(chuàng)建一個(gè)新的ServiceAccount
,為Traefik提供集群中的身份。
apiVersion: v1 kind: ServiceAccount metadata: name: traefik-ingress namespace: kube-system
要?jiǎng)?chuàng)建一個(gè)ServiceAccount
,需要在traefik-service-acc.yaml
中保存以上manifest并運(yùn)行:
kubectl create -f traefik-service-acc.yaml serviceaccount "traefik-ingress" created
接下來(lái),讓我們創(chuàng)建一個(gè)具有一組權(quán)限的ClusterRole,該權(quán)限將應(yīng)用于Traefik ServiceAccount
。通過(guò)ClusterRole
,Traefik可以管理和監(jiān)視集群中所有命名空間中的資源,例如服務(wù)、endpoint、secret以及Ingress。
kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: name: traefik-ingress rules: - apiGroups: - "" resources: - services - endpoints - secrets verbs: - get - list - watch - apiGroups: - extensions resources: - ingresses verbs: - get - list - watch
將這一規(guī)范保存到文件traefik-cr.yaml
中,并運(yùn)行:
kubectl create -f traefik-cr.yaml clusterrole.rbac.authorization.k8s.io “traefik-ingress” created
最后,啟用這些權(quán)限,我們應(yīng)該將ClusterRole
綁定到Traefik ServiceAccount
中。使用ClusterRoleBinding
manifest可以完成這一操作:
kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: name: traefik-ingress roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: traefik-ingress subjects: - kind: ServiceAccount name: traefik-ingress namespace: kube-system
保存這一規(guī)范到traefik-crb.yaml
中,并運(yùn)行以下命令:
kubectl create -f traefik-crb.yaml clusterrolebinding.rbac.authorization.k8s.io “traefik-ingress” created
接下來(lái),我們將部署Traefik到Kubernetes集群。官方Traefik文檔支持三種類型的部署:使用Deployment對(duì)象、使用DaemonSet對(duì)象或使用Helm Chart。
在本教程中,我們將使用Deployment manifest。相比其他選項(xiàng),Deployment有諸多優(yōu)勢(shì)。例如,它們能確保更好的可伸縮性,并為滾動(dòng)更新提供良好支持。
讓我們看一下 Deployment manifest:
kind: Deployment apiVersion: extensions/v1beta1 metadata: name: traefik-ingress namespace: kube-system labels: k8s-app: traefik-ingress-lb spec: replicas: 1 selector: matchLabels: k8s-app: traefik-ingress-lb template: metadata: labels: k8s-app: traefik-ingress-lb name: traefik-ingress-lb spec: serviceAccountName: traefik-ingress terminationGracePeriodSeconds: 60 containers: - image: traefik name: traefik-ingress-lb ports: - name: http containerPort: 80 - name: admin containerPort: 8080 args: - --api - --kubernetes - --logLevel=INFO
這個(gè)Deployment將在kube-system 命名空間中創(chuàng)建一個(gè)Traefik副本。Traefik容器將使用此manifest中指定的端口80和8080。
將這個(gè)manifest保存到traefik-deployment.yaml
文件中,并運(yùn)行以下命令創(chuàng)建Deployment:
kubectl create -f traefik-deployment.yaml deployment.extensions “traefik-ingress” created
現(xiàn)在,讓我們檢查一下Traefik Pod是否都成功創(chuàng)建了:
kubectl --namespace=kube-system get pods NAME READY STATUS RESTARTS AGE .... storage-provisioner 1/1 Running 3 23d traefik-ingress-54d6d8d9cc-ls6cs 1/1 Running 0 1m
如你所見(jiàn),Deployment Controller啟動(dòng)了一個(gè)Traefik副本,并在正在運(yùn)行,敲棒的!
讓我們創(chuàng)建一個(gè)服務(wù)來(lái)從集群外部訪問(wèn)Traefik。為此,我們需要一個(gè)暴露兩個(gè)NodePorts的服務(wù)。
kind: Service apiVersion: v1 metadata: name: traefik-ingress-service namespace: kube-system spec: selector: k8s-app: traefik-ingress-lb ports: - protocol: TCP port: 80 name: web - protocol: TCP port: 8080 name: admin type: NodePort
將這個(gè)manifest保存到traefik-svc.yaml
,并創(chuàng)建服務(wù):
kubectl create -f traefik-svc.yaml service “traefik-ingress-service” created
現(xiàn)在,讓我們驗(yàn)證該服務(wù)是否創(chuàng)建:
kubectl describe svc traefik-ingress-service --namespace=kube-system Name: traefik-ingress-service Namespace: kube-system Labels:Annotations: Selector: k8s-app=traefik-ingress-lb Type: NodePort IP: 10.102.215.64 Port: web 80/TCP TargetPort: 80/TCP NodePort: web 30565/TCP Endpoints: 172.17.0.6:80 Port: admin 8080/TCP TargetPort: 8080/TCP NodePort: admin 30729/TCP Endpoints: 172.17.0.6:8080 Session Affinity: None External Traffic Policy: Cluster Events:
如你所見(jiàn),我們現(xiàn)在有兩個(gè)NodePorts(web
和admin
),它們分別路由到Traefik Ingress Controller的80和8080容器端口?!癮dmin” NodePort將用于訪問(wèn)Traefik Web UI,“web” NodePort將用于訪問(wèn)通過(guò)Ingress暴露的服務(wù)。
為了能在瀏覽器中訪問(wèn)Traefik Web UI,你可以使用“admin”NodePort 30729(請(qǐng)注意,你的NodePort值可能會(huì)有所不同)。因?yàn)槲覀冞€沒(méi)有添加任何前端,所以UI此時(shí)應(yīng)該是空的。
由于我們尚未給Traefik進(jìn)行任何配置,因此我們會(huì)收到404的響應(yīng)。
curl $(minikube ip):30565 404 page not found
現(xiàn)在我們?cè)贙ubernetes集群中已經(jīng)將Traefik作為Ingress Controller了。然而,我們依舊需要定義Ingress資源和暴露Traefik Web UI的服務(wù)。
首先,我們創(chuàng)建一個(gè)服務(wù):
apiVersion: v1 kind: Service metadata: name: traefik-web-ui namespace: kube-system spec: selector: k8s-app: traefik-ingress-lb ports: - name: web port: 80 targetPort: 8080
保存manifest到traefik-webui-svc.yaml
中,并運(yùn)行:
kubectl create -f traefik-webui-svc.yaml service “traefik-web-ui” created
讓我們驗(yàn)證服務(wù)是否已經(jīng)創(chuàng)建:
kubectl describe svc traefik-web-ui --namespace=kube-system Name: traefik-web-ui Namespace: kube-system Labels:Annotations: Selector: k8s-app=traefik-ingress-lb Type: ClusterIP IP: 10.98.230.58 Port: web 80/TCP TargetPort: 8080/TCP Endpoints: 172.17.0.6:8080 Session Affinity: None Events:
如你所見(jiàn),服務(wù)的ClusterIP是10.98.230.58
,并在manifest中分配指定端口。
接下來(lái),我們需要?jiǎng)?chuàng)建一個(gè)Ingress資源,指向Traefik Web UI后端:
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: traefik-web-ui namespace: kube-system spec: rules: - host: traefik-ui.minikube http: paths: - path: / backend: serviceName: traefik-web-ui servicePort: web
本質(zhì)上,Ingress將所有請(qǐng)求路由到traefik-ui.minikube
,在上述步驟中創(chuàng)建的服務(wù)暴露Traefik Web UI。
將規(guī)范保存到traefik-ingress.yaml
,并運(yùn)行:
kubectl create -f traefik-ingress.yaml ingress.extensions “traefik-web-ui” created
為了能夠通過(guò)traefik-ui.minikube
在瀏覽器中可以訪問(wèn)Traefik Web UI,我們需要添加新的條目到我們/etc/hosts
文件中。該條目將包含Minikube IP和主機(jī)名。你可以通過(guò)運(yùn)行minikube ip來(lái)獲取minkube實(shí)例的IP地址,然后將新主機(jī)的名稱保存到/etc/hosts
文件中,如下所示:
echo "$(minikube ip) traefik-ui.minikube" | sudo tee -a /etc/hosts 192.168.99.100 traefik-ui.minikube
現(xiàn)在,你應(yīng)該能夠在瀏覽器中訪問(wèn)http://traefik-ui.minikube:
并查看Traefik Web UI。別忘了附加”admin”NodePort到主機(jī)地址。
在dashboard中,你可以點(diǎn)擊Health 鏈接來(lái)查看應(yīng)用程序的健康狀況:
現(xiàn)在,我們來(lái)演示如何使用Traefik Ingress Controller為前端列表設(shè)置基于名稱的路由。我們將使用簡(jiǎn)單的單頁(yè)網(wǎng)站創(chuàng)建3個(gè)Deployment,并顯示動(dòng)物圖像:熊、野兔和駝鹿。
--- kind: Deployment apiVersion: extensions/v1beta1 metadata: name: bear labels: app: animals animal: bear spec: replicas: 2 selector: matchLabels: app: animals task: bear template: metadata: labels: app: animals task: bear version: v0.0.1 spec: containers: - name: bear image: supergiantkir/animals:bear ports: - containerPort: 80 --- kind: Deployment apiVersion: extensions/v1beta1 metadata: name: moose labels: app: animals animal: moose spec: replicas: 2 selector: matchLabels: app: animals task: moose template: metadata: labels: app: animals task: moose version: v0.0.1 spec: containers: - name: moose image: supergiantkir/animals:moose ports: - containerPort: 80 --- kind: Deployment apiVersion: extensions/v1beta1 metadata: name: hare labels: app: animals animal: hare spec: replicas: 2 selector: matchLabels: app: animals task: hare template: metadata: labels: app: animals task: hare version: v0.0.1 spec: containers: - name: hare image: supergiantkir/animals:hare ports: - containerPort: 80
每個(gè)Deployment都將有兩個(gè)Pod副本,而每個(gè)Pod將在containerPort
80上服務(wù)“動(dòng)物“網(wǎng)站。
讓我們保存這些Deployment manifest到animals-deployment.yaml
中,并運(yùn)行:
kubectl create -f animals-deployment.yaml deployment.extensions “bear” created deployment.extensions “moose” created deployment.extensions “hare” created
現(xiàn)在,讓我們?yōu)槊總€(gè)Deployment創(chuàng)建一個(gè)服務(wù),使得Pod可以訪問(wèn):
--- apiVersion: v1 kind: Service metadata: name: bear spec: ports: - name: http targetPort: 80 port: 80 selector: app: animals task: bear --- apiVersion: v1 kind: Service metadata: name: moose spec: ports: - name: http targetPort: 80 port: 80 selector: app: animals task: moose --- apiVersion: v1 kind: Service metadata: name: hare annotations: traefik.backend.circuitbreaker: "NetworkErrorRatio() > 0.5" spec: ports: - name: http targetPort: 80 port: 80 selector: app: animals task: hare
請(qǐng)注意:第三項(xiàng)服務(wù)使用斷路器annotation。斷路器是Traefik的一項(xiàng)功能,可防止發(fā)生故障的服務(wù)器承受高負(fù)載。在本例中,我們防止服務(wù)器上的高負(fù)載超過(guò)50%。當(dāng)此條件匹配時(shí),CB進(jìn)入“跳閘“狀態(tài),在該狀態(tài)中它會(huì)使用預(yù)定義的HTTP狀態(tài)代碼進(jìn)行響應(yīng)或重定向到另一個(gè)前端。
保存這些服務(wù)manifest到animals-svc.yaml
并運(yùn)行:
kubectl create -f animals-svc.yaml service “bear” created service “moose” created service “hare” created
最后,為每個(gè)Deployment創(chuàng)建一個(gè)有3個(gè)前后端對(duì)的Ingress。bear.minikube
、moose.minikube
和hare.minikube
將是我們指向相應(yīng)后端服務(wù)的前端。
Ingress manifest如下所示:
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: animals annotations: kubernetes.io/ingress.class: traefik spec: rules: - host: hare.minikube http: paths: - path: / backend: serviceName: hare servicePort: http - host: bear.minikube http: paths: - path: / backend: serviceName: bear servicePort: http - host: moose.minikube http: paths: - path: / backend: serviceName: moose servicePort: http
保存規(guī)范到animals-ingress.yaml
并運(yùn)行:
kubectl create -f animals-ingress.yaml ingress.extensions “animals” created
現(xiàn)在,在Traefik dashboard內(nèi),你可以看到每個(gè)主機(jī)的前端以及相應(yīng)的后端列表:
如果你再次編輯etc/hosts
,你應(yīng)該能夠在你的瀏覽器中訪問(wèn)動(dòng)物網(wǎng)頁(yè):
echo “$(minikube ip) bear.minikube hare.minikube moose.minikube” | sudo tee -a /etc/hosts
你應(yīng)該使用“web“NodePort來(lái)訪問(wèn)特定網(wǎng)頁(yè)。例如,http://bear.minikube:
我們也可以將三個(gè)前端重新配置為在一個(gè)域下提供服務(wù),如下所示:
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: all-animals annotations: kubernetes.io/ingress.class: traefik traefik.frontend.rule.type: PathPrefixStrip spec: rules: - host: animals.minikube http: paths: - path: /bear backend: serviceName: bear servicePort: http - path: /moose backend: serviceName: moose servicePort: http - path: /hare backend: serviceName: hare servicePort: http
如果你激活這個(gè)Ingress,使用相應(yīng)的路徑,三個(gè)動(dòng)物在一個(gè)域下都能夠訪問(wèn)——animals.minikube
。別忘了將這個(gè)域添加到/etc/hosts
。
echo “$(minikube ip) animals.minikube” | sudo tee -a /etc/hosts
請(qǐng)注意:我們正在配置Traefik,以使用traefik.frontend.rule.type
注釋,從URL路徑中刪除前綴。這樣我們可以直接使用上一個(gè)示例中的容器。由于traefik.frontend.rule.type: PathPrefixStrip
規(guī)則,你必須使用http://animals.minikube:32484/moose/
而不是http://animals.minikube:32484/moose
借助Traefik,用戶可以使用服務(wù)權(quán)重以受控方式在多個(gè)deployment之間分配Ingress流量。這一功能可用于金絲雀發(fā)布,它最初應(yīng)該獲得少量但持續(xù)增長(zhǎng)的流量。
讓我們使用以下manifest在兩個(gè)微服務(wù)之間分配Traefik:
apiVersion: extensions/v1beta1 kind: Ingress metadata: annotations: traefik.ingress.kubernetes.io/service-weights: | animals-app: 99% animals-app-canary: 1% name: animals-app spec: rules: - http: paths: - backend: serviceName: animals-app servicePort: 80 path: / - backend: serviceName: animals-app-canary servicePort: 80 path: /
請(qǐng)注意traefik.ingress.kubernetes.io/service-weights
的注釋。它指定了流量如何在指定后端服務(wù)(animals-app
和animals-app-canary
)之間分配。Traefik將把99%的用戶請(qǐng)求路由到animals-app
deployment支持的Pod,并將1%的用戶請(qǐng)求路由到animals-app-canary
deployment支持的Pod。
要使此設(shè)置正常工作,需要滿足一些條件:
所有服務(wù)后端必須共享相同的路徑和主機(jī)。
跨服務(wù)后端共享的請(qǐng)求總數(shù)應(yīng)總計(jì)為100%。
百分比值應(yīng)該在支持的精度范圍內(nèi),目前Traefik支持3個(gè)小數(shù)位的權(quán)重。
“如何在K8S集群中部署Traefik Ingress Controller”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!