阿里云ack的創建與應用案例
- 創建前開通ack相關服務:
- 開始創建
- 簡單的魔方游戲,熟悉sv與clb自動注冊創建
- 部署一個nginx 服務示例:
- 走不同域名訪問不同svc資源:
- 為什么需要 Ingress ?
- 創建第一個域名的 Deployment和Service。
- 創建第二個域名的 Deployment和Service。
- 部署Ingress
- 測試訪問情況
- 灰度發布與藍綠發布參考:
- 探針場景
- 為什么要用探針?
- **探針案例**
- 生命周期舉例
- ack云日志如何接入(阿里的Logtail產品)
創建前開通ack相關服務:
https://help.aliyun.com/zh/ack/ack-managed-and-ack-dedicated/getting-started/quick-start-for-first-time-users/?spm=a2c4g.11186623.help-menu-85222.d_1_1.1b1c15442gwzA8&scm=20140722.H_161387._.OR_help-T_cn#DAS#zh-V_1
開始創建
https://help.aliyun.com/zh/ack/ack-managed-and-ack-dedicated/user-guide/create-an-ack-managed-cluster-2?spm=a2c4g.11186623.help-menu-85222.d_2_0_2_0.71e34e25vspFLq&scm=20140722.H_95108._.OR_help-T_cn#DAS#zh-V_1
測試環境:選擇使用 EIP 暴露 API Server, 才能在遠程連接或者通過控制臺的cloudshell管理集群
生產環境:找一臺內網安裝有kebctl客戶端機器進行訪問(做好訪問權限控制)
連接設置:
復制k8s的外網遠程連接配置到conf中
記得先備份好本地的config文件
cd $HOME/.kube/
cp config config.local.back
echo > config
vi config
查看nodes節點情況:
lantai@lantaideMacBook-Pro .kube % kubectl get nodes
NAME STATUS ROLES AGE VERSION
cn-chengdu.10.194.33.154 Ready <none> 54m v1.31.1-aliyun.1
cn-chengdu.10.245.11.206 Ready <none> 54m v1.31.1-aliyun.1
注:沒有節點信息就不正常,一般原因是余額不足,導致無法創建節點資源。
簡單的魔方游戲,熟悉sv與clb自動注冊創建
基于clb注冊暴露服務端口,會新創建一個clb進行轉發到node的暴露端口上,
不太推薦生產,多創建一個clb就多消耗資源(根據業務規模情況吧)
https://help.aliyun.com/zh/ack/ack-managed-and-ack-dedicated/getting-started/getting-started-with-ack-using-kubectl?spm=a2c4g.11186623.help-menu-85222.d_1_3.202c1a00AcmOam&scm=20140722.H_309552._.OR_help-T_cn#DAS#zh-V_1
部署前的clb:
部署后的clb:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ack-cube-svc LoadBalancer 192.168.31.155 47.108.xx.xx 80:31547/TCP 32s
在瀏覽器地址欄輸入該服務EXTERNAL-IP字段的IP地址,即可開始魔方游戲。
刪除練習相關資源:
kubectl delete -f ack-cube-svc.yaml
kubectl delete -f ack-cube.yaml
slb中的資源會自己刪除:
部署一個nginx 服務示例:
基于clb注冊暴露服務端口
- 先配置deployment
apiVersion: apps/v1 # for versions before 1.8.0 use apps/v1beta1
kind: Deployment
metadata:name: nginx-test #應用名稱。labels:app: nginx-test
spec:replicas: 1 #設置副本數量。selector:matchLabels:app: nginx-test #對應服務中Selector的值需要與其一致,才可以通過服務公開此應用。template:metadata:labels:app: nginx-testspec:containers:- name: nginx-testimage: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6 #替換為您實際的鏡像地址,格式為:<image_name:tags>。ports:- containerPort: 80 #需要在服務中暴露該端口。
Deployment資源創建與驗證:
kubectl apply -f nginx-test.yaml
kubectl get deployment nginx-test
- 配置nginx的 sv
apiVersion: v1
kind: Service
metadata:labels:app: nginx-testname: nginx-test-svcnamespace: default
spec:ports:- port: 8080 #公網暴露的端口,用了clb下面是LoadBalancer會自動開放端口到eip中protocol: TCPtargetPort: 80 selector:app: nginx-test # 需要與Deployment YAML文件中的matchLabels的值一致。type: LoadBalancer # 使用clb自動注冊,需要配置為LoadBalancer類型
Service資源創建與驗證:
kubectl apply -f nginx-svc.yaml
kubectl get svc nginx-test-svc
lantai@lantaideMacBook-Pro .kube % kubectl get svc nginx-test-svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-test-svc LoadBalancer 192.168.31.180 47.108.*.* 8080:30456/TCP 18m
瀏覽器中訪問: EXTERNAL-IP:8080
EXTERNAL-IP : 外部可訪問的公網ip地址
刪除資源:
kubectl delete -f nginx-svc.yaml
kubectl delete -f nginx-test.yaml
走不同域名訪問不同svc資源:
為什么需要 Ingress ?
- Service 可以使用 NodePort 暴露集群外訪問端口,但是性能低、不安全并且端口的范圍有限。
- Service 缺少七層(OSI 網絡模型)的統一訪問入口,負載均衡能力很低,不能做限流、驗證非法用戶、鏈路追蹤等等。
- Ingress 公開了從集群外部到集群內
服務
的 HTTP 和 HTTPS 路由,流量路由由 Ingress 資源上定義的規則控制。 - 我們使用 Ingress 作為整個集群統一的入口,配置 Ingress 規則轉發到對應的 Service 。
基于ack中的ingress進行域名的轉發規則實驗:
ack的ingress配置參考:
https://help.aliyun.com/zh/ack/ack-managed-and-ack-dedicated/user-guide/create-an-nginx-ingress-1?spm=a2c4g.11186623.0.0.1b1c4d29tyipum
ack ingress的副本數量控制:
https://help.aliyun.com/zh/ack/deploy-ingresses-in-a-high-reliability-architecture?spm=a2c4g.11186623.0.0.17ffae7bmNEj0W#task-1339886
k8s的ingress參考:
https://kubernetes.io/docs/concepts/services-networking/ingress/
生產環境的svc的type類型建議如下
type: ClusterIP
創建第一個域名的 Deployment和Service。
創建一個old-nginx.yaml 資源清單
apiVersion: apps/v1
kind: Deployment
metadata:name: old-nginx
spec:replicas: 1selector:matchLabels:run: old-nginx # 標簽和service資源定義的對應好template:metadata:labels:run: old-nginxspec:containers:- image: registry.cn-hangzhou.aliyuncs.com/acs-sample/old-nginx # 用的阿里封裝過的鏡像,生產根據實際情況配置鏡像倉庫地址imagePullPolicy: Alwaysname: old-nginxports:- containerPort: 80protocol: TCPrestartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:name: old-nginx
spec:ports:- port: 80protocol: TCPtargetPort: 80selector:run: old-nginxsessionAffinity: Nonetype: NodePort
b. 執行以下命令,創建Deployment和Service。
kubectl apply -f old-nginx.yaml
創建第二個域名的 Deployment和Service。
創建new-nginx.yaml。
apiVersion: apps/v1
kind: Deployment
metadata:name: new-nginx
spec:replicas: 1selector:matchLabels:run: new-nginxtemplate:metadata:labels:run: new-nginxspec:containers:- image: registry.cn-hangzhou.aliyuncs.com/acs-sample/new-nginximagePullPolicy: Alwaysname: new-nginxports:- containerPort: 80protocol: TCPrestartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:name: new-nginx
spec:ports:- port: 80protocol: TCPtargetPort: 80selector:run: new-nginxsessionAffinity: Nonetype: NodePort
b. 執行以下命令,創建Deployment和Service。
kubectl apply -f new-nginx.yaml
部署Ingress
創建ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: ingress-http
spec:rules: # 規則,這里配置的域名規則,類似nginx# 第一個svc域名- host: www.example.comhttp:paths:# 老版本nginx服務。- path: /backend:service: name: old-nginxport:number: 80 # 后端svc的端口號pathType: ImplementationSpecific# 第二個svc域名- host: www.test.comhttp:paths:# 新版本nginx服務。- path: /backend: # 指定路由到后端服務的service 相關配置service: name: new-nginxport:number: 80 # 后端svc的端口號pathType: ImplementationSpecific # ImplementationSpecific 匹配方法取決于 IngressClass
執行以下命令,部署Ingress。
kubectl apply -f ingress.yaml
測試訪問情況
查看ingress, 獲取外部訪問IP:
lantai@lantaideMacBook-Pro .kube % kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress-http nginx www.example.com,www.test.com 47.108.*.184 80 18s
查看clb控制面板并沒有增加條目,因為這次不是LoadBalancer類型的svc, 是NodePort類型的svc,不會向clb注冊條目,這次依靠ack內部的ingress組件進行域名轉發:
本地電腦主機編輯/etc/hosts進行測試:
47.108.*.184 www.test.com
47.108.*.184 www.example.com
然后,通過瀏覽器訪問不同的域名進行測試,測試效果如下:
測試完清空資源:
kubectl delete -f ingress.yaml
kubectl delete -f old-nginx.yaml
kubectl delete -f new-nginx.yaml
灰度發布與藍綠發布參考:
https://help.aliyun.com/zh/ack/ack-managed-and-ack-dedicated/user-guide/implement-gray-scale-and-blue-green-publishing-through-nginx-ingress?spm=a2c4g.11186623.help-menu-85222.d_2_3_5_2_7.7d9fae7beFROdE&scm=20140722.H_200941._.OR_help-T_cn~zh-V_1#38348104fea19
可基于請求頭、cookie 、請求參數,流量權重等控制。
探針場景
為什么要用探針?
主要做 健康檢查
- 在 Kubernetes 中,探針不是默認配置的,需要手動添加到 Pod 的定義中。
- 如果沒有添加
livenessProbe
和readinessProbe
,Kubernetes 不會自動進行基于應用層協議(如 HTTP)的健康檢查,只會檢查容器是否成功啟動(即容器的主進程是否運行)。
- 如果沒有添加
-
容器啟動狀態檢查
- 默認情況下,Kubernetes主要關注容器是否成功啟動并進入
Running
狀態。當Kubernetes調度一個Pod到節點上后,它會等待容器的主進程啟動。如果主進程能夠正常啟動,容器就會被標記為Running
。
- 默認情況下,Kubernetes主要關注容器是否成功啟動并進入
-
容器運行后的健康監測缺失(默認情況)
- 然而,僅容器啟動成功并不意味著應用在整個生命周期內都能正常提供服務。例如,應用可能會出現死鎖、進入無限循環、耗盡資源等情況,導致雖然容器仍在運行,但服務已經不可用。默認情況下,Kubernetes沒有內置對這些應用層問題的檢查機制,這就需要通過手動添加探針(如
livenessProbe
和readinessProbe
)來實現更細致的健康監測。
- 然而,僅容器啟動成功并不意味著應用在整個生命周期內都能正常提供服務。例如,應用可能會出現死鎖、進入無限循環、耗盡資源等情況,導致雖然容器仍在運行,但服務已經不可用。默認情況下,Kubernetes沒有內置對這些應用層問題的檢查機制,這就需要通過手動添加探針(如
-
與Pod生命周期的關系
- 在Pod的生命周期管理中,默認的
Running
狀態判斷相對比較基礎。從創建Pending
到進入Running
,Kubernetes確保了容器能夠啟動,但對于后續可能出現的各種應用故障場景,沒有默認的主動監測。添加探針后,可以更好地管理Pod在Running
狀態下的健康狀況,例如通過livenessProbe
來決定是否重啟故障容器,通過readinessProbe
來確定容器是否可以接收流量,這些操作有助于維護應用的高可用性和穩定性。
- 在Pod的生命周期管理中,默認的
-
Pod生命周期概述
- 創建階段(
Pending
):當創建一個Pod時,它首先進入Pending
狀態。此時,Kubernetes正在為Pod分配節點資源,包括下載鏡像等操作。例如,若Pod請求的資源(如CPU、內存)在集群中暫時無法滿足,或者鏡像拉取出現問題,Pod就會一直處于Pending
狀態。 - 運行階段(
Running
):當Pod成功被調度到節點并且容器啟動后,進入Running
狀態。此時,容器內的應用程序開始運行,提供相應的服務。但這并不意味著應用完全健康,可能還需要進一步的健康檢查(通過探針)來確保服務的質量。 - 終止階段(
Succeeded
或Failed
):當容器內的主進程正常退出時,Pod狀態變為Succeeded
;如果容器內主進程異常退出或者容器無法啟動,Pod狀態變為Failed
。
- 創建階段(
-
kubernetes提供了兩種探針來實現容器探測,分別是:
- 存活探針(
livenessProbe
):- 用于判斷容器是否還在“存活”狀態。
- 如果存活探針檢測失敗,Kubernetes會根據配置的策略(如重啟容器)來嘗試恢復服務。
-
- 例如,對于一個Web應用,可以設置一個HTTP存活探針,定期發送HTTP請求到應用的某個端點,如果連續多次無法得到正確響應(如返回狀態碼不是
200-299
),就認為容器可能出現問題,需要重啟。 - 在 Kubernetes 中,當
livenessProbe
(存活探針)檢測失敗達到一定次數(failureThreshold
)時,默認行為是重啟容器。- 對于
httpGet
類型的存活探針,Kubernetes 會按照periodSeconds
設置的時間間隔(這里是 5 秒)來檢查容器內應用的健康狀況。如果連續多次檢查(默認failureThreshold
為 3 次)都無法通過(例如,返回的 HTTP 狀態碼不是 200 - 399 范圍內),Kubernetes 就會判定容器不健康,并采取重啟操作,以嘗試恢復應用的正常運行。
- 對于
- kubernetes就會對容器所在的Pod進行重啟,其實這是由Pod的重啟策略決定的,Pod的重啟策略有3種,分別如下:
- Always:容器失效時,自動重啟該容器,默認值。
- OnFailure:容器終止運行且退出碼不為0時重啟。
- Never:不論狀態如何,都不重啟該容器。
- 例如,對于一個Web應用,可以設置一個HTTP存活探針,定期發送HTTP請求到應用的某個端點,如果連續多次無法得到正確響應(如返回狀態碼不是
- 存活探針(
restartPolicy: Never # 重啟策略設置格式
-
- 就緒探針(
readinessProbe
):- 用于判斷容器是否已經“準備好”接收流量。
- 只有當就緒探針檢測成功時,Service才會將流量轉發到該容器對應的Pod。
- 例如,一個應用可能在啟動后需要一些時間來加載配置文件或者初始化數據庫連接,在這個過程中,雖然容器已經運行(存活),但還沒有準備好接收流量。通過就緒探針可以確保只有在應用真正準備好后,才會讓流量進入。
- 就緒探針(
探針案例
- 將帶有探針的Pod納入Service管理
- 在Pod配置中添加探針(以
Deployment
為例):
假設要部署一個nginx
應用的Pod,并且添加探針。 - 創建一個
Deployment
的YAML
文件如下:
- 在Pod配置中添加探針(以
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-deployment-with-probes
spec:replicas: 3selector:matchLabels:app: nginx-probestemplate:metadata:labels:app: nginx-probesspec:containers:- name: nginx-container-with-probesimage: nginx:latestports:- containerPort: 80livenessProbe:httpGet: # 表示通過發送 HTTP GET 請求的方式來檢測容器內應用的狀態path: /port: 80initialDelaySeconds: 15 # 在容器啟動后,延遲多少秒才開始第一次進行存活探針檢測periodSeconds: 5 #它定義了每隔多長時間進行一次存活探針檢測,這里設置為 5 秒readinessProbe:httpGet:path: /port: 80initialDelaySeconds: 10 #表示容器啟動后,延遲 10 秒才開始第一次進行就緒探針檢測periodSeconds: 3
注:在這個配置中,livenessProbe和readinessProbe都是基于httpGet(還有其它方式)方式,即發送HTTP請求來檢查容器的狀態。path: /表示發送請求到容器內應用的根路徑(對于nginx來說就是首頁),port: 80表示通過80端口發送請求。initialDelaySeconds是容器啟動后延遲多久開始第一次探測,periodSeconds是每次探測的間隔時間。
創建Service
來管理帶有探針的Pod:
apiVersion: v1
kind: Service
metadata:name: nginx-service-for-probes
spec:selector:app: nginx-probesports:- port: 80targetPort: 80type: ClusterIP
- 當Pod配置好探針后,創建
Service
來管理這些Pod。例如: - 在
Service
的spec
部分,selector
字段通過app: nginx-probes
來選擇帶有這個標簽的Pod,這些Pod正是之前在Deployment
中配置了探針的nginx
Pod。 ports
部分定義了Service
本身的端口(port: 80
)和轉發到Pod的目標端口(targetPort: 80
)。- 這樣,
Service
就會根據Pod
的就緒狀態(通過就緒探針來判斷)將外部流量轉發到合適的Pod
上。當Pod
的存活探針檢測到容器出現問題時,Kubernetes會按照配置(如重啟容器)來處理,而Service
會自動更新其流量轉發的目標Pod
列表,確保流量始終導向健康的Pod
。
生命周期舉例
lifecycle
配置可以添加到Deployment
中- 在Kubernetes的
Deployment
資源中,可以為容器定義生命周期鉤子(lifecycle hooks
),用于在容器啟動后(postStart
)和容器停止前(preStop
)執行特定的操作。 - 這對于需要在容器生命周期的關鍵階段進行自定義操作(如初始化配置、清理資源等)非常有用。
- 在Kubernetes的
- 示例
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-deployment-with-lifecyclelabels:app: nginx
spec:replicas: 1selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:latestlifecycle:postStart: # 啟動后exec:command: ["/bin/sh","-c","echo postStart... > /usr/share/nginx/html/index.html"]preStop: # 停止前exec:command: ["/usr/sbin/nginx","-s","quit"]
- 以下是一個包含
lifecycle
配置的Deployment
示例,用于部署一個簡單的Nginx應用:
- 在這個示例中:- apiVersion、kind和metadata部分:
apiVersion
指定了使用的Kubernetes API版本(apps/v1
用于Deployment
資源)。kind
定義資源類型為Deployment
。metadata
包含了Deployment
的名稱(nginx-deployment-with-lifecycle
)和標簽(app: nginx
),用于標識和組織資源。
spec
部分:replicas
字段設置為1
,表示希望運行的Pod副本數量為1個。selector
定義了如何選擇這個Deployment
管理的Pod,通過匹配標簽app: nginx
來確定。template
部分定義了Pod的模板。metadata
中的標簽(app: nginx
)用于Pod的識別。spec
中的containers
字段定義了容器相關信息。- 容器名稱為
nginx
,使用nginx:latest
鏡像。 lifecycle
配置包含了postStart
和preStop
鉤子。postStart
鉤子在容器創建后執行,通過exec
方式運行一條命令,將postStart...
寫入Nginx容器的/usr/share/nginx/html/index.html
文件,從而修改了Nginx的首頁內容。preStop
鉤子在容器停止前執行,通過exec
方式運行命令/usr/sbin/nginx - s quit
來優雅地停止Nginx服務,確保在容器完全停止之前,Nginx能夠正常關閉,避免數據丟失或服務異常。
- 容器名稱為
- apiVersion、kind和metadata部分:
- 應用和驗證
kubectl apply -f nginx-deployment-with-lifecycle.yaml
- 可以使用
kubectl
命令來應用這個Deployment
配置: - 之后,可以通過以下方式驗證
lifecycle
鉤子的執行情況:- 驗證
postStart
:- 可以通過訪問Nginx服務(如果已經配置了服務暴露),查看Nginx的首頁內容是否被修改為
postStart...
。- 例如,如果使用
NodePort
服務類型暴露Nginx服務,可以通過http://<node-ip>:<node-port>
訪問,查看返回的頁面內容。
- 例如,如果使用
- 可以通過訪問Nginx服務(如果已經配置了服務暴露),查看Nginx的首頁內容是否被修改為
- 驗證
preStop
:- 可以通過手動刪除
Deployment
kubectl delete deployment nginx-deployment-with-lifecycle
)- 然后查看容器日志
- (
kubectl logs <pod-name>
)來確認preStop
命令是否被執行。 - 在日志中,應該可以看到Nginx服務被優雅地停止的相關信息。
- (
- 可以通過手動刪除
- 驗證
ack云日志如何接入(阿里的Logtail產品)
配置參考:https://help.aliyun.com/zh/ack/ack-managed-and-ack-dedicated/user-guide/collect-log-data-from-containers-by-using-log-service?spm=a2c4g.11186623.help-menu-85222.d_2_9_1_1.341a455bvxC9TP