Pod镜像拉取策略

我们在创建pod的时候,他都需要一个镜像,他需要这个镜像的时候我们呢怎么拉取这个镜像,有个策略

#下载策略有三个
[root@k8s-master1 ~]# kubectl explain pod.spec.containers.imagePullPolicy
KIND:     Pod
VERSION:  v1

FIELD:    imagePullPolicy <string>
#这也是个字符串

DESCRIPTION:
     Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always
     #三个下载策略一个叫Always  一个Never  一个叫IfNotPresent
     #镜像下载策略分两种情况,本地有没有,就是你把pod已经通过调度器已经绑定到一个node节点上了,
     #那么这个node节点有没有这个镜像呢,有镜像和没有镜像是两种情况,如果有,还要不要下载,
     #Always是有没有都要下载
     #Never不管有没有都不下载
     #IfNotPresent根据你镜像版本号(tag)如果是latest(最新的)(比如(nginx:latest)
     #他就永远都会去时使用Always(不管你本地有没有都会去拉取)如果你镜像不是latest(比如nginx:1.22.1)
     #如果你本地有他就不拉取
     if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated.
     More info:
     https://kubernetes.io/docs/concepts/containers/images#updating-images

     Possible enum values:
     - `"Always"` means that kubelet always attempts to pull the latest image.
     Container will fail If the pull fails.
     - `"IfNotPresent"` means that kubelet pulls if the image isn't present on
     disk. Container will fail if the image isn't present and the pull fails.
     - `"Never"` means that kubelet never pulls an image, but only uses a local
     image. Container will fail if the image isn't present

镜像拉取策略有三个:

Always:总是拉取,当镜像 tag 为 latest 时,且 imagePullPolicy 未配置,默认为Always

Never:不管是否存在都不会拉取

IfNotPresent : 镜像不存在时拉取镜像,如果tag 为非 latest,且 imagePullPolicy 未配置,默认为 IfNotPresent

操作方式

说明

Always

总是拉取,当镜像tag为latest时,且imagePullPolicy未配置默认为Always

Never

不管是否存在都不会拉取

IfNotPresent

镜像不存在时拉取镜像,如果tag为非lasest,且imagePullPolicy,未配置,默认为IfNotPresent

Pod重启策略

可以使用spec.restartPolicy指定容器的重启策略

重启肯定就是你的pod停止了,pod down了 容器down了,宕机以后会不会把我们这个容器进行重启呢?

restartPolicy比上面讲的级别要高,他不是在容器里面的,他是在spec里面的

他的级别也有三个

[root@k8s-master1 ~]# kubectl explain pod.spec.restartPolicy
KIND:     Pod
VERSION:  v1

FIELD:    restartPolicy <string>

DESCRIPTION:
     Restart policy for all containers within the pod. One of Always, OnFailure,
     Never. Default to Always. More info:
     https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy

     Possible enum values:
     - `"Always"`
     #不管什么原因造成的pod退出,都给你pod进行重启,默认是Always
     - `"Never"`
     #不管什么原因造成的都不重启
     - `"OnFailure"`
     #如果容器退出不是以0状态退出,非0状态退出容器,他会自动重启,如果不是非0的就不重启
     

操作方式

说明

Always

默认策略,容器失效时,自动重启该容器

Never

无论何种状态都不重启

Onfailure

容器以不为0的状态码中止,自动重启该容器

-o yaml 以yaml格式打印出来

[root@k8s-master1 ~]# kubectl get pods nginx-5 -o yaml
apiVersion: v1
#版本v1 自己写的
kind: Pod
#类型pod自己写的
metadata:
  annotations:
 #给加的资源注解自动加的
    cni.projectcalico.org/containerID: a0d92f4cecd6d9987c4e3b89f35b16780d4dca64fd8922f2f95bb3ed420eead0
    cni.projectcalico.org/podIP: 192.28.252.231/32
    cni.projectcalico.org/podIPs: 192.28.252.231/32
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"labels":{"app":"nginx","linux":"ubuntu"},"name":"nginx-5","namespace":"default"},"spec":{"containers":[{"image":"images.guoguo.com/apps/ubuntu-nginx:1.22.1","name":"nginx","ports":[{"containerPort":80}]}],"nodeName":"k8s-node2.guoguo.com"}}
  creationTimestamp: "2023-08-09T02:35:08Z"
  #创建的时间戳自动加的
  labels:
  #标签自己写的
    app: nginx
    linux: ubuntu
  name: nginx-5
  #pod名称自己写的
  namespace: default
  #名称空间自己写的
  resourceVersion: "116336"
  #版本自动加的
  uid: c3082ae6-0952-44e0-bfb9-f89b9fa3013a
spec:
  containers:
  - image: images.guoguo.com/apps/ubuntu-nginx:1.22.1
  #镜像路径自己写的
    imagePullPolicy: IfNotPresent
    #镜像下载策略因为我们写的tag版本不是latest,本地如果有就不下载了
    name: nginx
    #容器名字自己写的
    ports:
    - containerPort: 80
    #容器端口号自己写的
      protocol: TCP
    resources: {}
    #资源限制没写,为空
    terminationMessagePath: /dev/termination-log
    terminationMessagePolicy: File
    volumeMounts:
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: kube-api-access-cfg9z
      readOnly: true
  dnsPolicy: ClusterFirst
  enableServiceLinks: true
  nodeName: k8s-node2.guoguo.com
  preemptionPolicy: PreemptLowerPriority
  priority: 0
  restartPolicy: Always
  #pod重启策略,Always 默认就是这个
  schedulerName: default-scheduler
  #调度器的名称
  securityContext: {}
  serviceAccount: default
  serviceAccountName: default
  terminationGracePeriodSeconds: 30
  tolerations:
  - effect: NoExecute
    key: node.kubernetes.io/not-ready
    operator: Exists
    tolerationSeconds: 300
  - effect: NoExecute
    key: node.kubernetes.io/unreachable
    operator: Exists
    tolerationSeconds: 300
  volumes:
  - name: kube-api-access-cfg9z
    projected:
      defaultMode: 420
      sources:
      - serviceAccountToken:
          expirationSeconds: 3607
          path: token
      - configMap:
          items:
          - key: ca.crt
            path: ca.crt
          name: kube-root-ca.crt
      - downwardAPI:
          items:
          - fieldRef:
              apiVersion: v1
              fieldPath: metadata.namespace
            path: namespace
status:
#第五种状态,我们有五大状态,1是apiVersion,2是kind,3是spec,4是metadata,前四种是需要写在yaml文件里面的,
#第五种是status不需要我们呢自己手动写,自动加上的
  conditions:
  - lastProbeTime: null
    lastTransitionTime: "2023-08-09T02:35:08Z"
    status: "True"
    type: Initialized
  - lastProbeTime: null
    lastTransitionTime: "2023-08-09T02:38:19Z"
    status: "True"
    type: Ready
  - lastProbeTime: null
    lastTransitionTime: "2023-08-09T02:38:19Z"
    status: "True"
    type: ContainersReady
  - lastProbeTime: null
    lastTransitionTime: "2023-08-09T02:35:08Z"
    status: "True"
    type: PodScheduled
  containerStatuses:
  - containerID: containerd://0c57c25f874d8dc4810c5f45604c0926e285111adc9674473304f041a0684f6e
    image: images.guoguo.com/apps/ubuntu-nginx:1.22.1
    imageID: images.guoguo.com/apps/ubuntu-nginx@sha256:5d90159fb7d3c4076eabbe2fefe74dafe262e5a16d40a64fd685dbb4f14926d9
    lastState: {}
    name: nginx
    ready: true
    restartCount: 0
    started: true
    state:
      running:
        startedAt: "2023-08-09T02:38:19Z"
  hostIP: 172.17.8.12
  phase: Running
  podIP: 192.28.252.231
  podIPs:
  - ip: 192.28.252.231
  qosClass: BestEffort
  startTime: "2023-08-09T02:35:08Z"

以上这些在我们文件里可以进行修改

vim nginx-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-5
  namespace: default
  labels:
    app: nginx
    linux: ubuntu
spec:
  nodeName: k8s-node2.guoguo.com
  containers:
    name: nginx
    ports:
    - containerPort: 80
    image: images.guoguo.com/apps/ubuntu-nginx:1.20.1 
    
apiVersion: v1
kind: Pod
metadata:
  name: nginx-5
  namespace: default
  labels:
    app: nginx
    linux: ubuntu
spec:
  restartPolicy: Never #pod重启策略,默认是Always,改为Nerser 不重启
  containers:
  - name: nginx
    imagePullPolicy: Never #新加的镜像下载策略默认是Always,我们改为Nerser 不管有没有都不下载
    ports:
    - containerPort: 80
    image: images.guoguo.com/apps/ubuntu-nginx:1.24.0 #改为一个仓库没有的镜像
[root@k8s-master1 ~]# kubectl delete -f nginx-pod.yml
#删除原来的pod从新创建
[root@k8s-master1 ~]# kubectl get pods
NAME      READY   STATUS              RESTARTS        AGE
nginx-5   0/1     ErrImageNeverPull   0               4s
                #镜像下载失败
[root@k8s-master1 ~]# kubectl get pods -o wide
NAME      READY   STATUS              RESTARTS        AGE     IP               NODE                   NOMINATED NODE   
nginx-5   0/1     ErrImageNeverPull   0               59s     192.17.65.215    k8s-node3.guoguo.com  
                                                                        #已经绑定了node节点了

describe看下

