示例應(yīng)用介紹
代碼:https://github.com/Hugh-yw/kubernetes-example
源碼目錄結(jié)構(gòu)如下:
$ ls
backend deploy frontend
backend 目錄為后端源碼,frontend 目錄為前端源碼,deploy 目錄是應(yīng)用的 K8s Manifest,前后端都已經(jīng)包含構(gòu)建鏡像所需的 Dockerfile。
示例應(yīng)用由三個(gè)服務(wù)組成:
1. 前端;
2. 后端;
3. 數(shù)據(jù)庫。
其中,前端采用 React 編寫,它也是應(yīng)用對外提供服務(wù)的入口;后端由 Python 編寫;數(shù)據(jù)庫采用流行的 Postgres。
應(yīng)用整體架構(gòu)如下圖所示:
前端實(shí)現(xiàn)了三個(gè)功能,分別是存儲輸入的內(nèi)容,列出輸入內(nèi)容記錄以及刪除所有的記錄。這三個(gè)功能分別對應(yīng)了后端的三個(gè)接口,也就是 /add, /fetch 和 /delete,最后數(shù)據(jù)會被存儲在 Postgres 數(shù)據(jù)庫中。
應(yīng)用的 K8s 部署架構(gòu)圖如下:
Ingress (Traefik)是應(yīng)用的入口,Ingress 會根據(jù)請求路徑將流量分流至前后端的 Service 中,然后 Service 將請求轉(zhuǎn)發(fā)給前后端 Pod 進(jìn)行業(yè)務(wù)邏輯處理,后端的工作負(fù)載 Deployment 配置了 HPA 自動(dòng)橫向擴(kuò)容。同時(shí),Postgres 也是以 Deployment 的方式部署到集群內(nèi)的。最后,所有資源都部署在 K8s 的 example 命名空間(Namespace)下。
部署應(yīng)用到k8s
1.創(chuàng)建ns
$ kubectl create namespace example
2.部署db
$ kubectl create -f https://github.com/Hugh-yw/kubernetes-example/blob/main/deploy/database.yaml -n example
3.部署前后端
$ kubectl create -f https://github.com/Hugh-yw/kubernetes-example/blob/main/deploy/frontend.yaml -n example
$ kubectl create -f https://github.com/Hugh-yw/kubernetes-example/blob/main/deploy/backend.yaml -n example
4.創(chuàng)建ingressroute和hpa
cat front-ingroute.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: frontend-service
spec:
entryPoints:
- web
routes:
- match: Host(`frontend.demo.com`)
kind: Rule
services:
- name: frontend-service
port: 3000
- match: Host(`frontend.demo.com`) && PathPrefix(`/api`)
kind: Rule
services:
- name: backend-service
port: 5000
$ kubectl create -f https://github.com/Hugh-yw/kubernetes-example/blob/main/deploy/hpa.yaml -n example
5.通過域名“frontend.demo.com”訪問前端頁面,測試新增、刪除數(shù)據(jù)。
如何使用命名空間隔離團(tuán)隊(duì)及應(yīng)用環(huán)境?
NameSpace簡介
命名空間是集群的一種“軟隔離”機(jī)制,它通過這種隔離機(jī)制,為我們管理和組織集群資源提供了便利。集群和命名空間的關(guān)系如圖所示:
不同的命名空間具備一定的隔離性,業(yè)務(wù)應(yīng)用的工作負(fù)載以及其他的 K8s 對象可以部署在特定的命名空間中, 在不同命名空間中,相同類型的資源可以重名。利用這種特性,我們可以把集群虛擬的命名空間和現(xiàn)實(shí)中的不同團(tuán)隊(duì)、不同應(yīng)用在邏輯上聯(lián)系起來。
創(chuàng)建和刪除
在一個(gè) K8s 集群中,命名空間可以劃分為兩種類型:系統(tǒng)級命名空間和用戶自定義命名空間。
系統(tǒng)級的命名空間是 K8s 集群默認(rèn)創(chuàng)建的命名空間,主要用來隔離系統(tǒng)級的對象和業(yè)務(wù)對象,系統(tǒng)級的命名空間下面四種。
- default:默認(rèn)命名空間,也就是在不指定命名空間時(shí)的默認(rèn)命名空間。
- kube-system:K8s 系統(tǒng)級組件的命名空間,所有 K8s 的關(guān)鍵組件(例如 kube-proxy、coredns、metric-server 等)都在這個(gè)命名空間下。
- kube-public:開放的命名空間,所有用戶(包括未經(jīng)認(rèn)證)的用戶都可以讀取,這個(gè)命名空間是一個(gè)約定,但不是必須。
- kube-node-lease:和集群擴(kuò)展相關(guān)的命名空間。
在這幾個(gè)命名空間中,除了 default 命名空間,你都不應(yīng)該將業(yè)務(wù)應(yīng)用部署在其他系統(tǒng)默認(rèn)創(chuàng)建的命名空間下,也不要嘗試去刪除它們,這可能會導(dǎo)致集群異常。
創(chuàng)建:
kubectl create ns xxx
kubectl create -f test-ns.yaml
刪除:
kubectl delete ns xxx
刪除命名空間將會刪除該命名空間下的所有資源,所以在實(shí)際項(xiàng)目中請謹(jǐn)慎操作。另外,由于刪除動(dòng)作是異步的,因此刪除中的命名空間狀態(tài)會由正常的 Active 轉(zhuǎn)變?yōu)?Terminating,也就是“終止中的狀態(tài)”。
什么時(shí)候使用命名空間?
當(dāng)有以下場景需求時(shí),我建議你考慮使用命名空間。
- 環(huán)境管理:你可以使用命名空間來隔離開發(fā)環(huán)境、預(yù)發(fā)布環(huán)境和生產(chǎn)環(huán)境。例如用 dev、staging、prod 命名空間來區(qū)分這三個(gè)環(huán)境。命名空間的隔離特性可以讓開發(fā)環(huán)境的的操作不會影響到其他環(huán)境的工作。實(shí)際上,對于這種情況,我更建議使用不同的集群進(jìn)行硬隔離,命名空間的隔離方式只是一種選擇。
- 隔離: 當(dāng)你有多個(gè)團(tuán)隊(duì),或者多個(gè)產(chǎn)品線運(yùn)行在同一個(gè)集群時(shí),你可以使用命名空間來隔離這些團(tuán)隊(duì)或者產(chǎn)品線,讓他們相互之間不受影響。你甚至可以為每一個(gè)開發(fā)分配一個(gè)命名空間,讓他們獨(dú)立進(jìn)行開發(fā)工作。
- 資源控制: 你可以在命名空間級別配置 CPU、內(nèi)存等資源配額。通過這個(gè)方法,你可以為某個(gè)團(tuán)隊(duì)或者某條業(yè)務(wù)線設(shè)置總的資源配額,而不需要關(guān)注他們具體在每一個(gè)工作負(fù)載上怎么分配這些資源。此外,命名空間的資源配額還能夠合理確保每一個(gè)項(xiàng)目所需要的資源配額,避免出現(xiàn)資源惡性競爭導(dǎo)致業(yè)務(wù)不穩(wěn)定的情況。
- 權(quán)限控制:K8s 的 RBAC 可以幫助我們對某個(gè)用戶僅授權(quán)一個(gè)或者多個(gè)命名空間,確保只有特定的用戶能訪問特定命名空間下的資源。
- 提高集群性能: 命名空間有利于提高集群性能。在進(jìn)行資源搜索時(shí),命名空間有利于 K8s API 縮小查找范圍,對減小搜索延遲和提升性能具有一定的幫助。
如何跨命名空間通信?
在使用命名空間隔離資源之后,就會涉及到如何通信的問題。我們之前說命名空間是一種“軟隔離”機(jī)制,既然是軟隔離,那么不同命名空間完全是可以相互通信的。
當(dāng) K8s 創(chuàng)建 Service 時(shí),會創(chuàng)建相應(yīng)的 DNS 解析記錄,格式為:<service-name>.<namespace-name>.svc.cluster.local
。當(dāng)業(yè)務(wù)容器需要和 當(dāng)前命名空間 下其他服務(wù)通信時(shí),則可以省略<namespace-name>.svc.cluster.local
,也就是縮寫為<service-name>
就可以了。
同理,要跨不同的命名空間通信,我們可以指定完整的 Service URL 來實(shí)現(xiàn)。例如,要訪問 dev 命名空間下的 backend-service,完整的 URL 為:backend-service.dev.svc.cluster.lcoal
如何為業(yè)務(wù)選擇最適合的工作負(fù)載類型?
ReplicaSet、Deployment、StatefulSet、DaemonSet、Job、CronJob
如何解決服務(wù)發(fā)現(xiàn)問題?
service
- ClusterIP
- NodePort
- Loadbalancer
- ExternalName(ClusterIP、NodePort 和 Loadbalancer 類型都是通過 Pod 選擇器將 Service 和 Pod 關(guān)聯(lián)起來,然后將請求轉(zhuǎn)發(fā)到對應(yīng)的 Pod 中的。而 ExternalName 類型非常特殊,它不通過 Pod 選擇器關(guān)聯(lián) Pod ,而是將 Service 和另外一個(gè)域名關(guān)聯(lián)起來。)
ExternalName 類型的Service Manifest示例:
apiVersion: v1
kind: Service
metadata:
name: backend-service
namespace: default
spec:
type: ExternalName
externalName: backend-service.example.svc.cluster.local
當(dāng)應(yīng)用到集群之后,在 default 命名空間下訪問 http://backend-serivce:5000 時(shí),
請求將會被轉(zhuǎn)發(fā)到 example 命名空間下的 backend-service。會發(fā)現(xiàn)雖然目標(biāo) Service 和請求發(fā)起方不在同一個(gè)命名空間下,
但可以通過這種方法屏蔽它們在不同命名空間的調(diào)用差異,使得兩個(gè)服務(wù)看起來像是在同一個(gè)命名空間下。
此外,當(dāng)需要通過 Service 名稱的方式請求外部服務(wù)時(shí),例如請求在集群外的數(shù)據(jù)庫服務(wù),也可以使用這種方法。
如何遷移應(yīng)用配置?
Kubernetes 應(yīng)用配置的三種方案:
- Env 環(huán)境變量
- ConfigMap
- Secret
其中,Env 可以向 Pod 注入環(huán)境變量,使得業(yè)務(wù)應(yīng)用在容器內(nèi)可以直接讀取它們。ConfigMap 經(jīng)常用于為 Pod 注入配置文件,例如 ini、conf、.env 配置文件等。Secret 一般用來向 Pod 注入機(jī)密信息,例如第三方應(yīng)用的 Token 等。
如何將集群的業(yè)務(wù)服務(wù)暴露外網(wǎng)訪問?
在 Kubernetes 環(huán)境下,對外暴露服務(wù)則需要通過 Service 來實(shí)現(xiàn)。由于 Service 的 IP 默認(rèn)是一個(gè)集群內(nèi)的 IP,無法從外部訪問,所以需要為 Service 賦予外網(wǎng) IP 地址。其中,NodePort 類型可以通過 Kubernetes 節(jié)點(diǎn)外網(wǎng) IP + 端口號的方式提供外網(wǎng)訪問能力,不過并不推薦在生產(chǎn)環(huán)境使用這種方式。
LoadBalancer 類型則需要依賴云廠商的負(fù)載均衡器,一般由云廠商實(shí)現(xiàn)。在對 Service 配置為 LoadBalancer 類型后,云廠商將會異步創(chuàng)建負(fù)載均衡器實(shí)例,這種方式將暴露服務(wù)和 Kubernetes 節(jié)點(diǎn)進(jìn)行了解耦,是一種常用的服務(wù)暴露方式。
不過在生產(chǎn)環(huán)境下,也不推薦以 LoadBalancer 的方式暴露所有需要在外網(wǎng)訪問的業(yè)務(wù)服務(wù),因?yàn)檫@不利于統(tǒng)一管理訪問流量,并且還要為多個(gè)負(fù)載均衡器實(shí)例支付高昂的費(fèi)用。為了解決這個(gè)問題,強(qiáng)大的社區(qū)引入了 Ingress 來暴露服務(wù)。
值得注意的是,要使用 Ingress 除了聲明 Ingress 對象以外,還需要為集群安裝 Ingress-Controller,例如最常見的 Ingress-Nginx、Traefik等。在生產(chǎn)環(huán)境下,Ingress-Nginx 正是通過 LoadBalancer 類型的 Service 來自身暴露在公網(wǎng)環(huán)境的。
通過 Ingress 暴露服務(wù)的方式是我們在生產(chǎn)環(huán)境下最常用的方法,同時(shí)也是服務(wù)暴露的最佳實(shí)踐。
如何保障業(yè)務(wù)資源需求和自動(dòng)彈性擴(kuò)容?
通過 kubernetes 資源配額來保障業(yè)務(wù)的資源需求。為工作負(fù)載配置資源的請求(Request) 和限制(Limit),可以避免工作負(fù)載調(diào)度在了資源不足的節(jié)點(diǎn),避免資源相互搶占的問題。值得注意的是,CPU 資源是可壓縮資源,而內(nèi)存則是不可壓縮資源。這意味著,如果工作負(fù)載接近 CPU 的限制值,它只會出現(xiàn)等待的情況,而當(dāng)內(nèi)存出現(xiàn)超限的情況,Pod 將會被殺死并重啟。
為工作負(fù)載設(shè)置資源配額的同時(shí),也會影響工作負(fù)載的服務(wù)質(zhì)量(QOS),工作負(fù)載的服務(wù)質(zhì)量主要有三種:BestEffort、Burstable 和 Guaranteed。當(dāng)節(jié)點(diǎn)資源不足時(shí),kubernetes 會按照這個(gè)順序依次對 Pod 進(jìn)行驅(qū)逐。
在生產(chǎn)環(huán)境下,推薦為每一個(gè)工作負(fù)載都配置資源配額,尤其是對一些重要的中間件和核心服務(wù),應(yīng)當(dāng)為它們配置足夠的資源配額,并將 Request 和 Limit 配置為相等的值,保障它的服務(wù)質(zhì)量。而對于有明顯資源高低峰的業(yè)務(wù)(例如 Java 應(yīng)用),它的特點(diǎn)是在啟動(dòng)時(shí)消耗的資源較高,但運(yùn)行時(shí)消耗的資源會趨近平穩(wěn),所以可以將 Request 配置為啟動(dòng)后的資源消耗,Limit 配置為啟動(dòng)時(shí)所需的資源消耗,在確保業(yè)務(wù)所需資源的同時(shí),這樣做還能提高系統(tǒng)整體的資源利用率。
為業(yè)務(wù)配置水平擴(kuò)容(HPA)策略。HPA 可以基于 CPU 和內(nèi)存指標(biāo)對 Pod 進(jìn)行橫向擴(kuò)縮容,同時(shí)也是保障業(yè)務(wù)可用性的重要手段。當(dāng)然,HPA 除了使用內(nèi)置的 CPU 和內(nèi)存以外,還可以配置自定義指標(biāo),結(jié)合一些開源項(xiàng)目甚至能通過外部事件來觸發(fā)擴(kuò)縮容.
如何自動(dòng)檢查業(yè)務(wù)真實(shí)的健康狀態(tài)?
背景:
如果業(yè)務(wù)應(yīng)用沒有做好垃圾回收或者產(chǎn)生死鎖,那么再運(yùn)行一段時(shí)間后,它的內(nèi)存和 CPU 消耗會迅速飆升。顯然,這時(shí)候 Pod 已經(jīng)處于不健康狀態(tài)了,怎么讓 kubernetes 識別并將它重啟呢?
這時(shí)就需要使用到 kubernetes 的健康檢查特性
。
kubernetes 的三種健康檢查探針。其中,Readiness 就緒探針可以讓 kubernetes 感知到業(yè)務(wù)的真實(shí)可用狀態(tài),kubernetes 將根據(jù)業(yè)務(wù)的狀態(tài)判斷 Pod 是否處于 Ready 就緒狀態(tài),以此來控制什么時(shí)候?qū)?Pod 加入到 EndPoints 列表中接收外部流量。
Liveness 存活探針則更加徹底,當(dāng)它感知到 Pod 不健康時(shí),會重啟 Pod。在大多數(shù)情況下,Liveness 可以實(shí)現(xiàn)對業(yè)務(wù)無感的服務(wù)重啟,在第一時(shí)間發(fā)現(xiàn)故障的同時(shí)自動(dòng)恢復(fù)業(yè)務(wù),極大提升了業(yè)務(wù)系統(tǒng)的可用性。
StartupProbe 探針主要用來解決服務(wù)啟動(dòng)慢的問題,對于一些大型的應(yīng)用例如 Java 服務(wù),我建議你為它們配置 StartupProbe,以確保在服務(wù)啟動(dòng)完成后再對它進(jìn)行常規(guī)的就緒和存活健康檢查。文章來源:http://www.zghlxwxcb.cn/news/detail-573100.html
在實(shí)際的業(yè)務(wù)場景中,強(qiáng)烈建議為業(yè)務(wù)工作負(fù)載配置這三種探針,這樣可以最大程度地保障業(yè)務(wù)的高可用和穩(wěn)定性。文章來源地址http://www.zghlxwxcb.cn/news/detail-573100.html
到了這里,關(guān)于【GitOps系列】K8s極簡實(shí)戰(zhàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!