Docker与Kubernetes入门指南-小白也能看懂的容器技术
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 解决了单个容器的问题,但在生产环境中,你会面临:
- 容器太多管理不过来:几十上百个容器怎么管理?
- 容器挂了怎么办:谁来自动重启?
- 流量高峰怎么办:如何自动扩容?
- 服务如何互相发现:容器 IP 会变,如何通信?
- 如何滚动更新:怎样不停机更新应用?
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-servicemyapp.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 会:
- 观察当前状态(只有 2 个?)
- 对比期望状态(应该有 3 个)
- 执行调谐动作(创建 1 个)
- 持续循环这个过程
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 核心区别
| 维度 | Docker | Kubernetes |
|---|---|---|
| 定位 | 容器引擎(单机工具) | 容器编排平台(集群管理) |
| 解决问题 | 应用打包和运行 | 大规模容器管理和调度 |
| 管理范围 | 单个主机上的容器 | 多台主机组成的集群 |
| 核心功能 | 构建、运行、分享容器 | 部署、扩缩、负载均衡、自愈 |
| 学习曲线 | 相对简单 | 较为复杂 |
| 适用场景 | 开发测试、小规模部署 | 生产环境、大规模部署 |
4.2 形象比喻
Docker:
就像买了一辆汽车(容器)
你可以开车、停车、加油
适合个人使用
Kubernetes:
就像管理一个出租车公司
- 调度系统:哪辆车去接哪个订单
- 监控系统:车辆位置、状态监控
- 维修系统:车坏了自动派新车
- 扩容系统:高峰期增加车辆
适合企业运营
4.3 协作关系
┌─────────────────────────────────────────┐
│ 应用开发者 │
│ │
│ 编写 Dockerfile 构建镜像 │
└──────────────┬──────────────────────────┘
│
▼
┌──────────────────────────────────────────┐
│ Docker │
│ │
│ • 构建镜像:docker build │
│ • 推送镜像:docker push │
│ • 运行容器:docker run │
└──────────────┬───────────────────────────┘
│ 提供容器运行时
▼
┌──────────────────────────────────────────┐
│ Kubernetes │
│ │
│ • 拉取镜像:从仓库获取 │
│ • 创建 Pod:使用 Docker 创建容器 │
│ • 管理生命周期:调度、扩缩容、自愈 │
│ • 服务发现:负载均衡 │
└──────────────────────────────────────────┘
关系总结:
- Docker 是基础:Kubernetes 需要容器运行时(Docker 或 containerd)
- 分工明确:Docker 负责容器技术,K8s 负责编排管理
- 可以独立使用:小项目用 Docker,大项目用 K8s
- 也可以配合: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 行动建议
如果你是初学者:
- 先掌握 Docker 基础
- 用 Docker Compose 管理多容器应用
- 学习 Kubernetes 概念
- 在本地搭建 Minikube 实践
如果你是开发者:
- 为项目编写 Dockerfile
- 使用 Docker 统一开发环境
- 学习编写 K8s Manifest
- 参与部署流程
如果你是运维人员:
- 深入学习 K8s 架构
- 掌握集群运维技能
- 学习监控、日志、安全
- 关注云原生生态
结语
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! 🐳☸️
更多推荐
所有评论(0)