Kubernetes 入门教程之一

大纲

Kubernetes 简单介绍

各种部署方式的区别

传统的应用部署方式是通过插件或脚本来安装应用,这样做的缺点是应用的运行、配置、管理、所有生存周期将与当前操作系统绑定,这样做并不利于应用的升级更新、回滚等操作;当然也可以通过创建虚拟机的方式来实现某些功能,但是虚拟机非常重,并不利于可移植性。新的方式是通过部署容器方式实现,每个容器之间互相隔离,每个容器有自己的文件系统,容器之间进程不会相互影响,能区分计算资源。相对于虚拟机,容器能够快速部署,由于容器与底层设施、机器文件系统解耦的,所以它能在不同云、不同版本操作系统间进行迁移。容器占用资源少、部署快,每个应用可以被打包成一个容器镜像,每个应用与容器间成一对一关系也使容器有更大优势,使用容器可以在 buildrelease 的阶段,为应用创建容器镜像,因为每个应用不需要与其余的应用堆栈组合,也不依赖于生产环境基础结构,这使得从研发到测试、生产能提供一致环境。类似地,容器比虚拟机轻量、更 “透明”,这更便于监控和管理。

Kubernetes 基本介绍

Kubernetes 是 Google 于 2014 年 6 月正式开源的一个容器编排引擎,简称 K8s,是用 8 代替 8 个字符 ubernete 而成的缩写。Kubernetes 可用于管理云平台中多个主机上的容器化的应用,支持自动化部署、大规模扩缩容、应用容器化管理。在生产环境中部署一个应用程序时,通常要部署该应用的多个实例以便对应用请求进行负载均衡。Kubernetes 提供了应用部署、规划、更新、维护的一种机制。在 Kubernetes 中,可以创建多个容器,每个容器里面运行一个应用实例,然后通过内置的负载均衡策略,实现对这一组应用实例的管理、发现、访问,而这些细节都不需要运维人员去进行复杂的手工配置和处理。

Kubernetes 功能介绍

Kubernetes 是一个轻便的和可扩展的开源平台,用于管理容器化应用和服务。通过 Kubernetes 能够进行应用的自动化部署和扩缩容。在 Kubernetes 中,会将组成应用的容器组合成一个逻辑单元以更易管理和发现。Kubernetes 积累了作为 Google 生产环境运行工作负载 15 年的经验,并吸收了来自于社区的最佳想法和实践。Kubernetes 的核心功能如下:

  • 自动装箱:基于容器对应用运行环境的资源配置要求自动部署应用容器
  • 自我修复:当容器运行失败时,会对容器进行重启;当所部署的 Node(工作节点)有问题时,会对容器进行重新部署和重新调度;当容器未通过监控检查时,会关闭此容器直到容器正常运行时,才会对外提供服务
  • 水平扩展:通过简单的命令、用户 UI 界面或基于 CPU 等资源使用情况,对应用容器进行规模扩大或规模剪裁
  • 服务发现:用户不需使用额外的服务发现机制,就能够基于 Kubernetes 自身能力实现服务发现和负载均衡
  • 滚动更新:可以根据应用的变化,对应用容器运行的应用,进行一次性或批量式更新
  • 版本回退:可以根据应用部署情况,对应用容器运行的应用,进行历史版本即时回退
  • 密钥和配置管理:在不需要重新构建镜像的情况下,可以部署和更新密钥和应用配置,类似热部署
  • 存储编排:自动实现存储系统挂载及应用,这特别对有状态应用实现数据持久化非常重要;存储系统可以来自于本地目录、网络存储(NFS、Gluster、Ceph 等)、公共云存储服务
  • 批处理:提供一次性任务,定时任务,满足批量数据处理和分析的场景

Kubernetes 核心技术

