Docker概览

Docker架构

Docker采用client-server架构,client和daemon间使用REST API进行通讯。client和daemon可以运行在相同或不同的机器。daemon间可以通过Docker API通讯。 Docker Registry存储image,Docker Hub是默认的公有Registry,也可配置使用私有Registry。 使用Docker时会涉及image、container、network、volume、plugin等对象。

  • Image是用来创建Container的只读模板。一个Image可以建立在另一个Image之上,使用Dockerfile文件配置image。Dockerfile的每一指令创建一个image layer,当更改Dockerfile重建image时,仅更改的layer被重建。
  • Container是Image的运行实例。

Docker版本

自17年3月,Docker版本号采用YY.mm.patch格式,YY.mm代表年月。

安装和卸载

在CentOS 7或RHEL 7上安装默认版本的Docker,执行如下命令:

# yum install docker
# systemctl enable docker
# systemctl start docker

docker配置文件位置: /etc/sysconfig/docker /etc/docker目录

安装官方最新版本docker,以CentOS 7为例步骤如下:

卸载旧版本

旧版本称为docker或docker-engine,如安装过先卸载:

# yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

目录/var/lib/docker/下的内容不会删除,其中包含images、containers、volumes、networks等。

安装Docker CE

前提,必须启用centos-extras repository。推荐使用overlay2存储。

  1. 安装必须的Package

yum-utils提供yum-config-manager工具,用来配置Docker Repository;devicemapper storage driver需要device-mapper-persistent-data和lvm2

# yum install -y yum-utils device-mapper-persistent-data lvm2
  1. 配置Docker Repository
# yum-config-manager  --add-repo https://download.docker.com/linux/centos/docker-ce.repo
  1. 安装Docker CE
# yum install docker-ce docker-ce-cli containerd.io

安装后会创建docker group。

  1. 启动docker
# systemctl enable docker
# systemctl start docker
  1. 验证docker安装
# docker info
# docker version

运行hello-world:

# docker run hello-world

成功后输出如下内容:

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
1b930d010525: Pull complete
Digest: sha256:f9dfddf63636d84ef479d645ab5885156ae030f611a56f3a7ac7f2fdd86d7e4e
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/

查看image和container:

# docker images
# docker ps -a
  1. 用户管理

Docker Daemon绑定了Unix socket,而不是TCP端口,默认Unix socket由root和sudo权限的用户拥有。为了运行docker命令时不使用sudo,创建Unix group "docker"(Docker安装后创建了docker group),将用户添加到docker group即可。当docker daemon启动时,让docker group有读/写Unix Socket权限。

# groupadd docker
# usermod -aG docker $USER

执行以上命令后需重新登录或重启。

卸载Docker CE

# yum remove docker-ce

Images、 containers、 volumes、customized configuration files不会自动删除,执行以下命令删除:

# rm -rf /var/lib/docker

Docker CLI

几种CLI:

CLI Description
Docker CLI The main CLI for Docker, includes all docker commands
Compose CLI The CLI for Docker Compose, which allows you to build and run multi-container applications
Daemon CLI (dockerd) Persistent process that manages containers

下面介绍Docker CLI。

运行不带任何参数的docker命令或docker help,将列出所有可用的docker命令

为了查看某一命令的帮助,执行如下命令:

$ docker run --help

option参数可以组合在一起:

$ docker run -it ubuntu bash

管理命令

Command Description
builder Manage builds
config Manage Docker configs
container Manage containers
context Manage contexts
engine Manage the docker engine
image Manage images
network Manage networks
node Manage Swarm nodes
plugin Manage plugins
secret Manage Docker secrets
service Manage services
stack Manage Docker stacks
swarm Manage Swarm
system Manage Docker
trust Manage trust on Docker images
volume Manage volumes

根据用途不同,Docker CLI提供了一系列管理命令。

