0
点赞
收藏
分享

微信扫一扫

三、Kubernetes 工作负载

什么是工作负载

  • 工作负载是运行在 Kubernetes 上的一个应用程序。
  • 一个应用很复杂,可能由单个组件或者多个组件共同完成。无论怎样我们可以用一组Pod来表示一个应用,也就是一个工作负载
  • Pod又是一组容器(Containers)
    • 所以关系又像是这样
    • Pod控制一组容器(Containers)
      • 比如Deploy(工作负载) 3个副本的nginx(3个Pod),每个nginx里面是真正的nginx容器(container)

102.png

工作负载能让Pod能拥有自恢复能力。

一、Pod

一、什么是Pod

  • pod是一组(一个或多个)容器(docker容器)的集合,这些容器共享存储、网络、以及怎样运行这些容器的声明。
  • 我们一般不直接创建pod,而是创建一些工作负载,由他们来创建pod
  • pod的形式
    • pod对容器有自恢复能力(pod里面的容器如果出问题了,pod会自动重启失败的容器)
    • pod自己不能恢复自己,pod被删了就真的没了,如果pod没了,我们还是希望k8s可以设置pod的自恢复能力,工作负载就让pod拥有了自恢复能力。
    • 多容器协调pod,有一个住容器,我们可以把另外的容器称为SideCar(为应用赋能)
    • pod天生的为其成员容器提供了两种共享资源 网络存储
  • 一个pod由一个pause容器设置好整个pod里面所有容器的网络、名称空间等信息
  • systemctl status可以观测到pod和容器的进程关系
    • kubectl启动一个pod,准备两个容器,一个是pod声明的应用容器,另外一个是Pause。Pause给当前应用容器设置好网络空间

把容器删了以后,pod重新启动容器后,ip地址永远不变,原因就是pos里面有pause设置的名称空间

106.png

容器相当于明星,SideCar相当于经纪人,明星只负责拍戏、唱歌,经纪人去联系外界给经纪人联系业务。

105.png

我们先创建一个pod,再在docker删掉进程,pod里会重新启动一个容器

103.png 104.png

二、pod使用

107.png

题目:
一个pod容器里包含nginx容器和alpine容器,nginx的html界面挂载出来,alpine的一个文件挂载到和nginx的html同一个目录,想要得到的效果是,修改alpine的时间,在nginx看到联动修改效果

110.png

apiVersion: v1
kind: Pod
metadata:
  name: "multi-container-pod"
  namespace: hello
  labels:
    app: "multi-container-pod"
spec:
  volumes:    ### 以后见到的所有名字 都应该是一个合法的域名方式
  - name: nginx-vol
    emptyDir: {}  ### docker匿名挂载,外部创建一个位置  /abc
  containers:  ## kubectl exec -it podName  -c nginx-container(容器名)-- /bin/sh
  - name: nginx-container
    image: "nginx"
    volumeMounts:  #声明卷挂载  -v
      - name: nginx-vol
        mountPath: /usr/share/nginx/html
  - name: content-container
    image: "alpine"
    command: ["/bin/sh","-c","while true;do sleep 1; date > /app/index.html;done;"]
    volumeMounts: 
      - name: nginx-vol
        mountPath: /app
kubectl apply -f xxx.yaml

三、Pod的生命周期

111.png

  • Pod启动,会先依次执行所有初始化容器,有一个失败,则Pod不能启

  • 接下来启动所有的应用容器(每一个应用容器都必须能一直运行起来),Pod开始正式工作,一个启动失败就会尝试重启Pod内的这个容器,Pod只要是NotReady,Pod就不对外提供服务了。

  • 先创建两个容器,一个nginx,一个alpine

apiVersion: v1
kind: Pod
metadata:
  name: "multi-lifecycle"
  namespace: hello
spec:
  containers:  
  - name: nginx-lifecycle
    image: "nginx"
  - name: alpine-container
    image: "alpine"
kubectl apply -f xxx.yaml

我们可以看到,pod里面有一个容器起不来,导致pod启动失败

