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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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}…