跳到主要内容

概念

  • 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, 将容器目录挂载到指定的宿主机目录下

容器网络管理

跨主机的容器间通信通过 iptablesfilterFORWARD 链控制

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 语法的最新稳定版本
  • CMDENTRYPOINT 同时存在时, 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

下载安装

https://goharbor.io

配置

高可用