• OpenShift 4 - 了解 OpenShift 是如何使用节点本地镜像缓存


    OpenShift / RHEL / DevSecOps 汇总目录
    文本已在 OpenShift 4.15 环境中进行验证。

    什么是节点本地镜像缓存

    一个 OpenShift 集群节点在运行 Pod 前需要先从 Registry 拉取到相关 Image。这些镜像会保存在节点本地存储中并作为缓存,这样该节点如果再使用这个 Image 就会先使用节点缓存中的镜像,从而提升 Pod 的启动速度。

    在这里插入图片描述

    OpenShift 是如何使用节点本地镜像缓存

    查看节点本地保存的镜像缓存

    1. 确认可以访问到 https://quay.io/repository/openshiftroadshow/parksmap?tab=tags,其中有测试镜像。
      在这里插入图片描述
    2. 执行命令获取当前节点名。
    $ oc get node
    NAME                            STATUS   ROLES                         AGE   VERSION
    control-plane-cluster-cw8ww-1   Ready    control-plane,master,worker   30h   v1.28.7+f1b5f6c
     
    $ NODE_NAME=control-plane-cluster-cw8ww-1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    1. 执行命令,在 Deployment 中使用 quay.io/openshiftroadshow/parksmap:latest 镜像,并让其运行在指定节点以方便跟踪。
    $ oc apply -f - << EOF       
    kind: Deployment
    apiVersion: apps/v1
    metadata:
      name: parksmap
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: parksmap
      template:
        metadata:
          labels:
            app: parksmap
        spec:
          nodeName: ${NODE_NAME}
          containers:
            - name: hello-openshift
              image: 'quay.io/openshiftroadshow/parksmap:latest'
              ports:
                - containerPort: 8080
                  protocol: TCP
                - containerPort: 8888
                  protocol: TCP
              imagePullPolicy: IfNotPresent
    EOF
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    1. 运行命令,确认 Pod 可以正常运行起来,并注意 Pod 运行在指定节点上。
    $ oc get pod -owide
    NAME                                      READY   STATUS    RESTARTS   AGE   IP             NODE                            
    parksmap-9bdf99cc-km892                   1/1     Running   0          32m   10.132.0.114   control-plane-cluster-cw8ww-1
    
    • 1
    • 2
    • 3
    1. 进入 Pod 运行的的 Node,并切换到 /host。
    $ oc debug node/$NODE_NAME
    sh-4.4# chroot /host
    
    • 1
    • 2
    1. 运行以下命令,确认可以在节点中找到 openshiftroadshow/parksmap:latest 镜像信息。注意镜像的 id 和 digest。
    $  cat /var/lib/containers/storage/overlay-images/images.json | jq
    ......
      {
        "id": "0c2f55f381ee738ec77722ea7b92ac97fcfa1cb6ef8e323df929b0ab40c70a47",
        "digest": "sha256:89d1e324846cb431df9039e1a7fd0ed2ba0c51aafbae73f2abd70a83d5fa173b",
        "names": [
          "quay.io/openshiftroadshow/parksmap:latest"
        ],
        "names-history": [
          "quay.io/openshiftroadshow/parksmap:latest"
        ],
        "layer": "e0c471633f3e337a376fd877385b6bfc287b9144c003aa61c933ec853610e3ce",
        "metadata": "{}",
        "big-data-names": [
          "sha256:0c2f55f381ee738ec77722ea7b92ac97fcfa1cb6ef8e323df929b0ab40c70a47",
          "manifest-sha256:89d1e324846cb431df9039e1a7fd0ed2ba0c51aafbae73f2abd70a83d5fa173b",
          "manifest"
        ],
        "big-data-sizes": {
          "manifest": 1373,
          "manifest-sha256:89d1e324846cb431df9039e1a7fd0ed2ba0c51aafbae73f2abd70a83d5fa173b": 1373,
          "sha256:0c2f55f381ee738ec77722ea7b92ac97fcfa1cb6ef8e323df929b0ab40c70a47": 5671
        },
        "big-data-digests": {
          "manifest": "sha256:89d1e324846cb431df9039e1a7fd0ed2ba0c51aafbae73f2abd70a83d5fa173b",
          "manifest-sha256:89d1e324846cb431df9039e1a7fd0ed2ba0c51aafbae73f2abd70a83d5fa173b": "sha256:89d1e324846cb431df9039e1a7fd0ed2ba0c51aafbae73f2abd70a83d5fa173b",
          "sha256:0c2f55f381ee738ec77722ea7b92ac97fcfa1cb6ef8e323df929b0ab40c70a47": "sha256:0c2f55f381ee738ec77722ea7b92ac97fcfa1cb6ef8e323df929b0ab40c70a47"
        },
        "created": "2021-02-01T12:52:36.138979177Z"
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    1. 在 quay.io 中使用 digest 方式获取上述镜像,确认 digest 和上一步返回的 digest 一样。
      在这里插入图片描述
    2. 执行命令查找第 6 步返回的 id,确认该镜像已和 /var/lib/containers/storage/overlay-images 中名为 id 的目录对应起来。
    $ ls -al /var/lib/containers/storage/overlay-images | grep 0c2f55f381ee738ec77722ea7b92ac97fcfa1cb6ef8e323df929b0ab40c70a47
    drwx------.   2 root root   4096 Apr 10 01:15 0c2f55f381ee738ec77722ea7b92ac97fcfa1cb6ef8e323df929b0ab40c70a47
    
    • 1
    • 2
    1. 退出节点。
    2. 另外还可以在该节点的 YAML 或“详情”中确认该节点上有此镜像。
      在这里插入图片描述

    镜像缓存是如何被使用

    1. 在自有 Image Registry 上准备一个自用的测试镜像,例如 quay.io/dawnskyliu/hello-openshift:v1。
    2. 执行以下命令,在 Deployment 中使用以上镜像。由于 imagePullPolicy 使用了 IfNotPresent 策略,因此如果本地缓存中已有,就不会重新拉取该镜像。
    $ oc apply -f - << EOF
    kind: Deployment
    apiVersion: apps/v1
    metadata:
      name: hello-openshift-v1
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: hello-openshift-v1
      template:
        metadata:
          labels:
            app: hello-openshift-v1
        spec:
          nodeName: ${NODE_NAME}
          containers:
            - name: hello-openshift
              image: 'quay.io/dawnskyliu/hello-openshift:v1'
              ports:
                - containerPort: 8080
                  protocol: TCP
                - containerPort: 8888
                  protocol: TCP
              imagePullPolicy: IfNotPresent
    EOF
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    1. 确认使用该镜像的 Pod 可以运行起来。
    $ oc get pod
    NAME                                  READY   STATUS    RESTARTS   AGE
    hello-openshift-v1-6995c77fb5-hvd84   1/1     Running   0          13s
    
    • 1
    • 2
    • 3
    1. 可参照上一节确认在节点的存储中已有该镜像的缓存。
    2. 删除 quay.io/dawnskyliu/hello-openshift:v1 或修改 tag,使访问 quay.io/dawnskyliu/hello-openshift:v1 失效。
    3. 然后再删除 hello-openshift-v1 部署。
    $ oc delete deploy hello-openshift-v1
    
    • 1
    1. 重新执行命令,使用 quay.io/dawnskyliu/hello-openshift:v1 镜像创建部署。确认此时虽然 quay.io/dawnskyliu/hello-openshift:v1 已失效,但通过使用节点本地缓存 pod 还可成功运行。
    $ oc apply -f - << EOF
    kind: Deployment
    apiVersion: apps/v1
    metadata:
      name: hello-openshift-v1
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: hello-openshift-v1
      template:
        metadata:
          labels:
            app: hello-openshift-v1
        spec:
          nodeName: ${NODE_NAME}
          containers:
            - name: hello-openshift
              image: 'quay.io/dawnskyliu/hello-openshift:v1'
              ports:
                - containerPort: 8080
                  protocol: TCP
                - containerPort: 8888
                  protocol: TCP
              imagePullPolicy: IfNotPresent
    EOF
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    1. 再次删除 hello-openshift-v1 部署,然后重新启动 NODE_NAME 节点,最后再次创建 hello-openshift-v1 部署,确认 pod 依然可以运行成功。这说明节点本地存储依然发挥作用。
    2. 再次删除 hello-openshift-v1 部署,然后将 imagePullPolicy 改为 Always 再重新创建部署,确认会失败。这是由于 Always 会重新拉取镜像,但已无法访问到远程的 quay.io/dawnskyliu/hello-openshift:v1 镜像了。
    $ oc delete deploy hello-openshift-v1
    $ oc apply -f - << EOF
    kind: Deployment
    apiVersion: apps/v1
    metadata:
      name: hello-openshift-v1
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: hello-openshift-v1
      template:
        metadata:
          labels:
            app: hello-openshift-v1
        spec:
          nodeName: ${NODE_NAME}
          containers:
            - name: hello-openshift
              image: 'quay.io/dawnskyliu/hello-openshift:v1'
              ports:
                - containerPort: 8080
                  protocol: TCP
                - containerPort: 8888
                  protocol: TCP
              imagePullPolicy: Always
    EOF
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    自动清理节点本地镜像缓存

    随着保存在节点本地存储的镜像缓存的数量增加,会不断消耗节点的本地存储空间,因此需要定期清理镜像缓存以释放存储空间。运行在节点的 kubelet 提供了清理本地镜像缓存的机制,而 OpenShift 4 是无法手动删除节点镜像缓存的。

    基于 oc new-app 生成的部署和基于 YAML 的部署之间的差异

    即便不考虑节点本地的镜像缓存,基于 oc new-app 生成的部署和基于 YAML 的部署之间是存在一定差异。

    基于 oc new-app 生成的部署

    在使用 oc new-app 命令生成部署的时候,虽然在命令中提供的是远程镜像地址,但 OpenShift 首先会把镜像从远程拉到 OpenShift 内部的镜像库中,然后再在 Deployment 的定义中自动通过 ImageStream 使用已在 OpenShift 内部镜像库中的镜像。

    基于 YAML 创建的部署

    当使用基于 YAML 的部署时候,其容器使用的镜像地址不会发生变化,会直接使用远程镜像库中的镜像。

    参考

    https://www.redhat.com/en/blog/image-garbage-collection-in-openshift
    https://docs.openshift.com/container-platform/4.15/nodes/nodes/nodes-nodes-garbage-collection.html
    https://medium.com/kubernetes-tutorials/efficient-node-out-of-resource-management-in-kubernetes-67f158da6e59
    https://itnext.io/improve-container-image-availability-and-speed-with-caching-in-kubernetes-870fa7bfa1ed

  • 相关阅读:
    SCI投稿:投稿附言cover letter的写法和模板!
    Spring源码篇(十二)事件机制
    Skywalking Docker单机环境搭建
    刚考过PMP想问一下怎样才能转行做PM
    【编程题 】 CD108 反转部分单向链表(详细注释 易懂)
    基于UDP协议的接收和发送
    如何在 PC 机上测试移动端的网页?
    Codeforces Round 895 (Div. 3) (A~G)
    LeetCode —— dfs和bfs
    Selenium基础 — Selenium元素定位(一)
  • 原文地址:https://blog.csdn.net/weixin_43902588/article/details/137565521