【学习笔记】Docker 常用命令


前言

记录 Docker 的常用操作命令,主要目的在于巩固学习,同时也希望对初学者起到一此借鉴作用。

PS:本次演练的系统环境为 CentOS 7,Docker 版本为 20.10.12, build e91ed57。

本文内容参考:Docker 教程 | 菜鸟教程 (runoob.com)

Docker 镜像加速

国内从 DockerHub 拉取镜像有时会比较困难,可以配置镜像加速器。Docker 官方和国内很多云服务商都提供了国内加速器服务,例如:

  • 阿里云:https://tia33io9.mirror.aliyuncs.com
  • 科大镜像:https://docker.mirrors.ustc.edu.cn/
  • 道客云:http://f1361db2.m.daocloud.io
  • 网易:https://hub-mirror.c.163.com/
  • 七牛云:https://reg-mirror.qiniu.com

Docker 官方加速器 https://registry.docker-cn.com ,现在好像已经不能使用了,我们可以多添加几个国内的镜像,如果有不能使用的,会切换到可以使用个的镜像来拉取。

当配置某一个加速器地址之后,若发现拉取不到镜像,请切换到另一个加速器地址。国内各大云服务商均提供了 Docker 镜像加速服务,建议根据运行 Docker 的云平台选择对应的镜像加速服务。

打开终端,使用 vim 打开 /etc/docker/daemon.json 文件,写入以下内容(如果文件不存在请新建该文件):

# 打开/etc/docker/daemon.json文件
vim /etc/docker/daemon.json
{
	"registry-mirrors": [
		"https://tia33io9.mirror.aliyuncs.com",
		"https://docker.mirrors.ustc.edu.cn",
		"http://f1361db2.m.daocloud.io",
		"https://hub-mirror.c.163.com",
		"https://reg-mirror.qiniu.com",
		"https://registry.docker-cn.com"
	]
}

之后重新启动服务:

sudo systemctl daemon-reload
sudo systemctl restart docker

Docker 简单示例

Docker 允许你在容器内运行应用程序, 使用 docker run 命令来在容器内运行一个应用程序。此处以 Nginx 服务部署做一个演练。

 docker run --name my-nginx -d -p 8888:80 -e TZ=Asia/Shanghai nginx

执行结果见下图:

PS:由于之前没有拉取过 Nginx 的镜像,所以会先自动下载 Nginx 镜像。拉取后自动运行容器。通过 docker ps 命令可以查看运行中的容器列表。

各个参数解析:

  • docker: Docker 的二进制执行文件。
  • run: 与前面的 docker 组合来运行一个容器。
  • --name my-nginx:指定运行的容器名称为 my-nginx
  • -d :后台运行。在大部分的场景下,我们希望 docker 的服务是在后台运行的,我们可以过 -d 指定容器的运行模式。注:加了 -d 参数默认不会进入容器,想要进入容器需要使用指令 docker exec(下面会介绍到)。
  • -p 8888:80:映射端口。开放主机 8888 端口,映射到容器的 80 端口。
  • -e TZ=Asia/Shanghai:环境变量。设置容器中运行程序的时区为 亚洲-上海。(我个人感觉这个设置有时很有必要,如果服务器时区与访问客户端不一致时,会出问题的)
  • nginx:指定要运行的镜像,Docker 首先从本地主机上查找镜像是否存在,如果不存在,Docker 就会从镜像仓库 Docker Hub 下载公共镜像。

执行 docker ps 命令,会把当前运行的容器给列出来。结果如上图所示。

字段 名称 结果
CONTAINER ID 容器ID b7498b9d4ba1
IMAGE 镜像名称 nginx
COMMAND 执行命令 "/docker-entrypoint.…"
CREATED 创建时间 2 minutes ago
STATUS 运行状态 Up 2 minutes
PORTS 端口映射 0.0.0.0:8888->80/tcp, :::8888->80/tcp
NAMES 容器名称 my-nginx

CentOS虚拟机的 局域网 IP为 192.168.1.30,通过浏览器访问 http://192.168.1.30:8888 ,出现以下画面,说明 nginx 服务器已正常运行。

Docker 镜像使用

当运行容器时,使用的镜像如果在本地中不存在,docker 就会自动从 docker 镜像仓库中下载,默认是从 Docker Hub 公共镜像源下载。

1、列出镜像

我们可以使用 docker images 来列出本地主机上的镜像。