常用命令有快捷方式,比如: docker image build -> docker build docker image ls -> docker images docker image pull -> docker pull docker image push -> docker push docker image rm -> docker rmi docker image tag -> docker tag

docker container logs -> docker logs docker container ls -> docker ps docker container rm -> docker rm docker container run -> docker run docker container start -> docker start docker container stop -> docker stop

Image命令

Command Description
docker image Manage images
docker build Build an image from a Dockerfile
docker commit Create a new image from a container’s changes
docker history Show the history of an image
docker images List images
docker import Import the contents from a tarball to create a filesystem image
docker load Load an image from a tar archive or STDIN
docker pull Pull an image or a repository from a registry
docker push Push an image or a repository to a registry
docker rmi Remove one or more images
docker save Save one or more images to a tar archive (streamed to STDOUT by default)
docker search Search the Docker Hub for images
docker tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE

示例:

拉取image

$ docker pull hello-world

查询image

$ docker search openjdk

删除所有没用的image

$ docker image prune

删除所有image

$ docker rmi `docker images -a -q`

Container命令

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

示例:

删除所有停止的容器

$ docker container prune

删除所有容器

$ docker rm `docker ps -a -q`

Registry命令

Command Description
docker login Log in to a Docker registry
docker logout Log out from a Docker registry
docker pull Pull an image or a repository from a registry
docker push Push an image or a repository to a registry

docker build

使用docker build命令从Dockerfile构建image,是构建image的最常用方式。

docker build [OPTIONS] PATH | URL | -

我们先下载一个Node.js示例工程:

git clone https://github.com/dockersamples/node-bulletin-board
cd node-bulletin-board/bulletin-board-app

Dockerfile

Dockerfile描述了如何为容器组装文件系统,还可以包含一些元数据,说明如何基于此映像运行容器。

# Use the official image as a parent image
FROM node:current-slim

# Set the working directory
WORKDIR /usr/src/app

# Copy the file from your host to your current location
COPY package.json .

# Run the command inside your image filesystem
RUN npm install

# Inform Docker that the container is listening on the specified port at runtime.
EXPOSE 8080

# Run the specified command within the container.
CMD [ "npm", "start" ]

# Copy the rest of your app's source code from your host to your image filesystem.
COPY . .

Build Image

# docker build -t bulletinboard:1.0 .

默认使用当前目录下的Dockerfile构建image,也可以使用-f指定文件:

# docker build -f /path/to/a/Dockerfile .

可以使用多个-t 参数指定多个repository:

# docker build -t bulletinboard:1.0 -t bulletinboard:latest .

相关CLI

列出image:

# docker images

显示image详细信息:

# docker inspect bulletinboard:1.0

标记image,以便将image推送到存储库:

# docker tag bulletinboard:1.0 registry.itrunner.org/bulletinboard:1.0

推送image到存储库:

docker push registry.itrunner.org/bulletinboard:1.0

删除image:

# docker rmi bulletinboard:1.0

docker run

$ docker run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND] [ARG...]

运行前面的container:

# docker run -p 8000:8080 -d --name bb bulletinboard:1.0

参数说明:

  • -p 要求 Docker 将主机端口 8000 传入的流量转发到容器的端口 8080
  • -d 要求 Docker 在后台运行容器
  • --name 容器名字,未指定时将随机生成字符串作为名字

访问应用程序: http://localhost:8000

Container Identification

有三种方式识别容器:

Identifier type Example value
UUID long identifier “f78375b1c487e03c9438c729345e54db9d20cfa2ac1fc3494b6eb60872e74778”
UUID short identifier “f78375b1c487”
Name “evil_ptolemy”

运行容器成功后输出的信息即为UUID long identifier,也可以运行以下命令查看首行显示的“ID”:

$ docker container inspect bb

查看UUID short identifier,运行以下命令显示的CONTAINER ID:

$ docker ps -a

启动模式

docker container有两种启动模式:Detached、Foreground,默认为Foreground模式。

