高级调度1

一.初始化容器InitContainer

1.定义

initContainers 是 Kubernetes Pod 中的一个功能,用于在主容器启动之前执行初始化任务。initContainers 与主容器的作用不同,它们在主容器启动之前运行,并且可以完成准备工作,如下载依赖、配置文件等。

2.为什么使用InitContainer

initContainers 的作用是执行必要的初始化任务,确保主容器能够在预期的状态下启动。这些任务包括:

准备环境:如下载或解压文件、配置数据等。

执行依赖:如等待外部服务或数据库准备好。

初始化数据:如设置数据库表结构或填充初始数据。

它们在主容器启动之前完成,确保主容器能够在一个稳定的环境中运行。

具体示例:延迟指定时间后启动,修改内核参数,等待依赖服务启动

3.优势 

  1. 隔离初始化任务:将初始化逻辑与主容器的业务逻辑分开,有助于保持主容器的简单性和专注于其核心功能。
  2. 确保初始化完成initContainers 在主容器启动之前完成所有定义的任务。如果初始化失败,Pod 将不会启动主容器,确保主容器不会在不准备好的情况下运行。
  3. 依赖处理:可以处理主容器所需的外部依赖或前置条件,例如等待数据库就绪或下载配置文件。这些操作可以在主容器之前完成,避免主容器启动后遇到依赖问题。
  4. 数据共享:通过挂载 Volume,initContainers 可以创建或初始化共享数据,这些数据可以被主容器使用。这对于数据的预处理或配置文件的准备特别有用。
  5. 重用:可以使用 initContainers 执行通用的初始化任务,这些任务可以在多个 Pod 中重用,避免重复编写相同的逻辑。
  6. 灵活性:能够使用不同的镜像和命令来完成初始化任务,提供了更多的灵活性和控制力。
  7. 清晰的失败处理:如果 initContainers 中的任务失败,Pod 将不会进入运行状态,这有助于提前发现和解决问题,而不是让主容器在错误的环境中启动。

 4.实例1——延迟指定时间后启动

(1)创建一个pod,initContainers指定初始化容器,command : [ "sh","-c","sleep 15"] 表示初始化容器需要休眠15秒。

[root@k8s-master ~]# vim 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: {}

(2)创建pod

[root@k8s-master ~]# ku create -f init01.yml

 (3)不断查看15秒后发现pod开启启动

[root@k8s-master ~]# ku get pod
NAME      READY   STATUS     RESTARTS   AGE
initc01   0/1     Init:0/1   0          6s
[root@k8s-master ~]# ku get pod
NAME      READY   STATUS    RESTARTS   AGE
initc01   1/1     Running   0          22s

5.实例2——使用初始化容器 

        在容器里修改内核参数,实际上修改的就是物理机的内核参数,为了安全性,一般不允许在容器里修改内核参数,Seccomp代表安全计算(SecureComputing)模式,seccomp控制了容器能做哪些操作,添加securityContext参数之后就可以修改内核参数了。

        创建一个pod,initcontainers初始化容器里的securityContext:privileged:true表示该容器具有特权,可以执行命令"sh","-c","/sbin/sysctl -w  vm.swappiness=0" vm.swappiness设置为表示尽量少使用swap内存。

(1)编写pod文件

[root@k8s-master ~]# vim 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: {}

(2)创建pod

[root@k8s-master ~]# ku create -f init02.yml 
pod/initc02 created

 (3)查看pod的详细信息

[root@k8s-master ~]# ku get pod -o wide
NAME      READY   STATUS    RESTARTS   AGE     IP               NODE     NOMINATED NODE   READINESS GATES
initc01   1/1     Running   0          8m33s   10.244.140.71    node02   <none>   <none>
initc02   1/1     Running   0          11s     10.244.196.135   node01   <none>   <none>

(4)到pod所在的节点查看swappiness的值是否为0

