Docker

Stone大约 29 分钟

Docker

概述

Dockeropen in new window 是一个用于开发、交付和运行应用程序的开放平台,通过 Docker 可以快速交付、测试和部署应用程序。不论是开发人员还是运维人员,Docker 都是一门必需掌握的技术。

image-20230821213350218

用途

Docker 将应用程序与该程序的依赖,打包在一个镜像文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。当需要安装某些程序时,无需再去安装该程序的依赖,直接从仓库中下载其打包好的镜像文件安装即可。

架构

Docker 使用客户端-服务器架构。

包括:

  • Docker daemon:是一个运行在宿主机(DOCKER_HOST)的后台进程。
  • Client:Docker 客户端,接受用户命令,与 Docker daemon 通信。

docker architecture

其中:

  • Images:Docker 镜像,是一个包含应用程序及其依赖的文件。
  • Container:Docker 容器,是镜像的运行实例,是运行在宿主机上的沙盒进程。
  • Registry:Docker 仓库,用于存放镜像,官方仓库为 Docker Hubopen in new window

使用 Docker 最简单的方式就是从仓库下载镜像到本地主机,然后运行镜像生成容器,就可以访问该容器中的服务了。

部署

Docker 支持多种操作系统,这里以最常用的 CentOS 为例。

准备

操作系统

安装 CentOSopen in new window 操作系统,版本需要为 7 及以上。

[root@stone ~]# cat /etc/centos-release
CentOS Linux release 7.9.2009 (Core)

卸载旧版本

[root@stone ~]# yum remove docker*

安装

配置 YUM

需要先安装 yum-utils,才能使用 yum-config-manager 命令增加 Docker 的 YUM 仓库:

[root@stone ~]# yum install -y yum-utils
[root@stone ~]# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

如果不能访问 Docker 官网,使用国内镜像源:

[root@stone ~]# yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

安装 Docker

安装最新版:

[root@stone ~]# yum install docker-ce

安装指定版本:

[root@stone ~]# yum list docker-ce --showduplicates | sort -r
[root@stone ~]# yum install docker-ce-<VERSION_STRING>

例如:

[root@stone ~]# yum -y install docker-ce-18.09.9

启动并配置开机启动:

[root@stone ~]# systemctl start docker.service 
[root@stone ~]# systemctl enable docker.service 
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.
[root@stone ~]# systemctl status docker.service 
● docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
   Active: active (running) since Fri 2023-08-11 09:07:57 CST; 52s ago
     Docs: https://docs.docker.com
 Main PID: 1402 (dockerd)
   CGroup: /system.slice/docker.service
           └─1402 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

Aug 11 09:07:56 stone systemd[1]: Starting Docker Application Container Engine...
Aug 11 09:07:56 stone dockerd[1402]: time="2023-08-11T09:07:56.885548735+08:00" level=info msg="Starting up"
Aug 11 09:07:56 stone dockerd[1402]: time="2023-08-11T09:07:56.931113815+08:00" level=info msg="[graphdriver] using prior stora...erlay2"
Aug 11 09:07:56 stone dockerd[1402]: time="2023-08-11T09:07:56.933413646+08:00" level=info msg="Loading containers: start."
Aug 11 09:07:57 stone dockerd[1402]: time="2023-08-11T09:07:57.369310452+08:00" level=info msg="Default bridge (docker0) is ass...ddress"
Aug 11 09:07:57 stone dockerd[1402]: time="2023-08-11T09:07:57.459677858+08:00" level=info msg="Loading containers: done."
Aug 11 09:07:57 stone dockerd[1402]: time="2023-08-11T09:07:57.605236680+08:00" level=info msg="Docker daemon" commit=a61e2b4 g...=24.0.5
Aug 11 09:07:57 stone dockerd[1402]: time="2023-08-11T09:07:57.605491180+08:00" level=info msg="Daemon has completed initialization"
Aug 11 09:07:57 stone dockerd[1402]: time="2023-08-11T09:07:57.663001167+08:00" level=info msg="API listen on /run/docker.sock"
Aug 11 09:07:57 stone systemd[1]: Started Docker Application Container Engine.
Hint: Some lines were ellipsized, use -l to show in full.

查看版本及信息:

[root@stone ~]# docker version
Client: Docker Engine - Community
 Version:           24.0.5
 API version:       1.43
 Go version:        go1.20.6
 Git commit:        ced0996
 Built:             Fri Jul 21 20:39:02 2023
 OS/Arch:           linux/amd64
 Context:           default

Server: Docker Engine - Community
 Engine:
  Version:          24.0.5
  API version:      1.43 (minimum version 1.12)
  Go version:       go1.20.6
  Git commit:       a61e2b4
  Built:            Fri Jul 21 20:38:05 2023
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.6.22
  GitCommit:        8165feabfdfe38c65b599c4993d227328c231fca
 runc:
  Version:          1.1.8
  GitCommit:        v1.1.8-0-g82f18fe
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0
  
[root@stone ~]# docker info
Client: Docker Engine - Community
 Version:    24.0.5
 Context:    default
 Debug Mode: false
 Plugins:
  buildx: Docker Buildx (Docker Inc.)
    Version:  v0.11.2
    Path:     /usr/libexec/docker/cli-plugins/docker-buildx
  compose: Docker Compose (Docker Inc.)
    Version:  v2.20.2
    Path:     /usr/libexec/docker/cli-plugins/docker-compose

Server:
 Containers: 0
  Running: 0
  Paused: 0
  Stopped: 0
 Images: 0
 Server Version: 24.0.5
 Storage Driver: overlay2
  Backing Filesystem: xfs
  Supports d_type: true
  Using metacopy: false
  Native Overlay Diff: true
  userxattr: false
 Logging Driver: json-file
 Cgroup Driver: cgroupfs
 Cgroup Version: 1
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: inactive
 Runtimes: runc io.containerd.runc.v2
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 8165feabfdfe38c65b599c4993d227328c231fca
 runc version: v1.1.8-0-g82f18fe
 init version: de40ad0
 Security Options:
  seccomp
   Profile: builtin
 Kernel Version: 3.10.0-1127.el7.x86_64
 Operating System: CentOS Linux 7 (Core)
 OSType: linux
 Architecture: x86_64
 CPUs: 2
 Total Memory: 3.84GiB
 Name: stone
 ID: b824e009-ba55-4cd5-b413-316128dc36be
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 Experimental: false
 Insecure Registries:
  127.0.0.0/8
 Live Restore Enabled: false

验证:

[root@stone ~]# docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
719385e32844: Pull complete 
Digest: sha256:dcba6daec718f547568c562956fa47e1b03673dd010fe6ee58ca806767031d1c
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

配置 Docker