Detached模式 指定-d选项后,启用Detached模式,container将在后台运行。

$ docker run -p 8000:8080 -d --name bb bulletinboard:1.0

要附加到Detached容器,使用 Docker attach命令:

$ docker run -d --name topdemo ubuntu /usr/bin/top -b
$ docker attach topdemo

Foreground模式 以前台模式启动,可以将控制台附加到进程的标准输入、输出和标准错误,可以扮作TTY(这是大多数命令行可执行文件所期望的)并传递信号。

可配置项:

-a=[]           : Attach to `STDIN`, `STDOUT` and/or `STDERR`
-t              : Allocate a pseudo-tty
--sig-proxy=true: Proxy all received signals to the process (non-TTY mode only)
-i              : Keep STDIN open even if not attached

如果没有指定-a,将附加stdout和stderr,可以指定三个标准流中的哪一个(STDIN、STDOUT、STDERR):

$ docker run -a stdin -a stdout -it ubuntu /bin/bash

-it组合在一起使用,可以与容器进行交互。

运行以上命令后,会执行以下操作:

  1. 如本地没有ubuntu image,将从registry获取,相当于手动执行docker pull ubuntu
  2. Docker创建新的容器,相当于运行docker container create
  3. Docker给容器分配可读写的文件系统
  4. Docker创建网络接口连接容器到默认网络
  5. Docker启动容器并执行/bin/bash

容器启动后,可以执行shell命令,如下:

root@f7cbdac22a02:/# hostname
root@f7cbdac22a02:/# cat /etc/hosts
root@f7cbdac22a02:/# yum install -y vim
  1. 输入exit,终止/bin/bash,容器停止但不会被删除,可以重新启动。
root@f7cbdac22a02:/# exit

网络设置

--dns=[]           : Set custom dns servers for the container
--network="bridge" : Connect a container to a network
                  'bridge': create a network stack on the default Docker bridge
                  'none': no networking
                  'container:<name|id>': reuse another container's network stack
                      'host': use the Docker host network stack
                      '<network-name>|<network-id>': connect to a user-defined network
--network-alias=[] : Add network-scoped alias for the container
--add-host=""      : Add a line to /etc/hosts (host:IP)
--mac-address=""   : Sets the container's Ethernet device's MAC address
--ip=""            : Sets the container's Ethernet device's IPv4 address
--ip6=""           : Sets the container's Ethernet device's IPv6 address
--link-local-ip=[] : Sets one or more container's Ethernet device's link local IPv4/IPv6 add

默认,所有容器都启用了网络,可以进行任何传出连接。使用docker run --network none可以完全禁用网络,禁用所有传入和传出。在这种情况下,仅能通过文件或 STDIN 和 STDOUT 执行 I/O操作。

网络模式

  • none 无网络
  • bridge Docker默认网络配置,将创建一个桥接网络docker0,每创建一个容器分配一个IP、生成MAC地址,容器间可以通过IP通信。

容器间通信必须知道IP,特别Auto Scaling IP不确定时,这种方式不实用。bridge网络通常用于在独立容器运行的程序,而不需要通信。

发布端口并链接到其它容器仅适用于bridge:

$ docker run -d -p 8080:8080 --restart always --name heroes-api heroes-api
$ docker run -d -p 80:80 --restart always --name heroes-web --link heroes-api:heroes-api heroes-web

--link 参数中第一个heroes-api是容器名,第二个heroes-api定义容器别名,在heroes-web容器内可以使用别名访问heroes-api,如http://heroes-api:8080 。

链接功能是一个遗留功能,创建容器有顺序要求,不推荐使用。

  • host 共享主机的网络堆栈,容器没有自己的IP,来自主机的所有接口都可用于容器,容器间通信使用localhost即可。

-p、--mac-address是无效的;--hostname、 --domainname、--add-host、 --dns、 --dns-search、 --dns-option仅对容器生效,不会改变host配置。