技术名称技术描述
YAML 配置文件使用 YAML 文件定义 Kubernetes 资源,如 Pod、Service、Deployment 等,是声明式管理的基础。
kubectl 命令工具 Kubernetes 的命令行客户端工具,用于操作集群、部署资源、排查故障等。
PodKubernetes 中最小的可调度单元,通常封装一个或多个容器,容器共享网络和存储。
Controller(控制器)自动化资源管理的核心组件,如 Deployment、ReplicaSet、StatefulSet、DaemonSet 等控制器。
Service 定义一组 Pod 的统一访问入口,支持负载均衡和服务发现。
Label 给资源打标签的机制,支持资源的分类、选择、分组管理等,用于调度和服务发现。
Volume 提供容器持久化或共享数据的机制,支持本地存储、NFS、云存储等。
PVC 和 PVPVC(Persistent Volume Claim)是用户请求的存储资源,PV(Persistent Volume)是实际存储资源,解耦用户和存储实现。
Secret 和 ConfigMapSecret 用于管理敏感数据,ConfigMap 用于存储配置数据,都可挂载进容器或作为环境变量使用。
Namespace 提供资源隔离的逻辑空间,用于多租户环境或资源分类管理。
Probes(探针)包括存活探针(liveness)和就绪探针(readiness),用于健康检查和控制流量转发。
API ServerKubernetes 控制平面的核心组件,负责处理来自 kubectl 或其他客户端的请求,并与 Etcd、Controller(控制器)、Scheduler(调度器)等交互。
Scheduler(调度器)根据资源需求、约束条件和策略将 Pod 分配到合适的节点。
集群安装机制与 RBAC 安装机制包括 kubeadm、Kops、RKE 等,RBAC(基于角色的访问控制)用于权限管理和安全控制。
HelmKubernetes 的包管理工具,用于简化应用部署,支持版本管理、参数化配置等。

Kubernetes 核心概念

Kubernetes 三个核心概念(Pod、Controller、Service)的介绍(如图所示):

  • Pod(最小部署单元)

    • Pod 是 Kubernetes 中最小的调度和运行单元。
    • 本质上是一组容器的集合(通常是一个容器)。
    • 容器之间共享网络(IP、端口)和存储卷。
    • Pod 的生命周期可以是短暂的,比如用于运行临时任务或被控制器自动重建。
  • Controller(控制器)

    • 用于管理和自动化 Pod 的部署与副本数量。
    • 支持无状态应用部署(如 Deployment)。
    • 支持有状态应用部署(如 StatefulSet)。
    • 可实现以下功能:
      • 保证指定数量的 Pod 实例持续运行。
      • 在多个节点上部署同一类 Pod(如 DaemonSet)。
      • 支持一次性任务(Job)和定时任务(CronJob)。
  • Service(服务)

    • 负责定义一组 Pod 的访问规则。
    • 提供统一的访问入口(Cluster IP、NodePort、LoadBalancer 等),实现服务发现与负载均衡。
    • 解决 Pod 动态 IP 和短生命周期带来的访问不稳定问题。

Pod、Controller、Service 这三个核心概念的关系:

  • Pod 是具体运行的实例。
  • Controller 管理 Pod 的创建、副本和调度。
  • Service 让外部或内部服务可以稳定地访问 Pod。

Kubernetes 集群搭建

集群架构组件

  • Master(主控节点):Kubernetes 集群控制节点,负责对集群进行调度管理,接受集群外的用户去集群操作请求。Master 由 API Server、Scheduler、Controller Manager、Etcd 存储系统组成

    • Scheduler:节点调度,选择 Node(工作节点)来应用部署
    • API Server:集群统一入口,以 RESTful 接口将数据交给 Etcd 进行存储
    • Controller Manager:处理集群中的常规后台任务,一个资源对应一个控制器
    • Etcd 存储系统:用于存储集群相关的数据
  • Node(工作节点):Kubernetes 集群工作节点,负责运行用户业务应用容器,Node 由 Kubelet、Kube-Proxy 和 Container Runtime 组成

    • Kubelet:负责 Pod 对应的容器的创建、启停管理,与 Master 节点协作,实现集群管理的基本功能
    • Kube-Proxy:提供 Kubernetes 的通信与负载均衡功能的重要组件

Etcd 是什么

  • 在分布式系统中,Etcd 是一个高可用、强一致性的分布式键值存储系统,在 Kubernetes 等系统中扮演着核心元数据存储和协调中心的角色。
  • Etcd 属于更底层的基础组件,使用 Raft 算法实现强一致性(满足 CAP 中的 C 和 P),提供了一致性的 KV 存储、watch、lease、事务等机制。

集群搭建规划

Kubernetes 集群有两种类型,包括单 Master 集群和多 Master 集群,为了提高集群的高可用性,生产环境一般采用多 Master 集群方案,如下图所示:

