Kubernetes高級調度1

目錄

一:初始化容器 Initcontainer

1:Initcontainer 的基本概念

2:示例 1--延遲指定時間后啟動

3:示例 2--使用初始化容器修改內核參數

4:示例 3--等待依賴服務啟動

4:pause容器

二:臨時容器 Ephemeral Containers

1.臨時容器的概念

2.臨時容器的使用

三:自動擴縮容HPA

1:什么是 HPA

2:HPA 的工作原理

3:HPA 的工作流程

4:HPA 的應用場景

5:HPA 實踐--實現 web 服務器的自動伸縮特性


一:初始化容器 Initcontainer

首先來看初始化容器,顧名思義,初始化容器是用來進行初始化操作的。很多情況下,程序的啟動需要依賴各類配置、資源。但是又不能繼承在原有的啟動命令或者鏡像當中,因為程序的鏡像可能并沒有加載配置命令,此時 Initcontainer 就起了很大的作用。

1:Initcontainer 的基本概念

Initcontainer 是 Kubernetes 的初始化容器(也可稱之為 Init 容器),它是一種特殊的容器,在Pod 內的應用容器啟動之前運行,可以包括一些應用鏡像中不存在的使用工具和安裝腳本,用以在程序啟動時進行初始化,比如創建文件、修改內核參數、等待依賴程序啟動等。
每個 Pod 中可以包含多個容器,同時 Pod 也可以有一個或多個先于應用程序啟動的 Init 容器,在 Pod定義中和 container 同級,按順序逐個執行,當所有的 Init 容器運行完成時,Kubernetes 才會啟動 Pod內的普通容器。

Init 容器與普通的容器非常像,除了如下幾點:

  • 他們總是運行到完成。
  • 上一個運行完成才會運行下一個。
  • 如果 Pod 的 Init 容器失敗,Kubernetes 會不斷地重啟該 Pod,直到 Init 容器成功為止,但是
  • 如果 Pod 對應的 restartPolicy 值為 Never,Kubernetes 則不會重新啟動 Pod。

他們總是運行到完成。
上一個運行完成才會運行下一個。
如果 Pod 的 Init 容器失敗,Kubernetes 會不斷地重啟該 Pod,直到 Init 容器成功為止,但是
如果 Pod 對應的 restartPolicy 值為 Never,Kubernetes 則不會重新啟動 Pod。

備注:
lifecycle 主要指的是容器在其運行環境中經歷的不同階段,以及 Kubernetes 如何管理和響應這些階段的能力。Kubernetes 提供了容器生命周期鉤子(Container Lifecycle Hooks),這是一種允許用戶指定在容器生命周期的特定點上運行代碼片段或命令的功能。
容器生命周期鉤子主要包括以下兩個部分:Poststart:這個鉤子在容器被創建之后立即調用,但需要注意的是,在鉤子執行的時候容器內的主進程尚未啟動。這可以用于執行一些初始化任務,比如建立文件系統的緩存目錄或其他類型的準備動作。Prestop:這個鉤子在發送信號給容器內的主進程之前調用,這意味著這是在容器被終止之前可以執行一些清理工作的最后機會。它常被用來做一些資源釋放的工作,比如關閉已經打開的數據庫連接或網絡連接等。

在生產環境中,為了應用的安全和優化鏡像的體積,業務鏡像一般不會安裝高危工具和并不常用的運維工具,比如 cur1、sed、awk、python 或 dig 等,同時建議使用非 root 用戶去啟動容器。但是某些應用啟動之前可能需要檢査依賴的服務有沒有成功運行,或者需要更高的權限去修改一些系統級的配置,而這些檢測或配置更改都是一次性的,所以在制作業務鏡像時沒有必要為了一次配置的變更去安裝一個配置工具,更沒有必要因為使用一次高權限而把整個鏡像改成以root 身份運行。
考慮到上述問題和需求,Kubernetes 引入了初始化容器的概念,Init 容器具有與應用容器分離的單

獨鏡像,其啟動相關代碼具有如下優勢:

  • Init 容器可以包含安裝過程中應用容器中不存在的實用工具或個性化代碼。
  • Init 容器可以安全地運行這些工具,避免這些工具導致應用鏡像的安全性降低。
  • Init 容器可以以 root 身份運行,執行一些高權限命令。
  • Init 容器相關操作執行完成后就會退出,不會給業務容器帶來安全隱患。

由于 Init 容器必須在應用容器啟動之前運行完成,因此 Init 容器提供了一種機制來阻塞或延遲應用容器的啟動,直到滿足一組先決條件,Pod內的所有應用容器才會并行啟動。

2:示例 1--延遲指定時間后啟動

創建一個 pod,initcontainers 指定初始化容器,command:["sh","-c","sleep 15"]表示初始化容器需要休眠 15 秒。

[root@k8s-master ~]# cat init01.yml?
apiVersion: v1
kind: Pod
metadata:
? creationTimestamp: null
? labels:
? ? run: initc01
? name: initc01
spec:
? terminationGracePeriodSeconds: 0
? containers:
? - image: nginx:1.7.9
? ? imagePullPolicy: IfNotPresent
? ? name: n1
? ? resources: {}
? initContainers:
? - name: initc01
? ? image: nginx:1.7.9
? ? imagePullPolicy: IfNotPresent
? ? command: ["sh","-c","sleep 15"]
? dnsPolicy: ClusterFirst
? restartPolicy: Never
status: {}

啟動pod,15秒后會發現pod開始啟動

