Kubernetes--简述

时间:2024-10-09 11:11:03

官方文档:https://kubernetes.io/docs/home/

 

一、概述

Kubernetes 是一个可移植、可扩展的开源平台,用于管理容器化的工作负载和服务,方便进行声明式配置和自动化

 

Kubernetes可以提供:

  • 服务发现和负载均衡:Kubernetes 可以使用 DNS 名称或自己的 IP 地址来暴露容器。 如果进入容器的流量很大, Kubernetes 可以负载均衡并分配网络流量,从而使部署稳定。
  • 存储编排:Kubernetes 允许自动挂载选择的存储系统,例如本地存储、公共云提供商等。
  • 自动部署和回滚:可以使用 Kubernetes 描述已部署容器的所需状态, 它可以以受控的速率将实际状态更改为期望状态。 例如,可以自动化 Kubernetes 来为部署创建新容器, 删除现有容器并将它们的所有资源用于新容器。
  • 自动调度:Kubernetes 的调度器会根据容器定义的 CPU 和内存资源,结合集群的当前状态,自动计算并选择最佳节点来运行容器,从而充分利用资源。
  • 自我修复:Kubernetes 将重新启动失败的容器、替换容器、杀死不响应用户定义的运行状况检查的容器, 并且在准备好服务之前不将其通告给客户端。
  • 密钥与配置管理:Kubernetes 允许存储和管理敏感信息,例如密码、OAuth 令牌和 SSH 密钥。 可以在不重建容器镜像的情况下部署和更新密钥和应用程序配置,也无需在堆栈配置中暴露密钥。
  • 批处理执行:除了服务外,Kubernetes 还可以管理你的批处理和 CI(持续集成)工作负载,如有需要,可以替换失败的容器。
  • 水平扩缩:使用简单的命令、用户界面或根据 CPU 使用率自动对应用进行扩缩容。
  • IPv4/IPv6 双栈:为 Pod(容器组)和 Service(服务)分配 IPv4 和 IPv6 地址。
  • 可扩展性设计:在不改变上游源代码的情况下为Kubernetes 集群添加功能。

注:批处理(Batch Processing) 指的是处理一组任务或作业的方式,这些任务通常是一次性、短期的计算任务。Kubernetes 提供了特定的资源类型来管理这类作业,主要包括 Job 和 CronJob。 

 

1.1 Kubernetes 的历史背景

Kubernetes--简述_应用程序

 

 

传统部署

早期,各个组织是在物理服务器上运行应用程序。 由于无法限制在物理服务器中运行的应用程序资源使用,因此会导致资源分配问题。

例如,如果在同一台物理服务器上运行多个应用程序, 则可能会出现一个应用程序占用大部分资源的情况,而导致其他应用程序的性能下降。

一种解决方案是将每个应用程序都运行在不同的物理服务器上, 但是当某个应用程序资源利用率不高时,剩余资源无法被分配给其他应用程序, 而且维护许多物理服务器的成本很高。

因此,虚拟化技术被引入了。

 

虚拟化部署:

虚拟化技术允许在单个物理服务器的 CPU 上运行多台虚拟机(VM)。 虚拟化能使应用程序在不同 VM 之间被彼此隔离,且能提供一定程度的安全性, 因为一个应用程序的信息不能被另一应用程序随意访问。

虚拟化技术能够更好地利用物理服务器的资源,并且因为可轻松地添加或更新应用程序, 而因此可以具有更高的可扩缩性,以及降低硬件成本等等的好处。 通过虚拟化,可以将一组物理资源呈现为可丢弃的虚拟机集群。

每个 VM 是一台完整的计算机,在虚拟化硬件之上运行所有组件,包括其自己的操作系统。

 

容器部署:

容器类似于 VM,但是更宽松的隔离特性,使容器之间可以共享操作系统(OS)。 因此,容器比起 VM 被认为是更轻量级的。且与 VM 类似,每个容器都具有自己的文件系统、CPU、内存、进程空间等。

由于它们与基础架构分离,因此可以跨云和 OS 发行版本进行移植。

