Restruct and reorder chapters

This commit is contained in:
Baohua Yang
2026-02-21 22:22:17 -08:00
parent 2ab40eacc0
commit 33af380be1
141 changed files with 154 additions and 182 deletions

View File

@@ -0,0 +1,15 @@
# Kubernetes
`Kubernetes` Google 发起的开源容器编排系统它支持多种云平台与私有数据中心
`Kubernetes` 负责对容器工作负载进行调度与编排其目的是让用户通过集群声明式地管理应用而无需手动干预每个容器的生命周期细节
Kubernetes 的最小调度单位是 `Pod`一个 `Pod` 由一组紧密协作的容器构成它们共享网络命名空间IP 以及部分存储资源也可以根据需要对 Pod 进行端口映射
本章将分为 5 节介绍 `Kubernetes`包括
* 项目简介
* 快速入门
* 基本概念
* 实践例子
* 架构分析等高级话题

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -0,0 +1,61 @@
## Kubernetes 高级特性
掌握了 Kubernetes 的核心概念 (PodServiceDeployment) 我们需要了解更多高级特性以构建生产级应用
### Helm - 包管理工具
[Helm](https://helm.sh/) 被称为 Kubernetes 的包管理器 (类似于 Linux 的 apt/yum)。它将一组 Kubernetes 资源定义文件打包为一个 **Chart**。
* **安装应用**`helm install my-release bitnami/mysql`
* **版本管理**轻松回滚应用的发布版本
* **模板化**支持复杂的应用部署逻辑配置
### Ingress - 服务的入口
Service 虽然提供了负载均衡但通常是 4 (TCP/UDP)**Ingress** 提供了 7 (HTTP/HTTPS) 路由能力充当集群的网关
* **域名路由**基于 Host 将请求转发不同服务 (api.example.com -> api-svcweb.example.com -> web-svc)
* **路径路由**基于 Path 将请求转发 (/api -> api-svc / -> web-svc)
* **SSL/TLS**集中管理证书
常见的 Ingress Controller Nginx Ingress ControllerTraefikIstio Gateway
### Persistent Volume StorageClass
容器内的文件是临时的对于有状态应用 (如数据库)需要持久化存储
* **PVC (Persistent Volume Claim)**用户申请存储的声明
* **PV (Persistent Volume)**实际的存储资源 (NFSAWS EBSCeph )
* **StorageClass**定义存储类支持动态创建 PV
### Horizontal Pod Autoscaling
HPA 根据 CPU 利用率或其他指标 (如内存自定义指标) 自动扩缩 Deployment ReplicaSet 中的 Pod 数量
```yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: php-apache
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: php-apache
minReplicas: 1
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
```
### ConfigMap Secret
* **ConfigMap**存储非机密的配置数据 (配置文件环境变量)
* **Secret**存储机密数据 (密码Token证书) Etcd 中加密存储
通过将配置与镜像分离保证了容器的可移植性

View File

@@ -0,0 +1,208 @@
## 基本概念
如图 12-2 所示Kubernetes 由控制平面与工作节点构成
![Kubernetes 基本概念示意图](./_images/kubernetes_design.jpg)
12-2 Kubernetes 基本概念示意图
* 节点 (`Node`)一个节点是一个运行 Kubernetes 中的主机
* 容器组 (`Pod`)一个 Pod 对应于由若干容器组成的一个容器组同个组内的容器共享一个存储卷 (volume)
* 容器组生命周期 (`pod-states`)包含所有容器状态集合包括容器组状态类型容器组生命周期事件重启策略以及 replication controllers
* Replication Controllers主要负责指定数量的 pod 在同一时间一起运行
* 服务 (`services`)一个 Kubernetes 服务是容器组逻辑的高级抽象同时也对外提供访问容器组的策略
* (`volumes`)一个卷就是一个目录容器对其有访问权限
* 标签 (`labels`)标签是用来连接一组对象的比如容器组标签可以被用来组织和选择子对象
* 接口权限 (`accessing_the_api`)端口IP 地址和代理的防火墙规则
* web 界面 (`ux`)用户可以通过 web 界面操作 Kubernetes
* 命令行操作 (`cli`)`kubectl` 命令
### 节点
`Kubernetes` 节点是实际工作的点节点可以是虚拟机或者物理机器依赖于一个集群环境每个节点都有一些必要的服务以运行容器组并且它们都可以通过主节点来管理必要服务包括 Dockerkubelet 和代理服务
#### 容器状态
容器状态用来描述节点的当前状态现在其中包含三个信息
##### 主机 IP
主机 IP 需要云平台来查询`Kubernetes` 把它作为状态的一部分来保存如果 `Kubernetes` 没有运行在云平台上节点 ID 就是必需的IP 地址可以变化并且可以包含多种类型的 IP 地址如公共 IP私有 IP动态 IPipv6 等等
##### 节点周期
通常来说节点有 `Pending``Running``Terminated` 三个周期如果 Kubernetes 发现了一个节点并且其可用那么 Kubernetes 就把它标记为 `Pending`然后在某个时刻Kubernetes 将会标记其为 `Running`节点的结束周期称为 `Terminated`一个已经 `Terminated` 的节点不会接受和调度任何请求并且已经在其上运行的容器组也会删除
##### 节点状态
节点的状态主要是用来描述处于 `Running` 的节点当前可用的有 `NodeReachable` `NodeReady`以后可能会增加其他状态`NodeReachable` 表示集群可达`NodeReady` 表示 kubelet 返回 Status Ok 并且 HTTP 状态检查健康
#### 节点管理
节点并非 Kubernetes 创建而是由云平台创建或者就是物理机器虚拟机 Kubernetes 节点仅仅是一条记录节点创建之后Kubernetes 会检查其是否可用 Kubernetes 节点用如下结构保存
```json
{
"id": "10.1.2.3",
"kind": "Minion",
"apiVersion": "v1beta1",
"resources": {
"capacity": {
"cpu": 1000,
"memory": 1073741824
},
},
"labels": {
"name": "my-first-k8s-node",
},
}
```
Kubernetes 校验节点可用依赖于 ID在当前的版本中有两个接口可以用来管理节点节点控制和 Kube 管理
#### 节点控制
Kubernetes 主节点中节点控制器是用来管理节点的组件主要包含
* 集群范围内节点同步
* 单节点生命周期管理
节点控制有一个同步轮询主要监听所有云平台的虚拟实例会根据节点状态创建和删除可以通过 `--node_sync_period` 标志来控制该轮询如果一个实例已经创建节点控制将会为其创建一个结构同样的如果一个节点被删除节点控制也会删除该结构 Kubernetes 启动时可用通过 `--machines` 标记来显示指定节点同样可以使用 `kubectl` 来一条一条的添加节点两者是相同的通过设置 `--sync_nodes=false` 标记来禁止集群之间的节点同步你也可以使用 api/kubectl 命令行来增删节点
### 容器组
Kubernetes 使用的最小单位是容器组容器组是创建调度管理的最小单位一个容器组使用相同的 Docker 容器并共享卷 (挂载点)一个容器组是一个特定应用的打包集合包含一个或多个容器
和运行的容器类似一个容器组被认为只有很短的运行周期容器组被调度到一组节点运行直到容器的生命周期结束或者其被删除如果节点死掉运行在其上的容器组将会被删除而不是重新调度(也许在将来的版本中会添加容器组的移动)
#### 容器组设计的初衷
容器组 (Pod) 的设计主要是为了解决应用间的紧密协作和资源共享问题
#### 资源共享和通信
容器组主要是为了数据共享和它们之间的通信
在一个容器组中容器都使用相同的网络地址和端口可以通过本地网络来相互通信每个容器组都有独立的 IP可用通过网络来和其他物理主机或者容器通信
容器组有一组存储卷 (挂载点)主要是为了让容器在重启之后可以不丢失数据
#### 容器组管理
容器组是一个应用管理和部署的高层次抽象同时也是一组容器的接口容器组是部署水平放缩的最小单位
#### 容器组的使用
容器组可以通过组合来构建复杂的应用其本来的意义包含
* 内容管理文件和数据加载以及本地缓存管理等
* 日志和检查点备份压缩快照等
* 监听数据变化跟踪日志日志和监控代理消息发布等
* 代理网桥
* 控制器管理配置以及更新
#### 替代方案
为什么不在一个单一的容器里运行多个程序
* 1透明化为了使容器组中的容器保持一致的基础设施和服务比如进程管理和资源监控这样设计是为了用户的便利性
* 2解偶软件之间的依赖每个容器都可能重新构建和发布Kubernetes 必须支持热发布和热更新 (将来)
* 3方便使用用户不必运行独立的程序管理也不用担心每个应用程序的退出状态
* 4高效考虑到基础设施有更多的职责容器必须要轻量化
#### 容器组的生命状态
包括若干状态值`pending``running``succeeded``failed`
##### pending
容器组已经被节点接受但有一个或多个容器还没有运行起来这将包含某些节点正在下载镜像的时间这种情形会依赖于网络情况
##### running
容器组已经被调度到节点并且所有的容器都已经启动至少有一个容器处于运行状态 (或者处于重启状态)
##### succeeded
所有的容器都正常退出
##### failed
容器组中所有容器都意外中断了
#### 容器组生命周期
通常来说如果容器组被创建了就不会自动销毁除非被某种行为触发而触发此种情况可能是人为或者复制控制器所为唯一例外的是容器组由 succeeded 状态成功退出或者在一定时间内重试多次依然失败
如果某个节点死掉或者不能连接那么节点控制器将会标记其上的容器组的状态为 `failed`
举例如下
* 容器组状态 `running` 1 容器容器正常退出
* 记录完成事件
* 如果重启策略为
* 始终重启容器容器组保持 `running`
* 失败时容器组变为 `succeeded`
* 从不容器组变为 `succeeded`
* 容器组状态 `running` 1 容器容器异常退出
* 记录失败事件
* 如果重启策略为
* 始终重启容器容器组保持 `running`
* 失败时重启容器容器组保持 `running`
* 从不容器组变为 `failed`
* 容器组状态 `running` 2 容器 1 容器异常退出
* 记录失败事件
* 如果重启策略为
* 始终重启容器容器组保持 `running`
* 失败时重启容器容器组保持 `running`
* 从不容器组保持 `running`
* 当有 2 容器退出
* 记录失败事件
* 如果重启策略为
* 始终重启容器容器组保持 `running`
* 失败时重启容器容器组保持 `running`
* 从不容器组变为 `failed`
* 容器组状态 `running`容器内存不足
* 标记容器错误中断
* 记录内存不足事件
* 如果重启策略为
* 始终重启容器容器组保持 `running`
* 失败时重启容器容器组保持 `running`
* 从不记录错误事件容器组变为 `failed`
* 容器组状态 `running`一块磁盘死掉
* 杀死所有容器
* 记录事件
* 容器组变为 `failed`
* 如果容器组运行在一个控制器下容器组将会在其他地方重新创建
* 容器组状态 `running`对应的节点段溢出
* 节点控制器等到超时
* 节点控制器标记容器组 `failed`
* 如果容器组运行在一个控制器下容器组将会在其他地方重新创建
### Replication Controllers
> Replication Controller (RC) 是早期的控制器类型现代 Kubernetes 更推荐使用 ReplicaSet/Deployment
### 服务
> 服务 (Service) 定义一组 Pod 的逻辑集合和访问它们的策略
###
> (Volume) 包含可被 Pod 中容器访问的数据的目录
### 标签
> 标签 (Label) 是附加到对象 ( Pods) 上的键值对用于组织和选择对象子集
### 接口权限
> 接口权限通过认证授权和准入控制来保护 Kubernetes API 的访问
### web 界面
> Kubernetes Dashboard 是一个基于 Web 的用户界面用于管理集群
### 命令行操作
> kubectl Kubernetes 的命令行工具用于与集群进行交互

View File

@@ -0,0 +1,55 @@
## 架构设计
任何优秀的项目都离不开优秀的架构设计本小节将介绍 Kubernetes 在架构方面的设计考虑
### 基本考虑
如果让我们自己从头设计一套容器管理平台有如下几个方面是很容易想到的
* 分布式架构保证扩展性
* 逻辑集中式的控制平面 + 物理分布式的运行平面
* 一套资源调度系统管理哪个容器该分配到哪个节点上
* 一套对容器内服务进行抽象和 HA 的系统
### 运行原理
如图 12-3 所示该图完整展示了 Kubernetes 的运行原理
![Kubernetes 架构](./_images/k8s_architecture.png)
12-3 Kubernetes 运行原理图
可见Kubernetes 首先是一套分布式系统由多个节点组成节点分为两类一类是属于管理平面的主节点/控制节点 (Master Node)一类是属于运行平面的工作节点 (Worker Node)
显然复杂的工作肯定都交给控制节点去做了工作节点负责提供稳定的操作接口和能力抽象即可
从这张图上我们没有能发现 Kubernetes 中对于控制平面的分布式实现但是由于数据后端自身就是一套分布式的数据库 Etcd因此可以很容易扩展到分布式实现
### 控制平面
控制平面 (Control Plane) Kubernetes 集群的大脑负责做出全局决策 (如调度) 以及检测和响应集群事件
#### 主节点服务
主节点上需要提供如下的管理服务
* `apiserver` 是整个系统的对外接口提供一套 RESTful [Kubernetes API](https://kubernetes.io/zh/docs/concepts/overview/kubernetes-api/),供客户端和其它组件调用;
* `scheduler` 负责对资源进行调度分配某个 pod 到某个节点上 pluggable 意味着很容易选择其它实现方式
* `controller-manager` 负责管理控制器包括 endpoint-controller (刷新服务和 pod 的关联信息) replication-controller (维护某个 pod 的复制为配置的数值)
#### Etcd
这里 Etcd 即作为数据后端又作为消息中间件
通过 Etcd 来存储所有的主节点上的状态信息很容易实现主节点的分布式扩展
组件可以自动的去侦测 Etcd 中的数值变化来获得通知并且获得更新后的数据来执行相应的操作
### 工作节点
* kubelet 是工作节点执行操作的 agent负责具体的容器生命周期管理根据从数据库中获取的信息来管理容器并上报 pod 运行状态等
* kube-proxy 是一个简单的网络访问代理同时也是一个 Load Balancer它负责将访问到某个服务的请求具体分配给工作节点上的 Pod (同一类标签)
![Proxy 代理对服务的请求](./_images/kube-proxy.png)
12-4 kube-proxy 请求转发示意图

View File

@@ -0,0 +1,95 @@
## Kubernetes 简介
如图 12-1 所示Kubernetes 使用舵手图标作为项目标识
![Kubernetes 标识](./_images/kubernetes_logo.png)
12-1 Kubernetes 项目标识
### 什么是 Kubernetes
Kubernetes (常简称为 K8s) Google 开源的容器编排引擎如果说 Docker 解决了 如何打包和运送集装箱 的问题那么 Kubernetes 解决的就是 如何管理海量集装箱的调度运行和维护 的问题
它不仅仅是一个编排系统更是一个 **云原生应用操作系统**
> **名字由来**Kubernetes 在希腊语中意为 舵手 飞行员K8s 是因为 k s 之间有 8 个字母
---
### 为什么需要 Kubernetes
当我们在单机运行几个容器时Docker Compose 就足够了但在生产环境中我们需要面对
- **多主机调度**容器应该运行在哪台机器上
- **自动恢复**容器崩溃了怎么办节点挂了怎么办
- **服务发现**容器 IP 变了其他服务怎么找到它
- **负载均衡**流量大了如何分发给多个副本
- **滚动更新**如何不中断服务升级应用
Kubernetes 完美解决了这些问题
---
### 核心概念
本节涵盖了相关内容与详细描述主要探讨以下几个方面
#### Pod (豆荚)
Kubernetes 的最小调度单位一个 Pod 可以包含一个或多个紧密协作的容器 (共享网络和存储)就像豌豆荚里的豌豆一样
#### Node (节点)
运行 Pod 的物理机或虚拟机
#### Deployment (部署)
定义应用的期望状态 (需要 3 个副本镜像版本为 v1)K8s 会持续确保当前状态符合期望状态
#### Service (服务)
定义一组 Pod 的访问策略提供稳定的 Cluster IP DNS 名称负责负载均衡
#### Namespace (命名空间)
用于多租户资源隔离
---
### Docker 用户如何过渡
如果你已经熟悉 Docker学习 K8s 会很容易
| Docker 概念 | Kubernetes 概念 | 说明 |
|------------|----------------|------|
| Container | Pod | K8s 增加了一层 Pod 包装 |
| Volume | PersistentVolume | K8s 的存储更加抽象和强大 |
| Network | Service/Ingress| K8s 的网络模型更扁平 |
| Compose | Deployment + Service | 声明式配置的理念是一致的 |
---
### 架构
Kubernetes 也是 C/S 架构 **Control Plane (控制平面)** **Worker Node (工作节点)** 组成
- **Control Plane**负责决策 (API ServerSchedulerController Manageretcd)
- **Worker Node**负责干活 (KubeletKube-proxyContainer Runtime)
---
### 学习建议
Kubernetes 的学习曲线较陡峭建议的学习路径
1. **理解基本概念**PodDeploymentService
2. **动手实践**使用 Minikube Kind 在本地搭建集群
3. **部署应用**编写 YAML 部署一个无状态应用
4. **深入原理**网络模型存储机制调度算法
---
### 延伸阅读
- [Minikube 安装](../setup/README.md)本地体验 K8s
- [Kubernetes 官网](https://kubernetes.io/):官方文档

View File

@@ -0,0 +1,99 @@
## Kubernetes 实战练习
本章将通过一个具体的案例部署一个 Nginx 网站并为其配置 Service Ingress来串联前面学到的知识
### 目标
1. 部署一个 Nginx Deployment
2. 创建一个 Service 暴露 Nginx
3. (可选) 通过 Ingress 访问服务
### 步骤 1创建 Deployment
创建一个名为 `nginx-deployment.yaml` 的文件
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.27
ports:
- containerPort: 80
```
应用配置
```bash
kubectl apply -f nginx-deployment.yaml
```
### 步骤 2创建 Service
创建一个名为 `nginx-service.yaml` 的文件
```yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
type: NodePort # 使用 NodePort 方便本地测试
```
应用配置
```bash
kubectl apply -f nginx-service.yaml
```
查看分配的端口
```bash
kubectl get svc nginx-service
```
如果输出端口是 `80:30080/TCP`你可以通过 `http://<NodeIP>:30080` 访问 Nginx
### 步骤 3模拟滚动更新
修改 `nginx-deployment.yaml`将镜像版本改为 `nginx:1.27-alpine`
```bash
kubectl apply -f nginx-deployment.yaml
```
观察更新过程
```bash
kubectl rollout status deployment/nginx-deployment
```
### 步骤 4清理资源
练习结束后记得清理资源
```bash
kubectl delete -f nginx-service.yaml
kubectl delete -f nginx-deployment.yaml
```