[root@node01 images]# cat /proc/sys/vm/swappiness 
0

 6.示例3——等待依赖服务启动

        有时某些服务需要依赖其他组件才能启动,比如后端应用需要数据库启动之后,应用才能正常启动,此时需要检测数据库实例是否正常,等待数据库可以正常使用时,在启动后端应用,此时可以使用初始化容器进行控制。

(1)创建第一个pod

        该pod内要依赖两个条件才能启动,分别是利用busybox容器检测redis-service服务和mysql-server服务是否生成

[root@k8s-master ~]# vim 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;']

备注: command: ['sh', '-c', 'until nslookup mysql-service; do echo waiting for nginx02; sleep 2; done;']   这个命令是一个shell脚本 ,用于持续检查 mysql-service 的 DNS 解析。

sh  :shell解释器

-c   :后面要执行的命令

until do 直到型循环结构,直到条件成立终止循环

nslookup  查询 DNS(域名系统)记录

(2)创建该pod查看状态

[root@k8s-master ~]# ku create -f myapp.yaml 
pod/nginx created
[root@k8s-master ~]# ku get pod
NAME      READY   STATUS     RESTARTS   AGE
initc01   1/1     Running    0          23m
initc02   1/1     Running    0          15m
nginx     0/1     Init:0/2   0          5s

(3)创建第一个被依赖的service

编写pod

[root@k8s-master ~]# vim 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

 创建pod查看nginx的状态

[root@k8s-master ~]# ku create -f redis-deployment.yaml 
deployment.apps/redis created

[root@k8s-master ~]# ku get pod
NAME                     READY   STATUS     RESTARTS   AGE
initc01                  1/1     Running    0          27m
initc02                  1/1     Running    0          19m
nginx                    0/1     Init:1/2   0          4m40s
redis-56bcf55554-7ngl6   1/1     Running    0          32s

此时发现nginx的STATUS状态栏的值变了,表示已经有一个init启动完成并结束了。

(4)第二个pod

编写pod文件

[root@k8s-master ~]# vim 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

创建pod,查看nginxpod的状态

[root@k8s-master ~]# ku create -f mysql-deployment.yaml 
deployment.apps/mysql created
service/mysql-service created
[root@k8s-master ~]# ku get pod
NAME                     READY   STATUS    RESTARTS   AGE
initc01                  1/1     Running   0          31m
initc02                  1/1     Running   0          23m
mysql-7f5d669b6c-k4hj2   1/1     Running   0          31s
nginx                    1/1     Running   0          8m21s
redis-56bcf55554-7ngl6   1/1     Running   0          4m13s

二.pause容器

1.定义

        在 Kubernetes 中,pause 容器通常是用于保持 Pod 的网络和存储环境的稳定性。它是 Kubernetes 中 Pod 的基础容器,负责维持 Pod 的网络和命名空间,确保在 Pod 中的其他容器重启或更换时,网络配置和存储挂载保持不变。 

2.特点 

在Kubernetes中,Pod是部署和管理容器化应用的基本单位,而Pause(或称为Infra)容器则是Pod中一个非常特殊的容器。Pause容器的特点主要体现在以下几个方面:

1. 轻量级与无业务逻辑

  • 镜像非常小:Pause容器的镜像通常非常小,大约在700KB左右,这使得它非常轻量,对系统资源的占用极低。
  • 无业务逻辑:Pause容器本身不包含任何业务逻辑,它的主要作用是作为Pod中其他容器的“宿主”或“基础设施”,提供必要的环境和支持。

2. 提供命名空间和资源共享

  • 命名空间共享:Pause容器为Pod中的其他容器提供了PID、网络(Network Namespace)、IPC(进程间通信)和UTS(主机名)等命名空间的共享。这意味着Pod中的容器可以看到相同的网络视图、进程ID等,从而简化了容器间的通信和协作。
  • 共享存储卷:Pause容器还负责挂载和管理Pod级别的共享存储卷(如emptyDir卷),使得Pod中的容器可以共享文件系统,实现文件和数据的共享。

