image-20231005151808653: https://www.youtube.com/watch?v=TlHvYWVUZyc

概述

回顾

  • 部署方式的演化,详见kubernetes: Going back in time

    Deployment evolution: https://kubernetes.io/docs/concepts/overview/

  • docker部署存在的问题

    • 不利于扩缩容=>需求变动导致部署机器变动时,需要手动维护
    • 不利于管理=>部署基础镜像变更时,需要手动维护已部署的机器;负载均衡设计愈发复杂(当部署机器增多时,需要多层负载均衡机制)

    image-20231005111347640: https://www.youtube.com/watch?v=7bA0gTroJjw

  • k8s优点,详见kubernetes: Why you need Kubernetes and what it can do

    • Service discovery and load balancing
    • Storage orchestration
    • Automated rollouts and rollbacks
    • Automatic bin packing
    • Self-healing
    • Secret and configuration management

架构

Components of Kubernetes: https://kubernetes.io/docs/concepts/overview/components/

  • 一个Kubernetes集群至少包含一个控制平面(control plane),以及一个或多个工作节点(worker node)

  • 控制平面(Control Plane) : 控制平面负责管理工作节点和维护集群状态。所有任务分配都来自于控制平面

  • 工作节点(Worker Node) : 工作节点负责执行由控制平面分配的请求任务,运行实际的应用和工作负载

Control Plane

image-20231005134700376: https://www.youtube.com/watch?v=s_o8dwzRlu4

kube-apiserver

  • 如果需要与Kubernetes 集群进行交互,就要通过 API

  • apiserver是 Kubernetes 控制平面的前端,用于处理内部和外部请求

kube-scheduler

  • 集群状况是否良好?如果需要创建新的容器,要将它们放在哪里?这些是调度程序需要关注的问题

  • scheduler调度程序会考虑容器集的资源需求(例如 CPU 或内存)以及集群的运行状况。随后,它会将容器集安排到适当的计算节点

etcd

  • etcd是一个键值对数据库,用于存储配置数据和集群状态信息

kube-controller-manager

  • 控制器负责实际运行集群,controller-manager控制器管理器则是将多个控制器功能合而为一,降低了程序的复杂性。

  • controller-manager包含了这些控制器:

    • 节点控制器(Node Controller):负责在节点出现故障时进行通知和响应
    • 任务控制器(Job Controller):监测代表一次性任务的 Job 对象,然后创建 Pods 来运行这些任务直至完成
    • 端点控制器(Endpoints Controller):填充端点(Endpoints)对象(即加入 Service 与 Pod)
    • 服务帐户和令牌控制器(Service Account & Token Controllers):为新的命名空间创建默认帐户和 API 访问令牌

cloud-controller-manager

  • 控制平面还包含一个可选组件cloud-controller-manager

  • 云控制器管理器(Cloud Controller Manager)允许你将你的集群连接到云提供商的 API 之上, 并将与该云平台交互的组件同与你的集群交互的组件分离开来

  • 如果在自己的环境中运行 Kubernetes,或者在本地计算机中运行学习环境, 所部署的集群不需要有云控制器管理器

Worker Node

image.png: https://www.yuque.com/wukong-zorrm/qdoy5p/lrsast

kubelet

kube-proxy

  • kube-proxy 是集群中每个节点(node)上运行的网络代理,是实现 Kubernetes 服务(Service) 概念的一部分

  • kube-proxy 维护节点网络规则和转发流量,实现从集群内部或外部的网络与 Pod 进行网络通信

Container Runtime

Pod

  • Pod 是包含一个或多个容器的容器组,是 Kubernetes 中创建和管理的最小对象
  • Pod 有以下特点:
    • Pod是kubernetes中最小的调度单位(原子单元),Kubernetes直接管理Pod而不是容器
    • 同一个Pod中的容器总是会被自动安排到集群中的同一节点(物理机或虚拟机)上,并且一起调度
    • Pod可以理解为运行特定应用的“逻辑主机”,这些容器共享存储、网络和配置声明(如资源限制)
    • 每个 Pod 有唯一的 IP 地址。 IP地址分配给Pod,在同一个 Pod 内,所有容器共享一个 IP 地址和端口空间,Pod 内的容器可以使用localhost互相通信

