searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

容器从Docker运行态迁移到Containerd实践

2025-12-04 02:54:35
3
0

        目前部分传统行业客户的生产环境中仍在使用Docker作为容器运行时,当面临向containerd迁移的升级需求时,主要存在以下几个顾虑:一是担心历史遗留应用的兼容性问题,特别是那些依赖特定Docker API接口或使用非标准实现方式的老旧应用;二是对containerd的日志采集、网络配置等运维管理方式的改变存在适应成本;三是部分应用可能使用了Docker特有的功能或参数配置,需要评估改造范围;四是对containerd的稳定性和成熟度仍持观望态度,尤其是在关键业务系统中的表现。这些客户普遍希望能够获得平滑的迁移路径和充分的验证周期,确保业务连续性不受影响

一、Docker和Containerd对比

1.1 技术架构对比

Docker架构

text
Docker客户端 → Docker守护进程(dockerd) → containerd → runc

Docker是一个完整的容器平台,包含镜像构建、网络、存储、API等完整功能。

Containerd架构

text
Kubelet(CRI接口) → Containerd → runc

Containerd是专注于容器生命周期的核心运行时,职责单一、架构简洁。

核心差异

  • Docker:全功能平台,适合独立使用

  • Containerd:专业运行时,适合集成到Kubernetes等系统中

1.2 厂商和生态支持

Docker

  • Docker公司维护

  • 社区活跃,工具生态丰富

  • 桌面版、企业版等多种产品

  • 但随着Kubernetes成为标准,Docker在云原生领域影响力下降

Containerd

  • CNCF(云原生计算基金会)毕业项目

  • 得到Google、AWS、Azure等主流云厂商支持

  • 专注于成为标准容器运行时

  • Kubernetes原生支持

1.3 Kubernetes官方路线

  • 2016年:Kubernetes引入CRI(容器运行时接口)

  • 2018年:Kubernetes 1.10正式支持Containerd作为运行时

  • 2020年:Kubernetes 1.20宣布弃用Docker支持

  • 2021年:Kubernetes 1.22+默认不再支持Docker

  • 当前:Containerd是Kubernetes推荐的容器运行时

二、为什么用Containerd替代Docker

2.1 性能优势

对比项 Docker Containerd 优势说明
内存占用 ~350MB ~80MB 减少77%内存使用
启动速度 较慢 更快 容器启动快30-40%
镜像拉取 100MB/s 120MB/s 提升20%传输速度
CPU占用 较高 较低 更少的系统开销

关键原因

  • Containerd组件更少,调用链更短

  • 专为Kubernetes优化,去除了Docker中不必要的功能

  • 更高效的并发处理能力

2.2 安全性提升

安全特性 Docker Containerd 优势
攻击面 较大 较小 更少的组件,更少的漏洞风险
权限控制 完整 更精细 更好的安全隔离
默认配置 较宽松 更严格 默认更安全
审计跟踪 一般 更好 所有操作通过标准接口

安全改进

  1. 减少了50%以上的代码量

  2. 移除了不必要的网络和存储功能

  3. 更严格的默认安全策略

  4. 更好的权限分离机制

2.3 维护和稳定性

维护方面 Docker Containerd 说明
更新频率 频繁 稳定 Containerd发布更稳定
向后兼容 一般 优秀 Containerd保持良好兼容性
问题排查 复杂 简单 组件少,问题定位容易
社区支持 全面 专业 Containerd专注于运行时

三、从Docker迁移到Containerd的实践指南

3.1 迁移前提条件

检查清单

  1. 应用已容器化,有Dockerfile

  2. 镜像已推送到镜像仓库(Docker Hub、私有仓库等)

  3. 有Kubernetes部署配置文件(或可以创建)

  4. 目标集群已安装Containerd作为运行时

3.2 重新部署应用的具体步骤

步骤1:准备镜像

bash
# 如果使用原有Docker镜像
# 1. 确保镜像已推送到镜像仓库
docker push your-registry.com/your-app:v1.0

# 2. 或者使用原有镜像(如果仓库支持多架构)
# 无需特殊操作,Containerd可以拉取标准OCI镜像

步骤2:创建Kubernetes部署文件

原Docker运行命令

bash
docker run -d \
  --name myapp \
  -p 8080:80 \
  -v /data:/app/data \
  -e DB_HOST=db.example.com \
  your-registry.com/your-app:v1.0