[root@k8s-master ~]# kubectl create -f init01.yml?
pod/initc01 created
[root@k8s-master ~]# kubectl get pod
NAME ? ? ?READY ? STATUS ? ?RESTARTS ? AGE
initc01 ? 1/1 ? ? Running ? 0 ? ? ? ? ?3m44s

3:示例 2--使用初始化容器修改內核參數

在容器里修改內核參數,實際上修改的就是物理機的內核參數,為了安全性,一般不允許在容器里修改內核參數,Seccomp 代表安全計算(Secure computing)模式,seccomp 控制了容器能做哪些操作,添加 securitycontext 參數之后就可以修改內核參數了。
創建一個 pod,initcontainers 初始化容器里的 securitycontext:privileged:true 表示該容器具有特權,可以執行命令"sh","-c”,"/sbin/sysctl -w vm.swappiness=0",vm.swappiness 設置為8表示盡量少使用 swap 內存。

[root@k8s-master ~]# cat init02.yml?
apiVersion: v1
kind: Pod
metadata:
? creationTimestamp: null
? labels:
? ? run: initc02
? name: initc02
spec:
? terminationGracePeriodSeconds: 0
? containers:
? - image: nginx:1.7.9
? ? imagePullPolicy: IfNotPresent
? ? name: n1
? ? resources: {}
? initContainers:
? - name: initc02
? ? image: alpine
? ? imagePullPolicy: IfNotPresent
? ? command: ["sh","-c","/sbin/sysctl -w vm.swappiness=0"]
? ? securityContext:
? ? ? privileged: true
? dnsPolicy: ClusterFirst
? restartPolicy: Never
status: {}

[root@k8s-master ~]# kubectl create -f init02.yml?
pod/initc02 created
[root@k8s-master ~]# kubectl get pod
NAME ? ? ?READY ? STATUS ? ?RESTARTS ? AGE
initc01 ? 1/1 ? ? Running ? 0 ? ? ? ? ?20m
initc02 ? 1/1 ? ? Running ? 0 ? ? ? ? ?15s

查看pod中的容器

[root@k8s-master ~]# kubectl get pod -o wide
NAME ? ? ?READY ? STATUS ? ?RESTARTS ? AGE ? IP ? ? ? ? ? ? ?NODE ? ? ? ? NOMINATED NODE ? READINESS GATES
initc01 ? 1/1 ? ? Running ? 0 ? ? ? ? ?20m ? 10.244.85.193 ? k8s-node01 ? <none> ? ? ? ? ? <none>
initc02 ? 1/1 ? ? Running ? 0 ? ? ? ? ?24s ? 10.244.58.195 ? k8s-node02 ? <none> ? ? ? ? ? <none>

查看節點機器上的值是否為0

[root@k8s-node02 ~]# cat /proc/sys/vm/swappiness
0

4:示例 3--等待依賴服務啟動

有時某些服務需要依賴其他組件才能啟動,比如后端應用需要數據庫啟動之后,應用才能正常啟動,此時需要檢測數據庫實例是否正常,等待數據庫可以正常使用時,在啟動后端應用,此時可以使用初始化容器進行控制。

(1)創建第一個 Pod

該 Pod 內要依賴兩個條件才能啟動,一個是利用 busybox 容器檢測 redis-service 服務是否生成第二個是檢測 mysql-server 服務是否生成。

[root@k8s-master ~]# cat myapp.yaml?
apiVersion: v1
kind: Pod
metadata:
? name: nginx
? labels:
? ? name: nginx
spec:
? containers:
? - name: nginx
? ? image: nginx:1.7.9
? ? ports:
? ? - containerPort: 80
? initContainers:
? ? - name: init-redis
? ? ? image: busybox:1.28
? ? ? command: ['sh', '-c', 'until nslookup redis-service; do echo waiting for nginx01; sleep 2; done;']
? ? - name: init-mysql
? ? ? image: busybox:1.28
? ? ? command: ['sh', '-c', 'until nslookup mysql-service; do echo waiting for nginx02; sleep 2; done;']

[root@k8s-master ~]# kubectl create -f myapp.yaml?
pod/nginx created
[root@k8s-master ~]# kubectl get pod
NAME ? ?READY ? STATUS ? ? RESTARTS ? AGE
nginx ? 0/1 ? ? Init:0/2 ? 0 ? ? ? ? ?4s

(2)創建第一個被依賴的service

[root@k8s-master ~]# cat redis-deployment.yaml?
apiVersion: apps/v1
kind: Deployment
metadata:
? labels:
? ? app: redis
? name: redis
spec:
? replicas: 1
? selector:
? ? matchLabels:
? ? ? app: redis
? template:
? ? metadata:
? ? ? labels:
? ? ? ? app: redis
? ? spec:
? ? ? containers:
? ? ? ? - image: redis:5.0
? ? ? ? ? imagePullPolicy: IfNotPresent
? ? ? ? ? name: redis
---
apiVersion: v1
kind: Service
metadata:
? labels:
? ? app: redis
? name: redis-service
spec:
? ports:
? ? - port: 6379
? ? ? protocol: TCP
? ? ? targetPort: 6379
? selector:
? ? app: redis
? type: NodePort

[root@k8s-master ~]# kubectl create -f ?redis-deployment.yaml?
deployment.apps/redis created
service/redis-service created
[root@k8s-master ~]# kubectl get svc
NAME ? ? ? ? ? ?TYPE ? ? ? ?CLUSTER-IP ? ? ?EXTERNAL-IP ? PORT(S) ? ? ? ? ?AGE
kubernetes ? ? ?ClusterIP ? 10.96.0.1 ? ? ? <none> ? ? ? ?443/TCP ? ? ? ? ?3d19h
redis-service ? NodePort ? ?10.103.135.15 ? <none> ? ? ? ?6379:30083/TCP ? 6s

