Kubernetes 入门教程之一
大纲
- Kubernetes 入门教程之一、Kubernetes 入门教程之二、Kubernetes 入门教程之三
- Kubernetes 入门教程之四、Kubernetes 入门教程之五、Kubernetes 入门教程之六
- Kubernetes 入门教程之七、Kubernetes 入门教程之八、Kubernetes 入门教程之九
- Kubernetes 入门教程之十
Kubernetes 简单介绍
各种部署方式的区别
传统的应用部署方式是通过插件或脚本来安装应用,这样做的缺点是应用的运行、配置、管理、所有生存周期将与当前操作系统绑定,这样做并不利于应用的升级更新、回滚等操作;当然也可以通过创建虚拟机的方式来实现某些功能,但是虚拟机非常重,并不利于可移植性。新的方式是通过部署容器方式实现,每个容器之间互相隔离,每个容器有自己的文件系统,容器之间进程不会相互影响,能区分计算资源。相对于虚拟机,容器能够快速部署,由于容器与底层设施、机器文件系统解耦的,所以它能在不同云、不同版本操作系统间进行迁移。容器占用资源少、部署快,每个应用可以被打包成一个容器镜像,每个应用与容器间成一对一关系也使容器有更大优势,使用容器可以在 build 或 release 的阶段,为应用创建容器镜像,因为每个应用不需要与其余的应用堆栈组合,也不依赖于生产环境基础结构,这使得从研发到测试、生产能提供一致环境。类似地,容器比虚拟机轻量、更 “透明”,这更便于监控和管理。
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 的命令行客户端工具,用于操作集群、部署资源、排查故障等。 |
| Pod | Kubernetes 中最小的可调度单元,通常封装一个或多个容器,容器共享网络和存储。 |
| Controller(控制器) | 自动化资源管理的核心组件,如 Deployment、ReplicaSet、StatefulSet、DaemonSet 等控制器。 |
| Service | 定义一组 Pod 的统一访问入口,支持负载均衡和服务发现。 |
| Label | 给资源打标签的机制,支持资源的分类、选择、分组管理等,用于调度和服务发现。 |
| Volume | 提供容器持久化或共享数据的机制,支持本地存储、NFS、云存储等。 |
| PVC 和 PV | PVC(Persistent Volume Claim)是用户请求的存储资源,PV(Persistent Volume)是实际存储资源,解耦用户和存储实现。 |
| Secret 和 ConfigMap | Secret 用于管理敏感数据,ConfigMap 用于存储配置数据,都可挂载进容器或作为环境变量使用。 |
| Namespace | 提供资源隔离的逻辑空间,用于多租户环境或资源分类管理。 |
| Probes(探针) | 包括存活探针(liveness)和就绪探针(readiness),用于健康检查和控制流量转发。 |
| API Server | Kubernetes 控制平面的核心组件,负责处理来自 kubectl 或其他客户端的请求,并与 Etcd、Controller(控制器)、Scheduler(调度器)等交互。 |
| Scheduler(调度器) | 根据资源需求、约束条件和策略将 Pod 分配到合适的节点。 |
| 集群安装机制与 RBAC | 安装机制包括 kubeadm、Kops、RKE 等,RBAC(基于角色的访问控制)用于权限管理和安全控制。 |
| Helm | Kubernetes 的包管理工具,用于简化应用部署,支持版本管理、参数化配置等。 |
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 init和kubeadm join命令,可用于快速搭建 Kubernetes 集群。
- Kubeadm 是一个 Kubernetes 部署工具,提供
二进制包
- 从 Github 下载发行版的二进制包,手动部署每个组件,组成 Kubernetes 集群。Kubeadm 虽然降低部署门槛,但屏蔽了很多细节,遇到问题很难排查。
- 如果想集群整体更可控,生产环境推荐使用二进制包搭建 Kubernetes 集群,虽然手动部署比较麻烦,但期间可以学习很多工作原理,也利于后期维护。
集群搭建步骤
二进制包方式搭建集群
Kubeadm 方式搭建集群
Kubernetes 核心技术
kubectl 命令行工具
kubectl 是 Kubernetes 集群的命令行工具,通过 kubectl 能够对集群本身进行管理,并能够在集群上进行容器化应用的安装部署。
kubectl 的语法
命令语法:
kubectl [command] [type] [name] [flags]command:- 指定要对资源执行的操作
- 例如:
create、get、describe和delete
type:- 指定资源类型,资源类型是大小写敏感的,开发者能够以单数、复数和缩略的形式。例如:
kubectl get pod pod1kubectl get pods pod1kubectl get po pod1kubectl get nodes K8s-node1
name:- 指定资源的名称,名称大小写敏感。如果省略资源名称,则会显示所有的资源。例如:
kubectl get podskubectl get nodeskubectl get nodes K8s-node1
flags:- 指定可选的参数。例如,可以使用
-s或者-server参数指定 Kubernetes API Server 的地址和端口。
- 指定可选的参数。例如,可以使用
kubectl 的使用帮助手册
可以使用 kubectl --help 命令查看 kubectl 命令的整体使用帮助,包括所有可用的主命令及其简要说明;还可以通过 kubectl <command> --help 获取某个具体子命令的详细使用手册和参数说明。
1 | # 查看 kubectl 的所有主命令和帮助信息 |
比如,kubectl help 命令输出的帮助内容如下:
1 | kubectl controls the Kubernetes cluster manager. |
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 | # 对象类型:对象的一组键值对,使用冒号结构表示 |
- 数组:一组按次序排列的值,又称为序列 (Sequence) / 列表 (List)
1 | # 横向写法(行内数组) |
- 多行字符串可以使用
|保留换行符,也可以使用>折叠换行
1 | # 使用 `|` 保留换行符 |
- 多个 YAML 文档之间可以使用
---文档分隔符分隔
1 | # 第一个文档(例如定义一个 ConfigMap) |
YAML 资源清单的描述方法
在 Kubernetes 中,用户通常使用 YAML 格式的配置文件来定义和创建符合预期状态的集群资源(如 Pod、Deployment 等)。这类遵循 Kubernetes API 规范、用于描述资源对象及其期望状态的 YAML 文件,被称为资源清单(Manifest)。
- 常用字段(必须存在的属性)
| 参数名 | 字段类型 | 说明 |
|---|---|---|
version | String | K8s API 的版本,目前基本是 v1,可以用 kubectl api-versions 命令查询 |
kind | String | YAML 文件定义的资源类型和角色,例如:Pod |
metadata | Object | 元数据对象,固定值写 metadata |
metadata.name | String | 元数据对象的名字,由用户定义,例如命名 Pod 的名字 |
metadata.namespace | String | 元数据对象的命名空间,由用户定义 |
spec | Object | 详细定义对象,固定值写 spec |
spec.containers[] | list | spec 对象的容器列表定义,是一个列表 |
spec.containers[].name | String | 定义容器的名称 |
spec.containers[].image | String | 定义容器使用的镜像名称 |
- 资源清单的定义示例(创建一个 Nginx 的 Pod)
1 | apiVersion: v1 |
- 更完整的资源清单定义示例(创建一个 Nginx 的 Deployment)
1 | apiVersion: apps/v1 |
- 最后可以使用
kubectl apply -f xxxx.yaml命令来执行这个资源清单
快速生成 YAML 资源清单
- (1) 第一种方式:使用
kubectl create命令快速生成 YAML 的配置模板内容
1 | # 快速生成 YAML 配置模板内容,--dry-run=client 表示只在客户端进行验证和生成请求,而不把资源真正提交到 API Server |
1 | apiVersion: apps/v1 |
- (2) 第二种方式:使用
kubectl get命令导出正在运行的资源对象的 YAML 配置内容
1 | # 查看当前正在运行的 Deployment |
1 | # 导出当前正在运行的 Deployment 的 YAML 配置内容 |
1 | apiVersion: apps/v1 |
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
19apiVersion: 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-0、kafka-1、kafka-2。 - 每个 Pod 通常绑定一个专用的持久化存储卷(PVC),Pod 重启或调度后,仍然会挂载同一个存储卷,保证数据不丢失。
- 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
32apiVersion: 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) |