转换为Kubernetes部署文件

yaml
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: your-registry.com/your-app:v1.0  # 使用相同的镜像
        ports:
        - containerPort: 80
        env:
        - name: DB_HOST
          value: "db.example.com"
        volumeMounts:
        - name: app-data
          mountPath: /app/data
      volumes:
      - name: app-data
        hostPath:
          path: /data
---
# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: myapp-service
spec:
  selector:
    app: myapp
  ports:
  - port: 8080
    targetPort: 80
  type: LoadBalancer

步骤3:部署Containerd集群,建议通过云平台订购Containerd容器集群,可自动创建

步骤4:部署到Containerd集群

bash
# 1. 应用部署配置
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml

# 2. 检查部署状态
kubectl get pods
kubectl get services

# 3. 查看日志(替代docker logs)
kubectl logs deployment/myapp

# 4. 进入容器(替代docker exec)
kubectl exec -it deployment/myapp -- /bin/bash


3.3 简单迁移示例

假设有一个简单的Web应用:

原Docker运行方式

bash
# 构建镜像
docker build -t my-webapp:v1 .

# 运行容器
docker run -d -p 80:8080 my-webapp:v1

迁移到Containerd/Kubernetes

yaml
# 1. 推送镜像到仓库
docker tag my-webapp:v1 my-registry.com/my-webapp:v1
docker push my-registry.com/my-webapp:v1

# 2. 创建deployment.yaml
cat > deployment.yaml <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: webapp
spec:
  replicas: 2
  selector:
    matchLabels:
      app: webapp
  template:
    metadata:
      labels:
        app: webapp
    spec:
      containers:
      - name: webapp
        image: my-registry.com/my-webapp:v1
        ports:
        - containerPort: 8080
EOF

# 3. 创建service.yaml
cat > service.yaml <<EOF
apiVersion: v1
kind: Service
metadata:
  name: webapp-service
spec:
  selector:
    app: webapp
  ports:
  - port: 80
    targetPort: 8080
  type: LoadBalancer
EOF

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


0条评论
0 / 1000
廖****波
21文章数
0粉丝数
廖****波
21 文章 | 0 粉丝
原创

容器从Docker运行态迁移到Containerd实践

2025-12-04 02:54:35
3
0

        目前部分传统行业客户的生产环境中仍在使用Docker作为容器运行时,当面临向containerd迁移的升级需求时,主要存在以下几个顾虑:一是担心历史遗留应用的兼容性问题,特别是那些依赖特定Docker API接口或使用非标准实现方式的老旧应用;二是对containerd的日志采集、网络配置等运维管理方式的改变存在适应成本;三是部分应用可能使用了Docker特有的功能或参数配置,需要评估改造范围;四是对containerd的稳定性和成熟度仍持观望态度,尤其是在关键业务系统中的表现。这些客户普遍希望能够获得平滑的迁移路径和充分的验证周期,确保业务连续性不受影响

一、Docker和Containerd对比

1.1 技术架构对比

Docker架构

text
Docker客户端 → Docker守护进程(dockerd) → containerd → runc

Docker是一个完整的容器平台,包含镜像构建、网络、存储、API等完整功能。

Containerd架构

text
Kubelet(CRI接口) → Containerd → runc

Containerd是专注于容器生命周期的核心运行时,职责单一、架构简洁。

核心差异

  • Docker:全功能平台,适合独立使用

  • Containerd:专业运行时,适合集成到Kubernetes等系统中

1.2 厂商和生态支持

Docker

  • Docker公司维护

  • 社区活跃,工具生态丰富

  • 桌面版、企业版等多种产品

  • 但随着Kubernetes成为标准,Docker在云原生领域影响力下降

Containerd

  • CNCF(云原生计算基金会)毕业项目

  • 得到Google、AWS、Azure等主流云厂商支持

  • 专注于成为标准容器运行时

  • Kubernetes原生支持

1.3 Kubernetes官方路线

  • 2016年:Kubernetes引入CRI(容器运行时接口)

  • 2018年:Kubernetes 1.10正式支持Containerd作为运行时

  • 2020年:Kubernetes 1.20宣布弃用Docker支持

  • 2021年:Kubernetes 1.22+默认不再支持Docker

  • 当前:Containerd是Kubernetes推荐的容器运行时

