冒险岛079

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 5|回复: 0

Docker与Kubernetes初探:从容器到编排

[复制链接]

621

主题

13

回帖

1987

积分

管理员

积分
1987
发表于 昨天 08:46 | 显示全部楼层 |阅读模式
你用 Docker 跑了几个容器,觉得自己已经站在云原生的门口了。然后有人告诉你:"试试 Kubernetes 吧。"于是你打开官方文档,看到 Pod、Service、Deployment、ReplicaSet、Ingress……默默关上了浏览器。

别慌。今天这篇文章,就是帮你把那扇门真正推开。

先搞清楚一个问题:Docker 不够用吗?

Docker 解决了"在我机器上能跑"的经典难题。一个容器打包好,扔到哪里都能运行,这很好。

但当你的应用从 1 个容器变成 10 个、50 个时,问题来了:

  • 某个容器挂了,谁来自动重启?
  • 流量暴增时,谁来自动扩容?
  • 10 个容器之间的网络通信怎么管理?
  • 滚动更新怎么做到不停机?

    Docker Compose 能解决部分问题,但它本质上还是个"单机编排"工具。你需要的是一个集群级别的调度系统——这就是 Kubernetes(简称 K8s)登场的理由。

    Kubernetes 核心概念:只需记住三个

    K8s 的概念多到让人头皮发麻,但对于入门而言,你只需要先吃透三个。

    Pod:最小调度单元

    Pod 不是容器,而是"一组容器的包装"。大多数情况下,一个 Pod 里只跑一个容器,你可以简单理解为 Pod ≈ 一个运行中的容器实例

    为什么不直接管理容器?因为 K8s 需要在 Pod 层面附加额外信息:IP 地址、存储卷、重启策略等。Pod 是 K8s 的原子单位,就像进程之于操作系统。

    Deployment:声明式管理

    Deployment 告诉 K8s:"我希望始终有 3 个 Pod 在运行。"然后 K8s 会帮你维持这个状态——挂了一个就自动拉起一个,需要更新就滚动替换。

    这就是所谓的声明式思维:你不用说"先停掉旧的,再启动新的",你只需要说"我要的最终状态是什么",K8s 自己想办法达到。

    Service:稳定的访问入口

    Pod 的 IP 是临时的,每次重启都可能变化。Service 提供一个固定的虚拟 IP 和 DNS 名称,把请求自动转发到后面的 Pod 上。

    你可以把 Service 理解为一个内置的负载均衡器:前端应用访问
    1. http://backend-service:8080
    复制代码
    ,不用关心背后到底有几个 Pod、IP 是什么。

    从 Docker Compose 到 K8s:一个实际的迁移示例

    假设你有一个经典的 Web 应用,Docker Compose 文件长这样:
    1. # docker-compose.yml
    2. version: '3'
    3. services:
    4.   web:
    5.     image: my-web-app:1.0
    6.     ports:
    7.       - "8080:8080"
    8.     environment:
    9.       - DB_HOST=db
    10.   db:
    11.     image: mysql:8.0
    12.     environment:
    13.       - MYSQL_ROOT_PASSWORD=secret
    14.       - MYSQL_DATABASE=myapp
    15.     volumes:
    16.       - db-data:/var/lib/mysql
    17. volumes:
    18.   db-data:
    复制代码

    两个服务:一个 Web 应用,一个 MySQL 数据库。现在我们把它搬到 K8s 上。

    第一步:Web 应用的 Deployment + Service
    1. # web-deployment.yaml
    2. apiVersion: apps/v1
    3. kind: Deployment
    4. metadata:
    5.   name: web
    6. spec:
    7.   replicas: 3
    8.   selector:
    9.     matchLabels:
    10.       app: web
    11.   template:
    12.     metadata:
    13.       labels:
    14.         app: web
    15.     spec:
    16.       containers:
    17.         - name: web
    18.           image: my-web-app:1.0
    19.           ports:
    20.             - containerPort: 8080
    21.           env:
    22.             - name: DB_HOST
    23.               value: db-service
    24. ---
    25. apiVersion: v1
    26. kind: Service
    27. metadata:
    28.   name: web-service
    29. spec:
    30.   type: NodePort
    31.   selector:
    32.     app: web
    33.   ports:
    34.     - port: 8080
    35.       targetPort: 8080
    36.       nodePort: 30080
    复制代码

    关键对比: Compose 里写
    1. ports: "8080:8080"
    复制代码
    ,K8s 里拆成了
    1. containerPort
    复制代码
    1. targetPort
    复制代码
    1. nodePort
    复制代码
    三层。
    1. replicas: 3
    复制代码
    意味着直接起了 3 个实例——这在 Compose 里需要额外配置。

    第二步:数据库的 Deployment + Service
    1. # db-deployment.yaml
    2. apiVersion: apps/v1
    3. kind: Deployment
    4. metadata:
    5.   name: db
    6. spec:
    7.   replicas: 1
    8.   selector:
    9.     matchLabels:
    10.       app: db
    11.   template:
    12.     metadata:
    13.       labels:
    14.         app: db
    15.     spec:
    16.       containers:
    17.         - name: db
    18.           image: mysql:8.0
    19.           ports:
    20.             - containerPort: 3306
    21.           env:
    22.             - name: MYSQL_ROOT_PASSWORD
    23.               value: secret
    24.             - name: MYSQL_DATABASE
    25.               value: myapp
    26. ---
    27. apiVersion: v1
    28. kind: Service
    29. metadata:
    30.   name: db-service
    31. spec:
    32.   selector:
    33.     app: db
    34.   ports:
    35.     - port: 3306
    36.       targetPort: 3306
    复制代码

    Web 应用里环境变量
    1. DB_HOST=db-service
    复制代码
    ,对应的就是这个 Service 的名称。K8s 内置 DNS 会自动将
    1. db-service
    复制代码
    解析到数据库 Pod 的地址。

    (生产环境数据库建议用 StatefulSet 而非 Deployment,但入门阶段先这样跑起来,别给自己太大压力。)

    用 Minikube 在本地跑起来

    说了这么多 YAML,该动手了。Minikube 是 K8s 官方的本地开发工具,能在你的笔记本上模拟一个单节点集群。

    安装 Minikube

    macOS 用户一行命令搞定:
    1. brew install minikube
    复制代码

    Linux 用户:
    1. curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
    2. sudo install minikube-linux-amd64 /usr/local/bin/minikube
    复制代码

    启动集群并部署
    1. # 启动集群(首次启动需要几分钟,去倒杯水)
    2. minikube start
    3. # 部署数据库
    4. kubectl apply -f db-deployment.yaml
    5. # 部署 Web 应用
    6. kubectl apply -f web-deployment.yaml
    7. # 查看 Pod 状态
    8. kubectl get pods
    9. # 查看 Service
    10. kubectl get services
    复制代码

    顺利的话,你会看到类似这样的输出:
    1. NAME                   READY   STATUS    RESTARTS   AGE
    2. db-5d4f7b8c9-x2k8m    1/1     Running   0          45s
    3. web-7f8a6b5d4-abc12    1/1     Running   0          30s
    4. web-7f8a6b5d4-def34    1/1     Running   0          30s
    5. web-7f8a6b5d4-ghi56    1/1     Running   0          30s
    复制代码

    3 个 Web Pod,1 个数据库 Pod,全部 Running。

    访问应用
    1. minikube service web-service --url
    复制代码

    这条命令会返回一个本地可访问的 URL。打开浏览器,你的应用已经在 K8s 上跑起来了。

    体验自愈能力

    现在来点刺激的——手动删掉一个 Pod:
    1. kubectl delete pod web-7f8a6b5d4-abc12
    复制代码

    然后立刻执行
    1. kubectl get pods
    复制代码
    ,你会发现 K8s 在几秒内自动创建了一个新 Pod 来维持 3 副本的状态。这就是 Deployment 的声明式管理在起作用。

    Docker Compose 能做到吗?不能。容器挂了就是挂了,得你自己去重启。

    Compose 到 K8s 的核心思维转变

    | 维度 | Docker Compose | Kubernetes |
    |------|---------------|------------|
    | 运行范围 | 单机 | 集群 |
    | 扩缩容 | 手动 | 声明 replicas 自动维持 |
    | 自愈 | 无 | Pod 崩溃自动重建 |
    | 服务发现 | 容器名直连 | Service + 内置 DNS |
    | 更新策略 | 停机替换 | 滚动更新,零停机 |
    | 配置管理 | .env 文件 | ConfigMap / Secret |

    最核心的转变是:从"命令式"到"声明式"。你不再告诉系统"做什么",而是告诉它"我要什么样的结果"。

    下一步该学什么

    跑通了今天的例子,你已经完成了从单机 Docker 到集群编排的第一步。接下来建议按这个顺序深入:

    第一,ConfigMap 和 Secret。 把数据库密码写在 YAML 里显然不安全,Secret 专门解决这个问题。

    第二,Ingress。 目前我们用 NodePort 暴露服务,生产环境需要 Ingress 来做域名路由和 HTTPS 终止。

    第三,持久化存储。 数据库的数据不能跟着 Pod 一起消失,PersistentVolume 和 PersistentVolumeClaim 是必修课。

    第四,Helm。 当你的 YAML 文件多到需要"管理 YAML 的工具"时,Helm 就该上场了。它是 K8s 的包管理器,相当于 apt 之于 Ubuntu。

    Kubernetes 的学习曲线确实陡峭,但好消息是:你不需要一次学完。先把今天的 Deployment、Service、Pod 玩熟,足够覆盖大部分开发环境的需求。

    毕竟,登珠峰也是从大本营开始的——而你现在,已经扎好了营地。
  • 您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    果子博客
    扫码关注微信公众号

    Archiver|手机版|小黑屋|风叶林

    GMT+8, 2026-3-25 04:19 , Processed in 0.134205 second(s), 20 queries .

    Powered by 风叶林

    © 2001-2026 Discuz! Team.

    快速回复 返回顶部 返回列表