3. 生命周期管理

  • 持续运行:Pause容器在Pod的生命周期中持续运行,即使Pod中的其他容器被重启或替换,Pause容器仍然保持不变。这确保了Pod级别的网络命名空间和共享存储卷的持久性。
  • 容器启动顺序:由于Pause容器是Pod中第一个启动的容器,它确保了Pod的网络和存储环境在其他容器启动之前已经准备好。

4. 网络通信支持

  • 网络命名空间的主要进程:Pause容器在Pod中充当网络命名空间的主要进程,负责创建和配置Pod的网络环境,如IP地址、网络接口和路由规则等。这使得Pod中的其他容器可以通过与Pause容器共享网络命名空间来实现容器间的通信。

5. 自动生成与管理

  • 自动生成:Pause容器是由Kubernetes系统自动生成并注入到每个Pod中的,用户无需在Pod定义中显式定义它。
  • 自动管理:Pause容器的生命周期由Kubernetes系统自动管理,包括启动、停止和重启等操作。

综上所述,Pause容器是Kubernetes中Pod的一个重要组成部分,它通过提供命名空间共享、资源共享、生命周期管理和网络通信支持等功能,为Pod中的其他容器提供了一个稳定、可靠的运行环境。

三.临时容器

1.定义

临时容器是Kubernetes(简称K8s)中一个特殊的容器概念,它允许用户在现有的Pod中临时运行一个或多个容器,以便完成用户发起的操作,如故障排查、日志收集、临时测试等。临时容器是一种在Pod中临时运行的容器,它不作为Pod的持久部分,而是在需要时创建,并在任务完成后被删除。

2.临时容器特点

  • 无自动重启:临时容器永远不会自动重启,这与其他可能具有重启策略的常规容器不同。
  • 临时运行:临时容器在现有Pod中临时运行,以便完成用户发起的操作,如故障排查等。
  • 非构建用途:临时容器主要用于检查服务状态,而不是用于构建应用程序。
  • 一次性使用:临时容器通常用于一次性任务,如故障排查,完成后即被移除。
  • 交互式故障排查:当容器崩溃或容器镜像不包含调试工具而导致kubectl exec命令无用时,临时容器对于交互式故障排查非常有用。

3.作用

故障排查

当Pod中的某个容器出现问题或行为异常时,传统的方法可能包括查看日志、使用kubectl exec进入容器内部等。然而,在某些情况下,这些方法可能不够直接或有效,特别是当容器镜像不包含必要的调试工具时。临时容器允许用户向Pod中注入一个新的容器,该容器具有访问Pod中其他容器的网络和卷的能力,从而可以执行如查看进程、文件系统、执行诊断命令等任务,以帮助诊断问题。

交互式调试

类似于故障排查,但更侧重于提供一种交互式的方式来调查Pod内部的状态。由于临时容器可以按需启动,用户可以在需要时启动一个包含调试工具的容器,并与之交互,从而更深入地了解Pod的运行情况。

临时任务执行

虽然这不是临时容器的主要设计目标,但在某些情况下,它们也可以被用于在Pod中执行临时的、一次性的任务。这些任务可能包括但不限于数据收集、状态检查、清理工作等。

学习和探索

对于Kubernetes的新手或正在学习其内部工作原理的用户来说,临时容器提供了一个独特的机会来观察Pod内部的运行状况,了解容器之间的交互方式,以及探索Kubernetes的各种功能和特性。

注意事项

  • Alpha状态:需要注意的是,临时容器在Kubernetes中目前仍处于Alpha状态,这意味着它们可能在未来的版本中发生重大变化或被完全移除。因此,在生产环境中使用临时容器时应格外小心,并密切关注Kubernetes的更新和变更。
  • 安全性:由于临时容器可以访问Pod中的网络和存储资源,因此必须确保它们以安全的方式运行,避免潜在的安全风险。
  • 限制:临时容器在创建时有一些限制和约束,例如它们不能拥有自己的端口、生命周期、重启策略等。这些限制是为了确保临时容器不会干扰Pod中其他容器的正常运行。