容器因具有许多优势而变得流行起来,例如:

  • 敏捷应用程序的创建和部署:与使用 VM 镜像相比,提高了容器镜像创建的简便性和效率。
  • 持续开发、集成和部署:通过快速简单的回滚(由于镜像不可变性), 提供可靠且频繁的容器镜像构建和部署。
  • 关注开发与运维的分离:在构建、发布时创建应用程序容器镜像,而不是在部署时, 从而将应用程序与基础架构分离。
  • 可观察性:不仅可以显示 OS 级别的信息和指标,还可以显示应用程序的运行状况和其他指标信号。
  • 跨开发、测试和生产的环境一致性:在笔记本计算机上也可以和在云中运行一样的应用程序。
  • 跨云和操作系统发行版本的可移植性:可在 Ubuntu、RHEL、CoreOS、本地、 Google Kubernetes Engine 和其他任何地方运行。
  • 以应用程序为中心的管理:提高抽象级别,从在虚拟硬件上运行 OS 到使用逻辑资源在 OS 上运行应用程序。
  • 松散耦合、分布式、弹性、解放的微服务:应用程序被分解成较小的独立部分, 并且可以动态部署和管理, 而不是在一台大型单机上整体运行。
  • 资源隔离:可预测的应用程序性能。
  • 资源利用:高效率和高密度。

 

1.2 核心概念

Kubernetes 是一个强大的容器编排平台,具有许多核心概念和组件。

概念

描述

功能

Pod

Pod 是 Kubernetes 中的最小部署单元,表示一个或多个容器的集合,它们共享存储、网络和配置。

Pods 内的容器可以共享文件系统和网络,适合运行密切相关的应用程序。

Pods

Pods 是 Pod 的复数形式,表示多个 Pod

通常用于描述一组 Pod 或在命令行中指定多个 Pod

Node

Node 是 Kubernetes 集群中的一个工作机器,可以是物理或虚拟机。

每个 Node 上运行一个或多个 Pods,包含运行 Pods 所需的所有组件(如 kubelet、容器运行时等)。

Service

Service 是一种抽象,定义了一组 Pods 的访问策略,提供稳定的网络接口。

通过 Service,用户可以使用 DNS 名称访问 Pods,而无需关心 Pods 的 IP 地址变化。它支持负载均衡和服务发现。

Deployment

Deployment 是用于声明式管理 Pods 和 ReplicaSets 的资源。

自动化 Pods 的部署、升级和回滚,确保系统在更新时保持可用性。

ReplicaSet

ReplicaSet 确保指定数量的 Pod 实例在运行,在1.2 版本引入,以替代早期的 Replication Controller。

用于扩展和缩减 Pods 的数量,确保 Pods 的高可用性。

Namespace

Namespace 是 Kubernetes 的逻辑隔离机制,用于在同一集群中管理多个环境(如开发、测试和生产)。

通过 Namespace,可以在同一集群中使用相同的资源名称而不会冲突。

ConfigMap

用于存储配置信息以供 Pods 使用。

允许将配置信息从镜像中分离,便于管理和更新。

Secret

用于存储敏感信息(如密码、令牌等)。

提供安全的方式来传递敏感数据给 Pods。

Volume

Volume 是 Kubernetes 中用于持久化存储的抽象。

提供跨容器共享数据的能力,支持多种存储类型,如本地存储、NFS、云存储等。

Cluster

Cluster 是 Kubernetes 的核心概念,由多个 Node 组成。

提供一个统一的计算资源池,便于管理和调度。

Ingress

Ingress 是用于管理外部访问 Kubernetes 服务的 API 对象。

提供 HTTP 和 HTTPS 路由到集群内服务的能力,支持负载均衡、SSL/TLS 终端等功能。

Controller

Controller 是 Kubernetes 的控制循环,用于监控集群状态并执行所需的操作。

通过对比实际状态与期望状态,自动调整资源以确保系统稳定。

 

1.3 Kubernetes 组件

Kubernetes 的架构采用了一种主从设备模型,其中 Master Node 负责集群的管理和调度,而 Worker Node 则执行用户的应用程序。这个设计使得 Kubernetes 能够有效地进行容器编排和资源管理。

Kubernetes--简述_Deployment_02

 

1.3.1 控制平面组件

控制平面组件会为集群做出全局决策,比如资源的调度以及检测和响应集群事件。

控制平面组件可以在集群中的任何节点上运行。 然而,一般情况下,控制平面组件都安装在Master 节点上,因为控制平面需要处理集群的管理和协调任务,集中在 Master 节点上可以提高管理效率。

组件

描述

kube-apiserver

整个集群的入口,负责处理所有的 API 请求、管理集群状态、进行认证和授权。

etcd

一致且高可用的键值存储,用作 Kubernetes 所有集群数据的后台数据库,负责存储集群状态和配置数据。

kube-scheduler(调度器)

接受来自kube-apiserver的任务,根据集群的资源情况和预定义的调度策略,将 Pods 调度到合适的 Node 上。

kube-controller-manager(控制器管理器)

负责管理集群中的各类控制器,确保集群的实际状态与期望状态保持一致。通过不断监测和调整 Kubernetes 资源的状态,来实现自动化管理和自愈能力,例如创建、更新或删除资源。

cloud-controller-manager(云控制器管理器)

专门用于与云提供商的 API 进行交互,将集群的云特有功能与 Kubernetes 的核心功能分离,使得 Kubernetes 可以在多种云环境中灵活运行。

 

1.3.2 节点组件

节点组件会在每个节点上(通常是Worker Node)运行,负责维护运行的 Pod 并提供 Kubernetes 运行时环境。

组件

描述

kubelet

负责管理 Pods 和容器的生命周期。作为 Kubernetes 的主要代理,通过与 Kubernetes API 服务器和容器运行时的交互,确保集群中容器的正常运行和高效管理。

kube-proxy

负责实现网络代理和负载均衡。在每个工作节点上运行,确保服务的网络流量能够正确地路由到相应的 Pods。用户也可选择其他的网络代理插件。

Container runtime(容器运行时)

是 Kubernetes 集群中用于运行和管理容器的组件。它负责容器的创建、启动、停止、删除以及维护容器的生命周期。

 

1.3.3 插件(Addons)

在 Kubernetes 中,插件(Addons) 是增强集群功能的组件,它们通常提供附加的功能和服务,如监控、日志管理、网络管理和存储等。

组件

描述

DNS

用于提供服务发现和名称解析功能。Kubernetes 内置的 DNS 功能使得 Pods 和服务可以通过 DNS 名称轻松互相访问,而不需要使用 IP 地址。

Dashboard

基于 Web 的用户界面,用于管理和监控 Kubernetes 集群。提供了一种直观的方式来查看集群的状态、管理资源以及执行各种操作。

Flannel

网络插件,简化容器网络的设置,提供跨主机网络,其他如Calico: 提供网络策略和网络安全功能;Weave Net: 提供容器间的网络连接,支持网络策略。

Prometheus

监控插件,用于监控和报警,支持多种数据来源。

Persistent Volumes(PV)

存储插件,处理持久化存储的管理和挂载。

 

1.4 应用

在 Kubernetes 中,应用可以分为有状态应用和无状态应用。

 

1.4.1 无状态应用

无状态应用是指不依赖于任何特定的会话数据或用户状态。每次请求都是独立的,服务器不需要存储会话信息。

特点:

  • 可扩展性: 无状态应用可以轻松扩展,因为任何请求都可以被任何实例处理。
  • 容错性: 如果某个实例失败,其他实例可以无缝接管请求。
  • 易于部署: 更新和横向扩展简单,不需要考虑数据一致性问题。

示例:

  • Web 服务器(如 Nginx、Apache)
  • API 服务
  • 静态文件托管

Kubernetes 资源: 通常使用 Deployment 资源来管理无状态应用。

 

1.4.2 有状态应用

有状态应用是指需要保持会话信息或数据状态。每个实例的状态是独立的,可能会影响应用的行为。

特点:

  • 状态管理: 有状态应用需要管理和保存状态信息,通常需要持久化存储。
  • 复杂性: 部署和管理较复杂,需要考虑数据一致性、故障恢复等。
  • 数据迁移: 实例间的数据迁移和共享可能需要额外的配置。

