Table of Contents

一、Docker 常用命令操作

1. 常用帮助命令

1
2
3
$ docker version 		# 显示docker的版本信息
$ docker info			# 显示docker的系统信息	
$ docker 命令 --help	

2. 使用镜像

docker images 查看所有本地的主机上的镜像

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13

Usage:  docker images [OPTIONS] [REPOSITORY[:TAG]]

List images

Options:
  -a, --all             Show all images (default hides intermediate images)
      --digests         Show digests
  -f, --filter filter   Filter output based on conditions provided
      --format string   Pretty-print images using a Go template
      --no-trunc        Don't truncate output
  -q, --quiet           Only show image IDs

1
2
3
[user-for-dockerStudy@izuf6adsdfwblstgm2jy8sz ~]$ sudo docker images -a
REPOSITORY    TAG       IMAGE ID       CREATED       SIZE
hello-world   latest    feb5d9fea6a5   3 weeks ago   13.3kB

列表包含了 仓库名、标签、镜像 ID、创建时间 以及 所占用的空间。镜像 ID 则是镜像的唯一标识,一个镜像可以对应多个 标签。比如: ubuntu:18.04 和 ubuntu:bionic 拥有相同的 ID,因为它们对应的是同一个镜像。

docker image ls 同样可以查看镜像

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20

Usage:  docker image COMMAND

Manage images

Commands:
  build       Build an image from a Dockerfile
  history     Show the history of an image
  import      Import the contents from a tarball to create a filesystem image
  inspect     Display detailed information on one or more images
  load        Load an image from a tar archive or STDIN
  ls          List images
  prune       Remove unused images
  pull        Pull an image or a repository from a registry
  push        Push an image or a repository to a registry
  rm          Remove one or more images
  save        Save one or more images to a tar archive (streamed to STDOUT by default)
  tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE

Run 'docker image COMMAND --help' for more information on a command.

docker search 在Docker hub中搜索镜像

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11

Usage:  docker search [OPTIONS] TERM

Search the Docker Hub for images

Options:
  -f, --filter filter   Filter output based on conditions provided
      --format string   Pretty-print search using a Go template
      --limit int       Max number of search results (default 25)
      --no-trunc        Don't truncate output

docker pull 从 Docker 镜像仓库获取镜像

docker rm/rmi 删除本地镜像

1
2
3
4
$ docker image rm [选项] <镜像1> [<镜像2> ...]		
#  其中,<镜像> 可以是 镜像短 ID、镜像长 ID、镜像名 或者 镜像摘要。
$ docker image rm $(docker image ls -q redis)
#  配合使用

3. 操作容器

  • 启动

    启动容器有两种方式,一种是基于镜像新建一个容器并启动,另外一个是将在终止状态(exited)的容器重新启动。

    新建并启动

    docker run

    例如,下面的命令输出一个 “Hello World”,之后终止容器。

    1
    
    sudo docker run ubuntu:18.04 /bin/echo 'hello world'
    

    也可以启动bash终端,以交互形式运行 docker 容器。

    1
    2
    
    [user-for-dockerStudy@izuf6adsdfwblstgm2jy8sz ~]$ sudo docker run -it ubuntu:18.04 /bin/bash
    root@d7d8a7e6132a:/# 
    

    启动已终止容器

    docker container start 直接将一个已经终止(exited)的容器启动运行。

  • docker ps 查看当前运行容器,-a 查看历史容器

  • 守护态运行

    通过增加 -d 参数设置守护态运行。

    • 如果不使用 -a 参数运行容器
    1
    2
    3
    4
    5
    
    $ docker run ubuntu:18.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"
    hello world
    hello world
    hello world
    hello world
    

    容器会把输出的结果 (STDOUT) 打印到宿主机上面

    • 如果使用 -a 参数运行容器

      1
      2
      
      $ docker run -d ubuntu:18.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"
      77b2dc01fe0f3f1265df143181e7b9af5e05279a884f4776ee75350ea9d8017a
      

      此时容器会在后台运行并不会把输出的结果 (STDOUT) 打印到宿主机上面(输出结果可以用 docker logs 查看)。

    注: 容器是否会长久运行,是和 docker run 指定的命令有关,和 -d 参数无关。

  • 终止、启动、重启

    可以使用 docker container stop 来终止一个运行中的容器。

    此外,当 Docker 容器中指定的应用终结时,容器也自动终止。

    例如对于上一章节中只启动了一个终端的容器,用户通过 exit 命令或 Ctrl+D 来退出终端时,所创建的容器立刻终止。然而使用 Ctrl+P+Q 创建的容器不会终止。

    处于终止状态的容器,可以通过 docker container start 命令来重新启动。

    此外,docker container restart 命令会将一个运行态的容器终止,然后再重新启动它。

  • 进入容器

    在使用 -d 参数时,容器启动后会进入后台。

    某些时候需要进入容器进行操作,包括使用 docker attach 命令或 docker exec 命令,推荐大家使用 docker exec 命令。

    docker exec

    docker exec 后边可以跟多个参数,这里主要说明 -i -t 参数。

    只用 -i 参数时,由于没有分配伪终端,界面没有我们熟悉的 Linux 命令提示符,但命令执行结果仍然可以返回。

    当 -i -t 参数一起使用时,则可以看到我们熟悉的 Linux 命令提示符。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    # 1. 使用docker exec 进入容器,并exit 退出
    [user-for-dockerStudy@izuf6adsdfwblstgm2jy8sz ~]$ sudo docker exec -it bd109ac45e7b bash
    root@bd109ac45e7b:/# exit
    exit
    
    # 2. 查看docker 容器是否被停止
    [user-for-dockerStudy@izuf6adsdfwblstgm2jy8sz ~]$ sudo docker ps
    CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS         PORTS     NAMES
    bd109ac45e7b   ubuntu:18.04   "/bin/sh -c 'while t…"   5 minutes ago   Up 5 minutes             silly_ptolemy
    

    用docker exec 在容器中执行exit 后,也不会导致容器的停止。所以推荐大家使用 docker exec

    docker attach

    使用如下:

    1
    2
    3
    4
    
    [user-for-dockerStudy@izuf6adsdfwblstgm2jy8sz ~]$ sudo docker attach bd109ac45e7b
    hello world
    hello world
    hello world
    

    注意: 如果从这个 stdin 中 exit,会导致容器的停止。

  • 删除

    **docker container rm ** 来删除处于终止状态的容器。

    如果要删除一个运行中的容器,可以添加 -f 参数。Docker 会发送 SIGKILL 信号给容器。

    docker container prune 清理所有处于终止状态的容器。