$ docker run -d --restart always --network host --name heroes-api heroes-api
$ docker run -d --restart always --network host --name heroes-web heroes-web

host模式性能好,仅支持linux。容器可以完全访问本地系统服务(如 D-bus),因此存在安全问题。

  • container 共享另一容器的网络堆栈,必须提供另一容器的name或id

--add-host --hostname --dns --dns-search --dns-option and --mac-address --publish --publish-all --expose 均无效。

$ docker run -d --restart always --network host --name heroes-api heroes-api
$ docker run -d --restart always --network container:heroes-api --name heroes-web heroes-web
  • user-defined network

可以使用docker network driver 或 external network driver plugin来创建网络,连接多个容器到同一网络,容器间通信可以使用IP或name。

如下,使用内建的bridge driver创建网络,

$ docker network create -d bridge heroes-net
$ docker run -d --restart always --network heroes-net --name heroes-api heroes-api
$ docker run -d --restart always --network heroes-net --name heroes-web heroes-web

重启策略

使用--restart指定容器退出后的重启策略。

Policy Result
no 默认值,不自动重启
on-failure[:max-retries] 当容器非0状态退出时,可以限制重启重试次数
always 无论退出状态如何总是无限期重启
unless-stopped 无论退出状态如何总是重新启动,包括在启动daemon时,除非容器在 Docker daemon停止之前处于停止状态

自动清理

使用--rm,当容器退出时会自动删除容器。

比如,我们为了查看容器是否能正常启动,临时启动容器:

$ docker run -it heroes-api

资源限制

可以设定容器使用内存、CPU等资源的限额。

$ docker run -d -m 300M --cpu-period 50000 --cpu-quota 25000 --restart always --network host --name heroes-api heroes-api

相关命令

列出容器:

$ docker ps -a

-a 显示所有container,默认仅显示运行的container

显示容器进程:

$ docker top heroes-api

启动容器:

$ docker start heroes-api heroes-web

停止容器:

$ docker stop heroes-api heroes-web

重启容器:

$ docker restart heroes-api

删除容器:

$ docker rm heroes-api

查看容器日志:

$ docker logs -f heroes-api

查看容器详细信息:

$ docker container inspect heroes-api

查看容器资源使用统计信息:

$ docker stats heroes-api

docker commit

使用docker commit可以从container创建image。使用Dockerfile来创建和管理image是更好的方式,docker commit主要用于调试容器,或将数据导出到另一台服务器。

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

Options

Name, shorthand Default Description
--author , -a Author (e.g., “John Hannibal Smith hannibal@a-team.com”)
--change , -c Apply Dockerfile instruction to the created image
--message , -m Commit message
--pause , -p true Pause container during commit

从容器创建image

# docker commit bb bulletinboard:2.0

修改容器配置后创建image

#  docker container inspect -f "{{ .Config.Env }}" bb
[PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin NODE_VERSION=12.16.1 YARN_VERSION=1.22.0]

# docker commit --change "ENV MODIFIEDBY Jason" bb bulletinboard:2.0
sha256:8ad248d41ba1a99095087be7c2cf9e49e9792c9d731d679d4180edd43a3ee72a

# docker inspect -f "{{ .Config.Env }}" 8ad248d41ba1a99095087be7c2cf9e49e9792c9d731d679d4180edd43a3ee72a
[PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin NODE_VERSION=12.16.1 YARN_VERSION=1.22.0 MODIFIEDBY=Jason]

搭建私有Registry

docker常用命令结构:

docker <command> <registry-hostname>:<registry-port>/<namespace>/<image>:<tag>

默认Registry为Docker Hub,默认namespace为/library,以下三个命令效果相同:

# docker pull hello-world
# docker pull docker.io/hello-world
# docker pull docker.io/library/hello-world

使用Docker中国官方镜像registry.docker-cn.com可以享受到更快的下载速度和更强的稳定性,但只包含流行的公有镜像。

# docker pull registry.docker-cn.com/library/hello-world