docker images

# docker images 命令默认不显示中间镜像,如需查看全部镜像,请添加 -a 参数,使用 docker images -a 命令进行查询。

各列字段说明:

  • REPOSITORY:表示镜像的仓库源
  • TAG:镜像的标签
  • IMAGE ID:镜像ID
  • CREATED:镜像创建时间
  • SIZE:镜像大小

同一仓库源可以有多个 TAG,代表这个仓库源的不同个版本,如 ubuntu 仓库源里,有 15.10、14.04 等多个不同的版本,我们使用 REPOSITORY:TAG 来定义不同的镜像。

所以,我们如果要使用版本为15.10的ubuntu系统镜像来运行容器时,命令如下:

docker run -it ubuntu:15.10 /bin/bash 

如果你不指定一个镜像的版本标签,例如你只使用 ubuntu,docker 将默认使用 ubuntu:latest 镜像。

PS:如果想要查询某个镜像之前的版本(Tag),需要到 Docker Hub 官网 https://hub.docker.com/ 进行查询获取。

2、查找镜像

我们可以从 Docker Hub 网站来搜索镜像,Docker Hub 网址为: https://hub.docker.com/

我们也可以使用 docker search 命令来搜索镜像。比如我们需要一个 httpd 的镜像来作为我们的 web 服务。我们可以通过 docker search 命令搜索 httpd 来寻找适合我们的镜像。

[root@localhost ~]# docker search nginx

NAME: 镜像仓库源的名称

DESCRIPTION: 镜像的描述

OFFICIAL: 是否 docker 官方发布

STARS: 类似 Github 里面的 star,表示点赞、喜欢的意思。

AUTOMATED: 自动构建。

3、拖取镜像

当我们在本地主机上使用一个不存在的镜像时 Docker 就会自动下载这个镜像。如果我们想预先下载这个镜像,我们可以使用 docker pull 命令来下载它。

# 下载 ubuntu 镜像到本机
docker run ubuntu

输出内容如下所示:

[root@localhost ~]# docker pull ubuntu
Using default tag: latest
latest: Pulling from library/ubuntu
7b1a6ab2e44d: Pull complete
Digest: sha256:626ffe58f6e7566e00254b638eb7e0f3b11d4da9675088f4781a50ae288f3322
Status: Downloaded newer image for ubuntu:latest
docker.io/library/ubuntu:latest
[root@localhost ~]#

下载完成后,我们就可以使用这个镜像了。

# 运行并进入容器,执行相应命令
docker run -it ubuntu /bin/bash

PS:我运行到这里竟然失败了!出现以下提示:

WARNING: IPv4 forwarding is disabled. Networking will not work.

网上搜索了一下,通过以下办法解决 “IPv4 forwarding is disabled” 的问题。

第一步:在宿主机上执行 echo "net.ipv4.ip_forward = 1" >>/usr/lib/sysctl.d/00-system.conf

# 执行命令
echo "net.ipv4.ip_forward = 1" >>/usr/lib/sysctl.d/00-system.conf

# 查看文件
cat /usr/lib/sysctl.d/00-system.conf

# 以下为文件内容,可以看到 net.ipv4.ip_forward = 1 的设置已追加到文件末尾。

# Kernel sysctl configuration file
#
# For binary values, 0 is disabled, 1 is enabled.  See sysctl(8) and
# sysctl.conf(5) for more details.

# Disable netfilter on bridges.
net.bridge.bridge-nf-call-ip6tables = 0
net.bridge.bridge-nf-call-iptables = 0
net.bridge.bridge-nf-call-arptables = 0
net.ipv4.ip_forward = 1

第二步:重启network和docker服务

systemctl restart network && systemctl restart docker

第三步:验证是否成功

docker run -it ubuntu /bin/bash

完美解决。

4、删除镜像

镜像删除使用 **docker rmi ** 或 docker image rm 命令:

docker rmi ubuntu:14.04

删除指定镜像,也可以使用镜像ID:

