如何建立Pod


一、Pod的生命周期

建立pod

1. 提交 Pod 定义

  • 用户或控制器提交请求:用户通过 kubectl apply 命令或 Kubernetes 控制器(如 Deployment 控制器)提交包含 Pod 定义的 YAML 或 JSON 文件到 Kubernetes API 服务器。
  • Pod Spec 定义:Pod 包含详细的定义,如容器镜像、资源请求、环境变量、卷挂载等。

2. API 服务器处理

  • 验证和持久化:API 服务器接收到请求后,会验证请求格式和内容。通过验证的请求会被存储到 etcd(Kubernetes 的分布式数据库)中。
  • 对象创建:一旦存储在 etcd 中,Pod 就被正式创建,标记为 Pending 状态。

3. 调度

  • Kube-Scheduler 调度决定:Kubernetes 调度器监控未调度的 Pod,选择适合的节点来运行 Pod。
  • 节点选择:调度器根据资源需求、节点可用容量、亲和性/反亲和性、污点和容忍度等来选择节点。

4. 节点准备

  • Kubelet 执行动作:一旦 Pod 被分配到节点,节点上的 kubelet(节点代理)会获取 Pod 规范,负责在节点上进行 Pod 的管理。
  • 下载容器镜像:如果指定的容器镜像尚未存在于节点上,kubelet 使用容器运行时(如 Docker、containerd)来下载镜像。

5. 容器初始化

  • 执行 Init Containers(如果有):在应用容器启动之前,所有 Init 容器按顺序执行,如果任何一个失败,整个 Pod 都不能启动。
  • 配置网络和存储:kubelet 设置网络配置(如分配 IP 地址),并准备持久化存储卷(如 PVC)以供 Pod 使用。

6. 启动应用容器

  • 运行主容器:完成初始化之后,kubelet 启动 Pod 的应用容器。
  • 健康检查和监控:kubelet 定期检查 Pod 的健康状态和生命周期事件,并更新状态。

7. 持续管理

  • 监控和修复:kubelet 控制循环会不停检查 Pod 状态,如果容器崩溃(在配置重启策略时),kubelet 会尝试重新启动它。
  • 日志记录和收集:容器的日志可以被集群的日志系统(如 Fluentd)收集和存储,以便日后分析。

Pod结束

pod结束运行的过程是一个优雅的终止流程,确保容器有机会完成当前工作并释放资源。

  1. Pod running

    • Pod 正在运行中,所有容器都处于正常工作状态。
  2. Terminating

    • 当你删除 Pod 时,Pod 进入 Terminating 状态。此时,Kubernetes 开始执行优雅的终止流程。
  3. preStop hook

    • 如果 Pod 配置了 preStop 钩子,Kubernetes 会在发送终止信号之前执行这个钩子。preStop 钩子允许你在容器终止前执行一些清理操作或其他必要的任务。
  4. SIGTERM

    • Kubernetes 向 Pod 中的每个容器发送 SIGTERM 信号。SIGTERM 信号通知容器应该开始优雅地关闭,完成当前处理的请求并释放资源。
  5. terminationGracePeriodSeconds

    • Kubernetes 等待一段时间,称为 terminationGracePeriodSeconds,默认值为 30 秒。在这段时间内,容器有机会完成优雅关闭。如果容器在这段时间内没有终止,Kubernetes 将强制终止它。
  6. SIGKILL

    • 如果容器在 terminationGracePeriodSeconds 内没有终止,Kubernetes 会发送 SIGKILL 信号。SIGKILL 信号会立即终止容器,不再等待优雅关闭。
  7. Deleted

    • 当所有容器都终止后,Pod 资源会从 Kubernetes 集群中删除,Pod 进入 Deleted 状态。

Pod的探针

在 Kubernetes 中,探针(Probe)用于检测 Pod 中容器的健康状况和运行状态。探针有三种类型:存活探针(Liveness Probe)、就绪探针(Readiness Probe) 和 启动探针(Startup Probe)。每种探针都有不同的用途和配置方式。

1. 存活探针(Liveness Probe)

  • 用途:检测容器是否处于健康状态。如果存活探针失败,Kubernetes 会重启容器。
  • 配置:可以通过 HTTP 请求、TCP 连接或执行命令来配置。

2. 就绪探针(Readiness Probe)

  • 用途:检测容器是否已经准备好接受流量。如果就绪探针失败,Kubernetes 会将 Pod 从服务的端点列表中移除。
  • 配置:可以通过 HTTP 请求、TCP 连接或执行命令来配置。

3. 启动探针(Startup Probe)

  • 用途:检测容器是否已经成功启动。如果启动探针失败,Kubernetes 会重启容器。启动探针只在容器启动期间运行,一旦成功,其他探针(如存活探针和就绪探针)将接管。
  • 配置:可以通过 HTTP 请求、TCP 连接或执行命令来配置。

探针一般是配置在yaml文件中。

apiVersion: v1  
kind: Pod  
metadata:  
  name: example-pod  
spec:  
  containers:  
  - name: example-container  
    image: example-image  
    livenessProbe:  
      httpGet:  
        path: /healthz  路径,应用程序会暴露一个健康检查的URL
        port: 8080  
      initialDelaySeconds: 5  
      periodSeconds: 10

pod的钩子

在 Kubernetes 中,Pod 的生命周期钩子(Lifecycle Hooks)允许你在容器的生命周期的特定事件发生时执行自定义的操作。主要有两种类型的生命周期钩子:PostStart 和 PreStop。这些钩子可以帮助你对容器的启动和终止进行更精细的控制。

1. PostStart 钩子

  • 用途:在容器启动后立即执行一些初始化任务。这是在容器的入口点执行之前调用的。
  • 用例:可以用于初始化应用程序状态、记录启动日志或执行其他需要在应用启动前完成的操作。

2. PreStop 钩子

  • 用途:在 Kubernetes 终止容器之前执行一些清理或收尾工作。
  • 用例:用于完成与外部系统的正常关机、注销服务注册和状态保存等任务,以确保优雅停止。

运行机制

  • PostStart:在容器创建完毕并且所有 init 容器运行后立即调用。
  • PreStop:在 Kubernetes 向容器发送 SIGTERM 信号之前调用,给予容器机会进行收尾工作。
apiVersion: v1  
kind: Pod  
metadata:  
  name: example-pod  
spec:  
  containers:  
  - name: example-container  
    image: example-image  
    lifecycle:  
      postStart:  
        exec:  
          command: ["/bin/sh", "-c", "echo Hello from the postStart hook > /var/log/postStart.txt"]  
      preStop:  
        exec:  
          command: ["/bin/sh", "-c", "echo Goodbye from the preStop hook"]

二、使用yaml文件去启动pod

普通yaml文件启动pod

应用yaml文件来应用并启动pod。

kubectl apply -f pod-example.yaml

关闭pod

kubectl delete -f pod-example.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: harbor.hiuiu.com/nginx/nginx:1.21.5
    ports:
    - containerPort: 80

在这个YAML文件中:

  • apiVersion: v1 定义了API的版本。

  • kind: Pod 指明这个文件描述的是一个Pod。

  • metadata 包含了Pod的名字和标签,通过标签可以实现对Pod的分组和查询。

  • spec 部分描述了Pod内部的状态:

    • containers 列表定义了Pod中运行的一个或多个容器,这里使用了一个基于 nginx:latest 镜像的容器。
    • ports 定义了哪些端口需要暴露给集群中的其他组件。
      在这里插入图片描述
      注意:
      这里面还有个镜像拉取原则。
      imagePullPolicy 是一个用于控制在 Kubernetes 中如何拉取容器镜像的策略。它有三个选项:
  1. Always:每次启动容器时,总是从镜像仓库拉取最新的镜像。
  2. Never:从不从镜像仓库拉取镜像。如果镜像已经存在于本地,则尝试启动容器;如果不存在,则启动失败。
  3. IfNotPresent:只有当本地没有该镜像时才从镜像仓库拉取镜像。

默认镜像拉取策略设置规则:

  • 如果省略了 imagePullPolicy 字段,并且容器镜像的标签是 :latest

    • imagePullPolicy 会自动设置为 Always,以确保总是使用最新的镜像版本。
  • 如果省略了 imagePullPolicy 字段,并且没有为容器镜像指定任何标签:

    • imagePullPolicy 也会自动设置为 Always。在这种情况下,未指定标签通常被理解为使用 latest 标签。
  • 如果省略了 imagePullPolicy 字段,并且为容器镜像指定了非 :latest 的标签:

    • imagePullPolicy 会自动设置为 IfNotPresent,从而在本地不存在镜像的情况下才拉取镜像。

利用namespace进行资源限制生成pod

创建一个命名空间

kubectl create ns (namespace) test

切换当前默认的namespace

kubectl config set-context --current --namespace=test

查看当前namespace

kubectl config view

对命名空间的资源限制
查看命名空间的资源限制