可以配置Docker守护进程默认使用Docker中国官方镜像,这样无需在每次拉取时指定registry.docker-cn.com,修改文件/etc/docker/daemon.json添加registry-mirrors键值:

{
  "registry-mirrors": ["https://registry.docker-cn.com"]
}

保存后重启Docker以使配置生效。

初识Registry

  1. 使用官方registry镜像创建私有Registry
# mkdir /mnt/registry/docker
# docker run -d -p 5000:5000  --restart always -v /mnt/registry:/var/lib/registry --name registry registry

参数说明: --restart always 容器异常退出或重启docker后自动重启容器 -v /mnt/registry:/var/lib/registry 绑定/mnt/registry到容器/var/lib/registry目录(存放镜像文件的目录)来实现数据持久化

selinux 如系统启用了selinux,要为/mnt/registry设置selinux安全上下文类型,如下:

# semanage fcontext -a -t container_file_t "/mnt/registry(/.*)?"
# restorecon -R -v /mnt/registry
  1. 上传image

为image打标签后上传到仓库:

$ docker tag hello-world localhost:5000/hello-world:latest
$ docker push localhost:5000/hello-world:latest

tag语法: Usage: docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]

也可以使用IMAGE ID:

$ docker tag fce289e99eb9 localhost:5000/hello-world:latest

如系统启用了selinux,但未设置安全上下文类型,上传时会一直retry,报如下错误(可运行journalctl -xe查看原因):

SELinux is preventing /bin/registry from add_name access on the directory docker.

*****  Plugin catchall_labels (83.8 confidence) suggests   *******************

If you want to allow registry to have add_name access on the docker directory
Then you need to change the label on docker
Do
# semanage fcontext -a -t FILE_TYPE 'docker'
where FILE_TYPE is one of the following: container_file_t, container_var_lib_t, nfs_t, svirt_home_t, tmpfs_t, virt_home_t.
Then execute:
restorecon -v 'docker'
  1. 从本地registry运行容器
$ docker run localhost:5000/hello-world
  1. 查看registry中的image

列出所有image:

curl http://localhost:5000/v2/_catalog

列出hello-world image:

curl http://localhost:5000/v2/hello-world/tags/list
  1. 外部访问registry

通过上面方式创建的registry其协议为http,是不安全的,只适用于本地使用,若要从外部访问registry,需要编辑/etc/docker/daemon.json,增加insecure-registries,如下:

{
  "insecure-registries": ["192.168.122.1:5000"]
}

配置完毕后需重启docker。

SSL Registry

  1. 获取证书

以自签名证书为例,Registry URL为registry.itrunner.org,生成自签名证书:

$ cd /mnt/registry
$ mkdir certs
$ openssl req -newkey rsa:2048 -nodes -sha256 -keyout certs/domain.key \
-x509 -days 365 -out certs/domain.crt -subj /C=CN/ST=Beijing/L=Beijing/CN=registry.itrunner.org/OU=itrunner/O=itrunner/emailAddress=sjc-925@163.com

同样,如系统启用了selinux,需给certs目录指定安全上下文:

# semanage fcontext -a -t container_file_t "certs(/.*)?"
# restorecon -R -v certs

每台使用这个Registry的主机都需将自签名证书拷贝到/etc/docker/certs.d/registry.itrunner.org目录下:

# mkdir /etc/docker/certs.d/registry.itrunner.org
# cp certs/domain.crt /etc/docker/certs.d/registry.itrunner.org
  1. 删除当前运行的Registry
$ docker stop registry
$ docker rm registry
  1. 配置证书重新运行Registry
$ docker run -d --restart always --name registry -v /mnt/registry:/var/lib/registry \
-v "$(pwd)"/certs:/certs \
-e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
-p 443:443 \
registry
  1. 测试
$ curl -k https://registry.itrunner.org/v2/
$ docker tag hello-world registry.itrunner.org/hello-world
$ docker push registry.itrunner.org/hello-world
$ docker pull registry.trunner.org/hello-world