Docker 默认从 Docker Hub 仓库拉取镜像,可以在配置文件中设置国内镜像仓库,更快获取镜像。

创建配置文件:

[root@stone ~]# mkdir /etc/docker
[root@stone ~]# vi /etc/docker/daemon.json
{
"live-restore": true,
"registry-mirrors": ["https://registry.cn-hangzhou.aliyuncs.com"]
}

其中:

  • live-restore:在 Docker 服务停止运行时,保持容器继续运行
  • registry-mirrors:指定镜像地址
  • data-root:在 19 版本之前为 graph,指定 Docker 数据保存位置,默认为 /var/lib/docker

重启 Docker 服务:

[root@stone ~]# systemctl restart docker.service
[root@stone ~]# docker info
......
 Registry Mirrors:
  https://registry.cn-hangzhou.aliyuncs.com/

下面介绍如何管理镜像,容器和仓库。

image-20230811143652785

镜像

镜像可以分为仓库镜像和本地镜像。

与镜像相关的命令有:

[root@stone ~]# docker image --help

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        Download an image from a registry
  push        Upload an image 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 命令搜索仓库中的镜像。

[root@stone ~]# docker search nginx
NAME                                              DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
nginx                                             Official build of Nginx.                        18860     [OK]       
unit                                              Official build of NGINX Unit: Universal Web …   8         [OK]       
nginxinc/nginx-unprivileged                       Unprivileged NGINX Dockerfiles                  108                  
nginx/nginx-ingress                               NGINX and  NGINX Plus Ingress Controllers fo…   75                   
nginx/nginx-prometheus-exporter                   NGINX Prometheus Exporter for NGINX and NGIN…   33                   
nginx/unit                                        NGINX Unit is a dynamic web and application …   64                   
......

其中:

  • NAME:镜像名称
  • DESCRIPTION:描述
  • STARS:流行度
  • OFFICIAL:是否为官方仓库
  • AUTOMATED:是否是自动构建的镜像

下载镜像

使用 docker pull 或者 docker image pull 命令下载仓库中的镜像。

语法:

docker pull [OPTIONS] NAME[:TAG|@DIGEST]

下载最新版本镜像:

[root@stone ~]# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
648e0aadf75a: Pull complete 
262696647b70: Pull complete 
e66d0270d23f: Pull complete 
55ac49bd649c: Pull complete 
cbf42f5a00d2: Pull complete 
8015f365966b: Pull complete 
4cadff8bc2aa: Pull complete 
Digest: sha256:67f9a4f10d147a6e04629340e6493c9703300ca23a2f7f3aa56fe615d75d31ca
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest

下载指定版本镜像:

[root@stone ~]# docker pull nginx:1.18
1.18: Pulling from library/nginx
f7ec5a41d630: Pull complete 
0b20d28b5eb3: Pull complete 
1576642c9776: Pull complete 
c12a848bad84: Pull complete 
03f221d9cf00: Pull complete 
Digest: sha256:e90ac5331fe095cea01b121a3627174b2e33e06e83720e9a934c7b8ccc9c55a0
Status: Downloaded newer image for nginx:1.18
docker.io/library/nginx:1.18

使用以下命令获取镜像的 TAG(版本):

[root@stone ~]# wget -q https://registry.hub.docker.com/v1/repositories/nginx/tags -O -  | sed -e 's/[][]//g' -e 's/"//g' -e 's/ //g' | tr '}' '\n'  | awk -F: '{print $3}'

查看镜像

使用 docker images 或者 docker image ls 命令查看本地镜像。

语法:

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

常用选项有:

  • -a:显示所有镜像
  • -q:只显示镜像 ID

查看所有镜像:

[root@stone ~]# docker images -a
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
nginx         latest    89da1fb6dcb9   2 weeks ago    187MB
hello-world   latest    9c7a54a9a43c   3 months ago   13.3kB
nginx         1.18      c2c45d506085   2 years ago    133MB

查看指定镜像:

[root@stone ~]# docker images nginx
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
nginx        latest    89da1fb6dcb9   2 weeks ago   187MB
nginx        1.18      c2c45d506085   2 years ago   133MB

其中:

  • REPOSITORY:在仓库中镜像的名称
  • TAG:镜像标签,也就是镜像版本,latest 表示最新版
  • IMAGE ID:镜像唯一 ID
  • CREATED:镜像创建时间
  • SIZE:镜像大小

删除镜像

使用 docker rmi 或者 docker image rm 命令删除本地镜像。

语法:

docker rmi [OPTIONS] IMAGE [IMAGE...]

常用选项有:

  • -f:强制删除

删除指定镜像:

[root@stone ~]# docker rmi -f hello-world
Untagged: hello-world:latest
Untagged: hello-world@sha256:dcba6daec718f547568c562956fa47e1b03673dd010fe6ee58ca806767031d1c
Deleted: sha256:9c7a54a9a43cca047013b82af109fe963fde787f63f9e016fdc3384500c2823d

删除所有镜像:

[root@stone ~]# docker rmi -f $(docker images -q)

清理镜像

使用 docker image prune 命令清理 “dangling” 镜像,也就是未被标签(tag)标记和未被容器使用的镜像。

语法:

docker image prune [OPTIONS]

常用选项有:

  • -a:删除没有被容器使用的所有镜像

  • -f:无需确认提示,直接清理

  • --filter:使用 "key=value" 格式来限制清理哪些镜像,例如 "until=240h"

清理无容器使用的镜像:

[root@stone ~]# docker image prune -a

清理 10 天前创建,现在没有被容器使用的镜像:

[root@stone ~]# docker image prune -a -f --filter "until=240h"

保存镜像

使用 docker save 或者 docker image save 命令保存镜像。

语法:

docker save [OPTIONS] IMAGE [IMAGE...]

常用选项有:

  • -o:指定保存文件名,替代标准输出

保存镜像:

[root@stone ~]# docker save -o nginx.tar nginx

或者:

[root@stone ~]# docker save nginx > nginx.tar

加载镜像

使用 docker load 或者 docker image load 命令加载 docker save 保存的镜像。

常用选项有:

  • -i:替代标准输入,指定要加载的镜像文件名

加载保存的镜像:

[root@stone ~]# docker load -i nginx.tar

或者:

[root@stone ~]# docker load < nginx.tar

打标镜像

使用 docker tag 或者 docker image tag 命令给镜像打标签。

语法:

docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]

完整的镜像名称格式为:[HOST[:PORT_NUMBER]/]PATH

  • HOST:仓库主机名
  • PORT_NUMBER:仓库端口
  • PATH:仓库路径,对于 Docker Hubopen in new window,其 PATH 格式为:[NAMESPACE/]REPOSITORY
    • NAMESPACE:用户名
    • REPOSITORY:仓库名称

