Docker 与 Kubernetes 入门指南:小白也能看懂的容器技术

前言

在云原生时代,Docker 和 Kubernetes 已经成为软件开发和部署的标配技术。但对于初学者来说,这两个概念常常让人混淆:它们到底是什么?有什么区别?又是如何配合使用的?本文将用通俗易懂的方式,为你揭开容器技术的神秘面纱。


在这里插入图片描述

一、从一个生活场景开始理解

1.1 传统部署的困境

想象你是一个餐厅老板:

  • 传统方式:每次做一道新菜,你都需要准备整套厨房设备、调料、食材,非常麻烦
  • 不同环境的问题:在家里厨房能做好的菜,搬到餐厅厨房可能就做不出来了(设备、调料不同)
  • 资源浪费:每道菜都要独立的灶台,10 道菜就需要 10 个厨房

这就是传统软件部署面临的问题:

  • 开发环境能跑,测试环境不能跑
  • 不同服务器环境不一致
  • 资源利用率低

二、Docker:集装箱式的软件打包方案

2.1 什么是 Docker?

Docker 就像是软件世界的集装箱系统。

在物流行业,集装箱革命性地解决了货物运输问题:

  • 把货物标准化打包在集装箱里
  • 集装箱可以在轮船、火车、卡车之间无缝转运
  • 不用关心箱子里装的是什么

Docker 也是同样的思路:

  • 把应用和它需要的所有依赖打包成一个容器镜像
  • 这个镜像可以在任何安装了 Docker 的机器上运行
  • 不用担心环境差异问题

2.2 Docker 的核心概念

2.2.1 镜像(Image)

镜像 = 软件的安装包

类比:就像游戏的安装光盘,里面包含了运行游戏需要的所有文件。

# Dockerfile 示例:构建一个 Node.js 应用镜像
FROM node:18-alpine          # 基于 Node.js 18 环境
WORKDIR /app                 # 设置工作目录
COPY package*.json ./        # 复制依赖配置文件
RUN npm install              # 安装依赖
COPY . .                     # 复制应用代码
CMD ["node", "server.js"]    # 启动命令

关键特点

  • 镜像是只读的(不会被修改)
  • 镜像是分层的(像千层蛋糕,每一层都是一次操作)
  • 可以共享基础层(多个镜像可以共用相同的基础层,节省空间)
2.2.2 容器(Container)

容器 = 镜像运行起来的实例

类比:光盘安装后运行的游戏进程。

# 从镜像创建并运行容器
docker run -d -p 3000:3000 --name myapp my-node-app:latest

# 解释:
# -d: 后台运行
# -p 3000:3000: 端口映射(主机端口:容器端口)
# --name myapp: 容器名称
# my-node-app:latest: 使用的镜像

关键特点

  • 容器是可读写的(运行时产生的数据)
  • 容器之间相互隔离(互不干扰)
  • 容器可以随时创建、启动、停止、删除
2.2.3 仓库(Registry)

仓库 = 镜像的应用商店

类比:苹果的 App Store 或 Steam 游戏平台。

  • Docker Hub:Docker 官方的公共仓库
  • 私有仓库:公司内部搭建的镜像仓库
# 从仓库拉取镜像
docker pull nginx:latest

# 推送镜像到仓库
docker push mycompany/myapp:v1.0

2.3 Docker 的技术原理

2.3.1 容器隔离技术

Docker 容器本质上是运行在宿主机上的一个特殊进程,通过 Linux 内核技术实现隔离:

1. Namespace(命名空间)—— 隔离视图

让每个容器觉得自己独占整个系统:

Namespace 类型隔离内容作用
PID进程 ID容器内进程看不到宿主机其他进程
NET网络每个容器有独立的网络栈
MNT文件系统容器有自己的文件系统视图
UTS主机名容器可以有独立的主机名
IPC进程间通信隔离消息队列、共享内存
USER用户和组容器内的 root 不是宿主机的 root

2. Cgroups(控制组)—— 资源限制

控制容器能使用多少资源:

# 限制容器只能使用 512MB 内存和 0.5 个 CPU 核心
docker run -m 512m --cpus=0.5 nginx

