【云原生--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. 发布资源
kubectl apply -f myapp.yaml
kubectl get pod

在这里插入图片描述

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

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

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

在这里插入图片描述

  1. 编写myservice.yaml
apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 1111

在这里插入图片描述

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

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

  1. 编写mydb.yaml
apiVersion: v1
kind: Service
metadata:
  name: mydb
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 2222

在这里插入图片描述

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

在这里插入图片描述

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

在这里插入图片描述

  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

在这里插入图片描述
发布

kubectl apply -f test.yaml

查看pod信息

kubectl describe pod mypod

在这里插入图片描述
修改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

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

apiVersion: v1
kind: Secret
metadata:
  name: registry-pull-secret
data:
  .dockerconfigjson: ewoJImF1dGhzIjogewoJCSIxOTIuMTY4LjQ4LjEwIjogewoJCQkiYXV0aCI6ICJZV1J0YVc0NlNHRnlZbTl5TVRJek5EVT0iCgkJfQoJfQp9
type: kubernetes.io/dockerconfigjson

在这里插入图片描述

在这里插入图片描述
测试
编写一个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

进行发布

kubectl apply -f nginx-deploy.yaml
kubectl get pod

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

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

猜你喜欢

转载自blog.csdn.net/weixin_44175418/article/details/126110715
今日推荐