4. 小测试

  1. 部署nginx

    1
    2
    
    $ docker pull nginx
    $ docker run -d --name nginx-1 -p 3344:80 nginx
    

    利用-d 参数守护态运行,-p 指定容器及容器外部映射端口,分别为80 和 3344。(端口暴露)

    本机测试

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    
    [user-for-dockerStudy@izuf6adsdfwblstgm2jy8sz ~]$ curl localhost:3344
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
    html { color-scheme: light dark; }
    body { width: 35em; margin: 0 auto;
    font-family: Tahoma, Verdana, Arial, sans-serif; }
    </style>
    </head>
    <body>
    <h1>Welcome to nginx!</h1>
    <p>If you see this page, the nginx web server is successfully installed and
    working. Further configuration is required.</p>
    
    <p>For online documentation and support please refer to
    <a href="http://nginx.org/">nginx.org</a>.<br/>
    Commercial support is available at
    <a href="http://nginx.com/">nginx.com</a>.</p>
    
    <p><em>Thank you for using nginx.</em></p>
    </body>
    </html>
    

    image-20211021181345096

    5. 可视化

    portainer 工具

    安装: sudo docker run -d -p 9000:9000 --restart=always --name portainer -v /var/run/docker.sock:/var/run/docker.sock -v /Users/lee/dev/docker_file/portainer/data:/data docker.io/portainer/portainer

    image-20211021182653580

二、定制镜像

1. 利用 commit 理解镜像构成

不要使用 docker commit 定制镜像,定制镜像应该使用 Dockerfile 来完成。

  1. 创建一个nginx 容器

    改变nginx的一些内容

    1
    
    echo '<h1>Hello, Docker!</h1>' >  /usr/share/nginx/html/index.html
    

    image-20211021185018322

  2. 使用commit 保持容器的存储层为镜像

    现在我们定制好了变化,我们希望能将其保存下来形成镜像。

    要知道,当我们运行一个容器的时候(如果不使用卷的话),我们做的任何文件修改都会被记录于容器存储层里。而 Docker 提供了一个 docker commit 命令,可以将容器的存储层保存下来成为镜像。换句话说,就是在原有镜像的基础上,再叠加上容器的存储层,并构成新的镜像。以后我们运行这个新镜像的时候,就会拥有原有容器最后的文件变化。

    1
    
    sudo docker commit --author "firefoxking" --message "fda" nginx01 nginx01:v2
    

    利用 docker images 可以看到多了一个镜像。

    image-20211021185705167

    使用 docker commit 命令虽然可以比较直观的帮助理解镜像分层存储的概念,但是实际环境中并不会这样使用。由于commit 不会删除之前的每一层,每一次修改都会导致镜像更加臃肿以此。

2. 使用 Dockerfile 定制镜像

以nginx为例定制一个简单镜像:

1
2
3
4
5
$ mkdir mynginx
$ cd mynginx
$ touch Dockerfile

$ vim Dockerfile
1
2
FROM nginx
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html

这个 Dockerfile 很简单,一共就两行。涉及到了两条指令,FROM 和 RUN。

  • RUN 执行指令

    • shell 格式:RUN <命令>
    • exec 格式:RUN ["可执行文件", "参数1", "参数2"]

    Dockerfile 中每一个指令都会建立一层,RUN 也不例外。每一个 RUN 的行为,就和刚才我们手工建立镜像的过程一样:新建立一层,在其上执行这些命令,执行结束后,commit 这一层的修改,构成新的镜像。不会建太多层,案例如下:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    
    FROM debian:stretch
    
    RUN set -x; buildDeps='gcc libc6-dev make wget' \
        && apt-get update \
        && apt-get install -y $buildDeps \
        && wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
        && mkdir -p /usr/src/redis \
        && tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1 \
        && make -C /usr/src/redis \
        && make -C /usr/src/redis install \
        && rm -rf /var/lib/apt/lists/* \
        && rm redis.tar.gz \
        && rm -r /usr/src/redis \
        && apt-get purge -y --auto-remove $buildDeps
    
  • 构建镜像

    在 Dockerfile 文件所在目录执行:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    
    FROM debian:stretch
    
    RUN set -x; buildDeps='gcc libc6-dev make wget' \
        && apt-get update \
        && apt-get install -y $buildDeps \
        && wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
        && mkdir -p /usr/src/redis \
        && tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1 \
        && make -C /usr/src/redis \
        && make -C /usr/src/redis install \
        && rm -rf /var/lib/apt/lists/* \
        && rm redis.tar.gz \
        && rm -r /usr/src/redis \
        && apt-get purge -y --auto-remove $buildDeps
    

三、参考

更多关于这部分的内容可以参考使用 Dockerfile 定制镜像