示例:

  • 数据库(如 MySQL、PostgreSQL、MongoDB)
  • 缓存服务(如 Redis、Memcached)
  • 消息队列(如 RabbitMQ、Kafka)

Kubernetes 资源: 通常使用 StatefulSet 资源(kube-controller-manager里的一个控制器)来管理有状态应用,以便提供稳定的网络身份和持久化存储。

 

1.5 YAML文件

在 Kubernetes 中,YAML 文件用于定义和配置各种资源,如 Pods、Services、Deployments、ReplicaSets 等。

语法规则:

  • 大小写敏感,且资源类型通常使用大写(如 PodService),而其他键如 apiVersionkindmetadata 等使用小写。
  • 层级:使用缩进表示层级关系,相同层级的元素左侧对齐。
  • 缩进:使用空格进行缩进,不能使用制表符(Tab),通常每一级缩进使用两个空格。
  • 键值对:使用冒号 : 分隔键和值。值可以是字符串、数字、布尔值、列表或对象。
  • 数据类型:支持字符串,数字,布尔,列表等
  • 注释:使用 # 来添加注释,注释在行内或单独一行均可。
  • 分隔符:- - - 为可选的分隔符 ,当需要在一个文件中定义多个结构的时候需要使用。
  • 特殊字符:如果值包含特殊字符(如冒号、空格等),需要用引号括起来。

 

每个 YAML 文件通常由以下几个部分组成:

  1. apiVersion: 指定资源的 API 版本。
  2. kind: 定义资源的类型(如 Pod、Service、Deployment 等)。
  3. metadata: 描述资源的元数据,如名称、标签和注释。
  4. spec: 资源的具体配置,定义资源的期望状态。

 

1.5.1 apiVersion

在 Kubernetes 中,apiVersion 字段用于指定资源的 API 版本,帮助 Kubernetes 确定如何处理该资源,因此,选择合适的 apiVersion 是非常重要的。使用不兼容的版本可能导致资源创建失败或不按预期工作。

apiVersion 字段通常由两个部分组成:

  • 组(Group): 表示资源所属的 API 组。
  • 版本(Version): 表示该组的版本号。

例如,apps/v1 由组 apps 和版本 v1 组成。

 

常见的 API 组和版本(更多请看官方文档):

core(v1): 不属于任何组的资源,如 Pods、Services、Namespaces 等。版本为 v1

apiVersion: v1
kind: Pod

apps(v1): 包含与应用程序相关的资源,如 Deployments、ReplicaSets 和 StatefulSets。

apiVersion: apps/v1
kind: Deployment

batch(v1): 包含与批处理相关的资源,如 Jobs 和 CronJobs。

apiVersion: batch/v1
kind: Job

networking(v1): 包含与网络相关的资源,如 Ingress 和 NetworkPolicies。

apiVersion: networking.k8s.io/v1
kind: Ingress

rbac.authorization.k8s.io(v1): 包含与角色和权限相关的资源,如 Roles 和 RoleBindings。

apiVersion: rbac.authorization.k8s.io/v1
kind: Role

 

1.5.2 实例

定义一个yaml文件 my-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: my-container
          image: nginx:latest
          ports:
            - containerPort: 80

详解:

apiVersion: apps/v1    # 指定使用的 API 版本。在这里,apps/v1 表示这是一个 Deployment 类型的资源,属于 Kubernetes 的应用相关 API
kind: Deployment       # 定义资源的类型,Deployment用于管理 Pods 的副本
metadata:              # 此部分包含资源的元数据
  name: my-deployment  # 资源的名称,自定义
spec:                  # 定义资源的期望状态
  replicas: 3          # 指定要运行的 Pods 副本数,即运行3个容器
  selector:            # 用于选择与 Deployment 关联的 Pods
    matchLabels:       # 定义选择器的标签。在这里,选择所有具有标签 app: my-app 的 Pods
      app: my-app      # 标签,自定义
  template:            # 定义 Pods 的模板,用于创建新的 Pods
    metadata:          # 包含 Pods 的元数据
      labels:          # 为模板中的 Pods 定义标签。在这里,所有由此 Deployment 创建的 Pods 都会被标记为 app: my-app
        app: my-app    # 标签名,自定义
    spec:              # 定义 Pods 的具体配置
      containers:      # 列出 Pods 中的容器
        - name: my-container     # 容器的名称,自定义
          image: nginx:latest    # 容器所使用的基础Docker镜像,其他有CentOS,busybox,Ubuntu等
          ports:                 # 列出容器暴露的端口
            - containerPort: 80  # 指定容器内部的端口号

 

