在使用 Docker 的过程中,很多新手都会遇到各种各样的问题,例如镜像构建失败、容器无法启动、网络配置错误等等。本文将从底层原理出发,结合实际案例,带你一步步掌握 Docker 的核心技术,避免踩坑,最终达到灵活运用 Docker 解决实际问题的目的。
什么是 Docker?
Docker 可以理解为一种轻量级的虚拟化技术,它允许开发者将应用程序及其依赖项打包到一个容器中,然后发布到任何支持 Docker 的环境中。与传统的虚拟机相比,Docker 容器共享宿主机的操作系统内核,因此资源占用更少,启动速度更快。
Docker 镜像、容器和仓库
- 镜像(Image): 类似于虚拟机镜像,是一个只读的文件,包含了运行应用程序所需的所有文件、库和依赖项。
- 容器(Container): 镜像的运行实例。容器是隔离的,拥有自己的文件系统、进程空间和网络接口。
- 仓库(Repository): 用于存储和共享 Docker 镜像,例如 Docker Hub、阿里云镜像仓库等。
安装 Docker
不同操作系统安装 Docker 的方式不同,这里以 Ubuntu 为例:
sudo apt-get update
sudo apt-get install -y docker.io
sudo systemctl start docker
sudo systemctl enable docker
常用 Docker 命令
# 查看 Docker 版本
docker version
# 搜索镜像
docker search nginx
# 拉取镜像
docker pull nginx
# 查看本地镜像
docker images
# 运行容器
docker run -d -p 80:80 nginx # -d 后台运行,-p 端口映射
# 查看运行中的容器
docker ps
# 查看所有容器(包括已停止的)
docker ps -a
# 进入容器
docker exec -it <container_id> bash
# 停止容器
docker stop <container_id>
# 删除容器
docker rm <container_id>
# 删除镜像
docker rmi <image_id>
Dockerfile:构建自定义镜像
Dockerfile 是一个文本文件,包含了一系列用于构建 Docker 镜像的指令。通过编写 Dockerfile,我们可以自动化地创建自定义镜像。
Dockerfile 常用指令
FROM:指定基础镜像。MAINTAINER:指定维护者信息(已弃用,推荐使用 LABEL)。RUN:在镜像中执行命令。COPY:复制文件到镜像中。ADD:复制文件或 URL 到镜像中(支持自动解压)。WORKDIR:设置工作目录。EXPOSE:声明容器监听的端口。CMD:容器启动时执行的命令。ENTRYPOINT:容器启动时执行的入口点。ENV:设置环境变量。
Dockerfile 示例:构建一个简单的 Nginx 镜像
FROM ubuntu:latest
MAINTAINER linuxer_zhao
RUN apt-get update && apt-get install -y nginx
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
构建镜像
docker build -t my-nginx . # -t 指定镜像名称,. 表示 Dockerfile 所在目录
Docker Compose:编排多容器应用
当应用程序由多个容器组成时,可以使用 Docker Compose 来定义和管理这些容器。Docker Compose 使用 YAML 文件来描述应用程序的服务、网络和卷等。
Docker Compose 文件示例
version: "3.7"
services:
web:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html
depends_on:
- app
app:
image: python:3.8-slim-buster
volumes:
- ./app:/app
working_dir: /app
command: python app.py
常用 Docker Compose 命令
# 启动所有服务
docker-compose up -d
# 停止所有服务
docker-compose down
# 查看服务状态
docker-compose ps
# 查看服务日志
docker-compose logs web
Docker 网络:容器间通信
Docker 提供了多种网络模式,用于实现容器间的通信。
- bridge 网络: 默认的网络模式,容器通过 docker0 网桥与宿主机通信。
- host 网络: 容器与宿主机共享网络命名空间,直接使用宿主机的 IP 地址和端口。
- none 网络: 容器没有任何网络配置。
- overlay 网络: 用于跨主机容器间的通信。
创建自定义网络
docker network create my-network
将容器连接到网络
docker run --network my-network <image_name>
Docker Volume:数据持久化
Docker Volume 用于实现数据的持久化,即使容器被删除,数据也不会丢失。
创建 Volume
docker volume create my-volume
将 Volume 挂载到容器
docker run -v my-volume:/data <image_name>
Docker 实战:部署 Nginx + PHP 应用
接下来,我们以部署一个简单的 Nginx + PHP 应用为例,演示如何使用 Docker 进行应用部署。
- 创建 Dockerfile 文件,用于构建 PHP 镜像:
FROM php:7.4-fpm-alpine
RUN docker-php-ext-install pdo pdo_mysql
WORKDIR /var/www/html
COPY . .
- 创建 Dockerfile 文件,用于构建 Nginx 镜像:
FROM nginx:latest
COPY default.conf /etc/nginx/conf.d/
COPY html /usr/share/nginx/html
- 创建
default.conf文件,配置 Nginx 反向代理:
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.php index.html index.htm;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass app:9000; # app 是 php 容器的服务名
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
- 创建
docker-compose.yml文件,定义服务:
version: "3.7"
services:
web:
build: ./nginx
ports:
- "80:80"
depends_on:
- app
app:
build: ./php
volumes:
- ./html:/var/www/html
- 启动服务:
docker-compose up -d
通过以上步骤,我们就成功地使用 Docker 部署了一个简单的 Nginx + PHP 应用。 可以通过访问 http://localhost 来查看应用。
Docker 避坑经验
- 镜像体积优化: 使用多阶段构建,减少镜像体积。
- 容器资源限制: 使用
docker run --memory和docker run --cpu-shares限制容器的资源使用。 - 日志管理: 使用 Docker 日志驱动,将容器日志发送到集中式日志系统。
- 安全加固: 使用 Docker Content Trust 和 AppArmor 等安全工具,提高容器的安全性。
- 构建缓存利用: 合理安排 Dockerfile 中的指令顺序,充分利用构建缓存,加速镜像构建。
总结
本文详细介绍了 Docker 的核心概念、常用命令和实战技巧。希望通过本文的学习,能够帮助你快速入门 Docker,并能够在实际工作中灵活运用 Docker 解决各种问题。 Docker 技术在微服务架构、持续集成/持续部署 (CI/CD) 流程中扮演着越来越重要的角色,掌握 Docker 技能对于后端工程师来说至关重要。了解了 Docker 的原理后,可以更容易理解 Kubernetes (K8S) 的相关概念。
冠军资讯
linuxer_zhao