3. UnionFS(联合文件系统)—— 镜像分层

镜像分层示例:
[应用代码层]           ← 可写层(容器运行时)
[应用依赖层]           ← 只读层
[运行时环境层]         ← 只读层
[基础操作系统层]       ← 只读层(共享)
2.3.2 Docker 架构
┌─────────────────────────────────────────────┐
│           Docker Client (CLI)               │
│        docker run, docker build...          │
└─────────────┬───────────────────────────────┘
              │ REST API
┌─────────────▼───────────────────────────────┐
│          Docker Daemon (dockerd)            │
│  ┌──────────────────────────────────────┐   │
│  │    Images, Containers, Networks...   │   │
│  └──────────────────────────────────────┘   │
└─────────────┬───────────────────────────────┘
              │
┌─────────────▼───────────────────────────────┐
│         Container Runtime (containerd)      │
│              ↓                              │
│         Low-level Runtime (runc)            │
└─────────────────────────────────────────────┘

2.4 Docker 的典型使用场景

场景 1:环境一致性
# docker-compose.yml - 一键启动完整开发环境
version: '3.8'
services:
  web:
    image: node:18
    volumes:
      - ./app:/app
    ports:
      - "3000:3000"
    depends_on:
      - db

  db:
    image: postgres:15
    environment:
      POSTGRES_PASSWORD: secret
    volumes:
      - pgdata:/var/lib/postgresql/data

volumes:
  pgdata:

好处:新同事加入,只需运行 docker-compose up,无需手动配置环境。

场景 2:微服务架构
┌──────────────┐     ┌──────────────┐     ┌──────────────┐
│  用户服务容器 │ ──▶ │  订单服务容器 │ ──▶ │  支付服务容器 │
└──────────────┘     └──────────────┘     └──────────────┘
        │                    │                     │
        └────────────────────┴─────────────────────┘
                             │
                    ┌────────▼────────┐
                    │   数据库容器     │
                    └─────────────────┘

每个服务独立打包、独立部署、独立扩展。


三、Kubernetes:容器编排的指挥家

3.1 为什么需要 Kubernetes?

Docker 解决了单个容器的问题,但在生产环境中,你会面临:

  1. 容器太多管理不过来:几十上百个容器怎么管理?
  2. 容器挂了怎么办:谁来自动重启?
  3. 流量高峰怎么办:如何自动扩容?
  4. 服务如何互相发现:容器 IP 会变,如何通信?
  5. 如何滚动更新:怎样不停机更新应用?

Kubernetes(简称 K8s)就是解决这些问题的容器编排平台。

类比:

  • Docker = 单个集装箱
  • Kubernetes = 管理整个港口的集装箱调度系统

3.2 Kubernetes 的核心概念

3.2.1 集群架构
┌───────────────────────────────────────────────────────────┐
│                    Kubernetes 集群                         │
│                                                           │
│  ┌─────────────────────── Master Node ──────────────────┐ │
│  │  ┌──────────────┐  ┌──────────────┐  ┌────────────┐ │ │
│  │  │ API Server   │  │  Scheduler   │  │ Controller │ │ │
│  │  └──────────────┘  └──────────────┘  └────────────┘ │ │
│  │           ┌──────────────┐                          │ │
│  │           │     etcd      │ (集群数据存储)           │ │
│  │           └──────────────┘                          │ │
│  └──────────────────────────────────────────────────────┘ │
│                              │                            │
│      ┌───────────────────────┼───────────────────────┐    │
│      │                       │                       │    │
│  ┌───▼──────────┐    ┌───────▼──────┐    ┌─────────▼───┐ │
│  │ Worker Node 1│    │ Worker Node 2│    │Worker Node 3│ │
│  │  ┌────────┐  │    │  ┌────────┐  │    │ ┌────────┐  │ │
│  │  │Pod Pod │  │    │  │Pod Pod │  │    │ │Pod Pod │  │ │
│  │  └────────┘  │    │  └────────┘  │    │ └────────┘  │ │
│  │  ┌────────┐  │    │  ┌────────┐  │    │ ┌────────┐  │ │
│  │  │  Pod   │  │    │  │  Pod   │  │    │ │  Pod   │  │ │
│  │  └────────┘  │    │  └────────┘  │    │ └────────┘  │ │
│  └──────────────┘    └──────────────┘    └─────────────┘ │
└───────────────────────────────────────────────────────────┘

