2020 It邦幫忙鐵人賽 系列文章
這邊該了一些大綱,原本的內容還有一些 kubernetes 的設定,以及 GCP 相關服務的介紹。但既然我們的主題是把東西搬上 k8s 的踩雷旅程,那我們就繼續搬,繼續踩。剩下的時間大概會有四個題目。
由於我比較熟悉 GCP / GKE 的服務,這篇的操作過程都會以 GCP 平台作為範例,不過操作過程大體上是跨平台通用的。
寫文章真的是體力活,覺得我的文章還有參考價值,請左邊幫我點讚按個喜歡,右上角幫我按個追縱,底下歡迎留言討論。給我一點繼續走下去的動力。
對我的文章有興趣,歡迎到我的網站上 https://chechiachang.github.io 閱讀其他技術文章,有任何謬誤也請各方大德直接聯繫我,感激不盡。
Nginx 是一款高效能、耐用、且功能強大的 load balancer 以及 web server,也是市占率最高的 web server 之一。
這邊簡單講一下 kubernetes ingress。當我們在使用 kubernetes 時需要將外部流量 route 到集群內部,這邊使用 Ingress 這個 api resource,來定義外部到內部的設定,例如:
一個簡單的 ingress 大概長這樣
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: test-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /testpath
backend:
serviceName: test
servicePort: 80
除了一般的 k8s 資源,nginx 主要的設定會落在 spec,以及依賴底下實作不同,額外設定的 annotation。
這邊可以看到 spec.rule 定義了外部 http 流量,引導到 backend service 的路徑。
annotations 下已經標註的 nginx.ingress 的 annotation,來快速增加額外的設定。
雖然已經指定 nginx 的 annotation,但這邊要注意,ingress resource 本身是不指定底層的實現 (ingress controller),也就是說,底下是 nginx 也好,traefik 也行,只要能夠實現 ingress 裏頭設定的 routing rules 就可以。
只設定好 ingress,集群上是不會有任何作用的,還需要在集群上安裝 ingress controller 的實作,實作安裝完了以後,會依據 ingress 的設定,在 controller 裏頭實現,不管是 routing、ssl/tls termination、load balancing 等等功能。如同許多 Kubernetes resource 的設計理念一樣,這邊也很優雅的用 ingress 與 ingress controller,拆分的需求設定與實作實現兩邊的職責。
例如以 nginx ingress controller,安裝完後會依據 ingress 的設定,在 nginx pod 裡設定對應的 routing rules,如果有 ssl/tls 設定,也一併載入。
Kubernetes 官方文件提供了許多不同的 controller 可以依照需求選擇。
但如果不知道如何選擇,個人會推薦使用 nginx ingress controller,穩定、功能強大、設定又不至於太過複雜,基本的設定就能很好的支撐服務,不熟悉的大德們比較不容易被雷到。
底下我們就要來開始使用 nginx ingress controller。
我們這邊使用的 ingress-nginx 是 kubernetes org 內維護的專案,專案內容主要是再 k8s 上執行 nginx,抽象與實作的整合,並透過 configmap 來設定 nginx。針對 nginx ingress kubernetes 官方有提供非常詳細的說明文件 ,剛接觸 nginx 的大德可以透過這份文件,快速的操作 nginx 的設定,而不用直接寫 nginx.conf 的設定檔案。
我們這邊用 helm 部屬,Nginx Ingress Controller Stable Chart,讓各位大德用最簡單的步驟,獲得一個功能完整的 nginx ingress controller。
與前面幾個 helm chart 一樣,我們可以先取得 default values.yaml 設定檔,再進行更改。
$ wget https://raw.githubusercontent.com/helm/charts/master/stable/nginx-ingress/values.yaml
$ vim values.yaml
安裝時也可以使用 --set 來變更安裝 chart 時的 parameters
$ helm install stable/nginx-ingress \
--set controller.metrics.enabled=true \
-f values.yaml
安裝完後,resource 很快就起來。
kubectl get all --selector app=nginx-ingress
NAME READY STATUS RESTARTS AGE
pod/nginx-ingress-controller-7bbcbdcf7f-tx69n 1/1 Running 0 216d
pod/nginx-ingress-default-backend-544cfb69fc-rnn6h 1/1 Running 0 216d
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/nginx-ingress-controller LoadBalancer 10.15.246.22 34.35.36.37 80:30782/TCP,443:31933/TCP 216d
service/nginx-ingress-default-backend ClusterIP 10.15.243.19 <none> 80/TCP 216d
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx-ingress-controller 1/1 1 1 216d
deployment.apps/nginx-ingress-default-backend 1/1 1 1 216d
NAME DESIRED CURRENT READY AGE
replicaset.apps/nginx-ingress-controller-7bbcbdcf7f 1 1 1 216d
replicaset.apps/nginx-ingress-default-backend-544cfb69fc 1 1 1 216d
kubectl get configmap -l app=nginx-ingress
NAME DATA AGE
nginx-ingress-controller 2 216d
kubectl get ingress
NAME HOSTS ADDRESS PORTS AGE
ingress-nginx api.chechiachang.com 34.35.36.37 80, 443 216d
兩個 Pods
Service
第一個雷點是 helm chart install 帶入的 parameters,有些 parameter 是直接影響 deployment 的設定,如果沒注意到,安裝完後沒辦法透過 hot reload 來處理,只能幹掉重來。建議把這份表格都看過一次,再依照環境與需求補上。
$ helm install stable/nginx-ingress \
--set controller.metrics.enabled=true \
--set controller.service.externalTrafficPolicy=Local \
-f values.yaml
這邊開了 prometheus metrics exporter,以及 source IP preservation。
再安裝完後,外部的 load balancer 啟用後,就可以透過 GCP 的 external ip 連入 nginx,nginx 依照設定的 rule 向後端服務做集群內的 load balancing 與 routing。
如果在使用過程中,有需要執行更改設定,或是 hot reload config,在 kubernetes 上要如何做呢? 我們下回分解。