Docker入门基础
1、Docker核心概念
Docker 大部分的操作都围绕着它的三大核心概念:镜像、容器和仓库。因此,准确把握
这三大核心概念对于掌握Docker技术尤为重要。
1.1、docker镜像---(安装包)
Docker 镜像类似于虚拟机镜像,可以将它理解为一个只读的模板。
例如,一个镜像可以包含一个基本的操作系统环境,里面仅安装了 Apache 应用程序(或
用户需要的其他软件) 可以把它称为一个 Apache 镜像。
镜像是创建 Docker 容器的基础。
通过版本管理和增量的文件系统, Docker 提供了一套十分简单的机制来创建和更新现有
的镜像,用户甚至可以从网上下载一个已经做好的应用镜像,并直接使用。
1.2、docker容器---(应用)
Docker 容器类似于一个轻级的沙箱, Docker 利用容器来运行和隔离应用。
容器是从镜像创建的应用运行实例,它可以启动、开始、停止、删除,而这些容器都是
彼此相互隔离、互不可见的。
可以把容器看作一个简易版的 Linux 系统环境(包括 root 用户权限、进程空间、用户空
间和网络空间等)以及运行在其中的应用程序打包而成的盒子。
注意:镜像自身是只读的,容器从镜像启动的时候,会在镜像的最上层创建一个可写层。
1.3、docker仓库---(软件商店)
Docker 仓库类似于代码仓库,是 Docker 集中存放镜像文件的场所。
目前,最大的公开仓库是官方提供的 Docker Hub ,其中存放着数量庞大的镜像供用户下
国内不少云服务提供商(如腾讯云 阿里云等)也提供了仓库的本地源,可以提供稳定
的国内访问。
当然,用户如果不希望公开分享自己的镜像文件, Docker 也支持用户在本地网络内创建
一个只能自己访问的私有仓库。
当用户创建了自己的镜像之后就可以使用 push 命令将它上传到指定的公有或者私有仓
这样用户下次在另外一台机器上使用该镜像时,只需要将其从仓库上 pull 来就可以了。
2、Docker部署安装
2.1、在线安装
# 添加软件源信息
[root@openEuler-1 ~]# yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo# 在openEuler系统上,需要修改yum源的参数
[root@openEuler-1 ~]# sed -i "s/\$releasever/8/g" /etc/yum.repos.d/docker-ce.repo# 安装docker
[root@openEuler-1 ~]# yum install docker-ce -y
[root@openEuler-1 ~]# systemctl start docker# 查看版本
[root@openEuler-1 ~]# docker version
Docker version 26.1.3, build b72abbb
[root@openEuler-1 ~]# docker version
Client: Docker Engine - CommunityVersion: 26.1.3API version: 1.45Go version: go1.21.10Git commit: b72abbbBuilt: Thu May 16 08:34:39 2024OS/Arch: linux/amd64Context: defaultServer: Docker Engine - CommunityEngine:Version: 26.1.3API version: 1.45 (minimum version 1.24)Go version: go1.21.10Git commit: 8e96db1Built: Thu May 16 08:33:34 2024OS/Arch: linux/amd64Experimental: falsecontainerd:Version: 1.6.32GitCommit: 8b3b7ca2e5ce38e8f31a34f35b2b68ceb8470d89runc:Version: 1.1.12GitCommit: v1.1.12-0-g51d5e94docker-init:Version: 0.19.0GitCommit: de40ad0
注意:
官方软件源默认启用了最新的软件,您可以通过编辑软件源的方式获取各个版本的软件包。例如官方并没有将测试版本的软件源置为可用,您可以通过以下方式开启。同理可以开启各种测试版本等。
vim /etc/yum.repos.d/docker-ce.repo
将[docker-ce-test]下方的enabled=0修改为enabled=1# 想安装制定版本
[root@openEuler-1 ~]# yum list docker-ce.x86_64 --showduplicates | sort -r
2.2、二进制的安装
下载地址:Index of linux/static/stable/x86_64/
# 下载二进制安装包
[root@openEuler-2 ~]# wget -c https://download.docker.com/linux/static/stable/x86_64/docker-28.0.1.tgz# 解压
[root@openEuler-2 ~]# tar -zxvf docker-28.0.1.tgz
[root@openEuler-2 ~]# chown root:root docker/*
[root@openEuler-2 ~]# groupadd docker# 放入/usr/bin下
[root@openEuler-2 ~]# cp -p docker/* /usr/bin/
配置相关服务文件:docker.service 、docker.socket、 containerd.service。
[root@openEuler-2 ~]# tee /usr/lib/systemd/system/docker.socket <<EOF
> [Unit]
> Description=Docker Socket for the API
>
> [Socket]
> ListenStream=/var/run/docker.sock
> SocketMode=0660
> SocketUser=root
> SocketGroup=docker
>
> [Install]
> WantedBy=sockets.target
> EOF[root@openEuler-2 ~]# tee /usr/lib/systemd/system/containerd.service <<EOF
> [Unit]
> Description=containerd container runtime
> Documentation=https://containerd.io
> After=network.target local-fs.target
>
> [Service]
> ExecStartPre=-/sbin/modprobe overlay
> ExecStart=/usr/bin/containerd
>
> Type=notify
> Delegate=yes
> KillMode=process
> Restart=always
> RestartSec=5
>
> # Having non-zero Limit*s causes performance problems due to accounting overhead
>
> # in the kernel. We recommend using cgroups to do container-local accounting.
>
> LimitNPROC=infinity
> LimitCORE=infinity
> LimitNOFILE=infinity
>
> # Comment TasksMax if your systemd version does not supports it.
>
> # Only systemd 226 and above support this version.
>
> TasksMax=infinity
> OOMScoreAdjust=-999
>
> [Install]
> WantedBy=multi-user.target
> EOF[root@openEuler-2 ~]# tee /usr/lib/systemd/system/docker.service <<EOF
> [Unit]
> Description=Docker Application Container EngineStartLimitBurst=3StartLimitInterval=60sLimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinityTasksMax=infinity
> Documentation=https://docs.docker.comDelegate=yesKillMode=process
OOMScoreAdjust=-500[Install]
> After=network-online.target docker.socket firewalld.service containerd.service
> Wants=network-online.target
> Requires=docker.socket containerd.service
>
> [Service]
> Type=notify
> ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
> ExecReload=/bin/kill -s HUP $MAINPID
> TimeoutSec=0
> RestartSec=2
> Restart=always
>
> StartLimitBurst=3
>
> StartLimitInterval=60s
>
> LimitNOFILE=infinity
> LimitNPROC=infinity
> LimitCORE=infinity
>
> TasksMax=infinity
>
> Delegate=yes
>
> KillMode=process
> OOMScoreAdjust=-500
>
> [Install]
> WantedBy=multi-user.target
> EOF
2.3、配置镜像加速器
[root@openEuler-2 docker]# cat /etc/docker/daemon.json
{"registry-mirrors": ["https://docker.m.daocloud.io","https://hub-mirror.c.163.com","https://mirror.baidubce.com","https://docker.nju.edu.cn"]
}
可以加速我们拉取镜像
[root@openEuler-2 ~]# systemctl restart docker.service
[root@openEuler-2 ~]# docker pull busybox
Using default tag: latest
latest: Pulling from library/busybox
90b9666d4aed: Pull complete
Digest: sha256:f85340bf132ae937d2c2a763b8335c9bab35d6e8293f70f606b9c6178d84f42b
Status: Downloaded newer image for busybox:latest
docker.io/library/busybox:latest
[root@openEuler-2 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox latest 6d3e4188a38a 9 months ago 4.28MB
3、使用Docker镜像
3.1、拉取镜像
命令:
docker [image] pull NAME[:TAG]
# 其中name是镜像仓库名称,tag是镜像的标签(一般用于表示版本信息),若不加tag默认拉取latest版本
[root@openEuler-2 ~]# docker pull ubuntu:18.04
18.04: Pulling from library/ubuntu
7c457f213c76: Pull complete
Digest: sha256:152dc042452c496007f07ca9127571cb9c29697f42acbfad72324b2bb2e43c98
Status: Downloaded newer image for ubuntu:18.04
docker.io/library/ubuntu:18.04
[root@openEuler-2 ~]# docker pull ubuntu
Using default tag: latest
latest: Pulling from library/ubuntu
b08e2ff4391e: Pull complete
Digest: sha256:440dcf6a5640b2ae5c77724e68787a906afb8ddee98bf86db94eea8528c2c076
Status: Downloaded newer image for ubuntu:latest
docker.io/library/ubuntu:latest
3.2、查看镜像信息
①:image命令列出镜像
命令:
docker images
或
docker image ls
示例:
[root@openEuler-1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest a04dc4851cbc 5 weeks ago 78.1MB
ubuntu 18.04 f9a80a55f492 21 months ago 63.2MB[root@openEuler-1 ~]# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest a04dc4851cbc 5 weeks ago 78.1MB
ubuntu 18.04 f9a80a55f492 21 months ago 63.2MB
②:tag 命令添加镜像标签:
命令:
docker tag
示例:
[root@openEuler-2 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myubuntu new f9248aac10f2 3 weeks ago 78.1MB
ubuntu latest f9248aac10f2 3 weeks ago 78.1MB
busybox latest 6d3e4188a38a 9 months ago 4.28MB
ubuntu 18.04 f9a80a55f492 2 years ago 63.2MB
可以看到 myubuntu 和 ubuntu 的镜像ID一致,说明他俩指向的是同一个镜像文件。
③:inspect 命令查看详细信息
命令:
docker [image] inspect 仓库名:版本号
示例:
[root@openEuler-2 ~]# docker inspect ubuntu:latest
[{"Id": "sha256:f9248aac10f2f82e0970222e36cc7b71215b88e974e001282e5cd89797a82218","RepoTags": ["myubuntu:new","ubuntu:latest"],"RepoDigests": ["ubuntu@sha256:440dcf6a5640b2ae5c77724e68787a906afb8ddee98bf86db94eea8528c2c076"],"Parent": "","Comment": "","Created": "2025-06-19T23:16:36.086314448Z","DockerVersion": "24.0.7","Author": "","Config": {"Hostname": "","Domainname": "","User": "","AttachStdin": false,"AttachStdout": false,"AttachStderr": false,"Tty": false,"OpenStdin": false,"StdinOnce": false,"Env": ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd": ["/bin/bash"],"Image": "sha256:f0b585b8b34537e85ece3268950fc83162b2b470fe7105719d8d77b37d9ced3d","Volumes": null,"WorkingDir": "","Entrypoint": null,"OnBuild": null,"Labels": {"org.opencontainers.image.ref.name": "ubuntu","org.opencontainers.image.version": "24.04"}},"Architecture": "amd64","Os": "linux","Size": 78118302,"GraphDriver": {"Data": {"MergedDir": "/var/lib/docker/overlay2/dd045935274e1c62c1292ce0af0f83815c7ba5ba70624b18fd4e558322291dea/merged","UpperDir": "/var/lib/docker/overlay2/dd045935274e1c62c1292ce0af0f83815c7ba5ba70624b18fd4e558322291dea/diff","WorkDir": "/var/lib/docker/overlay2/dd045935274e1c62c1292ce0af0f83815c7ba5ba70624b18fd4e558322291dea/work"},"Name": "overlay2"},"RootFS": {"Type": "layers","Layers": ["sha256:45a01f98e78ce09e335b30d7a3080eecab7f50dfa0b38ca44a9dee2654ac0530"]},"Metadata": {"LastTagTime": "2025-07-12T10:35:31.700353737+08:00"}}
]
上面的代码是一个JSON格式的信息,若我们只要其中一项内容时,可以使用 -f 来指定:
示例:
[root@openEuler-1 ~]# docker inspect -f {{".Architecture"}} ubuntu:latest
amd64
④:查看镜像的历史命令
[root@openEuler-2 ~]# docker history ubuntu:latest
IMAGE CREATED CREATED BY SIZE COMMENT
f9248aac10f2 3 weeks ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 3 weeks ago /bin/sh -c #(nop) ADD file:0ebb3dd98809cffc1… 78.1MB
<missing> 3 weeks ago /bin/sh -c #(nop) LABEL org.opencontainers.… 0B
<missing> 3 weeks ago /bin/sh -c #(nop) LABEL org.opencontainers.… 0B
<missing> 3 weeks ago /bin/sh -c #(nop) ARG LAUNCHPAD_BUILD_ARCH 0B
<missing> 3 weeks ago /bin/sh -c #(nop) ARG RELEASE 0B
3.3、搜寻镜像
用于搜索Docker Hub官方仓库中的镜像的命令:
docker search [option] keyword-f,--filter filter:过滤输出内容
--format string:格式化输出内容
--limit int:限制输出结果个数,默认为25个
--no-trunc:不截断输出结果
3.4、删除和清理镜像
主要使用Docker镜像的rm和prune子命令。
①:使用标签删除
docker rmi 或 docker image rm
示例:
[root@openEuler-2 ~]# docker rmi ubuntu:latest
Untagged: ubuntu:latest
Untagged: ubuntu@sha256:440dcf6a5640b2ae5c77724e68787a906afb8ddee98bf86db94eea8528c2c076
[root@openEuler-2 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myubuntu new f9248aac10f2 3 weeks ago 78.1MB
busybox latest 6d3e4188a38a 9 months ago 4.28MB
ubuntu 18.04 f9a80a55f492 2 years ago 63.2MB
②:使用ID删除
[root@openEuler-2 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myubuntu new f9248aac10f2 3 weeks ago 78.1MB
busybox latest 6d3e4188a38a 9 months ago 4.28MB
ubuntu 18.04 f9a80a55f492 2 years ago 63.2MB
[root@openEuler-2 ~]# docker rmi f9a80a55f492
Untagged: ubuntu:18.04
Untagged: ubuntu@sha256:152dc042452c496007f07ca9127571cb9c29697f42acbfad72324b2bb2e43c98
Deleted: sha256:f9a80a55f492e823bf5d51f1bd5f87ea3eed1cb31788686aa99a2fb61a27af6a
Deleted: sha256:548a79621a426b4eb077c926eabac5a8620c454fb230640253e1b44dc7dd7562
[root@openEuler-2 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myubuntu new f9248aac10f2 3 weeks ago 78.1MB
busybox latest 6d3e4188a38a 9 months ago 4.28MB
③:清理镜像
命令:
docker image prune
# -a 删除所有无用镜像,不光是临时镜像
# -f 强制删除,不需要确认
# -filter 只删除给定过滤器的镜像
示例:
[root@openEuler-2 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myubuntu new f9248aac10f2 3 weeks ago 78.1MB
busybox latest 6d3e4188a38a 9 months ago 4.28MB
[root@openEuler-2 ~]# docker image prune -a
WARNING! This will remove all images without at least one container associated to them.
Are you sure you want to continue? [y/N] y
Deleted Images:
untagged: busybox:latest
untagged: busybox@sha256:f85340bf132ae937d2c2a763b8335c9bab35d6e8293f70f606b9c6178d84f42b
deleted: sha256:6d3e4188a38af91b0c1577b9e88c53368926b2fe0e1fb985d6e8a70040520c4d
deleted: sha256:65014c70e84b6817fac42bb201ec5c1ea460a8da246cac0e481f5c9a9491eac0Total reclaimed space: 4.278MB
[root@openEuler-2 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myubuntu new f9248aac10f2 3 weeks ago 78.1MB
3.5、存入和载入镜像
存入镜像:
[root@openEuler-1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest a04dc4851cbc 5 weeks ago 78.1MB[root@openEuler-1 ~]# docker save -o ubuntu_latest.tar ubuntu:latest# 传给另一台主机
[root@openEuler-1 ~]# ls
anaconda-ks.cfg ubuntu_latest.tar
[root@openEuler-1 ~]# scp ubuntu_latest.tar 192.168.93.11:~
载入镜像:
# 来自主机1的镜像包
[root@openEuler-2 ~]# ls
anaconda-ks.cfg ubuntu_latest.tar[root@openEuler-2 ~]# docker load -i ubuntu_latest.tar
4b7c01ed0534: Loading layer [==================================================>] 80.65MB/80.65MB
Loaded image: ubuntu:latest[root@openEuler-2 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest a04dc4851cbc 5 weeks ago 78.1MB
可以发现ID号也是一样的。
3.6、上传镜像
命令:
docker [images] push NAME[:TAG]
4、操作容器Docker
4.1、创建容器
①:新建容器
[root@node-1 ~]# docker create -it ubuntu:latest
e5f7fe746293fbef3ffd16ee1235df55cc5c2ef3bd6363d6c2d5e22b4c538c56
[root@node-1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e5f7fe746293 ubuntu:latest "/bin/bash" 8 seconds ago Created sweet_napier
512f2d30b9e4 ubuntu "/bin/bash" 2 hours ago Exited (0) 23 seconds ago hardcore_hertz
②:启动容器
[root@node-1 ~]# docker start sweet_napier
sweet_napier
[root@node-1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e5f7fe746293 ubuntu:latest "/bin/bash" 17 minutes ago Up 9 minutes sweet_napier
512f2d30b9e4 ubuntu "/bin/bash" 2 hours ago Exited (0) 17 minutes ago hardcore_hertz# 注意:docker start 后跟的是容器名称,在创建容器时通过--name来定义,否则自动生成名称
③:新建并启动容器
[root@node-1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest f9248aac10f2 3 weeks ago 78.1MB
[root@node-1 ~]# docker run -it ubuntu '/bin/bash'
root@cd18b86e3342:/#
root@cd18b86e3342:/# exit
exit
[root@node-1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cd18b86e3342 ubuntu "/bin/bash" 24 seconds ago Exited (0) 18 seconds ago strange_rhodes
e5f7fe746293 ubuntu:latest "/bin/bash" 21 minutes ago Up 13 minutes sweet_napier
512f2d30b9e4 ubuntu "/bin/bash" 2 hours ago Exited (0) 21 minutes ago hardcore_hertz
当使用docker run来创建并使用容器时,docker在后台允许时的标准操作包括:
- 检查本地是否存在指定的镜像,不存在就从公有仓库下载;
- 利用镜像创建一个容器,并启动该容器;
- 分配一个文件系统给容器,并在只读的镜像层外面挂载一层可读写层;
- 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中;
- 从网桥的地址池配置一个IP地址给容器;
- 执行用户指定的应用程序;
- 执行完毕后被自动终止;
④:守护态允许
[root@node-1 ~]# docker run -d ubuntu /bin/sh -c "while true;do echo hello world;sleep 1;done"
8a1ec939c4f89a2f64ab26239d31d98fa9acd351b1c36f167e9fbd4e18a3e02a
[root@node-1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8a1ec939c4f8 ubuntu "/bin/sh -c 'while t…" 1 second ago Up 1 second heuristic_villani
⑤:查看容器输出
[root@node-1 ~]# docker logs 8a1ec939c4f8
hello world
hello world
hello world
hello world
hello world
hello world
hello world
4.2、停止容器
①:暂停容器
[root@node-1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8a1ec939c4f8 ubuntu "/bin/sh -c 'while t…" 4 minutes ago Up 4 minutes heuristic_villani
[root@node-1 ~]# docker pause heuristic_villani
heuristic_villani
[root@node-1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8a1ec939c4f8 ubuntu "/bin/sh -c 'while t…" 5 minutes ago Up 5 minutes (Paused) heuristic_villani
②:终止容器
[root@node-1 ~]# docker stop heuristic_villani
heuristic_villani
[root@node-1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8a1ec939c4f8 ubuntu "/bin/sh -c 'while t…" 6 minutes ago Exited (137) 3 seconds ago heuristic_villani
此时,执行docker container prune 命令会自动清除掉所有处于停止状态的容器。
4.3、进入容器
①:attach命令
[root@node-1 ~]# docker run -itd ubuntu
97878e88b4da910f4e87e2c7ee83beb96d220cd407c5fb5726170dcf5c530549[root@node-1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
97878e88b4da ubuntu "/bin/bash" 10 seconds ago Up 10 seconds thirsty_clarke[root@node-1 ~]# docker attach thirsty_clarke
root@97878e88b4da:/#
如果推出后台运行还要保持继续运行:Ctrl+p --->Ctrl+q
[root@node-1 ~]# docker attach nifty_agnesi
root@9746b20b9671:/# read escape sequence
[root@node-1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9746b20b9671 ubuntu "/bin/bash" 35 seconds ago Up 35 seconds nifty_agnesi
②:exec命令
从Docker的1.3.0版本起,Docker提供了一个更加方便的工具exec命令,可以在运行中容器内直接执行任意命令。
[root@node-1 ~]# docker exec -it 9746b20b9671 /bin/bash
root@9746b20b9671:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@9746b20b9671:/#
4.4、删除容器
[root@node-1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9746b20b9671 ubuntu "/bin/bash" 7 minutes ago Up 7 minutes nifty_agnesi
[root@node-1 ~]# docker rm 9746b20b9671
Error response from daemon: cannot remove container "/nifty_agnesi": container is running: stop the container before removing or force remove
[root@node-1 ~]# docker rm -f 9746b20b9671
9746b20b9671
默认情况下,docker rm命令只能删除已经处于终止或退出状态的容器,通过-f参数,Docker会先发送sigkill信号给容器,终止其中的应用,之后强行删除。
删除所有容器(不管什么状态):
docker rm -f `docker ps -aq`
4.5、容器的导入和导出
①:导出容器
[root@node-1 ~]# docker run -d --name aaa nginx
4dc24464d740ed8abe20e9d0d9c68553e980214ba51cab81b880897f1fc5b6af
[root@node-1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4dc24464d740 nginx "/docker-entrypoint.…" 25 seconds ago Up 24 secon ds 80/tcp aaa
[root@node-1 ~]# docker export -o aaa_run.tar aaa
[root@node-1 ~]# ls
aaa_run.tar anaconda-ks.cfg apache-tomcat-9.0.87.tar.gz jdk-8u261-linux-x64.rpm ubuntu_latest.tar
[root@node-1 ~]# scp aaa_run.tar 192.168.93.11:~
The authenticity of host '192.168.93.11 (192.168.93.11)' can't be established.
ED25519 key fingerprint is SHA256:J8bSbLpNzJAt5ag4xo6oX6nU5ZjP5TUTwrNFb9xJgO4.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.93.11' (ED25519) to the list of known hosts.Authorized users only. All activities may be monitored and reported.
root@192.168.93.11's password:
aaa_run.tar 100% 186MB 162.0MB/s 00:01
②:导入容器
[root@openEuler-2 ~]# ls
aaa_run.tar anaconda-ks.cfg docker docker-28.0.1.tgz ubuntu_latest.tar# 从本地导入
[root@openEuler-2 ~]# docker import aaa_run.tar test_nginx:1.0
sha256:5aaa3019dac0ee39f3550b47ef8c30df6cdbcb98fbd9357de07bfa0d871fab42[root@openEuler-2 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test_nginx 1.0 5aaa3019dac0 10 seconds ago 191MB# 从标准输入导入镜像
cat [] | docker import - []:[TAG]
实际上,即可以使用docker load 命令来导入一个容器快照到本地镜像库,也可以使用docker import 命令来导入一个容器快照到本地镜像库。这两者的区别在于:容器快照文件将丢弃所有的历史记录和元数据信息(仅保存容器当时的快照状态),而镜像存储文件将保存完整记录,体积更大。此外,从容器快照文件导入时可以重新指定标签等元数据信息。
4.6、查看容器
①:查看容器详情
[root@node-1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4dc24464d740 nginx "/docker-entrypoint.…" 14 minutes ago Up 13 minutes 80/tcp aaa
[root@node-1 ~]# docker container inspect aaa
[{"Id": "4dc24464d740ed8abe20e9d0d9c68553e980214ba51cab81b880897f1fc5b6af","Created": "2025-07-12T07:06:10.329858942Z","Path": "/docker-entrypoint.sh","Args": ["nginx","-g","daemon off;"],"State": {"Status": "running","Running": true,"Paused": false,"Restarting": false,"OOMKilled": false,"Dead": false,"Pid": 9674,"ExitCode": 0,"Error": "",
...
②:查看容器内进程
[root@node-1 ~]# docker top aaa
UID PID PPID C STIME TTY TIME CMD
root 9674 9654 0 15:06 ? 00:00:00 nginx: master process nginx -g daemon off;
101 9716 9674 0 15:06 ? 00:00:00 nginx: worker process
101 9717 9674 0 15:06 ? 00:00:00 nginx: worker process
③:查看统计信息
[root@node-1 ~]# docker stats aaa
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
4dc24464d740 aaa 0.00% 2.98MiB / 1.394GiB 0.21% 1.23kB / 0B 1.43MB / 16.4kB 3
支持选项包括:
- -a,-a11:输出所有容器统计信息,默认仅在运行中口
- -format string:格式化输出信息;-no-stream:不持续输出,默认会自动更新持续实时结果
- -no-trunc:不截断输出信息。
4.7、其他命令容器
①:复制文件-cp
示例:将本地路径data复制到test容器的/tmp路径下
docker [container] cp data test:/tmp/
②:查看变更-diff
示例:查看test容器内的数据修改
docker [container] diff test
③:查看端口映射-port
示例:查看test容器的端口映射情况
docker [container] port test
更新配置-update
示例:限制总配额为 1s
docker [container] port test
5、Docker的数据管理
5.1、数据卷
数据卷是一个可供容器使用的特殊目录,它将主机操作系统目录直接映射进容器,类似于Linux中的mount行为。
数据卷的特性:
- 数据卷可以在容器之间共享和重用,容器间传递数据将变得高效与方便;
- 对数据卷内数据的修改会立马生效,无论是容器内操作还是本地操作;
- 对数据卷的共享不会影响镜像,解耦开应用和数据;
- 卷会一直存在,直到没有容器使用,可以安全地卸载它。
①:创建数据卷
Docker提供了volume子命令来管理数据卷,如下命令可以快速在本地创建一个数据卷:
[root@node-1 ~]# docker volume create -d local test
test
[root@node-1 ~]# ll /var/lib/docker/volumes/
total 28
brw-------. 1 root root 253, 0 Jul 12 15:02 backingFsBlockDev
-rw-------. 1 root root 32768 Jul 12 17:17 metadata.db
drwx-----x. 3 root root 4096 Jul 12 17:17 test
除了create子命令外,docker volume还支持inspect(查看详细信息)、ls(列出已有数据卷)、prune(清理无用数据卷)、rm(删除数据卷)等。
②:绑定数据卷
除了使用volume子命令来管理数据卷外,还可以在创建容器时将主机本地的任意路径挂载到容器内作为数据卷,这种形式创建的数据卷称为绑定数据卷。
在使用docker [container] run命令的时候,可以使用-mount选项来使用数据卷。-mount选项支持三种类型的数据卷,包括:
- volume:普通数据卷,映射到主机/var/lib/docker/volumes路径下;
- bind:绑定数据卷,映射到主机指定路径下;
- tmpfs:临时数据卷,只存在内存中。
示例:使用nginx镜像创建一个web容器,并创建一个数据卷挂载到容器的/opt/webapp目录:
[root@node-1 webapp]# docker run -d -P --name web -v /webapp:/opt/webapp nginx:1.17.1
Unable to find image 'nginx:1.17.1' locally
1.17.1: Pulling from library/nginx
0a4690c5d889: Pull complete
9719afee3eb7: Pull complete
44446b456159: Pull complete
Digest: sha256:b4b9b3eee194703fc2fa8afa5b7510c77ae70cfba567af1376a573a967c03dbb
Status: Downloaded newer image for nginx:1.17.1
7e4015ec5f3510c9eb3db09f4ab5696f5d7ea511e40ebb0b4b274486c7fd3af1[root@node-1 ~]# docker port web
80/tcp -> 0.0.0.0:32768
80/tcp -> [::]:32768
5.2、数据卷容器
如果用户需要在多个容器之间共享一些持续更新的数据,最简单的方式是使用数据卷容器。数据卷容器也是一个容器,但是它的目的是专门提供数据卷给其它容器挂载。
首先,创建一个数据卷容器dbdata,并在其中创建一个数据卷挂载到/dbdata:
[root@node-1 ~]# docker run -it -v /dbdata --name dbdata ubuntu
root@22d941485bce:/#
然后,可以在其它容器中使用--volume-from来挂载dbdata容器中的数据卷,例如创建db1和db2两个容器,并从dbdata容器挂载数据卷。
[root@node-1 ~]# docker run -it --volumes-from dbdata --name db1 ubuntu
root@7b0d950b0920:/#
exit
[root@node-1 ~]# docker run -it --volumes-from dbdata --name db2 ubuntu
root@0fc204844243:/#
exit
此时容器db1和db2都挂载同一个数据卷到相同的/dbdata目录,三个容器任何一方在该目录下写入,其它容器都可以可见。
测试:
# 容器db1
root@7b0d950b0920:/# touch dbdata/test.txt
root@7b0d950b0920:/# ls# 容器db2
root@0fc204844243:/# ls dbdata
test.txt
5.3、使用数据卷容器来迁移数据
①:备份
[root@node-1 ~]# docker run --volumes-from dbdata -v $(pwd):/backup --name worker ubuntu tar cvf /backup.tar /dbdata
# 该命令利用ubuntu镜像创建了一个容器worker。
# 使用--volumes-from dbdata参数来让worker容器挂载dbdata容器的数据卷(即dbdata数据卷);
# 使用-v $(pwd):/backup 参数来挂载本地的当前目录到worker容器的/backup目录。
# worker容器启动后,使用tar cvf /backup/backup.tar /dbdata命令将/dbdata下内容备份为容器内的/backup/backu.tar,即宿主主机当前目录下的backup.tar
②:恢复
如果要恢复数据到一个容器,首先创建一个带有数据卷的容器dbdata2:
[root@node-1 ~]# docker run -v /dbdata --name dbdata2 ubuntu /bin/bash
任何创建一个新的容器,挂载dbdata2的容器,并使用untar解压备份文件到所挂载的容器据卷中:
[root@node-1 ~]# docker run --volumes-from dbdata2 -v $(pwd):/backup ubuntu tar xvf /backup/backup.tar
6、端口映射与容器互联
使用-P参数时,Docker会随机映射一个端口号到内部容器开放的网络端口
使用-p则可以指定要映射的端口,并且,在一个指定端口上只可以绑定一个容器。支持的格式有:
- IP:HostPort:ContainerPort
- IP::ContainerPort
- HostPort:ContainerPort
6.1、端口映射实现容器访问
①:从外部容器访问应用
[root@openEuler-1 web]# docker run --name web -d -P -v /root/web:/usr/share/nginx/html nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
3da95a905ed5: Pull complete
6c8e51cf0087: Pull complete
9bbbd7ee45b7: Pull complete
48670a58a68f: Pull complete
ce7132063a56: Pull complete
23e05839d684: Pull complete
ee95256df030: Pull complete
Digest: sha256:93230cd54060f497430c7a120e2347894846a81b6a5dd2110f7362c5423b4abc
Status: Downloaded newer image for nginx:latest
27590614f512f2fc362202c73b4e7de77a613d617b5d315ea7024e55e23899f9[root@openEuler-1 web]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
27590614f512 nginx "/docker-entrypoint.…" 11 seconds ago Up 10 seconds 0.0.0.0:32768->80/tcp, :::32768->80/tcp web[root@openEuler-1 web]# echo "web test page" > /root/web/index.html
[root@openEuler-1 web]# curl localhost:32768
web test page
②:映射所有接口地址
使用 HostPort:ContainerPort 格式本地的80端口映射到容器的80端口:
[root@openEuler-1 web]# docker run --name web1 -d -p 80:80 -v /root/web:/usr/share/nginx/html nginx
1a23dd018ae0c4297abe5edf37de0c72e9309456a675d23fc84e4d17d7aa31bd
[root@openEuler-1 web]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope hostvalid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000link/ether 00:0c:29:41:54:76 brd ff:ff:ff:ff:ff:ffinet 192.168.93.10/24 brd 192.168.93.255 scope global noprefixroute ens33valid_lft forever preferred_lft foreverinet6 fe80::20c:29ff:fe41:5476/64 scope link noprefixroutevalid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group defaultlink/ether 02:42:14:a8:21:ea brd ff:ff:ff:ff:ff:ffinet 172.17.0.1/16 brd 172.17.255.255 scope global docker0valid_lft forever preferred_lft foreverinet6 fe80::42:14ff:fea8:21ea/64 scope linkvalid_lft forever preferred_lft forever
5: veth68a521b@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group defaultlink/ether da:d8:66:db:ba:20 brd ff:ff:ff:ff:ff:ff link-netnsid 0inet6 fe80::d8d8:66ff:fedb:ba20/64 scope linkvalid_lft forever preferred_lft forever
9: veth654ddeb@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group defaultlink/ether e2:d7:00:53:d4:f5 brd ff:ff:ff:ff:ff:ff link-netnsid 1inet6 fe80::e0d7:ff:fe53:d4f5/64 scope link tentativevalid_lft forever preferred_lft forever
[root@openEuler-1 web]# curl localhost
web test page
[root@openEuler-1 web]# curl 172.17.0.1
web test page
③:映射到指定地址的指定端口
[root@openEuler-1 web]# docker run --name web2 -d -p 127.0.0.1:80:80 -v /root/web:/usr/share/nginx/html nginx
94fcffc4603a5cca7f417d1030ab00419a89e67606a5be3b3a9adca07ad99cde
[root@openEuler-1 web]# docker port web2
80/tcp -> 127.0.0.1:32769
[root@openEuler-1 web]# curl 127.0.0.1:32769
web test page
④:映射到指定地址的任意端口
[root@openEuler-1 web]# docker run --name web2 -d -p 127.0.0.1::80 -v /root/web:/usr/share/nginx/html nginx
94fcffc4603a5cca7f417d1030ab00419a89e67606a5be3b3a9adca07ad99cde
[root@openEuler-1 web]# docker port web2
80/tcp -> 127.0.0.1:32769
[root@openEuler-1 web]# curl 127.0.0.1:32769
web test page
⑤:查看映射端口的配置
docker port
6.2、互联机制实现便捷互访
容器的互联是一种让多个容器中的应用进行快速交互的方式。它会在源和接受容器之间创建连接关系,接收容器可以通过容器名快速访问到源容器,而不用指定具体IP地址。
①:自定义容器命名
[root@openEuler-1 web]# docker run --name db -e MYSQL_ROOT_PASSWORD=123456 -d --restart=always mysql:5.6
Unable to find image 'mysql:5.6' locally
5.6: Pulling from library/mysql
35b2232c987e: Pull complete
fc55c00e48f2: Pull complete
0030405130e3: Pull complete
e1fef7f6a8d1: Pull complete
1c76272398bb: Pull complete
f57e698171b6: Pull complete
f5b825b269c0: Pull complete
dcb0af686073: Pull complete
27bbfeb886d1: Pull complete
6f70cc868145: Pull complete
1f6637f4600d: Pull complete
Digest: sha256:20575ecebe6216036d25dab5903808211f1e9ba63dc7825ac20cb975e34cfcae
Status: Downloaded newer image for mysql:5.6
99196757c37b700711959c1ee16faf6c975326587b96a5c7f0fafbf27fe6b0c8[root@openEuler-1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
99196757c37b mysql:5.6 "docker-entrypoint.s…" 9 minutes ago Up 9 minutes 3306/tcp db
②:容器互联
使用 --link 参数可以让容器之间安全地进行交互
# 创建一个新的容器,将其连接到db容器
[root@openEuler-1 ~]# docker run --name bbs -p 80:80 --link db:mysql -d --restar t=always wordpress
Unable to find image 'wordpress:latest' locally
latest: Pulling from library/wordpress
3da95a905ed5: Already exists
57425fa1eb7f: Pull complete
f05433f0219e: Pull complete
1e8752612fda: Pull complete
b0c8e9ff96e5: Pull complete
ae79cd1ac319: Pull complete
777f99eef8ce: Pull complete
8d5c7dfff743: Pull complete
f49d3e862d34: Pull complete
a546e38c8200: Pull complete
6dada9a66036: Pull complete
bfb2326228ed: Pull complete
066a2c719815: Pull complete
31cf41e2130b: Pull complete
4f4fb700ef54: Pull complete
d0de172ccfe2: Pull complete
fadfb64342a3: Pull complete
82c2be5c794c: Pull complete
f3af99c56e91: Pull complete
20321817e819: Pull complete
92e3e8314ee0: Pull complete
de8961e3b876: Pull complete
edb797f65965: Pull complete
c9ddd3e916ac: Pull complete
Digest: sha256:9ca181730570f82df91e301d2e53efc0ce2f98aa8112d2f95ef780bd341ffd12
Status: Downloaded newer image for wordpress:latest
9cebd9ebf4808f3c6e63b87345a801d00fc18d1f6b159d66d5aa0ba71b0853c2# 进入bbs容器查看
[root@openEuler-1 ~]# docker exec -it bbs bash
root@9cebd9ebf480:/var/www/html# 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 mysql 99196757c37b db
172.17.0.3 9cebd9ebf480
Docker通过两种方式为容器公开连接信息:
- 更新环境变量
- 更新/etc/hosts文件
root@9cebd9ebf480:/var/www/html# env
MYSQL_PORT=tcp://172.17.0.2:3306
MYSQL_PORT_3306_TCP_ADDR=172.17.0.2
MYSQL_NAME=/bbs/mysql
MYSQL_ENV_MYSQL_ROOT_PASSWORD=123456
MYSQL_PORT_3306_TCP_PORT=3306
HOSTNAME=9cebd9ebf480
PHP_VERSION=8.2.29
APACHE_CONFDIR=/etc/apache2
PHP_INI_DIR=/usr/local/etc/php
GPG_KEYS=39B641343D8C104B2B146DC3F9C39DC0B9698544 E60913E4DF209907D8E30D96659A97C9CF2A795A 1198C0117593497A5EC5C199286AF1F9897469DC
MYSQL_ENV_MYSQL_MAJOR=5.6
PHP_LDFLAGS=-Wl,-O1 -pie
MYSQL_PORT_3306_TCP=tcp://172.17.0.2:3306
...
7、镜像仓库
7.1、Docker Hub (公有仓库)
Docker Hub官网:https://hub.docker.com/
目前 Docker 官方维护了一个公共仓库Docker Hub ,大部分需求都可以通过在 Docker Hub 中直接下载镜像来实现。
如果你觉得拉取 Docker Hub 的镜像比较慢的话,我们可以配置一个镜像加速器,当然国内大部分云厂商都提供了相应的加速器,简单配置即可。
注册:你可以在 https://cloud.docker.com 免费注册一个 Docker 账号。
登录:通过执行docker login 命令交互式的输入用户名及密码来完成在命令行界 面登录 Docker Hub。
注销:你可以通过docker logout 退出登录。
7.2、Registry (私有仓库)
公司服务器大部分都是私网,为了安全和方便可以搭建私有仓库,而不用完全手动的去导入导出镜像,因为是局域网拉取速度非常快,可以节省带宽和大量时间。
构建私有的镜像仓库的原由:
有时候使用 Docker Hub 这样的公共仓库可能不方便,用户可以创建一个本地仓库供私人使用。
docker-registry是官方提供的工具,可以用于构建私有的镜像仓库。
一般情况下,不论是通过commit容器得到的镜像,或者是用dockerfile 制作的镜像,如果需要将镜像保存,可以使用我们之前提到的导出导入命令(save -o ; load -i)。导出的包,然后再传给其他dockerHost,这种方法也是可行的。
但往往在公司会有大量的镜像,而且不仅仅是单台的dockerHost。我们迫切需要有一个本地的共用的仓库,来实现多台dockerHost直接拉取镜像而不用手动的将镜像传来传去,之前的DockerHub可以帮助我们解决这个问题,当然前提需要申请一个DockerHub的账号,创建一个仓库。但这种方法需要消耗我们的带宽,因为是通过网络传输,既然是网络传输,就需要消耗一定的时间。
Registry仓库,是通过一个容器给我们提供的服务,是比较简易的私有仓库,以后在企业中还会有功能更加完善的Harbor仓库。
registry是官方提供的工具,可以用于构建私有的镜像仓库。你可以通过获取官方 registry 镜像来运行。
创建基于registry的私有仓库
①:用docker容器运行registry私有仓库服务
docker pull registry
②:运行私有仓库服务
docker run -itd --name registry --restart=always -p 5000:5000 -v /registry:/var/lib/registry registry
③:镜像重命名(要上传的镜像名需要注明私仓的ip)
docker tag mysql:5.6 192.168.93.10:5000/mysql:5.6
④:修改/etc/docker/daemon.json文件
[root@openEuler-1 ~]# cat /etc/docker/daemon.json
{"insecure-registries":["192.168.93.10:5000"], # 添加内容"registry-mirrors": ["https://docker.m.daocloud.io","https://hub-mirror.c.163.com","https://mirror.baidubce.com","https://docker.nju.edu.cn"]
}
查看仓库有哪些镜像,示例:
curl -XGET http://192.168.8.10:5000/v2/_catalog
-X/–request 指定什么命令
-G/–get 以get的方式来发送数据
-E/–cert cert[:passwd] 客户端证书文件和密码 (SSL)
-T/–upload-file 上传文件
[root@openEuler-1 ~]# curl -XGET http://192.168.93.10:5000/v2/_catalog
{"repositories":["mysql"]}
7.3、基于harbor构建docker私有仓库
实验环境下均关闭防火墙和SELinux
①:安装docker和docker-compse
[root@Rocky-1 ~]# yum install docker-ce -y
[root@Rocky-1 ~]# curl -L https://mirrors.aliyun.com/docker-toolbox/linux/compose/1.21.2/docker-compose-Linux-x86_64 -o /usr/local/bin//docker-compose
[root@Rocky-1 ~]# systemctl enable --now docker.service# 可以再配置一个镜像加速,在第2小节
②:安装harbor安装包,可以在github上进行下载:Releases · goharbor/harbor
[root@Rocky-1 ~]# ls
anaconda-ks.cfg harbor-offline-installer-v2.8.4.tgz
[root@Rocky-1 ~]# tar xvf harbor-offline-installer-v2.8.4.tgz -C /usr/local/
[root@Rocky-1 ~]# cd /usr/local/harbor/
[root@Rocky-1 harbor]# ls
common.sh harbor.v2.8.4.tar.gz harbor.yml.tmpl install.sh LICENSE prepare# 将参考文件复制过来
[root@Rocky-1 harbor]# cp harbor.yml.tmpl harbor.yml# 主要修改hostname,这里我配置的hostname为www.huiliyi.com
# 并且将https相关配置先注释了
[root@Rocky-1 harbor]# vim harbor.yml# 检查
[root@Rocky-1 harbor]# ./prepare# 安装
[root@Rocky-1 harbor]# ./install.sh
③:访问及使用
浏览器访问:http://域名或IP
默认用户名和密码:admin/Harbor12345
7.4、访问docker仓库
①:使用另一台主机进行测试上传镜像
# 配置host解析
[root@openEuler-1 ~]# echo "192.168.93.20 www.huiliyi.com" >> /etc/hosts# 加速器添加仓库
[root@openEuler-1 ~]# cat /etc/docker/daemon.json
{"insecure-registries":["www.huiliyi.com"],"registry-mirrors": ["https://docker.m.daocloud.io","https://hub-mirror.c.163.com","https://mirror.baidubce.com","https://docker.nju.edu.cn"]
}# 重启服务
[root@openEuler-1 ~]# systemctl restart docker.service# 登录仓库
[root@openEuler-1 ~]# docker login -u admin -p Harbor12345 www.huiliyi.com# 给镜像打上标签并上传镜像
[root@openEuler-1 ~]# docker tag mysql:5.6 www.huiliyi.com/library/mysql:5.6
[root@openEuler-1 ~]# docker push www.huiliyi.com/library/mysql:5.6
The push refers to repository [www.huiliyi.com/library/mysql]
7137327a7221: Pushed
49a1ca1cd2b8: Pushed
7c5a5c1986b1: Pushed
eba393347f89: Pushed
2612088e90f6: Pushed
e3dce1c82d4e: Pushed
7ea96a4e341b: Pushed
4085e588967d: Pushed
d414fdead0b9: Pushed
2e1029557391: Pushed
2b83e5699838: Pushed
5.6: digest: sha256:897086d07d1efa876224b147397ea8d3147e61dd84dce963aace1d5e9dc2802d size: 2621
查看web页面:
拉取镜像,首先清空主机中的所有镜像:
[root@openEuler-1 ~]# docker rmi -f $(docker images -aq)
[root@openEuler-1 ~]# docker pull www.huiliyi.com/library/mysql:5.6Digest: sha256:897086d07d1efa876224b147397ea8d3147e61dd84dce963aace1d5e9dc2802d
Status: Downloaded newer image for www.huiliyi.com/library/mysql:5.6
www.huiliyi.com/library/mysql:5.6
[root@openEuler-1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
www.huiliyi.com/library/mysql 5.6 dd3b2a5dcb48 3 years ago 303MB
再次查看页面:
可以看到下载次数+1。
也可以在里面创建新的项目,设置管理员。
访问级别设置为公开时,上传镜像需要docker login登录,下载则不需要。
访问级别设置为私有时,上传、下载均需要docker login登录。