Master Node(控制平面):大脑,负责决策和调度

  • API Server:集群的入口,所有操作都通过它
  • Scheduler:决定 Pod 运行在哪个节点
  • Controller Manager:维护集群状态(如保证副本数)
  • etcd:分布式数据库,存储集群配置

Worker Node(工作节点):干活的,运行容器

  • Kubelet:节点代理,管理 Pod 生命周期
  • kube-proxy:网络代理,处理服务发现和负载均衡
  • Container Runtime:容器运行时(通常是 Docker 或 containerd)
3.2.2 核心资源对象

1. Pod —— 最小调度单位

Pod 是一组紧密关联的容器(通常是 1 个):

apiVersion: v1
kind: Pod
metadata:
  name: my-app
spec:
  containers:
  - name: web
    image: nginx:latest
    ports:
    - containerPort: 80
  - name: sidecar
    image: busybox
    command: ['sh', '-c', 'while true; do echo hello; sleep 10; done']

为什么需要 Pod?

  • 有些容器需要紧密协作(如主应用 + 日志收集)
  • 共享网络和存储
  • 一起调度,保证在同一节点

2. Deployment —— 声明式部署

管理无状态应用的副本:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3                    # 运行 3 个副本
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.25
        ports:
        - containerPort: 80
        resources:
          limits:
            memory: "128Mi"
            cpu: "500m"

Deployment 的能力

  • 自动创建和管理多个 Pod 副本
  • 滚动更新(零停机更新)
  • 回滚到之前版本
  • 自动重启失败的 Pod

3. Service —— 服务发现与负载均衡

Pod 会被创建、销毁,IP 地址会变化。Service 提供固定的访问入口:

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx              # 选择 app=nginx 的 Pod
  ports:
  - protocol: TCP
    port: 80                # Service 端口
    targetPort: 80          # Pod 端口
  type: LoadBalancer        # 暴露到外网

Service 类型

  • ClusterIP(默认):集群内部访问
  • NodePort:通过节点 IP + 端口访问
  • LoadBalancer:云厂商的负载均衡器
  • ExternalName:映射到外部服务

4. ConfigMap & Secret —— 配置管理

# ConfigMap - 存储非敏感配置
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  database_url: "postgres://db:5432/mydb"
  log_level: "info"

---
# Secret - 存储敏感信息(Base64 编码)
apiVersion: v1
kind: Secret
metadata:
  name: db-secret
type: Opaque
data:
  password: cGFzc3dvcmQxMjM=  # password123 的 Base64

在 Pod 中使用:

spec:
  containers:
  - name: app
    image: myapp
    env:
    - name: DB_PASSWORD
      valueFrom:
        secretKeyRef:
          name: db-secret
          key: password
    envFrom:
    - configMapRef:
        name: app-config

5. Ingress —— HTTP 路由

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
spec:
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 8080
      - path: /
        pathType: Prefix
        backend:
          service:
            name: frontend-service
            port:
              number: 80

效果:

  • myapp.example.com/api → api-service
  • myapp.example.com/ → frontend-service

3.3 Kubernetes 的工作原理

3.3.1 声明式 API

传统命令式(告诉系统怎么做):

# 创建容器
docker run nginx
# 如果挂了,手动重启
docker restart xxx
# 需要扩容,再创建一个
docker run nginx

Kubernetes 声明式(告诉系统想要什么):

# 我要 3 个 nginx Pod 一直运行
replicas: 3

Kubernetes 会:

  1. 观察当前状态(只有 2 个?)
  2. 对比期望状态(应该有 3 个)
  3. 执行调谐动作(创建 1 个)
  4. 持续循环这个过程