kubectl get resourcequota -n test -o wide
apiVersion: v1  
kind: ResourceQuota  
metadata:  
  name: example-quota  
  namespace: test  
spec:  
  hard:  
    requests.cpu: "2"  
    requests.memory: "1Gi"  
    limits.cpu: "4"  
    limits.memory: "4Gi"  
    pods: "10"

ResourceQuota 是用来限制一个特定命名空间(在这里是 test 命名空间)中资源使用的对象。它可以帮助你在繁忙的环境中限制资源滥用。该配置的含义如下:

  • requests.cpu: "2":在这个命名空间中,所有 Pod 合起来可以请求的 CPU 资源最大值为 2 个 CPU。
  • requests.memory: "1Gi":在这个命名空间中,所有 Pod 合起来可以请求的内存资源最大值为 1 GiB。
  • limits.cpu: "4":在这个命名空间中,所有 Pod 合起来可以限制使用的 CPU 资源最大值为 4 个 CPU。
  • limits.memory: "4Gi":在这个命名空间中,所有 Pod 合起来可以限制使用的内存资源最大值为 4 GiB。
  • pods: "10":在这个命名空间中,最多可以存在 10 个 Pod。
    在这里插入图片描述
    如果命名空间受限制了,其后的每一个pod都要添加资源的限制内容,否则无法成功启动。
apiVersion: v1
kind: Pod  
metadata:  
  name: nginx
  namespace: test
spec:
  containers:
  - name: nginx
    image: harbor.hiuiu.com/nginx/nginx:1.21.5
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"
    ports:
      - containerPort: 8

在这里插入图片描述
当然,平常的pod也能限制资源,并非要在namespace下;但是有限制的namespace里的pod必须受限制才行。

下图删除相对应的命名空间,pod也会被删除。
在这里插入图片描述

副本控制器

在Kubernetes中,ReplicaSet(复制集)是用于确保在任何时候都有指定数量的Pod副本在运行的控制器。ReplicaSet的主要功能是维持Pod的稳定。

功能与作用

  1. 保持Pod数量一致:ReplicaSet会监控其管理的Pod的状态,并自动启动新的副本或删除多余的副本,以保持系统在用户定义的副本数量。
  2. 自动重启与故障恢复:如果有Pod意外终止或者节点故障导致Pod非正常消失,ReplicaSet会自动创建新的Pod来取代它。
  3. 滚动更新(与Deployment结合使用) :虽然ReplicaSet本身不直接支持滚动更新,但在与Deployment资源结合使用时,ReplicaSet可以参与到应用的滚动更新过程中。

相关命令
通常通过一个YAML配置文件来创建ReplicaSet:

kubectl apply -f replicaset.yaml  

查看当前命名空间中的所有ReplicaSet:

kubectl get replicasets  

查看特定ReplicaSet的详细信息:

kubectl describe replicaset <replicaset-name>
apiVersion: apps/v1  
kind: ReplicaSet  
metadata:  
  name: my-replicaset  
spec:  
  replicas: 10  
  selector:  
    matchLabels:  
      app: myapp  
  template:  
    metadata:  
      labels:  
        app: myapp  
    spec:  
      containers:  
      - name: mycontainer  
        image: harbor.hiuiu.com/nginx/nginx:1.21.5  
        ports:  
        - containerPort: 80

在这里插入图片描述
如果需要动态扩容怎么办?
只需要修改spec:
replicas: 5
然后重新执行yaml文件即可。注意:如果删除pod,repolicaset会自动创建该pod。

调度pod

在 Kubernetes 中,nodeName 和 nodeSelector 是用来指定 Pod 在某个节点上调度的两种方式。主要解决的是下面的问题如果需要将pod固定生成在某个节点上,该如何实现?

nodeName

  • 定义nodeName 是一个直接指定 Pod 需要调度到的节点名称。
  • 用法:当你在 Pod 规范中设置 nodeName 时,Kubernetes 调度器会跳过这个 Pod,而是将它直接指派到指定的节点上。因为没有调度的过程,这意味着如果指定的节点不可用或者不具备运行此 Pod 的条件,会导致 Pod 无法正常运行。

nodeSelector

  • 定义nodeSelector 是一种使用键值对的方式来限制 Pod 可以调度到哪些节点上。节点需要带有相应的标签才能被选中。
  • 用法nodeSelector 提供了一种简单的手段,通过基于标签的选择来指导调度器进行 Pod 指派。节点需要提前打上与 nodeSelector 匹配的标签。

实现方式

使用nodename

apiVersion: apps/v1
kind: ReplicaSet  
metadata:  
  name: my-replicaset
spec:
  replicas: 10
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: mycontainer
        image: harbor.hiuiu.com/nginx/nginx:1.21.5
        ports:
        - containerPort: 80
      nodeName: slave1
  #指定节点名字。

在这里插入图片描述
使用nodeSelector
使用这个必须要先在节点打上与之相匹配的标签。

给node打标签。
查看pod标签

kubectl get pod --show-labels

给pod打标签

kubectl label pod pod-name version=v1

查看节点的标签

kubectl get node --show-labels

给节点追加标签

kubectl label node slave1  nodename=one

给节点删除标签

kubectl label node slave1  nodename -

-L 后面跟随的标签键将作为附加列展示在 kubectl get 命令的输出中。

kubectl get pods  -L或--label-columns

-l 后面跟随的标签键值对用来过滤出拥有特定标签的资源。

kubectl get pods -l app=myapp
-l--selector

具体操作
给节点1加上标签

kubectl label node slave1 nodenum=first

在这里插入图片描述
在这里插入图片描述

apiVersion: apps/v1
kind: ReplicaSet  
metadata:  
  name: my-replicaset
spec:
  replicas: 10
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: mycontainer
        image: harbor.hiuiu.com/nginx/nginx:1.21.5
        ports:
        - containerPort: 80
      nodeSelector:
          nodenum: first
                        

注意:pod可能会出现Evicted状态。
在Kubernetes中,当节点资源紧张时,Kubelet可能会驱逐节点上的一些Pods以释放资源。当这种情况发生时,Pod的状态会被设置为"Evicted"。

利用亲和性调度pod

在 Kubernetes 中,Pod 亲和性(Affinity)是一种机制,用于影响 Pod 调度到节点上的策略。Pod 的亲和性规则可以帮助你控制哪些 Pod 应该一起或不应该一起调度到同一个节点上,从而提高应用程序的性能、可靠性以及资源利用效率。

Kubernetes 提供了两种主要的亲和性类型:

  1. 节点亲和性(Node Affinity)

    • 类似于 nodeSelector,但更灵活。

    • 允许你基于节点的标签,将 Pod 调度到满足特定条件的节点上。

    • 分为 “requiredDuringSchedulingIgnoredDuringExecution” 和 “preferredDuringSchedulingIgnoredDuringExecution” 两种类型:

      • requiredDuringSchedulingIgnoredDuringExecution:要求调度器严格满足节点亲和性规则。硬亲和。
      • preferredDuringSchedulingIgnoredDuringExecution:表示更倾向于满足节点亲和性规则,但不是非强制性的。软亲和
  2. Pod 亲和性和反亲和性(Pod Affinity and Anti-Affinity)

    • 允许你基于其他 Pod 的分布,控制 Pod 的调度。
    • 提供类似的 “required” 和 “preferred” 种类的规则。
    • Pod Affinity:要求调度器将新的 Pod 安排在某些具有特定标签的 Pod 运行的节点上。
    • Pod Anti-Affinity:要求调度器将新的 Pod 安排在没有特定标签的 Pod 运行的节点上。
  3. 实际操作

node的亲和性

kubectl explain pods.spec.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution
调度器将倾向于将pods调度到满足该字段指定的亲和性表达式的节点上,但它也可能选择违背一个或多个表达式的节点。最受青睐的节点是具有最大权重和的节点,即对于每个满足所有调度要求(资源请求、调度期间的亲和性表达式等)的节点,通过迭代该字段的元素计算和,如果节点匹配相应的匹配表达式,则为和添加“权重”,具有最高权重的节点是最受青睐的。---- 是软性偏好,表示调度器会尽量但不强求将Pod调度到满足特定条件的节点上。
kubectl explain pods.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution

如果调度时不满足该字段指定的亲和性要求,pod将不会被调度到该节点上。如果该字段指定的亲和性需求在pod执行期间的某个点停止满足(例如由于更新),系统可能会也可能不会尝试最终将pod从其节点中移除。---- 是硬性要求,表示Pod必须被调度到满足特定条件的节点上

硬限制

kubectl explain ReplicaSet.spec.template.spec.affinity.nodeAffinity
查询如何配置

在这里插入图片描述
给节点打上标签

kubectl label node slave1 zone=slave

在这里插入图片描述


apiVersion: apps/v1
kind: ReplicaSet  
metadata:  
  name: my-replicaset
spec:
  replicas: 10
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: mycontainer
        image: harbor.hiuiu.com/nginx/nginx:1.21.5
        ports:
        - containerPort: 80
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                - key: zone
                  operator: In
                  values:
                   - slave

