一、引言
容器技术已经成为现代软件开发和部署的标准实践。相比传统虚拟机,容器具有轻量级、启动快速、资源利用率高、环境一致性好等显著优势。Docker作为容器技术的代表,已经在DevOps、微服务架构、持续集成等场景中得到广泛应用。
openEuler作为面向企业级应用的开源操作系统,对容器技术提供了完善的支持。除了兼容Docker之外,openEuler还自主研发了iSula轻量级容器引擎,在启动速度、内存占用等方面表现优异。特别是在WSL2环境下,openEuler能够无缝运行Docker,为开发者提供与Linux服务器一致的容器化开发体验。
本文将基于openEuler 24.03 LTS版本,系统介绍容器化技术的完整实践。从Docker的安装配置、镜像构建、容器管理,到多容器编排、网络配置、数据持久化,再到实际应用的容器化改造和生产部署,全面覆盖容器化技术栈。通过实际操作和最佳实践,帮助开发者掌握在openEuler上进行容器化开发和部署的完整流程。
二、Docker环境搭建
2.1 Docker安装
openEuler 24.03已经内置了Docker支持,安装非常简单:
bash
# 检查系统版本
cat /etc/os-release
# 安装Docker
sudo dnf install -y docker
# 启动Docker服务
sudo systemctl start docker
sudo systemctl enable docker
# 验证安装
docker --version
# Docker version 20.10.x
# 查看Docker信息
docker info
# 运行hello-world测试
sudo docker run hello-world


2.2 配置Docker权限
默认情况下需要sudo才能运行docker命令,我们可以添加用户到docker组:
bash
# 创建docker组(如果不存在)
sudo groupadd docker
# 将当前用户添加到docker组
sudo usermod -aG docker $USER
# 重新登录或刷新组权限
newgrp docker
# 验证(无需sudo)
docker ps
# 测试
docker run hello-world
2.3 配置Docker镜像加速
使用国内镜像源可以大幅提升镜像拉取速度:
创建Docker配置目录
bash
# 创建Docker配置目录
sudo mkdir -p /etc/docker
# 配置镜像加速
sudo tee /etc/docker/daemon.json > /dev/null << 'EOF'
{
"registry-mirrors": [
"https://mirror.ccs.tencentyun.com",
"https://docker.mirrors.ustc.edu.cn",
"https://hub-mirror.c.163.com"
],
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
},
"storage-driver": "overlay2"
}
EOF
# 重启Docker服务
sudo systemctl daemon-reload
sudo systemctl restart docker
# 验证配置
docker info | grep -A 5 "Registry Mirrors"
三、Docker基础操作
3.1 镜像操作
bash
# 搜索镜像
docker search nginx
# 拉取镜像
docker pull nginx:latest
docker pull python:3.11-alpine
docker pull ubuntu:22.04
# 列出本地镜像
docker images
# 查看镜像详细信息
docker inspect nginx:latest
# 删除镜像
docker rmi image_name:tag
# 导出镜像
docker save -o nginx.tar nginx:latest
# 导入镜像
docker load -i nginx.tar
# 给镜像打标签
docker tag nginx:latest myregistry.com/nginx:v1.0
# 清理悬空镜像
docker image prune
3.2 容器操作
bash
# 运行容器
docker run -d --name mynginx -p 8080:80 nginx
# 参数说明:
# -d: 后台运行
# --name: 指定容器名称
# -p: 端口映射 host:container
# 列出运行中的容器
docker ps
# 列出所有容器(包括已停止)
docker ps -a
# 查看容器日志
docker logs mynginx
docker logs -f mynginx # 实时输出
# 进入容器
docker exec -it mynginx bash
# 停止容器
docker stop mynginx
# 启动容器
docker start mynginx
# 重启容器
docker restart mynginx
# 删除容器
docker rm mynginx
# 强制删除运行中的容器
docker rm -f mynginx
# 查看容器详细信息
docker inspect mynginx
# 查看容器资源使用
docker stats mynginx
# 容器与主机文件复制
docker cp mynginx:/etc/nginx/nginx.conf ./
docker cp ./index.html mynginx:/usr/share/nginx/html/
3.3 常用容器运行案例
运行Nginx Web服务器:
bash
docker run -d \
--name web \
-p 8080:80 \
-v $(pwd)/html:/usr/share/nginx/html:ro \
--restart=always \
nginx:alpine
# 访问测试
curl http://localhost:8080
运行MySQL数据库:
ini
docker run -d \
--name mysql \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=rootpass \
-e MYSQL_DATABASE=mydb \
-v mysql_data:/var/lib/mysql \
--restart=always \
mysql:8.0
# 连接测试
docker exec -it mysql mysql -uroot -prootpass
连接测试
bash
docker run -d \
--name redis \
-p 6379:6379 \
-v redis_data:/data \
--restart=always \
redis:alpine redis-server --appendonly yes
# 测试连接
docker exec -it redis redis-cli ping