[root@k8s-master ~]# kubectl get pod
NAME ? ? ? ? ? ? ? ? ? ? READY ? STATUS ? ? RESTARTS ? AGE
nginx ? ? ? ? ? ? ? ? ? ?0/1 ? ? Init:1/2 ? 0 ? ? ? ? ?2m24s
redis-56bcf55554-5ww9w ? 1/1 ? ? Running ? ?0 ? ? ? ? ?24s

(3)創建第二個被依賴的service

[root@k8s-master ~]# cat mysql-deployment.yaml?
apiVersion: apps/v1
kind: Deployment
metadata:
? labels:
? ? app: mysql
? name: mysql
spec:
? replicas: 1
? selector:
? ? matchLabels:
? ? ? app: mysql
? template:
? ? metadata:
? ? ? labels:
? ? ? ? app: mysql
? ? spec:
? ? ? containers:
? ? ? ? - env:
? ? ? ? ? ? - name: MYSQL_ROOT_PASSWORD
? ? ? ? ? ? ? value: 'moonfdd'
? ? ? ? ? image: 'mysql:8.0'
? ? ? ? ? imagePullPolicy: IfNotPresent
? ? ? ? ? name: mysql
? ? ? ? ? volumeMounts:
? ? ? ? ? ? - mountPath: /var/lib/mysql
? ? ? ? ? ? ? name: volv
? ? ? volumes:
? ? ? ? - hostPath:
? ? ? ? ? ? path: /root/k8s/moonfdd/mysql/var/lib/mysql
? ? ? ? ? ? type: DirectoryOrCreate
? ? ? ? ? name: volv
---
apiVersion: v1
kind: Service
metadata:
? labels:
? ? app: mysql
? name: mysql-service
spec:
? ports:
? ? - port: 3306
? ? ? protocol: TCP
? ? ? targetPort: 3306
? selector:
? ? app: mysql
? type: NodePort

[root@k8s-master ~]# kubectl create -f mysql-deployment.yaml?
deployment.apps/mysql created
service/mysql-service created

[root@k8s-master ~]# kubectl get svc
NAME ? ? ? ? ? ?TYPE ? ? ? ?CLUSTER-IP ? ? ?EXTERNAL-IP ? PORT(S) ? ? ? ? ?AGE
kubernetes ? ? ?ClusterIP ? 10.96.0.1 ? ? ? <none> ? ? ? ?443/TCP ? ? ? ? ?3d20h
mysql-service ? NodePort ? ?10.102.9.40 ? ? <none> ? ? ? ?3306:32586/TCP ? 17s
redis-service ? NodePort ? ?10.103.135.15 ? <none> ? ? ? ?6379:30083/TCP ? 29m

[root@k8s-master ~]# kubectl get pod
NAME ? ? ? ? ? ? ? ? ? ? READY ? STATUS ? ?RESTARTS ? AGE
mysql-7f5d669b6c-xcg5k ? 1/1 ? ? Running ? 0 ? ? ? ? ?33s
nginx ? ? ? ? ? ? ? ? ? ?1/1 ? ? Running ? 0 ? ? ? ? ?31m
redis-56bcf55554-5ww9w ? 1/1 ? ? Running ? 0 ? ? ? ? ?29m

到這里可以發現,當把 redis-service 和 mysq1-service 兩個服務創建出來后,nginx 的 Pod 就正常運行了。

4:pause容器

在 Kubernetes 中,pause 容器并不是指暫停容器的執行,而是指一個特殊的輔助容器,它被用于每個 Pod 以幫助實現網絡命名空間。pause 容器是 Kubernetes 中每個 Pod 的第一個容器,它的主要作用是
作為 Pod 內所有其他容器共享網絡命名空間的基礎。每個 Kubernetes Pod 都有一個 pause 容器,它是 Pod 的第一個容器,也是唯一必須運行的容器即使 Pod 中的其他容器都停止了,只要 pause 容器還在運行,Pod 就不會被 Kubernetes 認為是完全停止的。

(1)pause 容器的作用

網絡命名空間:pause 容器為 Pod 內的所有容器提供了一個共享的網絡命名空間。這意味著 Pod 內的所有容器都共享同一個 IP 地址和端口空間,從而使得它們可以直接通過 localhost 或者其他指定方式相互通信。

網絡接口:pause 容器負責設置 Pod 的網絡接口,使得 Pod 內的容器能夠通過這個接口訪問外部網絡。

穩定性:如果 Pod 中的所有聲明的容器都被刪除或停止,pause 容器將保持運行,從而保證 Pod 的網絡命名空間不會丟失。這也意味著 Pod 的網絡配置仍然保留,直到整個 Pod 被刪除。

生命周期管理:pause 容器是一個非常簡單的容器,其鏡像只包含一個命令/pause,該命令實際上是-個無限循環,保持容器處于運行狀態。它不執行任何業務邏輯,僅僅是作為 Pod 網絡基礎設施的-部分。

(2)使用 pause 容器的好處

  • 簡化了 Pod 內的網絡配置。
  • 提高了 Pod 網絡的一致性。
  • 減少了管理 Pod 網絡復雜性的開銷。

總的來說,pause 容器對于實現 Kubernetes Pod 的網絡功能至關重要,它是 Kubernetes 網絡模型的一個核心組成部分。

(3)Pause 容器實現

Pod 里的多個容器怎么去共享網絡?下面是個例子:
比如說現在有一個 Pod,其中包含了一個容器 A 和一個容器 B,它們兩個就要共享 NetworkNamespace。在 Kubernetes 里的解法是這樣的:它會在每個 Pod 里,額外起一個 Infra(基礎)container 小容器來共享整個Pod 的 Network Namespace。
Infra container 是一個非常小的容器,大概 700KB 左右,是一個( 語言寫的、永遠處于 “暫停”狀態的容器。由于有了這樣一個 Infra container 之后,其他所有容器都會通過 Join Namespace的方式加入到 Infra container 的Network Namespace 中.

所以說一個 Pod 里面的所有容器,它們看到的網絡視圖是完全一樣的。即:它們看到的網絡設備IP 地址、Mac 地址等等,跟網絡相關的信息,其實全是一份,這一份都來自于 Pod 第一次創建的這個Infra container。這就是 Pod 解決網絡共享的一個解法

在 Pod 里面,一定有一個 IP 地址,是這個 Pod 的 Network Namespace 對應的地址,也是這個Infra container 的 IP 地址。所以大家看到的都是同一份,而其他所有網絡資源,都是一個 Pod份,并且被 Pod 中的所有容器共享。這就是Pod 的網絡實現方式。

由于需要有一個相當于中間的容器存在,所以整個 Pod 里面,必然是 Infra container 第一個啟動。并且整個 Pod 的生命周期是等同于 Infra container 的生命周期的,與容器 A 和 B 是無關的。這也是為什么在 Kubernetes 里面,它是允許去單獨更新 Pod 里的某一個鏡像的,即:做這個操作,整個 Pod 不會重建,也不會重啟,這是非常重要的一個設計。

査看 nginx 的 Pod 運行在的主機

[root@k8s-master ~]# kubectl get pod -o wide
NAME ? ? ? ? ? ? ? ? ? ? READY ? STATUS ? ?RESTARTS ? AGE ? IP ? ? ? ? ? ? ?NODE ? ? ? ? NOMINATED NODE ? READINESS GATES
mysql-7f5d669b6c-xcg5k ? 1/1 ? ? Running ? 0 ? ? ? ? ?52m ? 10.244.85.195 ? k8s-node01 ? <none> ? ? ? ? ? <none>
nginx ? ? ? ? ? ? ? ? ? ?1/1 ? ? Running ? 0 ? ? ? ? ?83m ? 10.244.85.194 ? k8s-node01 ? <none> ? ? ? ? ? <none>
redis-56bcf55554-5ww9w ? 1/1 ? ? Running ? 0 ? ? ? ? ?81m ? 10.244.58.196 ? k8s-node02 ? <none> ? ? ? ? ? <none>

在node01主機上查看pod中的pause容器

[root@k8s-node01 ~]# docker ps | grep nginx
e8bf858f89f7 ? 84581e99d807 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"nginx -g 'daemon of…" ? 53 minutes ago ? ? ?Up 53 minutes ? ? ? ? ? ? ? ?k8s_nginx_nginx_default_c1238bdc-166b-4450-985d-1f858c8735d9_0
75ca92d09c39 ? registry.aliyuncs.com/google_containers/pause:3.6 ? "/pause" ? ? ? ? ? ? ? ? ?About an hour ago ? Up About an hour ? ? ? ? ? ? k8s_POD_nginx_default_c1238bdc-166b-4450-985d-1f858c8735d9_0

二:臨時容器 Ephemeral Containers

在生產環境中,為例優化鏡像體積和提高鏡像的安全性,并不會在容器中安裝太多高危工具,比如culr ,wget,dig 以及常用的net-tools等。這樣做雖然提高了鏡像的安全性,但是也帶來了一些不便,比如無法査看容器內的進程情況、無法査看容器內的鏈接情況、服務出了問題無法很方便的進行排査等。因為上述操作并非經常使用,所以我們并沒有必要從一開始就安裝這些工具,但是等到用他們的時候再安裝也是一件很麻煩的事情,那么我們該如何處理這個問題呢?
為了解決這類問題,在 1.16 版本后,Kubernetes 引入了 Ephemeral containers 的概念,可以不用安裝第三方工具即可實現在線 Debug 操作。

1.臨時容器的概念

臨時容器與其他容器的不同之處在于,臨時容器是被臨時添加到 Pod 上,用于在線調試應用的,他永遠不會自動重啟,因此不適用與構建應用程序,臨時容器的聲明和普通容器類似,但是臨時容器沒有端口配置,因此不能使用像 ports、livenessprobe、readnessProbe、resources這樣的字段,當然,臨時容器只是用來調試程序的,它的狀態不會影響其他正常容器,所以它并不需要這些字段配置。
臨時容器使用 API 中一種特殊的 Ephemeral containers 處理器進行創建,而不是直接添加到pod.spec 字段,因此無法使用 kubectl edit 來添加臨時容器,與常規容器一樣,將臨時容器添加到 Pod后,將不能更改或刪除臨時容器,但是當添加了臨時容器的 Pod 重啟后,臨時容器就會被銷毀。
因為臨時容器是為了調試程序而設計的,所以在添加臨時容器時,最好使用一個包含所有常用工具的鏡像進行創建。當業務容器崩潰或容器鏡像不包含調試工具而導致 kubectl exec 不可用時,臨時容器對于交互故障排査和在線 Debug 很有用。尤其是在使用像不包含任何 shel1 和其他工具的 destroless 鏡像作為基礎鏡像時,雖然可以減少攻擊面和漏洞,但對于問題的排査會變得尤為棘手,此時臨時容器就可以發揮很大的作用,帶來諸多便利性。

2.臨時容器的使用

(1)創建一個nginx的資源清單

[root@k8s-master ~]# cat pod-tomcat.yaml?
apiVersion: v1
kind: Pod
metadata:
? name: nginx-test
? namespace: default
? labels:
? ? app: ?nginx
spec:
? containers:
? - name: ?nginx-java
? ? ports:
? ? - containerPort: 80
? ? image: nginx:1.7.9
? ? imagePullPolicy: IfNotPresent

(2)創建pod

[root@k8s-master ~]# kubectl get pod
NAME ? ? ? ? ? ? ? ? ? ? READY ? STATUS ? ?RESTARTS ? AGE
mysql-7f5d669b6c-xcg5k ? 1/1 ? ? Running ? 0 ? ? ? ? ?62m
nginx ? ? ? ? ? ? ? ? ? ?1/1 ? ? Running ? 0 ? ? ? ? ?93m
nginx-test ? ? ? ? ? ? ? 1/1 ? ? Running ? 0 ? ? ? ? ?10s

(3)為nginx的pod容器創建臨時容器

[root@k8s-master ~]# kubectl debug -it nginx-test --image=busybox:1.28 --target=nginx-java
Targeting container "nginx-java". If you don't see processes from this container it may be because the container runtime doesn't support this feature.
Defaulting debug container name to debugger-nxf4t.
If you don't see a command prompt, try pressing enter.
/ # ip a

(4)查看nginx-tesst這個pod是否

[root@k8s-master ~]# kubectl describe pods nginx-test
Name: ? ? ? ? nginx-test
Namespace: ? ?default
Priority: ? ? 0
Node: ? ? ? ? k8s-node02/192.168.10.103
Start Time: ? Fri, 11 Jul 2025 11:23:42 +0800
Labels: ? ? ? app=nginx
Annotations: ?cni.projectcalico.org/containerID: 3e427a8c5fd207493006ed7ba047fb43cac64970b39964df611b290b3186ec67
? ? ? ? ? ? ? cni.projectcalico.org/podIP: 10.244.58.197/32
? ? ? ? ? ? ? cni.projectcalico.org/podIPs: 10.244.58.197/32
Status: ? ? ? Running
IP: ? ? ? ? ? 10.244.58.197
IPs:
? IP: ?10.244.58.197
Containers:
? nginx-java:
? ? Container ID: ? docker://085aed38e78b961e1ba697465aa88a5ba4a908132cbe7afa58dd14dfeaf2f13c
? ? Image: ? ? ? ? ?nginx:1.7.9
? ? Image ID: ? ? ? docker://sha256:84581e99d807a703c9c03bd1a31cd9621815155ac72a7365fd02311264512656
? ? Port: ? ? ? ? ? 80/TCP
? ? Host Port: ? ? ?0/TCP
? ? State: ? ? ? ? ?Running
? ? ? Started: ? ? ?Fri, 11 Jul 2025 11:23:44 +0800
? ? Ready: ? ? ? ? ?True
? ? Restart Count: ?0
? ? Environment: ? ?<none>
? ? Mounts:
? ? ? /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-nwjj4 (ro)
Ephemeral Containers:
? debugger-nxf4t:
? ? Container ID: ? docker://193c71245c23d89fe296267b5cfca0e5a613f4c5d27c206fdbdddbeac153ee41
? ? Image: ? ? ? ? ?busybox:1.28
? ? Image ID: ? ? ? docker://sha256:8c811b4aec35f259572d0f79207bc0678df4c736eeec50bc9fec37ed936a472a
? ? Port: ? ? ? ? ? <none>

三:自動擴縮容HPA

在集群安裝的過程中,我們可以安裝一個叫 Metrics Server 的組件,該組件在集群中負責采集 Pod和 Node 的度量值指標,比如 Pod 的 CPU、內存使用率和節點的內存、CPU 使用率,而且安裝的 Dashboard可以展示 CPU、內存信息也是依靠 Metrics server 的。當然,該組件不僅僅是用來展示數據的,還可以使用 Metrics Server 提供的數據結合 Kubernetes 的 HPA 功能實現 Pod 的自動擴縮容。

1:什么是 HPA

HPA(Horizontal Pod Autoscaler,水平 Pod 自動伸縮器)可以根據觀察到的 CPU、內存使用率或自定義度量標準來自動擴展或縮容 Pod 的數量。注意 HPA 不適用于無法縮放的對象,比如 Daemonset
HPA 控制器會定期調整 RC或 Deployment 的副本數,以使觀察到的平均 CPU 利用率與用戶指定的目標相匹配。

HPA 需要 Metrics Server 獲取度量指標,如果已經部署了 Metrics Server,本節的實踐部就分無須再次安裝 Metrics Server。如果沒有安裝 Metrics Server,可以參考其他實驗文檔自行部署。

2:HPA 的工作原理

  • HPA 根據觀察到的 CPU、內存使用率或自定義度量標準來自動擴展或縮容 Pod 的數量。
  • HPA 控制器會定期調整 RC(Replication controller)或 Deployment 的副本數,以使觀察到的平均 CPU 利用率(或其他度量標準)與用戶指定的目標相匹配。
  • HPA 需要 Metrics Server 獲取度量指標,Metrics Server 負責采集 Pod 和 Node 的度量值指標,如 CPU、內存使用率等。

3:HPA 的工作流程

  • 配置 HPA:使用 kubectl autoscale 命令為 Deployment、Replicaset 或 statefulset 等資
  • 源創建 HPA 對象,并指定目標 CPU 利用率、最小副本數和最大副本數。
  • 度量指標采集: Metrics Server 定期采集 Pod 和 Node 的度量值指標,并將這些數據提供給 HPA控制器。
  • 伸縮決策:HPA 控制器根據當前 Pod 的度量指標和目標利用率進行比較,如果當前利用率高于目標利用率,則增加 Pod 副本數;如果當前利用率低于目標利用率,則減少 Pod 副本數(在最小副本數和最大副本數之間調整)。
  • Pod 伸縮:Kubernetes 根據 HPA 控制器的決策自動調整 Pod 的副本數,以實現自動擴縮容。

4:HPA 的應用場景

  • 應對流量波動:在 web 服務中,流量可能會隨時間變化而波動。HPA 可以根據流量變化自動調整Pod 副本數,以確保服務的穩定性和響應速度。
  • 資源優化:通過自動擴縮容,HPA可以在保證服務質量的同時最大化資源利用率,降低運營成本。

5:HPA 實踐--實現 web 服務器的自動伸縮特性

在生產環境中,總會有一些意想不到的事情發生,比如公司網站流量突然升高,此時之前創建的 Pod已不足以支撐所有的訪問,而運維人員也不可能 24 小時守著業務服務,這時就可以通過配置 HPA,實現負載過高的情況下自動擴容 Pod 副本數以分攤高并發的流量,當流量恢復正常后,HPA 會自動縮減 Pod 的數量。

本節將測試實現一個 web 服務器的自動伸縮特性,具體步驟如下:

(1)首先用Deployment 啟動一個Nginx 服務(須配置 requests 參數):

[root@k8s-master ~]# cat nginx-deployment.yaml?
apiVersion: apps/v1
kind: Deployment
metadata:
? name: nginx-server
? labels:
? ? name: nginx-server
spec:
? replicas: 2
? selector:
? ? matchLabels:
? ? ? app: nginx
? template:
? ? metadata:
? ? ? labels:
? ? ? ? app: nginx
? ? spec:
? ? ? containers:
? ? ? ? - name: nginx
? ? ? ? ? resources:
? ? ? ? ? ? requests:
? ? ? ? ? ? ? cpu: 10m
? ? ? ? ? image: nginx:1.7.9
? ? ? ? ? ports:
? ? ? ? ? ? - name: nginx
? ? ? ? ? ? ? containerPort: 80

root@k8s-master ~]# kubectl create -f nginx-deployment.yaml?
deployment.apps/nginx-server created