总的来说,临时容器为Kubernetes提供了一种强大的工具,用于在Pod中执行临时任务、进行故障排查和调试。然而,由于其当前的状态和限制,用户在使用时应谨慎考虑其适用性和安全性。

4.实例

(1)创建一个tomcat的资源清单

[root@k8s-master ~]# vim pod-tomcat.yaml 

apiVersion: v1
kind: Pod
metadata:
  name: tomcat-test
  namespace: default
  labels:
    app:  tomcat
spec:
  containers:
  - name:  tomcat-java
    ports:
    - containerPort: 8080
    image: kubeguide/tomcat-app:v1
    imagePullPolicy: IfNotPresent

 (2)创建pod

[root@k8s-master ~]# ku create -f pod-tomcat.yaml 
pod/tomcat-test created

[root@k8s-master ~]# ku get pod
NAME                     READY   STATUS    RESTARTS   AGE
tomcat-test              1/1     Running   0          5s

(3)为tomcat 的pod 创建临时容器

[root@k8s-master ~]# ku debug -it tomcat-test --image=busybox:1.28 --target=tomcat-java
Targeting container "tomcat-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-6hl2d.
If you don't see a command prompt, try pressing enter.
/

(4)查看tomcat-test这个pod是否已有临时容器

ku describe pod tomcat-test

Ephemeral Containers:
  debugger-6hl2d:
    Container ID:   docker://d021890e98a6631665ed7c9d7969df603ddfffe39dc8df35aff298d03eef21ee
    Image:          busybox:1.28
    Image ID:       docker://sha256:8c811b4aec35f259572d0f79207bc0678df4c736eeec50bc9fec37ed936a472a

四.自动扩缩容HPA

        在集群安装的过程中,我们可以安装一个叫MetricsServer的组件,该组件在集群中负责采集Pod和Node的度量值指标,比如Pod的CPU、内存使用和节点的内存、CPU使用案,而且安装的Dashboard可以展示CPU、内存信息也是依靠MetricsServer的。当然,该组件不仅仅是用来展示数据的,还可以使用Metrics Server提供的数据结合Kubernetes的HPA功能实现Pod的自动扩缩容

1.什么是HPA

  •     HPA(HorizontalPodAutoscaler,水平Pod自动伸缩器)可以根据观察到的CPU、内存使用率或自定义度量标准来自动扩展或缩容Pod的数量。注意HPA不适用于无法缩放的对象,比如DaemonSet
  • HPA控制器会定期调整RC或Deployment的副本数,以使观察到的平均CPU利用率与用户指定的目标相匹配。
  •     HPA需要MetricsServer获取度量指标,如果已经部署了MetricsServer,本节的实践部就分无须再安装MetricsServe  如果没有安装Metrics eryer  可以参考其他实验文档自行部署

2.为什么使用自动缩容

Horizontal Pod Autoscaler (HPA) 在 Kubernetes 中用于自动扩缩容,主要有以下几个原因:

提高弹性:HPA 根据实时负载自动调整 Pod 数量,确保应用能够应对流量的波动,提高系统的弹性。

优化资源使用:自动调整 Pod 数量有助于在负载高峰时增加资源,在负载低谷时减少资源,从而优化资源的使用效率,降低成本。

简化管理:HPA 减少了手动干预的需要,通过自动化的方式调整容器数量,简化了运维工作。

保持性能:通过动态扩展或缩减 Pod 数量,HPA 能够保持应用性能稳定,避免因负载过高导致的性能下降或服务中断。

3.HPA实践——实现Web服务器的自动伸缩特性

        在生产环境中,总会有一些意想不到的事情发生,比如公司网站流量突然升高,此时之前创建的Pod已不足以支撑所有的访问,而运维人员也不可能24小时守着业务服务,这时就可以通过配置HPA,实现负载过高的情况下自动扩容Pod副本数以分摊高并发的流量,当流量恢复正常后,HPA会自动缩减Pod的数量。 

        实现一个web服务器的自动伸缩特性