给指定镜像打标签:

[root@stone ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
nginx        latest    89da1fb6dcb9   2 weeks ago   187MB
[root@stone ~]# docker tag nginx:latest stonebox/nginx:1.24
[root@stone ~]# docker images
REPOSITORY       TAG       IMAGE ID       CREATED        SIZE
stonebox/nginx   1.24      89da1fb6dcb9   2 weeks ago    187MB
nginx            latest    89da1fb6dcb9   2 weeks ago    187MB

构建镜像

使用 docker build 命令构建镜像。

语法:

docker buildx build [OPTIONS] PATH | URL | -

常用选项有:

  • -f:指定 Dockerfile,默认使用当前目录下的 Dockerfile
  • -t:指定标签

构建镜像需要先创建 Dockerfileopen in new window,常用的指令如下:

指令描述
FROM <image>指定基础镜像
LABEL <key>=<value> ...指定元数据信息
ENV <key>=<value> ...指定环境变量
WORKDIR <directory>指定后续命令的工作目录
RUN <command>在构建镜像时执行的命令
ADD <src> <dest>复制文件到镜像,支持 URL 和压缩包
COPY <src> <dest>复制文件到镜像,常用
EXPOSE <port> ...指定暴露的端口
CMD <command>在容器启动时执行的命令

创建所需文件及 Dockerfile:

[root@stone ~]# vi hello.py
from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

[root@stone ~]# vi Dockerfile
# syntax=docker/dockerfile:1
FROM ubuntu:22.04

# install app dependencies
RUN apt-get update && apt-get install -y python3 python3-pip
RUN pip install flask==2.1.*

# install app
COPY hello.py /

# final configuration
ENV FLASK_APP=hello
EXPOSE 8000
CMD flask run --host 0.0.0.0 --port 8000

构建镜像:

[root@stone ~]# docker build -t test:latest .
[+] Building 223.0s (11/11) FINISHED                                                                                             docker:default
 => [internal] load build definition from Dockerfile                                                                                       0.0s
 => => transferring dockerfile: 331B                                                                                                       0.0s
 => [internal] load .dockerignore                                                                                                          0.0s
 => => transferring context: 2B                                                                                                            0.0s
 => resolve image config for docker.io/docker/dockerfile:1                                                                                 2.4s
 => CACHED docker-image://docker.io/docker/dockerfile:1@sha256:ac85f380a63b13dfcefa89046420e1781752bab202122f8f50032edf31be0021            0.0s
 => [internal] load metadata for docker.io/library/ubuntu:22.04                                                                            1.9s
 => [1/4] FROM docker.io/library/ubuntu:22.04@sha256:0bced47fffa3361afa981854fcabcd4577cd43cebbb808cea2b1f33a3dd7f508                     23.9s
 => => resolve docker.io/library/ubuntu:22.04@sha256:0bced47fffa3361afa981854fcabcd4577cd43cebbb808cea2b1f33a3dd7f508                      0.0s
 => => sha256:0bced47fffa3361afa981854fcabcd4577cd43cebbb808cea2b1f33a3dd7f508 1.13kB / 1.13kB                                             0.0s
 => => sha256:b060fffe8e1561c9c3e6dea6db487b900100fc26830b9ea2ec966c151ab4c020 424B / 424B                                                 0.0s
 => => sha256:5a81c4b8502e4979e75bd8f91343b95b0d695ab67f241dbed0d1530a35bde1eb 2.30kB / 2.30kB                                             0.0s
 => => sha256:3153aa388d026c26a2235e1ed0163e350e451f41a8a313e1804d7e1afb857ab4 29.53MB / 29.53MB                                          21.0s
 => => extracting sha256:3153aa388d026c26a2235e1ed0163e350e451f41a8a313e1804d7e1afb857ab4                                                  2.8s
 => [internal] load build context                                                                                                          0.0s
 => => transferring context: 137B                                                                                                          0.0s
 => [2/4] RUN apt-get update && apt-get install -y python3 python3-pip                                                                   178.1s
 => [3/4] RUN pip install flask==2.1.*                                                                                                    13.5s
 => [4/4] COPY hello.py /                                                                                                                  0.0s 
 => exporting to image                                                                                                                     2.8s 
 => => exporting layers                                                                                                                    2.8s 
 => => writing image sha256:65399d462a6301160310775d4518af0cedf2883c423e5b3119248e4839650006                                               0.0s 
 => => naming to docker.io/library/test:latest

查看镜像:

[root@stone ~]# docker images test
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
test         latest    65399d462a63   43 seconds ago   476MB

镜像信息

使用 docker image inspect 命令查看镜像详细信息。

语法:

docker image inspect [OPTIONS] IMAGE [IMAGE...]

查看前面构建的 TEST 镜像信息:

[root@stone ~]# docker image inspect test
[
    {
        "Id": "sha256:65399d462a6301160310775d4518af0cedf2883c423e5b3119248e4839650006",
        "RepoTags": [
            "test:latest"
        ],
        "RepoDigests": [],
        "Parent": "",
        "Comment": "buildkit.dockerfile.v0",
        "Created": "2023-08-14T16:53:10.705962132+08:00",
        "Container": "",
        "ContainerConfig": {
            "Hostname": "",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": null,
            "Cmd": null,
            "Image": "",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": null
        },
        "DockerVersion": "",
        "Author": "",
        "Config": {
            "Hostname": "",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "8000/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "FLASK_APP=hello"
            ],
            "Cmd": [
                "/bin/sh",
                "-c",
                "flask run --host 0.0.0.0 --port 8000"
            ],
            "ArgsEscaped": true,
            "Image": "",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {
                "org.opencontainers.image.ref.name": "ubuntu",
                "org.opencontainers.image.version": "22.04"
            }
        },
        "Architecture": "amd64",
        "Os": "linux",
        "Size": 476017494,
        "VirtualSize": 476017494,
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/nqzj2u64qq5711iqrsg7p0f8a/diff:/var/lib/docker/overlay2/zdx6812r4hbe26nhf08a1n528/diff:/var/lib/docker/overlay2/8d9c61e9d6fe0dc9183fc86e75af935fae9c21bc59dc473702084e487877ef3a/diff",
                "MergedDir": "/var/lib/docker/overlay2/ndh00dhgjdwkuznlowyny1g3d/merged",
                "UpperDir": "/var/lib/docker/overlay2/ndh00dhgjdwkuznlowyny1g3d/diff",
                "WorkDir": "/var/lib/docker/overlay2/ndh00dhgjdwkuznlowyny1g3d/work"
            },
            "Name": "overlay2"
        },
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:59c56aee1fb4dbaeb334aef06088b49902105d1ea0c15a9e5a2a9ce560fa4c5d",
                "sha256:66a0a7fac9a2f4ae9c0b9d2382ec6e6dee846174413bdfdb1dbefd43c9cfd540",
                "sha256:2218c45d7d58ae63c0c037f157515e8804a2e87c4fa8633f5957e1ac4d627ea3",
                "sha256:d5c54e56156af59d05e3d6ffe1cb24167e2cca91e4dcd2e2217927673a3b4ee9"
            ]
        },
        "Metadata": {
            "LastTagTime": "2023-08-14T16:53:13.465552096+08:00"
        }
    }
]