四、Dockerfile镜像构建
4.1 Dockerfile基础语法
ini
# Dockerfile示例
# 基础镜像
FROM python:3.11-slim
# 维护者信息
LABEL maintainer="your.email@example.com"
LABEL version="1.0"
LABEL description="Python Flask应用"
# 设置环境变量
ENV PYTHONUNBUFFERED=1 \
APP_HOME=/app
# 设置工作目录
WORKDIR $APP_HOME
# 复制依赖文件
COPY requirements.txt .
# 安装依赖
RUN pip install --no-cache-dir -r requirements.txt
# 复制应用代码
COPY . .
# 暴露端口
EXPOSE 5000
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost:5000/health || exit 1
# 启动命令
CMD ["python", "app.py"]

4.2 构建Python Flask应用镜像
项目结构:
flask_app/
├── Dockerfile
├── requirements.txt
├── app.py
└── templates/
└── index.html
python
from flask import Flask, jsonify, render_template
import os
import socket
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
@app.route('/api/info')
def info():
return jsonify({
'hostname': socket.gethostname(),
'python_version': os.sys.version,
'env': os.environ.get('ENVIRONMENT', 'development')
})
@app.route('/health')
def health():
return jsonify({'status': 'healthy'}), 200
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
requirements.txt:
ini
Flask==3.0.0
gunicorn==21.2.0
Dockerfile:
bash
FROM python:3.11-slim
# 安装系统依赖
RUN apt-get update && \
apt-get install -y --no-install-recommends curl && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 5000
HEALTHCHECK CMD curl -f http://localhost:5000/health || exit 1
CMD ["gunicorn", "-b", "0.0.0.0:5000", "-w", "4", "app:app"]
构建和运行:
bash
# 构建镜像
docker build -t myapp:1.0 .
# 查看构建的镜像
docker images | grep myapp
# 运行容器
docker run -d \
--name myapp \
-p 5000:5000 \
-e ENVIRONMENT=production \
myapp:1.0
# 测试应用
curl http://localhost:5000/api/info
# 查看日志
docker logs -f myapp
4.3 多阶段构建优化
多阶段构建可以显著减小镜像大小:
bash
# 第一阶段:构建
FROM python:3.11 as builder
WORKDIR /build
COPY requirements.txt .
RUN pip install --user --no-cache-dir -r requirements.txt
# 第二阶段:运行
FROM python:3.11-slim
WORKDIR /app
# 从构建阶段复制依赖
COPY --from=builder /root/.local /root/.local
# 复制应用代码
COPY . .
# 确保pip安装的包在PATH中
ENV PATH=/root/.local/bin:$PATH
EXPOSE 5000
CMD ["python", "app.py"]
对比效果:
perl
# 单阶段构建
docker build -t myapp:single .
docker images | grep myapp
# myapp single 850MB
# 多阶段构建
docker build -t myapp:multi -f Dockerfile.multi .
docker images | grep myapp
# myapp multi 180MB
五、Docker Compose多容器编排
5.1 安装Docker Compose
bash
# 下载Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/v2.23.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 添加执行权限
sudo chmod +x /usr/local/bin/docker-compose
# 验证安装
docker-compose --version
# Docker Compose version v2.23.0
5.2 Web应用完整栈
项目结构:
webapp/
├── docker-compose.yml
├── nginx/
│ └── nginx.conf
├── backend/
│ ├── Dockerfile
│ ├── app.py
│ └── requirements.txt
└── frontend/
├── Dockerfile
└── index.html
docker-compose.yml:
yaml
version: '3.8'
services:
# 数据库
db:
image: postgres:15-alpine
container_name: webapp_db
environment:
POSTGRES_DB: webapp
POSTGRES_USER: dbuser
POSTGRES_PASSWORD: dbpass
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- backend
healthcheck:
test: ["CMD-SHELL", "pg_isready -U dbuser"]
interval: 10s
timeout: 5s
retries: 5
# Redis缓存
redis:
image: redis:alpine
container_name: webapp_redis
networks:
- backend
command: redis-server --appendonly yes
volumes:
- redis_data:/data
# 后端API
backend:
build:
context: ./backend
dockerfile: Dockerfile
container_name: webapp_backend
environment:
DATABASE_URL: postgresql://dbuser:dbpass@db:5432/webapp
REDIS_URL: redis://redis:6379/0
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
networks:
- backend
- frontend
restart: always
# 前端应用
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
container_name: webapp_frontend
networks:
- frontend
restart: always
# Nginx反向代理
nginx:
image: nginx:alpine
container_name: webapp_nginx
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./nginx/ssl:/etc/nginx/ssl:ro
depends_on:
- backend
- frontend
networks:
- frontend
restart: always
networks:
backend:
driver: bridge
frontend:
driver: bridge
volumes:
postgres_data:
redis_data:
nginx/nginx.conf:
ini
events {
worker_connections 1024;
}
http {
upstream backend {
server backend:5000;
}
upstream frontend {
server frontend:80;
}
server {
listen 80;
server_name localhost;
# 前端
location / {
proxy_pass http://frontend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 后端API
location /api {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# 健康检查
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
}
}
启动和管理:
ini
# 启动所有服务
docker-compose up -d
# 查看服务状态
docker-compose ps
# 查看日志
docker-compose logs -f
# 查看特定服务日志
docker-compose logs -f backend
# 重启服务
docker-compose restart backend
# 停止所有服务
docker-compose stop
# 停止并删除容器
docker-compose down
# 删除容器和数据卷
docker-compose down -v
# 重新构建并启动
docker-compose up -d --build
# 扩展服务实例
docker-compose up -d --scale backend=3

六、数据持久化与网络配置
6.1 数据卷管理
bash
# 创建数据卷
docker volume create mydata
# 列出所有数据卷
docker volume ls
# 查看数据卷详情
docker volume inspect mydata
# 使用数据卷
docker run -d \
--name app \
-v mydata:/app/data \
myimage
# 绑定挂载(宿主机目录)
docker run -d \
--name app \
-v $(pwd)/data:/app/data \
myimage
# 只读挂载
docker run -d \
--name app \
-v $(pwd)/config:/app/config:ro \
myimage
# 备份数据卷
docker run --rm \
-v mydata:/source \
-v $(pwd)/backup:/backup \
alpine tar czf /backup/mydata_backup.tar.gz -C /source .
# 恢复数据卷
docker run --rm \
-v mydata:/target \
-v $(pwd)/backup:/backup \
alpine tar xzf /backup/mydata_backup.tar.gz -C /target
# 删除数据卷
docker volume rm mydata
# 清理未使用的数据卷
docker volume prune
6.2 网络配置
bash
# 创建自定义网络
docker network create mynetwork
docker network create --driver bridge --subnet=172.18.0.0/16 custom_net
# 列出网络
docker network ls
# 查看网络详情
docker network inspect mynetwork
# 连接容器到网络
docker network connect mynetwork container_name
# 断开网络连接
docker network disconnect mynetwork container_name
# 创建容器时指定网络
docker run -d \
--name app \
--network mynetwork \
--network-alias app \
myimage
# 查看容器网络配置
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_name
# 删除网络
docker network rm mynetwork
# 清理未使用的网络
docker network prune
6.3 容器间通信示例
ini
# 创建自定义网络
docker network create appnet
# 启动数据库容器
docker run -d \
--name db \
--network appnet \
--network-alias database \
-e POSTGRES_PASSWORD=secret \
postgres:15
# 启动应用容器(可以通过'database'访问数据库)
docker run -d \
--name app \
--network appnet \
-e DB_HOST=database \
-e DB_PORT=5432 \
-e DB_PASSWORD=secret \
myapp
# 测试连接
docker exec app ping database
docker exec app nc -zv database 5432
七、实战案例:WordPress部署
7.1 使用Docker Compose部署WordPress
yaml
# wordpress/docker-compose.yml
version: '3.8'
services:
wordpress:
image: wordpress:latest
container_name: wordpress
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: wpuser
WORDPRESS_DB_PASSWORD: wppass
WORDPRESS_DB_NAME: wordpress
volumes:
- wordpress_data:/var/www/html
depends_on:
- db
restart: always
db:
image: mysql:8.0
container_name: wordpress_db
environment:
MYSQL_DATABASE: wordpress
MYSQL_USER: wpuser
MYSQL_PASSWORD: wppass
MYSQL_ROOT_PASSWORD: rootpass
volumes:
- db_data:/var/lib/mysql
restart: always
volumes:
wordpress_data:
db_data:
bash
# 启动WordPress
cd wordpress
docker-compose up -d
# 查看状态
docker-compose ps
# 访问 http://localhost:8080 完成安装
# 备份
docker-compose exec db mysqldump -u root -prootpass wordpress > wordpress_backup.sql
# 查看日志
docker-compose logs -f wordpress

八、容器监控与日志管理
8.1 资源监控
bash
# 查看所有容器资源使用
docker stats
# 查看特定容器
docker stats container_name
# 查看容器进程
docker top container_name
# 查看容器事件
docker events
# 查看容器端口映射
docker port container_name
8.2 日志管理
bash
# 查看日志
docker logs container_name
# 实时跟踪日志
docker logs -f container_name
# 查看最近100行
docker logs --tail 100 container_name
# 查看时间范围
docker logs --since 10m container_name
docker logs --until 2024-01-01T00:00:00 container_name
# 配置日志驱动(daemon.json)
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3",
"compress": "true"
}
}
8.3 集成Prometheus监控
yaml
# monitoring/docker-compose.yml
version: '3.8'
services:
prometheus:
image: prom/prometheus
container_name: prometheus
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
restart: always
grafana:
image: grafana/grafana
container_name: grafana
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
volumes:
- grafana_data:/var/lib/grafana
depends_on:
- prometheus
restart: always
cadvisor:
image: gcr.io/cadvisor/cadvisor
container_name: cadvisor
ports:
- "8090:8080"
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
restart: always
volumes:
prometheus_data:
grafana_data:
九、生产环境最佳实践
9.1 安全加固
ini
# 使用非root用户运行
FROM python:3.11-slim
RUN useradd -m -u 1000 appuser
WORKDIR /app
COPY --chown=appuser:appuser . .
USER appuser
CMD ["python", "app.py"]
# 扫描镜像漏洞
docker scan myimage:latest
# 限制容器资源
docker run -d \
--name app \
--memory="512m" \
--cpus="1.0" \
--pids-limit=100 \
myimage
9.2 健康检查
bash
# Dockerfile中添加健康检查
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
CMD curl -f http://localhost:5000/health || exit 1
# docker-compose.yml中配置
services:
app:
image: myapp
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:5000/health"]
interval: 30s
timeout: 3s
retries: 3
start_period: 40s
9.3 自动重启策略
ini
# 容器退出时总是重启
docker run -d --restart=always myimage
# 仅非正常退出时重启
docker run -d --restart=on-failure:5 myimage
# 除非手动停止,否则重启
docker run -d --restart=unless-stopped myimage
十、总结与展望
通过本次在openEuler上的容器化实践,我们全面掌握了从基础的Docker操作到生产环境部署的完整技能。openEuler提供的稳定系统环境和完善的Docker支持,为容器化应用提供了可靠的运行平台。
核心收获:
- ✅ Docker基础操作和镜像管理
- ✅ Dockerfile编写和多阶段构建
- ✅ Docker Compose多容器编排
- ✅ 数据持久化和网络配置
- ✅ 监控日志和生产部署
下一步方向:
- Kubernetes容器编排
- CI/CD流水线集成
- 微服务架构实践
- 服务网格(Service Mesh)
- 容器安全加固
参考资源:
- Docker官方文档:docs.docker.com/
- Docker Compose文档:docs.docker.com/compose/
- openEuler容器指南:docs.openEuler.openatom.cn/
作者声明:本文为原创技术实践文章,所有操作均在openEuler 24.03 LTS + Docker环境中验证。