[root@localhost ~]# docker image rm 9b9cb95443b5
Untagged: ubuntu:15.10
Untagged: ubuntu@sha256:02521a2d079595241c6793b2044f02eecf294034f31d6e235ac4b2b54ffc41f3
Deleted: sha256:9b9cb95443b5f846cd3c8cfa3f64e63b6ba68de2618a08875a119c81a8f96698
Deleted: sha256:b616585738eaf78ff7d86c7526caf7c91a35bc4028ef63204e5bfee82f7494b5
Deleted: sha256:dee1316f97acc7e1a5088b02fbc2b3078e0bfa038dd904b8072e2de5656e7bb8
Deleted: sha256:e7d9ae1a69c53c9fefa1aef34348be5a5dbf2fe79e7dd647b3d4f4e927587ebc
Deleted: sha256:f121afdbbd5dd49d4a88c402b1a1a4dca39c9ae75ed7f80a29ffd9739fc680a7
[root@localhost ~]# #这里再列表所有镜像,可以看到 ubuntu:15.10 已不见了。
[root@localhost ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
nginx        latest    605c77e624dd   8 days ago     141MB
ubuntu       latest    ba6acccedd29   2 months ago   72.8MB
[root@localhost ~]#

5、创建镜像

当我们从 docker 镜像仓库中下载的镜像不能满足我们的需求时,我们可以通过以下两种方式对镜像进行更改。

  • 1、从已经创建的容器中更新镜像,并且提交这个镜像
  • 2、使用 Dockerfile 指令来创建一个新的镜像

5.1 更新镜像

更新镜像之前,我们需要使用镜像来创建一个容器。

[root@localhost ~]# docker run -t -i ubuntu:latest /bin/bash
root@dd88dacb1af7:/#
# 注意哦,通过前面显示的登录账号名称,可以看出,目前已是进入了 ubuntu 容器中了。

在运行的容器内使用 apt-get update 命令进行更新。

在完成操作之后,输入 exit 命令来退出这个容器。

此时 ID 为 dd88dacb1af7 的容器,是按我们的需求更改的容器。我们可以通过命令 docker commit 来提交容器副本。

[root@localhost ~]# docker commit -m="This has been updated." -a="jack" dd88dacb1af7 jack/ubuntu:v2
sha256:d1c2e19bdcdcb5f3ffb4c5b1c795e938defa9c316588ec49603a817c472f303b
[root@localhost ~]#

各个参数说明:

  • -m: 提交的描述信息
  • -a: 指定镜像作者
  • dd88dacb1af7:容器 ID
  • jack/ubuntu:v2: 指定要创建的目标镜像名

我们可以使用 docker images 命令来查看我们的新镜像 jack/ubuntu:v2

[root@localhost ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED              SIZE
jack/ubuntu   v2        d1c2e19bdcdc   About a minute ago   105MB
nginx         latest    605c77e624dd   8 days ago           141MB
ubuntu        latest    ba6acccedd29   2 months ago         72.8MB

5.2 构建镜像

使用VS2022,基于.NET 6 ,创建一个控制台程序进行镜像发布。最简单的 Hello World 输出。

  • 选择项目模板

  • 设置项目名称,就叫 HelloWorldDemo 吧。(选择将解决方案和项目放在同一目录)

  • 选择运行时版本为 .NET 6.0 (长期支持),然后点击“创建”按钮。

项目创建完成,整个程序目前仅一句代码:

Console.WriteLine("Hello, World!");

  • 点击右侧解决方案资源管理器,在项目名称上面右键,选择 “添加” -- “Docker 支持 …”,会弹出一个“Docker 文件选项”窗口,选择 “Linux” 。

  • 点击确定后,会在项目下生成一个 Dockerfile 文件。

Dockerfile 文件代码如下:

#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/dotnet/runtime:6.0 AS base
WORKDIR /app

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["HelloWorldDemo.csproj", "."]
RUN dotnet restore "./HelloWorldDemo.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "HelloWorldDemo.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "HelloWorldDemo.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "HelloWorldDemo.dll"]

每一个指令都会在镜像上创建一个新的层,每一个指令的前缀都必须是大写的。

第一条FROM,指定使用哪个镜像源

RUN 指令告诉docker 在镜像内执行命令,安装了什么。。。

后面,我们会使用 Dockerfile 文件,通过 docker build 命令来构建一个镜像。

  • 选择控制台输出方式,本地运行调试。输出 “Hello World” ,说明程序运行正常。

OK ,到了这一步,我们的程序已准备好了。下面就选择把项目整体打包到 Linux,在服务器上进行编辑打包,镜像构建。

  • 打开项目所在文件夹,把一些无用的文件删除掉。

  • 清理掉无用文件夹,直接把项目文件夹上传服务器。如下图所示,关键点就在于本次上传的文件中包含了 Dockerfile 文件。

  • 执行镜像打包 docker build 命令: ( 注意哦,命令最后面有一个 “.” 符号 )
docker build -t my-hello-world .

参数说明:

  • -t :指定要创建的目标镜像名
  • . :Dockerfile 文件所在目录,可以指定Dockerfile 的绝对路径
  • 开台下载中间镜像,并进行编辑。

最终完整输出如下:


[root@localhost HelloWorldDemo]# docker build -t my-hello-world .
Sending build context to Docker daemon  7.168kB
Step 1/15 : FROM mcr.microsoft.com/dotnet/runtime:6.0 AS base
6.0: Pulling from dotnet/runtime
a2abf6c4d29d: Pull complete
08af7dd3c640: Pull complete
742307799914: Pull complete
a260dbcd03fc: Pull complete
Digest: sha256:315b0ab91f3abf2b29bc91963d86be6dd69abce3fe272306ed4ef8a5a7a190c0
Status: Downloaded newer image for mcr.microsoft.com/dotnet/runtime:6.0
 ---> 8a2ce7cb4b01
Step 2/15 : WORKDIR /app
 ---> Running in 9c79c4e71115
Removing intermediate container 9c79c4e71115
 ---> f6738ccc8759
Step 3/15 : FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
6.0: Pulling from dotnet/sdk
a2abf6c4d29d: Already exists
08af7dd3c640: Already exists
742307799914: Already exists
a260dbcd03fc: Already exists
96c3c696f47e: Pull complete
d81364490ceb: Pull complete
3e56f7c4d95f: Pull complete
9939dbdaf4a7: Pull complete
Digest: sha256:a7af03bdead8976d4e3715452fc985164db56840691941996202cea411953452
Status: Downloaded newer image for mcr.microsoft.com/dotnet/sdk:6.0
 ---> e86d68dca8c7
Step 4/15 : WORKDIR /src
 ---> Running in 2442842227a1
Removing intermediate container 2442842227a1
 ---> d11c08ee15dd
Step 5/15 : COPY ["HelloWorldDemo.csproj", "."]
 ---> cf0d49961aad
Step 6/15 : RUN dotnet restore "./HelloWorldDemo.csproj"
 ---> Running in b3962d0da619
  Determining projects to restore...
  Restored /src/HelloWorldDemo.csproj (in 2.16 sec).
Removing intermediate container b3962d0da619
 ---> 649ed5b1ae54
Step 7/15 : COPY . .
 ---> e43f4a0cc84f
Step 8/15 : WORKDIR "/src/."
 ---> Running in 95ee5b391f75
Removing intermediate container 95ee5b391f75
 ---> dd6909ce462f
Step 9/15 : RUN dotnet build "HelloWorldDemo.csproj" -c Release -o /app/build
 ---> Running in e05f29a6ca5b
Microsoft (R) Build Engine version 17.0.0+c9eb9dd64 for .NET
Copyright (C) Microsoft Corporation. All rights reserved.

  Determining projects to restore...
  All projects are up-to-date for restore.
  HelloWorldDemo -> /app/build/HelloWorldDemo.dll

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:06.11
Removing intermediate container e05f29a6ca5b
 ---> 266ccf4a1f98
Step 10/15 : FROM build AS publish
 ---> 266ccf4a1f98
Step 11/15 : RUN dotnet publish "HelloWorldDemo.csproj" -c Release -o /app/publish
 ---> Running in 1e914748682c
Microsoft (R) Build Engine version 17.0.0+c9eb9dd64 for .NET
Copyright (C) Microsoft Corporation. All rights reserved.

  Determining projects to restore...
  All projects are up-to-date for restore.
  HelloWorldDemo -> /src/bin/Release/net6.0/HelloWorldDemo.dll
  HelloWorldDemo -> /app/publish/
Removing intermediate container 1e914748682c
 ---> 018f9624857c
Step 12/15 : FROM base AS final
 ---> f6738ccc8759
Step 13/15 : WORKDIR /app
 ---> Running in 8764e2145751
Removing intermediate container 8764e2145751
 ---> d7ec7560e4f9
Step 14/15 : COPY --from=publish /app/publish .
 ---> 637fe040bfdc
Step 15/15 : ENTRYPOINT ["dotnet", "HelloWorldDemo.dll"]
 ---> Running in be3764a6bee1
Removing intermediate container be3764a6bee1
 ---> 1add28a21d49
Successfully built 1add28a21d49
Successfully tagged my-hello-world:latest
[root@localhost HelloWorldDemo]#

  • 使用docker images 查看创建的镜像已经在列表中存在,镜像ID为1add28a21d49,名称为 my-hello-world

  • 最后,我们可以使用容器来运行镜像。可以看出,Hello,World !已正常输出。( ?? ω ?? )?
docker run my-hello-world

6、设置标签

我们可以使用 docker tag 命令,为镜像添加一个新的标签。

 docker tag 1add28a21d49 my-hello-world:V1.0
 # 参数说明:
 # docker tag <镜像ID> <镜像源名> <新的标签名>

使用 docker images 命令可以看到,ID为 1add28a21d49 的镜像多一个标签 V1.0。


[root@localhost HelloWorldDemo]# docker images
REPOSITORY                         TAG       IMAGE ID       CREATED          SIZE
my-hello-world                     V1.0      1add28a21d49   15 minutes ago   188MB
my-hello-world                     latest    1add28a21d49   15 minutes ago   188MB
                                 018f9624857c   15 minutes ago   726MB
mcr.microsoft.com/dotnet/sdk       6.0       e86d68dca8c7   2 weeks ago      716MB
mcr.microsoft.com/dotnet/runtime   6.0       8a2ce7cb4b01   2 weeks ago      188MB
[root@localhost HelloWorldDemo]#

PS:我个人理解,打标签就是把原甩的镜像复制一份,加个标签显示而已。

Docker 容器使用

1、帮助手册

docker 客户端非常简单 ,我们可以直接输入 docker 命令来查看到 Docker 客户端的所有命令选项。

[root@localhost ~]# docker

这个就不放图了,可以自己去试一下。可以通过命令 docker command --help 更深入的了解指定的 Docker 命令使用方法。

例如我们要查看 docker run 指令的具体使用方法:

[root@localhost ~]# docker run --help

2、获取镜像

如果我们本地没有镜像,我们可以使用 docker pull 命令来载入镜像:

docker pull nginx

2、启动容器

[root@localhost HelloWorldDemo]# docker run -d -p 9999:80 --name my-nginx nginx
24054bd26a66522c9b3b6fc067d2a24d2bb9153b5be38f8dc3d658ba6a3a9e04

参数说明:(见前面简单示例内容)

3、启动已停止运行的容器

查看所有的容器命令如下:

docker ps -a

使用 docker start 启动一个已停止的容器:

docker start 70994ac442fa

4、后台运行

在大部分的场景下,我们希望 docker 的服务是在后台运行的,我们可以过 -d 指定容器的运行模式。

docker run -d -p 9999:80 --name my-nginx nginx

注:加了 -d 参数默认不会进入容器,想要进入容器需要使用指令 docker exec

5、停止容器

停止容器的命令如下:

docker stop <容器 ID>

停止的容器可以通过 docker restart 重启:

docker restart <容器 ID>

6、进入容器

在使用 -d 参数时,容器启动后会进入后台。此时想要进入容器,可以通过以下指令进入:

  • docker attach
  • docker exec:推荐大家使用 docker exec 命令,因为此退出容器终端,不会导致容器的停止。
# 进入容器
[root@localhost HelloWorldDemo]# docker exec -it 24054bd26a66 /bin/bash

# 查看当前目录
root@24054bd26a66:/# ls
bin   dev                  docker-entrypoint.sh  home  lib64  mnt  proc  run   srv  tmp  var
boot  docker-entrypoint.d  etc                   lib   media  opt  root  sbin  sys  usr

# 退出容器
root@24054bd26a66:/# exit
exit
[root@localhost HelloWorldDemo]#

7、删除容器

删除容器使用 docker rm 命令:

# 正常情况下,我们只能删除已停止的容器,添加  -f  参数,强制执行,不再考虑容器是否正在运行。
[root@localhost HelloWorldDemo]# docker rm -f 70994ac442fa
70994ac442fa
[root@localhost HelloWorldDemo]# 

8、查看日志

docker logs [ID或者名字] 可以查看容器内部的标准输出。

[root@localhost HelloWorldDemo]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                                   NAMES
24054bd26a66   nginx     "/docker-entrypoint.…"   18 minutes ago   Up 18 minutes   0.0.0.0:9999->80/tcp, :::9999->80/tcp   my-nginx
[root@localhost HelloWorldDemo]# docker logs 24054bd26a66
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2022/01/09 07:29:48 [notice] 1#1: using the "epoll" event method
2022/01/09 07:29:48 [notice] 1#1: nginx/1.21.5
2022/01/09 07:29:48 [notice] 1#1: built by gcc 10.2.1 20210110 (Debian 10.2.1-6)
2022/01/09 07:29:48 [notice] 1#1: OS: Linux 3.10.0-1160.49.1.el7.x86_64
2022/01/09 07:29:48 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2022/01/09 07:29:48 [notice] 1#1: start worker processes
2022/01/09 07:29:48 [notice] 1#1: start worker process 32
2022/01/09 07:29:48 [notice] 1#1: start worker process 33
2022/01/09 07:29:48 [notice] 1#1: start worker process 34
2022/01/09 07:29:48 [notice] 1#1: start worker process 35
[root@localhost HelloWorldDemo]#

9、运行状态

通过 docker stats <容器名称|ID> 命令可以查看容器的运行状态(会一直监控)。

[root@localhost HelloWorldDemo]# docker stats my-nginx
#================================
CONTAINER ID   NAME       CPU %     MEM USAGE / LIMIT     MEM %     NET I/O     BLOCK I/O     PIDS
24054bd26a66   my-nginx   0.01%     3.074MiB / 1.777GiB   0.17%     656B / 0B   0B / 14.3kB   5
CONTAINER ID   NAME       CPU %     MEM USAGE / LIMIT     MEM %     NET I/O     BLOCK I/O     PIDS
24054bd26a66   my-nginx   0.01%     3.074MiB / 1.777GiB   0.17%     656B / 0B   0B / 14.3kB   5
CONTAINER ID   NAME       CPU %     MEM USAGE / LIMIT     MEM %     NET I/O     BLOCK I/O     PIDS
24054bd26a66   my-nginx   0.00%     3.074MiB / 1.777GiB   0.17%     656B / 0B   0B / 14.3kB   5
…… ……

10、查看配置

使用 docker inspect 来查看 Docker 的底层信息。它会返回一个 JSON 文件记录着 Docker 容器的配置和状态信息。

[root@localhost HelloWorldDemo]# docker inspect my-nginx
[
    {
        "Id": "24054bd26a66522c9b3b6fc067d2a24d2bb9153b5be38f8dc3d658ba6a3a9e04",
        "Created": "2022-01-09T07:29:47.729484247Z",
        "Path": "/docker-entrypoint.sh",
        "Args": [
            "nginx",
            "-g",
            "daemon off;"
        ],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 20677,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2022-01-09T07:29:48.345380918Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        "Image": "sha256:605c77e624ddb75e6110f997c58876baa13f8754486b461117934b24a9dc3a85",
        "ResolvConfPath": "/var/lib/docker/containers/24054bd26a66522c9b3b6fc067d2a24d2bb9153b5be38f8dc3d658ba6a3a9e04/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/24054bd26a66522c9b3b6fc067d2a24d2bb9153b5be38f8dc3d658ba6a3a9e04/hostname",
        "HostsPath": "/var/lib/docker/containers/24054bd26a66522c9b3b6fc067d2a24d2bb9153b5be38f8dc3d658ba6a3a9e04/hosts",
        "LogPath": "/var/lib/docker/containers/24054bd26a66522c9b3b6fc067d2a24d2bb9153b5be38f8dc3d658ba6a3a9e04/24054bd26a66522c9b3b6fc067d2a24d2bb9153b5be38f8dc3d658ba6a3a9e04-json.log",
        "Name": "/my-nginx",
        "RestartCount": 0,
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": null,
        "HostConfig": {
            "Binds": null,
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "default",
            "PortBindings": {
                "80/tcp": [
                    {
                        "HostIp": "",
                        "HostPort": "9999"
                    }
                ]
            },
            "RestartPolicy": {
                "Name": "no",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "CapAdd": null,
            "CapDrop": null,
            "CgroupnsMode": "host",
            "Dns": [],
            "DnsOptions": [],
            "DnsSearch": [],
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "private",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": null,
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "Runtime": "runc",
            "ConsoleSize": [
                0,
                0
            ],
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": [],
            "BlkioDeviceReadBps": null,
            "BlkioDeviceWriteBps": null,
            "BlkioDeviceReadIOps": null,
            "BlkioDeviceWriteIOps": null,
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": [],
            "DeviceCgroupRules": null,
            "DeviceRequests": null,
            "KernelMemory": 0,
            "KernelMemoryTCP": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": null,
            "OomKillDisable": false,
            "PidsLimit": null,
            "Ulimits": null,
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0,
            "MaskedPaths": [
                "/proc/asound",
                "/proc/acpi",
                "/proc/kcore",
                "/proc/keys",
                "/proc/latency_stats",
                "/proc/timer_list",
                "/proc/timer_stats",
                "/proc/sched_debug",
                "/proc/scsi",
                "/sys/firmware"
            ],
            "ReadonlyPaths": [
                "/proc/bus",
                "/proc/fs",
                "/proc/irq",
                "/proc/sys",
                "/proc/sysrq-trigger"
            ]
        },
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/4a3a739f9a9119beba2e538df7337fea5f168341dc42c9bc65ce36be7a528718-init/diff:/var/lib/docker/overlay2/88d844c8acf8fbfec44d5f4c7327504bdca4e1873113199ade6260d4da46c623/diff:/var/lib/docker/overlay2/b69d39d9431945be58d6a8924dd234c0007243113890853cea9fe0c77a0b5586/diff:/var/lib/docker/overlay2/81a4e929367676ac2cdf41efbcc243f6d5ccb086f37bc68d0bc479126cfd4ec7/diff:/var/lib/docker/overlay2/9b1e65f53f3fdefeb5691bd2311fe667bdc235090b88044ccca7c1ae14d975ed/diff:/var/lib/docker/overlay2/f4eed501c804e0d20564b21c8168e6ad11cca0d39fbf540343a90cdcffed0977/diff:/var/lib/docker/overlay2/f551faa359b34434e21a0ab26f5bed102c84318472f73412e0e2c5adcb5fe968/diff",
                "MergedDir": "/var/lib/docker/overlay2/4a3a739f9a9119beba2e538df7337fea5f168341dc42c9bc65ce36be7a528718/merged",
                "UpperDir": "/var/lib/docker/overlay2/4a3a739f9a9119beba2e538df7337fea5f168341dc42c9bc65ce36be7a528718/diff",
                "WorkDir": "/var/lib/docker/overlay2/4a3a739f9a9119beba2e538df7337fea5f168341dc42c9bc65ce36be7a528718/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [],
        "Config": {
            "Hostname": "24054bd26a66",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "80/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "NGINX_VERSION=1.21.5",
                "NJS_VERSION=0.7.1",
                "PKG_RELEASE=1~bullseye"
            ],
            "Cmd": [
                "nginx",
                "-g",
                "daemon off;"
            ],
            "Image": "nginx",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": [
                "/docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": {
                "maintainer": "NGINX Docker Maintainers "
            },
            "StopSignal": "SIGQUIT"
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "248e77ef721f2e006d6e200c746f6844beb190ec15ad229d17080e4ae644cada",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {
                "80/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "9999"
                    },
                    {
                        "HostIp": "::",
                        "HostPort": "9999"
                    }
                ]
            },
            "SandboxKey": "/var/run/docker/netns/248e77ef721f",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "ab9dd37591919447479f7a12c54fde1b45e39083a7906f6200092896d33b481b",
            "Gateway": "172.17.0.1",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.17.0.2",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "MacAddress": "02:42:ac:11:00:02",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "94f59e18e4d854c6dc8fa1848d791f91905e675619c9ddd2d6a46f880882c3bc",
                    "EndpointID": "ab9dd37591919447479f7a12c54fde1b45e39083a7906f6200092896d33b481b",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:02",
                    "DriverOpts": null
                }
            }
        }
    }
]

小结

以上内容,已把 Docker 容器的一些常用操作命令进行了演示,掌握之后,正常操作入门已是没有太大问题。

在进行本次演练的过程中,我也是踩了不少的坑。比如自己构建镜像的那一块,我就是由于对 Dockerfile 的配置没有写正确,导致镜像打包过程中总是报错。后面还是向社区的朋友请教了之后才磕磕碰碰的发布成功。

^ _ ^ ,感谢 橙子! 这是他搞的一个开源项目,ccnetcore/Yi: Yi.Framework-基于.NET5+Vue快速开发框架 (github.com),大家感兴趣的可以去瞅瞅!顺便点个星星。