K8S和容器概念

Docker vs K8S

Docker 是“创建容器”的工具,而 K8S 是“管理容器集群”的系统。
类比:Docker 像是一台汽车的发动机,而 K8S 则是整个交通管理系统,协调成千上万辆汽车(容器)的运行。

虽然 K8S 最初主要支持 Docker,但它不依赖特定容器运行时。目前,K8S 支持多种容器运行时,包括:

  • containerd(Docker 的核心组件,现已成为主流)
  • CRI-O(专为 K8S 设计的轻量级运行时)
  • Kata Containers(安全容器)
  • 其他符合 CRI(Container Runtime Interface) 标准的运行时。

关键业务概念

https://www.cnblogs.com/aibi1/p/18762342

K8S 编排的核心能力

K8S 对容器(无论是否由 Docker 创建)的编排能力包括:

调度(Scheduling)**:自动将容器分配到合适的节点(基于资源需求、亲和性等)。

Kubernetes(K8S)的 调度(Scheduling) 是指将 Pod 分配到集群中合适的 Node(节点) 上的过程。调度器(kube-scheduler)基于资源需求、约束策略和集群状态,确保 Pod 在满足条件的节点上运行。以下是核心机制和示例说明:


一、调度的核心机制

调度过程分为两个阶段:

  1. 过滤(Predicates):排除不满足 Pod 需求的节点(如资源不足、标签不匹配)。
  2. 评分(Priorities):对剩余节点打分,选择最优节点(如资源利用率最均衡的节点)。

最终,调度器将 Pod 绑定到得分最高的节点,由该节点的 kubelet 启动容器。


二、调度关键概念

  1. 资源请求(Resource Requests)
    Pod 需要声明所需的 CPU、内存等资源(如 requests.cpu: 1),调度器根据此分配节点。
    示例:若 Pod 请求 2 CPU,但节点只剩 1 CPU,该节点会被过滤。

  2. 节点亲和性(Node Affinity)
    定义 Pod 倾向于调度到哪些节点(基于节点标签)。
    示例:将 Pod 部署到带有 disktype=ssd 标签的节点。

  3. Pod 亲和性/反亲和性(Pod Affinity/Anti-Affinity)
    定义 Pod 与其他 Pod 的共存规则。
    示例:避免同一服务的多个副本部署到同一节点(反亲和性)。

  4. 污点与容忍(Taints and Tolerations)

    • 污点(Taint):节点标记为“排斥某些 Pod”。
    • 容忍(Toleration):Pod 声明可以容忍污点。
      示例:专用 GPU 节点添加污点,只有声明了容忍的 Pod(如 AI 训练任务)才能调度。
  5. 节点选择器(nodeSelector)
    强制 Pod 调度到特定标签的节点(旧版简化亲和性)。
    示例:将 Pod 部署到带有 env=prod 标签的节点。


三、调度示例场景

示例 1:资源请求不足导致调度失败

  • Pod 定义:请求 2 CPU,但集群中没有节点满足。
    apiVersion: v1
    kind: Pod
    metadata:
      name: web-app
    spec:
      containers:
        - name: nginx
          image: nginx
          resources:
            requests:
              cpu: "2"
              memory: "1Gi"
      nodeSelector:
        env: prod
    
  • 调度结果
    若所有 env=prod 的节点可用 CPU < 2,Pod 处于 Pending 状态,直到资源满足。

示例 2:节点亲和性

  • 节点标签
    节点 node-1 有标签 disktype=ssd
  • Pod 定义:优先调度到 disktype=ssd 的节点。
    apiVersion: v1
    kind: Pod
    metadata:
      name: db-pod
    spec:
      affinity:
        nodeAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
            - weight: 1
              preference:
                matchExpressions:
                  - key: disktype
                    operator: In
                    values: [ssd]
      containers:
        - name: mysql
          image: mysql
    
  • 调度结果
    优先选择 node-1,若无满足条件的节点,则选择其他节点。

示例 3:Pod 反亲和性(避免单节点部署多个副本)

  • Deployment 定义:同一服务的 Pod 避免部署到同一节点。
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: web
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: web
      template:
        metadata:
          labels:
            app: web
        spec:
          affinity:
            podAntiAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                - labelSelector:
                    matchExpressions:
                      - key: app
                        operator: In
                        values: [web]
                  topologyKey: kubernetes.io/hostname
          containers:
            - name: nginx
              image: nginx
    
  • 调度结果
    三个 Pod 会分布在三个不同节点(若节点数 ≥3)。

示例 4:污点与容忍(专用节点)

  • 节点污点:标记一个节点为专用 GPU 节点。
    kubectl taint nodes node-1 gpu=true:NoSchedule
    
  • Pod 定义:声明容忍污点。
    apiVersion: v1
    kind: Pod
    metadata:
      name: ai-task
    spec:
      tolerations:
        - key: "gpu"
          operator: "Equal"
          value: "true"
          effect: "NoSchedule"
      containers:
        - name: tensorflow
          image: tensorflow/gpu
      nodeSelector:
        gpu: "true"
    
  • 调度结果
    只有 node-1 能运行此 Pod。

四、调度过程调试

  • 查看 Pod 调度失败原因

    kubectl describe pod <pod-name>
    

    输出中的 Events 会显示调度失败原因(如资源不足、无匹配节点)。

  • 手动绑定 Pod 到节点(仅调试用):

    spec:
      nodeName: node-2  # 跳过调度器,直接指定节点
    

扩缩容(Scaling)**:根据负载自动调整容器副本数量(如 Horizontal Pod Autoscaler)。

Horizontal Pod Autoscaler(HPA)的配置并不是直接基于 Deployment 的配置文件,而是通过 独立的 HPA 资源对象 来定义。HPA 通过引用目标 Deployment(或其他可扩缩资源,如 StatefulSet)的名称,监控其关联的 Pod 指标,并动态调整副本数。


一、HPA 的配置方式

HPA 的配置有以下两种方式,均不依赖 Deployment 的 YAML 文件:

1. 通过 kubectl autoscale 命令创建

直接通过命令行工具快速创建 HPA,无需编写 YAML 文件:

kubectl autoscale deployment <deployment-name> \
  --cpu-percent=50 \  # 目标 CPU 使用率阈值
  --min=2 \           # 最小副本数
  --max=10            # 最大副本数

2. 通过 YAML 文件定义独立的 HPA 资源

创建单独的 HPA 配置文件(如 hpa.yaml),引用目标 Deployment:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: web-app-hpa   # HPA 资源名称
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web-app     # 指向目标 Deployment
  minReplicas: 2
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 50  # 目标 CPU 使用率 50%

然后应用配置:

kubectl apply -f hpa.yaml

二、HPA 与 Deployment 的关系

  1. HPA 通过 scaleTargetRef 关联 Deployment
    HPA 通过字段 scaleTargetRef 指定要管理的 Deployment(或其他资源),并不需要修改原 Deployment 的配置文件。

  2. HPA 操作 Deployment 的副本数
    HPA 通过 Kubernetes API 动态调整 Deployment 的 replicas 字段,触发 Pod 的扩缩容。

  3. Deployment 无需特殊配置
    Deployment 本身无需任何 HPA 相关配置,只需确保:

    • Pod 配置中声明了 资源请求(resources.requests(若使用 CPU/内存指标)。
    • 目标 Deployment 已正常运行。

三、配置示例与验证

1. 示例:Deployment 的资源配置

Deployment 的 Pod 模板需要声明资源请求(requests),否则 HPA 无法计算 CPU/内存使用率:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 2
  template:
    spec:
      containers:
        - name: nginx
          image: nginx
          resources:
            requests:
              cpu: "100m"  # 必须声明 CPU 请求
              memory: "128Mi"
            limits:
              cpu: "200m"
              memory: "256Mi"

2. 验证 HPA 状态

# 查看 HPA 状态
kubectl get hpa

# 输出示例
NAME          REFERENCE               TARGETS   MINPODS  MAXPODS  REPLICAS  AGE
web-app-hpa   Deployment/web-app      0%/50%    2        10       2         1m

# 查看扩缩容事件详情
kubectl describe hpa web-app-hpa

四、HPA 的高级配置

1. 多指标扩缩容

HPA 支持基于 CPU、内存、自定义指标外部指标 的组合策略:

metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 50
  - type: Pods
    pods:
      metric:
        name: http_requests_per_second  # 自定义指标(需预先配置)
      target:
        type: AverageValue
        averageValue: 100

2. 行为控制(Behavior)

调整扩缩容的冷却时间和速率:

behavior:
  scaleDown:
    stabilizationWindowSeconds: 300  # 缩容冷却时间 5 分钟
    policies:
      - type: Percent
        value: 10                    # 每次最多缩容 10% 的副本
        periodSeconds: 60
  scaleUp:
    stabilizationWindowSeconds: 60    # 扩容冷却时间 1 分钟
    policies:
      - type: Pods
        value: 4                     # 每次最多扩容 4 个副本
        periodSeconds: 15

五、核心注意事项

  1. 资源请求必须声明
    如果使用 CPU/内存作为指标,Pod 必须配置 resources.requests,否则 HPA 无法计算使用率。

  2. 监控组件需就绪

    • 使用内置资源指标(CPU/内存)需安装 Metrics Server
    • 使用自定义指标需部署 Prometheus + Prometheus Adapter 或其他指标提供者。
  3. 避免频繁震荡(Flapping)
    合理设置 behavior 参数,避免副本数因指标波动频繁变化。


六、总结

  • HPA 的配置独立于 Deployment,通过 YAML 文件或 kubectl autoscale 命令单独定义。
  • HPA 通过 API 动态管理 Deployment 的副本数,无需修改原 Deployment 的配置。
  • 确保 Pod 声明资源请求,并正确配置监控组件,是 HPA 正常工作的关键。

- 服务发现与负载均衡:通过 Service 和 Ingress 暴露服务,并分配流量。

Pod 是临时性的,其 IP 地址会因重启、扩缩容或故障而频繁变化。直接依赖 Pod IP 会导致服务不可靠。
Service 为 Pod 组分配一个 固定的虚拟 IP(ClusterIP) 和 DNS 名称,屏蔽后端 Pod 的变化细节。
服务发现:Service 通过 标签选择器(Label Selector) 动态发现匹配的 Pod,并自动更新后端端点列表。

简单的理解:Service暴露固定IP或者域名和其他Service通讯。 流量请求到Service,Service会基于负载均衡算法路由到POD。

但是,在微服务架构里面。 都是POD和POD通过IP通讯,由注册中心提供服务发现的功能。

- 自我修复(Self-Healing):自动重启故障容器、替换不健康的实例。

- 滚动更新与回滚:无中断更新应用版本,失败时快速回退。

- 存储与配置管理:为容器动态挂载存储卷,传递配置和密钥。

posted @ 2025-03-10 11:28  向着朝阳  阅读(64)  评论(0)    收藏  举报