概念
- image > contrainerd > contrainerd-shim-runc > runc > container
- NAMESPACE 环境隔离
- Control Groups 资源分配
安装
包管理器
二进制
1. 下载解压
wget https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/static/stable/x86_64/docker-20.10.24.tgz
tar -xf docker-20.10.24.tgz -C /usr/local/
2. 安装
cd /usr/local/
cp docker/* /usr/bin/
3. 创建服务
4. 验证
docker info
5. 配置优化
Tab 补全脚本
wget -O /etc/bash_completion.d/docker https://raw.githubusercontent.com/docker/cli/refs/heads/master/contrib/completion/bash/docker
or 点击下载 docker-completion 脚本, 放置在 /etc/bash-completion.d/ 目录下
镜像和容器管理
管理 Docker
docker system COMMAND
- df, 查看 docker 对磁盘占用
- info, 同
docker info - prune, 删除 停止的容器, 无容器使用的网络, 未使用的 build 缓存, 悬置镜像
- events, 实时打印 docker 日志, 同
docker events
导入/导出镜像
docker save [OPTIONS] IMAGE [IMAGE...]
- -o, 输出成指定的 tar 包, 默认输出到STDOUT
docker load [OPTIONS]
- -i, 指定要加载的 tar 包, 默认从 STDIN 加载
查看镜像构建
docker history [OPTIONS] IMAGE
- --no-trunc, 打印完整构建命令
创建并运行容器
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
- -h, 指定容器主机名
- --name, 指定容器名称
- --restart, 四种模式, 通常需要为
always, 即容器随 docker daemon 启动而重启 - --privileged, 使容器拥有宿主机的 root 权限
- --rm, 容器随前台退出自动删除
- -d, 容器在宿主机后台运行
- -it, <SHELL> 通过指定 shell 与容器交互,
ctrl+q+p仅退出交互而不退出容器 - -P, 将每个 Dockerfile 中暴露的端口绑定到宿主机上的随机端口
- -p, 通过 <宿主机端口:容器端口> 暴露容器端口
docker run相当于 pull + create + start, 只有容器中有前台程序在执行容器才不会退出
查看已创建容器的完整创建命令, 可 pip3 install runlike 安装第三方工具
容器文件拷贝
docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH
源或目标为-时, 与 STDIN/STDOUT 交互
- -a, 归档模式, 保留uid/gid
- -L, 追踪软链接
操作容器
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
- -it, 以交互模式进入运行中的容器, 如
docker exec -it nginx bash - -e, 以 name=value 指定环境变量
- --env-file, 指定环境变量文件
删除容器
docker rm [OPTIONS] CONTAINER [CONTAINER...]
- -f, 强制删除运行中的容器
# 删除所有停止的容器
docker container prune
# 等价于
docker rm `docker ps -aqf status=exited`
查看容器进程
docker top CONTAINER [ps OPTIONS]
查看运行的容器在宿主机的进程
查看容器占用
docker stats [OPTIONS] [CONTAINER...]
查看容器参数
docker inspect [OPTIONS] NAME|ID [NAME|ID...]
可以查看容器的 ip 地址等参数
查看运行的容器
docker ps [OPTIONS]
- -s, 显示容器大小
- -q, 仅打印容器IDs
- -f, 通过 NAME=VALUE 形式过滤, 如
status=exited - -a, 打印所有容器( 包括已停止的 )
查看容器日志
docker logs [OPTIONS] CONTAINER
- -f, 持续 follow 容器日志
- -n, 输出末尾 n 行
- -t, 显示时间戳, 默认不显示
容器卷管理
overlay 联合文件系统, 多个设备可挂载到同一挂载点. 从而容器卷采用分层构建, 提高可复用性
LowerDir镜像层UpperDir可读写的容器层MergedDir镜像和容器合并形成层
# 查看所有容器卷
docker volume ls
# 查看指定容器卷详情
docker volume inspect
# 删除不使用得卷
docker volumn prune
# 与指定容器共用同一容器卷
docker run --volumns-from CONTAINER_NAME
匿名容器卷
不通过 -v 参数指定容器卷时, 会在 Docker Root Dir 下创建随机字符名称的目录, 用来存放多层容器数据, 容器被删除时可读写的容器层不会保留
命名容器卷
docker run -v <VOLUME NAME>:CONTAINER_DIR
指定 VOLUME NAME 会在 Docker Root Dir 目录下生成对应容器卷
挂载容器卷
docker run -v HOST_DIR:CONTAINER_DIR
指定宿主机目录 HOST_DIR, 将容器目录挂载到指定的宿主机目录下
容器网络管理
跨主机的容器间通信通过 iptables 的 filter 表 FORWARD 链控制
docker run --link CONTAINER_NAME:ALIAS 实现通过目标容器名或别名通信, 原理是在本容器 /etc/hosts 文件中添加解析
bridge
不同容器的网卡连接到同一网桥, 通过 NAT 访问外网, 底层用 iptables 实现
出站:

入站:

host
容器使用宿主机的 IP 和端口号
null
容器没有网卡和ip, 无法进行网络通讯
container
通过 --network container:CONTAINER_NAME 指定与某容器共用同一个网络
自定义网络
自定义网络内部容器默认彼此可通过容器名互访, 且不改变 /etc/hosts 创建容器时通过 --network 引用
docker network create [OPTIONS] NETWORK
- -d, 指定驱动, 默认为 bridge
- --gateway, 指定网关
- --subnet, 用 CIDR 格式指定网段
Docker-compose
单机容器编排. 相关镜像, 容器, 网络等命令只会对当前所在项目进行处理
安装
DOCKER_CONFIG=${DOCKER_CONFIG:-/usr/local/lib/docker/}
mkdir -p $DOCKER_CONFIG/cli-plugins
curl -SL https://github.com/docker/compose/releases/download/v5.0.1/docker-compose-linux-x86_64 -o $DOCKER_CONFIG/cli-plugins/docker-compose
chmod u+x /usr/local/lib/docker/cli-plugins/docker-compose
执行 docker compose version 验证
docker-compose.yml
不同版本语法不同.
version: '3'
volumns:
my_data:
external: true
services:
web:
image: nginx:1.2.3
container_name: nginx
restart: unless-stopped
depends_on:
- mongodb
volumns:
- ./webdata:/var/lib/html/www
entrypoint: ["", ""]
environment:
- TZ=Asia/Shanghai
mongodb:
image: mongo:4.0.27
container_name: mongo
restart: always
volumns:
- xxx
environment:
- xxx
在文件所在路径下运行 docker compose up -d 拉取镜像并运行项目, docker compose down 停止并删除容器和网络.
镜像制作
手动制作
分层制作, 底层环境相同, 可复用.
定制 OS 镜像 -> 开发环境镜像 -> 中间件/app镜像
创建镜像
进入容器手动配置好环境, 使用下面命令提交
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
- -a, 指定作者 (e.g., "John Hannibal Smith
<hannibal@a-team.com>") - -m, Commit message
批量制作
创建结构化目录, 各个目录分别放置对应镜像的 Dockerfile 文件
mkdir -p /opt/dockerfile/{os/{centos,debian},dev/{go,jre},web/{nginx}}
创建镜像
docker build [OPTIONS] PATH | URL | -
- -t, 指定 <name:tag>
根据指定路径的 Dockerfile 构建镜像
Dockerfile 参考
ENV一直持久化到容器里, 而ARG只在 build 镜像时有效# syntax=docker/dockerfile:1会导致 BuildKit 在构建之前拉取 Dockerfile 语法的最新稳定版本CMD与ENTRYPOINT同时存在时,CMD会成为为ENTRYPOINT的参数ENTRYPOINT一定要使用exec用业务进程替换PID 1默认的/bin/sh -c进程, 避免业务进程不能及时接收到信号
# syntax=docker/dockerfile:1
FROM alpine
LABEL org.opencontainers.image.authors="SvenDowideit@home.org.au"
LABEL version=v1.0.0
LABEL description="..."
ARG CONT_IMG_VER
ENV CONT_IMG_VER=${CONT_IMG_VER:-v1.0.0}
ADD a.tar.gz b.tar.gz /opt/
RUN <<EOT
#!/usr/bin/env python
echo "构建镜像中..."
EOT
CMD PARAM1 ...
# gosu 是切换用户并执行命令
ENTRYPOINT exec gosu postgres
搭建私有仓库
依赖 docker 和 docker compose