首页 > 其他分享 >K8S之Pod进阶

K8S之Pod进阶

时间:2025-01-14 20:05:11浏览次数:3  
标签:容器 进阶 -- Init 镜像 Pod K8S name

文章目录

容器

容器的状态

容器的状态——
Waiting处于Waiting状态的容器仍在运行它完成启动所需要的操作:例如, 从某个容器镜像仓库拉取容器镜像,或者向容器应用Secret数据等等。
RunningRunning状态表明容器正在执行状态并且没有问题发生。 如果配置了postStart回调,那么该回调已经执行且已完成。
Terminating处于Terminated状态的容器开始执行后,或者运行至正常结束或者因为某些原因失败。
CrashBackOff这一状态表明,对于一个给定的、处于崩溃循环、反复失效并重启的容器, 回退延迟机制目前正在生效。

pod实例

apiVersion: v1
kind: Pod
metadata:
  name: demo-pod
  namespace: demo
  labels:
    app: nginx
spec:
  containers:
  imagePullSecrets: # Pull镜像时使用的仓库名称
    - name:  aliyun
  - name: nginx
    image: nginx:1.20.2# 镜像名称
    imagePullPolicy: Always# 镜像拉取策略:IfNotPresent(默认)、Always、Never
    env: # 环境变量 相当于 docker run -e  xxx = xxx
    - name: MYSQL_ROOT_PASSWORD
      value: "123456"
    - name:  MYSQL_DATABASE
      value: ssm
    commend: ["/bin/sh","-c","Eouch /tmp/hello.txt;while true;do /bin/echo $(date +%T) >> /tmp/hello.txt; sleep 3; done;"]
    args:
      - "--lower_case_table_names=1"
      - "--character-set-server=utf8mb4"
      - "--collation-server=utf8mb4_general_ci"
      - "--default-authentication-plugin=mysql_native_password"    
    ports:
    - name: nginx-port
      containerPort:  80
      portocol: TCP
    resources: # 资源限制
      limits:
        cpu: 2
        memory: 1500M
      requests:
        cpu: 1
        memory: 1024M
    volumeMounts: # 卷挂载
      - name: localtime
        mountPath: /etc/localtime
      livenessProbe: # 探针
        exeс:
          command: ["/bin/ca]","/tmp/hello.txt"] #执行一个查看文件的命令
        initialDelaySeconds: 1# 探测延迟,RUNNING 后指定 20 秒后才执行探测,默认为 0 秒。
        periodSeconds: 5       # 执行探测的时间间隔(单位是秒),默认为 10 秒。
        successThreshold: 1    # 成功阈值:连续几次成功才算成功。探测器在失败后,被视为成功的最小连续成功数。默认值是 1 ,存活和启动探针的这个值必须是 1。最小值是 1。
        failureThreshold: 3    # 失败阈值:连续几次失败才算失败。当探测失败时,Kubernetes 的重试次数。 存活探测情况下的放弃就意味着重新启动容器。 就绪探测情况下的放弃 Pod 会被打上未就绪的标签。默认值是 3。最小值是 1。
        timeoutSeconds: 5      # 探测的超时后等待多少秒。默认值是 1 秒。最小值是 1。
  - name: arcgis
    image: registry.cn-shanghai.aliyuncs.com/xudaxian/arcgis/v1.0
    imagePullPolicy: Always
  restartPolicy: Always

配置镜像仓库

# -n demo :表示该密钥将只在指定的名称空间 demo 中生效
# docker-registry aliyun :指定 Docker 镜像仓库的名称
# --docker-server:Docker 镜像仓库的地址
# --docker-username:Docker 镜像仓库的用户名
# --docker-password:Docker 镜像仓库的密码
kubectl create secret -n demo docker-registry aliyun \
       --docker-server=registry.cn-shanghai.aliyuncs.com \
       --docker-username=xudaxian \
       --docker-password=123456

拉镜像默认值

  • 如果镜像tag为具体版本号,默认策略是: IfNotPresent
  • 如果镜像tag为: latest(最终版本),默认策略是always

特别说明

  • 通过上面发现command已经可以完成启动命令和传递参数的功能,为什么这里还要提供一个args选项,用于传递参数呢?
  • 这其实跟docker类似,kubernetes中的command, args两项其实是实现覆盖Dockerfile中ENTRYPoINT的功能。
    • 如果command和args均没有写,那么用Dockerfile的配置。
    • 如果command写了,但args没有写,那么Dockerfile默认的配置会被忽略,执行输入的command
    • 如果command没写,但args写了,那么Dockerfile中配置的ENTRYPOINT的命令会被执行,使用当前args的参数
    • 如果command和args都写了,那么Dockerfile的配置被忽略,执行command并追加上args参数

容器重启策略

Pod 的spec中包含一个restartPolicy字段,其可能取值包括 Always、OnFailure 和 Never。默认值是 Always。

  • Always:只要容器终止就自动重启容器。
  • OnFailure:只有在容器错误退出(退出状态非零)时才重新启动容器。
  • Never:不会自动重启已终止的容器。

Init 容器

Init 容器与普通的容器非常像,除了如下两点:

  • 它们总是运行到完成。
  • 每个都必须在下一个启动之前成功完成。(初始化容器是串行化过程)
    如果 Pod 的 Init 容器失败,kubelet 会不断地重启该 Init 容器直到该容器成功为止。 然而,如果 Pod 对应的 restartPolicy 值为 “Never”,Kubernetes 不会重新启动 Pod。并且 Pod 的 Init 容器失败, 则 Kubernetes 会将整个 Pod 状态设置为失败。

Init容器优势

  • Init 容器可以包含一些安装过程中应用容器中不存在的实用工具或个性化代码。 例如,没有必要仅为了在安装过程中使用类似sed、awk、python或dig这样的工具而去FROM一个镜像来生成一个新的镜像。
  • 应用镜像的创建者和部署者可以各自独立工作,而没有必要联合构建一个单独的应用镜像。
  • 与同一 Pod 中的多个应用容器相比,Init 容器能以不同的文件系统视图运行。因此,Init 容器可以被赋予访问应用容器不能访问的Secret的权限。
  • 由于 Init 容器必须在应用容器启动之前运行完成,因此 Init 容器提供了一种机制来阻塞或延迟应用容器的启动,直到满足了一组先决条件。 一旦前置条件满足,Pod 内的所有的应用容器会并行启动。
  • Init 容器可以安全地运行实用程序或自定义代码,而在其他方式下运行这些实用程序或自定义代码可能会降低应用容器镜像的安全性。 通过将不必要的工具分开,你可以限制应用容器镜像的被攻击范围。

Init容器实例

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app.kubernetes.io/name: 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.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
  - name: init-mydb
    image: busybox:1.28
    command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]

特殊说明

  • 在 Pod 启动过程中,每个 Init 容器会在网络和数据卷初始化之后按顺序启动。 每个 Init 容器成功退出后才会启动下一个 Init 容器。 如果某容器因为容器运行时的原因无法启动,或以错误状态退出,kubelet 会根据 Pod 的 restartPolicy 策略进行重试。 然而,如果 Pod 的 restartPolicy 设置为 “Always”,Init 容器失败时会使用 restartPolicy 的 “OnFailure” 策略。
  • 在所有的 Init 容器没有成功之前,Pod 将不会变成 Ready 状态。 Init 容器的端口将不会在 Service 中进行聚集。正在初始化中的 Pod 处于 Pending 状态, 但会将状况 Initializing 设置为 true。
  • 如果 Pod 重启,所有 Init 容器必须重新执行。
  • 对 Init 容器规约的修改仅限于容器的 image 字段。 更改 Init 容器的 image 字段,等同于重启该 Pod。
  • 因为 Init 容器可能会被重启、重试或者重新执行,所以 Init 容器的代码应该是幂等的。 特别地,基于 emptyDirs 写文件的代码,应该对输出文件可能已经存在做好准备。
  • Init容器只有完成状态,所以不需要、也没有就绪检测、存活检测。
  • 在 Pod 中的每个应用容器和 Init 容器的名称必须唯一, 与任何其它容器共享同一个名称,会在校验时抛出错误。

