docker常用命令

启动一个容器

1
docker run -h 容器主机名 --name 容器名 -Pdit 镜像名

启动一个新的bash对运行中的容器进行管理

1
docker exec -it 容器名 bash

指定以root用户启动bash对容器进行管理

默认会按照容器启动的用户打开bash,如果想以root身份打开bash需要执行

1
docker exec -it -u root 容器名 bash

其他常用命令

镜像 容器
创建 build -t/commit create/run
删除 rmi rm
重命名 tag+rmi rename
查看列表 images ps/ps -a/ps -l -q
运行状态 stats top
查看日志 history --no-trunc logs
登录 login
拉取 pull
推送 push
查找 search
查看容器信息 inspect
发信号 kill
附到主进程 attach
执行新进程 exec

docker run 常用参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
-d   # 后台运行
-it # 打开STDIN,支持终端登录
--name <容器名>
-h <主机名>
-P # 随机映射所有配置在EXPOSE中的端口
-p [<宿主端口>:]<容器端口> # 指定映射一个端口,不指定宿主端口时表示随机
--expose <容器端口> # 指定暴露一个容器端口,但不映射到宿主机
-v [<宿主路径|卷名称>:]<容器路径>[:ro|:rw] # 卷映射,宿主路径是以/开头的绝对路径,
卷名称不存在时自动创建新卷,容器路径不存在时自动创建,ro表示只读,默认是rw表示读写
--volumes-from <容器名> # 指定容器里的所有卷都将加入到新创建的容器里
--network <网络名> # 默认bridge,同一个非默认网络下的容器可以使用主机名相互访问,
如果设置为host表示和宿主机共用网络,容器内的端口都将直接绑定到宿主机而无需-p建立映射
--link <容器名>:<主机名> # 在新创建的容器里可以通过主机名访问另一个运行中的容器
--add-host <主机名>:<IP> # 指定主机名解析添加到/etc/hosts文件
--env <环境变量名>=<环境变量值> # 设置环境变量,-e 选项可以重复多次
--env-file <环境变量文件> # 指定环境变量文件,换行符分割
--user <用户名>
--workdir <工作目录>
--mac-address="xx:xx:xx:xx:xx:xx" # 指定MAC地址
--ip="x.x.x.x" # 指定IP地址
--rm # 容器停止时自动删除容器,当镜像提供的是一个命令而不是服务器的时候尤其适合
--restart=always|unless-stopped|on-failure # 指定容器的重启策略,
如果容器内运行的是服务器则应该指定重启策略
always表示任何时候只要docker daemon开着总是重启容器
unless-stopped表示除非在docker启动时(如果宿主机重启就是上次关机时)容器就是stop状态,否则总是重启容器
on-failure表示只在容器以非0状态结束时自动重启

关于资源限制的参数

1
2
3
4
5
--cpuset-cpus="1,3" # 限制在核1、3上运行
--memory=1G # 限制内存最大使用1G
--device-read-bps /dev/sdd:40mb # 限制读取sdd的速度最大40mb
--device-write-bps /dev/sdd:30mb # 限制写入sdd的速度最大30mb
(机械硬盘读写速度是60-80MB,固态硬盘读写速度是130~300MB,都是写慢读快)

docker network 常用参数

1
2
3
4
5
6
7
create [--gateway=192.168.1.1] [--subnet=192.168.1.0/24] <网络名> # 创建一个新的网络
connect <网络名> <容器名> # 向一个网络中添加一个容器
disconnect <网络名> <容器名> # 从一个网络中移除一个容器
inspect <网络名> # 查看指定网络详细信息
ls # 查看网络列表
prune # 删除所有未使用的网络
rm <网络名> # 删除指定网络

docker inspect 常用参数

--format format的用法比较复杂,用几个逐级深入的例子演示,事实上我通常把docker_ip, docker_volume设成Linux别名方便使用

docker_id 查看容器的Id

1
docker inspect --format='{{.Id}}' 容器名

docker_ip 查看容器在所有网络中分配的所有的ip

1
docker inspect --format='{{range .NetworkSettings.Networks}}{{println .IPAddress}}{{end}}' 容器名

docker_volume 查看容器的卷

1
docker inspect --format='{{range .Mounts}}{{.Source}}:{{.Destination}}{{println}}{{end}}' 容器名

docker_port 查看容器所有的端口映射情况,用docker inspect实现 docker port命令

1
docker inspect --format='{{range $p, $conf := .NetworkSettings.Ports}}{{range $conf}}{{$p}} -> {{.HostIp}}:{{.HostPort}}{{println}}{{end}}{{end}}' 容器名

docker volume 常用参数

1
2
3
4
5
6
7
create [卷名] # 创建一个卷,一般不用这个命令,因为在docker run -v [卷名:]容器路径 会自动创建
inspect 卷名 # 查看卷的详细信息
ls # 列出所有卷
prune # 删除当前未被使用的卷,最常用的是这个命令
rm 卷名 # 删除指定的卷


允许普通用户使用docker命令

1
usermod -aG docker <username>

容器内访问卷的权限

如果容器以非root用户启动,卷中的文件在宿主机设置怎么样的权限可以被容器内的普通用户访问呢,一般容器内的普通用户的UID是1000,在宿主机上可以对UID是1000的用户授权,无论容器内和宿主机的UID是1000的用户名是否相同。

