使用 Traefik 引導 Kubernetes 流量
將流量引入 Kubernetes 樹莓派集群的分步指南。
-- Lee Carpenter
在本文中,我們將部署幾個簡單的網站,並學習如何使用 Traefik 將來自外部世界的流量引入到我們的集群中。之後,我們還將學習如何刪除 Kubernetes 資源。讓我們開始吧!
準備
要繼續閱讀本文,你只需要我們在上一篇文章中構建的k3s 樹莓派集群。由於你的集群將從網路上拉取鏡像,因此該集群需要能夠訪問互聯網。
出於解釋目的,本文將顯示一些配置文件和示例 HTML 文件。所有示例文件都可以在此處下載。
部署一個簡單的網站
之前,我們使用kubectl進行了直接部署。但是,這不是典型的部署方法。一般情況都會使用 YAML 配置文件,這也是我們要在本文中使用的配置文件。我們將從頂部開始,並以自頂向下的方式創建該配置文件。
部署配置
首先是部署配置。配置如下所示,並在下面進行說明。我通常以Kubernetes 文檔中的示例為起點,然後根據需要對其進行修改。例如,下面的配置是複製了部署文檔中的示例後修改的。
創建一個文件mysite.yaml,其內容如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysite-nginx
labels:
app: mysite-nginx
spec:
replicas: 1
selector:
matchLabels:
app: mysite-nginx
template:
metadata:
labels:
app: mysite-nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
其中大部分是樣板。重要的部分,我們會將該部署命名為mysite-nginx,並為其加上同名的app標籤。我們指定了一個副本(replica),這意味著將只創建一個 Pod。我們還指定了一個容器,我們將其命名為nginx。我們將鏡像(image)指定為nginx。這意味著在部署時,k3s 將從 DockerHub 下載nginx鏡像並從中創建一個 Pod。最後,我們指定了容器埠(containerPort)為80,這隻意味著在容器內部 Pod 會監聽80埠。
我在上面強調了「在容器內部」,因為這是一個重要的區別。由於我們是按容器配置的,因此只能在容器內部訪問它,並且進一步將其限制為內部網路。這對於允許多個容器在同一容器埠上監聽所是必要的。換句話說,通過這種配置,其他一些 Pod 也可以在其容器埠 80 上偵聽,並且不會與此容器衝突。為了提供對該 Pod 的正式訪問許可權,我們需要一個服務(service)配置。
服務配置
在 Kubernetes 中,服務(service)是一種抽象。它提供了一種訪問 Pod 或 Pod 集合的方法。當連接到服務時,服務會路由到單個 Pod,或者如果定義了多個 Pod 副本,會通過負載均衡路由到多個 Pod。
可以在同一配置文件中指定該服務,這就是我們將在此處要做的。用---分隔配置區域,將以下內容添加到mysite.yaml中:
---
apiVersion: v1
kind: Service
metadata:
name: mysite-nginx-service
spec:
selector:
app: mysite-nginx
ports:
- protocol: TCP
port: 80
在此配置中,我們將服務命名為mysite-nginx-service。我們提供了一個選擇器(selector):app: mysite-nginx。這是服務選擇其路由到的應用程序容器的方式。請記住,我們為容器提供了app標籤:mysite-nginx。這就是服務用來查找我們的容器的方式。最後,我們指定服務協議為TCP,在埠80上監聽。
入口配置
入口(Ingress)配置指定了如何將流量從集群外部傳遞到集群內部的服務。請記住,k3s 預先配置了 Traefik 作為入口控制器。因此,我們將編寫特定於 Traefik 的入口配置。將以下內容添加到mysite.yaml中(不要忘了用---分隔):
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: mysite-nginx-ingress
annotations:
kubernetes.io/ingress.class: "traefik"
spec:
rules:
- http:
paths:
- path: /
backend:
serviceName: mysite-nginx-service
servicePort: 80
在此配置中,我們將入口記錄命名為mysite-nginx-ingress。我們告訴 Kubernetes,我們希望traefik成為我們的入口控制器,再加上kubernetes.io/ingress.class的註解。
在規則(rules)部分中,我們基本上是說,當http流量進入時,並且path匹配/(或其下的任何內容),將其路由到由serviceName mysite-nginx-service指定的後端(backend)服務中,並將其路由到servicePort 80。這會將傳入的 HTTP 流量連接到我們之前定義的服務。
需要部署的東西
就配置而言,就是這樣了。如果我們現在部署,我們將獲得默認的 nginx 頁面,但這不是我們想要的。讓我們創建一些簡單但可自定義的部署方式。創建具有以下內容的文件index.html:
html {
font-size: 62.5%;
}
body {
font-family: sans-serif;
background-color: midnightblue;
color: white;
display: flex;
flex-direction: column;
justify-content: center;
height: 100vh;
}
div {
text-align: center;
font-size: 8rem;
text-shadow: 3px 3px 4px dimgrey;
}
Hello from K3S!
我們尚未介紹 Kubernetes 中的存儲機制,因此在這裡我們偷懶一下,僅將該文件存儲在 Kubernetes 配置映射中。這不是我們推薦的部署網站的方式,但對於我們的目的來說是可行的。運行以下命令:
kubectl create configmap mysite-html --from-file index.html
該命令從本地文件index.html創建名為mysite-html的配置映射(configmap)資源。這實際上是在 Kubernetes 資源中存儲一個文件(或一組文件),我們可以在配置中調出該文件。它通常用於存儲配置文件(因此而得名),我們在這裡稍加濫用。在以後的文章中,我們將討論 Kubernetes 中適當的存儲解決方案。
創建配置映射後,讓我們將其掛載在我們的nginx容器中。我們分兩個步驟進行。首先,我們需要指定一個卷(volume)來調出配置映射。然後我們需要將該卷掛載到nginx容器中。通過在mysite.yaml中的container後面的spec標籤下添加以下內容來完成第一步:
? ? volumes:
? ? - name: html-volume
? ? ? configMap:
? ? ? ? name: mysite-html
這告訴 Kubernetes 我們要定義一個名為html-volume的卷,並且該卷應包含名為html-volume(我們在上一步中創建的)的配置映射的內容。
接下來,在nginx容器規範中的埠(ports)下方,添加以下內容:
? ? ? volumeMounts:
? ? ? - name: html-volume
? ? ? ? mountPath: /usr/share/nginx/html
這告訴 Kubernetes,對於nginx容器,我們想在容器中的/usr/share/nginx/html路徑上掛載名為html-volume的卷。 為什麼要使用/usr/share/nginx/html?那個位置就是nginx鏡像提供 HTML 服務的地方。通過在該路徑上掛載卷,我們用該卷內容替換了默認內容。
作為參考,配置文件的deployment部分現在應如下所示:
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysite-nginx
labels:
? app: mysite-nginx
spec:
replicas: 1
selector:
? matchLabels:
? ? app: mysite-nginx
template:
? metadata:
? ? labels:
? ? ? app: mysite-nginx
? spec:
? ? containers:
? ? - name: nginx
? ? ? image: nginx
? ? ? ports:
? ? ? - containerPort: 80
? ? ? volumeMounts:
? ? ? - name: html-volume
? ? ? ? mountPath: /usr/share/nginx/html
? ? volumes:
? ? - name: html-volume
? ? ? configMap:
? ? ? ? name: mysite-html
部署它!
現在我們準備部署! 我們可以這樣做:
kubectl apply -f mysite.yaml
你應該看到類似於以下內容:
deployment.apps/mysite-nginx created
service/mysite-nginx-service created
ingress.networking.k8s.io/mysite-nginx-ingress created
這意味著 Kubernetes 為我們指定的三個配置分別創建了資源。使用以下方法檢查 Pod 的狀態:
kubectl get pods
如果看到狀態為ContainerCreating,請給它一些時間並再次運行kubectl get pods。通常,第一次會花一些時間,因為 k3s 必須下載nginx鏡像來創建 Pod。一段時間後,你應該看到Running的狀態。
嘗試一下!
Pod 運行之後,就該嘗試了。打開瀏覽器,然後在地址欄中輸入kmaster。
恭喜你!你已經在 k3s 集群上部署了一個網站!
另一個
因此,現在我們有了一個運行單個網站的整個 k3s 集群。但是我們可以有更多的網站!如果我們要在同一集群中提供另一個網站怎麼辦?讓我們看看如何做到這一點。
同樣,我們需要部署一些東西。碰巧我的狗有一條她想讓全世界都知道的信息,她想了好久了。因此,我專門為她製作了一些 HTML(可從示例 zip 文件中獲得)。同樣,我們將使用配置映射的技巧來託管這些 HTML。這次我們將把整個目錄(html目錄)放到配置映射中,但是調用是相同的。
kubectl create configmap mydog-html --from-file html
現在,我們需要為此站點創建一個配置文件。它幾乎與用於mysite.yaml的完全相同,因此首先將mysite.yaml複製為mydog.yaml。現在將mydog.yaml修改為:
apiVersion: apps/v1
kind: Deployment
metadata:
name: mydog-nginx
labels:
app: mydog-nginx
spec:
replicas: 1
selector:
matchLabels:
app: mydog-nginx
template:
metadata:
labels:
app: mydog-nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
volumeMounts:
- name: html-volume
mountPath: /usr/share/nginx/html
volumes:
- name: html-volume
configMap:
name: mydog-html
---
apiVersion: v1
kind: Service
metadata:
name: mydog-nginx-service
spec:
selector:
app: mydog-nginx
ports:
- protocol: TCP
port: 80
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: mydog-nginx-ingress
annotations:
kubernetes.io/ingress.class: "traefik"
traefik.frontend.rule.type: PathPrefixStrip
spec:
rules:
- http:
paths:
- path: /mydog
backend:
serviceName: mydog-nginx-service
servicePort: 80
我們只需進行搜索並將mysite替換為mydog即可完成大多數修改。其他兩個修改在入口部分中。我們將path更改為/mydog,並添加了一個註解traefik.frontend.rule.type: PathPrefixStrip。
/mydog路徑的規範指示 Traefik 將以/mydog路徑開頭的所有傳入請求路由到mydog-nginx-service。任何其他路徑將繼續路由到mysite-nginx-service。
新的註解PathPrefixStrip告訴 Traefik 在將請求發送到mydog-nginx-service之前先去除前綴/mydog。我們這樣做是因為mydog-nginx應用程序不需要前綴。這意味著我們可以簡單地通過更改入口記錄中的前綴來更改掛載的服務的位置。
現在我們可以像以前一樣進行部署:
kubectl apply -f mydog.yaml
現在,我的狗的消息應該可以在http://kmaster/mydog/上找到。
呼!消息發出去了!也許今晚我們都可以睡一覺。
因此,現在,我們有了一個 k3s 集群,該集群託管了兩個網站,Traefik 根據路徑名決定將請求傳遞給哪個服務!但是,不僅限於基於路徑的路由,我們也可以使用基於主機名的路由,我們將在以後的文章中進行探討。
另外,我們剛剛託管的網站是標準的未加密 HTML 網站,而如今的所有內容都使用 SSL/TLS 加密。在我們的下一篇文章中,我們將為 k3s 集群添加支持以託管 SSL/TLS HTTPS 站點!
清理
在開始之前,由於本文主要涉及的是示例站點,因此我想向你展示如何刪除內容,以防萬一你不希望將這些示例丟在集群中。
對於大多數配置,只需使用與部署時使用的相同配置文件運行delete命令即可撤消配置。因此,讓我們同時清理mysite和mydog。
kubectl delete -f mysite.yaml
kubectl delete -f mydog.yaml
由於我們是手動創建配置映射的,因此我們也需要手動刪除它們。
kubectl delete configmap mysite-html
kubectl delete configmap mydog-html
現在,如果我們執行kubectl get pods,我們應該看到我們的 nginx Pod 不存在了。
$ kubectl get pods
No resources found in default namespace.
一切都清理了。
請在下面的評論中告訴我你對這個項目有什麼想法。
via:https://opensource.com/article/20/3/kubernetes-traefik
作者:Lee Carpenter選題:lujun9972譯者:wxy校對:wxy
本文由LCTT原創編譯,Linux中國榮譽推出