临时容器

  • 临时容器是一种特殊的容器,该容器可以在现有的 Pod 中临时运行,以便完成我们发起的操作,比如故障排查。我们应该使用临时容器来检查服务,而不是用临时容器来构建应用程序。
  • 临时容器和其他容器的不同之处在于,它们缺少对资源或执行的保证,并且永远不会自动重启,因此不适合用来构建应用程序。临时容器使用和常规容器相同的 ContainerSpec 来描述,但是许多字段是不兼容或者不允许的。
    临时容器没有端口配置,因此像 portslivenessProbereadinessProbe这样的字段是没有的。
  • Pod 的资源分配是不可变的,因此 resources 这样的配置临时容器也是没有的。
  • 临时容器是使用 ephemeralcontainers 来进行创建的,而不是直接添加到 pod.spec 中,所以是无法使用 kubectl edit 来添加一个临时容器。
  • 当由于容器奔溃或容器镜像不包含调试工具而导致 kubectl exec 无用的时候,临时容器对于交互式故障排查非常有用。

hook 钩子函数

  • 钩子函数能够感知自身生命周期中的事件,并在相应的时刻到来时运行用户指定的程序代码。
  • Kubernetes 在主容器启动之后和停止之前提供了两个钩子函数:
    • postStart:容器创建之后执行,如果失败会重启容器。
    • preStop:容器终止之前执行,执行完成之后容器将成功终止,在其完成之前会阻塞删除容器的操作。
  • 钩子处理器支持使用下面的三种方式定义动作:
    • exec 命令:在容器内执行一次命令。
    • tcpSocket:在当前容器尝试访问指定的 socket。
    • httpGet:在当前容器中向某 url 发起 HTTP 请求(应用程序使用此种方式最多)

容器探针

  • 探针是kubelet检测容器的方式,有四种探测方式:exec(执行命令成功)、grpc(调用成功)、http(调用成功)、tcp(调用成功)。
  • 有三种探针:
    • livenessProbe(存活探针):指示容器是否正在运行。周期性执行。 如果存活态探测失败,则 kubelet 会杀死容器, 并且容器将根据其重启策略决定未来。如果容器不提供存活探针, 则默认状态为 Success。
    • readinessProbe(就绪探针):指示容器是否准备好为请求提供服务。周期性执行。 如果就绪态探测失败, 端点控制器将从与 Pod 匹配的所有服务的端点列表中删除该 Pod 的 IP 地址。 初始延迟之前的就绪态的状态值默认为 Failure。 如果容器不提供就绪态探针,则默认状态为 Success。
    • startupProbe(启动探针): 指示容器中的应用是否已经启动。仅在容器启动的时候执行,不像其他两类指针一样一直执行。 如果提供了启动探针,则所有其他探针都会被禁用,直到此探针成功为止。如果启动探测失败,kubelet 将杀死容器,而容器依其 重启策略进行重启。 如果容器没有提供启动探测,则默认状态为 Success。

何时该使用启动探针

  • 对于所包含的容器需要较长时间才能启动就绪的 Pod 而言,启动探针是有用的。
  • 你不再需要配置一个较长的存活态探测时间间隔,只需要设置另一个独立的配置选定,对启动期间的容器执行探测,从而允许使用远远超出存活态时间间隔所允许的时长。

Pause(Infra) 容器

背景

  • Pod 需要让里面的多个容器之间最高效的共享某些资源和数据。
  • 因为容器之间原本是被 Linux Namespace 和 cgroups 隔开的,所以现在实际要解决的是怎么去打破这个隔离,然后共享某些事情和某些信息。
  • 所以说具体的解法分为两个部分:网络和存储。
  • Pause 容器就是为解决 Pod 中的网络问题而生的。

实现

  • Infra container 是一个非常小的镜像,大概 700KB 左右,是一个 C 语言写的、永远处于“暂停”状态的容器。由于有了这样一个 Infra container 之后,其他所有容器都会通过 Join Namespace 的方式加入到 Infra container 的 Network Namespace 中。
  • 所以说一个 Pod 里面的所有容器,它们看到的网络视图是完全一样的。即:它们看到的网络设备、IP 地址、Mac 地址等等,跟网络相关的信息,其实全是一份,这一份都来自于 Pod 第一次创建的这个 Infra container。在 Pod 里面有一个 IP 地址,是这个 Pod 的 Network Namespace 对应的地址,也是这个 Infra container 的 IP 地址。
  • 由于需要有一个相当于说中间的容器存在,所以整个 Pod 里面,必然是 Infra container 第一个启动。并且整个 Pod 的生命周期是等同于 Infra container 的生命周期的,与容器 A 和 B 是无关的。