容器

容器是镜像的运行实例。

与容器相关的命令有:

[root@stone ~]# docker container --help

Usage:  docker container COMMAND

Manage containers

Commands:
  attach      Attach local standard input, output, and error streams to a running container
  commit      Create a new image from a container's changes
  cp          Copy files/folders between a container and the local filesystem
  create      Create a new container
  diff        Inspect changes to files or directories on a container's filesystem
  exec        Execute a command in a running container
  export      Export a container's filesystem as a tar archive
  inspect     Display detailed information on one or more containers
  kill        Kill one or more running containers
  logs        Fetch the logs of a container
  ls          List containers
  pause       Pause all processes within one or more containers
  port        List port mappings or a specific mapping for the container
  prune       Remove all stopped containers
  rename      Rename a container
  restart     Restart one or more containers
  rm          Remove one or more containers
  run         Create and run a new container from an image
  start       Start one or more stopped containers
  stats       Display a live stream of container(s) resource usage statistics
  stop        Stop one or more running containers
  top         Display the running processes of a container
  unpause     Unpause all processes within one or more containers
  update      Update configuration of one or more containers
  wait        Block until one or more containers stop, then print their exit codes

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

运行容器

使用 docker run 或者 docker container run 命令从镜像创建并运行容器。

语法:

docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

常用选项有:

  • -d:后台运行并打印容器 ID
  • -e:设置容器的环境变量
  • -i:打开标准输入(STDIN)
  • -t:分配 TTY 以支持终端登录
  • -p:端口映射,格式为:宿主机端口:容器端口
  • -v:文件映射,格式为:宿主机文件:容器文件
  • -h:容器主机名
  • -m:内存限制
  • --cpus:CPU 数量
  • --name:容器名称
  • --privileged:授予容器更多权限
  • --rm:容器终止运行后自动删除容器文件
  • --restart:容器停止后的重启策略,包括:
    • no:容器退出时不重启,默认
    • on-failure:容器故障退出(返回值非零)时重启
    • always:容器退出时总是重启

创建并运行 NGINX 容器:

[root@stone ~]# docker run -itd -p 8080:80 --name nginx nginx
6c9b4365097635a66da42805cce8b7f7db203d8eb883dd693dcc9580818d1e6f

查看容器

使用 docker ps 或者 docker container ps 或者 docker container ls 命令查看容器。

语法:

docker ps [OPTIONS]

常用选项有:

  • -a:显示所有容器,默认只显示正在运行的容器
  • -l:显示最近创建的容器
  • -q:只显示容器 ID
  • -s:显示总文件大小
  • --no-trunc:不截断输出,完全显示各个字段值

查看所有容器:

[root@stone ~]# docker ps -a
CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS                   PORTS                                   NAMES
6c9b43650976   nginx          "/docker-entrypoint.…"   7 minutes ago   Up 7 minutes             0.0.0.0:8080->80/tcp, :::8080->80/tcp   nginx
c1a00f5d404f   9c7a54a9a43c   "/hello"                 7 hours ago     Exited (0) 7 hours ago                                           awesome_roentgen

[root@stone ~]# docker ps -qa
6c9b43650976
c1a00f5d404f

其中:

  • CONTAINER ID:容器 ID
  • IMAGE:镜像名称
  • COMMAND:启动容器时运行的命令
  • CREATED:容器的创建时间
  • STATUS:容器的运行状态
  • PORTS:端口映射
  • NAMES:容器名称

查看端口

使用 docker port 或者 docker container port 命令查看容器端口映射。

语法:

docker port CONTAINER [PRIVATE_PORT[/PROTO]]

查看 NGINX 容器端口映射:

[root@stone ~]# docker port nginx
80/tcp -> 0.0.0.0:8080
80/tcp -> [::]:8080

查看日志

使用 docker logs 或者 docker container logs 命令查看容器日志。

语法:

docker logs [OPTIONS] CONTAINER

常用选项有:

  • -f:保存输出
  • -n:指定行数,默认显示所有
  • -t:显示时间戳
  • --since:指定开始时间
  • --until:指定结束时间

查看 NGINX 容器日志:

[root@stone ~]# docker logs -f -n 10 nginx
2023/08/14 01:22:54 [notice] 1#1: OS: Linux 3.10.0-1127.el7.x86_64
2023/08/14 01:22:54 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2023/08/14 01:22:54 [notice] 1#1: start worker processes
2023/08/14 01:22:54 [notice] 1#1: start worker process 29
2023/08/14 01:22:54 [notice] 1#1: start worker process 30
2023/08/14 01:56:37 [error] 29#29: *2 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 192.168.44.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "192.168.44.135:8080", referrer: "http://192.168.44.135:8080/"
192.168.44.1 - - [14/Aug/2023:01:56:37 +0000] "GET /favicon.ico HTTP/1.1" 404 555 "http://192.168.44.135:8080/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.1901.200" "-"
192.168.44.1 - - [14/Aug/2023:01:57:47 +0000] "GET / HTTP/1.1" 200 18 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.1901.200" "-"
192.168.44.1 - - [14/Aug/2023:03:09:03 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.1901.200" "-"
192.168.44.1 - - [14/Aug/2023:06:07:59 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.1901.200" "-"

查看进程

使用 docker top 或者 docker container top 命令查看容器运行的进程。

语法:

docker top CONTAINER [ps OPTIONS]

查看 NGINX 容器进程:

[root@stone ~]# docker top nginx
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                1808                1787                0                   09:22               pts/0               00:00:00            nginx: master process nginx -g daemon off;
101                 1852                1808                0                   09:22               pts/0               00:00:00            nginx: worker process
101                 1853                1808                0                   09:22               pts/0               00:00:00            nginx: worker process
root                3208                1787                0                   13:57               pts/1               00:00:00            /bin/bash

停止容器

使用 docker stop 或者 docker container stop 命令停止容器。

先发送信号 SIGTERM 给容器主进程,宽限期后还没有停止,再发送信号 SIGKILL 给容器主进程。

语法:

docker stop [OPTIONS] CONTAINER [CONTAINER...]

停止 NGINX 容器:

[root@stone ~]# docker stop nginx
nginx

[root@stone ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

杀掉容器

使用 docker kill 或者 docker container kill 命令杀掉容器。

默认发送信号 SIGKILL 给容器主进程。

语法:

docker kill [OPTIONS] CONTAINER [CONTAINER...]

常用选项有:

-s:指定发送到容器的信号,默认为 SIGKILL,具体信号参考 signal(7)open in new window

杀掉 NGINX 容器:

[root@stone ~]# docker kill nginx
nginx

启动容器

使用 docker start 或者 docker container start 命令启动容器。

语法:

docker start [OPTIONS] CONTAINER [CONTAINER...]

启动前面停止的 NGINX 容器:

[root@stone ~]# docker start nginx
nginx

重启容器

使用 docker restart 或者 docker container restart 命令重启容器。

语法:

docker restart [OPTIONS] CONTAINER [CONTAINER...]

重启 NGINX 容器:

[root@stone ~]# docker restart nginx
nginx

暂停进程

使用 docker pause 或者 docker container pause 命令暂停容器所有进程。

语法:

docker pause CONTAINER [CONTAINER...]

暂停 NGINX 容器所有进程:

[root@stone ~]# docker pause nginx
nginx

恢复进程

使用 docker unpause 或者 docker container unpause 命令恢复暂停的进程。

语法:

docker unpause CONTAINER [CONTAINER...]

恢复 NGINX 容器暂停的进程:

[root@stone ~]# docker unpause nginx
nginx

进入容器

使用 docker exec 或者 docker container exec 命令在运行的容器中执行命令。

语法:

docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

常用选项有:

  • -i:打开标准输入(STDIN)
  • -t:分配 TTY 以支持终端登录

向运行的 NGINX 容器发送一条命令:

[root@stone ~]# docker exec -it nginx cat /etc/hosts
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2      6c9b43650976

进入 NGINX 容器后再执行命令:

[root@stone ~]# docker exec -it nginx /bin/bash
root@6c9b43650976:/# hostname
6c9b43650976
root@8061357ee01a:/# echo "Hello StoneCoding" > /usr/share/nginx/html/index.html

导出容器

使用 docker export 或者 docker container export 命令导出容器为镜像。用于制作基础镜像。

语法:

docker container export [OPTIONS] CONTAINER

常用选项有:

  • -o:指定保存文件名,替代标准输出

导出 NGINX 容器:

[root@stone ~]# docker export -o nginx_v1.tar nginx

或者:

[root@stone ~]# docker export nginx > nginx_v1.tar

导入镜像

使用 docker import 或者 docker image import 命令导入 docker export 导出的镜像。

语法:

docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]

导入 nginx_v1.tar

[root@stone ~]# docker import nginx_v1.tar nginx:v1
sha256:ee4bd0f6f24ffb9c6fee136e49f83319e326cc57e9a8f083950a539bff8d9ac6
[root@stone ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
nginx         v1        ee4bd0f6f24f   7 seconds ago   185MB
nginx         latest    89da1fb6dcb9   2 weeks ago     187MB
stone/nginx   1.24      89da1fb6dcb9   2 weeks ago     187MB

运行导入的镜像:

[root@stone ~]# docker run -itd -p 8090:80 --name nginx_v1 nginx:v1 /docker-entrypoint.sh nginx -g 'daemon off;'
8a5308e0557045e0152f140c818e797abf4dbc8a7d5438cd4e2d5b2eed526740
[root@stone ~]# docker ps
CONTAINER ID   IMAGE      COMMAND                  CREATED         STATUS         PORTS                                   NAMES
8a5308e05570   nginx:v1   "/docker-entrypoint.…"   5 seconds ago   Up 4 seconds   0.0.0.0:8090->80/tcp, :::8090->80/tcp   nginx_v1
8061357ee01a   nginx      "/docker-entrypoint.…"   2 hours ago     Up 2 hours     0.0.0.0:8080->80/tcp, :::8080->80/tcp   nginx

注意:

运行导入的镜像时,需要指定命令,否则会报如下错误:

docker: Error response from daemon: No command specified.

创建镜像

使用 docker commit 或者 docker container commit 命令从容器直接创建镜像。

语法:

docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

创建 NGINX 镜像:

[root@stone ~]# docker commit nginx nginx:v2
sha256:febcbe74ab28eaae1a885f6d5d5e0b5b930630ef0bb677ad398d1862968b3980
[root@stone ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
nginx         v2        febcbe74ab28   5 seconds ago   187MB
nginx         v1        ee4bd0f6f24f   3 hours ago     185MB
nginx         latest    89da1fb6dcb9   2 weeks ago     187MB
stone/nginx   1.24      89da1fb6dcb9   2 weeks ago     187MB

拷贝文件

使用 docker cp 或者 docker container cp 命令在容器和宿主机之间拷贝文件。

语法:

docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH

拷贝容器文件到宿主机:

[root@stone ~]# docker cp nginx:/usr/share/nginx/html/index.html /root
                                               Successfully copied 2.05kB to /root

拷贝宿主机文件到容器:

[root@stone ~]# docker cp /root/index.html nginx:/
                                             Successfully copied 2.05kB to nginx:/

创建容器

使用 docker create 或者 docker container create 命令创建容器。

语法:

docker create [OPTIONS] IMAGE [COMMAND] [ARG...]

常用选项有:

  • -e:设置容器的环境变量
  • -i:打开标准输入(STDIN)
  • -t:分配 TTY 以支持终端登录
  • -p:端口映射,格式为:宿主机端口:容器端口
  • -v:文件映射,格式为:宿主机文件:容器文件
  • -h:容器主机名
  • -m:内存限制
  • --cpus:CPU 数量
  • --name:容器名称
  • --privileged:授予容器更多权限
  • --rm:容器终止运行后自动删除容器文件
  • --restart:容器停止后的重启策略,包括:
    • no:容器退出时不重启,默认
    • on-failure:容器故障退出(返回值非零)时重启
    • always:容器退出时总是重启

创建 NGINX 容器:

[root@stone ~]# docker create -it -p 8180:80 --name nginx_v2 nginx
aa8adcb230e2ce48d50127bc0b5b1ef9040223d0f2524f4893cdfc52af510b51
[root@stone ~]# docker ps -a
CONTAINER ID   IMAGE      COMMAND                  CREATED          STATUS       PORTS                                   NAMES
aa8adcb230e2   nginx      "/docker-entrypoint.…"   14 seconds ago   Created                                              nginx_v2
8a5308e05570   nginx:v1   "/docker-entrypoint.…"   4 hours ago      Up 4 hours   0.0.0.0:8090->80/tcp, :::8090->80/tcp   nginx_v1
8061357ee01a   nginx      "/docker-entrypoint.…"   6 hours ago      Up 6 hours   0.0.0.0:8080->80/tcp, :::8080->80/tcp   nginx

容器信息

使用 docker container inspect 命令查看容器详细信息。

语法:

docker container inspect [OPTIONS] CONTAINER [CONTAINER...]

查看 NGINX 容器详细信息:

[root@stone ~]# docker container inspect nginx
[
    {
        "Id": "8061357ee01a2ab9b500f6efa2d8e4dfabed142155e0e4568b267d2d6703fe53",
        "Created": "2023-08-14T01:22:53.394079106Z",
        "Path": "/docker-entrypoint.sh",
        "Args": [
            "nginx",
            "-g",
            "daemon off;"
        ],
        "State": {
            "Status": "exited",
            "Running": false,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 0,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2023-08-14T01:22:54.096108855Z",
            "FinishedAt": "2023-08-14T09:00:33.10211215Z"
        },
        "Image": "sha256:89da1fb6dcb964dd35c3f41b7b93ffc35eaf20bc61f2e1335fea710a18424287",
        "ResolvConfPath": "/var/lib/docker/containers/8061357ee01a2ab9b500f6efa2d8e4dfabed142155e0e4568b267d2d6703fe53/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/8061357ee01a2ab9b500f6efa2d8e4dfabed142155e0e4568b267d2d6703fe53/hostname",
        "HostsPath": "/var/lib/docker/containers/8061357ee01a2ab9b500f6efa2d8e4dfabed142155e0e4568b267d2d6703fe53/hosts",
        "LogPath": "/var/lib/docker/containers/8061357ee01a2ab9b500f6efa2d8e4dfabed142155e0e4568b267d2d6703fe53/8061357ee01a2ab9b500f6efa2d8e4dfabed142155e0e4568b267d2d6703fe53-json.log",
        "Name": "/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": "8080"
                    }
                ]
            },
            "RestartPolicy": {
                "Name": "no",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "ConsoleSize": [
                45,
                138
            ],
            "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",
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": [],
            "BlkioDeviceReadBps": [],
            "BlkioDeviceWriteBps": [],
            "BlkioDeviceReadIOps": [],
            "BlkioDeviceWriteIOps": [],
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": [],
            "DeviceCgroupRules": null,
            "DeviceRequests": null,
            "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/f7a837870b97fcab878ae8366bcf750b00bcf55c4be07ec19f7f1a507f5a3b4e-init/diff:/var/lib/docker/overlay2/7184b006e20471ad0876d8292da8fed74c5fd0f9a586ee210229b3a3a9a97f4f/diff:/var/lib/docker/overlay2/a9a133c99c702c3668afb7379d90f0ffed2a0cef7172facec6650502fa42c106/diff:/var/lib/docker/overlay2/1c08c28e7252fcd425f7e9e7a31d543d4102a65902fa5af0cb71826f1847ece0/diff:/var/lib/docker/overlay2/39c11aea909cb482a0fa64be173595012e86056d29f353bb26e91af26195c334/diff:/var/lib/docker/overlay2/28a4e649419649849f81b289e5c155a3eb2adc8811ab61b9b48067fcf6fc635e/diff:/var/lib/docker/overlay2/56c094dca17d5bdc5a5250e04463180a774115ea2bcfce20010940f8f475f644/diff:/var/lib/docker/overlay2/894fc05bad847231508dd40c6b1c83a15c7134c5354e440099a34e3a6672d249/diff",
                "MergedDir": "/var/lib/docker/overlay2/f7a837870b97fcab878ae8366bcf750b00bcf55c4be07ec19f7f1a507f5a3b4e/merged",
                "UpperDir": "/var/lib/docker/overlay2/f7a837870b97fcab878ae8366bcf750b00bcf55c4be07ec19f7f1a507f5a3b4e/diff",
                "WorkDir": "/var/lib/docker/overlay2/f7a837870b97fcab878ae8366bcf750b00bcf55c4be07ec19f7f1a507f5a3b4e/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [],
        "Config": {
            "Hostname": "8061357ee01a",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "80/tcp": {}
            },
            "Tty": true,
            "OpenStdin": true,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "NGINX_VERSION=1.25.1",
                "NJS_VERSION=0.7.12",
                "PKG_RELEASE=1~bookworm"
            ],
            "Cmd": [
                "nginx",
                "-g",
                "daemon off;"
            ],
            "Image": "nginx",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": [
                "/docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": {
                "maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>"
            },
            "StopSignal": "SIGQUIT"
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "4e66635eec8100f21e345a2eb07b5fe75901763f2f6a0da832d111d6dd396ec0",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {},
            "SandboxKey": "/var/run/docker/netns/4e66635eec81",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "",
            "Gateway": "",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "",
            "IPPrefixLen": 0,
            "IPv6Gateway": "",
            "MacAddress": "",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "d28006420a4b9b3c892362a71ea1576b65f705c71a89731bd1148d85d7847e01",
                    "EndpointID": "",
                    "Gateway": "",
                    "IPAddress": "",
                    "IPPrefixLen": 0,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "",
                    "DriverOpts": null
                }
            }
        }
    }
]