集群搭建要求

搭建 Kubernetes 集群需要满足以下几个条件:

  • 一台或多台机器,建议操作系统 CentOS 7(64 位)
  • Master 节点的硬件配置:2GB 或更多 RAM,2 个 CPU 或更多 CPU,硬盘 20GB 或更多
  • Node(工作节点)的硬件配置:4GB 或更多 RAM,4 个 CPU 或更多 CPU,硬盘 40GB 或更多
  • 集群中所有机器之间的网络可以互通
  • 系统内可以访问外网,需要拉取镜像
  • 禁用 Swap 分区(必须)

集群搭建方式

目前生产环境搭建 Kubernetes 集群主要有以下两种方式:

  • Kubeadm

    • Kubeadm 是一个 Kubernetes 部署工具,提供 kubeadm initkubeadm join 命令,可用于快速搭建 Kubernetes 集群。
  • 二进制包

    • 从 Github 下载发行版的二进制包,手动部署每个组件,组成 Kubernetes 集群。Kubeadm 虽然降低部署门槛,但屏蔽了很多细节,遇到问题很难排查。
    • 如果想集群整体更可控,生产环境推荐使用二进制包搭建 Kubernetes 集群,虽然手动部署比较麻烦,但期间可以学习很多工作原理,也利于后期维护。

集群搭建步骤

二进制包方式搭建集群

Kubeadm 方式搭建集群

Kubernetes 核心技术

kubectl 命令行工具

kubectl 是 Kubernetes 集群的命令行工具,通过 kubectl 能够对集群本身进行管理,并能够在集群上进行容器化应用的安装部署。

kubectl 的语法

  • 命令语法:kubectl [command] [type] [name] [flags]

  • command

    • 指定要对资源执行的操作
    • 例如:creategetdescribedelete
  • type

    • 指定资源类型,资源类型是大小写敏感的,开发者能够以单数、复数和缩略的形式。例如:
    • kubectl get pod pod1
    • kubectl get pods pod1
    • kubectl get po pod1
    • kubectl get nodes K8s-node1
  • name

    • 指定资源的名称,名称大小写敏感。如果省略资源名称,则会显示所有的资源。例如:
    • kubectl get pods
    • kubectl get nodes
    • kubectl get nodes K8s-node1
  • flags

    • 指定可选的参数。例如,可以使用 -s 或者 -server 参数指定 Kubernetes API Server 的地址和端口。

kubectl 的使用帮助手册

可以使用 kubectl --help 命令查看 kubectl 命令的整体使用帮助,包括所有可用的主命令及其简要说明;还可以通过 kubectl <command> --help 获取某个具体子命令的详细使用手册和参数说明。

1
2
3
4
5
# 查看 kubectl 的所有主命令和帮助信息
# kubectl --help

# 查看 kubectl get 子命令的详细用法和参数说明
# kubectl get --help

比如,kubectl help 命令输出的帮助内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
kubectl controls the Kubernetes cluster manager.

Find more information at: https://kubernetes.io/docs/reference/kubectl/overview/

Basic Commands (Beginner):
create Create a resource from a file or from stdin.
expose 使用 replication controller, service, deployment 或者 pod 并暴露它作为一个 新的 Kubernetes
Service
run 在集群中运行一个指定的镜像
set 为 objects 设置一个指定的特征

Basic Commands (Intermediate):
explain 查看资源的文档
get 显示一个或更多 resources
edit 在服务器上编辑一个资源
delete Delete resources by filenames, stdin, resources and names, or by resources and label selector

Deploy Commands:
rollout Manage the rollout of a resource
scale Set a new size for a Deployment, ReplicaSet or Replication Controller
autoscale 自动调整一个 Deployment, ReplicaSet, 或者 Replication Controller 的副本数量

Cluster Management Commands:
certificate 修改 certificate 资源.
cluster-info 显示集群信息
top Display Resource (CPU/Memory/Storage) usage.
cordon 标记 node 为 unschedulable
uncordon 标记 node 为 schedulable
drain Drain node in preparation for maintenance
taint 更新一个或者多个 node 上的 taints