(2)配置nginx-server的service

[root@k8s-master ~]# kubectl expose deployment nginx-server --port=80
service/nginx-server exposed

(3)使用kubectl autoscale命令創建HPA

[root@k8s-master ~]# kubectl autoscale deployment nginx-server --cpu-percent=10 --min=1 --max=10
horizontalpodautoscaler.autoscaling/nginx-server autoscaled

此 HPA 將根據 CPU的使用率自動增加和減少副本數量,上述設置的是 CPU 使用率超過 10%(--cpu-percent 參數指定)就會增加 Pod 的數量,以保持所有 Pod 的平均 CPU 利用率為 10%,允許最大的 Pod 數量為10(--max),最少的 Pod 數為1(--min)。

(4)查看當前 HPA 的狀態

因為未對其發送任何請求,所以當前 CPU 使用率為 0%

[root@k8s-master ~]# kubectl get hpa
NAME ? ? ? ? ? REFERENCE ? ? ? ? ? ? ? ? TARGETS ? MINPODS ? MAXPODS ? REPLICAS ? AGE
nginx-server ? Deployment/nginx-server ? 0%/10% ? ?1 ? ? ? ? 10 ? ? ? ?2 ? ? ? ? ?74s

(5)查看當前nginx的service地址

[root@k8s-master ~]# kubectl get service
NAME ? ? ? ? ? TYPE ? ? ? ?CLUSTER-IP ? ? ?EXTERNAL-IP ? PORT(S) ? AGE
kubernetes ? ? ClusterIP ? 10.96.0.1 ? ? ? <none> ? ? ? ?443/TCP ? 3d21h
nginx-server ? ClusterIP ? 10.100.216.91 ? <none> ? ? ? ?80/TCP ? ?3m13s