构建镜像的一些技巧

Dockerfile中使用CMD指定容器启动时执行的脚本

1
CMD ["bash", "/root/setup.sh"]

如果容器提供是一个服务器,则脚本不应结束,一旦脚本结束则容器也会结束,如果服务后台运行,需要把前台卡住,可以使用

1
tail -f /dev/null

放在setup.sh的结尾。

另外我们可以选择启动脚本发生错误是直接退出,还是带着错误继续运行而不让容器退出。

在setup.sh的开始执行

1
set +e

表示脚本将无视错误继续执行,这也是默认行为

1
set -e

表示脚本将在遇到错误时立即退出,同时容器也将停止(即启动失败)

Dockerfile样例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
FROM daimingzhuang/ubuntu:18.04
MAINTAINER DaiMingzhuang "kyo86.dai@gmail.com"
ENV REFRESHED_AT=2022-10-21
RUN apt update -yqq \
&& apt install -y vim openjdk-8-jre-headless python3.6 python3-pip libpqxx-dev cron redis-server nginx
ENV JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
ENV JRE_HOME=$JAVA_HOME/jre
ENV CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV PATH=$PATH:$JAVA_HOME/bin

ADD requirements.txt /root/requirements.txt
RUN pip3 install -r /root/requirements.txt

ADD zookeeper-3.4.14.tgz /opt/
ADD kafka_2.12-2.3.1.tgz /opt/
# 添加kafka配置文件
ADD kafka-server.properties /opt/kafka_2.12-2.3.1/config/server.properties
# 添加zookeeper配置文件
ADD zoo.cfg /opt/zookeeper-3.4.14/conf/zoo.cfg
# 添加zookeeper启动脚本
ADD zk_server_start.sh /opt/zookeeper-3.4.14/bin/zk_server_start.sh
# 添加redis配置文件
ADD redis.conf /etc/redis/redis.conf
# 添加nginx服务器配置
ADD nginx.conf /etc/nginx/nginx.conf
# 添加nginx站点配置
ADD nginx-default /etc/nginx/sites-available/default

ADD loop_run /usr/local/bin/supervised_run
ADD setup.sh /root/setup.sh
WORKDIR "/root/"
CMD ["bash", "/root/setup.sh"]

setup.sh样例

1
2
3
4
5
6
7
8
9
10
#!/bin/bash
set +e
service cron start
service redis-server start
nohup supervised_run /opt/zookeeper-3.4.14/bin/zk_server_start.sh >/dev/null 2>&1 &
sleep 5
nohup supervised_run /opt/kafka_2.12-2.3.1/bin/kafka-server-start.sh /opt/kafka_2.12-2.3.1/config/server.properties >/dev/null 2>&1 &
sleep 5
nginx -c /etc/nginx/nginx.conf
tail -f /dev/null

构建镜像命令

1
docker build <imagename>:<tag> .

注意最后的. 表示存放Dockerfile的目录

docker login 失败解决

1
apt purge golang-docker-credential-helpers

为启动中的容器增加卷或端口映射

查看并记录容器的运行参数,主要包括name/user/卷映射/端口映射

1
docker inspect <container-name-or-id>

上面步骤如果不清楚要记录什么,也可以用工具自动生成run命令

生成容器的run命令

1
2
pip install runlike
runlike <container-name-or-id>

停止需要增加卷或端口映射的容器

1
docker container stop <container-name-or-id>

将现有容器制成镜像

1
docker commit <container-name-or-id> <new-image-name>

重命名旧容器(如果新容器希望沿用旧名字,并且不想立刻删除旧容器,以便新容器有问题时重新启用旧容器)

1
docker rename <container-name> <container-new-name>

用新镜像启动容器,用之前生成的run命令并带上需要新增的卷映射或端口映射

1
docker run -v xxx:xxx -p xx:xx <new-image-name>

确认无误后删除旧容器

1
docker rm <container-name-or-id>

docker配置文件

/etc/docker/daemon.json

默认是空的配置,可以自己增加项目,例如修改docker的根路径和修改镜像源。

1
2
3
4
{
"data-root": "/data/docker",
"registry-mirrors": ["https://eyl5ycru.mirror.aliyuncs.com"]
}

导出镜像

1
docker save <镜像名>:<标签名> -o <tar文件路径>

导入镜像

1
docker load -i <tar文件路径>

docker-compose

docker-compose可以把多个相互配合容器(通过网络或共享卷)的启动参数写在一个yml文件里。或者只是把一个容器的启动参数固定在yml文件里。

docker-compose.yml样例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
version: '3'
services:
clickhouse:
image: clickhouse/clickhouse-server
container_name: clickhouse
ulimits:
nofile:
soft: 262144
hard: 262144
ports:
- "8123:8123"
- "9000:9000"
volumes:
- /data/clickhouse-data/data/:/var/lib/clickhouse/
- /data/clickhouse-data/log/:/var/log/clickhouse-server/
restart: unless-stopped
environment:
- CLICKHOUSE_USER=default
- CLICKHOUSE_PASSWORD=default@clickhouse

创建并启动

1
docker-compose up -d

停止并删除

1
docker-compose down