docker · 2019-12-22 0

docker基本命令

一、镜像命令

1.列出本机上的镜像

docker images

参数:

  • -a 列出本地所有(默认隐藏了中间状态的镜像)
  • -q 只显示镜像ID
  • --digests 显示镜像的摘要信息
  • --no-trunc 显示完整的镜像信息

2.搜索镜像

docker search <image_name>

参数:

  • -s 列出收藏数不小于指定值的镜像(-s 30 收藏数大于30的)
  • --no-trunc 显示完整的镜像描述
  • --automated 只列出automated build类型的镜像

3.下载镜像

docker pull <image_name>[:tag] 

如果不指定tag,则下载latest版本

4.删除镜像

docker rmi <image_name>[:tag]/<image_id>

  • 强制删除单个 docker rmi -f <image_id>docker rmi --force <image_id>
  • 删除多个 docker rmi <image_id> <image_id>
  • 删除全部 docker rmi $(docker images -qa)
  • 删除所有未使用的镜像 docker image prune -f -a
  • 删除空悬镜像( <none>)(dangling images) ,高版本 docker image prune 低版本 docker rmi $(docker images -f "dangling=true" -q)
  • 删除指定标签的镜像 docker rmi $(docker images | grep "1.0" | awk '{print $3}')

5.导出镜像

docker save -o demo.tar demo:1.0

6.导入镜像