112.png

从以下日志我们可以看出,alpine拉取成功,但启动失败,原因是alpine不会启动,必须在拉取容器后写启动命令才可以成功启动。

113.png

由此,我们可以得出,pod中,只要有一个容器不启动,pod就无法正常运行 下面,我们给alpine加上启动命令,让它睡20s。可以看到两个容器都启动后,pod可以正常运行

114.png

1、初始化容器

初始化的容器是执行在应用容器之前的,语法如下:

apiVersion: v1
kind: Pod
metadata:
  name: "init-multi-lifecycle"
  namespace: hello
spec:
  initContainers:
  - name: init-01
    image: nginx
  containers:  
  - name: nginx-lifecycle
    image: "nginx"
  - name: alpine-container
    image: "alpine"
    command: ["/bin/sh","-c","sleep 20"]
  • 我们可以发现,status处,出现一个init,并且一直处于0/1状态 115.png

  • 看日志也没有发现报错信息,原因是,初始化容器不可以一直处于启动状态,因为初始化容器执行完成之后,应用容器部分才会启动,所以,我们需要在初始化容器完成工作后,让它停止。 116.png

  • 所以此时,nginx这种一直启动的服务就不适合做初始化容器,我们用alpine做初始化容器,并且使alpine和应用容器nginx的html界面挂载同一个目录后,在初始化容器给挂载文件添加内容,容器启动后,看nginx访问界面是不是初始化容器修改的内容,如果是,则证明,初始化容器执行完毕,并且生效了。

apiVersion: v1
kind: Pod
metadata:
  name: "init-multi-lifecycle"
  namespace: hello
spec:
  volumes:
  - name: contentvol
    emptyDir: {}
  initContainers:
  - name: init-01
    image: nginx
    command: ["/bin/sh","-c","echo 666 > /app/index.html;sleep 20"]
    volumeMounts:
    - name: contentvol
      mountPath: /app
  containers:  
  - name: nginx-lifecycle
    image: "nginx"
    volumeMounts:
    - name: contentvol
      mountPath: /usr/share/nginx/html
  - name: alpine-container
    image: "alpine"
    command: ["/bin/sh","-c","sleep 20"]
  • 当初始化容器执行完成后返回:PodInitializing ,如下: 117.png

  • 容器全部启动后,返回如下: 118.png

  • 访问pod发现,返回的是初始化容器修改的内容,证明初始化容器的内容已经生效,并且pod正常运行 119.png

多容器协作,我们进入容器的方式如下,需要指定容器名称

kubectl exec -it pod名称 -c 容器名称 -- /bin/bash
kubectl exec -it pod名称 -c 容器名称 -- /bin/sh

120.png

2、临时容器(目前还没有形成稳定版本,先有这个概念,kubeadm安装配置了还有问题,后续稳定后再研究)

  • 临时容器:线上排错。
    • 有些容器基础镜像。线上没法排错。使用临时容器进入这个Pod。临时容器共享了Pod的所有。临时容器有Debug的一些命令,排错完成以后,只要exit退出容器,临时容器自动删除。

临时容器需要开启特性门控 --feature-gates="EphemeralContainers=true" 在所有组件,api-server、kubelet、scheduler、controller-manager都得配置

使用临时容器的步骤:

  • 1、声明一个临时容器。准备好json文件
{
    "apiVersion": "v1",
    "kind": "EphemeralContainers",
    "metadata": {
            "name": "my-nginx666" //指定Pod的名字
   },
    "ephemeralContainers": [{
        "command": [
          "sh"
       ],
        "image": "busybox",  //jre的需要jdk来调试

        "imagePullPolicy": "IfNotPresent",
        "name": "debugger",
        "stdin": true,
        "tty": true,
        "terminationMessagePolicy": "File"
   }]
}
  • 2、使用临时容器,应用一下即可
kubectl replace --raw /api/v1/namespaces/default/pods/my-nginx666【pod
名】/ephemeralcontainers  -f ec.json
举报

相关推荐

0 条评论