(6)壓力測試

新開一個終端,使用-個“死”循環或其他壓測工具模擬訪問該 Service,從而增加該 Pod的負載

[root@k8s-node02 ~]# while true;do wget -q -O- http://10.100.216.91 >/dev/null;done
?

備注:
-q 是不輸出 wget 的頭信息。
-0-(大寫字母 0)選項表示將下載的內容輸出到標準輸出(通常是終端),而不是保存到文件。

(7)查看HPA 狀態

等待一分鐘左右,再次査看 HPA,可以看到 Pod 的 CPU 已經升高。

[root@k8s-master ~]# kubectl get hpa
NAME ? ? ? ? ? REFERENCE ? ? ? ? ? ? ? ? TARGETS ? MINPODS ? MAXPODS ? REPLICAS ? AGE
nginx-server ? Deployment/nginx-server ? 45%/10% ? 1 ? ? ? ? 10 ? ? ? ?2 ? ? ? ? ?4m6s

(8)再次查看pod,可以看到已經擴容

[root@k8s-master ~]# kubectl get pod
NAME ? ? ? ? ? ? ? ? ? ? ? ? ? ?READY ? STATUS ? ?RESTARTS ? AGE
nginx-server-6ddcfd4c8f-5sjvc ? 1/1 ? ? Running ? 0 ? ? ? ? ?31s
nginx-server-6ddcfd4c8f-7r9jl ? 1/1 ? ? Running ? 0 ? ? ? ? ?7m7s
nginx-server-6ddcfd4c8f-ndrnz ? 1/1 ? ? Running ? 0 ? ? ? ? ?46s
nginx-server-6ddcfd4c8f-nr2dw ? 1/1 ? ? Running ? 0 ? ? ? ? ?7m7s
nginx-server-6ddcfd4c8f-p9pnj ? 1/1 ? ? Running ? 0 ? ? ? ? ?61s
nginx-server-6ddcfd4c8f-qjbq7 ? 1/1 ? ? Running ? 0 ? ? ? ? ?61s
nginx-server-6ddcfd4c8f-rhkn8 ? 1/1 ? ? Running ? 0 ? ? ? ? ?46s
nginx-server-6ddcfd4c8f-vnpjm ? 1/1 ? ? Running ? 0 ? ? ? ? ?46s
nginx-server-6ddcfd4c8f-vzchv ? 1/1 ? ? Running ? 0 ? ? ? ? ?31s
nginx-server-6ddcfd4c8f-z9ts9 ? 1/1 ? ? Running ? 0 ? ? ? ? ?46s

