新闻详情

新闻详情

首页 / 资讯中心 / 详情

Docker与Kubernetes:从容器化基础到集群编排的实践总结

发布时间:2026/9/29 4:37:05来源:尧图网络
Docker与Kubernetes:从容器化基础到集群编排的实践总结
Docker 和 Kubernetes 这两个词这几年几乎成了后端开发和运维的“标配话题”。但说实话我见过不少人把两者混在一起来学结果 Docker 刚会拉镜像跑容器就被 K8s 的一堆概念砸晕也有人反过来先在 K8s 里折腾 Pod 调度却对镜像分层、容器生命周期毫无概念出了问题无从下手。这篇文章就把 Docker 和 Kubernetes 放在一起做一次系统性的总结说清楚它们各自解决什么问题、怎么配合使用、常见的坑有哪些适合刚接触容器化、打算把现有项目迁到 K8s 的同学也适合想把自己零散的知识梳理一遍的人。1. 先说结论Docker 解决“怎么装”K8s 解决“怎么管”1.1 从一次部署事故谈起我曾经帮一个朋友排查线上故障他的服务在单台服务器上用 Docker 跑得好好的后来业务量上来要把服务扩容到三台机器。问题立刻来了三台机器上的容器各自为政配置文件不统一版本偶尔不一致负载均衡要手动改 IP某个容器挂了也不会自动重启到别的机器上。他当时第一反应是“Docker 不行”但真正的问题不是 Docker而是缺少一层“编排调度”的东西。这个场景特别典型。Docker 本身解决的是“应用怎么打包、怎么运行”的问题它把代码、运行时、系统库、配置统统装进一个镜像让同一套东西在任何 Linux 机器上表现一致。但当你有多台机器、多个服务、需要弹性伸缩和高可用的时候Docker 单机命令就不够用了。这时候 Kubernetes 登场它解决的是“一堆容器在多台机器上怎么组织、怎么调度、怎么自愈、怎么暴露服务”的问题。1.2 Docker 的核心价值镜像与容器Docker 的核心创新可以浓缩成两个词镜像Image和容器Container。镜像是一个只读的模板里面包含应用运行所需的完整文件系统。比如一个 MySQL 镜像里面有 MySQL 的二进制文件、依赖库、默认配置、启动脚本。你可以把镜像理解成“安装光盘”容器则是用这张光盘启动出来的“运行实例”。同一台机器上同一个镜像可以启动多个容器每个容器相互隔离拥有独立的文件系统、进程空间和网络栈。这里最容易被忽视的是“分层存储”。Docker 镜像不是一个大文件而是由一层层只读层叠加而成。比如基于 Ubuntu 的镜像先有系统层然后加上 JDK 层再加上应用层。每一层都可以被多个镜像复用所以拉取镜像时如果本地已经有了公共层就只需要下载新增的部分。这也是为什么 Docker 镜像能比传统虚拟机镜像小很多、启动快很多的原因。1.3 Kubernetes 的核心价值声明式编排与自愈Kubernetes下称 K8s是一个容器编排平台它最大的特点不是“能跑容器”而是“按照你声明的期望状态来维护容器”。什么叫声明式你不需要告诉 K8s“先启动 3 个 Pod等 5 分钟再检查不行就重启”。你只需要写一个 YAML声明“我要 3 个副本镜像是 nginx:1.25端口是 80”。K8s 的控制器会持续对比当前状态和期望状态如果当前只有 2 个副本它就补一个如果某个 Pod 挂了它重新调度一个新的如果镜像版本变了它就滚动更新。这种“只管要什么不管怎么做”的思想是 K8s 和传统脚本运维最本质的区别。自愈能力也值得单独说。K8s 里的 Pod 是调度和运行的最小单元但 Pod 本身可能随时被杀掉。真正保证“应用不中断”的是工作负载控制器比如 Deployment。Deployment 会确保指定数量的 Pod 一直处于 Running 状态节点宕机后它会在其他节点重新创建 Pod。这种能力用传统 shell 脚本很难做到足够健壮而 K8s 把它做成了平台的内建能力。1.4 两者的关系不是替代而是分工很多人以为学了 Docker 就不需要 K8s或者学了 K8s 就不用管 Docker 了其实不是。K8s 的节点上运行容器时默认使用的容器运行时就是 containerd——它本来就是 Docker 公司捐给 CNCF 的容器运行时核心。Docker 提供的是完整的开发者工具链构建镜像、本地运行、调试K8s 提供的是生产环境的多机编排能力。两者是上下游关系Docker 负责“把应用装进盒子”K8s 负责“把盒子放到合适的架子上并持续维护”。举个例子你在本地用docker build构建好镜像推到镜像仓库然后在 K8s 集群里写一个 Deployment引用这个镜像。K8s 的 kubelet 会在节点上通过 containerd 拉取镜像并启动容器。所以即便你只在 K8s 环境里工作也需要理解镜像怎么构建、容器怎么运行否则很难排查镜像层的问题。2. Docker 篇常用概念与落地操作2.1 镜像、容器、仓库三个最基础的概念先理清三个词的关系镜像是一个静态文件容器是镜像的运行态仓库是存放镜像的地方。日常开发中你大概率会这样做写 Dockerfile 描述镜像内容执行docker build构建镜像把镜像docker push到仓库在服务器上docker pull拉取镜像用docker run启动容器。这里有一个我刚开始总记混的地方docker run实际上等于“创建容器 启动容器”。如果你只想临时验证一下镜像能不能跑可以用docker run --rm这样容器退出后会自动删除不会留下垃圾容器。而docker start是启动一个已经存在的容器docker exec是进入一个正在运行的容器执行命令三者别搞混。镜像仓库也讲究私有的必要性。虽然公共仓库很方便但生产环境必须使用私有仓库原因很简单镜像里可能包含业务代码、密钥、内部配置。早期很多团队自己搭 Harbor后来直接用云厂商的镜像服务。私有仓库还有一个好处——内网拉取快不占用公网带宽。2.2 写一个能用的 Dockerfile带多阶段构建示例Dockerfile 是镜像的“配方”但新手写 Dockerfile 最常见的问题是“能用”和“好用”差距太大。我见过很多项目把 JDK、Maven、代码全部打进一个镜像镜像体积好几个 GB构建一次能去喝杯咖啡。正确的做法是多阶段构建先用一个带编译工具的基础镜像编译代码再用一个精简的运行镜像只复制产物。下面是一个 Java 项目的例子# 第一阶段编译 FROM maven:3.8-openjdk-11 AS builder WORKDIR /app COPY pom.xml . RUN mvn dependency:go-offline COPY src ./src RUN mvn clean package -DskipTests # 第二阶段运行 FROM openjdk:11-jre-slim WORKDIR /app COPY --frombuilder /app/target/myapp.jar . EXPOSE 8080 CMD [java, -jar, myapp.jar]第一阶段的镜像可能超过 700MB但第二阶段只有 JRE 和 jar 包加起来不到 200MB。构建完成后第一阶段会自动成为中间层最终镜像只保留第二阶段的内容。这里有几个细节你要注意首先COPY pom.xml .和RUN mvn dependency:go-offline这两步是为了利用 Docker 层缓存。只要 pom.xml 没变后续构建不会重新下载依赖。其次CMD和ENTRYPOINT有区别CMD可以被docker run后面的命令覆盖ENTRYPOINT则很难覆盖。对于需要接受参数的容器建议用ENTRYPOINT指定主程序用CMD给默认参数。最后尽量把EXPOSE当成“文档”看待它并不真的发布端口真正发布端口是在docker run -p或者 Compose 文件里做的。2.3 数据卷与网络最容易忽略的细节容器是“用完之后即弃”的设计所以数据必须放在容器外面。最常用的方式就是数据卷Volume和绑定挂载Bind Mount。数据卷由 Docker 管理存放在/var/lib/docker/volumes/下适合存放数据库数据文件。绑定挂载则是把宿主机目录直接映射进容器适合开发时热加载代码。比如docker run -d -p 3306:3306 \ -v mysql_data:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD123456 \ mysql:8.0这样 MySQL 的数据写进mysql_data卷里容器删了重建数据还在。网络部分Docker 默认有三种网络模式bridge、host、none。bridge是默认模式容器通过虚拟网桥和宿主机通信适合多个容器之间的隔离与互通。host模式直接共享宿主机网络性能好但端口会直接占用宿主机的端口。none则完全隔离一般用于特殊安全需求。自定义 bridge 网络是生产环境很好的习惯。比如你用docker network create mynet建一个网络然后让 MySQL 容器和业务容器都加入这个网络业务容器里就可以直接用mysql这个容器名作为主机名连接数据库不需要记 IP。2.4 Docker Compose单机多容器编排的实用方案如果你只需要在一台机器上跑多个容器K8s 有点重Docker Compose 是恰到好处。Compose 用 YAML 描述服务、网络、卷一条命令拉起整套环境。举个例子一个最常见的 Web 服务加 Redisversion: 3.8 services: web: build: . ports: - 8080:8080 depends_on: - redis environment: - REDIS_ADDRredis:6379 redis: image: redis:7-alpine volumes: - redis_data:/data volumes: redis_data:这里的depends_on只控制启动顺序不保证 Redis 已经可以接受连接。所以应用代码里要做重试。另外version字段在新版 Docker Compose 中已经废弃可以不写写了也只会被忽略。Compose 真正好用的地方在于docker compose up -d --build一条命令完成构建和启动docker compose logs -f查看所有服务的日志docker compose down清理资源。很多人在单机部署 MySQL 主从、Redis 主从时也是用 Compose 先搭一套验证逻辑后再迁移到 K8s。这是很稳的学习路径因为 Compose 的网络模型和 K8s 的 Service 发现有不少相似之处转了之后理解会很快。3. Kubernetes 篇从 Pod 到生产集群3.1 架构速览控制平面与工作节点K8s 集群分为控制平面Control Plane和工作节点Worker Node。控制平面负责做出全局决策比如调度哪个 Pod 到哪个节点工作节点负责实际运行 Pod。控制平面上的关键组件有四个kube-apiserver所有请求的入口也是唯一直接操作 etcd 的组件etcd保存集群所有状态一个分布式键值数据库kube-scheduler负责为待调度的 Pod 选择合适的节点kube-controller-manager运行各种控制器比如节点控制器、副本控制器。工作节点上的核心组件是 kubelet 和 kube-proxy。kubelet 负责接收控制平面下发的 Pod 规格调用容器运行时如 containerd真正启动容器kube-proxy 负责维护节点的网络规则实现 Service 的流量转发。理解架构最重要的是理解“控制平面不会直接操作容器”。你执行的kubectl create请求到达 apiserver 后会写入 etcdscheduler 观察到有未调度的 Pod就会为它选择节点并把绑定信息写回 etcd节点上的 kubelet 通过 apiserver 的 watch 机制发现这个 Pod 被调度到自己身上然后才去创建容器。这个过程完全是指令驱动、异步执行的所以分析问题时不能只看组件状态还要看事件和日志。3.2 工作负载Deployment、StatefulSet、DaemonSet、JobDeployment 是最常用的工作负载适用于无状态服务。它负责管理 ReplicaSetReplicaSet 又负责管理 Pod 的副本数量。升级时 Deployment 会滚动更新默认情况下先启动新 Pod等新 Pod 就绪后再删除旧 Pod。StatefulSet 用于有状态应用比如 MySQL、Redis、Elasticsearch。它和 Deployment 最大的区别是 Pod 有稳定的网络标识如mysql-0、mysql-1和稳定的存储。每一个 Pod 重新调度后主机名、网络标识都不变对应的 PVC 也会重新绑定。这解决了有状态应用最棘手的“身份识别”问题。DaemonSet 保证每个节点上恰好运行一个指定 Pod适合日志采集比如 Filebeat、监控探针比如 Prometheus Node Exporter、网络插件比如 Calico。当新节点加入集群时DaemonSet 自动在新节点创建 Pod节点删除Pod 也一并清理。Job 和 CronJob 则是任务型负载。Job 执行一次就结束适合批处理CronJob 按照 cron 表达式定时执行适合数据清理、报表生成。这里要说一个我踩过的坑Job 里如果容器主进程退出码是 0Job 才视为完成如果退出码非 0Job 会按backoffLimit重试默认 6 次。所以写 Job 镜像时脚本里务必捕获异常并设置正确的退出码否则就算逻辑报错了Job 也会显示 Completed。3.3 服务暴露Service、Ingress 和 DNSPod 的 IP 是动态的每次调度都可能变化。所以 K8s 用 Service 为一组 Pod 提供稳定的访问入口。Service 通过 selector 选择 Pod然后自动维护 Endpoints 列表。创建 Service 后集群内部的 DNS 会为它生成一个域名比如my-service.default.svc.cluster.local其他 Pod 可以通过这个域名访问它。Service 的类型有 ClusterIP、NodePort、LoadBalancer。ClusterIP 只在集群内部可访问是默认类型NodePort 会在每个节点上开一个端口30000-32767然后转发到 Service适合测试和简单场景LoadBalancer 则会调用云厂商的负载均衡服务把外部流量引入集群适合生产。如果要按域名、路径做路由就得用 Ingress。Ingress 不是一种 Service 类型而是一组 API 对象需要部署 Ingress Controller比如 Nginx Ingress、Traefik来真正实现转发。Ingress 的典型配置apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: web-ingress spec: rules: - host: app.example.com http: paths: - path: / pathType: Prefix backend: service: name: web-service port: number: 80有了 Ingress你就可以用同一个负载均衡入口承载多个域名和多个服务还能在这个入口层统一配置 TLS 证书、限流、灰度等能力。这里要提醒一下Ingress Controller 本身也是一个 Deployment要被外部访问通常也得有个 Service一般是 LoadBalancer 或 NodePort。所以调试 Ingress 问题时先确认 Controller 的 Pod 是否 Running再检查 Ingress 规则是否被 Controller 加载。3.4 配置与存储ConfigMap、Secret、PV/PVC不要把配置写死在镜像里。镜像一旦构建运行时改配置很麻烦而且敏感信息留在镜像里也不安全。K8s 提供了 ConfigMap 和 Secret 来管理配置。ConfigMap 适合保存非敏感配置比如 nginx.conf、环境变量、应用参数。Secret 适合保存敏感信息比如数据库密码、API Key。它们的使用方式都一样要么通过env把某个 key 注入环境变量要么通过volumes把整个配置挂载成文件。区别在于 Secret 存的是 base64 编码值并且可以对接外部密钥管理系统比如云厂商的 KMS。存储部分容器里的文件系统是临时的Pod 重建数据就没了。K8s 的持久化存储方案是 PVPersistentVolume和 PVCPersistentVolumeClaim。PV 是集群里的存储资源由管理员创建或通过 StorageClass 动态供给PVC 是用户对存储的请求。Pod 声明使用某个 PVCkubelet 就会把对应的 PV 挂载进容器。实际使用中多数人不会手动创建 PV而是借助 StorageClass。比如云服务器上配置一个storageClassName: alicloud-diskPVC 创建时云厂商的 CSI 插件会自动创建一块云盘并绑定到 PVC。这样做的好处是无需预先分配存储按需创建。坏处是如果你删除了 PVC很多 StorageClass 的策略会同时删除云盘数据会一起没了所以删除前一定要确认回收策略是Retain还是Delete。3.5 调度与资源管理requests/limits 为什么重要新手部署 Pod 经常会漏掉资源限制或者随便填一个resources.limits。这在测试环境没什么感觉一上生产就会引发连锁反应。requests告诉调度器“这个 Pod 至少需要这么多资源”调度器据此为 Pod 选择合适的节点。limits是硬上限如果容器使用的 CPU 超过 limits会被限制如果内存超过 limits容器可能被 OOM Kill。这里有个容易误解的点CPU 是可压缩资源limits 限制的是 CPU 时间内存是不可压缩资源一旦超过 limits内核只能杀进程。举一个实际见过的案例某个节点有 8G 内存管理员在上面部署了 10 个 Pod每个 Pod 的requests.memory都写了 2G。调度器看总 requests 已经超过节点容量后续 Pod 就会一直 Pending只会显示内存压力。解决方法不是盲目加节点而是合理设置 requests。比如应用实测峰值 500M你就写requests: 256Milimits: 1Gi而不是统一写 2G。生产环境建议配合 HPAHorizontal Pod Autoscaler根据 CPU 或自定义指标动态调整副本数。4. 从 Docker 迁移到 Kubernetes 的实操路径4.1 评估现有 Docker 应用在把一个docker-compose.yml改成 K8s 配置之前先给应用分个类无状态还是有状态内部服务还是外部访问是否需要固定的网络标识。大部分 Web 应用、API 服务都是无状态的可以直接用 Deployment Service 搞定。数据库、消息队列这类有状态服务优先考虑使用云厂商的托管服务而不是贸然搬进 K8s。原因很简单在 K8s 里跑好 MySQL 主从需要大量经验和运维成本如果业务并不是特别需要“数据库和业务容器同集群调度”托管数据库是更省心的选择。对于有状态但必须留在集群里的服务比如 Redis、Elasticsearch建议先用官方 Operator如 Redis Operator、Elastic Cloud Operator来部署。Operator 封装了备份、扩容、故障恢复等复杂逻辑比自己写 StatefulSet 可靠得多。4.2 把 docker-compose 翻译成 K8s 资源这里给你一个快速对照表Docker ComposeKubernetesservicesDeployment / Serviceimageimage (在 Deployment 里)environmentenv (在 Deployment 里)volumesPVC 或 emptyDirnetworksService 自动提供 DNS 发现portsService.portsdepends_on不需要用 readinessProbe 代替restart: always不需要Deployment 自动重启翻译时最容易忽略的是“依赖关系”。Compose 里depends_on只是启动顺序K8s 里不需要这个字段因为 Service 的名字在 DNS 里始终存在即使后端 Pod 还没就绪前端也能解析到域名。这时候需要做的是在 Deployment 里配置readinessProbe和livenessProbe让流量只打到就绪的 Pod。探针配置是 K8s 里最容易被轻视但最影响稳定性的东西。livenessProbe如果配置不好可能导致容器频繁重启readinessProbe如果没配置请求可能被转发到还在启动中的 Pod。我一般推荐这样写readinessProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 10 periodSeconds: 5 timeoutSeconds: 2 failureThreshold: 3initialDelaySeconds要大于应用实际启动时间否则应用刚开始准备就绪检查就失败会被连续标记为未就绪。这个值需要根据日志反复调整。4.3 本地开发minikube/kind 快速验证如果你只用云上集群调试每次改动都要推送镜像、拉取镜像效率很低。本地跑 K8s 有两条路minikube 和 kind。minikube 适合初学者它帮你创建单节点集群支持各种驱动也自带一些插件。kind 是基于 Docker 的轻量方案它把整个 K8s 集群跑在 Docker 容器里启动快资源占用小适合 CI/CD 中做集成测试。本地开发时还有一个效率技巧不要在代码改动后立即docker build再推到仓库可以用ctr或者其他工具直接导入本地镜像到集群或者设置镜像拉取策略为IfNotPresent。不过这个技巧容易踩坑因为不同容器运行时的本地镜像命名方式不同我更推荐你直接用云厂商的镜像仓库在本地构建后推送集群里拉取。整个过程自动化后并不慢。4.4 上线前必做的四件事第一给命名空间和资源打上标签并用kubectl get all -n namespace验证所有资源都在预期范围内。第二确认所有 Deployment 都配置了资源请求和限制并且设置了探针。第三检查网络策略确认哪些服务可以被外部访问哪些只能在集群内部访问。第四把日志和监控接好至少要有 Prometheus Grafana以及日志采集方案。没有监控就上生产等于闭着眼睛开车。上线时建议用命名空间隔离环境比如dev、staging、prod。不同环境使用相同镜像通过 ConfigMap 区分配置。这样能最大程度避免“测试环境没问题生产环境就爆炸”的经典问题。5. 常见问题与排查技巧5.1 Docker 常见问题速查问题 1Docker Desktop 在 Windows 上启动失败提示 virtualization support not detected这是 Windows 上最常遇到的问题。原因通常是 BIOS 里没有开启虚拟化或者 Hyper-V 功能没启用。解决办法是进入 BIOS 开启 Intel VT-x 或 AMD SVM然后在“启用或关闭 Windows 功能”里勾选“虚拟机平台”和“适用于 Linux 的 Windows 子系统”。如果你用的是 Windows 11Docker Desktop 依赖 WSL2还需要执行wsl --update更新内核。修改 BIOS 后记得重启。问题 2docker命令提示 permission denied默认情况下 Docker 守护进程需要 root 权限。解决办法是把当前用户加入 docker 组sudo usermod -aG docker $USER newgrp docker注意加组之后需要重新登录或者执行newgrp docker才能生效。生产服务器上我不建议这么做尽量通过 sudo 或者使用 root 用户管理。问题 3容器里网络不通如果你在容器里访问宿主机服务失败先弄清楚是容器访问外部还是外部访问容器。容器访问宿主机可以用host.docker.internal在 Mac/Windows 上有效Linux 上需要加--add-host。多个容器之间互相访问确认它们是否在同一网络。如果不在同一个自定义 bridge 网络里容器名解析不通只能通过 IP 访问。问题 4镜像下载慢这个问题在国内外都很常见。最有效的办法是配置镜像加速器。Docker Desktop 中可以在 Settings - Docker Engine 里添加registry-mirrors配置。国内云服务商基本都提供加速地址选自己云厂商给出的地址即可。注意加速器只对公共仓库生效私有仓库不经过加速器。问题 5failed to connect to the docker api at npipe:////./pipe/dockerDesktopLinuxEngine这是 Windows Docker 常见错误通常是因为 Docker Desktop 引擎还没启动完成或者 WSL2 内核版本过旧。先看托盘图标是否变绿再执行wsl --shutdown后重启 Docker Desktop。如果还不行执行netsh winsock reset并重启电脑。5.2 Kubernetes 常见问题速查问题 1Pod 一直 PendingPending表示 Pod 没有被调度到节点上。用kubectl describe pod pod-name查看 Events最常见的两个原因是节点资源不足或者 PVC 没有绑定。资源不足时看requests是否设置过大PVC 未绑定看 StorageClass 是否可用。问题 2Pod 一直 ImagePullBackOff说明镜像拉取失败或镜像不存在。先检查镜像名和 tag 是否正确然后看节点上的容器运行时能不能拉取到私有仓库镜像。如果是私有仓库需要创建imagePullSecrets并在 Deployment 里引用。还有一个隐藏坑镜像 tag 是latest时如果本地缓存了旧版本且没有重新拉取策略可能一直在跑旧镜像。建议给镜像打固定 tag比如myapp:1.0.0不要用latest。问题 3Pod 反复重启状态 CrashLoopBackOffCrashLoopBackOff说明容器启动后很快就崩溃K8s 正在按退避策略重试。用kubectl logs看容器输出如果日志为空加上--previous看上一次崩溃的日志。最常见的原因是启动命令报错、配置文件缺失、环境变量没注入。如果日志里显示 connection refused大概率是依赖服务还没就绪。问题 4服务之间域名解析失败K8s 集群内的 DNS 一般由 CoreDNS 提供。如果某个服务域名解析不了先检查 Service 是否存在名字是否拼对然后进入其他容器用nslookup验证。如果 CoreDNS Pod 本身不正常用kubectl get pods -n kube-system -l k8s-appkube-dns查看状态。还有一种情况部署使用hostNetwork或者服务端口冲突导致 DNS 请求被拦截。问题 5修改了 Deployment 的镜像但 Pod 没有更新Deployment 更新触发条件是 spec 里的字段变化。如果你只改了env里某个值使用kubectl apply应该能触发滚动更新。如果你改的是 ConfigMap 里的内容而 Deployment 通过环境变量引用那 ConfigMap 更新不会自动重启 Pod。解决方法是执行kubectl rollout restart deployment/name或者给 Pod 模板加一个类似checksum/config的注解来自动触发滚动更新。5.3 通用排查思路不管是 Docker 还是 K8s排查问题都要遵循“从底层到上层”的顺序。第一层看资源是否存在docker ps -a或kubectl get all -n ns。第二层看事件docker inspect或kubectl describe。第三层看日志容器标准输出、应用日志、系统日志。第四层看网络连通性、DNS、端口。很多人一遇到问题就改代码重启其实大多数问题都是配置问题先把describe里的 Events 看完再动手会省很多时间。专家建议写一个排障流程脚本把常用的get、describe、logs组合成一个函数比如kdebug pod一次输出 Pod 状态、Events、最近日志、所在节点信息。长期下来你的排查速度会快很多。6. 学习路径与避坑心得先把 Docker 学到能独立构建镜像、管理容器、编排 Compose再进入 K8s。K8s 的学习不要一上来就是生产集群要有耐心做实验。我推荐的学习顺序是用 Docker 跑通一个 Web 服务 数据库用 Compose 一键拉起一整套环境用 minikube 部署一个应用理解 Deployment、Service手动模拟一次 Pod 删除观察 Deployment 自动重建加入 Ingress 和 ConfigMap再把你的应用从 Compose 迁移到 K8s。这中间最容易放弃的是第 3 步因为概念一下子变多。我的经验是不要试图一次看懂所有概念先照着 YAML 模板改几个字段让它跑起来再倒回去看文档理解会快很多。踩坑方面有几点很痛的经验。第一个是资源限制刚开始为了省事所有 Deployment 都不写 resources结果某个服务内存泄漏把整个节点拖垮所有 Pod 都被 OOM Kill。后来我要求所有服务必须写 requests 和 limits宁可多申请一点也不能裸奔。第二个是探针曾有一个服务只在启动时加载一个大文件readinessProbe 的 initialDelaySeconds 设短了导致流量还没准备好就打进来报错率飙升。第三个是镜像 Tag生产环境用latest是个定时炸弹团队里只要有一个人 push 了latest线上就可能莫名其妙变版本。现在我所有交付镜像都是带有 Git commit 短哈希的 tag比如myapp:7f3a2b1。还有一个容易被忽略的习惯所有资源都应该用kubectl apply而不要用kubectl run、kubectl create之类的命令直接生成资源。因为apply是声明式操作你的 YAML 就是唯一事实来源后续修改可以方便地通过git diff追踪。用命令直接创建的资源没有持久化的 YAML时间一长根本不知道集群里有什么。最后说一点个人体会容器化改造不是一个纯技术问题它涉及团队协作方式的变化。Docker 让你能在本地复现生产环境K8s 让运维和开发在同一个平台上对“期望状态”达成一致。这两个工具真正成熟的表现不是“会用命令”而是当你写的 YAML 被 apply 之后你心里清楚它会怎样运行、会怎样失败、从哪里看日志、怎么恢复。先把 Docker 的底子打好再学 K8s 的编排思想这条路虽长但每一步都走得稳。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

AI智能体与多AI协作实战:从训练方法到工具选型 2026/9/29 4:37:01

AI智能体与多AI协作实战:从训练方法到工具选型

今天打开各种群,发现讨论最多的还是智能体、编程辅助和各种“AI副业”的消息。其实这类信息每天都有,但真正值得记录的,往往是那些能落地、能改变工作方式的小细节。我干脆把今天看到、试到手的东西整理成一份日报式的清单,聊聊几…

阅读更多 →
Docker 容器连不上外网、访问不了宿主机、端口映射不生效?网络三连坑逐个拆 2026/9/29 4:36:55

Docker 容器连不上外网、访问不了宿主机、端口映射不生效?网络三连坑逐个拆

Docker 网络是新手最容易懵的部分,报错又特别分散:容器里 ping baidu.com 不通、应用连宿主机上的 MySQL 报 Connection refused、明明 -p 8080:80 了浏览器却打不开。这三个问题看起来不相干,其实都落在 Docker 网络模型上。这篇把容器网络最…

阅读更多 →
Nginx 高可用:Keepalived 主备切换详解 2026/9/29 4:36:55

Nginx 高可用:Keepalived 主备切换详解

安装 keepalived 安装 keepalived 的安装包:https://mirrors.huaweicloud.com/home 下搜索 keepalived选择版本下载:keepalived-2.3.4.tar.gz,上传至 /opt 目录下解压:tar -zxvf keepalived-2.3.4.tar.gz执行安装的步骤&#xff…

阅读更多 →
小白程序员必看:FDE如何让AI从Demo落地到生产环境? 2026/9/29 4:36:55

小白程序员必看:FDE如何让AI从Demo落地到生产环境?

本文对比了Prompt与FDE在AI应用中的差异:Prompt解决单次对话,而FDE负责AI落地。FDE(前沿部署工程师)作为AI企业与客户间的桥梁,需懂技术、业务及流程,将AI整合进企业真实环境。FDE不同于驻场外包或售前&…

阅读更多 →
【RAG】35-RAG研究方向:未来RAG技术的潜在研究领域与TaoToken配置实践 2026/9/29 4:36:55

【RAG】35-RAG研究方向:未来RAG技术的潜在研究领域与TaoToken配置实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
Docker 容器时间差 8 小时?时区问题的四种解法与各自适用场景 2026/9/29 4:36:54

Docker 容器时间差 8 小时?时区问题的四种解法与各自适用场景

容器里 date 一看是 UTC 时间,比北京时间慢 8 小时——这大概是每个国内 Docker 用户都会撞上的问题。表现五花八门:日志时间戳对不上、定时任务凌晨跑成下午、数据库存的时间查出来差 8 小时、JWT 过期判断错乱。这篇把时区问题拆开讲:为什么…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