人生理想,技术交流加Q:411239339

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

浏览:16次阅读
没有评论

共计 3760 个字符,预计需要花费 10 分钟才能阅读完成。

你用 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 理解为一个内置的负载均衡器:前端应用访问 http://backend-service:8080,不用关心背后到底有几个 Pod、IP 是什么。

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

假设你有一个经典的 Web 应用,Docker Compose 文件长这样:

# docker-compose.yml
version: '3'
services:
  web:
    image: my-web-app:1.0
    ports:
      - "8080:8080"
    environment:
      - DB_HOST=db
  db:
    image: mysql:8.0
    environment:
      - MYSQL_ROOT_PASSWORD=secret
      - MYSQL_DATABASE=myapp
    volumes:
      - db-data:/var/lib/mysql
volumes:
  db-data:

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

第一步:Web 应用的 Deployment + Service

# web-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: web
          image: my-web-app:1.0
          ports:
            - containerPort: 8080
          env:
            - name: DB_HOST
              value: db-service
---
apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  type: NodePort
  selector:
    app: web
  ports:
    - port: 8080
      targetPort: 8080
      nodePort: 30080

关键对比: Compose 里写 ports: "8080:8080",K8s 里拆成了 containerPorttargetPortnodePort 三层。replicas: 3 意味着直接起了 3 个实例——这在 Compose 里需要额外配置。

第二步:数据库的 Deployment + Service

# db-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: db
spec:
  replicas: 1
  selector:
    matchLabels:
      app: db
  template:
    metadata:
      labels:
        app: db
    spec:
      containers:
        - name: db
          image: mysql:8.0
          ports:
            - containerPort: 3306
          env:
            - name: MYSQL_ROOT_PASSWORD
              value: secret
            - name: MYSQL_DATABASE
              value: myapp
---
apiVersion: v1
kind: Service
metadata:
  name: db-service
spec:
  selector:
    app: db
  ports:
    - port: 3306
      targetPort: 3306

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

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

用 Minikube 在本地跑起来

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

安装 Minikube

macOS 用户一行命令搞定:

brew install minikube

Linux 用户:

curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube

启动集群并部署

# 启动集群(首次启动需要几分钟,去倒杯水)minikube start

# 部署数据库
kubectl apply -f db-deployment.yaml

# 部署 Web 应用
kubectl apply -f web-deployment.yaml

# 查看 Pod 状态
kubectl get pods

# 查看 Service
kubectl get services

顺利的话,你会看到类似这样的输出:

NAME                   READY   STATUS    RESTARTS   AGE
db-5d4f7b8c9-x2k8m    1/1     Running   0          45s
web-7f8a6b5d4-abc12    1/1     Running   0          30s
web-7f8a6b5d4-def34    1/1     Running   0          30s
web-7f8a6b5d4-ghi56    1/1     Running   0          30s

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

访问应用

minikube service web-service --url

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

体验自愈能力

现在来点刺激的——手动删掉一个 Pod:

kubectl delete pod web-7f8a6b5d4-abc12

然后立刻执行 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 玩熟,足够覆盖大部分开发环境的需求。

毕竟,登珠峰也是从大本营开始的——而你现在,已经扎好了营地。

正文完
创作不易,扫码加点动力
post-qrcode
 0
果较瘦
版权声明:本站原创文章,由 果较瘦 于2026-03-24发表,共计3760字。
转载说明:除特殊说明外本站文章皆由果较瘦原创发布,转载请注明出处。