Troubleshooting and Debugging Commands:
describe 显示一个指定 resource 或者 group 的 resources 详情
logs 输出容器在 pod 中的日志
attach Attach 到一个运行中的 container
exec 在一个 container 中执行一个命令
port-forward Forward one or more local ports to a pod
proxy 运行一个 proxy 到 Kubernetes API server
cp 复制 files 和 directories 到 containers 和从容器中复制 files 和 directories.
auth Inspect authorization

Advanced Commands:
diff Diff live version against would-be applied version
apply 通过文件名或标准输入流(stdin)对资源进行配置
patch 使用 strategic merge patch 更新一个资源的 field(s)
replace 通过 filename 或者 stdin替换一个资源
wait Experimental: Wait for a specific condition on one or many resources.
convert 在不同的 API versions 转换配置文件
kustomize Build a kustomization target from a directory or a remote url.

Settings Commands:
label 更新在这个资源上的 labels
annotate 更新一个资源的注解
completion Output shell completion code for the specified shell (bash or zsh)

Other Commands:
alpha Commands for features in alpha
api-resources Print the supported API resources on the server
api-versions Print the supported API versions on the server, in the form of "group/version"
config 修改 kubeconfig 文件
plugin Provides utilities for interacting with plugins.
version 输出 client 和 server 的版本信息

Use "kubectl <command> --help" for more information about a given command.
Use "kubectl options" for a list of global command-line options (applies to all commands).

kubectl 的子命令使用分类

  • 基础命令
命令说明
create通过文件名或标注输入创建资源
expose将一个资源公开为一个新的 Service
run在集群中运行一个特定的镜像
set在对象上设置特定的功能
get显示一个或多个资源
explain文档参考资料
edit使用默认的编辑器编辑一个资源
delete通过文件名、标注输入、资源名或标注选择来删除资源
  • 部署命令
命令说明
rollout管理资源的发布
rolling-update对某些类型的副本控制器滚动更新
scale扩容或缩容 Pod 数量,Deployment、ReplicaSet、Replication Controller 或 Job
autoscale创建一个自动选择扩容或缩容容器并设置 Pod 数量
  • 集群管理命令
命令说明
certificate修改证书资源
cluster-info显示集群信息
top显示资源(CPU/Memory/Storage)使用情况,需要 Heapster 运行
cordon标记节点不可调度
uncordon标记节点可调度
drain驱逐节点上的应用,准备下线维护
taint修改节点 Taint 标记
  • 故障和调试命令
命令说明
describe显示特定资源或资源组的详细信息
logs在一个 Pod 中打印一个容器日志。如 Pod 只有一个容器,容器名称是可选的
attach附加到一个运行的容器
exec执行命令到容器
port-forward转发一个或多个本地端口到一个 Pod
proxy运行一个 Proxy 到 Kubernetes API server
cp拷贝文件和目录到容器中或从容器中拷贝出来
auth检查授权
  • 其他高级命令
命令说明
apply通过文件名或标准输入对资源应用配置
patch使用补丁修改、更新资源的字段
replace通过文件名或标准输入替换一个资源
convert不同的 API 版本之间转换配置文件
  • 其他设置命令
命令说明
label更新资源上的标签
annotate更新资源上的注释
  • 其他常用命令
命令说明
completion用于实现 kubectl 工具自动补全
api-versions打印可用的 API 版本
config修改 kubeconfig 文件(用于访问 API,比如凭证信息配置)
help所有命令帮助
plugin运行一个可执行插件
version打印客户端和服务端的版本信息

最常用的命令

  • kubectl get pods:查看当前命名空间下所有 Pod 的状态信息。
  • kubectl get nodes:查看集群中所有节点(Node)的状态信息。
  • kubectl get svc: 查看当前命名空间下所有 Service(服务)资源的配置信息。
  • kubectl get cs: 查看集群核心组件(ComponentStatus,如 Scheduler、Controller Manager 等)的运行状态,已过时不推荐使用。

YAML 资源编排清单

在 Kubernetes 集群中,资源管理和资源对象的编排部署可以通过声明式的 YAML 文件来实现。用户可以将对资源对象的操作需求编写到 YAML 格式的配置文件中,这种文件称为资源清单文件。通过 kubectl 命令直接调用这些资源清单文件,就能够高效地完成大量资源对象的编排和部署工作。

YAML 的概述

  • YAML 是一个可读性高,用来表达数据序列的格式。
  • YAML 仍是一种标记语言,为了强调这种语言以数据作为中心,而不是以标记语言为重点。

YAML 的基本语法

  • 使用空格作为缩进;
  • 缩进的空格数量不重要,只要相同层级的元素左侧对齐即可;
  • 低版本缩进时,不允许使用 Tab 键,只允许使用空格;
  • 使用 --- 作为文档分隔符,表示一个 YAML 文件中的多文档边界;
  • 使用 # 标识注释,从这个字符一直到行尾,都会被 YAML 解释器忽略。

YAML 支持的数据结构

  • 对象:键值对的集合,又称为映射 (Mapping) / 哈希 (Hash) / 字典 (Dictionary)
1
2
3
4
5
6
# 对象类型:对象的一组键值对,使用冒号结构表示
name: Tom
age: 18

# Yaml 也允许另一种写法,将所有键值对写成一个行内对象
hash: {name: Tom, age: 18}
  • 数组:一组按次序排列的值,又称为序列 (Sequence) / 列表 (List)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 横向写法(行内数组)
fruits: ["apple", "banana", "cherry"]

# 纵向写法(可读性更好,推荐)
fruits:
- apple
- banana
- cherry

# 结合对象的数组(数组中每个元素都是一个对象)
users:
- name: Alice
age: 25
- name: Peter
age: 30
  • 多行字符串可以使用 | 保留换行符,也可以使用 > 折叠换行
1
2
3
4
# 使用 `|` 保留换行符
this: |
Foo
Bar
  • 多个 YAML 文档之间可以使用 --- 文档分隔符分隔
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 第一个文档(例如定义一个 ConfigMap)
apiVersion: v1
kind: ConfigMap
metadata:
name: config1
data:
key: value

---

# 第二个文档(例如定义一个 Secret)
apiVersion: v1
kind: Secret
metadata:
name: secret1
type: Opaque
data:
token: BASE64_ENCODED_DATA

YAML 资源清单的描述方法