3.3.2 控制器模式
┌────────────────────────────────────────┐
│         Controller Loop                │
│                                        │
│  ┌──────────────────────────────────┐  │
│  │  1. Watch 资源变化                 │  │
│  │  2. 获取当前状态                   │  │
│  │  3. 对比期望状态                   │  │
│  │  4. 执行调谐动作                   │  │
│  │  5. 更新状态                       │  │
│  └──────────┬───────────────────────┘  │
│             └──────┐                    │
│                    │ 循环               │
│                    ↓                    │
└────────────────────────────────────────┘

实例:Deployment Controller

期望状态:replicas: 3
当前状态:2 个 Pod 运行,1 个 Pod 失败

调谐动作:
1. 删除失败的 Pod
2. 创建新的 Pod
3. 等待新 Pod 就绪
4. 更新状态为 3 个 Running
3.3.3 Pod 调度流程
1. 用户提交 Pod 创建请求
   │
   ▼
2. API Server 验证并存储到 etcd
   │
   ▼
3. Scheduler 监听到新 Pod
   │
   ▼
4. Scheduler 筛选可用节点
   ├─ 检查资源(CPU、内存够不够?)
   ├─ 检查亲和性(是否要求特定节点?)
   ├─ 检查污点和容忍(节点是否有限制?)
   └─ 打分排序(选最优节点)
   │
   ▼
5. 绑定 Pod 到选中的节点
   │
   ▼
6. 该节点的 Kubelet 收到任务
   │
   ▼
7. Kubelet 调用容器运行时创建容器
   │
   ▼
8. 容器运行,定期健康检查

3.4 Kubernetes 的典型使用场景

场景 1:自动扩缩容(HPA)
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: web-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web-app
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70  # CPU 超过 70% 时扩容

效果

  • 流量低时:保持 2 个副本
  • 流量高峰:自动扩到 10 个副本
  • 流量恢复:自动缩回到 2 个
场景 2:滚动更新
# 更新镜像版本
kubectl set image deployment/web-app web=myapp:v2

# Kubernetes 滚动更新过程:
# 1. 创建 1 个 v2 Pod
# 2. 等待 v2 Pod 就绪
# 3. 删除 1 个 v1 Pod
# 4. 重复直到全部更新
# 5. 如果 v2 有问题,一键回滚
kubectl rollout undo deployment/web-app
场景 3:有状态应用(StatefulSet)
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  serviceName: mysql
  replicas: 3
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:8.0
        volumeMounts:
        - name: data
          mountPath: /var/lib/mysql
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: ["ReadWriteOnce"]
      resources:
        requests:
          storage: 10Gi

StatefulSet 特点

  • Pod 名称固定(mysql-0, mysql-1, mysql-2)
  • 有序启动和停止
  • 每个 Pod 有独立的持久存储
  • 适合数据库、消息队列等有状态应用

四、Docker vs Kubernetes:区别与联系

4.1 核心区别

维度DockerKubernetes
定位容器引擎(单机工具)容器编排平台(集群管理)
解决问题应用打包和运行大规模容器管理和调度
管理范围单个主机上的容器多台主机组成的集群
核心功能构建、运行、分享容器部署、扩缩、负载均衡、自愈
学习曲线相对简单较为复杂
适用场景开发测试、小规模部署生产环境、大规模部署

4.2 形象比喻

Docker:
就像买了一辆汽车(容器)
你可以开车、停车、加油
适合个人使用

Kubernetes:
就像管理一个出租车公司
- 调度系统:哪辆车去接哪个订单
- 监控系统:车辆位置、状态监控
- 维修系统:车坏了自动派新车
- 扩容系统:高峰期增加车辆
适合企业运营

4.3 协作关系

┌─────────────────────────────────────────┐
│          应用开发者                      │
│                                         │
│  编写 Dockerfile 构建镜像               │
└──────────────┬──────────────────────────┘
               │
               ▼
┌──────────────────────────────────────────┐
│            Docker                        │
│                                          │
│  • 构建镜像:docker build                │
│  • 推送镜像:docker push                 │
│  • 运行容器:docker run                  │
└──────────────┬───────────────────────────┘
               │ 提供容器运行时
               ▼