Kubectl

  • kubectl 是一个kubernetes命令行工具

  • kubectl 使用 Kubernetes API 与 Kubernetes 集群的control plane进行通信,可以使用 kubectl 部署应用程序、检查和管理群集资源以及查看日志

Workload

  • Deployment是对 ReplicaSet 和 Pod 更高级的抽象。它使 Pod 拥有多副本,自愈,扩缩容、滚动升级等能力
  • ReplicaSet 是一个 Pod 的集合。它可以设置运行 Pod 的数量,确保任何时间都有指定数量的 Pod 副本在运行。通常我们不直接使用 ReplicaSet,而是在Deployment 中声明
  • statefulset主要用于持久化数据 Pod 管理
  • daemonset:跟随 node 变化而自动生成和删除特定 pod,如需要在每个 node 运行日志收集服务

Service

image.png

概念

  • Service将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法

  • Service为一组 Pod 提供相同的 DNS 名,并且在它们之间进行负载均衡

  • Kubernetes 为 Pod 提供分配了IP 地址,但IP地址可能会发生变化

  • 集群内的容器可以通过service名称访问服务,而不需要担心Pod的IP发生变化


  • 逻辑上的一组可以互相替换的 Pod,通常称为微服务

  • Service 对应的 Pod 集合通常是通过Labels and Selectors来确定的

  • 举个例子,在一个Service中运行了3个nginx的副本。这些副本是可互换的,我们不需要关心它们调用了哪个nginx,也不需要关注 Pod的运行状态,只需要调用这个服务就可以了

Service对象(ServiceType 取值)

  • ClusterIP:将服务公开在集群内部。kubernetes会给服务分配一个集群内部的 IP,集群内的所有主机都可以通过这个Cluster-IP访问服务。集群内部的Pod可以通过service名称访问服务
  • NodePort:通过每个节点的主机IP 和静态端口(NodePort)暴露服务。 集群的外部主机可以使用节点IP和NodePort访问服务
  • ExternalName:将集群外部的网络引入集群内部
  • LoadBalancer:使用云提供商的负载均衡器向外部暴露服务

config yaml(声明式对象配置)

管理对象

  • 命令行指令

    • 例如,使用kubectl命令来创建和管理 Kubernetes 对象

    • 命令行就好比口头传达,简单、快速、高效

    • 但它功能有限,不适合复杂场景,操作不容易追溯,多用于开发和调试

  • 声明式配置

    • kubernetes使用yaml文件来描述 Kubernetes 对象

    • 声明式配置就好比申请表,学习难度大且配置麻烦

    • 好处是操作留痕,适合操作复杂的对象,多用于生产

常用命令缩写

名称 缩写 Kind
namespaces ns Namespace
nodes no Node
pods po Pod
services svc Service
deployments deploy Deployment
replicasets rs ReplicaSet
statefulsets sts StatefulSet

YAML规范

  • 缩进代表上下级关系
  • 缩进时不允许使用Tab键,只允许使用空格,通常缩进2个空格
  • : 键值对,后面必须有空格
  • -列表,后面必须有空格
  • [ ]数组
  • #注释
  • | 多行文本块
  • ---表示文档的开始,多用于分割多个资源对象

配置对象

  • 在创建的 Kubernetes 对象所对应的 yaml文件中,需要配置的字段如下:

    • apiVersion - Kubernetes API 的版本
    • kind - 对象类别,例如PodDeploymentServiceReplicaSet
    • metadata - 描述对象的元数据,包括一个 name 字符串、UID 和可选的 namespace
    • spec - 对象的配置
  • 使用YAML配置pod, kubernetes: Using Pods

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # my-pod.yaml
    apiVersion: v1
    kind: Pod
    metadata:
    name: my-nginx
    spec:
    containers:
    - name: nginx
    image: nginx:1.22
    ports:
    - containerPort: 80
  • 使用yaml文件管理对象

    1
    2
    3
    4
    5
    6
    7
    8
    # 创建对象
    kubectl apply -f my-pod.yaml
    # 获取对象
    kubectl get pods
    # 编辑对象
    kubectl edit pod my-nginx
    # 删除对象
    kubectl delete -f my-pod.yaml