`docker load -i demo.tar

7.打标签

docker tag old_image:old_tag new_image:new_tag

二、容器命令

有镜像才能创建容器,这是根本前提

1.新建并启动容器

docker run <image_name>[:tag]/<image_id>

例如:

docker run -it --name mycentos0 centos
docker run -it -p 8888:8080 tomcat
docker run -itd --name busybox_1 busybox:1.33.1

-e TZ=Asia/Shanghai 设置中国时区

参数:

  • --name <container_name> 为容器指定一个名称
  • -d 后台运行容器,并返回容器ID,也启动守护式容器
  • -i 以交互模式运行容器,通常与-t同时使用
  • -t 为容器重新分配一个伪输入终端,通常与-i 同时使用
  • -P 随机端口映射
  • -p 指定端口映射,有四种格式 ip:host_port:container_port,ip::container_port,host_port:container_port,container_port
  • -v或--volume 添加数据卷
  • -e 设置环境变量
  • –net或--network 连接到指定网络
  • --ip 指定 ip
  • -h或--hostname 指定容器的hostname(修改/etc/hostname)
  • --link <container-name/container-id>:alias 添加链接到另一个容器(添加到/etc/hosts) 例: --link=nginx_80:nginx_host
  • --add-host (添加到/etc/hosts) 例:--add-host www.abc.com:127.0.0.1
  • --privileged 使用该参数,container内的root拥有真正的root权限,否则,container内的root只是外部的一个普通用户权限
  • -u或--user <user>或--user <user>:<group> 执行命令的用户名或者ID
  • --cpus 最大使用CPU核数
  • -m或--memory 最大内存
  • --memory-swap 交换内存,-1 表示无限制
  • --restart=always 在容器退出时总是重启容器
  • --restart=no 默认策略,在容器退出时不重启容器
  • --restart=on-failure 在容器非正常退出时(退出状态非0),才会重启容器
  • --restart=unless-stopped 在容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容器
  • -w 指定工作目录
docker run -it -v /宿主机绝对路径目录:/容器内目录 镜像名
docker run -it -v /宿主机绝对路径目录:/容器内目录:ro 镜像名
docker run -it -v /myDataVolume:/dataVolumneContailner 镜像名

对于已经启动的容器,设置开启自启动
docker update --restart=always <container_name>/<container_id>

注:查看容器内存情况,free -h,容器和宿主机显示的一样,因为 free -h 本质上是读取 /proc/meminfo 文件内容,可使用 docker stats --no-stream 查看

主机层没有开启 swap ,容器运行时无论怎么设置 --memory-swap,都不会使用到 swap,容器最大能使用的内存等于设置的内存限制;

docker run的退出状态码如下:

  • 0,表示正常退出
  • 非0,表示异常退出(退出状态码采用chroot标准)
  • 125,Docker守护进程本身的错误
  • 126,容器启动后,要执行的默认命令无法调用
  • 127,容器启动后,要执行的默认命令不存在
  • 其他命令状态码,容器启动后正常执行命令,退出命令时该命令的返回状态码作为容器的退出状态码

容器关闭 swap 分区:

  • 启动容器时,增加启动参数--memory-swappiness=0,即可禁止容器使用swap;
  • 同时,配置 --memory的值 与 --memory-swap的值 相等,也可以阻止容器使用swap:
  • 宿主机执行 sudo swapoff -a,临时关闭宿主机的 swap 分区,也临时关闭容器的 swap;

2.列出当前容器

 docker ps 列出当前正在运行的容器

参数:

  • -a 或 --all 列出当前所有正在运行的容器+历史上运行过的
  • -l 或 --latest 显示最近创建的容器
  • -n 显示最近n个创建的容器
  • -q 或 --quiet 静默模式,只显示容器编号
  • --no-trunc 不截断输出
  • -f 或 --filter 过滤

docker ps -a --filter name=ubuntu

3.退出容器

exit 容器停止退出

ctrl+P+Q 容器不停止退出

4.启动容器

docker start <container_id>

docker restart <container_id>

5.停止容器

docker stop <container_name>/<container_id> 停止容器

docker kill <container_name>/<container_id> 强制停止容器

6.删除容器

docker rm <container_name>/<container_id>

删除所有容器

docker rm -f $(docker ps -a -q)
docker ps -a -q | xargs docker rm
docker container prune -f 删除所有停止的容器

7.容器重命名

docker rename <old_container_name> <new_container_name>

8.查看容器日志

docker logs <container_name>/<container_id>

参数:

  • -t 加入时间戳
  • -f 跟随最新的日志打印
  • --tail n 显示最后n条

例如:docker nginx 的 access.log 会软连接到 /dev/stdout,才实现了在 docker logs 看日志,也就是写入 /dev/stdout 的信息,会出现在 docker 日志中

9.查看容器内运行的进程

docker top <container_name>/<container_id>

10.查看容器内部细节

docker inspect <container_name>/<container_id>

11.主机执行容器内命令

docker exec -it <container_name>/<container_id> command

例:docker exec -it <container_name>/<container_id> ls

12.进入正在运行的容器

docker exec -it <container_name>/<container_id> /bin/bash

docker attack <container_name>/<container_id> 

docker exec -it -u root <container_name>/<container_id> /bin/bash

-u root 以 root 进入容器

attach 直接进入容器启动命令的终端,不会启动新的进程

exec 是在容器打开新的终端,并且可以启动新的进程

13.提交

提交容器副本使之成为一个新的镜像

docker commit -m=“提交的描述信息” -a=“作者” 容器ID 要创建的目标镜像名:[标签名]

14.拷贝

docker cp  容器ID:容器内路径 目的主机路径

15.统计

docker stats <container_name> 实时统计容器内存情况
docker stats --no-stream <container_name> 统计容器内存情况

zxm@zxm-pc:~$ docker stats --no-stream
CONTAINER ID   NAME          CPU %     MEM USAGE / LIMIT     MEM %     NET I/O         BLOCK I/O        PIDS
f0af77a27b96   node3   0.03%     134MiB / 31.21GiB     0.42%     57.7kB / 164B   324kB / 24.6kB   41
a92739d831f8   node2   0.02%     135.3MiB / 31.21GiB   0.42%     58.4kB / 164B   328kB / 24.6kB   42
aed1ad426890   node1   0.02%     243.6MiB / 31.21GiB   0.76%     61.8kB / 164B   159MB / 24.6kB   42

三、系统命令

1.查看 docker 所占的硬盘大小

docker system df 查看 docker 所占的硬盘大小

-docker system df -v 查看 docker 每部分占用硬盘大小

zxm@zxm-pc:~$ docker system df
TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          27        18        13.44GB   2.482GB (18%)
Containers      23        0         13.74GB   13.74GB (100%)
Local Volumes   188       19        13.2GB    11.53GB (87%)
Build Cache     21        0         70.41MB   70.41MB

TYPE 列出了 Docker 使用磁盘的 4 种类型:

  • Images 所有镜像占用的空间,包括拉取下来的镜像,和本地构建的
  • Containers 运行的容器占用的空间,表示每个容器的读写层的空间
  • Local Volumes 容器挂载本地数据卷的空间
  • Build Cache 镜像构建过程中产生的缓存空间(只有在使用 BuildKit 时才有,Docker 18.09 以后可用)

最后的 RECLAIMABLE 这一列表示可回收的大小

2.清理空间

docker builder prune 一键清理 Build Cache 缓存命令

docker builder prune --filter 'until=240h' 清理时长更久的缓存,保留最近10天的缓存

docker system prune 自动清理空间

该指令默认会清除所有如下资源:

  • 已停止的容器(container)
  • 未被任何容器所使用的卷(volume)
  • 未被任何容器所关联的网络(network)
  • 所有悬空镜像(image)

docker system prsune -a 清理得更加彻底,可以将没有容器使用 Docker 镜像都删掉

四、网络命令

网络类型有:

  • host模式 –net=host 容器和宿主机共享Network namespace。
  • container模式 –net=container-name/container-id 容器和另外一个容器共享Network namespace。 kubernetes中的pod就是多个容器共享一个Network namespace。
  • none模式 –net=none 容器有独立的Network namespace,但并没有对其进行任何网络设置,如分配veth pair 和网桥连接,配置IP等。
  • bridge模式 –net=bridge (默认为该模式)

1.创建网络并指定网段

docker network create -d networktype network_name

-d 参数指定 Docker 网络类型,有 bridge overlay

例如:docker network create -d bridge my-net

建立网络,并指定网段 docker network create --driver bridge --subnet 172.18.0.0/24 --gateway 172.18.0.1 my-net

2.查看网络

docker network ls

3.删除网络

docker network rm <network_id>/<network_name>

4.查看网络的详细信息

docker network inspect <network_id>/<network_name>

五、数据卷

数据卷 是一个可供一个或多个容器使用的特殊目录,它绕过 UFS。数据卷 可以在容器之间共享和重用;数据卷 默认会一直存在,即使容器被删除。

注意:数据卷 的使用,类似于 Linux 下对目录或文件进行 mount,镜像中的被指定为挂载点的目录中的文件会复制到数据卷中(仅数据卷为空时会复制)。

1.创建数据卷

docker volume create <volume_name>

例如:

docker volume create busybox_vol_1

2.查看数据卷

  • docker volume ls 查看所有的数据卷
  • docker volume inspect <volume_name> 查看指定的数据卷

3.启动一个挂载数据卷的容器

docker run -itd --name busybox_1 -v busybox_vol_1:/test/1 busybox:1.36.0
docker run -itd --name busybox_1 --mount source=busybox_vol_1,target=/test/1 busybox:1.36.0
docker run -itd --name busybox_1 --mount type=volume,source=busybox_vol_1,target=/test/1 busybox:1.36.0

容器目录不可以为相对路径
映射容器目录/test/1(如果目录不存在则自动创建)

docker inspect busybox_1 查看容器的数据卷信息

"Mounts": [
    {
        "Type": "volume",
        "Name": "busybox_vol_1",
        "Source": "/var/lib/docker/volumes/busybox_vol_1/_data",
        "Destination": "/test/1",
        "Driver": "local",
        "Mode": "z",
        "RW": true,
        "Propagation": ""
    }
]

4.映射主机目录

docker run -itd --name busybox_2 -v /data/test/2:/test/2 busybox:1.36.0

容器目录不可以为相对路径

-v 参数,会在宿主机创建目录 /data/test/2(如果目录不存在则自动创建),映射容器目录/test/2(如果目录不存在则自动创建),主机目录的内容会覆盖容器目录的内容

docker run -itd --name busybox_2 --mount type=bind,source=/data/test/2,target=/test/2 busybox:1.36.0

--mount 参数,需要宿主机目录存在,否则会报错

"Mounts": [
    {
        "Type": "bind",
        "Source": "/data/test/2",
        "Destination": "/test/2",
        "Mode": "",
        "RW": true,
        "Propagation": "rprivate"
    }
]

docker run -itd --name busybox_3 -v test3:/test/3 busybox:1.36.0
若主机目录,是相对目录,则会在 docker 数据目录 /var/lib/docker/volumes,创建目录

"Mounts": [
    {
        "Type": "volume",
        "Name": "test3",
        "Source": "/var/lib/docker/volumes/test3/_data",
        "Destination": "/test/3",
        "Driver": "local",
        "Mode": "z",
        "RW": true,
        "Propagation": ""
    }
]

docker run -itd --name busybox_4 -v /test/4 busybox:1.36.0

若 -v 指定一个目录,则会在 docker 数据目录 /var/lib/docker/volumes下,随机生成的一个目录名

"Mounts": [
    {
        "Type": "volume",
        "Name": "7120d0b42f7825f41ef90adeba1e912f383eaab36f0ed6ef1496a95336e0629f",
        "Source": "/var/lib/docker/volumes/7120d0b42f7825f41ef90adeba1e912f383eaab36f0ed6ef1496a95336e0629f/_data",
        "Destination": "/test/4",
        "Driver": "local",
        "Mode": "",
        "RW": true,
        "Propagation": ""
    }
]

如果你使用 Bind mounts 挂载宿主机目录到一个容器中的非空目录,那么此容器中的非空目录中的文件会被隐藏,容器访问这个目录时能够访问到的文件均来自于宿主机目录。这也是 Bind mounts 模式和 Volumes 模式最大的不同

5.删除数据卷

  • docker volume rm <volume_name> 删除数据卷
  • docker volume prune 删除无主数据卷

数据卷 是被设计用来持久化数据的,它的生命周期独立于容器,Docker 不会在容器被删除后自动删除 数据卷,并且也不存在垃圾回收这样的机制来处理没有任何容器引用的 数据卷。如果需要在删除容器的同时移除数据卷。可以在删除容器的时候使用 docker rm -v 这个命令。

六、数据目录

docker info 可以查询到数据目录的位置,默认 docker 数据目录在 /var/lib/docker

  • /var/lib/docker/containers: 包含 Docker 容器的元数据和持久化数据,如容器的配置信息、日志、状态等。
  • /var/lib/docker/volumes: 存储 Docker 卷的数据,这些卷可以用来在容器之间共享数据或持久化数据。
  • /var/lib/docker/images: 存储 Docker 镜像的数据,这些镜像可以用来创建容器。
  • /var/lib/docker/networks: 存储 Docker 网络的数据,这些网络可以用来连接容器。
  • /var/lib/docker/swarm: 存储 Docker Swarm 的数据,这些数据包括集群的配置信息、状态信息等。
  • /var/lib/docker/tmp 目录用于存储 Docker 的临时文件
  • /var/lib/docker/overlay2 目录用于存储 Docker 的文件系统层
zxm@zxm-pc:~$ sudo ls -lh /var/lib/docker
总用量 80K
drwx--x--x   4 root root 4.0K 10月 18  2022 buildkit
drwx--x---  24 root root 4.0K 4月  27 10:11 containers
drwx------   3 root root 4.0K 10月 18  2022 image
drwxr-x---   3 root root 4.0K 10月 18  2022 network
drwx--x--- 256 root root  36K 4月  28 08:56 overlay2
drwx------   4 root root 4.0K 10月 18  2022 plugins
drwx------   2 root root 4.0K 4月  28 08:56 runtimes
drwx------   2 root root 4.0K 10月 18  2022 swarm
drwx------   2 root root 4.0K 4月  28 08:56 tmp
drwx------   2 root root 4.0K 10月 18  2022 trust
drwx-----x  56 root root 4.0K 4月  28 08:56 volumes

七、ubuntu 20.04 安装 docker

1.卸载旧版本

apt-get remove docker docker-engine docker.io containerd runc

2.设置 Docker 仓库

1)安装依赖包

apt install apt-transport-https ca-certificates curl gnupg2 software-properties-common

2)添加GPG密钥

添加 Docker 的官方 GPG 密钥:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -

如果你在阿里云上部署,可能使用阿里云的镜像源,添加阿里云的证书会更好一些。添加阿里云证书:
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | apt-key add -

3)添加软件源

使用阿里云的软件仓库:

add-apt-repository 
    "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu 
    $(lsb_release -cs) 
    stable"

也可以使用官方的软件仓库:

add-apt-repository 
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu 
  $(lsb_release -cs) 
  stable"

3.安装 DOCKER ENGINE-COMMUNITY

apt update
apt install docker-ce
systemctl restart docker

免 sudo 运行:

usermod -aG docker $USER

八、docker 与 虚拟机

docker 容器文件系统与 host OS 是隔离的。容器镜像中的应用软件无法看到主机文件系统,除非将主机文件系统挂载为容器的卷。

base image 并不带有 linux 内核,因为容器会使用主机的内核。

之所以成为 base image,而不是 base OS,是因为 base image 中并不包括完整的 OS。而这一点,是容器与虚拟机之前的本质区别之一。那就是,容器并没有虚拟化,而是共享主机上的linux 内核。