┌──────────────────────────────────────────┐
│          Kubernetes                      │
│                                          │
│  • 拉取镜像:从仓库获取                   │
│  • 创建 Pod:使用 Docker 创建容器         │
│  • 管理生命周期:调度、扩缩容、自愈        │
│  • 服务发现:负载均衡                     │
└──────────────────────────────────────────┘

关系总结

  1. Docker 是基础:Kubernetes 需要容器运行时(Docker 或 containerd)
  2. 分工明确:Docker 负责容器技术,K8s 负责编排管理
  3. 可以独立使用:小项目用 Docker,大项目用 K8s
  4. 也可以配合:K8s 管理 Docker 容器(最常见)

4.4 技术栈对比

Docker 技术栈

应用代码
    ↓
Dockerfile(构建脚本)
    ↓
Docker Image(镜像)
    ↓
Docker Container(容器)
    ↓
Docker Compose(多容器编排)- 可选

Kubernetes 技术栈

应用代码
    ↓
Dockerfile → Docker Image
    ↓
Kubernetes Manifest(YAML 配置)
    ↓
Pod(容器组)
    ↓
Deployment/Service/Ingress(高级资源)
    ↓
Helm(包管理器)- 可选

五、实战案例:从 Docker 到 Kubernetes

5.1 场景:部署一个博客应用

阶段 1:Docker 单机部署

1. 编写 Dockerfile

# Dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "app.js"]

2. 使用 Docker Compose 编排

# docker-compose.yml
version: '3.8'
services:
  blog:
    build: .
    ports:
      - "3000:3000"
    environment:
      - DB_HOST=db
      - DB_PASSWORD=secret
    depends_on:
      - db

  db:
    image: postgres:15
    environment:
      POSTGRES_PASSWORD: secret
    volumes:
      - db-data:/var/lib/postgresql/data

volumes:
  db-data:

3. 运行

docker-compose up -d

存在的问题

  • 只能在单台机器运行
  • 流量大了无法自动扩容
  • 容器挂了需要手动重启
  • 没有负载均衡
阶段 2:迁移到 Kubernetes

1. 构建并推送镜像

docker build -t myregistry.com/blog:v1.0 .
docker push myregistry.com/blog:v1.0

2. 创建 Kubernetes 配置

# blog-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: blog
spec:
  replicas: 3                      # 运行 3 个副本
  selector:
    matchLabels:
      app: blog
  template:
    metadata:
      labels:
        app: blog
    spec:
      containers:
      - name: blog
        image: myregistry.com/blog:v1.0
        ports:
        - containerPort: 3000
        env:
        - name: DB_HOST
          value: postgres-service
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: password
        resources:
          requests:
            memory: "128Mi"
            cpu: "100m"
          limits:
            memory: "256Mi"
            cpu: "200m"
        livenessProbe:             # 健康检查
          httpGet:
            path: /health
            port: 3000
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:            # 就绪检查
          httpGet:
            path: /ready
            port: 3000
          initialDelaySeconds: 5
          periodSeconds: 5

---
# blog-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: blog-service
spec:
  selector:
    app: blog
  ports:
  - protocol: TCP
    port: 80
    targetPort: 3000
  type: LoadBalancer

---
# postgres-statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgres
spec:
  serviceName: postgres-service
  replicas: 1
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
      - name: postgres
        image: postgres:15
        ports:
        - containerPort: 5432
        env:
        - name: POSTGRES_PASSWORD
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: password
        volumeMounts:
        - name: postgres-storage
          mountPath: /var/lib/postgresql/data
  volumeClaimTemplates:
  - metadata:
      name: postgres-storage
    spec:
      accessModes: ["ReadWriteOnce"]
      resources:
        requests:
          storage: 20Gi

---
# postgres-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: postgres-service
spec:
  selector:
    app: postgres
  ports:
  - protocol: TCP
    port: 5432
    targetPort: 5432
  clusterIP: None  # Headless Service for StatefulSet

---
# db-secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: db-secret
type: Opaque
stringData:
  password: "your-secret-password"

---
# hpa.yaml - 自动扩缩容
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: blog-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: blog
  minReplicas: 3
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70