[root@k8s-master1 ~]# kubectl describe pods nginx-5
#前面省略
Events:
  Type     Reason             Age                  From               Message
  ----     ------             ----                 ----               -------
  Normal   Scheduled          105s                 default-scheduler  Successfully assigned default/nginx-5 to k8s-node3.guoguo.com
  Warning  ErrImageNeverPull  11s (x10 over 105s)  kubelet            Container image "images.guoguo.com/apps/ubuntu-nginx:1.24.0" is not present with pull policy of Never
            #容器镜像 1.29.1        不存在                             #下载策略为Nerser
  Warning  Failed             11s (x10 over 105s)  kubelet            Error: ErrImageNeverPull

因为node3没有nginx1.24.1镜像所以不能生成,我们去node3下载一个镜像

切换到node3 下载一个1.24.0镜像

然后再看pod状态


[root@k8s-master1 ~]# kubectl get pods
NAME      READY   STATUS    RESTARTS        AGE
nginx-5   1/1     Running   0               4m39s
#已经Running了

[root@k8s-master1 ~]# kubectl describe pods nginx-5
Events:
  Type     Reason             Age                     From               Message
  ----     ------             ----                    ----               -------
  Normal   Scheduled          7m41s                   default-scheduler  Successfully assigned default/nginx-5 to k8s-node3.guoguo.com
  Warning  ErrImageNeverPull  5m40s (x12 over 7m40s)  kubelet            Container image "images.guoguo.com/apps/ubuntu-nginx:1.24.0" is not present with pull policy of Never
  Warning  Failed             5m40s (x12 over 7m40s)  kubelet            Error: ErrImageNeverPull
  Normal   Pulled             5m25s                   kubelet            Container image "images.guoguo.com/apps/ubuntu-nginx:1.24.0" already present on machine
  #已经发现镜像存在主机里面 正常拉取到了

继续关注 restartPolicy: Never #pod重启策略,默认是Always,改为Nerser 不重启

restartPolicy设置的是Nerver,不重启

我们进入容器里面然后关闭nginx服务,这样容器就会退出,看看给不给重启

可以去dashboard 的ui界面去操作

也可以命令行kubectl exec 进入容器里面

[root@k8s-master1 ~]# kubectl exec -it nginx-5 /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@nginx-5:/# nginx -s stop
#关闭nginx
root@nginx-5:/# command terminated with exit code 137

[root@k8s-master1 ~]# kubectl get pods
NAME      READY   STATUS      RESTARTS   AGE
nginx-5   0/1     Completed   0          82m
				#状态为Completed

如果我们关闭了容器的进程,那么容器会关闭,因为我们设置了容器的重启策略为Nerver

删掉这容器

[root@k8s-master1 ~]# kubectl delete -f nginx-pod.yml
pod "nginx-5" deleted

我们将restartPolicy的状态改为Always,不管啥情况都重启

vim nginx-pod.yml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-5
  namespace: default
  labels:
    app: nginx
    linux: ubuntu
spec:
  restartPolicy: Always #改为Always
  containers:
  - name: nginx
    imagePullPolicy: Never
    ports:
    - containerPort: 80
    image: images.guoguo.com/apps/ubuntu-nginx:1.24.0
[root@k8s-master1 ~]# kubectl apply -f nginx-pod.yml
pod/nginx-5 created
[root@k8s-master1 ~]# kubectl get pods
NAME      READY   STATUS    RESTARTS     AGE
nginx-5   1/1     Running   1 (7s ago)   80s
[root@k8s-master1 ~]# kubectl exec -it nginx-5 /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@nginx-5:/# nginx -s stop
root@nginx-5:/# command terminated with exit code 137

[root@k8s-master1 ~]# kubectl get pods
NAME      READY   STATUS      RESTARTS      AGE
nginx-5   0/1     Completed   1 (43s ago)   116s
#稍等片刻再查询

[root@k8s-master1 ~]# kubectl get pods
NAME      READY   STATUS    RESTARTS      AGE
nginx-5   1/1     Running   2 (32s ago)   2m24s
[root@k8s-master1 ~]# kubectl describe pods nginx-5
#前面省略
Events:
  Type     Reason     Age                  From               Message
  ----     ------     ----                 ----               -------
  Normal   Scheduled  2m51s                default-scheduler  Successfully assigned default/nginx-5 to k8s-node3.guoguo.com
  Warning  BackOff    58s                  kubelet            Back-off restarting failed container nginx in pod nginx-5_default(bf17257e-c091-4ef5-bc06-25d6bf392802)
  Normal   Pulled     44s (x3 over 2m51s)  kubelet            Container image "images.guoguo.com/apps/ubuntu-nginx:1.24.0" already present on machine
  Normal   Created    44s (x3 over 2m51s)  kubelet            Created container nginx
  Normal   Started    44s (x3 over 2m51s)  kubelet            Started container nginx