赞
踩
目录
Docker 是一种领先的容器化平台,可以简化应用程序的开发、部署和管理。通过使用 Docker,您可以创建一致、可移植且可扩展的环境,从而实现高效的开发和运营。本指南将介绍 Docker 的最佳实践,帮助您充分利用 Docker 的潜力并确保应用程序的安全性和性能。
容器运行权限
避免容器以 root
用户身份运行:
root
用户身份运行的。root
权限,可能对主机造成威胁。USER
指令,将容器默认用户设置为非特权用户,例如: - FROM ubuntu:latest
- RUN groupadd -r appgroup && useradd -r -g appgroup appuser
- USER appuser
以非特权用户身份运行:
--user
标志指定非特权用户: docker run --user 1000:1000 myimage
- version: '3'
- services:
- app:
- image: myimage
- user: "1000:1000"
Docker 守护进程权限
确保只有可信用户能访问 Docker 守护进程:
root
用户身份运行,具有较高的系统权限。/var/run/docker.sock
,只有 docker
组的成员可以访问。chmod
或 chown
确保 /var/run/docker.sock
只允许可信用户访问: - sudo chown root:docker /var/run/docker.sock
- sudo chmod 660 /var/run/docker.sock
docker
组: sudo usermod -aG docker trusted_user
限制 Docker 守护进程的网络访问权限:
防火墙
限制 Docker 守护进程的网络访问:
iptables
或 firewalld
)确保 Docker 守护进程仅接受来自可信主机的连接: - iptables -A INPUT -p tcp --dport 2375 -s TRUSTED_IP -j ACCEPT
- iptables -A INPUT -p tcp --dport 2375 -j DROP
隔离容器网络:
iptables -A FORWARD -s 172.17.0.0/16 -d 172.18.0.0/16 -j DROP
Docker 网络模型
合理选择网络模型:
配置网络策略:
可信镜像
使用官方或可信来源的镜像:
避免使用 latest
标签:
latest
标签指向最新版本的镜像,可能引入未知风险。docker run myimage:1.0.0
定期扫描
使用漏洞扫描工具:
持续监控新漏洞:
Docker 守护进程隔离
安全配置审计
内存限制
--memory
限制容器内存使用:
docker run --memory 500m myimage
- version: '3'
- services:
- app:
- image: myimage
- deploy:
- resources:
- limits:
- memory: 500M
CPU 限制
--cpus
或 --cpu-shares
限制容器 CPU 使用:
docker run --cpus 1.5 myimage
--cpu-shares
指定相对权重: docker run --cpu-shares 512 myimage
- version: '3'
- services:
- app:
- image: myimage
- deploy:
- resources:
- limits:
- cpus: '1.5'
磁盘 IO 限制
--device-read-bps
和 --device-write-bps
限制读取和写入速率:
docker run --device-read-bps /dev/sda:1mb --device-write-bps /dev/sda:1mb myimage
文件句柄数量限制
--ulimit
设置文件句柄数量限制:
docker run --ulimit nofile=1024:2048 myimage
减少 Dockerfile 中的图层数量,合并不必要的 RUN
命令
在 Docker 中,每个指令(如 RUN
、COPY
、ADD
)都会创建一个新的镜像层。过多的层次会导致镜像体积过大、构建时间变长。
合并相关的 RUN
命令,可以减少不必要的层次。例如,将多个 RUN
命令合并为一个:
优化前:
- FROM ubuntu:latest
- RUN apt-get update
- RUN apt-get install -y python python-pip
优化后:
- FROM ubuntu:latest
- RUN apt-get update && \
- apt-get install -y python python-pip
在确保构建过程中不会引入额外问题的情况下,尽量合并相关的指令来减少层数。
使用 Docker 缓存(--cache-from
)构建镜像
Docker 会使用缓存加速镜像构建,但在某些情况下,缓存可能失效,导致完全重新构建镜像。
使用 --cache-from
参数可以从现有镜像中恢复缓存层,加速构建:
docker build --cache-from=myimage:previous -t myimage:latest .
在多阶段构建中,--cache-from
可以帮助不同阶段共享缓存,提高构建效率。
多阶段构建减少最终镜像大小
多阶段构建可以将构建和生产环境分离,确保生产镜像中只包含必要的文件。
通过引入多个 FROM
指令,实现构建环境和生产环境的分离:
- # 构建阶段
- FROM golang:1.19 as builder
- WORKDIR /app
- COPY . .
- RUN go build -o myapp
-
- # 生产阶段
- FROM alpine:latest
- WORKDIR /app
- COPY --from=builder /app/myapp .
- CMD ["./myapp"]
通过这种方法,最终的生产镜像仅包含编译后的二进制文件和必要的依赖项,减少了镜像大小。
使用卷保持数据持久化
Docker 容器的文件系统是临时性的,容器停止或删除后,内部数据将丢失。
使用 Docker 卷,可以将数据存储在主机上,从而实现数据持久化:
docker run -v /host/data:/container/data myimage
在 Docker Compose 中使用卷:
- version: '3'
- services:
- app:
- image: myimage
- volumes:
- - /host/data:/container/data
避免频繁修改容器内部文件系统
Docker 容器的文件系统性能相对较低,频繁修改文件系统会影响容器性能。
使用卷将数据存储到主机上可以提高性能,并减少容器内部文件系统的修改:
docker run -v /host/data:/container/data myimage
使用 tmpfs 卷在内存中存储临时数据,可以进一步提高性能:
docker run --tmpfs /container/tmpfs myimage
选择合适的基础镜像
ubuntu:latest
更改为 alpine:latest
:- FROM ubuntu:latest
- RUN apt-get update && apt-get install -y python
优化后: - FROM alpine:latest
- RUN apk --no-cache add python
清理构建依赖
- FROM ubuntu:latest
- RUN apt-get update && \
- apt-get install -y build-essential && \
- make && \
- apt-get remove -y build-essential && \
- apt-get autoremove -y && \
- rm -rf /var/lib/apt/lists/*
多阶段构建
压缩镜像
docker-slim
等工具可以进一步压缩镜像大小: docker-slim build myimage
资源限制
在编排工具中设置资源限制,确保容器不会滥用集群资源:
Docker Compose:
- version: '3'
- services:
- app:
- image: myimage
- deploy:
- resources:
- limits:
- cpus: '1.0'
- memory: '500M'
Kubernetes:
- apiVersion: v1
- kind: Pod
- metadata:
- name: app
- spec:
- containers:
- - name: app
- image: myimage
- resources:
- limits:
- memory: "500Mi"
- cpu: "1"
副本数
水平扩展
Docker 的性能优化涉及多个方面,包括分层结构、镜像大小、卷的使用、多阶段构建以及编排性能优化。在实际开发和生产中,合理应用这些技术和策略可以显著提高 Docker 容器的性能和效率。
保持 Dockerfile 简洁,注释清晰,并遵循官方最佳实践指南
使用官方基础镜像:官方基础镜像通常经过严格的测试和优化,选择合适的官方镜像可以提高质量并减少潜在问题。
FROM python:3.9-slim
明确标签和版本:避免使用 latest
标签,尽量指定明确的镜像版本。
FROM node:16.14.0
合并相关命令,减少层数:合并 RUN
指令,减少镜像层数。
优化前:
- FROM ubuntu:latest
- RUN apt-get update
- RUN apt-get install -y python3 python3-pip
优化后:
- FROM ubuntu:latest
- RUN apt-get update && \
- apt-get install -y python3 python3-pip
最小化构建依赖:尽量只安装构建过程中需要的依赖,并在构建完成后进行清理。
- RUN apt-get update && \
- apt-get install -y --no-install-recommends build-essential && \
- make && \
- apt-get purge -y --auto-remove build-essential && \
- rm -rf /var/lib/apt/lists/*
多阶段构建:使用多阶段构建确保最终镜像只包含必要文件。
- # 构建阶段
- FROM golang:1.19 AS builder
- WORKDIR /app
- COPY . .
- RUN go build -o main
-
- # 生产阶段
- FROM alpine:latest
- WORKDIR /app
- COPY --from=builder /app/main .
- CMD ["./main"]
注释清晰:为关键步骤添加注释,方便他人理解和维护。
- # 使用 Python 官方精简版镜像
- FROM python:3.9-slim
-
- # 设置工作目录
- WORKDIR /app
-
- # 复制应用程序代码
- COPY . /app
-
- # 安装依赖
- RUN pip install --no-cache-dir -r requirements.txt
-
- # 启动应用
- CMD ["python", "app.py"]
避免使用 latest
标签,尽量指定明确的版本
latest
标签,因为它可能指向不同的版本,导致不一致的行为。FROM node:16.14.0
将 Docker 镜像构建纳入持续集成流程,确保镜像构建自动化
集成工具:使用 Jenkins、GitLab CI/CD、GitHub Actions 或其他 CI/CD 工具自动化 Docker 镜像的构建和测试。
示例:GitHub Actions
- name: Build and Push Docker Image
-
- on:
- push:
- branches: [ main ]
- pull_request:
- branches: [ main ]
-
- jobs:
- build:
- runs-on: ubuntu-latest
- steps:
- - name: Checkout code
- uses: actions/checkout@v2
-
- - name: Set up Docker Buildx
- uses: docker/setup-buildx-action@v1
-
- - name: Cache Docker layers
- uses: actions/cache@v2
- with:
- path: ~/.docker
- key: ${{ runner.os }}-docker-${{ hashFiles('**/Dockerfile') }}
- restore-keys: |
- ${{ runner.os }}-docker
-
- - name: Log in to Docker Hub
- uses: docker/login-action@v1
- with:
- username: ${{ secrets.DOCKER_HUB_USERNAME }}
- password: ${{ secrets.DOCKER_HUB_TOKEN }}
-
- - name: Build and push Docker image
- uses: docker/build-push-action@v2
- with:
- push: true
- tags: myusername/myimage:latest
.github/workflows/docker-build.yml
文件,并添加以下内容:示例:GitLab CI/CD
- image: docker:latest
-
- services:
- - docker:dind
-
- stages:
- - build
- - test
- - deploy
-
- variables:
- DOCKER_DRIVER: overlay2
-
- build:
- stage: build
- script:
- - docker build -t myusername/myimage:latest .
-
- test:
- stage: test
- script:
- - docker run --rm myusername/myimage:latest pytest
-
- deploy:
- stage: deploy
- script:
- - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
- - docker push myusername/myimage:latest
.gitlab-ci.yml
文件,并添加以下内容:定期更新 Docker 版本
- docker --version
- sudo apt-get update && sudo apt-get install -y docker-ce docker-ce-cli containerd.io
关注官方的安全公告
通过遵循 Dockerfile 最佳实践、将 Docker 镜像构建纳入持续集成流程、定期更新 Docker 版本、利用社区资源等手段,可以确保 Docker 开发流程的高效和安全。持续学习和改进这些实践,有助于在生产环境中成功运行容器化应用。
遵循这些 Docker 最佳实践,您可以最大限度地提高应用程序的安全性、性能和开发效率。Docker 提供了一套强大的工具和功能来优化应用程序的交付和运行时环境。通过实施这些最佳实践,您可以充分利用 Docker 的潜力,确保应用程序的可靠性和可扩展性。
祝您的 Docker 之旅一切顺利!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。