3. 部署到 Kubernetes

# 创建 Secret
kubectl apply -f db-secret.yaml

# 部署数据库
kubectl apply -f postgres-statefulset.yaml
kubectl apply -f postgres-service.yaml

# 部署应用
kubectl apply -f blog-deployment.yaml
kubectl apply -f blog-service.yaml

# 启用自动扩缩容
kubectl apply -f hpa.yaml

# 查看状态
kubectl get pods
kubectl get services
kubectl get hpa

4. 滚动更新

# 更新到新版本
kubectl set image deployment/blog blog=myregistry.com/blog:v1.1

# 查看更新过程
kubectl rollout status deployment/blog

# 如果有问题,回滚
kubectl rollout undo deployment/blog

获得的能力

  • ✅ 高可用:3 个副本,挂一个不影响服务
  • ✅ 自动扩容:CPU 高时自动增加副本
  • ✅ 自愈:Pod 挂了自动重启
  • ✅ 负载均衡:流量自动分发到多个 Pod
  • ✅ 滚动更新:不停机更新应用
  • ✅ 健康检查:自动移除不健康的 Pod

六、技术选型建议

6.1 什么时候用 Docker?

适合场景

  • ✅ 本地开发环境
  • ✅ 小规模应用(1-5 个容器)
  • ✅ 快速原型验证
  • ✅ CI/CD 构建环境
  • ✅ 学习容器技术

示例

# 快速启动开发数据库
docker run -d \
  --name dev-postgres \
  -e POSTGRES_PASSWORD=dev123 \
  -p 5432:5432 \
  postgres:15

# 使用 Docker Compose 管理多容器开发环境
docker-compose up

6.2 什么时候用 Kubernetes?

适合场景

  • ✅ 生产环境部署
  • ✅ 微服务架构
  • ✅ 需要自动扩缩容
  • ✅ 多环境管理(开发/测试/生产)
  • ✅ 大规模容器集群(10+ 容器)
  • ✅ 需要高可用和容灾

示例

  • 电商网站(流量波动大,需要自动扩容)
  • SaaS 应用(多租户,需要资源隔离)
  • 大数据处理(批处理任务调度)

6.3 技术演进路径

阶段 1:学习 Docker
├─ 理解容器概念
├─ 编写 Dockerfile
├─ 使用 Docker Compose
└─ 熟悉镜像管理

阶段 2:过渡期(Docker + 轻量编排)
├─ Docker Swarm(Docker 自带的编排)
└─ 或 Nomad、Rancher 等

阶段 3:Kubernetes
├─ 学习核心概念(Pod、Deployment、Service)
├─ 实践基本操作(部署、扩容、更新)
├─ 深入高级特性(网络、存储、安全)
└─ 生态工具(Helm、Istio、Prometheus)

七、常见问题解答

Q1: Docker 和虚拟机有什么区别?

虚拟机:
┌─────────────────────────────┐
│        应用 A    应用 B      │
│       ┌─────┐  ┌─────┐      │
│       │GuestOS│ │GuestOS│    │
│       └─────┘  └─────┘      │
│      Hypervisor (VMware)    │
│      Host OS (Windows)      │
│      硬件                    │
└─────────────────────────────┘

Docker 容器:
┌─────────────────────────────┐
│     容器 A     容器 B        │
│    ┌─────┐   ┌─────┐        │
│    │ App │   │ App │         │
│    └─────┘   └─────┘        │
│    Docker Engine            │
│    Host OS (Linux)          │
│    硬件                      │
└─────────────────────────────┘
对比项虚拟机Docker 容器
启动速度分钟级秒级
资源占用GB 级内存MB 级内存
隔离级别完全隔离(硬件级)进程隔离(共享内核)
性能有损耗接近原生
体积几 GB几十 MB

Q2: Kubernetes 一定要用 Docker 吗?

不一定! Kubernetes 支持多种容器运行时:

Kubernetes CRI (Container Runtime Interface)
        │
        ├─── Docker (通过 dockershim/cri-dockerd)
        ├─── containerd (推荐,CNCF 项目)
        ├─── CRI-O (Red Hat 主导)
        └─── Kata Containers (安全容器)

