本篇笔记记录 k8s 的核心概念、架构组件,以及 Pod 的详细使用。环境是一主两从的集群,镜像从私有 Harbor 仓库拉取。
环境说明
集群已提前搭建完成,参考这篇文章。
| 主机 | IP | 用途 |
|---|---|---|
| k8s-master | 192.168.100.20 | 控制平面节点 |
| k8s-node1 | 192.168.100.21 | worker 节点 |
| k8s-node2 | 192.168.100.22 | worker 节点 |
| harbor | 192.168.100.14 | 私有镜像仓库 |
Harbor 仓库信息:
- 域名:
reg.westos.org - 镜像地址:
reg.westos.org/library/
已经提前搭建k8s集群环境,若没有请参考 ../搭建k8s集群
| 主机 | ip | 用途 |
|---|---|---|
| k8s-master | 192.168.100.20 | k8s主节点 |
| k8s-node1 | 192.168.100.21 | work节点 |
| k8s-node2 | 192.168.100.22 | work节点 |
| harbor | 192.168.100.14 | 私有镜像仓库 |
harbor仓库域名为reg.westos.org 镜像地址为reg.westos.org/library/
一、k8s介绍
第一部分:K8s是什么,解决了什么问题,设计理念和思想
1.1 K8s是什么
Kubernetes(K8s) 是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。
- 名称由来:Kubernetes 源于希腊语,意为”舵手”或”领航员”,缩写K8s是因为K和s之间有8个字母
- 起源:Google基于其内部容器编排系统Borg的经验,于2014年开源
- 当前状态:已成为云原生应用编排的事实标准,由CNCF(Cloud Native Computing Foundation)维护
1.2 解决了什么问题
传统部署方式的痛点:
-
资源利用率低
- 物理机部署:一台服务器只运行一个应用,资源浪费严重
- 环境隔离差:多个应用共享一台服务器,相互影响
-
扩展困难
- 手动扩容:需要人工介入,响应慢
- 弹性伸缩难:无法根据负载自动调整
-
运维复杂
- 服务发现困难:需要手动配置IP和端口
- 负载均衡配置繁琐
- 应用更新风险高:停机时间长,回滚困难
K8s的解决方案:
-
自动化容器编排
- 自动部署和调度容器到合适的节点
- 自动重启失败的容器
- 自动替换和重新调度故障节点上的容器
-
服务发现和负载均衡
- 自动分配DNS名称和IP地址
- 内置负载均衡,自动分发流量
-
自动扩缩容
- 水平扩展:根据CPU使用率或自定义指标自动增减Pod数量
- 垂直扩展:调整容器资源限制
-
自动化发布和回滚
- 滚动更新:逐步替换旧版本,零停机
- 自动回滚:检测到问题自动恢复到上一版本
-
存储编排
- 自动挂载存储系统(本地存储、云存储等)
-
自我修复
- 健康检查:定期检测容器健康状态
- 自动重启不健康的容器
1.3 设计理念和思想
核心设计理念:
-
声明式API
- 用户只需要声明”期望状态”(Desired State),无需关心如何实现
- K8s会持续工作,使”当前状态”(Current State)趋向于”期望状态”
- 例如:声明需要3个副本,K8s会自动创建、维护这3个副本
-
控制器模式(Controller Pattern)
for {实际状态 := 获取集群实际状态()期望状态 := 获取用户定义的期望状态()if 实际状态 == 期望状态 {什么都不做} else {执行编排动作,将实际状态调整为期望状态}} -
松耦合架构
- 各个组件独立运行,通过API Server通信
- 组件可以独立升级和替换
-
资源对象化
- 一切皆对象:Pod、Service、Deployment等都是资源对象
- 通过YAML/JSON文件描述资源
- 统一的API接口管理所有资源
-
Label和Selector机制
- Label:键值对标签,附加到资源对象上
- Selector:通过标签选择器查询和关联资源
- 实现松耦合的资源关联
-
分层架构
- 应用层:用户应用
- 编排层:K8s核心功能
- 资源层:计算、存储、网络
- 基础设施层:物理机、虚拟机、云服务
设计思想:
- 可移植性:跨云平台、跨数据中心运行
- 可扩展性:支持插件机制,可自定义资源和控制器
- 自动化:最小化人工干预
- 高可用:组件冗余,故障自动恢复
第二部分:K8s架构、组件及其关系
2.1 K8s整体架构
K8s采用主从架构(Master-Worker),分为控制平面(Control Plane)和工作节点(Worker Node)。
2.2 核心组件概览
Master节点组件(控制平面):
| 组件 | 作用 |
|---|---|
| API Server | 集群的统一入口,提供RESTful API |
| etcd | 分布式键值存储,保存集群所有数据 |
| Scheduler | 负责Pod调度到合适的Node节点 |
| Controller Manager | 运行各种控制器,维护集群状态 |
| Cloud Controller (可选) | 与云平台交互 |
Worker节点组件:
| 组件 | 作用 |
|---|---|
| Kubelet | 管理Pod和容器的生命周期 |
| Kube-proxy | 实现Service的网络代理和负载均衡 |
| Container Runtime | 容器运行时(如Docker、containerd) |
附加组件(Add-ons):
| 组件 | 作用 |
|---|---|
| CoreDNS | 集群内部DNS服务 |
| Dashboard | Web UI管理界面 |
| CNI插件 | 网络插件(如Calico、Flannel) |
| Metrics Server | 资源监控 |
2.3 组件之间的关系和工作流程
典型的Pod创建流程:
-
用户提交
kubectl create -f pod.yaml- kubectl将请求发送到API Server
-
API Server处理
- 验证请求合法性
- 将Pod信息写入etcd
- 返回确认给用户
-
Scheduler监听
- 通过Watch机制监听到新Pod(状态为Pending,未分配节点)
- 执行调度算法,选择最优节点
- 将绑定信息(Pod → Node)写回API Server
-
API Server更新
- 更新Pod信息,指定运行节点
- 将数据持久化到etcd
-
Kubelet监听
- 对应节点的Kubelet监听到分配给自己的Pod
- 调用Container Runtime创建容器
- 定期上报Pod状态给API Server
-
Controller Manager监控
- 持续监控Pod状态
- 如果Pod异常,触发重建流程
-
Kube-proxy配置
- 如果Pod属于某个Service,Kube-proxy更新iptables/ipvs规则
- 实现服务发现和负载均衡
组件通信原则:
- 所有组件只与API Server通信,不直接互相通信
- API Server是唯一直接操作etcd的组件
- 使用List-Watch机制实现事件驱动:
- List:获取资源列表
- Watch:监听资源变化
第三部分:各个组件的详细功能和作用
3.1 API Server(kube-apiserver)
核心功能:
-
集群管理的统一入口
- 提供RESTful API接口
- 所有操作都要通过API Server
-
认证、授权、准入控制
- 认证(Authentication):验证用户身份(证书、Token、ServiceAccount)
- 授权(Authorization):验证操作权限(RBAC、ABAC)
- 准入控制(Admission Control):修改或拒绝请求(如资源配额检查)
-
资源操作接口
- CRUD操作:创建、读取、更新、删除资源
- Watch接口:实时监听资源变化
-
数据持久化
- 将资源状态写入etcd
- 缓存机制提高性能
-
集群状态查询
- 提供集群当前状态的视图
特点:
- 无状态:可以水平扩展多个实例
- 高可用:通过负载均衡器对外提供服务
3.2 etcd
核心功能:
-
分布式键值存储
- 存储K8s所有集群数据
- 保存资源对象的定义和状态
-
一致性保证
- 使用Raft协议保证数据一致性
- 支持分布式锁
-
Watch机制
- 支持高效的事件监听
- 实现K8s的响应式架构
存储的数据:
- Pod、Service、Deployment等资源对象
- 节点信息
- 配置信息(ConfigMap、Secret)
- 集群状态
部署建议:
- 生产环境建议3-5个节点的集群
- 定期备份数据
- 使用SSD提高性能
3.3 Scheduler(kube-scheduler)
核心功能:
-
Pod调度
- 为新创建的Pod选择合适的节点
-
调度算法
预选(Predicate): 过滤不符合条件的节点
- PodFitsResources:节点资源是否充足
- PodFitsHostPorts:端口是否冲突
- NodeSelector:节点标签匹配
- NodeAffinity:节点亲和性
优选(Priority): 对预选节点打分,选择最优节点
- LeastRequestedPriority:选择资源使用率最低的节点
- BalancedResourceAllocation:CPU和内存使用率均衡
- NodeAffinityPriority:节点亲和性得分
-
高级调度策略
- NodeSelector:指定节点标签
- NodeAffinity:节点亲和性(硬性/软性要求)
- PodAffinity:Pod亲和性(将相关Pod调度到一起)
- PodAntiAffinity:Pod反亲和性(将Pod分散到不同节点)
- Taints和Tolerations:污点和容忍度(排斥特定Pod)
调度流程:
监听未调度的Pod → 预选过滤节点 → 优选打分排序 → 选择最优节点 → 绑定Pod到节点3.4 Controller Manager(kube-controller-manager)
核心功能:
运行多个控制器,每个控制器负责维护特定资源的期望状态。
主要控制器:
-
Replication Controller / ReplicaSet Controller
- 确保指定数量的Pod副本运行
- Pod数量不足时创建,过多时删除
-
Deployment Controller
- 管理ReplicaSet,实现声明式更新
- 支持滚动更新和回滚
-
StatefulSet Controller
- 管理有状态应用
- 提供稳定的网络标识和持久化存储
-
DaemonSet Controller
- 确保每个节点运行一个Pod副本
- 常用于日志收集、监控代理
-
Job Controller / CronJob Controller
- Job:运行一次性任务
- CronJob:定时任务
-
Service Controller
- 监听Service对象,创建Endpoint
- 与云平台交互创建LoadBalancer
-
Namespace Controller
- 删除namespace时清理相关资源
-
Node Controller
- 监控节点状态
- 节点异常时驱逐Pod
-
Endpoint Controller
- 维护Service和Pod之间的映射关系
工作原理:
控制循环: 监听资源变化 → 比较期望状态和实际状态 → 执行调谐动作 → 更新资源状态3.5 Kubelet
核心功能:
-
Pod生命周期管理
- 接收API Server分配的Pod
- 调用Container Runtime创建容器
- 管理容器的启动、停止、重启
-
容器健康检查
- Liveness Probe:存活探针,检测容器是否运行,失败则重启
- Readiness Probe:就绪探针,检测容器是否准备好接收流量
- Startup Probe:启动探针,检测容器应用是否启动
-
资源监控
- 监控Pod和容器的资源使用情况(CPU、内存)
- 通过cAdvisor收集数据
-
Volume管理
- 挂载Volume到容器
- 支持多种存储类型
-
状态上报
- 定期向API Server上报节点和Pod状态
-
镜像管理
- 拉取镜像
- 镜像垃圾回收
Static Pod:
- Kubelet可以直接管理本地的YAML文件(通常在/etc/kubernetes/manifests/)
- 不受API Server控制,常用于部署控制平面组件
3.6 Kube-proxy
核心功能:
-
Service网络代理
- 实现Service的虚拟IP(ClusterIP)
- 将流量转发到后端Pod
-
负载均衡
- 在多个Pod副本之间分发流量
-
工作模式
iptables模式(默认):
- 通过iptables规则实现
- 性能好,但规则多时性能下降
- 随机负载均衡
ipvs模式(推荐):
- 使用IPVS内核模块
- 支持更多负载均衡算法(rr、lc、dh等)
- 性能更好,适合大规模集群
userspace模式(已废弃):
- 在用户空间代理,性能差
-
Service类型支持
- ClusterIP:集群内部访问
- NodePort:通过节点端口暴露服务
- LoadBalancer:云平台负载均衡器
- ExternalName:DNS CNAME映射
工作流程:
监听Service和Endpoint变化 → 生成代理规则(iptables/ipvs) → 流量转发到后端Pod3.7 Container Runtime(容器运行时)
核心功能:
-
容器生命周期管理
- 创建、启动、停止、删除容器
-
镜像管理
- 拉取、存储、删除镜像
常见运行时:
- Docker:最早支持,功能完善
- containerd:Docker的核心组件,轻量级(推荐)
- CRI-O:专为K8s设计的轻量级运行时
CRI接口:
- K8s通过CRI(Container Runtime Interface)与运行时通信
- 解耦K8s和具体的容器实现
3.8 CoreDNS
核心功能:
-
集群内部DNS
- 为Service提供DNS解析
- 格式:
<service-name>.<namespace>.svc.cluster.local
-
服务发现
- Pod通过Service名称访问服务
- 无需知道具体IP地址
示例:
# Service: nginx-service 在 default namespace# 其他Pod可以通过以下方式访问:nginx-servicenginx-service.defaultnginx-service.default.svc.cluster.local3.9 CNI网络插件
核心功能:
-
Pod网络通信
- 为每个Pod分配IP地址
- 实现Pod之间的网络互通
-
网络策略
- 实现网络隔离和访问控制
常见网络插件:
- Flannel:简单易用,适合小规模集群
- Calico:功能强大,支持网络策略,性能好
- Weave:易于部署,支持加密
- Cilium:基于eBPF,高性能
网络模型要求:
- 所有Pod可以互相通信(无需NAT)
- 所有Node可以与所有Pod通信
- Pod看到的自己的IP和其他Pod看到的一致
总结
K8s核心价值:
- 自动化容器编排和管理
- 声明式配置,用户只需关心”要什么”
- 自我修复,高可用
架构特点:
- 主从架构,职责清晰
- 控制器模式,持续调谐
- 所有组件通过API Server通信
关键组件协作:
用户 → kubectl → API Server ← → etcd ↓ ┌──────────────┼──────────────┐ ↓ ↓ ↓ Scheduler Controller Manager Kubelet ↓ Container Runtime通过这些组件的协同工作,K8s实现了强大的容器编排能力,成为云原生时代的基石。
二、Pod详解
1. Pod设计理念与基本概念
1.1 Pod是什么
Pod是Kubernetes中最小的可部署单元,是一组(一个或多个)容器的集合。
核心特点:
-
共享网络:Pod内的所有容器共享同一个网络命名空间
- 共享同一个IP地址和端口空间
- 容器之间可以通过localhost通信
-
共享存储:Pod内的容器可以共享Volume
- 实现容器间数据共享
- 持久化数据存储
-
生命周期一致:Pod内的容器同生共死
- 一起调度到同一节点
- 一起启动和停止
1.2 为什么需要Pod
设计原因:
-
容器间紧密协作
- 某些应用需要多个容器协同工作
- 例如:主应用容器 + 日志收集容器 + 配置代理容器
-
简化网络通信
- Pod内容器通过localhost通信,无需复杂的网络配置
- 对外呈现为一个整体,只有一个IP地址
-
资源共享
- 容器间可以共享文件、IPC、网络等资源
Pod的两种使用模式:
-
单容器Pod(最常见)
Pod├── Container (应用容器) -
多容器Pod(Sidecar模式)
Pod├── Container 1 (主应用容器)├── Container 2 (Sidecar容器 - 日志收集)└── Container 3 (Sidecar容器 - 配置同步)
1.3 Pod的组成
一个Pod包含以下部分:
Pod├── Pause容器(基础容器/根容器)│ └── 负责创建网络命名空间,维护Pod的网络├── Init容器(可选)│ └── 初始化容器,在主容器启动前运行,用于初始化工作└── 应用容器(一个或多个) ├── 主容器 └── Sidecar容器(可选)Pause容器:
- 每个Pod都有一个隐藏的Pause容器(也叫Infra容器)
- 占用极少资源,镜像很小(几百KB)
- 作用:
- 创建并持有网络命名空间
- 其他容器加入到这个网络命名空间
- 即使应用容器重启,Pod的IP也不会变
2. Pod的创建过程、状态、生命周期和探针
2.1 Pod的创建过程
完整流程:
1. 用户提交Pod定义 kubectl apply -f pod.yaml ↓2. API Server接收请求 - 验证YAML格式和权限 - 写入etcd(状态:Pending) ↓3. Scheduler调度 - 选择合适的Node节点 - 更新Pod信息(绑定Node) ↓4. Kubelet创建Pod - 拉取镜像 - 创建Pause容器 - 运行Init容器(如果有) - 运行主容器 ↓5. 容器运行(状态:Running) - 执行健康检查 - 上报状态到API Server ↓6. Pod完成或失败(状态:Succeeded/Failed)2.2 Pod的生命周期
Pod Phase(阶段):
| 阶段 | 说明 |
|---|---|
| Pending | Pod已创建,但容器还未运行(可能在拉取镜像或调度中) |
| Running | Pod已绑定到节点,所有容器已创建,至少一个容器在运行 |
| Succeeded | Pod中所有容器成功终止,且不会重启 |
| Failed | Pod中所有容器终止,至少一个容器异常退出 |
| Unknown | 无法获取Pod状态(通常是节点通信问题) |
容器状态(Container State):
| 状态 | 说明 |
|---|---|
| Waiting | 容器等待中(拉取镜像、等待Init容器等) |
| Running | 容器正在运行 |
| Terminated | 容器已终止 |
重启策略(RestartPolicy):
| 策略 | 说明 | 适用场景 |
|---|---|---|
| Always | 容器终止后总是重启(默认策略) | 长期运行的服务 |
| OnFailure | 容器异常终止时才重启(退出码非0) | 批处理任务 |
| Never | 容器终止后不重启 | 一次性任务 |
2.3 容器探针(Probe)
探针是Kubelet对容器执行的定期诊断,用于检测容器的健康状况。
三种探针类型:
-
Liveness Probe(存活探针)
- 作用:检测容器是否存活
- 失败处理:重启容器
- 使用场景:检测应用是否死锁、无响应
- 示例:应用进程存在但卡死,需要重启恢复
-
Readiness Probe(就绪探针)
- 作用:检测容器是否准备好接收流量
- 失败处理:从Service的Endpoint列表中移除该Pod
- 使用场景:应用启动慢,需要预热;临时过载,暂时无法处理请求
- 示例:数据库连接初始化中、缓存加载中
-
Startup Probe(启动探针)
- 作用:检测容器应用是否已启动
- 失败处理:重启容器
- 使用场景:启动慢的应用(避免Liveness探针过早杀死容器)
- 示例:Java应用启动需要几分钟
探测方式:
| 方式 | 说明 | 示例 |
|---|---|---|
| exec | 在容器内执行命令,退出码为0表示成功 | 执行cat检查文件是否存在 |
| httpGet | 发送HTTP GET请求,状态码200-399表示成功 | 访问/health端点 |
| tcpSocket | TCP连接测试,能连接表示成功 | 检测MySQL 3306端口是否可连接 |
| grpc (新增) | 调用gRPC健康检查服务 | gRPC应用的健康检查 |
探针参数配置:
livenessProbe: httpGet: path: /health # 检查路径 port: 8080 # 端口 initialDelaySeconds: 30 # 容器启动后多久开始探测 periodSeconds: 10 # 探测间隔 timeoutSeconds: 5 # 探测超时时间 successThreshold: 1 # 成功阈值(连续成功多少次才算成功) failureThreshold: 3 # 失败阈值(连续失败多少次才算失败)探针使用建议:
- Liveness:谨慎使用,避免频繁重启
- Readiness:推荐使用,优雅地处理流量
- Startup:对启动慢的应用必须配置
2.4 Init容器
Init容器在主容器启动前运行,用于初始化工作。
特点:
- 顺序执行:多个Init容器按顺序依次运行
- 必须成功:所有Init容器成功后,主容器才会启动
- 独立镜像:可以使用不同的镜像
使用场景:
- 等待依赖服务启动(如等待数据库就绪)
- 初始化配置文件
- 下载依赖或数据
- 设置权限
示例:
initContainers:- name: init-mysql image: busybox command: ['sh', '-c', 'until nslookup mysql; do echo waiting for mysql; sleep 2; done']3. YAML资源清单与Pod创建
3.1 YAML资源清单基础
YAML文件结构:
apiVersion: v1 # API版本kind: Pod # 资源类型metadata: # 元数据 name: my-pod # Pod名称 labels: # 标签 app: nginxspec: # 规格/期望状态 containers: # 容器列表 - name: nginx # 容器名称 image: nginx:1.20 # 镜像 ports: # 端口 - containerPort: 80四个核心字段:
| 字段 | 说明 | 必需 |
|---|---|---|
| apiVersion | API版本(如v1、apps/v1) | ✓ |
| kind | 资源类型(如Pod、Deployment) | ✓ |
| metadata | 元数据(name、labels、namespace等) | ✓ |
| spec | 规格说明(期望状态) | ✓ |
3.2 简单Pod示例
最简单的Pod:
apiVersion: v1kind: Podmetadata: name: nginx-podspec: containers: - name: nginx image: nginx:1.20带探针的Pod:
apiVersion: v1kind: Podmetadata: name: nginx-pod-with-probe labels: app: nginxspec: containers: - name: nginx image: nginx:1.20 ports: - containerPort: 80 livenessProbe: httpGet: path: / port: 80 initialDelaySeconds: 10 periodSeconds: 5 readinessProbe: httpGet: path: / port: 80 initialDelaySeconds: 5 periodSeconds: 3多容器Pod:
apiVersion: v1kind: Podmetadata: name: multi-container-podspec: containers: - name: app image: myapp:1.0 ports: - containerPort: 8080 - name: sidecar-log image: busybox command: ['sh', '-c', 'tail -f /var/log/app.log'] volumeMounts: - name: log-volume mountPath: /var/log volumes: - name: log-volume emptyDir: {}4. 实操:构建镜像并部署Pod
4.1 准备测试环境
在harbor机器上配置kubectl远程管理K8s集群
我们使用harbor机器(192.168.100.14)作为远程管理节点,而不是直接在master上操作,这是生产环境的最佳实践。
步骤:
-
在master节点上获取kubeconfig
Terminal window # 在k8s-master上执行cat ~/.kube/config -
在harbor机器上安装kubectl
Terminal window # 下载kubectlcurl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"# 安装chmod +x kubectlmv kubectl /usr/local/bin/# 验证kubectl version --client -
配置kubeconfig
Terminal window # 创建.kube目录mkdir -p ~/.kube# 将master的config内容复制到harbor机器vi ~/.kube/config# 粘贴master节点的config内容,修改server地址为master的IP# server: https://192.168.100.20:6443# 设置权限chmod 600 ~/.kube/config#设置k8s命令补齐echo "source <(kubectl completion bash)" >> ~/.bashrcsource ~/.bashrc -
测试连接
Terminal window kubectl get nodeskubectl cluster-info
4.2 准备应用镜像
准备两个镜像:
- nginx前端:连接数据库测试
- mysql数据库:MySQL 8.0
项目目录结构:
/root/k8s-demo/├── nginx/│ ├── Dockerfile│ └── index.php└── mysql/ └── Dockerfile1. 创建MySQL镜像
mkdir -p /root/k8s-demo/mysqlcd /root/k8s-demo/mysqlDockerfile:
FROM mysql:8.0
# 设置环境变量ENV MYSQL_ROOT_PASSWORD=Westos123ENV MYSQL_DATABASE=testdb
# 暴露端口EXPOSE 3306构建并推送:
# 构建镜像docker build -t reg.westos.org/library/mysql:8.0 .
# 推送到私有仓库docker push reg.westos.org/library/mysql:8.02. 创建Nginx+PHP镜像
mkdir -p /root/k8s-demo/nginxcd /root/k8s-demo/nginxDockerfile:
FROM php:7.4-apache
# 安装mysqli扩展RUN docker-php-ext-install mysqli
# 复制测试页面COPY index.php /var/www/html/
# 暴露端口EXPOSE 80
# 启动ApacheCMD ["apache2-foreground"]index.php:
<?phpheader('Content-Type: text/plain; charset=utf-8');
echo "Nginx-PHP Container\n";echo "Hostname: " . gethostname() . "\n";echo "Server IP: " . $_SERVER['SERVER_ADDR'] . "\n";echo "\n";
// 数据库连接信息(稍后手动修改)$db_host = "DB_HOST_HERE"; // 稍后替换为MySQL Pod的IP$db_user = "root";$db_pass = "Westos123";$db_name = "testdb";
// 尝试连接数据库$conn = new mysqli($db_host, $db_user, $db_pass, $db_name);
if ($conn->connect_error) { echo "Database connection failed: " . $conn->connect_error . "\n";} else { echo "Database connected successfully!\n"; echo "MySQL Version: " . $conn->server_info . "\n";}
$conn->close();?>构建并推送:
# 构建镜像docker build -t reg.westos.org/library/nginx-php:v1 .
# 推送到私有仓库docker push reg.westos.org/library/nginx-php:v14.3 创建Pod资源清单
创建YAML文件目录:
mkdir -p /root/k8s-yamlcd /root/k8s-yaml1. mysql-pod.yaml
apiVersion: v1kind: Podmetadata: name: mysql-pod labels: app: mysqlspec: containers: - name: mysql image: reg.westos.org/library/mysql:8.0 ports: - containerPort: 3306 env: - name: MYSQL_ROOT_PASSWORD value: "Westos123" - name: MYSQL_DATABASE value: "testdb" livenessProbe: tcpSocket: port: 3306 initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: exec: command: - sh - -c - "mysqladmin ping -h localhost -pWestos123" initialDelaySeconds: 10 periodSeconds: 52. nginx-pod.yaml
apiVersion: v1kind: Podmetadata: name: nginx-pod labels: app: nginxspec: containers: - name: nginx-php image: reg.westos.org/library/nginx-php:v1 ports: - containerPort: 80 livenessProbe: httpGet: path: / port: 80 initialDelaySeconds: 10 periodSeconds: 5 readinessProbe: httpGet: path: / port: 80 initialDelaySeconds: 5 periodSeconds: 34.4 部署和测试
1. 创建MySQL Pod
# 创建Harbor认证Secret(如果library仓库是私有的,不配置拉取镜像会出现ImagePullBackOff错误。)kubectl create secret docker-registry harbor-auth \ --docker-server=reg.westos.org \ --docker-username=admin \ --docker-password=12345 \ --docker-email=admin@westos.org
#认证绑定命名空间,自动授权kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "harbor-auth"}]}'
# 创建Podkubectl apply -f mysql-pod.yaml
# 查看Pod状态kubectl get pods -o wide
# 查看Pod详细信息kubectl describe pod mysql-pod
# 查看日志kubectl logs mysql-pod2. 获取MySQL Pod的IP地址
# 获取IPkubectl get pod mysql-pod -o wide
# 假设输出:# NAME READY STATUS RESTARTS AGE IP NODE# mysql-pod 1/1 Running 0 1m 10.244.1.10 k8s-node13. 创建Nginx Pod
# 创建Podkubectl apply -f nginx-pod.yaml
# 查看状态kubectl get pods -o wide
# 获取nginx-pod的IP(假设是10.244.2.15)4. 进入Nginx容器修改数据库连接
# 进入nginx容器kubectl exec -it nginx-pod -- bash
# 修改index.php文件,替换数据库IPsed -i 's/DB_HOST_HERE/10.244.169.133/' /var/www/html/index.php
# 验证修改cat /var/www/html/index.php | grep db_host
# 退出容器exit5. 在集群内测试连接
#准备busybox镜像docker pull busybox:1.30.1docker tag busybox:1.30.1 reg.westos.org/library/busybox:1.30.1docker push reg.westos.org/library/busybox:1.30.1
# 从任意节点或Pod内测试kubectl run test-pod --image=reg.westos.org/library/busybox:1.30.1 --rm -it -- sh
# 在test-pod中测试wget -q -O- http://10.244.2.15# 应该看到连接成功的消息
# 或者在master节点直接curlcurl http://10.244.2.15预期输出:
Nginx-PHP ContainerHostname: nginx-podServer IP: 10.244.2.15
Database connected successfully!MySQL Version: 8.0.444.5 常用Pod管理命令
# 查看所有Podkubectl get podskubectl get pods -o wide # 显示更多信息(IP、节点等)kubectl get pods -A # 查看所有命名空间的Pod
# 查看Pod详情kubectl describe pod <pod-name>
# 查看日志kubectl logs <pod-name>kubectl logs <pod-name> -f # 实时查看kubectl logs <pod-name> -c <container> # 多容器Pod指定容器
# 进入容器kubectl exec -it <pod-name> -- bashkubectl exec -it <pod-name> -c <container> -- sh # 多容器指定容器
# 删除Podkubectl delete pod <pod-name>kubectl delete -f pod.yaml
# 编辑Pod(部分字段不可修改)kubectl edit pod <pod-name>
# 查看Pod的YAMLkubectl get pod <pod-name> -o yaml
# 查看Pod事件kubectl get events --field-selector involvedObject.name=<pod-name>4.6 验证和排错
检查清单:
-
Pod状态检查
Terminal window kubectl get pods# 正常应显示:Running,READY 1/1 -
如果Pod状态为Pending
- 检查节点资源是否充足
- 检查镜像是否能正常拉取
Terminal window kubectl describe pod <pod-name># 查看Events部分的错误信息 -
如果Pod状态为ImagePullBackOff
- 检查镜像名称是否正确
- 检查私有仓库认证(后续会讲Secret)
Terminal window kubectl logs <pod-name> -
如果Pod状态为CrashLoopBackOff
- 容器启动后立即崩溃
- 查看日志定位问题
Terminal window kubectl logs <pod-name> --previous # 查看上一次运行的日志 -
测试网络连通性
Terminal window # 从任意节点或Pod内测试kubectl run test-pod --image=reg.westos.org/library/busybox:1.30.1 --rm -it --restart=Never -- sh# 在test-pod中测试wget -q -O- http://<pod-ip># 应该看到连接成功的消息# 或者在master节点直接curlcurl http://<pod-ip>
常见问题:
| 问题 | 原因 | 解决方法 |
|---|---|---|
| ImagePullBackOff | 镜像拉取失败 | 检查镜像名称、仓库地址、网络连接 |
| CrashLoopBackOff | 容器启动后崩溃 | 检查日志、检查启动命令、检查依赖服务 |
| Pending | 无法调度(资源不足、节点异常等) | 检查节点状态、资源配额 |
| Error | Pod启动失败 | 查看describe和logs |
| 0/1 Ready | 容器未通过就绪探针 | 检查探针配置、应用启动状态 |