• 【云原生--Kubernetes】Pod容器与镜像拉取策略



    前言:pod作为k8s最小资源单位,对于pod的管理也将尤为重要,本文将详细介绍pod

    一. Pod容器的分类

    1.1 基础容器(infrastructure container)

    1. 维护整个 Pod 网络和存储空间
    2. node 节点中操作
    3. 启动一个容器时,k8s会自动启动一个基础容器

    1.2 初始化容器(initcontainer)

    Init 容器必须在应用程序容器启动之前运行完成,而应用程序容器是并行运行的,所以 Init 容器能够提供了一种简单的阻塞或延迟应用容器的启动的方法。Init 容器与普通的容器非常像,除了以下两点:

    1. init 容器总是运行到成功完成为止
    2. 每个 Init 容器都必须在下一个 Init 容器启动之前成功完成启动和退出
      如果 Pod 的 init 容器失败,k8s 会不断地重启该 Pod,直到 Init 容器成功为止。然而,如果 Pod 对应的重启策略(restartPolicy)为 Never,它不会重新启动。

    init 的容器作用
    因为 init 容器具有与应用容器分离的单独镜像,其启动相关代码具有如下优势:

    1. Init 容器可以包含一些安装过程中应用容器中不存在的实用工具或个性化代码。例如,没有必要仅为了在安装过程中使用类似 sed、 awk、python 或 dig 这样的工具而去 FROM 一个镜像来生成一个新的镜像。
    2. Init 容器可以安全地运行这些工具,避免这些工具导致应用镜像的安全性降低。
    3. 应用镜像的创建者和部署者可以各自独立工作,而没有必要联合构建一个单独的应用镜像。
    4. Init 容器能以不同于 Pod 内应用容器的文件系统视图运行。因此,Init 容器可具有访问 Secrets的权限,而应用容器不能够访问。
    5. 由于 Init 容器必须在应用容器启动之前运行完成,因此 Init容器提供了一种机制来阻塞或延迟应用容器的启动,直到满足了一组先决条件。一旦前置条件满足,Pod 内的所有的应用容器会并行启动。

    1.3 应用容器(main container)

    应用容器会在 init 容器完成并退出后并行启动。

    1.4 操作示例

    参考官网:init容器说明
    下面的例子定义了一个具有 2 个 Init 容器的简单 Pod。 第一个等待 myservice 启动, 第二个等待 mydb 启动。 一旦这两个 Init容器 都启动完成,Pod 将启动 spec 节中的应用容器。

    1. 编写yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: myapp-pod
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp-container
        image: busybox:1.28
        command: ['sh','-c','echo The app is running! && sleep 3600']
      initContainers:
      - name: init-myservice
        image: busybox:1.28
        command: ['sh','-c','until nslookup myservice;do echo waiting for myservice; sleep2; done;']
      - name: init-mydb
        image: busybox:1.28
        command: ['sh','-c','until nslookup mydb; do echo waiting for mydb; sleep 2; done;']
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在这里插入图片描述

    1. 发布资源
    kubectl apply -f myapp.yaml
    kubectl get pod
    
    • 1
    • 2

    在这里插入图片描述

    1. 查看pod创建过程
    kubectl describe pod myapp-pod
    
    
    • 1
    • 2

    在这里插入图片描述
    发现开启 init-myservice 容器后,创建步骤停滞,查看 init-myservice 日志进一步查明原因。

    1. 查看pod日志
    kubectl logs myapp-pod -c init-myservice
    
    
    • 1
    • 2

    在这里插入图片描述

    1. 编写myservice.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: myservice
    spec:
      ports:
      - protocol: TCP
        port: 80
        targetPort: 1111
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述

    1. 发布myservice.yaml
    kubectl create -f myservice.yaml 
    
    • 1

    在这里插入图片描述
    在此我们可以看到init变为了,1/2,但是pod还是没有完全拉起

    1. 编写mydb.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: mydb
    spec:
      ports:
      - protocol: TCP
        port: 80
        targetPort: 2222
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述

    1. 发布mydb.yaml
    kubectl create -f mydb.yaml
    kubectl get pod,svc
    
    • 1
    • 2

    在这里插入图片描述

    1. 查看pod详细信息
    kubectl describe pod myapp-pod
    
    • 1

    在这里插入图片描述

    1. 创建过程中第一次停滞,是 init-myservice 容器启动后,未能发现 myservice 域名,无法得到解析,因此陷入循环。
    2. 第二次停滞,是 init-mydb 容器启动后,未能发现 mydb 域名,无法得到解析,因此再次陷入循环中。
    3. 在上述两个 init 容器成功并退出后,myapp-pod 才开始创建,否则 pod 无法创建。

    小结

    1. 在 Pod 启动过程中,Init 容器会按顺序在网络和数据卷初始化之后启动。每个容器必须在下一个容器启动之前成功退出。
    2. 如果由于运行时或失败退出,将导致容器启动失败,它会根据 Pod 的 restartPolicy 指定的策略进行重试。然而,如果 Pod的 restartPolicy 设置为 Always,Init 容器失败时会使用 RestartPolicy 策略。
    3. 在所有的 Init 容器没有成功之前,Pod 将不会变成 Ready 状态。Init 容器的端口将不会在 Service中进行聚集。正在初始化中的 Pod 处于 Pending 状态,但应该会将 Initializing 状态设置为 true。
    4. 如果 Pod 重启,所有 Init 容器必须重新执行。
    5. 对 Init 容器 spec 的修改被限制在容器 image 字段,修改其他字段都不会生效。更改 Init 容器的 image字段,等价于重启该 Pod。
    6. Init 容器具有应用容器的所有字段。除了 readinessProbe,因为 **Init容器无法定义不同于完成(completion)的就绪(readiness)之外的其他状态。**这会在验证过程中强制执行。
    7. 在 Pod 中的每个 app 和 Init 容器的名称必须唯一;与任何其它容器共享同一个名称,会在验证时抛出错误。

    二. 镜像拉取策略(imagePullPolicy)

    Pod的核心是运行容器,必须指定容器引擎,比如Docker,启动容器时需要拉取镜像,k8s的镜像拉取策略可以由用户指定:

    1. IfNotPresent:在镜像已经存在的情况下,kubelet将不再去拉取镜像,仅当本地缺失时才会从仓库中拉取,默认的镜像拉取策略。
    2. Alaways:每次创建Pod都会重新拉取一次镜像
    3. Never:Pod不会主动拉取这个镜像,仅使用本地镜像。
      注意:对于标签为latest的镜像文件,其默认的镜像获取策略即为Always;而对于其他标签的镜像,其默认策略则为IfNotPresent。

    2.1 使用always策略下载镜像

    参考官网:镜像拉取策略说明

    apiVersion: v1
    kind: Pod
    metadata:
      name: mypod
    spec:
      containers:
        - name: nginx
          image: nginx
          imagePullPolicy: Always
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述
    发布

    kubectl apply -f test.yaml
    
    • 1

    查看pod信息

    kubectl describe pod mypod
    
    • 1

    在这里插入图片描述
    修改pod名,并再次发布
    在这里插入图片描述
    在这里插入图片描述

    2.2 使用IfNotPresent策略下载镜像

    再次修改yaml文件,更改pod名与策略
    在这里插入图片描述
    再次发布,并查看pod2信息

    在这里插入图片描述
    删除本地镜像,并再次修改yaml文件的pod名
    在node节点删除镜像
    在这里插入图片描述
    在这里插入图片描述

    2.3 使用Never策略,镜像拉取

    删除本地镜像,再次修改yaml文件
    在这里插入图片描述
    在这里插入图片描述

    三. 私有仓库部署

    使用harbor私有仓库存储镜像
    需要在node节点设置私有仓库地址
    在harbor仓库新建一个项目xy,并上传一个镜像文件用于待会测试
    在这里插入图片描述
    在这里插入图片描述
    查看下载次数
    在这里插入图片描述

    在k8s的所有node节点上修改私有仓库地址

    vim /etc/docker/daemon.json
    {
      "insecure-registries": ["192.168.48.10"]
    }
    systemctl daemon-reload
    systemctl restart docker
    #登录私有仓库,随便选择一个node节点进行登录
    docker login 192.168.48.10
    #查看登录凭据
    cat .docker/config.json |base64 -w 0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述
    在这里插入图片描述
    制作harbor认证
    在master节点创建yaml文件
    vim registry-pull-secret.yaml

    apiVersion: v1
    kind: Secret
    metadata:
      name: registry-pull-secret
    data:
      .dockerconfigjson: ewoJImF1dGhzIjogewoJCSIxOTIuMTY4LjQ4LjEwIjogewoJCQkiYXV0aCI6ICJZV1J0YVc0NlNHRnlZbTl5TVRJek5EVT0iCgkJfQoJfQp9
    type: kubernetes.io/dockerconfigjson
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述

    在这里插入图片描述
    测试
    编写一个nginx的yaml文件

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
      labels:
        app: nginx
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          imagePullSecrets:
          - name: registry-pull-secret
          containers:
          - name: nginx
            image: 192.168.48.10/xy/nginx:v1
            ports:
            - containerPort: 80
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx
    spec:
      type: NodePort
      ports:
      - port: 80
        targetPort: 80
        nodePort: 30080
      selector:
        app: nginx
    
    • 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
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    进行发布

    kubectl apply -f nginx-deploy.yaml
    kubectl get pod
    
    • 1
    • 2

    在这里插入图片描述
    在harbor仓库查看下载次数
    在这里插入图片描述

    打开浏览器进行访问:30080端口
    在这里插入图片描述

  • 相关阅读:
    c++ 函数重载
    【深度学习】特征融合的重要方法 | 张量的拼接 | torch.cat()函数 | torch.add(函数
    爬虫入门四(抽屉半自动点赞、xpath使用、动作链、打码平台、scrapy框架介绍与安装及创建项目)
    使用QUME搭建ZNS SSD
    Confluence 解决PDF导出乱码问题
    仓库管理无纸化,WMS仓库管理软件+条形码技术
    【linux命令讲解大全】083.Linux 常用命令ispell , spell , atrm, chattr
    关系数据库
    Flex 布局,学会瞬间让你不再掉头发,让布局变的更简单
    EasyNLP 集成 K-BERT 算法,借助知识图谱实现更优 Finetune
  • 原文地址:https://blog.csdn.net/weixin_44175418/article/details/126110715