删除容器

使用 docker rm 或者 docker container rm 命令删除容器。

语法:

docker rm [OPTIONS] CONTAINER [CONTAINER...]

常用选项有:

  • -f:强制删除运行的容器,发送信号 SIGKILL
  • -v:删除宿主机上映射的文件

删除 NGINX 容器:

[root@stone ~]# docker ps -a
CONTAINER ID   IMAGE          COMMAND                  CREATED             STATUS                        PORTS     NAMES
6c9b43650976   nginx          "/docker-entrypoint.…"   About an hour ago   Exited (137) 18 seconds ago             nginx
c1a00f5d404f   9c7a54a9a43c   "/hello"                 8 hours ago         Exited (0) 8 hours ago                  awesome_roentgen
[root@stone ~]# docker rm nginx
nginx
[root@stone ~]# docker rm -f c1a00f5d404f
c1a00f5d404f
[root@stone ~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

清理容器

使用 docker container prune 命令删除所有停止的容器。停止容器后不会自动删除这个容器,除非在启动容器的时候指定了 –rm 标志。

语法:

docker container prune [OPTIONS]

常用选项有:

  • -f:无需确认提示,直接删除
  • --filter:使用 "key=value" 格式来限制清理哪些容器,例如 "until=240h"

删除所有停止的容器:

[root@stone ~]# docker container prune

删除 10 天前创建且已停止的容器:

[root@stone ~]# docker container prune -f --filter "until=240h"

仓库

仓库用于存放镜像,包括官方仓库 Docker Hubopen in new window 和私有仓库 Harboropen in new window

登录仓库

使用 docker login 命令登录仓库。

语法:

docker login [OPTIONS] [SERVER]

如果没有指定 SERVER,则登录到 Docker Hubopen in new window,需要先在 Docker Hubopen in new window 进行注册。

常用选项有:

  • -u:指定用户名
  • -p:指定密码

登录 Docker Hubopen in new window

[root@stone ~]# docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: stonebox
Password: 
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

上传镜像

使用 docker push 或者 docker image push 命令上传镜像到仓库。

语法:

docker push [OPTIONS] NAME[:TAG]

常用选项有:

  • -a:上传镜像的所有版本

上传 NGINX 镜像:

[root@stone ~]# docker push stonebox/nginx:1.24
The push refers to repository [docker.io/stonebox/nginx]
922d16116201: Pushed 
abc3beec4b30: Pushed 
c88d3a8ff009: Pushed 
8aedfcd777c7: Pushed 
4deafab383fa: Pushed 
24ee1d7d6a62: Pushed 
c6e34807c2d5: Pushed 
1.24: digest: sha256:73e957703f1266530db0aeac1fd6a3f87c1e59943f4c13eb340bb8521c6041d7 size: 1778

登出仓库

使用 docker logout 命令登出仓库。

语法:

docker logout [SERVER]

如果没有指定 SERVER,则登出 Docker Hubopen in new window

登出 Docker Hubopen in new window

[root@stone ~]# docker logout
Removing login credentials for https://index.docker.io/v1/

私有仓库

这里使用 Harboropen in new window 来部署 Docker 私有仓库。

安装 Docker Compose

Docker Compose 使用 YAML 配置文件编排多个 Docker 容器的运行。Harbor 服务包含多个 Docker 容器,需要先安装 Docker Compose,以便使用其来运行 Harbor。

[root@harbor ~]# hostnamectl set-hostname harbor.stonecoding.net
[root@harbor ~]# vi /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

192.168.44.135   harbor harbor.stonecoding.net
[root@harbor ~]# yum -y install docker-compose
[root@harbor ~]# docker-compose version
docker-compose version 1.18.0, build 8dd22a9
docker-py version: 2.6.1
CPython version: 3.6.8
OpenSSL version: OpenSSL 1.0.2k-fips  26 Jan 2017

安装 Harbor

下载安装包并解压:

[root@harbor ~]# wget https://github.com/goharbor/harbor/releases/download/v2.1.1/harbor-offline-installer-v2.1.1.tgz
[root@harbor ~]# tar -xvzf harbor-offline-installer-v2.1.1.tgz

修改配置文件:

[root@harbor ~]# cd harbor/
[root@harbor harbor]# cp harbor.yml.tmpl harbor.yml
[root@harbor harbor]# vi harbor.yml
hostname: harbor.stonecoding.net

#https:
  # https port for harbor, default is 443
  #port: 443
  # The path of cert and key files for nginx
  #certificate: /your/certificate/path
  #private_key: /your/private/key/path
  
[root@stone harbor]# grep -v ^$ harbor.yml | grep -v ^.*#
hostname: harbor.stonecoding.net
http:
  port: 80
harbor_admin_password: Harbor12345
database:
  password: root123
  max_idle_conns: 50
  max_open_conns: 1000
data_volume: /data
clair:
  updaters_interval: 12
trivy:
  ignore_unfixed: false
  skip_update: false
  insecure: false
jobservice:
  max_job_workers: 10
notification:
  webhook_job_max_retry: 10
chart:
  absolute_url: disabled
log:
  level: info
  local:
    rotate_count: 50
    rotate_size: 200M
    location: /var/log/harbor
_version: 2.0.0
proxy:
  http_proxy:
  https_proxy:
  no_proxy:
  components:
    - core
    - jobservice
    - clair
    - trivy

创建目录并安装:

[root@stone harbor]# mkdir /data
[root@stone harbor]# ./install.sh 
[root@stone harbor]# docker-compose ps
      Name                     Command               State                  Ports                
-------------------------------------------------------------------------------------------------
harbor-core         /harbor/entrypoint.sh            Up                                          
harbor-db           /docker-entrypoint.sh            Up                                          
harbor-jobservice   /harbor/entrypoint.sh            Up                                          
harbor-log          /bin/sh -c /usr/local/bin/ ...   Up      127.0.0.1:1514->10514/tcp           
harbor-portal       nginx -g daemon off;             Up                                          
nginx               nginx -g daemon off;             Up      0.0.0.0:80->8080/tcp,:::80->8080/tcp
redis               redis-server /etc/redis.conf     Up                                          
registry            /home/harbor/entrypoint.sh       Up                                          
registryctl         /home/harbor/start.sh            Up

关闭和启动(需进入目录中):

[root@stone harbor]# docker-compose stop
[root@stone harbor]# docker-compose start

配置 Harbor

根据配置访问登录页面,输入用户名:admin,密码:Harbor12345

image-20230816160238495

登录后,点击 NEW PROJECT 创建项目:

image-20230816161102731

指定 Porject NameappAccess LevelPublic

image-20230816161147723

创建完成后,进入该项目,点击 PUSH COMMAND 可以看到对镜像打标和推送的命令:

image-20230816172000869

点击 Policy 进入策略页面,点击 ADD RULE 配置镜像的删除规则:

image-20230816162008335

保留最近 7 天被拉取过的镜像:

image-20230816162334006

然后点击 Schedule 项的 EDIT

image-20230816162649370

指定调度周期为 Weekly,再点击 SAVE

image-20230816162810545

再次确认:

image-20230816162855453

点击左侧菜单栏中的 Administration 下的 Garbage Collection,进入垃圾清理页面,点击 EDIT

image-20230816163427671

指定调度周期为 Weekly,再点击 SAVE

image-20230816163530203

配置 Docker

调整 Docker 的配置文件,添加 insecure-registries 项,允许不使用证书访问私有仓库:

[root@stone ~]# vi /etc/docker/daemon.json 
{
"insecure-registries": ["harbor.stonecoding.net"],
"live-restore": true,
"registry-mirrors": ["https://registry.cn-hangzhou.aliyuncs.com"]
}

调整后重启 Docker 和 Harbor:

[root@stone ~]# systemctl restart docker.service
[root@harbor ~]# cd harbor/
[root@harbor harbor]# docker-compose stop
[root@harbor harbor]# docker-compose start
[root@harbor harbor]# docker-compose ps
      Name                     Command               State                  Ports                
-------------------------------------------------------------------------------------------------
harbor-core         /harbor/entrypoint.sh            Up                                          
harbor-db           /docker-entrypoint.sh            Up                                          
harbor-jobservice   /harbor/entrypoint.sh            Up                                          
harbor-log          /bin/sh -c /usr/local/bin/ ...   Up      127.0.0.1:1514->10514/tcp           
harbor-portal       nginx -g daemon off;             Up                                          
nginx               nginx -g daemon off;             Up      0.0.0.0:80->8080/tcp,:::80->8080/tcp
redis               redis-server /etc/redis.conf     Up                                          
registry            /home/harbor/entrypoint.sh       Up                                          
registryctl         /home/harbor/start.sh            Up 

登录仓库

登录到私有仓库:

[root@stone ~]# docker login harbor.stonecoding.net
Username: admin
Password: 
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

打标镜像

对镜像打标,指定 Harbor 所在的主机名:

[root@stone ~]# docker tag nginx harbor.stonecoding.net/app/nginx:1.24

上传镜像

将打标的镜像上传到 Harbor 仓库:

[root@harbor ~]# docker push harbor.stonecoding.net/app/nginx:1.24
The push refers to repository [harbor.stonecoding.net/app/nginx]
68e722008ce0: Pushed 
021a192bcc44: Pushed 
103ee56c0db5: Pushed 
5a2a0d1ab8fe: Pushed 
d9979288f618: Pushed 
e17417668755: Pushed 
c6e34807c2d5: Pushed 
1.24: digest: sha256:ac996bb3b9ef06b378de35132e6c53638c433770bb8c64f26b4c8684c738ab60 size: 1778

系统

可以使用 docker system 命令管理 Docker。

相关命令有:

[root@kbs03t1 ~]# docker system --help

Usage:  docker system COMMAND

Manage Docker

Commands:
  df          Show docker disk usage
  events      Get real time events from the server
  info        Display system-wide information
  prune       Remove unused data

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

查看信息

使用 docker system info 查看 Docker 系统信息,与 docker info 命令的输出类似。

[root@linux ~]# systemctl status docker
● docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled)
   Active: inactive (dead)
     Docs: https://docs.docker.com