在 Kubernetes 中,用户通常使用 YAML 格式的配置文件来定义和创建符合预期状态的集群资源(如 Pod、Deployment 等)。这类遵循 Kubernetes API 规范、用于描述资源对象及其期望状态的 YAML 文件,被称为资源清单(Manifest)。

  • 常用字段(必须存在的属性
参数名字段类型说明
versionStringK8s API 的版本,目前基本是 v1,可以用 kubectl api-versions 命令查询
kindStringYAML 文件定义的资源类型和角色,例如:Pod
metadataObject 元数据对象,固定值写 metadata
metadata.nameString 元数据对象的名字,由用户定义,例如命名 Pod 的名字
metadata.namespaceString 元数据对象的命名空间,由用户定义
specObject 详细定义对象,固定值写 spec
spec.containers[]listspec 对象的容器列表定义,是一个列表
spec.containers[].nameString 定义容器的名称
spec.containers[].imageString 定义容器使用的镜像名称
  • 资源清单的定义示例(创建一个 Nginx 的 Pod)
1
2
3
4
5
6
7
8
9
10
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
  • 更完整的资源清单定义示例(创建一个 Nginx 的 Deployment)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
  • 最后可以使用 kubectl apply -f xxxx.yaml 命令来执行这个资源清单

快速生成 YAML 资源清单

  • (1) 第一种方式:使用 kubectl create 命令快速生成 YAML 的配置模板内容
1
2
3
4
5
# 快速生成 YAML 配置模板内容,--dry-run=client 表示只在客户端进行验证和生成请求,而不把资源真正提交到 API Server
# kubectl create deployment nginx --image=nginx --dry-run=client -o yaml

# 或者将生成 YAML 配置模板内容输出到文件中
# kubectl create deployment nginx --image=nginx --dry-run=client -o yaml > nginx.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: nginx
name: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
resources: {}
status: {}
  • (2) 第二种方式:使用 kubectl get 命令导出正在运行的资源对象的 YAML 配置内容
1
2
3
4
# 查看当前正在运行的 Deployment
# kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 1/1 1 1 2d12h
1
2
# 导出当前正在运行的 Deployment 的 YAML 配置内容
# kubectl get deployment nginx -o yaml > nginx.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "1"
creationTimestamp: "2025-07-22T14:09:51Z"
generation: 1
labels:
app: nginx
managedFields:
- apiVersion: apps/v1
fieldsType: FieldsV1
fieldsV1:
f:metadata:
f:labels:
.: {}
f:app: {}
f:spec:
f:progressDeadlineSeconds: {}
f:replicas: {}
f:revisionHistoryLimit: {}
f:selector:
f:matchLabels:
.: {}
f:app: {}
f:strategy:
f:rollingUpdate:
.: {}
f:maxSurge: {}
f:maxUnavailable: {}
f:type: {}
f:template:
f:metadata:
f:labels:
.: {}
f:app: {}
f:spec:
f:containers:
k:{"name":"nginx"}:
.: {}
f:image: {}
f:imagePullPolicy: {}
f:name: {}
f:resources: {}
f:terminationMessagePath: {}
f:terminationMessagePolicy: {}
f:dnsPolicy: {}
f:restartPolicy: {}
f:schedulerName: {}
f:securityContext: {}
f:terminationGracePeriodSeconds: {}
manager: kubectl-create
operation: Update
time: "2025-07-22T14:09:51Z"
- apiVersion: apps/v1
fieldsType: FieldsV1
fieldsV1:
f:metadata:
f:annotations:
.: {}
f:deployment.kubernetes.io/revision: {}
f:status:
f:availableReplicas: {}
f:conditions:
.: {}
k:{"type":"Available"}:
.: {}
f:lastTransitionTime: {}
f:lastUpdateTime: {}
f:message: {}
f:reason: {}
f:status: {}
f:type: {}
k:{"type":"Progressing"}:
.: {}
f:lastTransitionTime: {}
f:lastUpdateTime: {}
f:message: {}
f:reason: {}
f:status: {}
f:type: {}
f:observedGeneration: {}
f:readyReplicas: {}
f:replicas: {}
f:updatedReplicas: {}
manager: kube-controller-manager
operation: Update
time: "2025-08-07T03:19:49Z"
name: nginx
namespace: default
resourceVersion: "300851"
selfLink: /apis/apps/v1/namespaces/default/deployments/nginx
uid: f8edd19f-3292-45ac-ad16-932611f528a8
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: nginx
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
app: nginx
spec:
containers:
- image: nginx
imagePullPolicy: Always
name: nginx
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
status:
availableReplicas: 1
conditions:
- lastTransitionTime: "2025-07-22T14:09:51Z"
lastUpdateTime: "2025-07-22T14:10:24Z"
message: ReplicaSet "nginx-6799fc88d8" has successfully progressed.
reason: NewReplicaSetAvailable
status: "True"
type: Progressing
- lastTransitionTime: "2025-08-07T03:19:49Z"
lastUpdateTime: "2025-08-07T03:19:49Z"
message: Deployment has minimum availability.
reason: MinimumReplicasAvailable
status: "True"
type: Available
observedGeneration: 1
readyReplicas: 1
replicas: 1
updatedReplicas: 1

Kubernetes 扩展知识

无状态和有状态应用

无状态和有状态应用的概念

  • 无状态应用(Stateless):
    • 应用实例之间没有任何区别,不依赖本地存储或唯一身份。
    • 任何一个实例都可以处理任何请求,并且可以被随时替换或扩展而不影响整体应用。
    • 这是云原生和微服务架构的默认假设。
    • 典型代表:Nginx、Web 服务、后端接口、无状态微服务。
  • 有状态应用(Stateful):
    • 应用实例有唯一身份(比如节点一、节点二)、需要稳定的持久化存储,或者实例之间有主从等依赖关系。
    • 替换或重新调度实例时,需要保持其身份和对应的数据。
    • 典型代表:MySQL、Kafka、ZooKeeper、ElasticSearch、Redis Cluster。

无状态应用的部署

在 Kubernetes 中,无状态应用通常使用 Deployment 来部署。

  • 部署特点

    • 所有 Pod 副本共享同一个持久化存储(如果需要)或完全不持久化数据。
    • Pod 的名称和网络标识是不稳定的(例如 web-app-7dfd644c7b-abcx5)。
    • 服务的访问方式是随机的,任何一个 Pod 都可以处理请求。
  • 部署例子

    • Web 前端应用:例如 React、Vue、Angular 应用。它们通常只是提供静态文件,会话数据(Session)可能存储在外部的 Cookie 或 Redis 中。
    • 简单的 RESTful API / 微服务:比如一个用户查询服务、商品详情服务,这些服务本身不存储任何数据,状态(数据)保存在后端的数据库(如 MySQL、PostgreSQL)或缓存(如 Redis)中。
    • 反向代理 / 负载均衡器:例如 Nginx 或 Traefik,它们根据规则路由流量,自身不会产生需要持久化的数据。
    • 无状态的计算:例如一个图像处理 Worker,它从消息队列(如 RabbitMQ、Kafka)中获取任务,处理完后将结果存入另一个数据库,任务本身与之前的状态无关。
  • 配置示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    apiVersion: apps/v1
    kind: Deployment # 使用 Deployment
    metadata:
    name: web-frontend
    spec:
    replicas: 3
    selector:
    matchLabels:
    app: web-frontend
    template:
    metadata:
    labels:
    app: web-frontend
    spec:
    containers:
    - name: nginx
    image: nginx:latest
    ports:
    - containerPort: 80

有状态应用的部署

在 Kubernetes 中,有状态应用必须使用 StatefulSet 来部署。

  • 部署特点

    • 每个 Pod 有唯一且稳定的网络标识(主机名),例如 kafka-0kafka-1kafka-2
    • 每个 Pod 通常绑定一个专用的持久化存储卷(PVC),Pod 重启或调度后,仍然会挂载同一个存储卷,保证数据不丢失。
    • Pod 的启动、扩容、缩容和更新是有严格顺序的(例如顺序创建、逆序终止等)。
  • 部署例子

    • 数据库(这是最典型的例子):
      • MySQL / PostgreSQL 主从集群:主节点需要读写,从节点同步数据。每个节点的数据和身份至关重要,不能混淆。
      • MongoDB 副本集:节点有明确的角色(如 Primary、Secondary)。
    • 缓存:
      • Redis Sentinel / 集群:包含不同角色的节点,身份固定,存储的数据不能丢失(如果开启了持久化)。
    • 消息队列:
      • Kafka 集群:每个 Broker 有唯一的 Broker ID,消息主题(Topic)的分区(Partitions)分布在不同的 Broker 上,存储的数据不能丢失。
      • RabbitMQ 集群:每个节点有唯一的节点名称。
    • 分布式数据存储:
      • Elasticsearch 集群:每个节点都有唯一的名称,存储特定的分片数据。
      • Etcd / ZooKeeper 集群:用于服务发现和配置共享,需要稳定的网络标识来组建集群。
    • 有状态的应用中间件:
      • 游戏服务器:每个实例管理一个特定的游戏房间或用户状态。
  • 配置示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    apiVersion: apps/v1
    kind: StatefulSet # 使用StatefulSet
    metadata:
    name: kafka
    spec:
    serviceName: "kafka-hs" # 必须有对应的无头服务
    replicas: 3
    selector:
    matchLabels:
    app: kafka
    template:
    metadata:
    labels:
    app: kafka
    spec:
    containers:
    - name: kafka
    image: kafka:latest
    ports:
    - containerPort: 9092
    volumeMounts:
    - name: data
    mountPath: /var/lib/kafka
    volumeClaimTemplates: # 关键:存储卷申请模板,每个Pod都会按此模板自动创建唯一的PVC
    - metadata:
    name: data
    spec:
    accessModes: [ "ReadWriteOnce" ]
    storageClassName: "ssd"
    resources:
    requests:
    storage: 100Gi

总结对比

特性无状态应用 (Deployment) 有状态应用 (StatefulSet)
Pod 身份随机,不唯一固定,有序且唯一
网络标识共享 Service,随机负载均衡稳定的 DNS 名称:<pod-name>.<svc-name>.<namespace>.svc.cluster.local
存储所有 Pod 共享持久化存储卷或无需存储每个 Pod 有自己独立的持久化存储卷(volumeClaimTemplates
部署 / 扩展并行,无顺序顺序操作(如:扩缩容时,从 0 到 N 顺序创建,从 N 到 0 逆序终止)
典型应用 Web 前端、API 微服务、无状态计算数据库(如 MySQL、PostgreSQL)、消息队列(如 Kafka、RabbitMQ)、集群(ES、ZK、Etcd)