在Docker解决了"应用环境标准化"问题后,面对大规模容器集群的部署、调度、运维难题,Kubernetes(简称K8s)应运而生。作为云原生技术栈的核心,K8s提供了容器编排、自动扩缩容、故障自愈、服务发现等一站式能力,已成为企业级微服务集群的标配。本文从K8s核心架构出发,逐步拆解核心资源、基础操作、进阶配置,最后结合企业级实战场景给出最佳实践与避坑指南,帮助开发者从"Docker使用者"平滑过渡到"K8s实践者",掌握云原生时代的核心技能。
一、K8s核心认知:为什么它是容器编排的事实标准?
1. K8s的定位与核心价值
K8s是Google基于Borg系统开源的容器编排平台,核心目标是自动化容器的生命周期管理。相较于Docker Compose(单宿主机编排)、Swarm(Docker原生集群),K8s具备更强大的扩展性、高可用性和生态兼容性,能轻松应对从几十到上万节点的容器集群管理需求。
其核心价值体现在三大维度:
- 自动化运维:实现容器的自动部署、自动重启、自动扩缩容、自动负载均衡,大幅降低人工运维成本。
- 高可用保障:通过节点容错、Pod自愈、数据持久化等机制,确保应用7x24小时稳定运行,提升系统可用性。
- 弹性伸缩与扩展:支持基于CPU、内存、自定义指标的弹性扩缩容,同时兼容多云环境,可无缝对接微服务、Serverless等架构。
2. K8s与Docker的关系(澄清常见误区)
很多开发者会混淆二者的定位,实际上它们是"互补而非替代"的关系:
- Docker:负责"容器打包与运行",解决应用环境一致性问题,是K8s的容器运行时基础(目前K8s也支持containerd、CRI-O等其他运行时)。
- K8s:负责"容器集群的编排与管理",解决大规模容器的部署、调度、运维问题,将Docker容器纳入统一的集群管理体系。
核心逻辑:Docker构建镜像→K8s编排容器,二者共同构成"容器化+集群化"的完整解决方案,是云原生技术栈的基石。
3. K8s核心架构:分布式系统的"大脑与手脚"
K8s采用"控制平面+节点"的分布式架构,各组件协同工作实现集群管理,整体可分为"决策层"和"执行层"。
控制平面(Control Plane):集群的"大脑"
负责集群的决策与管理,通常部署在独立节点(可单节点或多节点高可用部署),核心组件包括:
- kube-apiserver:K8s的"API网关",所有集群操作(创建Pod、部署服务)都通过它进行,提供认证、授权、访问控制等功能,是组件间通信的核心枢纽。
- etcd:分布式键值数据库,存储集群的所有配置信息和状态数据(如Pod部署、服务配置),是K8s的"数据中心",需保证高可用。
- kube-controller-manager:控制器管理器,运行各类控制器(如Node控制器、Pod控制器、Service控制器),负责监控集群状态,将实际状态调整为期望状态(如Pod故障后自动重启)。
- kube-scheduler:调度器,根据节点资源情况、Pod需求(如CPU/内存限制),将Pod调度到合适的节点上运行,确保资源合理分配。
- cloud-controller-manager:云服务控制器,对接公有云(如阿里云、AWS)的API,实现集群与云服务的联动(如自动创建负载均衡、云盘)。
节点(Node):集群的"手脚"
负责运行容器化应用,是集群的工作节点,核心组件包括:
- kubelet:节点代理,运行在每个工作节点上,监听kube-apiserver的指令,负责Pod的创建、启动、停止、监控等操作,确保Pod按期望运行。
- kube-proxy:网络代理,运行在每个工作节点上,负责维护节点的网络规则,实现Pod间、Pod与外部网络的通信,支持Service的负载均衡功能。
- 容器运行时(Container Runtime):负责容器的实际运行,如Docker、containerd,接收kubelet的指令,完成容器的创建与销毁。
二、K8s核心资源:理解K8s的"乐高积木"
K8s通过"资源对象"描述集群的状态和应用的需求,所有操作本质上都是对这些资源的CRUD(创建、读取、更新、删除)。核心资源包括Pod、Deployment、Service、ConfigMap、Secret等,掌握这些资源是使用K8s的基础。
1. Pod:K8s最小部署单元
Pod是K8s中最小的可部署、可调度单元,包含一个或多个容器,这些容器共享Pod的网络命名空间、存储卷等资源,紧密协同工作(如一个应用容器+一个日志收集容器)。
- 特性:Pod是短暂的,生命周期有限,故障后会被重新创建(但IP会变化);容器间通过localhost通信,无需网络映射。
- 创建方式:可通过kubectl命令快速创建,或通过yaml配置文件定义(生产环境推荐yaml,便于版本控制和复用)。
示例:Pod yaml配置(nginx-pod.yaml)
yaml
apiVersion: v1 # API版本,不同资源有对应版本
kind: Pod # 资源类型为Pod
metadata:
name: nginx-pod # Pod名称
labels: # 标签,用于筛选和关联其他资源
app: nginx
spec:
containers: # 容器列表
- name: nginx # 容器名称
image: nginx:1.24 # 容器镜像
ports:
- containerPort: 80 # 容器暴露端口(仅容器内可见)
resources: # 资源限制
requests: # 最小资源需求
cpu: "100m" # 100毫核(0.1核)
memory: "128Mi" # 128MB内存
limits: # 最大资源限制
cpu: "500m"
memory: "256Mi"
Pod核心操作命令
bash
# 1. 通过yaml创建Pod
kubectl apply -f nginx-pod.yaml
# 2. 查看Pod列表
kubectl get pods # 简写:kubectl get po
kubectl get pods -o wide # 查看Pod所在节点、IP等详情
# 3. 查看Pod日志
kubectl logs nginx-pod # 查看指定Pod日志
kubectl logs -f nginx-pod # 实时跟踪日志
# 4. 进入Pod的容器(类似docker exec)
kubectl exec -it nginx-pod -- /bin/bash
# 5. 删除Pod
kubectl delete pod nginx-pod
kubectl delete -f nginx-pod.yaml # 通过yaml删除
2. Deployment:无状态应用的编排控制器
直接管理Pod存在诸多局限(如无法自动扩缩容、故障后需手动重建),Deployment作为最常用的控制器,通过管理ReplicaSet(副本集)实现Pod的"声明式编排",支持滚动更新、回滚、扩缩容等功能,适用于无状态应用(如Web服务、API服务)。
-
核心功能:维持指定数量的Pod副本( replicas )、滚动更新Pod版本(避免服务中断)、回滚到历史版本、暂停/恢复部署。
-
逻辑关系:Deployment → ReplicaSet → Pod,Deployment通过控制ReplicaSet的数量和版本,间接管理Pod。
示例:Deployment yaml配置(nginx-deploy.yaml)
yaml
apiVersion: apps/v1 # Deployment对应的API版本
kind: Deployment
metadata:
name: nginx-deploy
spec:
replicas: 3 # 期望的Pod副本数
selector: # 选择器,匹配要管理的Pod(通过标签)
matchLabels:
app: nginx
strategy: # 更新策略
type: RollingUpdate # 滚动更新(默认)
rollingUpdate:
maxSurge: 1 # 更新时最多新增1个Pod
maxUnavailable: 1 # 更新时最多不可用1个Pod
template: # Pod模板,与单独创建Pod的配置一致
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.24
ports:
- containerPort: 80
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "256Mi"
Deployment核心操作命令
bash
# 1. 创建Deployment
kubectl apply -f nginx-deploy.yaml
# 2. 查看Deployment列表
kubectl get deployments # 简写:kubectl get deploy
# 3. 查看ReplicaSet
kubectl get replicasets # 简写:kubectl get rs
# 4. 扩缩容(临时调整副本数)
kubectl scale deploy nginx-deploy --replicas=5
# 5. 滚动更新(更新镜像版本)
kubectl set image deploy nginx-deploy nginx=nginx:1.25
# 6. 查看更新状态
kubectl rollout status deploy nginx-deploy
# 7. 回滚到上一版本
kubectl rollout undo deploy nginx-deploy
# 8. 查看历史版本
kubectl rollout history deploy nginx-deploy
3. Service:Pod的稳定访问入口
Pod是短暂的,IP会随重建而变化,Service通过标签选择器关联Pod,提供一个稳定的IP和端口,实现对Pod的负载均衡和统一访问入口,解决"Pod IP漂移"问题。
Service的四种类型
| 类型 | 核心特性 | 适用场景 |
|---|---|---|
| ClusterIP(默认) | 仅集群内部可访问,提供集群内稳定IP,通过kube-proxy实现负载均衡 | 集群内服务间通信(如微服务调用) |
| NodePort | 在每个节点上暴露一个静态端口,外部通过"节点IP:NodePort"访问 | 开发/测试环境,简单外部访问需求 |
| LoadBalancer | 对接公有云负载均衡服务,自动创建负载均衡器,外部通过负载均衡器IP访问 | 生产环境,需要公网访问的服务 |
| ExternalName | 将Service映射到外部域名(如xxx.com),无需关联Pod | 访问集群外部服务,统一入口管理 |
示例:NodePort类型Service yaml(nginx-svc.yaml)
yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
type: NodePort # 服务类型为NodePort
selector:
app: nginx # 关联标签为app:nginx的Pod
ports:
- port: 80 # Service暴露的端口(集群内访问端口)
targetPort: 80 # 映射到Pod的端口
nodePort: 30080 # 节点暴露的端口(范围:30000-32767,可选,不指定则自动分配)
Service核心操作命令
bash
# 1. 创建Service
kubectl apply -f nginx-svc.yaml
# 2. 查看Service列表
kubectl get services # 简写:kubectl get svc
# 3. 查看Service详情(包含关联的Pod、端口映射等)
kubectl describe svc nginx-svc
# 4. 删除Service
kubectl delete svc nginx-svc
4. 其他核心资源(生产环境必备)
- ConfigMap :存储非敏感配置信息(如数据库地址、应用端口),实现"配置与代码分离",可动态更新配置,无需重建Pod。
`
示例:ConfigMap配置
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
DB_HOST: "mysql-service"
DB_PORT: "3306"
APP_ENV: "prod"
`
- Secret :存储敏感信息(如密码、密钥、证书),数据会经过Base64编码(非加密,生产环境需配合加密插件),避免配置文件中明文存储敏感数据。
`
示例:Secret配置(存储mysql密码)
apiVersion: v1
kind: Secret
metadata:
name: mysql-secret
type: Opaque
data:
root-password: MTIzNDU2Cg== # Base64编码后的密码(原密码:123456)
`
- PersistentVolume(PV)/PersistentVolumeClaim(PVC):实现数据持久化,PV是集群级别的存储资源(如云盘、NFS目录),PVC是Pod对存储资源的"申请",类似"存储版的Pod与Service",解耦存储资源与应用。
三、K8s基础实操:从环境搭建到应用部署
1. 环境搭建(三种主流方式)
根据使用场景选择合适的搭建方式,开发测试推荐Minikube,生产环境推荐kubeadm或云厂商托管K8s(如阿里云ACK、AWS EKS)。
方式一:Minikube(本地单节点测试环境)
Minikube是轻量级K8s工具,可在本地快速搭建单节点K8s集群,适合开发者学习和测试。
bash
# 1. 安装Minikube(依赖Docker环境)
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
# 2. 启动Minikube集群(指定Docker为容器运行时)
minikube start --driver=docker
# 3. 验证集群状态
minikube status
kubectl cluster-info
# 4. 停止/删除集群
minikube stop
minikube delete
方式二:kubeadm(生产环境自建集群)
kubeadm是官方推荐的集群搭建工具,可快速部署多节点K8s集群,适合需要自主管理集群的场景(需至少2台服务器:1台控制平面+1台工作节点)。
前置准备(所有节点)
bash
# 1. 关闭防火墙、SELinux、Swap
sudo systemctl stop firewalld
sudo systemctl disable firewalld
sudo setenforce 0
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
sudo swapoff -a
sudo sed -i '/swap/s/^/#/' /etc/fstab
# 2. 配置内核参数,开启IP转发
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system
# 3. 安装容器运行时(containerd)
sudo yum install -y containerd
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
sudo sed -i 's/SystemdCgroup \= false/SystemdCgroup \= true/' /etc/containerd/config.toml
sudo systemctl restart containerd
sudo systemctl enable containerd
# 4. 安装kubeadm、kubelet、kubectl
sudo tee /etc/yum.repos.d/kubernetes.repo <<'EOF'
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-\$basearch
enabled=1
gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
exclude=kubelet kubeadm kubectl
EOF
sudo yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
sudo systemctl enable --now kubelet
初始化控制平面节点
bash
# 初始化集群(指定Pod网络网段,需与后续网络插件一致)
sudo kubeadm init --pod-network-cidr=10.244.0.0/16
# 配置kubectl权限(当前用户)
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
# 安装网络插件(Calico,主流CNI插件)
kubectl apply -f https://docs.projectcalico.org/v3.25/manifests/calico.yaml
# 验证控制平面状态
kubectl get nodes # 控制平面节点状态为Ready即正常
添加工作节点
bash
# 在控制平面节点执行,获取加入命令(包含令牌和哈希值)
kubeadm token create --print-join-command
# 在工作节点执行上述命令(示例)
sudo kubeadm join 192.168.1.100:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# 在控制平面节点验证工作节点是否加入
kubectl get nodes # 工作节点状态变为Ready即成功
2. 完整应用部署实战(Nginx示例)
结合上述核心资源,实现从Deployment创建、Service暴露到外部访问的完整流程。
bash
# 1. 创建Deployment(3个副本)
kubectl apply -f nginx-deploy.yaml
# 2. 查看Deployment和Pod状态,确保Pod全部Ready
kubectl get deploy nginx-deploy
kubectl get po -l app=nginx
# 3. 创建NodePort类型Service,暴露外部访问端口
kubectl apply -f nginx-svc.yaml
# 4. 查看Service,确认NodePort端口(如30080)
kubectl get svc nginx-svc
# 5. 外部访问(通过任意节点IP:NodePort)
curl http://192.168.1.101:30080 # 访问成功则返回Nginx默认页面
四、K8s进阶配置:存储、网络与安全
1. 存储配置:PV与PVC实现数据持久化
以NFS存储为例,实现Pod数据持久化,确保Pod删除后数据不丢失。
步骤1:搭建NFS服务器(单独节点)
bash
# 安装NFS服务
sudo yum install -y nfs-utils
# 创建共享目录
sudo mkdir -p /nfs/data
sudo chmod 777 /nfs/data
# 配置NFS共享(允许集群节点访问)
sudo tee /etc/exports <<'EOF'
/nfs/data 192.168.1.0/24(rw,no_root_squash,no_all_squash,sync)
EOF
# 启动NFS服务
sudo systemctl start nfs-server
sudo systemctl enable nfs-server
步骤2:创建PV(关联NFS存储)
yaml
# nfs-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv
spec:
capacity:
storage: 10Gi # PV存储容量
accessModes:
- ReadWriteMany # 访问模式:多节点读写
persistentVolumeReclaimPolicy: Retain # 回收策略:保留数据
nfs:
path: /nfs/data # NFS共享目录
server: 192.168.1.102 # NFS服务器IP
步骤3:创建PVC(Pod申请存储)
yaml
# nfs-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi # 申请5Gi存储(不超过PV容量)
步骤4:Pod挂载PVC
yaml
# 修改Deployment的Pod模板,添加存储挂载
spec:
template:
spec:
containers:
- name: nginx
image: nginx:1.24
ports:
- containerPort: 80
volumeMounts:
- name: nfs-volume # 挂载名称,与volumes对应
mountPath: /usr/share/nginx/html # 容器内挂载目录
volumes:
- name: nfs-volume
persistentVolumeClaim:
claimName: nfs-pvc # 关联创建的PVC
2. 网络配置:CNI插件与网络策略
K8s本身不提供网络实现,需通过CNI(容器网络接口)插件完成网络配置,主流插件包括Calico、Flannel、Weave Net等,其中Calico因支持网络策略、性能稳定,被广泛用于生产环境。
网络策略(NetworkPolicy):Pod间通信控制
通过NetworkPolicy定义Pod间的通信规则(允许/拒绝),实现网络隔离,增强集群安全性。示例:仅允许带"app:web"标签的Pod访问带"app:mysql"标签的Pod的3306端口。
yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: mysql-network-policy
spec:
podSelector:
matchLabels:
app: mysql # 目标Pod(被访问方)
policyTypes:
- Ingress # 入站规则
ingress:
- from:
- podSelector:
matchLabels:
app: web # 允许访问的Pod(访问方)
ports:
- protocol: TCP
port: 3306 # 允许访问的端口
3. 安全配置:权限控制与镜像安全
-
RBAC权限控制:基于角色的访问控制,通过Role、ClusterRole、RoleBinding、ClusterRoleBinding定义用户/服务账户的权限,避免过度授权(如限制开发人员仅能查看Pod,无法删除)。
-
镜像安全 :仅允许从可信镜像仓库拉取镜像,通过ImagePolicyWebhook验证镜像签名,避免运行恶意镜像;禁止容器以root用户运行,通过SecurityContext切换普通用户。
`
示例:容器运行普通用户
spec:
containers:
- name: nginx
image: nginx:1.24
securityContext:
runAsUser: 1000 # 普通用户ID
runAsGroup: 1000 # 用户组ID
allowPrivilegeEscalation: false # 禁止权限提升`
五、企业级实战:K8s与微服务、CI/CD集成
1. 微服务容器化部署(Spring Cloud示例)
微服务架构与K8s天然契合,通过K8s的Deployment、Service、ConfigMap等资源,实现微服务的弹性扩缩容、服务发现、配置管理。核心流程:
- 将每个微服务(如用户服务、订单服务)打包为Docker镜像,推送至私有仓库。
- 通过Deployment创建微服务Pod,使用ConfigMap注入配置(如注册中心地址、数据库配置),使用Secret存储敏感信息(如数据库密码)。
- 通过ClusterIP类型Service暴露微服务,实现服务间内部调用;通过Ingress(HTTP/HTTPS路由)统一管理外部访问入口。
- 结合Spring Cloud Discovery与K8s Service,实现微服务自动注册与发现。
2. K8s与CI/CD集成(Jenkins+GitLab)
实现"代码提交→自动构建镜像→推送镜像→K8s部署"的全流程自动化,核心步骤:
- GitLab代码提交触发Jenkins任务,Jenkins拉取代码、编译打包。
- 通过Dockerfile构建微服务镜像,推送至私有镜像仓库(如Harbor)。
- Jenkins通过kubectl命令(或Helm)更新K8s Deployment的镜像版本,触发滚动更新。
- 通过Prometheus监控部署状态,若更新失败,触发回滚操作。
Jenkins构建脚本示例(Shell)
bash
#!/bin/bash
# 编译代码
mvn clean package -DskipTests
# 构建Docker镜像
IMAGE_NAME="192.168.1.100:5000/user-service:${BUILD_NUMBER}"
docker build -t $IMAGE_NAME ./user-service
# 推送镜像到私有仓库
docker push $IMAGE_NAME
# 更新K8s Deployment镜像(滚动更新)
kubectl set image deploy user-service user-service=$IMAGE_NAME -n default
# 等待更新完成
kubectl rollout status deploy user-service -n default
# 验证Pod状态
kubectl get po -l app=user-service -n default
3. 监控与告警:Prometheus+Grafana
K8s集群及应用的监控是生产环境必备能力,通过Prometheus采集集群、Pod、应用的监控指标,Grafana可视化展示,AlertManager实现告警通知。
- 核心监控指标:集群节点CPU/内存/磁盘使用率、Pod资源占用、Service请求量/延迟、应用健康状态。
- 部署方式:通过Helm快速部署Prometheus、Grafana、AlertManager,配置自定义监控规则(如Pod CPU使用率超过80%告警)。
六、实战避坑指南:生产环境常见问题与解决方案
| 问题 | 原因 | 解决方案 |
|---|---|---|
| Pod处于Pending状态 | 节点资源不足、调度规则限制、镜像拉取失败、PV绑定失败 | 1. 查看事件:kubectl describe po ;2. 检查节点资源:kubectl top node;3. 验证镜像拉取权限、PV/PVC状态 |
| Service无法访问Pod | 标签选择器不匹配、Pod未就绪、网络策略拦截、kube-proxy异常 | 1. 确认Pod标签与Service选择器一致;2. 检查Pod状态为Ready;3. 排查网络策略规则;4. 重启kube-proxy:kubectl rollout restart daemonset kube-proxy -n kube-system |
| 滚动更新失败 | 新镜像拉取失败、应用启动失败、健康检查配置错误 | 1. 回滚更新:kubectl rollout undo deploy ;2. 检查镜像地址、应用日志;3. 优化健康检查配置(livenessProbe、readinessProbe) |
| 数据持久化失败 | PV/PVC绑定失败、存储插件异常、权限不足 | 1. 查看PV/PVC状态:kubectl get pv,pvc;2. 验证存储服务器(如NFS)是否正常;3. 检查Pod挂载目录权限 |
生产环境最佳实践
- 高可用部署:控制平面多节点部署(至少3台),etcd集群高可用,工作节点多可用区部署,避免单点故障。
- 资源规划:为所有Pod设置资源requests和limits,避免资源抢占;根据业务需求合理规划节点资源,预留冗余资源应对峰值。
- 版本管理:K8s版本选择稳定版(如1.27.x、1.28.x),避免使用最新版;镜像使用固定版本标签,禁止使用latest标签。
- 备份与恢复:定期备份etcd数据(集群配置核心),制定灾难恢复预案,确保集群故障后可快速恢复。
七、总结与进阶方向
K8s作为云原生的核心,其价值不仅在于容器编排,更在于提供了一套标准化的分布式应用管理体系,为微服务、Serverless、多云部署等场景提供了基础支撑。本文从核心架构、资源操作、实操部署到企业级实战,覆盖了K8s的核心知识点,帮助开发者完成从"入门"到"落地"的跨越。
后续可深入学习的进阶方向:
- Helm:K8s包管理工具,简化应用的部署、升级、回滚,适合复杂应用的分发与管理。
- Operator:基于K8s CRD(自定义资源)实现有状态应用(如MySQL、Elasticsearch)的自动化运维,扩展K8s能力。
- Serverless Kubernetes:如阿里云ASK、AWS Fargate,无需管理节点,按需付费,降低集群运维成本。
- ServiceMesh:如Istio,实现服务间通信的流量控制、熔断、追踪、加密,解耦服务治理与业务代码。
K8s的学习曲线较陡,建议结合实际项目多动手实践,从简单应用部署开始,逐步探索进阶特性,最终将其灵活运用到生产环境,发挥云原生技术的最大价值。