(8)停止壓力測試,再次查看HPA狀態

[root@k8s-master ~]# kubectl get hpa
NAME ? ? ? ? ? REFERENCE ? ? ? ? ? ? ? ? TARGETS ? MINPODS ? MAXPODS ? REPLICAS ? AGE
nginx-server ? Deployment/nginx-server ? 0%/10% ? ?1 ? ? ? ? 10 ? ? ? ?10 ? ? ? ? 6m4s

(9)查看pod的副本數

[root@k8s-master ~]# kubectl get pod
NAME ? ? ? ? ? ? ? ? ? ? ? ? ? ?READY ? STATUS ? ?RESTARTS ? AGE
nginx-server-6ddcfd4c8f-nr2dw ? 1/1 ? ? Running ? 0 ? ? ? ? ?14m

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/914004.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/914004.shtml
英文地址,請注明出處:http://en.pswp.cn/news/914004.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

服務器機柜與網絡機柜各自的優勢

一、服務器機柜優勢服務器機柜設計有強大的承重結構&#xff0c;能承受大量服務器設備堆疊產生的重量&#xff0c;保障設備安全穩定放置&#xff0c;防止因承重不足導致機柜變形甚至設備損壞&#xff0c;同時&#xff0c;服務器在運行的過程中&#xff0c;會產生大量熱量&#…

AI技術通過提示詞工程(Prompt Engineering)正在深度重塑職場生態和行業格局,這種變革不僅體現在效率提升,更在重構人機協作模式。

AI技術通過提示詞工程&#xff08;Prompt Engineering&#xff09;正在深度重塑職場生態和行業格局&#xff0c;這種變革不僅體現在效率提升&#xff0c;更在重構人機協作模式。以下是關鍵影響維度及未來趨勢分析&#xff1a;一、職場效率革命&#xff08;效率提升300%場景&…

Hugging Face 開源機器人 Reachy Mini 開啟預定

我們最新的開源機器人 Reachy Mini 正式亮相 &#x1f389; 這款富有表現力的開源機器人由 Pollen Robotics 與 Hugging Face 聯合打造&#xff0c;專為人機交互、創意編程和 AI 實驗而設計。它價格親民&#xff0c;體積小巧&#xff0c;卻蘊藏著無限可能。來自全球的各個年齡段…

vue3+node.js+mysql寫接口(二)

目錄 一、產品模塊(products表) 1.1、添加產品(/adminapi/product/add) 1.2、產品列表(/adminapi/product/list) 1.3、編輯產品(/adminapi/product/update) 1.4、首頁產品聯動 二、前臺模塊 2.1、路由配置 2.2、NavBar組件 2.3、新聞搜索 2.4、新聞選項卡 2.5、新聞…

解析LLM層裁剪:Qwen實戰指南

怎么實現對LLM 部分層裁剪輸出結果 Qwen 7b 是28層MLP,28頭 Qwen 14b 是48層MLP,40頭,詞向量維度:5120 模型加載部分 from transformers import AutoTokenizer, AutoModelForCausalLM

【AI大模型】深度學習正則化技術:Batch Normalization (BatchNorm) 詳解

1. 為什么需要 BatchNorm&#xff1f; - 問題的根源&#xff1a;Internal Covariate Shift (ICS)問題描述&#xff1a; 深度神經網絡在訓練過程中&#xff0c;隨著網絡層數的加深&#xff0c;前面層參數的微小更新會導致后面層輸入數據的分布發生顯著變化。這種現象稱為內部協變…

20.緩存問題與解決方案詳解教程

文章目錄1. 緩存基礎概念1.1 什么是緩存1.2 緩存的作用1.3 常見的緩存類型1.4 緩存架構示例2. 緩存雪崩 (Cache Avalanche)2.1 什么是緩存雪崩2.2 緩存雪崩的原因2.3 緩存雪崩的危害2.4 緩存雪崩的解決方案方案1&#xff1a;設置隨機過期時間方案2&#xff1a;緩存集群和主從復…