(1)首先Deployment启动一个Nginx服务(必须配置requests参数):

[root@k8s-master ~]# vim 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 ~]# vim nginx-deployment.yaml 
[root@k8s-master ~]# ku create -f nginx-deployment.yaml 
deployment.apps/nginx-server created
[root@k8s-master ~]# ku get pod
NAME                            READY   STATUS    RESTARTS   AGE

nginx-server-6ddcfd4c8f-69z4h   1/1     Running   0          12s
nginx-server-6ddcfd4c8f-dhtzf   1/1     Running   0          12s

(2)配置nginx-server的service

[root@k8s-master ~]# ku expose deployment nginx-server --port=80
service/nginx-server exposed
[root@k8s-master ~]# ku get svc
NAME            TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE

nginx-server    ClusterIP   10.96.1.192      <none>        80/TCP           30s

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

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

         此时PHA将根据CPU的使用率自动增加和减少副本数量,上述设置的是CPU使用率超过10%(--cpu-percent参数指定)就会增加Pod的数量,以保持所有Pod的平均CPU利用率为10%,允许最大pod的数量为10(--max),最少数量为1(--min)

(4)查看当前HPA的状态

[root@k8s-master ~]# ku get hpa
NAME           REFERENCE                 TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
nginx-server   Deployment/nginx-server   0%/10%    1         10        2          4m56s

因为未对其发送任何请求,所以当前CPU利用率为0%。

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

[root@k8s-master ~]# ku get svc 
NAME            TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
kubernetes      ClusterIP   10.96.0.1        <none>        443/TCP          8d
nginx-server    ClusterIP   10.96.1.192      <none>        80/TCP           7h37m

(6)压力测试

打开一个新的终端,使用一个“死”循环或其他压测工具模仿访问service,从而增加该pod的负载

[root@k8s-master ~]# while true;do wget -q -o- http://10.96.1.192 >/dev/null;done

(7)查看HPA状态

等待一分钟左右,再次查看HPA,可以看到pod的cpu已经升高

[root@k8s-master ~]# ku get hpa
NAME           REFERENCE                 TARGETS    MINPODS   MAXPODS   REPLICAS   AGE
nginx-server   Deployment/nginx-server   520%/10%   1         10        4          11m

查看pod,发现副本数也增加了

[root@k8s-master ~]# ku get pod
NAME                            READY   STATUS    RESTARTS   AGE
nginx-server-6ddcfd4c8f-2mkk2   1/1     Running   0          29s
nginx-server-6ddcfd4c8f-2tb4z   1/1     Running   0          44s
nginx-server-6ddcfd4c8f-69z4h   1/1     Running   0          7h44m
nginx-server-6ddcfd4c8f-7g7wx   1/1     Running   0          14s
nginx-server-6ddcfd4c8f-9t7qn   1/1     Running   0          29s
nginx-server-6ddcfd4c8f-bjhfw   1/1     Running   0          44s
nginx-server-6ddcfd4c8f-d6lv8   1/1     Running   0          14s
nginx-server-6ddcfd4c8f-pjb7g   1/1     Running   0          29s
nginx-server-6ddcfd4c8f-t2pgl   1/1     Running   0          44s
nginx-server-6ddcfd4c8f-v6kg7   1/1     Running   0          29s

(8)停止压力测试

发现cpu的使用率很快就降下来了

[root@k8s-master ~]# ku get hpa
NAME           REFERENCE                 TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
nginx-server   Deployment/nginx-server   0%/10%    1         10        10         15m

pod的副本数量要等几分钟再去查看

[root@k8s-master ~]# ku get pod
NAME                            READY   STATUS    RESTARTS   AGE
nginx-server-6ddcfd4c8f-69z4h   1/1     Running   0          7h54m

  • 11
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值