运行这个文件来创建一个Deployment,运行3个nginx容器,端口开放80

kubectl apply -f my-deployment.yaml

查看

# 查看 Deployment
kubectl get deployments
# 查看 Deployment 详细信息
kubectl describe deployment my-deployment

# 查看 Pods
kubectl get pods
# 查看 Pod 详细信息
kubectl describe pod <pod-name>

# 删除
kubectl delete deployment my-deployment

 

1.6 kubectl

kubectl 是 Kubernetes 的命令行工具,用于管理 Kubernetes 集群和其资源。它提供了一组命令,允许用户与 Kubernetes API 进行交互,从而执行各种操作,如创建、更新、删除和获取资源的状态。

 

主要功能:

  1. 管理集群资源:使用 kubectl 可以创建、更新和删除 Pods、Deployments、Services 等各种 Kubernetes 资源。
  2. 查看资源状态:可以通过命令查看集群中各个资源的状态和详细信息,例如 Pods、Nodes、Namespaces 等。
  3. 调试和排错:提供命令用于查看日志、执行命令、进入容器等,帮助用户调试和维护应用程序。
  4. 配置管理:支持管理 Kubernetes 配置文件(如 kubeconfig),以便连接到不同的集群。
  5. 集成 CI/CD 工具kubectl 可用于自动化和持续集成/持续部署(CI/CD)流程,方便与其他工具集成。

 

常用命令:

# 查看集群信息
kubectl cluster-info

# 查看 Pods
kubectl get pods

# 创建资源
kubectl apply -f my-resource.yaml

# 删除资源
kubectl delete pod my-pod

# 查看 Pod 日志
kubectl logs my-pod

# 进入容器
kubectl exec -it my-pod -- /bin/sh

 

kubectl apply -f 和kubectl create -f 和 kubectl replace -f:

在 Kubernetes 中,kubectl apply -fkubectl create -f 和 kubectl replace -f 是用于管理资源的三种命令,适用于不同的场景,在大多数情况下,使用 kubectl apply -f 是最佳实践。

命令

创建新资源

更新现有资源

适用场景

kubectl apply -f



日常工作流、CI/CD、团队协作

kubectl create -f



确定资源不存在时的初始化设置

kubectl replace -f



需要完全替换现有资源的情况

 

二、集群搭建

详见:

或者参考官方文档:https://kubernetes.io/zh-cn/docs/setup/production-environment/tools/

 

三、各概念简述

3.1 Pod

Pod 是 Kubernetes 中的最小可部署单元,通常包含一个或多个容器,这些容器共享存储、网络和运行环境。

共享网络: Pod 内的所有容器共享同一个 IP 地址和端口空间,可以通过 localhost 互相通信。

共享存储: Pod 可以挂载存储卷,所有容器都可以访问同一数据。

 

3.1.1 容器

在 Kubernetes 中,每个 Pod 通常会包含一个特殊的容器,称为 Pause 容器(根容器),也被称为 基础设施容器。用户通常不需要直接管理 Pause 容器,它在 Pod 创建时自动启动,用户只需关注业务容器。

Pause 容器是一个轻量级的容器,通常是一个只包含基本工具的 Linux 镜像,用于创建 Pod 的网络命名空间和其他基础设施功能。如 gcr.io/google_containers/pause。

 

3.1.1.1 功能

网络命名空间

  • 共享网络: Pause 容器创建并持有 Pod 的网络命名空间,所有在同一 Pod 中的业务容器共享这一网络命名空间。这意味着它们可以通过 localhost 互相通信。
  • IP 地址分配: Pause 容器使得 Pod 拥有一个单独的 IP 地址,该地址被分配给整个 Pod,而不是单个容器。