(滿滿的坑LLAMA3使用申請被拒絕rejected)利用huggingface導入LLAMA3模型

文章目錄前言坑后續前言 大家都知道&#xff0c;使用huggingface導入大模型是使用如下辦法 from transformers import AutoModelForCausalLM, AutoTokenizermodel_name "Qwen/Qwen2.5-7B-Instruct"#要導入的大模型名稱。model AutoModelForCausalLM.from_pretrai…

大規模集群下 Prometheus 監控架構實戰經驗分享

大規模集群下 Prometheus 監控架構實戰經驗分享 1 業務場景描述 在互聯網金融業務發展過程中&#xff0c;我們需要對數千臺主機、上萬容器與微服務實例進行指標監控&#xff0c;并統計歷史數據以支持 SLA 報表、告警與容量規劃。傳統監控系統面臨以下挑戰&#xff1a; 實例動態…

主流消息隊列技術總結和對比

消息隊列&#xff08;Message Queue&#xff0c;簡稱 MQ&#xff09;作為構建分布式互聯網應用的關鍵組件&#xff0c;松耦合的架構設計能顯著提升系統的可用性與可擴展性。在分布式系統中扮演著至關重要的角色&#xff0c;主要承擔著實現異步消息傳遞、應用解耦、流量削峰以及…

數據結構 順序表(3)---順序表的應用

在之間的兩篇文章中&#xff0c;我們著重講了順序表及順序表的實現。今天這篇文章我們將簡單講解關于順序表的三個算法題。這三個題也都屬于力扣上的經典例題。1.例題1:移除元素例題來源(力扣) : https://leetcode.cn/problems/remove-element/description/這是一道數組操作算法…

逆向入門(9)匯編篇-bound指令的學習

看程序的時候碰到這么一行沒見過的代碼&#xff0c;簡單記錄一下 00427AC8 |. 6215 3C7B4200 |bound edx,qword ptr ds:[0x427B3C]這里是用到了bound指令&#xff0c;這是 x86 匯編中的指令&#xff0c;用于檢查數組索引是否在有效范圍內。 指令解析 bound edx, qword ptr ds…

【web應用】若依框架中,使用Echarts導出報表為PDF文件

文章目錄前言一、Echarts準備工作1、查看是否安裝了Echarts2、Echarts導入script 中3、使用Echarts創建圖表二、報表制作打印html2canvas和jsPDF準備工作1、安裝html2canvas和jsPDF依賴包2、html2canvas和jsPDF引用到script中3、制作并打印報表三、導出結果前言 若依框架前端中…

優選算法 --(雙指針算法 1~8)

引言&#xff1a;此專欄為記錄算法學習&#xff0c;本專題作為算法學習的第一部分&#xff0c;優選算法專題共計100題&#xff0c;分為不同小模塊進行&#xff0c;算法學習需堅持積累&#xff0c;時代不會辜負長期主義者&#xff0c;僅以此句&#xff0c;與君共勉。 講解算法分…

XRDMatch代碼復現與分析報告

XRDMatch代碼復現與分析報告 1. 項目概述 XRDMatch是一個用于X射線衍射(XRD)數據匹配和分析的開源工具,由zhengwan-chem開發并托管在GitHub上。本項目旨在復現XRDMatch的核心功能,并對其實現進行詳細分析。 X射線衍射是材料科學中用于確定晶體結構的重要技術,通過分析衍射…

SpringAI×Ollama:Java生態無縫集成本地大模型實踐指南

摘要 隨著大語言模型(LLM)的普及,數據隱私和技術棧統一性成為企業級AI應用的核心挑戰。本文系統闡述如何通過SpringAI框架與Ollama本地化模型引擎的結合,構建安全高效的生成式AI應用。通過實戰案例解析配置優化、流式響應、工具調用等關鍵技術,為Java開發者提供零Python依…

從采購申請到報廢核銷:如何用數字化縫合企業物資管理的“斷點”?

在企業的日常運營中&#xff0c;物資管理是一項至關重要的工作。從采購申請到物資的入庫、使用&#xff0c;再到最終的報廢核銷&#xff0c;這一系列流程就像一條長長的鏈條&#xff0c;環環相扣。然而&#xff0c;在傳統管理模式下&#xff0c;這條鏈條上卻存在著諸多“斷點”…

AVL平衡二叉樹

01. 初始AVL樹 AVL樹是最早發明的自平衡二叉搜索樹。在AVL樹中&#xff0c;任何節點的兩個子樹的高度差&#xff08;平衡因子&#xff09;最多為1&#xff0c;這使得AVL樹能夠保持較好的平衡性&#xff0c;從而保證查找、插入和刪除操作的時間復雜度都是O(log n)。包含n個節點…

教育行業可以采用Html5全鏈路對視頻進行加密?有什么優勢?

文章目錄前言一、什么是Html5加密&#xff1f;二、使用Html5對視頻加密的好處三、如何采用Html5全鏈路對視頻進行加密&#xff1f;四、教育行業采用Html5全鏈路視頻加密有什么優勢&#xff1f;總結前言 面對優質課程盜錄傳播的行業痛點&#xff0c;教育機構如何守護核心知識產…

Vue3 tailwindcss

1、安裝tailwindcsspnpm i -D tailwindcss postcss autoprefixer # yarn add -D tailwindcss postcss autoprefixer # npm i -D tailwindcss postcss autoprefixer2、 創建TailwindCSS配置文件npx tailwindcss init -ptailwind.config.js/** type {import(tailwindcss).Config}…