在这里插入图片描述
现在删除node的标签后,再观察pod的情况。
在这里插入图片描述
发现无法调度pod。

软限制

apiVersion: apps/v1
kind: ReplicaSet  
metadata:  
  name: my-replicaset
spec:
  replicas: 10
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: mycontainer
        image: harbor.hiuiu.com/nginx/nginx:1.21.5
        ports:
        - containerPort: 80
      affinity:
        nodeAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 1
            preference:
              matchExpressions:
              - key: zone
                operator: In
                values:
                - slave

在这里插入图片描述
现在,我们在node1节点上打上labels,重新分配pod再观察。
在这里插入图片描述
现在看,大多数的pod会在slave1上,可能因为资源不足等的情况,分配到节点2上去,并不是硬限制。

pod的亲和性
应用场景

  1. 性能优化

    • 将需要频繁通信的 Pods 放在同一个节点上,以减少网络延迟,提高性能。
  2. 高可用性

    • 使用反亲和性策略确保应用的各个副本分布在不同节点上,以防止单点故障。
  3. 资源利用

    • 将不同类型的工作负载(如 CPU 密集型和 I/O 密集型)放在一起,优化资源利用。
  4. 区域部署

    • 根据区域或机架信息将 Pods 部署在特定位置,以满足拓扑结构需求。
  5. 合规性

    • 遵循数据政策,确保特定应用被限制在特定节点或区域。

pod亲和性
先创建一个pod

apiVersion: v1
kind: Pod  
metadata:  
  name: pod-first
  labels:  
    app2: myapp2  
    tier: frontend
spec:  
  containers:  
  - name: myapp  
    image: harbor.hiuiu.com/nginx/nginx:1.21.5

在这里插入图片描述
利用pod亲和性创建另一个pod

apiVersion: v1  
kind: Pod  
metadata:  
  name: pod-second  
  labels:  
    app: backend  
    tier: db  
spec:  
  containers:  
  - name: mysql  
    image: harbor.hiuiu.com/nginx/nginx:1.21.5  
    imagePullPolicy: IfNotPresent  
  affinity:  
    podAffinity:  
      requiredDuringSchedulingIgnoredDuringExecution:  
      - labelSelector:  
          matchExpressions:  
          - key: app2  
            operator: In  
            values: ["myapp2"]  
        topologyKey: kubernetes.io/hostname

在这里插入图片描述
创建成功。

反亲和性
跟亲和性一样配置,意思是不允许同时存在满足条件的pods上面。

apiVersion: v1  
kind: Pod  
metadata:  
  name: pod-second  
  labels:  
    app: backend  
    tier: db  
spec:  
  containers:  
 - name: mysql  
    image: harbor.hiuiu.com/nginx/nginx:1.21.5  
    imagePullPolicy: IfNotPresent  
  affinity:  
    podAntiAffinity:  
      requiredDuringSchedulingIgnoredDuringExecution:  
      - labelSelector:  
          matchExpressions:  
          - key: app2  
            operator: In  
            values: ["myapp2"]  
        topologyKey: kubernetes.io/hostname

在这里插入图片描述
注意
上述文件中有一个topologyKey: kubernetes.io/hostname,其作用是用来限制 Kubernetes 调度规则在节点级别生效。具体来说:

  • 亲和性:Pods 更倾向于被调度到同一个节点上。
  • 反亲和性:Pods 被避免调度到已经有特定标签的 Pods 的同一个节点上。

Pod的重启策略

在 Kubernetes 中,Pod 的重启策略通过 restartPolicy 字段设置,常用于定义容器在失败时的重启行为。restartPolicy 可以有以下三种策略:

  1. Always

    • 默认重启策略。
    • 无论容器运行结果如何(成功或失败),总是会重启容器。
    • 常用于长期运行的服务,因为可以确保服务总是处于运行状态。
  2. OnFailure

    • 仅在容器因错误退出(退出码非零)时才重启容器。
    • 适用于批处理作业等场景,当容器成功完成后(退出码为零)不会重启。
  3. Never

    • 容器无论以任何退出状态(成功或失败)退出,都不会被重启。
    • 适用于希望容器仅运行一次并且不再重启的情况。

需要注意的是,这些重启策略适用于 Pod 中的单个容器,并且对于通过其他控制器(如 Deployment、StatefulSet)管理的 Pod,一般使用 Always 进行管理,而 Pod 级别的重启通常由这些控制器处理。

  • 15
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值