[root@linux ~]# systemctl start docker
[root@linux ~]# docker system info
Client: Docker Engine - Community
 Version:    24.0.7
 Context:    default
 Debug Mode: false
 Plugins:
  buildx: Docker Buildx (Docker Inc.)
    Version:  v0.11.2
    Path:     /usr/libexec/docker/cli-plugins/docker-buildx
  compose: Docker Compose (Docker Inc.)
    Version:  v2.21.0
    Path:     /usr/libexec/docker/cli-plugins/docker-compose

Server:
 Containers: 0
  Running: 0
  Paused: 0
  Stopped: 0
 Images: 0
 Server Version: 24.0.7
 Storage Driver: overlay2
  Backing Filesystem: xfs
  Supports d_type: true
  Using metacopy: false
  Native Overlay Diff: true
  userxattr: false
 Logging Driver: json-file
 Cgroup Driver: cgroupfs
 Cgroup Version: 1
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: inactive
 Runtimes: runc io.containerd.runc.v2
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 61f9fd88f79f081d64d6fa3bb1a0dc71ec870523
 runc version: v1.1.9-0-gccaecfc
 init version: de40ad0
 Security Options:
  seccomp
   Profile: builtin
 Kernel Version: 3.10.0-1160.el7.x86_64
 Operating System: CentOS Linux 7 (Core)
 OSType: linux
 Architecture: x86_64
 CPUs: 1
 Total Memory: 1.777GiB
 Name: linux
 ID: 908394af-11ae-4d30-9102-b5d326276b35
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 Username: stonebox
 Experimental: false
 Insecure Registries:
  127.0.0.0/8
 Registry Mirrors:
  https://docker.mirrors.sjtug.sjtu.edu.cn/
 Live Restore Enabled: true

查看磁盘

使用 docker system df 查看 Docker 磁盘使用情况。

常用选项有:

  • -v:显示详细信息。
[root@kbs03t1 ~]# docker system df
TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          133       23        15.66GB   13.33GB (85%)
Containers      46        44        17.5GB    7.856kB (0%)
Local Volumes   1         1         0B        0B
Build Cache     0         0         0B        0B

查看事件

使用 docker events 查看 Docker 守护进程中正在进行的活动,只返回最近的 1000 行日志信息。

常用选项有:

  • -f, --filter:指定条件进行过滤

  • --since:显示指定时间后的日志信息

  • --until:显示指定时间前的日志信息

在一个 Shell 中执行:

[root@linux ~]# docker events

在其他 Shell 中执行:

[root@linux ~]# docker run -itd -p 8080:80 --name nginx nginx

就可以在第一个 Shell 中看到日志信息:

[root@linux ~]# docker events
2024-04-03T14:39:13.137109660+08:00 image pull nginx:latest (maintainer=NGINX Docker Maintainers <docker-maint@nginx.com>, name=nginx)
2024-04-03T14:39:13.932935129+08:00 container create a753cc5a4552f5a23a272aaece4482bf640dd67bc65b1a112f438322ab5a863d (image=nginx, maintainer=NGINX Docker Maintainers <docker-maint@nginx.com>, name=nginx)
2024-04-03T14:39:14.012837730+08:00 network connect 000469480cb1c29badf0220d15eff44f271017c62c0ae920f16633aeee9159d5 (container=a753cc5a4552f5a23a272aaece4482bf640dd67bc65b1a112f438322ab5a863d, name=bridge, type=bridge)
2024-04-03T14:39:14.275761580+08:00 container start a753cc5a4552f5a23a272aaece4482bf640dd67bc65b1a112f438322ab5a863d (image=nginx, maintainer=NGINX Docker Maintainers <docker-maint@nginx.com>, name=nginx)

清除数据

使用 docker system prune 清除所有未使用的容器,网络和镜像(包括 “dangling” 及未被使用的),以及卷。

语法:

docker system prune [OPTIONS]

常用选项有:

  • -a, --all:清理所有未被使用的镜像
  • --filter:使用 "key=value" 格式来限制清理哪些数据,例如 "until=240h",1.28 版本之后才有该选项
  • -f, --force:无需确认提示,直接清理
  • --volumes:清理卷

清除数据:

[root@linux ~]# docker system prune -a
WARNING! This will remove:
  - all stopped containers
  - all networks not used by at least one container
  - all images without at least one container associated to them
  - all build cache

Are you sure you want to continue? [y/N] y

这个命令将清理整个系统,并且只会保留真正在使用的镜像,容器,数据卷以及网络,因此需要格外谨慎。比如,建议不要在生产环境中运行该命令,因为一些备用镜像(用于备份,回滚等)有时候需要被用到,如果这些镜像被删除了,则运行容器时需要重新下载。

上次编辑于:
贡献者: stonebox,stone