资讯详情

资讯详情

从Docker到K8s:容器编排实战与LNMP集群部署解析

你们有没有遇到过这种情况用 Docker 跑起来一个 MySQL高高兴兴地测试完了想把服务迁到另一台机器上。你敲下docker run然后开始祈祷那台机器上端口没被占、数据目录路径没错、容器名没冲突、网络能连通……如果只有一台机器Docker 确实够用。但当你面前摆着 5 台、10 台、甚至几十台服务器要部署的不只是一个数据库而是一整套业务系统时Docker 那一套run/stop/rm的手工操作马上就会变成一场灾难。这时候Kubernetes简称 K8s就登场了。很多同学第一个问题是Docker 和 K8s 到底是竞争关系还是上下游关系有了 Docker为什么还要 K8s这个问题如果没想明白后面学习容器技术时很容易从一开始就走偏——两套技术混着学概念互相打架连 YAML 该写在哪个文件里都搞不清楚。这篇文章不会只给你背概念。我会从一个实际部署场景出发对比“只用 Docker”和“用 Docker K8s”两种方式讲清楚各自的定位、核心概念、适用场景再用 LNMP 架构的一次部署实验把整个流程串起来。读完你会明白Docker 解决的是“怎么把应用和环境打包运行”的问题K8s 解决的是“大量容器如何调度、管理、自愈”的问题。二者不是替代关系而是分工不同的两代人。1. 这篇文章真正要解决的问题先不急着敲命令我们花两分钟搞清楚K8s 到底补上了 Docker 的什么短板。1.1 Docker 让人惊喜也让人头疼Docker 刚流行起来时最打动人的一句话是“Build once, run anywhere”。镜像把代码、运行时、依赖、配置全部打包所以应用在任何装了 Docker 的机器上都能跑起来。这个体验对开发环境来说是革命性的——以前“在我机器上能跑”是句嘲讽现在“我有 Dockerfile”就理直气壮。但 Docker 本身解决的核心是单机问题在一台机器上把应用装进容器隔离运行。把容器导出成镜像分发出去。用 Docker Compose 管理单机上的多容器编排。一旦生产环境有多台服务器问题就来了某个容器挂了Docker 不会自动帮你把它“再拉起来”更不会换一台机器重新部署。流量大了需要扩容Docker 没有原生的“一键伸缩”能力你得自己写脚本去每台机器上docker run。多个容器分散在多台机器上时它们之间怎么互相发现IP 变了怎么办Docker 默认网络模型只覆盖单机。更新版本时你有几十个容器要滚动升级Docker 本身没有内置的“滚动更新”策略。1.2 K8s 解决的是规模化编排问题Kubernetes 的核心定位是容器编排平台。它不负责构建镜像也不直接运行容器它运行的是 Pod 中的容器但它负责调度集群里有那么多机器新容器应该放到哪台K8s 根据资源诉求、节点标签、亲和性等做决策。自愈某个容器异常退出K8s 会按照期望状态重建它。伸缩通过修改副本数或根据 CPU、内存指标自动扩缩容。服务发现与负载均衡每个 Pod 有独立的 IP但 Pod 会重建、IP 会变化。K8s 用 Service 提供稳定的访问入口在多个 Pod 之间做负载均衡。滚动更新与回滚更新 Deployment 镜像版本时可以控制一次替换多少 Pod失败时能快速回滚。形象一点说Docker 像一个能干的单兵战士把应用打包得整整齐齐K8s 像一个指挥官负责把这个战士安排到合适的位置在他倒下时立刻派人补位在敌人变多时快速增兵。1.3 什么人最需要搞懂这个问题后端 / 运维工程师业务上了多台服务器后容器化部署迟早要面对。K8s 是生产环境容器化的事实标准理解它和 Docker 的分工是学习曲线中最重要的一步。经常用 Docker 做本地开发的同学docker run、docker-compose 用的很熟但团队里一旦引入 K8s之前的经验哪些能迁移哪些不能必须弄清楚。准备 K8s 面试的读者k8s和docker区别是高频考点。不要背几句口号而是要从“单机 vs 集群”“容器 vs 编排”的角度讲清楚。读完这篇文章你会得到一个适合自己技术栈的判断当前阶段用 Docker 就够了还是应该把 K8s 纳入观察范围。2. Docker 和 K8s 的核心概念先分清谁管什么2.1 Docker 的核心抽象镜像、容器、ComposeDocker 最核心的三个概念概念通俗解释类比镜像Image一个只读模板包含运行应用所需的一切安装光盘容器Container镜像运行后的进程实例有独立的文件系统、网络和进程空间用光盘装好的电脑系统Docker Compose用 YAML 描述并启动多个容器适合单机编排一条生产线上的装配清单# 从镜像启动一个 MySQL 容器 docker run -d \ --name mysql-test \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORDroot123 \ mysql:8.0这条命令我们都很熟悉。它在单机上把 MySQL 跑起来暴露3306端口设置 root 密码。如果你只是想本地测试Docker 完全够用。所以很多人用 Docker 很久后觉得“这不挺好用的吗为什么要上一个那么复杂的 K8s”关键在于Docker 没有跨机器的抽象。你没法用docker run告诉它“把这个容器调度到 10.0.3.11 那台机器上”。2.2 K8s 的核心抽象Pod、Deployment、ServiceKubernetes 有自己的一套概念层刚开始最容易绕晕。我们先用最小集合理解它们。Pod是 K8s 最小的部署单元。一个 Pod 里可以装一个或多个容器这些容器共享网络命名空间和存储卷。为什么 K8s 不直接调度容器而是引入 Pod原因是有些应用场景里多个进程需要“紧耦合”地跑在一起比如一个日志采集 sidecar 和业务容器共享日志文件。这种情况下把它们放在同一个 Pod 里最合理。Deployment负责管理一组无状态的 Pod。你可以指定“我要 3 个副本”Deployment 会保证集群里始终有 3 个 Pod 在运行。它支持滚动更新、回滚、故障重建。Service提供稳定的访问入口。Pod 的 IP 会变但 Service 的 IP 和 DNS 名字不会。前端或其他服务访问时只需要访问 Service由 Service 把流量转发到后端的某个 Pod。用一句话总结K8s 里Docker 容器是“干活的进程”Pod 是“进程的家”Deployment 是“监工”Service 是“前台接待”。2.3 容易混淆的地方K8s 并不直接运行容器很多教程会说“K8s 直接运行容器”这个概念其实不够准确。K8s 通过容器运行时接口CRI来操作容器。过去默认的容器运行时正是 Docker通过 dockershim 适配但 K8s 其实是一个“容器无关”的编排平台它也可以使用 containerd、CRI-O 等运行时。这里不需要展开太多你只需要记住K8s 操作的粒度不是容器而是 PodPod 里的容器才是真正执行任务的进程。这也是为什么网上有那么多“k8s和docker区别”的搜索——因为两者根本不在同一个抽象层级直接对比谁更强是错误命题。3. 环境准备从一台 Ubuntu 机器开始在动手做实验之前先搭建一套可运行的环境。下面演示以 Ubuntu 22.04 为例使用 containerd 作为运行时。版本信息请以实际安装时为准这里主要演示整体思路。3.1 Docker 环境安装如果你机器上还没有 Docker先安装它# 更新软件源 sudo apt update # 安装依赖 sudo apt install -y apt-transport-https ca-certificates curl software-properties-common # 添加 Docker 官方 GPG 密钥来源以官方文档为准 curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg # 添加软件源 echo deb [arch$(dpkg --print-architecture) signed-by/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable | sudo tee /etc/apt/sources.list.d/docker.list /dev/null # 安装 Docker sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io有时你会在 Windows 上安装 Docker Desktop如果碰到“virtualisation support wasn‘t detected”之类的报错一般是 BIOS 里虚拟化没开或者依赖的 Windows Hypervisor Platform 没启用。这是很常见的 Docker 安装问题后面排查部分会展开。3.2 用 kind 搭一套轻量 K8s 集群正式的生产 K8s 集群搭建比如 kubeadm 方式需要比较多的机器和网络配置。本地学习阶段推荐用 kindKubernetes in Docker。kind 用 Docker 容器来模拟 K8s 节点可以在一台机器上快速搭出集群非常适合跑实验。# 安装 kind curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.20.0/kind-linux-amd64 chmod x ./kind sudo mv ./kind /usr/local/bin/kind创建集群配置文件kind-config.yamlkind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 nodes: - role: control-plane - role: worker - role: worker用配置文件创建集群kind create cluster --config kind-config.yaml执行完你会看到类似输出Creating cluster kind ... ✓ Ensuring node image (kindest/node:v1.27.3) ✓ Preparing nodes ✓ Writing configuration ✓ Starting control-plane ️ ✓ Installing CNI ✓ Installing StorageClass ✓ Set kubectl context to kind-kind这意味着你已经有一个模拟的“控制平面 两个工作节点”的集群了。虽然它在网络性能、存储等层面和真实物理集群有差距但用来学习 Deployment、Service、自动伸缩等核心概念完全足够了。3.3 安装 kubectlkubectl 是操作 K8s 集群的客户端工具# 下载 kubectl版本以官方发布为准 curl -LO https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl chmod x kubectl sudo mv ./kubectl /usr/local/bin/kubectl验证一下kubectl version --client4. LNMP 实验只用 Docker 会遇到什么接下来做一个有代表性的实验在容器里部署一套 LNMP 架构Linux Nginx MySQL PHP。这个实验非常经典因为很多同学都用它验证自己的 Docker 技能。先用 Docker Compose 在单机上跑起来然后再用 K8s 重新描述一遍对比两套工作流的差异。4.1 Docker Compose 部署 LNMP创建一个目录lnmp-docker里面放一个docker-compose.ymlversion: 3.8 services: nginx: image: nginx:1.25 ports: - 80:80 volumes: - ./html:/usr/share/nginx/html - ./nginx/conf.d:/etc/nginx/conf.d depends_on: - php php: image: php:8.2-fpm volumes: - ./html:/var/www/html mysql: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: root123 MYSQL_DATABASE: testdb ports: - 3306:3306 volumes: - mysql_data:/var/lib/mysql volumes: mysql_data:启动docker-compose up -d查看容器状态docker-compose ps这个方案最舒服的地方是开发环境。一条命令全部拉起来没有路径找不到的问题。但生产环境一复杂问题就接踵而至如果 Nginx 挂了谁来重启它流量涨了PHP 容器如何自动扩展Compose 没有内置水平伸缩。换成两台机器Nginx 容器在机器 AMySQL 在机器 B它们之间如何发现对方要发布新版本需要手动docker-compose up -d且无法控制滚动窗口一次建多个副本时容易造成服务中断。4.2 K8s 部署 LNMP先定义期望状态同样的 LNMP 架构在 K8s 里写法完全不同。核心思路是你要描述“集群里应该有什么”而不是一步一步执行“启动、连接”等命令。我们先看 Nginx PHP 部分。创建一个 Deployment 文件lnmp-web.yamlapiVersion: apps/v1 kind: Deployment metadata: name: lnmp-web labels: app: lnmp tier: web spec: replicas: 2 selector: matchLabels: app: lnmp tier: web template: metadata: labels: app: lnmp tier: web spec: containers: - name: nginx image: nginx:1.25 ports: - containerPort: 80 volumeMounts: - name: html mountPath: /usr/share/nginx/html - name: php image: php:8.2-fpm ports: - containerPort: 9000 volumeMounts: - name: html mountPath: /var/www/html volumes: - name: html emptyDir: {}这个文件里replicas: 2表示希望有 2 个 Pod。每个 Pod 内部同时运行 Nginx 和 PHP-FPM 两个容器它们共享emptyDir卷所以 PHP 代码文件可以同时被 Nginx 访问。再创建一个 Service 文件lnmp-web-svc.yamlapiVersion: v1 kind: Service metadata: name: lnmp-web-svc spec: type: NodePort selector: app: lnmp tier: web ports: - port: 80 targetPort: 80 nodePort: 30080应用这两个文件kubectl apply -f lnmp-web.yaml kubectl apply -f lnmp-web-svc.yaml查看部署状态kubectl get pods kubectl get svc如果一切正常你可以通过http://任意节点IP:30080访问到 Nginx。因为你写的是声明式配置K8s 会不断检查实际状态是否和期望状态一致。某个 Pod 挂了它会自动重建你更新了镜像它会执行滚动更新。4.3 对比结论Compose 是“启动器”K8s 是“集群大脑”通过 LNMP 这个例子我们可以非常清楚地看到差异Docker Compose 适合固定节点、固定拓扑的编排它适合开发环境、测试环境以及规模不大的单机生产环境。K8s 适合动态拓扑、需要调度和自愈的集群它把“期望状态”交给控制平面由控制平面不断把现实调整到期望值。这不代表 K8s 是万能的。如果只有一台服务器、应用就两三个容器用 K8s 反而引入更多复杂度。它需要维护 Control Plane、Node 组件、网络插件、存储插件学习成本高维护成本也不低。5. K8s 完整示例以 MySQL 和 Redis 为例为了让你能直接照着练习我们再跑两个有代表性的服务一个是有状态服务 MySQL一个是缓存服务 Redis。这两个服务在生产环境使用频率最高也是搜索热词中出现最多的场景。5.1 用 Deployment 快速部署 MySQL在 K8s 里部署 MySQL 时最简单的方式是用 Deployment 加环境变量apiVersion: apps/v1 kind: Deployment metadata: name: mysql labels: app: mysql spec: replicas: 1 selector: matchLabels: app: mysql template: metadata: labels: app: mysql spec: containers: - name: mysql image: mysql:8.0 ports: - containerPort: 3306 env: - name: MYSQL_ROOT_PASSWORD value: root123 - name: MYSQL_DATABASE value: testdb部署命令kubectl apply -f mysql-deployment.yaml kubectl get pods -l appmysql但要注意这个方式把数据存在 Pod 的文件系统里一旦 Pod 被删除数据就丢失了。生产环境必须使用持久卷PersistentVolume / PersistentVolumeClaim。下面补充一个 PVC 示例apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mysql-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 10Gi然后在 Deployment 的spec.template.spec中挂载这个 PVCvolumes: - name: mysql-storage persistentVolumeClaim: claimName: mysql-pvc在容器配置里挂载到/var/lib/mysqlvolumeMounts: - name: mysql-storage mountPath: /var/lib/mysql这是 K8s 入门阶段最容易忽视的点有状态服务必须考虑数据持久化。5.2 部署 Redis 主从结构Redis 主从结构也是高频需求。传统的 Docker 方式是分别运行 master 和 slave 容器再手动执行slaveof命令。在 K8s 里你可以用 StatefulSet 来做有状态服务的编排。为了保持示例简单这里用 Deployment 跑一个 Redis masterapiVersion: apps/v1 kind: Deployment metadata: name: redis-master labels: app: redis role: master spec: replicas: 1 selector: matchLabels: app: redis role: master template: metadata: labels: app: redis role: master spec: containers: - name: redis image: redis:7.0 ports: - containerPort: 6379对应的 ServiceapiVersion: v1 kind: Service metadata: name: redis-master-svc spec: selector: app: redis role: master ports: - port: 6379 targetPort: 6379应用kubectl apply -f redis-master.yaml kubectl apply -f redis-master-svc.yaml在 K8s 里任意一个 Pod 都可以通过redis-master-svc:6379访问 Redis master而不需要关心 master Pod 的 IP 是什么。这就解决了容器重建后 IP 变化导致的地址维护问题。5.3 StatefulSet 为什么更适合有状态服务上面用 Deployment 跑 MySQL 和 Redis适合学习和中小项目。但如果 MySQL、Redis 要保证稳定标识、要按顺序启停K8s 官方更推荐 StatefulSet。区别在于Deployment 创建的 Pod 名字是随机后缀比如mysql-abc123。StatefulSet 创建的 Pod 名字是固定序号比如mysql-0、mysql-1。StatefulSet 会为每个 Pod 创建独立的持久卷不会多个 Pod 共用同一个卷。生产环境中的数据库集群建议优先考虑 StatefulSet 或 Operator 方案比如专门的 MySQL Operator、Redis Operator而不是徒手写一堆 Deployment 死磕。6. Docker 和 K8s 的常用命令对照为了帮你把已有 Docker 经验迁移到 K8s整理一份核心命令对照表。看到 K8s 命令时先在脑子里把它和 Docker 的对应关系想清楚学习速度会快很多。操作意图Docker 命令K8s 命令查看运行中的容器/Poddocker pskubectl get pods查看所有容器/Poddocker ps -akubectl get pods -A查看日志docker logs containerkubectl logs pod进入容器/Poddocker exec -it container bashkubectl exec -it pod -- bash查看资源详情docker inspect containerkubectl describe pod pod镜像列表docker imageskubectl get pods无法直接对应对应 Docker 是docker imagesK8s 层面主要看 Deployment 镜像版本启动一个实例docker runkubectl create deployment更新镜像版本Docker 无原生滚动更新kubectl set image deployment/name containernginx:1.26回滚Docker 无原生回滚kubectl rollout undo deployment/name端口转发docker run -p 8080:80kubectl port-forward svc/service-name 8080:80有个很常见的误区是有人想在 K8s 里“进入节点上的某个容器”来改配置。K8s 的设计哲学是Pod 是临时资源不要手动改它内部的文件。你有任何变更都应该通过修改 Deployment / ConfigMap 等对象让 K8s 重建 Pod 来达到目标状态。6.1 发布变更的正确姿势假设你要把 LNMP 里的 Nginx 镜像从nginx:1.25升级到nginx:1.26kubectl set image deployment/lnmp-web nginxnginx:1.26查看滚动更新状态kubectl rollout status deployment/lnmp-web如果新版本有问题可以回滚到上一个版本kubectl rollout undo deployment/lnmp-web这套滚动更新的能力在纯 Docker 时代很难实现。你需要在多台机器上手动docker pull、docker stop、docker run还要处理负载均衡器摘流。K8s 把这些流程标准化了。7. K8s 故障排查的完整思路这一节值得收藏。K8s 上手后你面对的就不只是“容器启动失败”而是一层一层的对象。排查故障时最重要的是先定位问题发生在哪一层。7.1 从下往上排查Pod → Deployment → Service → Node遇到服务访问不了基本的排查顺序是Pod 是否 Runningkubectl get pods如果状态不是Running看kubectl describe pod pod-name。容器日志是否正常kubectl logs pod-name如果 Pod 里有多个容器要指定-c container-name。Service 是否正确关联 Podkubectl get svc kubectl describe svc service-name检查 Service 的Endpoints是否有内容。没有 Endpoints说明 selector 没有匹配到任何 Pod。访问入口是否正常 如果你用的是 NodePort试着从节点 IP NodePort 访问如果是 Ingress再看 Ingress 配置和负载均衡器。7.2 常见问题与排查方法问题现象可能原因排查方式解决方案Pod 一直Pending集群资源不足或节点亲和性无法满足kubectl describe pod pod查看Events增加节点资源或调整资源请求Pod 反复CrashLoopBackOff容器启动命令报错或健康检查失败kubectl logs pod查看启动日志修复应用启动命令检查探针配置镜像拉取失败ImagePullBackOff镜像不存在、仓库认证失败、网络受限kubectl describe pod pod查看Events检查镜像名称、仓库地址、认证信息Service 没有 Endpointsselector 与 Pod label 不匹配kubectl get pods --show-labels修改 Service selectorNode 内存/磁盘压力节点资源不足kubectl describe node node清理节点或增加资源K8s 集群 DNS 解析异常CoreDNS 异常或网络插件故障kubectl get pods -n kube-system重启 CoreDNS 或检查 CNI 插件为什么单独提镜像拉取失败因为和 Docker 时代的docker pull失败原因非常相似要么是网络源不通要么是镜像 tag 写错。你在 Docker 里踩过的坑在 K8s 里大部分还会以另一种形式出现。8. 从 Docker Compose 迁移到 K8s 的路径很多人学 K8s 是为了把已有的 Docker Compose 项目迁移上来。这个过程的难点在于思维的转变Compose 文件描述“有哪些服务”而 K8s 描述“每个服务应该如何运行”。两种心态完全不同。8.1 不建议迁移的场景本地小项目用 Docker Compose 就够K8s 资源占用和维护成本不低。没有集群需求的团队服务器就一两台没有高可用、弹性伸缩需求强行上 K8s 会把运维复杂度推得很高。没有容器平台运维能力的团队K8s 的控制平面、集群升级、网络插件、存储插件都需要专门知识团队人力不足时反而会影响交付速度。8.2 适合迁移的场景服务数量多比如 10 个以上服务手工写脚本管理容器已经明显吃力。需要弹性扩缩容业务流量波动大让 K8s 根据 CPU 或内存自动扩缩容。需要高可用和自愈某台机器挂了K8s 能把 Pod 调度到其他节点。需要规范化发布流程滚动更新、灰度发布、失败回滚K8s 全部原生支持。迁移时不要一把梭。建议流程先用kompose把 Docker Compose 转成 K8s YAML作为初始模板。逐个服务应用观察日志和上下游依赖。优先处理无状态服务再处理有状态服务数据库、缓存。通过 Service 替换原来的容器名访问方式。最后再考虑 ConfigMap、Secret、Ingress 等高级配置。举个例子Compose 里服务名叫php其他服务访问它时直接用http://php:9000。迁移到 K8s 后PHP 容器在 Pod 里外部访问要改成一个 Service服务名在集群内才能被直接解析。9. 最佳实践与工程建议这个部分不是泛泛而谈而是从实际踩坑经验里提炼出来的几条建议。9.1 Docker 阶段就要做好的事镜像编写一定要写清楚基础镜像版本。FROM nginx看似省事实际上镜像漂移会给你带来不小的麻烦。更稳妥的是FROM nginx:1.25并且在生产构建中固定镜像摘要。容器进程不要以 root 运行。在 Dockerfile 里显式创建普通用户并切换能减少安全风险。单容器只跑一个主进程。虽然容器里可以跑多个进程但日志、监控、生命周期管理会变得麻烦。数据目录一定用卷挂载不要写在容器可写层里。9.2 K8s 阶段的几条铁律不要手动修改 Pod 内部文件。改完也会在 Pod 重建后丢失正确做法是改 Deployment / ConfigMap。为每个服务配置资源 requests/limits。没有资源限制的容器可能会把节点内存打爆。默认给服务加 livenessProbe 和 readinessProbe。这样 K8s 才知道你的应用是“死是活”、是否对外提供服务。敏感信息使用 Secret不要写在镜像里和环境变量明文里。生产环境数据库尽量用外部中间件或 Operator 管理不要自己裸写 Deployment。资源限制示例resources: requests: cpu: 100m memory: 128Mi limits: cpu: 500m memory: 512Mi9.3 团队协作建议如果团队准备引入 K8s建议先派 1-2 人做技术调研在一个非核心业务上试点三到六个月。试点期间要把“部署耗时、故障恢复时间、发布效率”等指标记录下来和原来的方式做对比。不要一上来要求所有业务立刻迁到 K8s。10. 总结与后续学习方向回到最开始的问题有了 Docker为什么还要 K8s因为 Docker 负责的是单机上把应用容器化、标准化运行而 K8s 负责的是在集群规模下让容器按期望状态运行。Docker 让“一次构建随处运行”成为现实K8s 让“集群调度、自动伸缩、故障自愈”成为标准能力。两者不在同一层也没法互相替代。真正适合对比的不是 Docker 与 K8s而是“单机容器管理”与“集群容器编排”。对开发者来说判断自己要不要学 K8s看的是业务规模和团队环境。如果你还在本地阶段Docker 和 Docker Compose 足以支撑开发、测试工作一旦应用真正上生产多台机器、多个服务同时运行K8s 带来的标准化治理能力会明显超过它的学习成本。下一步你可以从这几个方向继续深入把 LNMP 的 K8s 部署文件补充完整加上 ConfigMap、Secret、Ingress。用kubectl scale测试水平扩容观察 Service 自动把流量分发到多个 Pod。用kubectl rollout undo验证失败回滚流程。学习 StatefulSet 和 PersistentVolume理解有状态应用在 K8s 里的正确打开方式。如果网络环境复杂再去看网络插件和 Multus 相关方案不过建议先把基础模型玩熟。K8s 的复杂性是真实的但它解决的也是真实的问题。把这篇文章里的最小实验跑通你就能建立一张清晰的地图哪些问题该由 Docker 管哪些问题该交给 K8s。有了这张地图后面踩坑时你至少知道去哪里看日志。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →