【K8s】Kubernetes核心概念与架构详解

本专栏文章持续更新 ,新增内容使用蓝色表示。

Kubernetes 是一个开源的容器编排引擎,用来对容器化应用进行自动化部署、扩缩和管理。

官网链接:
Kubernetes 文档 | Kuberneteshttps://kubernetes.io/zh-cn/docs/home/

K8sKubernetes 的缩写形式,一个意思,因为 K 和 s 之间8个字符。

一、k8s集群组件

Kubernetes 集群由控制平面 和一个或多个工作节点组成。如下图所示:

工作节点承载着作为应用工作负载组成部分的 Pod。控制平面负责管理集群中的工作节点以及Pod,通常运行在多台机器上,防止单点故障

1.1 控制平面(Control Plane)

作用是管理集群的整体状态,主要有以下组件:

kube-apiserver (API 服务器): Kubernetes 的最高管理进程,集群的唯一入口,为集群其他组件提供与etcd交互的网关。访问K8s必须经过它

etcd:具备一致性和高可用性的键值存储,用于所有 API 服务器的数据存储。

kube-scheduler (调度器):查找尚未绑定到节点的 Pod,并将每个 Pod 分配给合适的节点。决定Pod放在哪个节点上

kube-controller-manager(控制器管理器):通过 API Server 持续监控集群状态,当集群的实际状态与期望状态不一致时,它会通过 API Server 尝试将系统状态修复到期望状态。

cloud-controller-manager(云控制器管理器)【可选】:云服务器提供,不属于 K8s 本身。

1.2 节点(Node)

节点组件在每个节点上运行,维护运行的 Pod 并提供 Kubernetes 运行时环境:

kubelet:负责与 api-server 通信,并管理本节点的 Pod 及其中的容器。但它并不管理非 Kubernetes 创建的容器。

kube-proxy【可选】:是一个网络代理,通过动态维护节点上的网络规则(如 iptables/IPVS),实现Service 到 Pod 的流量转发(负载均衡),集群内外网络通信(通过ClusterIP/NodePort/LoadBalancer 类型 Service)。

container runtime(容器运行时):真正管理容器生命周期的软件。kubelet 通过 CRI(container run interface)使用各种容器运行时间接管理容器。CRI 是 kubelet 与容器运行时之间的 gRPC 协议规范。

kubelet 创建 Pod 的流程

当 kubelet 收到创建 Pod 的指令时,通过 CRI 分步骤操作容器:

1)创建 Pod 沙箱(Sandbox)

先调用 CRI 的 RunPodSandbox 方法,创建一个隔离环境(Linux 下是 pause 容器)。沙箱负责共享网络/存储命名空间,为后续容器提供运行环境。

2)依次创建容器

通过 CRI 的 CreateContainer 为每个 spec.containers 创建容器。容器会共享沙箱的网络和存储卷。

3)启动容器

调用 StartContainer 启动所有容器。

【思考】Pod如果已创建,还可以增加容器吗?

不可以,Pod 有不可变性,其绝大多数元数据都是不可变,但是可以通过 deployment 实现动态更新。

1.3 插件(Addons)

由于K8s的涉及理念是"小而精",所以它只做容器编排,其它功能由插件扩展。插件使用K8s资源实现集群级别的功能。以下是常见的插件示例:

功能类别 依赖的接口规范 插件示例 作用说明
集群DNS 无(K8s原生需求) CoreDNS, kube-dns 解析 svc.cluster.local 等域名
网络插件 CNI Calico(支持BGP), Cilium, Flannel 实现Pod间通信和网络策略
Web界面 Kubernetes API Dashboard 可视化资源管理
容器资源监控 Metrics API Prometheus, Metrics Server 采集容器指标和告警
集群层面日志 无(自定义收集) Fluentd, Loki 集中存储和分析容器日志

二、K8s涉及到的常见概念

以下为简单概述,后期会有详细介绍每部分的文章。

2.1 容器

打包应用及其运行依赖环境的技术。

2.2 容器镜像

一个随时可以运行的软件包, 包含运行应用程序所需的一切:代码和它需要的所有运行时、应用程序和系统库,以及一些基本设置的默认值。 容器旨在设计成无状态且不可变的,如果要修改一个容器化的应用程序,需要先构建更改后的新镜像,再基于新构建的镜像重新运行容器。

2.3 Pod

Pod 是 K8s 能够创建、管理和部署的最小计算单元 ,也是 K8s 进行资源分配(CPU、内存、存储、网络等)的基本单位,它像一个豌豆荚,内部包含一个或多个容器。出于微服务的思想,一个 Pod 通常只运行一个主容器,只有容器紧耦合并且需要共享磁盘等资源时,才应将其编排在一个 Pod 中。

2.3.1 Pod的生命周期

Pod 的 phase 是其生命周期的宏观状态标签,直接反映 Pod 所处的核心阶段。以下是其取值:

取值 描述
Pending(悬决) Pod 已被 K8s 系统接受,但有一个或者多个容器镜像尚未创建。等待时间包括调度 Pod 的时间和通过网络下载镜像的时间。
Running(运行中) 该 Pod 已经绑定到了一个节点上,Pod 中所有的容器都已被创建,至少有一个容器正在运行,或者正处于启动或重启状态。
Succeeded(成功) Pod 中的所有容器都已成功结束,并且不会再重启。
Failed(失败) Pod 中的所有容器都已终止了,并且至少有一个容器是因为失败终止,即容器以非 0 状态退出或者被系统终止。
Unknown(未知) 因为某些原因无法取得 Pod 的状态,通常是因为 Pod 与其所在主机通信失败。