标签

  • 标签(Labels) 是附加到对象(比如 Pod)上的键值对,用于补充对象的描述信息

  • 标签使用户能够以松散的方式管理对象映射,而无需客户端存储这些映射

  • 由于一个集群中可能管理成千上万个容器,我们可以使用标签高效的进行选择和操作容器集合

  • 键的格式:前缀**(可选)/名称(必须)。

  • 有效名称和值:

  • 必须为 63 个字符或更少(可以为空)

  • 如果不为空,必须以字母数字字符([a-z0-9A-Z])开头和结尾

  • 包含破折号-、下划线_、点.和字母或数字

  • YAML文件配置,kubernetes: Syntax and character set

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    apiVersion: v1
    kind: Pod
    metadata:
    name: label-demo
    labels: #定义Pod标签
    environment: test
    app: nginx
    spec:
    containers:
    - name: nginx
    image: nginx:1.22
    ports:
    - containerPort: 80

选择器

  • 标签选择器 可以识别一组对象。标签不支持唯一性

  • 标签选择器最常见的用法是为Service选择一组Pod作为后端

  • YMAL文件配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    apiVersion: v1
    kind: Service
    metadata:
    name: my-service
    spec:
    type: NodePort
    selector: #与Pod的标签一致
    environment: test
    app: nginx
    ports:
    # 默认情况下,为了方便起见,`targetPort` 被设置为与 `port` 字段相同的值。
    - port: 80
    targetPort: 80
    # 可选字段
    # 默认情况下,为了方便起见,Kubernetes 控制平面会从某个范围内分配一个端口号(默认:30000-32767)
    nodePort: 30007
  • 目前支持两种类型的选择运算:基于等值的基于集合的。 多个选择条件使用逗号分隔,相当于And(&&)运算

    • 等值选择

      1
      2
      3
      4
      selector:
      matchLabels: # component=redis && version=7.0
      component: redis
      version: 7.0
    • 集合选择

      1
      2
      3
      4
      selector:
      matchExpressions: # tier in (cache, backend) && environment not in (dev, prod)
      - {key: tier, operator: In, values: [cache, backend]}
      - {key: environment, operator: NotIn, values: [dev, prod]}

Deployment 和 StatefulSet 在 Kubernetes 中的区别

  1. Deployment
    • 适用性:用于部署无状态应用,如 Web 服务器、API 服务器等。适合可以水平扩展和缩减副本数量的应用。
    • 唯一性:每个 Pod 是相互独立的,没有任何关联或特定顺序。
    • 稳定性:Deployment 控制器确保应用持续可用,但不保证 Pod 的唯一性和稳定性。
    • 命名:Pod 的名称通常是随机的,不具备可预测性。
    • 存储:Deployment 不适合需要持久化存储或有序部署的应用。
  2. StatefulSet
    • 适用性:用于部署有状态应用,如数据库、消息队列等。适合需要唯一标识、稳定网络标识和持久化存储的应用。
    • 唯一性:每个 Pod 有唯一的标识符,保持稳定的网络标识和有序部署。
    • 稳定性:StatefulSet 会为每个 Pod 提供稳定的标识符和网络标识,确保在 Pod 重启或迁移时保持稳定性。
    • 命名:Pod 的名称遵循一定的命名约定,如<StatefulSet名称>-<ordinal>
    • 存储:StatefulSet 支持有序部署、持久化存储卷和有状态应用的数据保留。

参考

  • kubernetes官网
  • you need to learn Kubernetes RIGHT NOW!!,B站, youtube
  • Kubernetes入门90分钟精讲,bilibilidocument
  • Kubernetes Crash Course for Absolute Beginners [NEW],youtube
  • Kubernetes Explained in 6 Minutes | k8s Architecture,youtube
  • Kubernetes Course - Full Beginners Tutorial (Containerize Your Apps!),youtube