Kubernetes v1.24 从入门到实战:核心概念与集群管理详解
📌 前言
Kubernetes(简称 K8s)已经成为容器编排领域的绝对标准。本文将从零开始,系统讲解 K8s 的核心概念、架构原理及实战操作,帮助读者快速上手。内容涵盖:K8s 是什么、核心架构、常用资源(Pod、Deployment、Service、Ingress、存储、配置)的使用方法,以及工作流程与网络模型。所有示例均基于 Kubernetes v1.24 ,容器运行时为 containerd。
文中涉及大量 YAML 示例和命令行操作,建议读者一边阅读一边动手实践。
1. K8s 概览
1.1 什么是 Kubernetes?
Kubernetes(源于希腊语,意为"舵手")是一个开源的容器编排平台,用于自动部署、扩缩和管理容器化应用。它源自 Google 15 年的生产环境经验,具备以下核心特性:
- 服务发现与负载均衡:无需修改应用即可使用内置的服务发现机制。
- 存储编排:自动挂载所选的存储系统(本地存储、云存储、NFS 等)。
- 自动上线与回滚:分步骤发布应用变更,出现问题时一键回滚。
- 自我修复:重启失败的容器,替换不健康的节点上的容器。
- 水平自动扩缩:根据 CPU 使用率等指标自动调整副本数量。
- 配置与密钥管理:无需重建镜像即可更新配置和敏感信息。
对比 Docker(单机容器引擎)与 K8s(集群编排引擎):
- Docker:负责打包应用及其依赖为镜像,提供可执行环境。
- K8s:负责在集群中调度、运行、伸缩和管理这些容器。
1.2 K8s 核心架构(Master-Worker)
K8s 采用典型的 Master-Worker 架构:
Worker节点2
Worker节点1
Master节点
kube-apiserver
kube-scheduler
kube-controller-manager
etcd
kubelet
kube-proxy
Container Runtime
kubelet
kube-proxy
Container Runtime
| 组件 | 作用 |
|---|---|
| kube-apiserver | 集群统一入口,所有操作(kubectl、UI、其他组件)均通过它进行认证和授权。 |
| kube-scheduler | 负责将新创建的 Pod 分配到合适的 Worker 节点。 |
| kube-controller-manager | 运行各种控制器(Node、Deployment、Service 等),维持期望状态。 |
| etcd | 分布式键值存储,保存集群所有配置和状态数据。 |
| kubelet | Worker 节点上的代理,负责与 Master 通信并管理本节点的 Pod。 |
| kube-proxy | 维护节点上的网络规则,实现 Service 的负载均衡和集群内外的网络通信。 |
| Container Runtime | 实际运行容器的引擎(containerd、Docker 等)。 |
2. 快速实战
2.1 kubectl 基本用法
kubectl 是 K8s 的命令行工具,用于与 apiserver 交互。常用命令结构:
bash
kubectl [command] [TYPE] [NAME] [flags]
| command | 说明 | 示例 |
|---|---|---|
| get | 获取资源 | kubectl get pod |
| describe | 查看详情 | kubectl describe pod my-pod |
| create | 创建资源 | kubectl create -f file.yaml |
| apply | 声明式创建/更新 | kubectl apply -f file.yaml |
| delete | 删除资源 | kubectl delete pod my-pod |
| logs | 查看容器日志 | kubectl logs my-pod |
| exec | 进入容器执行命令 | kubectl exec -it my-pod -- bash |
💡 提示:使用
kubectl explain <resource>可查看资源的字段说明,例如kubectl explain pod.spec.containers。
2.2 Namespace(命名空间)
命名空间用于逻辑隔离集群资源(不隔离网络)。K8s 启动后默认有四个命名空间:
| 命名空间 | 用途 |
|---|---|
default |
默认创建的资源位置 |
kube-system |
K8s 系统组件(如 kube-proxy、coredns) |
kube-public |
公共可读,通常用于集群级信息 |
kube-node-lease |
存放节点心跳租约,提高节点故障检测效率 |
命令示例:
bash
# 查看所有命名空间
kubectl get namespace
# 创建命名空间
kubectl create namespace tuling
# 查看某命名空间下的 Pod
kubectl get pods -n kube-system
# 删除命名空间(会删除其下所有资源)
kubectl delete namespace tuling
YAML 示例: (my-namespace.yaml)
yaml
apiVersion: v1
kind: Namespace
metadata:
name: tulingmall
执行:kubectl apply -f my-namespace.yaml
2.3 Pod(最小部署单元)
Pod 是 K8s 中可创建和管理的最小计算单元。一个 Pod 包含一个或多个容器,它们共享网络、存储和 Linux 命名空间。
Pod
Pause容器
(共享网络栈)
业务容器 A
业务容器 B
创建单容器 Pod
命令行:
bash
kubectl run mynginx --image=nginx:1.14.2 --port=80
kubectl get pod -o wide
kubectl logs mynginx
kubectl delete pod mynginx
YAML 方式: (nginx-pod.yaml)
yaml
apiVersion: v1
kind: Pod
metadata:
name: mynginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
执行:kubectl apply -f nginx-pod.yaml
🤔 思考:一个 Pod 中能否运行多个容器?
可以! 例如同时运行 nginx 和 tomcat:
yaml
apiVersion: v1
kind: Pod
metadata:
name: multi-container-pod
spec:
containers:
- name: nginx
image: nginx:1.14.2
- name: tomcat
image: tomcat:9.0.55
多容器场景通常用于辅助容器(如日志收集、代理、调试)与主容器协同工作。
2.4 Deployment(声明式应用管理)
Deployment 为 Pod 提供多副本、自愈、滚动更新、回滚等功能,是生产环境最常用的控制器。
自愈重建
滚动更新
版本异常
创建Deployment
运行ReplicaSet
管理Pod副本
Pod崩溃
更新镜像
滚动更新
回滚
创建 Deployment
bash
kubectl create deployment my-tomcat --image=tomcat:9.0.55
# 查看 deployment 和 replicaset
kubectl get deploy,rs
# 扩容到 3 副本
kubectl scale deployment my-tomcat --replicas=3
# 查看 Pod 自动增量
kubectl get pods -w
自愈能力演示
删除一个 Pod,Deployment 会立即重建它:
bash
kubectl delete pod my-tomcat-xxxxx # 删除后立即有新 Pod 出现
滚动更新与回滚
bash
# 更新镜像版本到 tomcat:10.1.11
kubectl set image deployment my-tomcat tomcat=tomcat:10.1.11 --record
# 查看更新历史
kubectl rollout history deployment my-tomcat
# 回滚到上一版本
kubectl rollout undo deployment my-tomcat
# 回滚到指定版本
kubectl rollout undo deployment my-tomcat --to-revision=2
YAML 示例(Deployment)
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-tomcat
spec:
replicas: 3
selector:
matchLabels:
app: my-tomcat
template:
metadata:
labels:
app: my-tomcat
spec:
containers:
- name: tomcat
image: tomcat:9.0.55
ports:
- containerPort: 8080
2.5 Service(稳定访问入口)
Service 为一组 Pod 提供固定的访问入口(ClusterIP)和负载均衡。Pod 的 IP 会变化,但 Service 的 IP 不变。
Service 类型
| Type | 说明 |
|---|---|
ClusterIP |
默认类型,仅在集群内部可访问。 |
NodePort |
在每个节点上开放一个静态端口(30000-32767),外部可通过 <NodeIP>:NodePort 访问。 |
LoadBalancer |
云环境专用,自动创建外部负载均衡器。 |
ExternalName |
返回 CNAME 记录,将服务映射到外部域名。 |
创建 Service 示例(NodePort)
命令行:
bash
kubectl expose deployment my-tomcat --name=tomcat-svc --port=8080 --type=NodePort
kubectl get svc
# 输出示例:tomcat-svc NodePort 10.107.42.139 <none> 8080:30001/TCP
外部访问:http://<任意节点IP>:30001
YAML 方式: (tomcat-svc.yaml)
yaml
apiVersion: v1
kind: Service
metadata:
name: tomcat-svc
spec:
type: NodePort
selector:
app: my-tomcat # 匹配 deployment 中的 label
ports:
- port: 8080 # Service 的端口
targetPort: 8080 # Pod 的端口
nodePort: 30001 # 节点端口(可选,不指定则随机)
2.6 存储(Volume / PV / PVC)
2.6.1 Volume 类型简介
| 类型 | 说明 |
|---|---|
emptyDir |
临时目录,Pod 删除时清空,适用于缓存、临时数据。 |
hostPath |
挂载宿主机目录,多 Pod 可共享,但易导致节点耦合,生产慎用。 |
configMap |
注入非敏感配置。 |
secret |
注入敏感信息(密码、证书)。 |
nfs |
挂载 NFS 共享目录,支持多 Pod 读写。 |
2.6.2 搭建 NFS 共享存储(示例)
Master 节点(NFS Server):
bash
yum install -y nfs-utils
echo "/nfs/data *(insecure,rw,sync,no_root_squash)" > /etc/exports
mkdir -p /nfs/data
systemctl enable rpcbind nfs-server
systemctl start rpcbind nfs-server
exportfs -r
Worker 节点(NFS Client):
bash
yum install -y nfs-utils
showmount -e <Master_IP>
mkdir -p /nfs/data
mount -t nfs <Master_IP>:/nfs/data /nfs/data
2.6.3 使用 NFS Volume 的 Deployment
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-nfs
spec:
replicas: 2
selector:
matchLabels:
app: nginx-nfs
template:
metadata:
labels:
app: nginx-nfs
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
volumes:
- name: html
nfs:
server: 192.168.11.101 # NFS 服务器 IP
path: /nfs/data/nginx-pv
2.6.4 PV & PVC(存储资源抽象)
- PV(PersistentVolume):集群级别的存储资源,由管理员预先创建。
- PVC(PersistentVolumeClaim):用户对存储的申请(大小、访问模式等)。
创建
创建
绑定
使用
管理员
PV
用户
PVC
Pod
静态供应示例:
- 创建 PV(
pv.yaml)
yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-nfs-1gi
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs
nfs:
server: 192.168.11.101
path: /nfs/data/01
- 创建 PVC(
pvc.yaml)
yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nginx-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 200Mi
storageClassName: nfs
- Pod 使用 PVC
yaml
volumes:
- name: data
persistentVolumeClaim:
claimName: nginx-pvc
动态供应 (通过 StorageClass 自动创建 PV)需要部署 nfs-subdir-external-provisioner,较复杂但更灵活,本文暂略。
2.7 配置(ConfigMap & Secret)
2.7.1 ConfigMap(非敏感配置)
创建方式示例:
bash
# 从字面量创建
kubectl create cm my-config --from-literal=key1=value1
# 从文件创建
kubectl create cm redis-conf --from-file=redis.conf
# 从 YAML 创建
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
app.properties: |
spring.profiles.active=prod
server.port=8080
EOF
Pod 中使用 ConfigMap(作为环境变量或文件):
yaml
spec:
containers:
- name: app
env:
- name: KEY1
valueFrom:
configMapKeyRef:
name: my-config
key: key1
volumeMounts:
- name: config
mountPath: /etc/config
volumes:
- name: config
configMap:
name: app-config
2.7.2 Secret(敏感信息)
Secret 默认存储为 base64 编码,并非加密(生产建议开启 etcd 加密)。
创建 Secret 示例:
bash
# 从字面量
kubectl create secret generic db-secret --from-literal=username=admin --from-literal=password=123456
# 从文件
echo -n "admin" > ./username
kubectl create secret generic user-secret --from-file=./username
使用私有镜像仓库的 Secret:
bash
kubectl create secret docker-registry myregistrykey \
--docker-server=registry.cn-hangzhou.aliyuncs.com \
--docker-username=yourname \
--docker-password=yourpassword
在 Pod 中引用:
yaml
spec:
containers:
- name: app
image: registry.cn-hangzhou.aliyuncs.com/fox666/myapp:latest
imagePullSecrets:
- name: myregistrykey
2.8 Ingress(七层路由)
Ingress 将集群外部的 HTTP/HTTPS 流量路由到内部 Service,相比 NodePort 更灵活(支持域名、路径、TLS)。
/api
/web
外部客户端
Ingress Controller
Service A
Service B
安装 Ingress Controller(以 nginx-ingress 为例)
bash
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.47.0/deploy/static/provider/baremetal/deploy.yaml
# 修改镜像地址为国内可拉取的镜像(如 registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images/ingress-nginx-controller:v0.46.0)
vi deploy.yaml
kubectl apply -f deploy.yaml
创建 Ingress 规则
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tomcat-ingress
spec:
rules:
- host: tomcat.tuling.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: tomcat-svc # 之前创建的 Service 名称
port:
number: 8080
应用并测试:
bash
kubectl apply -f ingress.yaml
kubectl get ingress
本地 hosts 添加解析:<任意节点IP> tomcat.tuling.com,浏览器访问 http://tomcat.tuling.com 即可。
Service 与 Ingress 的关系总结
Internet
Ingress
ServiceA
ServiceB
Pod1
Pod2
Pod3
- Service:集群内部的四层负载均衡,提供稳定的 ClusterIP。
- Ingress:集群外部的七层路由,依赖 Ingress Controller 实现。
3. K8s 核心原理
3.1 网络模型
K8s 集群中存在三种网络:
- 节点网络:主机物理网络,用于 Master 与 Worker 之间的通信。
- Pod 网络 :虚拟网络,为每个 Pod 分配独立 IP(如 Flannel 分配的
10.244.0.0/16网段)。 - Service 网络:虚拟 IP 网络(ClusterIP),用于服务发现,不配置在网卡上,而是通过 kube-proxy 转换为 iptables/ipvs 规则。
Service网络
Pod网络
节点网络
Node1
192.168.65.180
Node2
192.168.65.38
Pod A
10.244.1.2
Pod B
10.244.2.3
Service
10.96.0.1
3.2 工作流程(部署 Nginx 为例)
kubelet(Node) scheduler controller-manager etcd kube-apiserver 用户(kubectl) kubelet(Node) scheduler controller-manager etcd kube-apiserver 用户(kubectl) kubectl create deployment nginx 保存 deployment 对象 监听 deployment 变更 创建 replicaset 监听未调度的 Pod 绑定 Pod 到 Node 通知创建 Pod 更新 Pod 状态 返回创建结果
3.3 核心六问
Q1:Master 与 Worker 如何通信?
- kubelet 定期向 apiserver 注册并汇报节点状态。
- apiserver 通过 kubelet 的 HTTPS 接口下发指令(创建、删除 Pod)。
- kube-proxy 从 apiserver 监听到 Service 和 Endpoint 变化后更新本地规则。
Q2:调度器如何选择 Node?
- 预选(Predicates):过滤不满足资源、端口冲突、节点选择器等的节点。
- 优选(Priorities):对通过预选的节点打分(资源均衡、亲和性等),选最高分节点。
Q3:集群状态存在哪里?谁维护?
- 使用 etcd 存储所有状态数据。
- 只有 apiserver 直接读写 etcd,其他组件均通过 apiserver 间接访问。
Q4:外部用户如何访问 Pod?
- 可通过 NodePort 或 LoadBalancer 类型的 Service。
- 推荐使用 Ingress 提供七层路由。
Q5:如何实现 Pod 动态扩缩容?
- Deployment 控制器维护
replicas字段。 - 手动:
kubectl scale deployment --replicas=5 - 自动:配置 HorizontalPodAutoscaler(HPA),根据 CPU/内存使用率自动调整副本数。
Q6:各组件如何协作?
- kube-controller-manager 运行众多控制器(Deployment、ReplicaSet、Node、Service 等),每个控制器是一个控制循环,通过 apiserver 获取期望状态 ,再调谐实际状态直到一致。
4. 总结与最佳实践
| 资源类型 | 作用 | 生产建议 |
|---|---|---|
| Namespace | 环境隔离(dev/test/prod) | 不要使用 default 命名空间跑业务 |
| Pod | 最小调度单元 | 推荐一个 Pod 一个主容器,辅助容器(sidecar)酌情 |
| Deployment | 无状态应用管理(多副本、滚动更新、回滚) | 默认使用此控制器管理 Pod |
| Service | 为 Pod 提供稳定的访问入口和负载均衡 | 内部服务用 ClusterIP,对外暴露用 Ingress |
| Ingress | 七层路由(域名、路径、TLS) | 生产必备,配合 cert-manager 自动管理证书 |
| ConfigMap | 存储非敏感配置 | 避免存储大文件(1MB 限制) |
| Secret | 存储敏感信息(密码、token、镜像拉取凭据) | 建议启用 etcd 加密,或配合外部密钥管理工具 |
| PV / PVC | 持久化存储抽象,解耦存储与 Pod | 生产使用动态供应(StorageClass) |
🚀 学习路径建议
- 本地测试:使用 minikube 或 kind 搭建单节点集群。
- 核心资源:熟练掌握 Pod、Deployment、Service、Ingress 的 YAML 编写。
- 进阶:理解存储(PV/PVC)、配置(ConfigMap/Secret)、RBAC、Helm。
- 生态:Prometheus(监控)、Grafana(可视化)、Istio(服务网格)。
参考资料
本文所有操作均基于 Kubernetes v1.24.3 + containerd v1.6.4,CentOS 7.9 环境验证通过。如遇网络拉取镜像慢,可配置镜像加速器或使用阿里云镜像仓库。
下一篇预告: 《K8s 存储进阶:StatefulSet 与动态 PV 实践》