Registry Proxy

每次都从远程Registry获取image浪费网络资源,效率低下。虽然我们可以先从远程pull,再push到私有Registry,但这样操作非常烦琐。Registry Proxy可以本地存储image,减少了重复的pull操作。Registry Proxy不支持push。 这次我们使用配置文件运行registry,执行以下命令获取默认配置文件:

$ docker run -it --rm --entrypoint cat registry /etc/docker/registry/config.yml > config.yml

文件内容如下:

version: 0.1
log:
  fields:
    service: registry
storage:
  cache:
    blobdescriptor: inmemory
  filesystem:
    rootdirectory: /var/lib/registry
http:
  addr: :5000
  headers:
    X-Content-Type-Options: [nosniff]
health:
  storagedriver:
    enabled: true
    interval: 10s
    threshold: 3

增加proxy配置:

version: 0.1
log:
  fields:
    service: registry
storage:
  cache:
    blobdescriptor: inmemory
  filesystem:
    rootdirectory: /var/lib/registry
http:
  addr: 0.0.0.0:443
  headers:
    X-Content-Type-Options: [nosniff]
  tls:
    certificate: /var/lib/registry/certs/domain.crt
    key: /var/lib/registry/certs/domain.key
health:
  storagedriver:
    enabled: true
    interval: 10s
    threshold: 3
proxy:
  remoteurl: https://registry-1.docker.io

修改/etc/docker/daemon.json:

{
  "registry-mirrors": ["https://registry.itrunner.org"]
}

重启docker后运行registry:

$ docker run -d --restart always --name registry-proxy -p 443:443 -v /mnt/registry:/var/lib/registry \
registry /var/lib/registry/config.yml

测试:

$ docker pull hello-world

查看proxy:

$ curl -k https://registry.itrunner.org/v2/_catalog
{"repositories":["library/hello-world"]}

可以看到hello-world已保存到proxy中。

搭建Nexus私服

除默认Registry外,使用docker时必须指定Registry域名,能否像Maven一样统一使用一个仓库呢?Nexus 3支持Docker Repository,同Maven一样分为三种类型:group、hosted、proxy。hosted相当于私有Registry,用来存储公司内部image;proxy为代理Registry;group可以将hosted、proxy、group三者组合在一起。

Docker Proxy

下面创建docker.io的代理,依次点击Repository -> Repositories -> Create repository -> docker(proxy) : 参数说明: Repository Connectors Docker Client连接Repository的地址,仅需指定HTTP或HTTPS端口,若使用HTTPS则启动Nexus时也需使用HTTPS。一般不直接访问Proxy,而是通过group,此处不必配置。 Force basic authentication 若启用则禁止匿名访问,需提供nexus账号 Enable Docker V1 API 一般不必启用V1 API,现在常用的是V2 API Remote Repository:https://registry-1.docker.io ,Docker Index:Use Docker Hub

Docker Hosted

依次点击Repository -> Repositories -> Create repository -> docker(hosted) :

Docker Group

依次点击Repository -> Repositories -> Create repository -> docker(group) :

匿名访问

首先确认是否启用了匿名访问,依次点击Security -> Anonymous: 其他配置保持默认值。 然后创建docker匿名用户角色并授予适当权限,依次点击Security -> Roles -> Create role - Nexus role: 接下来将角色授予匿名用户,依次点击Security -> Users -> anonymous:

使用私服

同样,修改/etc/docker/daemon.json:

{
  "registry-mirrors": ["https://nexus.itrunner.org:8443"]
}

重启docker后测试:

$ docker pull hello-world

从浏览器可以方便的查看已下载的image:

常见问题

docker error initializing network controller 删除/var/lib/docker/network/files下的文件,重新启动。

参考文档

Docker Documentation How to Set Up a Registry Proxy Cache with Docker Open Source Registry