Pause 容器的作用

在这里插入图片描述

kubernetes 中的 pause 容器主要为每个业务容器提供以下功能:

  • 在 pod 中担任 Linux 命名空间共享的基础;
  • 启用 pid 命名空间,开启 init 进程。

我们首先在节点上运行一个 pause 容器。

docker run -d --name pause -p 8880:80 --ipc=shareable jimmysong/pause-amd64:3.0

然后再运行一个 nginx 容器,nginx 将为localhost:2368创建一个代理。

$ cat <<EOF >> nginx.conferror_log stderr;events { worker_connections  1024; }http {    access_log /dev/stdout combined;    server {        listen 80 default_server;        server_name example.com www.example.com;        location / {            proxy_pass http://127.0.0.1:2368;        }    }}EOF$ docker run -d --name nginx -v `pwd`/nginx.conf:/etc/nginx/nginx.conf --net=container:pause --ipc=container:pause --pid=container:pause nginx

然后再为ghost创建一个应用容器,这是一款博客软件。

$ docker run -d --name ghost --net=container:pause --ipc=container:pause --pid=container:pause ghost

现在访问 http://localhost:8880/ 就可以看到 ghost 博客的界面了。

解析

  • pause 容器将内部的 80 端口映射到宿主机的 8880 端口,pause 容器在宿主机上设置好了网络 namespace 。
  • nginx 容器加入到该网络 namespace 中,我们看到 nginx 容器启动的时候指定了–net=container:pause,ghost 容器同样加入到了该网络 namespace 中。
  • 这样三个容器就共享了网络,互相之间就可以使用localhost直接通信,–ipc=contianer:pause --pid=container:pause就是三个容器处于同一个 namespace 中,init 进程为pause,这时我们进入到 ghost 容器中查看进程情况。

Pod Preset

  • 有时候想要让一批容器在启动的时候就注入一些信息,比如 secret、volume、volume mount 和环境变量,而又不想一个一个的改这些 Pod 的 template,这时候就可以用到 Pod Preset 这个资源对象了。
  • Pod Preset是用来在 Pod 被创建的时候向其中注入额外的运行时需求的 API 资源。
  • 您可以使用label selector来指定为哪些 Pod 应用 Pod Preset。
  • 使用 Pod Preset 使得 pod 模板的作者可以不必为每个 Pod 明确提供所有信息。这样一来,pod 模板的作者就不需要知道关于该服务的所有细节。

如何工作

  • Kubernetes 提供了一个准入控制器(PodPreset),当其启用时,Pod Preset 会将应用创建请求传入到该控制器上。当有 Pod 创建请求发生时,系统将执行以下操作:
  1. 检索所有可用的PodPresets。
  2. 检查 PodPreset 标签选择器上的标签,看看其是否能够匹配正在创建的 Pod 上的标签。
  3. 尝试将由PodPreset定义的各种资源合并到正在创建的 Pod 中
  4. 出现错误时,在该 Pod 上引发记录合并错误的事件,PodPreset不会注入任何资源到创建的 Pod 中。
  5. 注释刚生成的修改过的 Pod spec,以表明它已被 PodPreset 修改过。
  • 每个 Pod 可以匹配零个或多个 Pod Prestet;并且每个PodPreset可以应用于零个或多个 Pod。PodPreset应用于一个或多个 Pod 时,Kubernetes 会修改 Pod Spec。对于Env、EnvFrom和VolumeMounts的更改,Kubernetes 修改 Pod 中所有容器的容器 spec;对于Volume的更改,Kubernetes 修改 Pod Spec。
  • 注意:Pod Preset 可以在适当的时候修改 Pod spec 中的spec.containers字段。Pod Preset 中的资源定义将不会应用于initContainers字段。

标签:容器,进阶,--,Init,镜像,Pod,K8S,name
From: https://blog.csdn.net/woshihlf/article/details/145146328

相关文章

  • 敏捷团队的进阶之路:工具的实践与应用
    ​在当今快节奏、高竞争的商业环境中,“敏捷”已经从一种开发模式演变为广泛适用于各行业的工作哲学。然而,对于很多团队来说,敏捷并不仅仅是学习几个概念或框架,更是如何在日常实践中将这些理念真正落地。而在这个过程中,敏捷工具的作用显得尤为重要。为什么敏捷工具成为敏捷落地的......
  • AIGC从入门到实战:进阶:魔法打败魔法,让 AI 自动生成提示词
    AIGC,提示词生成,自然语言处理,深度学习,Transformer,预训练模型,算法原理,实践应用1.背景介绍近年来,人工智能生成内容(AIGC)技术蓬勃发展,以其强大的文本生成能力,在创作、翻译、摘要等领域展现出巨大的潜力。然而,AIGC的应用离不开高质量的提示词,而手工撰写提示词......
  • 20250114基础k8s部分
    20250114基础k8s部分No1.Kubernetes项目要解决的问题是什么?编排?调度?容器云?还是集群管理?对于大多数用户来说,他们希望Kubernetes项目带来的体验是确定的:现在我有了应用的容器镜像,请帮我在一个给定的集群上把这个应用运行起来。进一步地说,我还希望Kubernetes能给我提供路由网......
  • 织梦CMS进阶 - 修改织梦网站模板的详细步骤与实用技巧
    织梦(DedeCMS)是一款流行的开源内容管理系统,广泛应用于企业官网和个人博客建设。以下是关于如何修改织梦网站模板的一些基本指导和高级技巧:登录后台管理界面使用管理员账号登录织梦后台,进入“模板管理”模块。在这里您可以上传、编辑或删除现有的模板文件。同时,通过修改CSS文件来......
  • KuboardSpray v1.2.4 在 Rocky Linux 9.5 上部署 K8s 失败报错“当前资源包不支持此操
    KuboardSpray报错日志截图进入KuboardSpray的docker容器实例里的当前用户目录下,再用find.-name"*.yaml"|xargs-igrep-iHn"distribution:Rocky"{}查找声明RockyLinux系统版本的地方,如下图解决办法:只需对上图中红框处的3个配置文件进行修改,加上较新版本的Rock......
  • 2024大模型实战指南:大模型学习,从小白到专家的详细步骤与进阶策略!
    前言随着人工智能技术的迅猛发展,大模型(LargeModels)已成为这一领域的新宠。从GPT系列到BERT,再到各类变体,大模型以其强大的能力吸引了无数开发者和研究者的目光。那么,作为一个零基础的学习者,如何快速入门并精通大模型技术呢?本文将为你提供一份详尽的学习指南。一、大模型基......
  • NLP 进阶:BERT + CRF 用于命名实体识别(NER)
    引言:命名实体识别(NER)是自然语言处理(NLP)中的一项关键任务,它帮助我们从文本中识别出具有特定意义的实体,例如人名、地名、组织机构等。在许多NER任务中,结合BERT和CRF(条件随机场)提供了强大的性能提升。今天,我们将深入探讨如何将BERT与CRF结合,打造一个高效、精准的命名实......
  • NLP 进阶:BERT + CNN 结合打造高效文本分类模型!
    引言:在自然语言处理(NLP)中,文本分类任务是一个核心问题,涵盖了情感分析、新闻分类、垃圾邮件检测等多个领域。传统的深度学习方法虽然取得了一定的成效,但随着BERT(BidirectionalEncoderRepresentationsfromTransformers)和CNN(ConvolutionalNeuralNetworks)技术的出现,文本分......
  • 欧拉OpenEuler基于Kubeasz部署k8s.250114
    欧拉OpenEuler基于Kubeasz部署k8s系统优化修改主机名hostnamectlset-hostnamePRD-MS-K8S01vim/etc/hosts172.62.17.101PRD-MS-K8S01172.62.17.102PRD-MS-K8S02172.62.17.103PRD-MS-K8S03关闭防火墙systemctlstopfirewalldsystemctldisablefirewalld关闭se......
  • 从代码先锋到团队统帅:技术领导力的进阶之路
    解释什么是技术领导力,列举一些具有技术领导力的程序员的特征和行为。深入剖析技术领导力的重要性,为什么一名程序员在技术领导力上做得好会使得团队更有凝聚力,更有效率和创新性>前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮......