这几年后端技术圈里云原生、Docker、K8s 这几个关键词几乎成了绕不开的“标配”。不管是招聘 JD 里的加分项还是云厂商产品文档里的高频词甚至是技术评审时架构师嘴里时不时蹦出的概念都在指向同一个事实容器化和容器编排已经不是“要不要学”的问题而是“什么时候学、学到多深”的问题。这篇内容我不会从零开始复述官方文档而是结合我这些年实际部署、迁移、排障的经验把 Docker 和 K8s 这两套东西的优缺点、适用场景、核心原理尽量讲清楚。适合刚接触容器化的新人也适合正在评估“要不要把项目迁到 K8s”的团队做参考。1. 云原生从传统架构到容器编排的演进逻辑1.1 传统架构的痛点环境不一致与资源浪费在讲 Docker 和 K8s 之前得先理解它们要解决什么问题。早年间做应用部署最常见的场景是开发环境代码跑得好好的一到测试环境就各种报错测试通过了上线到生产服务器又崩了。排查到最后往往是一句“环境不一样”或者“依赖版本对不上”。那时候部署一套应用从装 JDK、配数据库、调中间件参数到启动脚本每一步都可能踩坑而且每台服务器都要重复做一遍。更麻烦的是资源利用率。传统物理机部署模式下一台服务器跑一个应用实例CPU 和内存经常大量闲置用虚拟机虽然做了隔离但每个虚拟机要装完整操作系统动辄几个 GB 的磁盘和几百 MB 的内存开销启动速度也慢。这种“杀鸡用牛刀”的方式在业务量增长时很难快速弹性伸缩。1.2 云原生的四个核心支柱云原生这个概念本质上是一套构建和运行应用程序的方法论强调应用从一开始就为“云”设计。它通常包含四个核心内容微服务把单体应用拆分成多个独立部署的小服务每个服务只负责一个业务领域可以独立开发、部署、扩缩容。容器化用容器作为微服务的交付载体把代码、运行时、系统库、配置全部打包保证任何环境下的运行一致性。DevOps打破开发和运维的边界通过自动化流水线实现持续集成、持续交付缩短从代码提交到上线的周期。持续交付让每一次代码变更都有可能直接发布到生产环境配合灰度发布、滚动更新等策略降低发布风险。这四个支柱不是孤立的而是互相配合的。微服务让系统变复杂了容器化让交付变简单了DevOps 让流程变快了持续交付让发布变稳了。而 Docker 和 K8s恰好是“容器化”和“微服务”这两个支柱最核心的技术底座。1.3 为什么偏偏是 Docker K8s在 Docker 之前有 LXC 这类 Linux 容器技术在 K8s 之前也有 Docker Swarm、Mesos 等编排方案但最终普及度最高的组合就是 Docker 加 K8s。原因有两方面。一方面是 Docker 把镜像构建、分发、运行的标准统一了。Docker 镜像就像是一个打包好的“运行环境快照”开发者构建一次就能在任何装了 Docker 的机器上跑起来不再需要为环境差异操心。另一方面是 K8s 在容器编排领域的生态统治力。它背靠云原生计算基金会CNCF周边有完整的监控、日志、服务网格、持续交付工具链这比 Swarm 和 Mesos 的社区生态丰富得多。实际招聘市场上“K8s”几乎是容器编排的唯一代名词。2. Docker把应用和环境打包成一个“标准件”2.1 Docker 的核心原理镜像分层与容器隔离Docker 的精髓可以总结成两句话镜像定义环境容器运行环境。镜像是一个只读模板里面包含应用代码、运行时、依赖库、配置文件容器是镜像的运行实例增加了可写层跑起来就是一个隔离的进程。镜像有一个非常关键的设计——分层Layer。每一层是 Dockerfile 里的一条指令产生的增量比如FROM指定基础镜像RUN安装依赖COPY拷贝文件。因为分层是可以共享的多个镜像如果基于同一个基础镜像比如ubuntu:22.04磁盘上只会存一份底层数据拉取和启动速度都会快很多。这也是为什么 Docker 镜像仓库能高效存储成千上万个镜像的原因。容器隔离依赖 Linux 内核的两项能力Namespace 实现资源视图隔离进程、网络、文件系统、用户等Cgroups 实现资源限制CPU、内存、磁盘 IO。简单说Namespace 让容器里的进程以为自己独占了一台机器Cgroups 保证它不能把宿主机资源吃光。2.2 常用 Docker 操作与部署示例容器化的日常操作其实不复杂最常用的命令就那么几个# 构建镜像 docker build -t myapp:1.0 . # 查看本地镜像列表 docker images # 运行容器映射宿主机端口到容器端口 docker run -d --name myapp -p 8080:8080 myapp:1.0 # 查看运行中的容器 docker ps # 查看容器日志 docker logs -f myapp # 进入容器内部调试 docker exec -it myapp /bin/bash # 停止并删除容器 docker stop myapp docker rm myapp # 查看容器资源占用 docker stats拿一个实际项目举例。比如要用 Docker 部署 MySQL 8.0 并且做数据持久化标准做法是docker run -d \ --name mysql8 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORDyourpassword \ -e MYSQL_DATABASEtestdb \ -v /data/mysql:/var/lib/mysql \ --restartalways \ mysql:8.0这里的-v参数很重要它把容器内的数据目录挂载到宿主机磁盘容器删了数据还在。--restartalways让容器在宿主机重启后自动拉起。这两点分别是“数据不丢”和“服务自动恢复”的基础。2.3 Docker 的优缺点盘点Docker 能火遍全球优势非常明显维度说明环境一致性镜像构建一次运行处处一致彻底解决“在我电脑上能跑”的问题资源利用率高相比虚拟机容器共享宿主机内核启动快、占用小交付标准化应用和依赖统一打包成镜像配合镜像仓库实现标准化分发隔离性进程级隔离一个容器崩溃不影响其他容器生态成熟官方镜像、第三方工具、云厂商支持都非常完善但 Docker 不是银弹缺点同样明显单机能力有限Docker 本身只能管一台机器上的容器无法跨节点调度。机器宕机了上面的容器不会自动迁移。不适合有状态应用数据库这类有状态服务虽然可以做数据卷持久化但故障转移、主从切换、数据一致性都要自己实现非常繁琐。缺少高级编排能力滚动更新、弹性伸缩、服务发现、负载均衡这些能力原生 Docker 基本没有或者非常简陋。镜像体积控制需要经验Dockerfile 写得不讲究镜像动辄几个 GB拉取和部署效率都受影响。2.4 单独用 Docker 的典型场景如果只是个人开发、小项目、或者在单台服务器上跑几个中间件Docker 完全够用。比如我在一台 4 核 8G 的云服务器上用 Docker 跑了 Nginx、MySQL、Redis、三四个微服务一条docker ps就能看到所有服务的运行状态部署和升级都非常方便。但一旦业务量上来、服务数量变多问题就来了某个服务内存溢出把整台机器搞挂了怎么办高峰期需要自动扩容到多台机器怎么办发布新版本时怎么做到不停服这些已经不是 Docker 单体能解决的需要引入编排层。3. K8s把多台服务器“拼”成一台巨型计算机3.1 为什么需要容器编排当服务数量少、机器只有一两台的时候脚本加 Docker 就能撑住。但当你有几十个微服务、几百个容器实例、几十台服务器时人工管理根本不可行。你需要一套系统来自动处理容器该调度到哪台机器、资源不够时怎么扩容、某个节点宕机后容器怎么迁移、服务之间怎么互相发现、流量怎么负载均衡、新版本怎么平滑发布。K8s 干的就是这件事。官方的定义是“用于自动部署、扩展和管理容器化应用程序的开源系统”。我更愿意把它理解为把多台服务器抽象成一台巨型计算机你只需要告诉它“要跑什么、要多少副本”它负责分配资源、维持状态、处理故障。3.2 K8s 核心组件拆解K8s 的架构可以分成控制平面Master和工作节点Node两大部分。控制平面相当于大脑负责整个集群的管理和决策kube-apiserver所有组件和用户交互的唯一入口处理 REST 请求校验并存储状态。etcd集群的数据库保存所有资源对象的状态。etcd 挂了整个集群就失去“记忆”了。kube-controller-manager运行各种控制器持续确保实际状态向期望状态收敛。比如 Deployment 控制器保证副本数永远和声明的一致。kube-scheduler负责为新创建的 Pod 挑选最合适的节点考虑资源、亲和性、污点等因素。工作节点是干活的地方kubelet每个节点上的代理负责管理本节点的 Pod 生命周期与 apiserver 通信。kube-proxy维护节点上的网络规则实现服务负载均衡。容器运行时真正运行容器的组件常见的是 containerd如今默认或 Docker历史版本中作为运行时。K8s 里有个核心抽象叫 Pod它是 K8s 调度的最小单位。一个 Pod 可以包含一个或多个容器这些容器共享网络命名空间和存储卷通常用于部署关系紧密的进程对比如主进程加日志采集 sidecar。3.3 K8s 的五个关键能力K8s 之所以能用“声明式 API”简化运维靠的是几个核心对象。我挑五个最常用的展开说Deployment无状态应用的首选控制器。你声明“运行 3 个副本”它保证永远有 3 个 Pod 处于运行状态。升级时支持滚动更新RollingUpdate默认情况下逐个替换旧 Pod期间服务始终可用。发现问题可以一键回滚到上一个版本。ServicePod 是动态的IP 随时会变。Service 提供稳定的访问入口并自动把流量转发到后端的 Pod 集合上。它本质是一个 VIP 加 kube-proxy 转发规则的组合配合 DNS 实现服务发现。ConfigMap / Secret把配置和敏感信息从镜像中剥离出来。同一个镜像通过挂载不同的 ConfigMap就能在不同环境开发、测试、生产跑出不同配置效果。Secret 类似只是内容会做 Base64 编码并支持加密存储。IngressService 工作在网络层Ingress 负责七层 HTTP 路由。你可以在 Ingress 规则里配置域名、路径到 Service 的映射关系Nginx Ingress Controller 会根据规则做反向代理一个集群复用一份 Certificate 就能统一管理所有域名的 HTTPS。HPAHorizontalPodAutoscaler根据 CPU、内存或自定义指标自动调整副本数量。比如设置“CPU 平均使用率超过 70% 时扩容”高峰期 Pod 数量自动从 3 个升到 10 个流量回落后再缩回去。3.4 K8s 的优缺点盘点K8s 的优势是让大规模容器化应用的管理成为可能维度说明自动修复节点宕机或 Pod 崩溃后自动重建无需人工干预弹性伸缩支持 Pod 级别 HPA 和节点级别 Cluster Autoscaler滚动发布支持金丝雀发布、蓝绿部署发布期间服务不中断服务发现与负载均衡Service DNS Ingress 自动完成生态丰富Prometheus 监控、Istio 服务网格、Helm 包管理周边工具链完善但 K8s 的代价也相当显著学习曲线陡峭概念多Pod、Deployment、Service、Ingress、PV/PVC、RBAC……光是理解各个对象之间的关系就要一段时间。排查问题时需要同时懂 Linux 网络、DNS、存储和容器原理。运维复杂度高控制平面组件高可用、etcd 备份恢复、证书轮换、集群升级、插件管理每一项都比传统的“装个 JDK 启动 jar”复杂得多。资源开销不小一个生产级集群至少要 3 台 master 和 3 台 node每台节点的系统组件要占用约 1-2G 内存。小规模项目用它其实不划算。有状态应用依然难虽然引入了 StatefulSet、Operator 等机制但数据库、消息队列上 K8s 依然需要精细的运维经验和专门的 Operator不适合新手直接上手。3.5 单节点 K8s 与生产级高可用集群K8s 并不是只有大规模集群一种玩法。我在实际工作中见过不少团队用单节点 K8s 跑测试环境和中小型生产应用。单节点部署通常用 k3s、minikube 或者 kind 这类轻量方案安装简单、资源占用小也能享受到 K8s 的声明式管理和自动恢复能力。但要注意单节点意味着 etcd 只有一份数据节点宕机 集群不可用。所以单节点适合跑开发测试环境或者对可用性要求不高的内部系统。生产环境至少需要三台 master 节点做高可用通常配合负载均衡器比如 Keepalived HAProxy把流量分发到三个 apiserver 前面。etcd 也是三副本集群任何一个节点宕机只要副本数仍过半集群就能继续工作。我之前帮一个团队做过三台 master 的高可用部署方案选的是 KubeKey 加 HAProxy Keepalived。KubeKey 是青云开源的一个部署工具对中文用户友好可以一条命令拉起高可用集群。相比手动用 kubeadm 配置 etcd 和负载均衡KubeKey 把很多繁琐步骤自动化了适合中小团队快速落地。4. Docker 和 K8s 是什么关系不是二选一而是上下层4.1 Docker 是运行时K8s 是编排平台很多新手会问我有 Docker 了为什么还要用 K8s或者反过来问有了 K8s是不是就不需要 Docker 了这两个问题的答案其实是一句话Docker 管“单机上的容器”K8s 管“集群里的容器”。它们不在同一层不是竞争关系而是基础与上层的关系。类比来说Docker 相当于给一个餐厅配了统一规格的保鲜盒镜像每个菜装进盒子里方便运输和保存K8s 则是整个餐厅的中央管理系统决定哪个菜在哪个灶台做、做几份、哪份坏了立即补做。从实际部署角度看K8s 集群里的每个节点上也确实需要有容器运行时。早期 K8s 直接用 Docker 作为运行时后来因为 CRIContainer Runtime Interface标准化越来越多 K8s 集群改用 containerd但镜像格式仍然是 Docker 镜像标准docker build构建出来的镜像在 containerd 里照样能跑。所以可以说Docker 的“镜像制”依然是事实标准但“运行容器”这件事已经越来越不依赖 Docker 这个具体软件了。4.2 什么时候只用 Docker 就够了如果你的项目满足这些条件完全可以只用 Docker服务数量在 10 个以内跑在一两台服务器上发布频率不高可以接受停机更新没有自动扩缩容需求流量基本稳定团队没有足够的精力维护 K8s 集群本身。这种情况下硬上 K8s 反而得不偿失。我见过一个项目就三个微服务硬是搭了一套三节点 K8s结果集群没人会维护证书过期了都不知道最后服务全挂还不如直接用 Docker Compose 来得清爽。Docker Compose 是一个值得提的中间方案。它用 YAML 定义多容器应用可以一条命令启动整套服务支持依赖顺序、网络配置、数据卷挂载。适合单机多容器的场景是“从 Docker 到 K8s”之间的平滑过渡。4.3 什么时候必须上 K8s反过来出现下面这些信号时K8s 基本是必经之路微服务数量多服务间的依赖和调用关系复杂需要按流量自动扩缩容或者同一套代码在多环境频繁发布对可用性要求高不能接受单点故障必须有自动故障转移团队有专门的运维或者平台工程师愿意投入成本维护集群。我这些年看到的典型场景是业务规模到了几十个服务以上多台服务器靠人肉管理部署脚本已经维护不过来容器数量一多就会乱。这时候 K8s 带来的标准化管理和自动化能力价值远远超过它的学习成本。4.4 从 Docker 迁移到 K8s 的技术路径从 Docker 到 K8s不是推倒重来。大部分服务要做的改造并不大Dockerfile 构建镜像的流程不需要变还是docker build只是最终镜像推送到私有仓库方便 K8s 拉取。容器不支持持久化所以有状态服务要提前规划数据卷K8s 里对应的是 PV/PVC。环境变量和配置文件从 Docker 的-e参数和挂载文件改成 ConfigMap 和 Secret。端口暴露从 Docker 的-p改成 K8s 的 Service 和 Ingress不再直接映射宿主机端口。我在一个若依微服务项目的迁移中实践过这套流程。当时是把原本用脚本部署的整套若依微服务Nacos、Gateway、多个业务服务迁移到单节点 K8s。步骤大致是先给每个服务写 Dockerfile 构建镜像推送私有仓库然后针对 Nacos 这类有状态服务配置 StatefulSet 和持久化存储再写 Service 的 YAML 暴露内部访问最后用 Ingress 统一对外提供 HTTP 入口。整个过程大概两三天迁移后最大的变化是发布不再需要登录服务器手动敲脚本直接kubectl set image或者 apply 新的 YAML 就能滚动升级。4.5 K8s 常用命令速查这里整理一份我日常用得最多的 K8s 命令熟练掌握这些基本可以应付日常工作# 查看所有命名空间的 Pod kubectl get pods -A # 查看 Pod 详细信息排障必备 kubectl describe pod pod-name # 查看容器日志 kubectl logs -f pod-name -c container-name # 进入 Pod 内部调试 kubectl exec -it pod-name -- /bin/bash # 查看服务、配置、节点 kubectl get svc kubectl get configmap kubectl get nodes # 查看资源占用 kubectl top pods kubectl top nodes # 应用或更新配置 kubectl apply -f deployment.yaml # 回滚到上一个版本 kubectl rollout undo deployment/deployment-name # 扩容缩容 kubectl scale deployment/deployment-name --replicas55. 落地场景从单机 Docker 到生产级集群5.1 场景一用 Docker 快速搭建中间件环境如果你只是想快速起一套 MySQL、Redis、Nginx 的开发环境Docker 是最方便的。我自己经常在本地用 Docker Desktop 跑中间件几分钟就能搭好一套环境。这里有个实际经验分享本地开发环境最好用 Docker Compose 统一管理而不是一条条docker run因为 Compose 文件能版本化团队新成员拉下来一个docker-compose up -d就搞定整个环境。一个典型的开发环境docker-compose.yml大概是这样的version: 3.8 services: mysql: image: mysql:8.0 container_name: dev-mysql environment: MYSQL_ROOT_PASSWORD: root123 MYSQL_DATABASE: testdb ports: - 3306:3306 volumes: - ./data/mysql:/var/lib/mysql redis: image: redis:7 container_name: dev-redis ports: - 6379:6379 nginx: image: nginx:1.25 container_name: dev-nginx ports: - 80:80 volumes: - ./nginx/conf.d:/etc/nginx/conf.d - ./nginx/html:/usr/share/nginx/html这个文件定义了三个服务一条命令启动一条命令停止不会污染宿主机环境也不用手动记各种配置参数。5.2 场景二单节点 K8s 跑中小型微服务如果服务数量到了十几个但达不到上大规模集群的程度单节点 K8s 是一个性价比很高的选择。我比较推荐 k3s它是 Rancher 出品的轻量级 K8s 发行版把 etcd、apiserver、scheduler 等组件打包成一个二进制文件内存占用比完整版 K8s 小很多。安装只需要一条命令curl -sfL https://get.k3s.io | sh -装完后可以查看集群状态kubectl get node kubectl get pods -A在单节点 K8s 上跑微服务几乎不需要考虑调度、跨节点网络这些问题YAML 写起来更简单Pod 崩溃后重建、滚动发布这些能力都保留了。对于管理一套若依微服务或者内部管理系统完全够用。5.3 场景三高可用集群与监控、GPU 支持生产环境如果要上 K8s优先考虑三个问题高可用、监控、证书周期管理。高可用方面三台 master 节点加三台 node 节点是比较常见的配置。master 前挂负载均衡器HAProxy、Keepalived、云厂商的 SLBapiserver 地址配置成域名。etcd 在这种部署方式下可能是独立集群也可能是嵌在 master 节点里取决于安装方式。节点角色也有讲究master 节点通常会加污点Taint避免业务 Pod 被调度上去把所有资源留给 etcd 和控制平面组件。监控方面Prometheus Grafana 是事实标准。可以通过 kube-prometheus-stack 这个 Helm Chart 一条命令部署全套监控Prometheus 采集指标、Grafana 展示面板、Alertmanager 发告警。需要注意的坑是kube-state-metrics 和 node-exporter 的资源请求要提前规划好Pod 多了以后Prometheus 本身占用的内存也会涨得很快。GPU 支持是很多 AI 团队关注的点。K8s 原生不支持 GPU 调度需要安装 NVIDIA 的 device plugin 组件。装了之后你可以在 Pod 的 resources 里声明nvidia.com/gpu: 1Kubelet 会把这个 Pod 调度到有 GPU 的节点上并自动挂载驱动和 CUDA 库。实际配置时还要在节点上装好 NVIDIA 驱动和 nvidia-container-toolkit环境对不上会非常折腾。证书管理是另一个容易踩坑的地方。K8s 集群内部各组件通信使用 TLS 证书默认有效期一年。如果没做自动化证书过期后整个集群会突然“失联”。生产环境建议配置自动续签机制或者定期用一条命令手动滚动更新所有证书kubeadm certs renew all然后重启相关组件让新证书生效。但是注意基本每隔一年都要处理一次所以自动化很重要。一个常见做法是在 cron 里定期执行续签命令再检查几个关键组件的证书时间。5.4 Docker Desktop 与环境常见报错排查很多新手第一次用 Docker是在 Windows 或 Mac 上装 Docker Desktop。这个工具确实方便但报错也不少。我把最常见的几种情况整理一下virtualization support not detected未检测到虚拟化支持这个报错在 Windows 上出现的频率最高。基本原因是 CPU 虚拟化没有在 BIOS 里开启或者 Windows 的 Hyper-V / WSL2 功能没打开。排查步骤是先检查任务管理器里 CPU 的“虚拟化”是否已启用。没启用就进 BIOS 打开 Intel VT-x 或 AMD-V。启用了还报错就在 Windows 功能里把“适用于 Linux 的 Windows 子系统”和“虚拟机平台”勾选上然后重启。failed to connect to the docker api at npipe这个报错一般发生在 Docker Desktop 引擎没启动或者启动失败时。先尝试重启 Docker Desktop如果还不行检查 Windows 服务里 Docker Desktop Service 是否正常运行也可以执行wsl --shutdown然后重启 Docker Desktop。Windows 离线安装 Docker内网环境没有外网可以下载 Docker Desktop 安装包在能联网的机器上导出镜像为 tar 文件拷贝到内网后用docker load -i导入。注意内网拉取镜像时要配置私有镜像仓库或者在 Docker Daemon 的registry-mirrors中指向内网仓库地址。Linux 下安装 DockerUbuntu 和 CentOS 的官方文档给了标准安装方法但我建议配置阿里云或者中科大镜像源否则国内网络环境下拉取 Docker 官方源的包可能很慢。安装完后记得把当前用户加入 docker 组否则每次执行 docker 命令都要加 sudosudo usermod -aG docker $USER5.5 常见问题速查表问题原因解决方法容器启动后立即退出前台进程退出检查 CMD/ENTRYPOINT确保进程在前台运行镜像拉取超时网络问题或镜像源慢配置镜像加速器或私有仓库Pod 一直 Pending资源不足或调度失败kubectl describe pod查看事件检查节点资源Pod 反复 CrashLoopBackOff应用启动报错查看日志kubectl logs检查环境变量和配置节点 NotReadykubelet 异常检查 kubelet 服务状态、磁盘空间、Docker/containerd 状态容器内无法访问外网DNS 或网络插件问题检查 CoreDNS 状态和网络插件Calico/Flannel证书过期导致 apiserver 报错证书未续期执行kubeadm certs renew all并重启组件Service 无法跨节点访问kube-proxy 或网络插件异常检查 kube-proxy 的 iptables/IPVS 规则和节点网络Volume 无法挂载PV/PVC 配置不一致确认 storageClass、accessModes 和路径正确6. 工具选型与部署方案建议6.1 主流 K8s 部署方式对比不同环境、不同团队规模K8s 的部署方式差别很大。简单对比一下几种方案方案适用场景优点缺点minikube本地学习一条命令启动单节点集群不适合生产kind本地开发、CI 测试用 Docker 容器跑 K8s速度快网络性能有限k3s边缘计算、单节点生产资源占用小安装简单生态组件略少kubeadm生产集群官方工具可控性强高可用配置要手动搭KubeKey生产集群快速部署自动化程度高支持高可用社区资料相对少云厂商托管ACK/TKE/EKS不想维护 master 的团队控制平面免运维升级简单费用较高绑定云厂商我的建议是本地学习优先 minikube 或 kind小团队生产环境且资源有限k3s 是很务实的选择需要完整生产高可用集群有运维能力就选 kubeadm想省事可以试 KubeKey如果预算充足直接用云厂商的托管版 K8s 是最省心的毕竟自己维护 etcd 和三台 master 的工作量真不小。6.2 证书过期和集群长期运维的排障心得在实际维护 K8s 集群的过程中我踩过最惨的一个坑就是证书过期。当时有一段时间没登录集群突然发现kubectl命令全部报证书有效性错误排查了半天才反应过来是 apiserver 的证书过期。好在服务还在跑因为组件间的连接还保持着但任何新请求都无法处理。后来我把证书检查写进了日常巡检脚本每个月执行一次kubeadm certs check-expiration同时配合定时任务自动续签证书并且重启相关组件。这里有个注意点续签完证书需要重启 kube-apiserver、kube-controller-manager、kube-scheduler 这些控制平面组件才能让新证书生效。如果是多 master 集群要逐台操作避免全部同时重启导致集群不可用。另外一个容易被忽略的运维经验是etcd 的定期备份。K8s 集群的数据库存在 etcd 里一旦数据损坏没有备份等于一切重建。我一般建议每天把 etcd 快照备份到对象存储保留最近 30 天。备份一条命令就能完成ETCDCTL_API3 etcdctl --endpointshttps://127.0.0.1:2379 \ --cacert/etc/kubernetes/pki/etcd/ca.crt \ --cert/etc/kubernetes/pki/etcd/server.crt \ --key/etc/kubernetes/pki/etcd/server.key \ snapshot save /backup/etcd-snapshot-$(date %Y%m%d).db6.3 GPU 支持与 AI 场景部署补充如果要在 K8s 上跑 AI 训练或推理任务需要额外配置 GPU 支持。前面提到要装 NVIDIA device plugin现在更推荐用 GPU Operator 这套方案它会自动处理驱动、container runtime、device plugin 的安装和升级。配置好 GPU 之后工作负载的 YAML 里增加资源声明resources: limits: nvidia.com/gpu: 1调度器会识别这个资源。要注意的是如果节点有多张 GPU默认情况下每个 Pod 只能绑定一张如果需要整卡独占、显存共享这类配置要结合 Node 的标签和污点做更细粒度的调度。6.4 若依微服务迁移到 K8s 的经验复盘我前面提到过帮一个团队把若依微服务全家桶迁移到单节点 K8s这里复盘一下完整流程供有类似需求的朋友参考。若依微服务的典型组成是Nacos注册中心和配置中心、Gateway网关、若干业务服务比如系统管理、定时任务、文件服务通常还需要 MySQL 和 Redis 作为基础中间件。迁移步骤构建镜像为每个服务编写 Dockerfile使用mvn package打出 jar 包再打入镜像。基础镜像可以选择eclipse-temurin:8-jre这类精简 JRE 镜像比完整 JDK 镜像小很多。准备中间件MySQL 和 Redis 不急着容器化或者上 K8s前期可以继续用现有的通过 Service 或者直接配置外部地址访问。部署 NacosNacos 本身是有状态服务需要配置持久化存储。如果在单节点 K8s 上跑用 hostPath 类的 PV 就够了保证 Nacos 重启后配置不丢。部署业务服务每个服务写一个 Deployment Service 的 YAML 文件从 Nacos 拉取配置健康检查配置成/actuator/health。配置 Ingress把 Gateway 的 Service 通过 Ingress 暴露到集群外通过域名访问整套系统。验证和切换逐步把流量从旧环境切到新集群观察日志和指标稳定后再下线旧环境。这个过程踩了几个小坑。第一个是 Nacos 用的数据库连接如果 MySQL 跑在宿主机上容器内访问宿主机的localhost是访问不通的要改成访问宿主机网卡 IP。第二个是时区问题基础镜像默认是 UTC 时区数据库里的时间和实际差 8 小时我在 Dockerfile 里加了ENV TZAsia/Shanghai解决。第三个是内存限制JVM 默认按宿主机内存配置堆大小容器里如果不设置-Xmx很容易因为内存超限被 K8s 杀掉我在启动命令里显式指定了 JVM 参数。7. 写在最后我的一些实际体会如果你问我 Docker 和 K8s 到底值不值得学我的回答是Docker 是必学项K8s 看需求。Docker 能解决环境一致性和交付标准化的问题这个能力在任何规模的团队都有价值。K8s 则是一个“能力越大、责任越大”的平台它能帮你管理大规模容器集群但也要求团队有相应的维护能力。最后分享一个小技巧刚开始学 K8s 的时候不要一上来就背概念直接在本地用 Docker Desktop 自带的 K8s 或者 minikube 起一个集群把常见的 Deployment、Service、Ingress 都亲手部署一遍遇到问题再回头查文档比从头到尾读一遍文档效率高得多。容器化这条路动手踩坑永远是学的最快的办法。