2.4 kubeadm

kubeadm 是 Kubernetes 的集群部署工具,提供了构建集群的指令,用于快速初始化控制平面和添加工作节点。kubeadm init 初始化集群,kubeadm join 扩充集群节点。

2.5 kubectl

kubectl 是 K8s 的命令行管理工具,将命令行转换为 API 请求,通过 API Server 操作集群。常见操作如下:

功能类别 典型操作
集群管理 查看节点状态、配置上下文(Context)、切换命名空间(Namespace)。
资源操作 创建/删除/更新 Pod、Deployment、Service 等资源。
状态监控 查看日志(log)、进入容器调试、检查资源状态和事件。
故障排查 描述资源详情(describe)、端口转发(port-forward)、执行命令(exec)。

命令格式:

bash 复制代码
kubectl action resource

常用命令:

  • kubectl get - 列出资源
  • kubectl describe - 显示有关资源的详细信息
  • kubectl logs - 打印 Pod 中容器的日志
  • kubectl exec - 在 Pod 中的容器上执行命令

创建对象:

bash 复制代码
kubectl apply -f <对象定义文件>.yaml

查看对象:

bash 复制代码
kubectl get <对象类型> [选项]       # 默认显示当前命名空间下的对象

| 选项 | 作用 |
| -w | 实时监控对象变化 |
| -o wide | 显示对象 IP 和节点信息 |

-A 查询所有命名空间

删除对象:

bash 复制代码
kubectl delete -f <对象定义文件>.yaml

2.6 K8s 对象

Kubernetes 对象是用户通过 API 声明 的实体,用于表示整个集群的状态(应用、资源、配置等) 。所有对象都通过 YAML/JSON 文件 定义,(kubectl)提交给 Kubernetes API Server 后,由控制平面确保集群状态与声明一致。创建对象本质上是在告知 Kubernetes 系统集群工作负载的期望状态。

在日常使用和官方文档中,K8s 对象K8s 资源 常混用,指的是同一个概念

常见 K8s 对象类型
对象类型 作用
Pod 最小部署单元,包含 1 个或多个容器。
Deployment 管理 Pod 的副本数和滚动更新(声明式无状态应用)。
Service 定义 Pod 的访问方式(ClusterIP、NodePort、LoadBalancer)。
ConfigMap 存储非敏感配置。
Secrets 存储敏感配置。
Namespace 逻辑隔离集群资源。

Kubernetes 对象所对应的清单(YAML 或 JSON 文件)中,需要配置的字段如下:

  • apiVersion - 创建该对象所使用的 Kubernetes API 的版本
  • kind - 想要创建的对象的类别
  • metadata - 唯一标识对象的一些数据,包括一个 name 字符串、UID 和可选的 namespace
  • spec - 该对象的期望状态

不同 Kubernetes 对象的 spec 字段有所不同,包含了特定于该对象的嵌套字段。

以 Kubernetes Deployment 为例(这里不做具体介绍):

bash 复制代码
cat > deployment-service.yml <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment-servicetest
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
EOF

创建对象有两种方法:命令行创建和 YAML 文件创建(推荐)。

使用 YAML 文件创建对象的过程简单总结为:编写 YAML 脚本,然后 kubectl apply ,也可以用 create 。两者的区别为:

  • apply :若资源不存在则创建,若存在则按 YAML 增量更新(仅修改变化字段)。
  • create: 资源已存在时报错 AlreadyExists,必须先用 delete 删除旧资源。

所以推荐使用 apply 。

三、常见问题

3.1 K8s 集群的创建过程

1)安装与配置服务器节点。

2)在各节点上安装 docker-ce, docker-ce-cli, containerd.io, docker-compose-plugin;部署 CRI-Docker。

3)在各个节点关闭 Swap 分区;加载 br_netfilter 以允许 iptables 桥接流量;安装 kubeadm, kubectl 和 kubelete 软件包;集成 CRI-Docker。

4)在 master 节点上部署集群(kubeadm.yaml),创建集群(kubeadm init), 加入各节点(kubeadm join)。

5)部署 Calico 网络插件,检查验证集群状态。

3.2 部署安装K8s为什么要关闭swap分区?

在虚拟内存管理系统中,尽管 swap 可以在磁盘上增加系统的可用内存量,但在磁盘虚拟页面和内存页面交换过程中会带来额外的磁盘 I/O 负载,加之容器运行环境自身对磁盘的吞吐量有很高的需求, 因此,swap 分区的使用会在高负载情况下导致 K8s 系统的整体性能下降并有可能导致应用程序的崩溃。

3.3 以下问题文中有答案

3.3.1 kube-apiserver, etcd, kube-controller-manager, kube-scheduler的作用

3.3.2 kubelet, kube-proxy作用

3.3.3 请解释Pod是什么?

3.3.4 Pod的生命周期

预告下一篇

命名空间和Pod,以及其分类、如何创建、删除、查看等内容。


如有问题或建议,欢迎在评论区中留言~