资源管理

  • 资源隔离: Pause 容器提供了一个基础设施层,帮助 Kubernetes 管理 Pod 中的容器资源。Pod 的生命周期与 Pause 容器相绑定。
  • 容器状态管理: 当 Kubernetes 需要检查 Pod 的状态时,它可以通过 Pause 容器来管理和跟踪 Pod 的健康状态。

 

3.1.1.2 与业务容器的关系
  • 紧密耦合: 用户业务容器是 Pod 中的主要应用容器,通常执行实际的业务逻辑。它们与 Pause 容器紧密耦合,共享网络和存储资源。
  • 容器间协作: 通过共享 Pause 容器的网络命名空间,用户业务容器能够高效地进行数据交换和通信。

 

3.1.2 资源限制

在 Kubernetes 中,可以为 Pod 设置资源限制,以确保应用程序在运行时不会消耗过多的资源。资源限制主要包括 CPU 和内存。

资源请求(Requests): 表示容器启动时所需的最低资源量。如果节点没有足够的资源满足请求,该 Pod 将不会被调度到该节点。

资源限制(Limits): 表示容器可以使用的最大资源量。如果容器尝试使用超过这个限制的资源,会终止这个容器。

 

示例

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
    - name: my-container
      image: nginx
      resources:
        requests:
          memory: "64Mi"   # 请求的内存
          cpu: "250m"      # 请求的 CPU
        limits:
          memory: "128Mi"  # 限制的内存
          cpu: "500m"      # 限制的 CPU

内存单位:

  • B: 字节
  • Ki: Kibibyte(1024 字节)
  • Mi: Mebibyte(1024 KiB)
  • Gi: Gibibyte(1024 MiB)
  • Ti: Tebibyte(1024 GiB)

cpu单位:

  • 核(Core): 通常表示为 1,代表一个完整的 CPU 核心。
  • 毫核(milli-core): 使用 m 表示,表示一个 CPU 核心的千分之一。

 

3.1.3 镜像拉取

在yaml文件里,可以定义容器镜像拉取的策略。

  • Always: 每次启动 Pod 时都拉取镜像。适用于需要确保使用最新版本的镜像。
  • IfNotPresent: 只有在本地不存在镜像时才拉取,默认策略。
  • Never: 不拉取镜像,假设镜像已经在节点上。适用于开发或测试环境

 

默认情况下,Kubernetes 从 Docker Hub 或指定的私有镜像仓库拉取镜像;如果镜像名称中包含仓库地址(如 my-registry/my-image:tag),Kubernetes 将从该地址拉取。

如果镜像是私有的,Kubernetes 会使用相应的凭证进行身份验证;这些凭证通常存储在 Kubernetes 中的 Secret 对象中,并与 ServiceAccount 绑定。

如果拉取镜像失败,Kubernetes 将根据 Pod 的配置重试拉取。如果多次失败,Pod 将进入 ImagePullBackOff 状态;管理员可以通过检查 Pod 的事件或使用 kubectl describe pod <pod-name> 命令来查看具体错误信息。

 

示例

apiVersion: v1
kind: Pod
metadata:
  name: my-nginx-pod
  labels:
    app: nginx
spec:
  containers:
  - name: nginx-container
    image: nginx:latest        # 使用最新的 Nginx 镜像
    imagePullPolicy: Always    # 每次都拉取镜像
    ports:
    - containerPort: 80

 

3.1.4 重启策略

在 Kubernetes 中,Pod 的重启策略(restartPolicy)决定了容器在失败后的处理方式。

  • Always:无论容器的退出状态如何,Kubernetes 始终会重启该容器。通常用于长时间运行的服务,如 Web 应用或数据库。
  • OnFailure:仅在容器以非零状态退出时(表示失败)重启容器。适合批处理任务或需要在失败后重新尝试的场景。
  • Never:无论容器的退出状态如何,Kubernetes 都不会重启该容器。适用于一次性任务或批处理作业,通常与 Job 资源一起使用。

 

示例

apiVersion: v1
kind: Pod
metadata:
  name: always-restart-pod
spec:
  restartPolicy: Always    # 设置重启策略
  containers:
  - name: my-container
    image: my-image:latest

 