二、为什么用Containerd替代Docker

2.1 性能优势

对比项 Docker Containerd 优势说明
内存占用 ~350MB ~80MB 减少77%内存使用
启动速度 较慢 更快 容器启动快30-40%
镜像拉取 100MB/s 120MB/s 提升20%传输速度
CPU占用 较高 较低 更少的系统开销

关键原因

  • Containerd组件更少,调用链更短

  • 专为Kubernetes优化,去除了Docker中不必要的功能

  • 更高效的并发处理能力

2.2 安全性提升

安全特性 Docker Containerd 优势
攻击面 较大 较小 更少的组件,更少的漏洞风险
权限控制 完整 更精细 更好的安全隔离
默认配置 较宽松 更严格 默认更安全
审计跟踪 一般 更好 所有操作通过标准接口

安全改进

  1. 减少了50%以上的代码量

  2. 移除了不必要的网络和存储功能

  3. 更严格的默认安全策略

  4. 更好的权限分离机制

2.3 维护和稳定性

维护方面 Docker Containerd 说明
更新频率 频繁 稳定 Containerd发布更稳定
向后兼容 一般 优秀 Containerd保持良好兼容性
问题排查 复杂 简单 组件少,问题定位容易
社区支持 全面 专业 Containerd专注于运行时

三、从Docker迁移到Containerd的实践指南

3.1 迁移前提条件

检查清单

  1. 应用已容器化,有Dockerfile

  2. 镜像已推送到镜像仓库(Docker Hub、私有仓库等)

  3. 有Kubernetes部署配置文件(或可以创建)

  4. 目标集群已安装Containerd作为运行时

3.2 重新部署应用的具体步骤

步骤1:准备镜像

bash
# 如果使用原有Docker镜像
# 1. 确保镜像已推送到镜像仓库
docker push your-registry.com/your-app:v1.0

# 2. 或者使用原有镜像(如果仓库支持多架构)
# 无需特殊操作,Containerd可以拉取标准OCI镜像

步骤2:创建Kubernetes部署文件

原Docker运行命令

bash
docker run -d \
  --name myapp \
  -p 8080:80 \
  -v /data:/app/data \
  -e DB_HOST=db.example.com \
  your-registry.com/your-app:v1.0

转换为Kubernetes部署文件

yaml
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: your-registry.com/your-app:v1.0  # 使用相同的镜像
        ports:
        - containerPort: 80
        env:
        - name: DB_HOST
          value: "db.example.com"
        volumeMounts:
        - name: app-data
          mountPath: /app/data
      volumes:
      - name: app-data
        hostPath:
          path: /data
---
# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: myapp-service
spec:
  selector:
    app: myapp
  ports:
  - port: 8080
    targetPort: 80
  type: LoadBalancer

步骤3:部署Containerd集群,建议通过云平台订购Containerd容器集群,可自动创建

步骤4:部署到Containerd集群

bash
# 1. 应用部署配置
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml

# 2. 检查部署状态
kubectl get pods
kubectl get services

# 3. 查看日志(替代docker logs)
kubectl logs deployment/myapp

# 4. 进入容器(替代docker exec)
kubectl exec -it deployment/myapp -- /bin/bash


3.3 简单迁移示例

假设有一个简单的Web应用:

原Docker运行方式

bash
# 构建镜像
docker build -t my-webapp:v1 .

# 运行容器
docker run -d -p 80:8080 my-webapp:v1

迁移到Containerd/Kubernetes

yaml
# 1. 推送镜像到仓库
docker tag my-webapp:v1 my-registry.com/my-webapp:v1
docker push my-registry.com/my-webapp:v1

# 2. 创建deployment.yaml
cat > deployment.yaml <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: webapp
spec:
  replicas: 2
  selector:
    matchLabels:
      app: webapp
  template:
    metadata:
      labels:
        app: webapp
    spec:
      containers:
      - name: webapp
        image: my-registry.com/my-webapp:v1
        ports:
        - containerPort: 8080
EOF

# 3. 创建service.yaml
cat > service.yaml <<EOF
apiVersion: v1
kind: Service
metadata:
  name: webapp-service
spec:
  selector:
    app: webapp
  ports:
  - port: 80
    targetPort: 8080
  type: LoadBalancer
EOF

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


文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
0
0