从 Kubernetes 1.24 开始,默认不再支持 Docker,推荐使用 containerd

Q3: 学习曲线有多陡峭?

Docker:         ⛰️ (1-2周入门)
Kubernetes:     🏔️🏔️🏔️ (1-3个月入门)

建议路径:
1. 先学 Linux 基础(2周)
2. 再学 Docker(2周)
3. 实践 Docker 项目(1个月)
4. 学习 Kubernetes 概念(2周)
5. 搭建 K8s 集群实践(1个月)
6. 深入生态工具(持续学习)

Q4: 成本如何?

Docker

  • 开源免费(Docker Engine)
  • Docker Desktop 商业使用需付费

Kubernetes

  • 开源免费
  • 但运维复杂,人力成本高
  • 云厂商托管服务(如 EKS、AKS、GKE)需付费

建议

  • 小团队:使用云厂商托管 K8s(省运维成本)
  • 大团队:自建集群(更灵活,成本可控)

Q5: 生产环境最佳实践?

Docker 镜像

# ❌ 不好的做法
FROM ubuntu
RUN apt-get update && apt-get install -y python3 ...
# 镜像 500MB+

# ✅ 最佳实践
FROM python:3.11-alpine    # 使用精简基础镜像
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt  # 不缓存
COPY . .
USER nobody                # 非 root 用户
HEALTHCHECK CMD curl -f http://localhost:8000/health || exit 1
# 镜像 50MB

Kubernetes 配置

# ✅ 设置资源限制
resources:
  requests:
    memory: "128Mi"
    cpu: "100m"
  limits:
    memory: "256Mi"
    cpu: "200m"

# ✅ 健康检查
livenessProbe:
  httpGet:
    path: /health
    port: 8080
readinessProbe:
  httpGet:
    path: /ready
    port: 8080

# ✅ 安全配置
securityContext:
  runAsNonRoot: true
  readOnlyRootFilesystem: true

# ✅ 多副本
replicas: 3

# ✅ 滚动更新策略
strategy:
  type: RollingUpdate
  rollingUpdate:
    maxSurge: 1
    maxUnavailable: 0

八、学习资源推荐

8.1 官方文档

  • Docker:https://docs.docker.com/
  • Kubernetes:https://kubernetes.io/docs/

8.2 实践环境

Docker

  • 本地安装 Docker Desktop
  • Play with Docker(在线环境):https://labs.play-with-docker.com/

Kubernetes

  • Minikube(本地单节点集群)
  • Kind(Docker 中运行 K8s)
  • K3s(轻量级 K8s)
  • Play with Kubernetes(在线环境):https://labs.play-with-k8s.com/

8.3 学习路线

1. Docker 基础(1-2周)
   ├─ 容器概念
   ├─ Dockerfile 编写
   ├─ Docker Compose
   └─ 镜像管理

2. Docker 进阶(1-2周)
   ├─ 网络模式
   ├─ 数据卷
   ├─ 多阶段构建
   └─ 安全最佳实践

3. Kubernetes 基础(2-4周)
   ├─ 架构原理
   ├─ Pod、Deployment、Service
   ├─ ConfigMap、Secret
   └─ 基本操作

4. Kubernetes 进阶(1-2个月)
   ├─ 网络(Service、Ingress、NetworkPolicy)
   ├─ 存储(PV、PVC、StorageClass)
   ├─ 调度(亲和性、污点、容忍)
   └─ 安全(RBAC、SecurityContext、NetworkPolicy)

5. 生态工具(持续学习)
   ├─ Helm(包管理)
   ├─ Istio(服务网格)
   ├─ Prometheus + Grafana(监控)
   └─ ArgoCD(GitOps)

九、总结

9.1 核心要点回顾

Docker

  • 🎯 定位:容器化技术,解决"在我机器上能跑"问题
  • 🔧 核心:镜像(Image)、容器(Container)、仓库(Registry)
  • 💡 原理:Namespace、Cgroups、UnionFS
  • ✅ 适用:开发测试、小规模部署

Kubernetes

  • 🎯 定位:容器编排平台,解决大规模容器管理问题
  • 🔧 核心:Pod、Deployment、Service、Ingress
  • 💡 原理:声明式 API、控制器模式、调度系统
  • ✅ 适用:生产环境、微服务架构、自动化运维

关系

  • Docker 提供容器技术基础
  • Kubernetes 提供编排管理能力
  • 两者配合,构建现代云原生应用

9.2 技术演进趋势

过去:物理机 → 虚拟机
现在:容器(Docker)→ 容器编排(Kubernetes)
未来:Serverless、边缘计算、WebAssembly

Kubernetes 已成为容器编排的事实标准
云原生技术栈的核心基础设施

9.3 行动建议

如果你是初学者

  1. 先掌握 Docker 基础
  2. 用 Docker Compose 管理多容器应用
  3. 学习 Kubernetes 概念
  4. 在本地搭建 Minikube 实践

如果你是开发者

  1. 为项目编写 Dockerfile
  2. 使用 Docker 统一开发环境
  3. 学习编写 K8s Manifest
  4. 参与部署流程

如果你是运维人员

  1. 深入学习 K8s 架构
  2. 掌握集群运维技能
  3. 学习监控、日志、安全
  4. 关注云原生生态

结语

Docker 和 Kubernetes 是现代软件工程的基石技术。Docker 让我们能够轻松打包和运行应用,Kubernetes 让我们能够大规模管理这些应用。虽然学习曲线较陡,但掌握这两项技术将极大提升你的技术能力和职业竞争力。

记住:先理解原理,再动手实践,最后融入日常工作。 容器技术不是银弹,但它确实是解决现代软件部署问题的最佳方案之一。

希望这篇文章能帮助你建立对 Docker 和 Kubernetes 的清晰认识。现在,开始你的容器化之旅吧!


作者:Claude Code
日期:2025-11-07
标签:#Docker #Kubernetes #容器技术 #云原生 #DevOps


附录:常用命令速查

Docker 命令

# 镜像操作
docker build -t myapp:v1 .          # 构建镜像
docker images                        # 查看镜像
docker pull nginx:latest             # 拉取镜像
docker push myapp:v1                 # 推送镜像
docker rmi myapp:v1                  # 删除镜像

# 容器操作
docker run -d -p 8080:80 nginx       # 运行容器
docker ps                            # 查看运行中容器
docker ps -a                         # 查看所有容器
docker stop <container-id>           # 停止容器
docker start <container-id>          # 启动容器
docker rm <container-id>             # 删除容器
docker logs <container-id>           # 查看日志
docker exec -it <container-id> sh    # 进入容器

# Docker Compose
docker-compose up -d                 # 启动服务
docker-compose down                  # 停止并删除服务
docker-compose logs -f               # 查看日志

Kubernetes 命令

# 集群信息
kubectl cluster-info                 # 集群信息
kubectl get nodes                    # 查看节点

# Pod 操作
kubectl get pods                     # 查看 Pod
kubectl describe pod <pod-name>      # Pod 详情
kubectl logs <pod-name>              # 查看日志
kubectl exec -it <pod-name> -- sh    # 进入 Pod
kubectl delete pod <pod-name>        # 删除 Pod

# Deployment 操作
kubectl get deployments              # 查看部署
kubectl create deployment nginx --image=nginx:latest
kubectl scale deployment nginx --replicas=5
kubectl set image deployment/nginx nginx=nginx:1.25
kubectl rollout status deployment/nginx
kubectl rollout undo deployment/nginx

# Service 操作
kubectl get services                 # 查看服务
kubectl expose deployment nginx --port=80 --type=LoadBalancer

# 配置管理
kubectl apply -f app.yaml            # 应用配置
kubectl delete -f app.yaml           # 删除配置
kubectl get all                      # 查看所有资源

# 命名空间
kubectl get namespaces               # 查看命名空间
kubectl create namespace dev         # 创建命名空间
kubectl config set-context --current --namespace=dev  # 切换命名空间

Happy Containerizing! 🐳☸️

更多推荐