3.1.5 Pod的类型

  1. 单容器 Pod
  • 定义: 每个 Pod 只包含一个容器。
  • 场景: 适用于简单的应用程序,易于管理和监控。大多数情况下,用户会创建这种类型的 Pod。
  1. 多容器 Pod
  • 定义: 一个 Pod 包含多个容器,这些容器紧密协作。
  • 类型:
  • Sidecar 模式: 通过辅助容器提供附加功能,例如日志收集、监控等。
  • Init Containers: 在主容器启动之前执行初始化任务,用于设置环境或预处理。
  • 代理模式: 代理容器处理主应用与外部的通信。
  1. DaemonSet Pods
  • 定义: 这种 Pod 确保在每个节点上运行一个 Pod 副本。
  • 场景: 适用于需要在每个节点上运行某些服务的情况,例如监控代理或日志收集器。
  1. Job Pods
  • 定义: 用于执行一次性的任务或批处理作业。
  • 场景: 适用于需要完成某项任务后退出的应用,例如数据处理或数据库迁移。
  1. CronJob Pods
  • 定义: 类似于 Job,但按照预定的时间表定期创建 Pods。
  • 场景: 适用于定期任务,例如备份、报告生成等。
  1. StatefulSet Pods
  • 定义: 用于管理有状态应用的 Pods,确保每个 Pod 有一个唯一的身份和持久化存储。
  • 场景: 适用于数据库和其他需要稳定网络身份和持久存储的应用。
  1. Replication Controller / ReplicaSet Pods
  • 定义: 确保指定数量的 Pod 副本在任何时候都在运行。
  • 场景: 适用于负载均衡和高可用性的需求。
  1. Namespace-specific Pods
  • 定义: Pods 可以在不同的 Namespace 中创建,以实现逻辑隔离。
  • 场景: 适合多租户环境或不同开发、测试、生产环境的隔离。

 

3.1.6 调度

Kubernetes 中的 Pod 调度是将 Pods 分配到适当节点的过程。调度器负责根据多种因素(如资源需求、节点可用性、亲和性规则等)来决定 Pods 的运行位置。

调度过程一般分为两个步骤:

过滤阶段:调度器会根据条件过滤出不符合要求的节点

  • 资源需求: 检查节点是否有足够的 CPU、内存等资源。
  • 节点亲和性: 检查 Pods 是否有特定的节点亲和性或反亲和性要求。
  • 污点和容忍: 处理节点的污点和 Pods 的容忍度。
  • Pod 反亲和性: 确保 Pods 不会被调度到不允许的节点上。

优先级阶段:在过滤出可用的节点后,调度器会根据优先级评分,选择最合适的节点,优先级包括

  • 最少使用资源: 选择当前资源使用最少的节点。
  • 节点亲和性: 优先选择符合 Pods 亲和性规则的节点。
  • 均衡负载: 尽量将 Pods 均匀分布到各个节点上。

 

调度方式

  1. 自动调度:使用控制器(如RS,DaemonSet)创建的 Pods 会由 Kubernetes 自动调度到最适合的节点,后文介绍
  2. 手动调度:通过在 Pod 定义中直接指定 nodeName 字段或nodeSelector 字段,将 Pod 调度到特定节点
  3. 其他调度:如亲和性调度,污点和容忍等

 

3.1.6.1 标签

Kubernetes 中的标签(Labels)是用于组织和选择对象(如 Pods、节点等)的关键机制。标签是附加到对象上的键值对,用于标识和分类这些对象,以便于管理和查询

 

1. 标签的基本概念

  • 键值对: 标签由一个键(Key)和一个值(Value)组成,格式为 key: value
  • 多元性: 同一个对象可以有多个标签,标签的组合可以提供更丰富的上下文信息。

2. 标签的用途

  • 选择器: 可以使用标签选择器(Label Selector)来选择特定的对象。例如,可以选择所有具有某个特定标签的 Pods。
  • 分组: 标签用于将相关的资源分组,以便进行管理和查询。
  • 调度: 节点标签可以帮助调度器将 Pods 调度到适当的节点上。
  • 服务发现: 通过标签,Kubernetes 服务可以选择一组 Pods 进行负载均衡。

3. 标签的格式

  • : 必须小写字母、数字、下划线(_)、连字符(-)和点(.),且不能以点(.)开头或结尾,最大长度为 63 个字符。
  • : 可以是任意字符,但最大长度为 63 个字符,且可以为空。

4. 标签选择器

标签选择器用于根据标签选择对象,主要有以下两种类型:

  • 等值选择器: 选择具有特定键值对的对象。
  • 集合选择器: 选择具有特定键的对象,并且值在给定的集合中。

 

为pod打标签:

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
  labels:
    app: my-app
    environment: production
spec:
  containers:
  - name: my-container
    image: my-image:latest

 

使用命令行

# 查看
kubectl get pods --show-labels

# 创建
kubectl label pods my-pod app=my-app

# 覆盖已有标签
kubectl label pods my-pod environment=staging --overwrite

# 删除
kubectl label pods my-pod environment-

 

为node打标签

apiVersion: v1
kind: Node
metadata:
  name: my-node
  labels:
    disktype: ssd
    zone: us-west-1a

使用命令行

kubectl label nodes my-node disktype=ssd

 

3.1.6.2 NodeName

在 Kubernetes 中,使用 nodeName 字段可以将 Pod 直接调度到特定的节点,nodeName 是 Pod 的一个属性,允许用户在 Pod 的配置中指定要在哪个节点上运行。

注意事项:

  • 跳过调度器: 使用 nodeName 时,Kubernetes 调度器会跳过调度过程,直接将 Pod 绑定到指定的节点。
  • 节点状态: 确保指定的节点处于可用状态(NotReady 状态的节点无法调度 Pods)。
  • 资源分配: 仍然需要确保指定节点有足够的资源来满足 Pod 的需求(如 CPU 和内存)。

适用场景:

  • 硬件依赖: 当应用需要特定硬件(如特定型号的 GPU)时,可以将其调度到具备该硬件的节点。
  • 网络配置: 对于需要特定网络配置的 Pods,可以指定在具有相应网络设置的节点上运行。

 

实例

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  nodeName: my-node  # 指定要调度的节点名称
  containers:
  - name: my-container
    image: my-image:latest

 

3.1.6.3 NodeSelector

NodeSelector 是 Pod 规格中的一个字段,允许用户指定节点的标签,以便将 Pods 调度到具有特定标签的节点上。适用于需要特定资源或特征的 Pods,例如要求在 SSD 存储节点上运行的数据库 Pods。

如果没有节点满足 NodeSelector 的条件,Pod 将不会被调度,状态会保持为 Pending。除了标签匹配外,确保目标节点有足够的资源(如 CPU、内存)来满足 Pod 的需求。

 

先为节点打上标签

kubectl label nodes my-node disktype=ssd

yaml文件里选择这个标签

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  nodeSelector:
    disktype: ssd  # 指定节点标签
  containers:
  - name: my-container
    image: my-image:latest

 

删除标签

kubectl get nodes --show-labels
kubectl label nodes <node-name> <label-key>-

 

3.1.6.4 Taint(污点)

Taint 是节点的一种属性,用于标识节点不适合某些 Pods。通过在节点上设置污点,可以阻止 Pods 被调度到这些节点,除非它们具有相应的容忍度

 

Taint 由三个部分构成:

  • Key: 污点的名称,通常是一个字符串
  • Value: 污点的具体值,通常是一个字符串
  • Effect: 污点的效应,可以是以下三种之一:
  • NoSchedule: 不允许没有容忍度的 Pods 调度到该节点。
  • PreferNoSchedule: 尽量不调度没有容忍度的 Pods 到该节点,但不是强制的。
  • NoExecute: 不允许没有容忍度的 Pods 在该节点上运行,如果已在运行,会被驱逐。

 

为节点添加污点

kubectl taint nodes node1 key=value:NoSchedule

 

删除污点

kubectl describe nodes <node-name>
kubectl taint nodes <node-name> <key>:<value>:<effect>-

 

污点使用 Key-Value 的组合的原因:

重要的原因:

1. 灵活性

  • 多样性: 通过使用 Key 和 Value 的组合,可以为同一个 Key 定义多个不同的情况。例如,可以有多个污点,如: