一、Docker核心概念
Docker 大部分的操作都围绕着它的三大核心概念:镜像 、容器 和仓库 。因此,准确把握
这三大核心概念对于掌握 Docker 技术尤为重要。
1、docker镜像
Docker 镜像类似于虚拟机镜像,可以将它理解为一个只读的模板。
例如,一个镜像可以包含一个基本的操作系统环境,里面仅安装了 Apache 应用程序(或
用户需要的其他软件) 可以把它称为一个 Apache 镜像。
镜像是创建 Docker 容器的基础。
通过版本管理和增量的文件系统, Docker 提供了一套十分简单的机制来创建和更新现有
的镜像,用户甚至可以从网上下载一个已经做好的应用镜像,并直接使用。
2、docker容器
Docker 容器类似于一个轻级的沙箱, Docker 利用容器来运行和隔离应用。
容器是从镜像创建的应用运行实例,它可以启动、开始、停止、删除,而这些容器都是
彼此相互隔离、互不可见的。
可以把容器看作一个简易版的 Linux 系统环境(包括 root 用户权限、进程空间、用户空
间和网络空间等)以及运行在其中的应用程序打包而成的盒子。
注意:镜像自身是只读的,容器从镜像启动的时候,会在镜像的最上层创建一个可写层。
3、docker仓库
Docker 仓库类似于代码仓库,是 Docker 集中存放镜像文件的场所。
目前,最大的公开仓库是官方提供的 Docker Hub ,其中存放着数量庞大的镜像供用户下
国内不少云服务提供商(如腾讯云 阿里云等)也提供了仓库的本地源,可以提供稳定
的国内访问。
当然,用户如果不希望公开分享自己的镜像文件, Docker 也支持用户在本地网络内创建
一个只能自己访问的私有仓库。
当用户创建了自己的镜像之后就可以使用 push 命令将它上传到指定的公有或者私有仓
这样用户下次在另外一台机器上使用该镜像时,只需要将其从仓库上 pull 来就可以了。
二、Docker安装配置
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
Client: Docker Engine - Community
Version: 26.1.3
API version: 1.45
Go version: go1.21.10
Git commit: b72abbb
Built: Thu May 16 08:34:39 2024
OS/Arch: linux/amd64
Context: default
Server: Docker Engine - Community
Engine:
Version: 26.1.3
API version: 1.45 (minimum version 1.24)
Go version: go1.21.10
Git commit: 8e96db1
Built: Thu May 16 08:33:34 2024
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.6.32
GitCommit: 8b3b7ca2e5ce38e8f31a34f35b2b68ceb8470d89
runc:
Version: 1.1.12
GitCommit: v1.1.12-0-g51d5e94
docker-init:
Version: 0.19.0
GitCommit: de40ad0
注意:
官方软件源默认启用了最新的软件,您可以通过编辑软件源的方式获取各个版本的软件包。例如官方并没有将测试版本的软件源置为可用,您可以通过以下方式开启。同理可以开启各种测试版本等。
vim /etc/yum.repos.d/docker-ce.repo
将[docker-ce-test]下方的enabled=0修改为enabled=1
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/
配置相关服务文件:
[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 Engine
StartLimitBurst=3
StartLimitInterval=60s
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity
> Documentation=https://docs.docker.com
Delegate=yes
KillMode=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
启动服务:
[root@openEuler-2 ~]# systemctl start docker.service
[root@openEuler-2 ~]# docker version
Client:
Version: 28.0.1
API version: 1.48
Go version: go1.23.6
Git commit: 068a01e
Built: Wed Feb 26 10:40:04 2025
OS/Arch: linux/amd64
Context: default
Server: Docker Engine - Community
Engine:
Version: 28.0.1
API version: 1.48 (minimum version 1.24)
Go version: go1.23.6
Git commit: bbd0a17
Built: Wed Feb 26 10:41:19 2025
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: v1.7.25
GitCommit: bcc810d6b9066471b0b6fa75f557a15a1cbf31bb
runc:
Version: 1.2.5
GitCommit: v1.2.5-0-g59923ef
docker-init:
Version: 0.19.0
GitCommit: de40ad0
3、配置镜像加速器
# 供参考
[root@openEuler-1 ~]# tee /etc/docker/daemon.json <<EOF
> {
> "registry-mirrors": [
> "https://docker.m.daocloud.io",
> "https://hub-mirror.c.163.com",
> "https://mirror.baidubce.com",
> "https://docker.nju.edu.cn"
> ]
> }
> EOF
可以加速我们拉取镜像:
[root@openEuler-1 ~]# systemctl restart docker.service
[root@openEuler-1 ~]# docker pull busybox
Using default tag: latest
latest: Pulling from library/busybox
9c0abc9c5bd3: Pull complete
Digest: sha256:498a000f370d8c37927118ed80afe8adc38d1edcbfc071627d17b25c88efcab0
Status: Downloaded newer image for busybox:latest
docker.io/library/busybox:latest
[root@openEuler-1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox latest 31311c5853a2 5 months ago 4.27MB
三、使用Docker镜像
1、拉取镜像
命令:
docker [image] pull NAME[:TAG]
# 其中name是镜像仓库名称,tag是镜像的标签(一般用于表示版本信息),若不加tag默认拉取latest版本
示例:
[root@openEuler-1 ~]# 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-1 ~]# docker pull ubuntu
Using default tag: latest
latest: Pulling from library/ubuntu
5a7813e071bf: Pull complete
Digest: sha256:72297848456d5d37d1262630108ab308d3e9ec7ed1c3286a32fe09856619a782
Status: Downloaded newer image for ubuntu:latest
docker.io/library/ubuntu:latest
2、查看镜像信息
(1)images 命令列出镜像
命令:
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
(2)tag 命令添加镜像标签
命令:
docker tag
示例:
[root@openEuler-1 ~]# docker tag ubuntu:latest myubuntu:new
[root@openEuler-1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myubuntu new a04dc4851cbc 5 weeks ago 78.1MB
ubuntu latest a04dc4851cbc 5 weeks ago 78.1MB
ubuntu 18.04 f9a80a55f492 21 months ago 63.2MB
可以看到 myubuntu 和 ubuntu 的镜像ID一致,说明他俩指向的是同一个镜像文件。
(3)inspect 命令查看详细信息
命令:
docker inspect
示例:
[root@openEuler-1 ~]# docker inspect ubuntu:latest
[
{
"Id": "sha256:a04dc4851cbcbb42b54d1f52a41f5f9eca6a5fd03748c3f6eb2cbeb238ca99bd",
"RepoTags": [
"ubuntu:latest"
],
"RepoDigests": [
"ubuntu@sha256:72297848456d5d37d1262630108ab308d3e9ec7ed1c3286a32fe09856619a782"
],
"Parent": "",
"Comment": "",
...
上面的代码是一个JSON格式的信息,若我们只要其中一项内容时,可以使用 -f 来指定:
[root@openEuler-1 ~]# docker inspect -f {{".Architecture"}} ubuntu:latest
amd64
(4)history 命令查看镜像历史
示例:查看 ubuntu:latest 镜像的创建过程
[root@openEuler-1 ~]# docker history ubuntu:latest
IMAGE CREATED CREATED BY SIZE COMMENT
a04dc4851cbc 5 weeks ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 5 weeks ago /bin/sh -c #(nop) ADD file:6df775300d76441aa... 78.1MB
<missing> 5 weeks ago /bin/sh -c #(nop) LABEL org.opencontainers.... 0B
<missing> 5 weeks ago /bin/sh -c #(nop) LABEL org.opencontainers.... 0B
<missing> 5 weeks ago /bin/sh -c #(nop) ARG LAUNCHPAD_BUILD_ARCH 0B
<missing> 5 weeks ago /bin/sh -c #(nop) ARG RELEASE 0B
3、搜寻镜像
命令:
docker search [option] keyword
用于搜索Docker Hub官方仓库中的镜像。
4、删除和清理镜像
主要使用Docker镜像的rm 和prune子命令。
(1)使用标签删除镜像
命令:
docker rmi
或
docker image rm
示例:
[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 rmi ubuntu:latest
Untagged: ubuntu:latest
Untagged: ubuntu@sha256:72297848456d5d37d1262630108ab308d3e9ec7ed1c3286a32fe09856619a782
Deleted: sha256:a04dc4851cbcbb42b54d1f52a41f5f9eca6a5fd03748c3f6eb2cbeb238ca99bd
Deleted: sha256:4b7c01ed0534d4f9be9cf97d068da1598c6c20b26cb6134fad066defdb6d541d
[root@openEuler-1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 18.04 f9a80a55f492 21 months ago 63.2MB
(2)使用ID删除镜像
示例:
[root@openEuler-1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 18.04 f9a80a55f492 21 months ago 63.2MB
[root@openEuler-1 ~]# docker rmi f9a80a55f492
Untagged: ubuntu:18.04
Untagged: ubuntu@sha256:152dc042452c496007f07ca9127571cb9c29697f42acbfad72324b2bb2e43c98
Deleted: sha256:f9a80a55f492e823bf5d51f1bd5f87ea3eed1cb31788686aa99a2fb61a27af6a
Deleted: sha256:548a79621a426b4eb077c926eabac5a8620c454fb230640253e1b44dc7dd7562
[root@openEuler-1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
(3)清理镜像
命令:
docker image prune
# -a 删除所有无用镜像,不光是临时镜像
# -f 强制删除,不需要确认
# -filter 只删除给定过滤器的镜像
示例:
[root@openEuler-1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest b52e0b094bc0 4 weeks ago 192MB
ubuntu latest a04dc4851cbc 5 weeks ago 78.1MB
ubuntu 18.04 f9a80a55f492 21 months ago 63.2MB
[root@openEuler-1 ~]# 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: nginx:latest
untagged: nginx@sha256:9d6b58feebd2dbd3c56ab5853333d627cc6e281011cfd6050fa4bcf2072c9496
deleted: sha256:b52e0b094bc0e26c9eddc9e4ab7a64ce0033c3360d8b7ad4ff4132c4e03e8f7b
deleted: sha256:3c8b88c16794e3082397557e5482f5a04a6c295cec37919c65c234e1a3645e80
deleted: sha256:d5c83383666c732fcb30d7e25c74c2e0884c262f2e497cc9f2844870980311d8
deleted: sha256:d62b6301e685a7cdc3bb3b1508a959e4710a707ea2f680f848c19a9ad74ac6a7
deleted: sha256:d443654bda4a04f31ba6bd39bed82a053a17f2974b401fef552e4e88d6546db8
deleted: sha256:129409d5d363e5d5af273f0b2a90237f708ed9972f8d58a4dbcd17f1abbabe21
deleted: sha256:a3a2912e392a24d8c7dde076a3778c6eded8839660963ac2084e051eb6931c13
deleted: sha256:5f1ee22ffb5e68686db3dcb6584eb1c73b5570615b0f14fabb070b96117e351d
untagged: ubuntu:18.04
untagged: ubuntu@sha256:152dc042452c496007f07ca9127571cb9c29697f42acbfad72324b2bb2e43c98
deleted: sha256:f9a80a55f492e823bf5d51f1bd5f87ea3eed1cb31788686aa99a2fb61a27af6a
deleted: sha256:548a79621a426b4eb077c926eabac5a8620c454fb230640253e1b44dc7dd7562
untagged: ubuntu:latest
untagged: ubuntu@sha256:72297848456d5d37d1262630108ab308d3e9ec7ed1c3286a32fe09856619a782
deleted: sha256:a04dc4851cbcbb42b54d1f52a41f5f9eca6a5fd03748c3f6eb2cbeb238ca99bd
deleted: sha256:4b7c01ed0534d4f9be9cf97d068da1598c6c20b26cb6134fad066defdb6d541d
Total reclaimed space: 333.3MB
[root@openEuler-1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
5、存出和载入镜像
(1)存出镜像
[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.121.12:~
(2)载入镜像
# 来自主机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也是一致
6、上传镜像
命令:
docker [images] push NAME[:TAG]
四、操作Docker容器
1、创建容器
(1)新建容器
[root@openEuler-1 ~]# docker create -it ubuntu:latest
1e13caf317353f1c70e554368aadb7148d62a62f74ea0e2d4aec283d0f857c28
[root@openEuler-1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1e13caf31735 ubuntu:latest "/bin/bash" 6 seconds ago Created naughty_curran
(2)启动容器
[root@openEuler-1 ~]# docker start naughty_curran
naughty_curran
[root@openEuler-1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1e13caf31735 ubuntu:latest "/bin/bash" 4 minutes ago Up 9 seconds naughty_curran
# 注意:docker start 后跟的是容器名称,在创建容器时通过--name来定义,否则自动生成名称
(3)新建并启动容器
[root@openEuler-1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest b52e0b094bc0 4 weeks ago 192MB
ubuntu latest a04dc4851cbc 5 weeks ago 78.1MB
[root@openEuler-1 ~]# docker run -it ubuntu '/bin/bash'
root@739f5b01a99b:/#
exit
[root@openEuler-1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
739f5b01a99b ubuntu "/bin/bash" 8 seconds ago Exited (0) 6 seconds ago dazzling_shamir
当使用docker run来创建并使用容器时,docker在后台允许时的标准操作包括:
- 检查本地是否存在指定的镜像,不存在就从公有仓库下载;
- 利用镜像创建一个容器,并启动该容器;
- 分配一个文件系统给容器,并在只读的镜像层外面挂载一层可读写层;
- 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中;
- 从网桥的地址池配置一个IP地址给容器;
- 执行用户指定的应用程序;
- 执行完毕后被自动终止;
(4)守护态允许
# 使用-d参数,后台运行
[root@openEuler-1 ~]# docker run -d ubuntu /bin/sh -c "while true;do echo hello world;sleep 1;done"
69dd4a94ab43385abf94f4dff63ec553be20ed7ab06ab0286ab6f1cdfac75ad8
[root@openEuler-1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
69dd4a94ab43 ubuntu "/bin/sh -c 'while t..." 18 seconds ago Up 17 seconds thirsty_noether
[root@openEuler-1 ~]#
(5)查看容器输出
[root@openEuler-1 ~]# docker logs 69dd4a94ab43
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
...
2、停止容器
(1)暂停容器
[root@openEuler-1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
69dd4a94ab43 ubuntu "/bin/sh -c 'while t..." 3 minutes ago Up 3 minutes thirsty_noether
[root@openEuler-1 ~]# docker pause thirsty_noether
thirsty_noether
[root@openEuler-1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
69dd4a94ab43 ubuntu "/bin/sh -c 'while t..." 4 minutes ago Up 4 minutes (Paused) thirsty_noether
(2)终止容器
[root@openEuler-1 ~]# docker stop thirsty_noether
thirsty_noether
[root@openEuler-1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
69dd4a94ab43 ubuntu "/bin/sh -c 'while t..." 5 minutes ago Exited (137) 13 seconds ago thirsty_noether
此时,执行docker container prune 命令会自动清除掉所有处于停止状态的容器。
3、进入容器
(1)attach命令
[root@openEuler-1 ~]# docker run -itd ubuntu
b2f0e4ffad5cc026598cf46b82ca20eee5c36683d70c2de6252d82ee60c68bd2
[root@openEuler-1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b2f0e4ffad5c ubuntu "/bin/bash" 3 seconds ago Up 2 seconds pensive_bassi
[root@openEuler-1 ~]# docker attach pensive_bassi
root@b2f0e4ffad5c:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@b2f0e4ffad5c:/#
exit
(2)exec命令
从Docker的1.3.0版本起,Docker提供了一个更加方便的工具exec命令,可以在运行中容器内直接执行任意命令。
[root@openEuler-1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f1de97b5cd5e ubuntu "/bin/bash" 14 seconds ago Up 13 seconds stoic_hugle
[root@openEuler-1 ~]# docker exec -it f1de97b5cd5e /bin/bash
root@f1de97b5cd5e:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
4、删除容器
[root@openEuler-1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f1de97b5cd5e ubuntu "/bin/bash" 2 minutes ago Up 2 minutes stoic_hugle
[root@openEuler-1 ~]# docker rm f1de97b5cd5e
Error response from daemon: cannot remove container "/stoic_hugle": container is running: stop the container before removing or force remove
[root@openEuler-1 ~]# docker rm -f f1de97b5cd5e
f1de97b5cd5e
[root@openEuler-1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
默认情况下,docker rn命令只能删除已经处于终止或退出状态的容器,通过-f参数,Docker会先发送sigkill信号给容器,终止其中的应用,之后强行删除。
删除所有容器(不管什么状态):
docker rm -f `docker ps -aq`
5、导入和导出容器
(1)导出容器
# 创建容器
[root@openEuler-1 ~]# docker run --name web -itd nginx
f7e452e122bf3651803be40052a90ac59b20b2aa4fd2ad75e08cae5b31286bcf
[root@openEuler-1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f7e452e122bf nginx "/docker-entrypoint...." 7 seconds ago Up 6 seconds 80/tcp web
# 导出容器
[root@openEuler-1 ~]# docker export -o web_run.tar web
[root@openEuler-1 ~]# ls
anaconda-ks.cfg web_run.tar
# 复制给主机2
[root@openEuler-1 ~]# scp web_run.tar 192.168.121.12:~
(2)导入容器
[root@openEuler-2 ~]# ls
anaconda-ks.cfg web_run.tar
[root@openEuler-2 ~]# docker import web_run.tar test/nginx:v1.0
sha256:752b509bcc8204ba4eaf87fa22d1bc4c709a6a5016f95a0214460cfbe383d90c
[root@openEuler-2 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@openEuler-2 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test/nginx v1.0 752b509bcc82 15 seconds ago 190MB
实际上,即可以使用docker load 命令来导入一个容器快照到本地镜像库,也可以使用docker import 命令来导入一个容器快照到本地镜像库。这两者的区别在于:容器快照文件将丢弃所有的历史记录和元数据信息(仅保存容器当时的快照状态),而镜像存储文件将保存完整记录,体积更大。此外,从容器快照文件导入时可以重新指定标签等元数据信息。
6、查看容器
(1)查看容器详情
[root@openEuler-1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f7e452e122bf nginx "/docker-entrypoint...." 12 minutes ago Up 12 minutes 80/tcp web
[root@openEuler-1 ~]# docker container inspect web
[
{
"Id": "f7e452e122bf3651803be40052a90ac59b20b2aa4fd2ad75e08cae5b31286bcf",
"Created": "2025-03-08T11:34:14.241873229Z",
"Path": "/docker-entrypoint.sh",
"Args": [
"nginx",
"-g",
"daemon off;"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
...
(2)查看容器内进程
[root@openEuler-1 ~]# docker top web
UID PID PPID C STIME TTY TIME CMD
root 5908 5888 0 19:34 ? 00:00:00 nginx: master process nginx -g daemon off;
101 5950 5908 0 19:34 ? 00:00:00 nginx: worker process
101 5951 5908 0 19:34 ? 00:00:00 nginx: worker process
(3)查看统计信息
[root@openEuler-1 ~]# docker stats web
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
f7e452e122bf web 0.00% 2.387MiB / 1.394GiB 0.17% 1.23kB / 0B 0B / 16.4kB 3
7、其它容器命令
(1)复制文件-cp
示例:将本地路径data复制到test容器的/tmp路径下
docker [container] cp data test:/tmp/
(2)查看变更-diff
示例:查看test容器内的数据修改
docker [container] diff test
(3)查看端口映射-port
示例:查看test容器的端口映射情况
docker [container] port test
(4)更新配置-update
示例:限制总配额为 1s
docker update --cpu-quota 1000000 test
五、Docker数据管理
1、数据卷
数据卷是一个可供容器使用的特殊目录,它将主机操作系统目录直接映射进容器,类似于Linux中的mount行为。
数据卷的特性:
- 数据卷可以在容器之间共享和重用,容器间传递数据将变得高效与方便;
- 对数据卷内数据的修改会立马生效,无论是容器内操作还是本地操作;
- 对数据卷的共享不会影响镜像,解耦开应用和数据;
- 卷会一直存在,直到没有容器使用,可以安全地卸载它。
(1)创建数据卷
Docker提供了volume子命令来管理数据卷,如下命令可以快速在本地创建一个数据卷:
[root@openEuler-1 ~]# docker volume create -d local test
test
# 查看/var/lib/docker/volumes 路径下,会发现所创建的数据卷的位置
[root@openEuler-1 ~]# ll /var/lib/docker/volumes/
drwx-----x 3 root root 4096 Mar 8 20:16 test
出来create子命令外,docker volume还支持inspect(查看详细信息)、ls(列出已有数据卷)、prune(清理无用数据卷)、rm(删除数据卷)等。
(2)绑定数据卷
除了使用volume子命令来管理数据卷外,还可以在创建容器时将主机本地的任意路径挂载到容器内作为数据卷,这种形式创建的数据卷称为绑定数据卷。
在使用docker [container] run命令的时候,可以使用-mount选项来使用数据卷。-mount选项支持三种类型的数据卷,包括:
- volume:普通数据卷,映射到主机/var/lib/docker/volumes路径下;
- bind:绑定数据卷,映射到主机指定路径下;
- tmpfs:临时数据卷,只存在内存中。
示例:使用nginx镜像创建一个web容器,并创建一个数据卷挂载到容器的/opt/webapp目录:
[root@openEuler-1 ~]# docker run -d -P --name web -v /webapp:/opt/webapp nginx
0a5630ef7b350d9a418ffa41472378e78aedf8a317cf6df5a45282c4cbfa076c
# -P 随机端口映射
[root@openEuler-1 ~]# docker port web
80/tcp -> 0.0.0.0:32768
80/tcp -> [::]:32768
2、数据卷容器
如果用户需要在多个容器之间共享一些持续更新的数据,最简单的方式是使用数据卷容器。数据卷容器也是一个容器,但是它的目的是专门提供数据卷给其它容器挂载。
首先,创建一个数据卷容器dbdata,并在其中创建一个数据卷挂载到/dbdata:
[root@openEuler-1 ~]# docker run -it -v /dbdata --name dbdata ubuntu
root@20815dabc4c0:/#
然后,可以在其它容器中使用--volume-from来挂载dbdata容器中的数据卷,例如创建db1和db2两个容器,并从dbdata容器挂载数据卷。
[root@openEuler-1 ~]# docker run -it --volumes-from dbdata --name db1 ubuntu
root@d4e4d052642a:/#
[root@openEuler-1 ~]# docker run -it --volumes-from dbdata --name db2 ubuntu
root@d4e4d052642a:/#
此时容器db1和db2都挂载同一个数据卷到相同的/dbdata目录,三个容器任何一方在该目录下写入,其它容器都可以可见。
测试:
# 容器dbdata:
root@20815dabc4c0:/# touch dbdata/test.txt
# 容器db1:
root@d4e4d052642a:/# ls /dbdata
test.txt
如果删除了挂载的容器(包括dbdata、db1和db2),数据卷并不会自动删除。如果要删除一个数据卷,必须在删除最后一个还挂载着它的容器时,显式使用docker rm -v命令来指定同时删除关联的容器。
3、使用数据卷容器来迁移数据
(1)备份
[root@openEuler-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
(2)恢复
如果要恢复数据到一个容器,首先创建一个带有数据卷的容器dbdata2:
[root@openEuler-1 ~]# docker run -v /dbdata --name dbdata2 ubuntu /bin/bash
任何创建一个新的容器,挂载dbdata2的容器,并使用untar解压备份文件到所挂载的容器据卷中:
[root@openEuler-1 ~]# docker run --volumes-from dbdata2 -v $(pwd):/backup ubuntu tar xvf /backup/backup.tar
六、端口映射与容器互联
使用-P参数时,Docker会随机映射一个端口号到内部容器开放的网络端口
使用-p则可以指定要映射的端口,并且,在一个指定端口上只可以绑定一个容器。支持的格式有:
- IP:HostPort:ContainerPort
- IP::ContainerPort
- HostPort:ContainerPort
1、端口映射实现容器访问
[root@openEuler-1 ~]# docker run --name web -d -P -v /web:/usr/share/nginx/html nginx
d90f6282e6483bba0f2b2b4c2361f215cbb76881f084700aac8e802379bf2ba5
[root@openEuler-1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d90f6282e648 nginx "/docker-entrypoint...." 21 seconds ago Up 21 seconds 0.0.0.0:32771->80/tcp, :::32771->80/tcp web
[root@openEuler-1 ~]# echo "web test page" > /web/index.html
[root@openEuler-1 ~]# curl localhost:32771
web test page
(2)映射所有接口地址
使用 HostPort:ContainerPort 格式本地的80端口映射到容器的80端口:
[root@openEuler-1 ~]# docker run --name web1 -d -p 80:80 -v /web:/usr/share/nginx/html nginx
2815a5b303ffd327207987d143d1379a3164958c7fa95e1ed1cc152872634cc0
[root@openEuler-1 ~]# curl localhost
web test page
(3)映射到指定地址的指定端口
使用 IP:HostPort:ContainerPort 格式本地ip127.0.0.1的80端口映射到容器的80端口:
[root@openEuler-1 ~]# docker run --name web1 -d -p 127.0.0.1:80:80 -v /web:/usr/share/nginx/html nginx
b7609be970dacd7038c658de556bab69d584798f5905f15253de8fb318e8c75b
[root@openEuler-1 ~]# curl 127.0.0.1
web test page
(4)映射到指定地址的任意端口
使用 IP::ContainerPort 格式本地ip127.0.0.1的任意端口映射到容器的80端口:
[root@openEuler-1 ~]# docker run --name web1 -d -p 127.0.0.1::80 -v /web:/usr/share/nginx/html nginx
285615fedc0742e3a6598b06872133923fa66fd95c6f7dfe072a344a1a73899f
[root@openEuler-1 ~]# docker port web1
80/tcp -> 127.0.0.1:32768
[root@openEuler-1 ~]# curl 127.0.0.1:32768
web test page
(5)查看映射端口配置
命令:
docker port
2、互联机制实现便捷互访
容器的互联是一种让多个容器中的应用进行快速交互的方式。它会在源和接受容器之间创建连接关系,接收容器可以通过容器名快速访问到源容器,而不用指定具体IP地址。
(1)自定义容器命名
使用 --name 标记可以为容器自定义命名:
[root@openEuler-1 ~]# docker run -d -P --name web nginx
4b2a273ef4ae777ada5b29c00d86ec2156c041876d6234f3072f38af4a6b9414
[root@openEuler-1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4b2a273ef4ae nginx "/docker-entrypoint...." 5 seconds ago Up 4 seconds 0.0.0.0:32773->80/tcp, :::32773->80/tcp web
(2)容器互联
使用 --link 参数可以让容器之间安全地进行交互:
# 首先创建一个新的数据库容器
[root@openEuler-1 ~]# docker run -d --name db -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
4363b2b8bc6613c418df1bf15dbf5da7143785d62c966b48d963be909cf73610
# 任何创建一个新的web容器,将其连接到db容器
[root@openEuler-1 ~]# docker run -d -P --name web --link db:web_db nginx
c3dd58e28c90377e87eb0327f6a5f3cab95d06eae34a07e160a38ce3b7244849
# 进入web容器查看
[root@openEuler-1 ~]# docker exec -it web bash
root@c3dd58e28c90:/# 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 web_db 4363b2b8bc66 db
172.17.0.3 c3dd58e28c90
Docker通过两种方式为容器公开连接信息:
- 更新环境变量
- 更新/etc/hosts文件
使用env命令来查看web容器的环境变量:
root@c3dd58e28c90:/# env
WEB_DB_PORT_33060_TCP_PROTO=tcp
HOSTNAME=c3dd58e28c90
WEB_DB_PORT_33060_TCP_ADDR=172.17.0.2
PWD=/
PKG_RELEASE=1~bookworm
HOME=/root
WEB_DB_PORT_3306_TCP_ADDR=172.17.0.2
DYNPKG_RELEASE=1~bookworm
WEB_DB_PORT=tcp://172.17.0.2:3306
NJS_VERSION=0.8.9
WEB_DB_PORT_3306_TCP=tcp://172.17.0.2:3306
TERM=xterm
WEB_DB_ENV_MYSQL_ROOT_PASSWORD=123456
SHLVL=1
...
其中WEB_DB_开头的环境变量是供web容器连接db容器使用,前缀采用大写的连接别名。
除了环境变量,Docker还添加host信息到父容器的/etc/hosts的文件下,在上面演示过。
七、基于harbor构建docker私有仓库
1、搭建docker仓库
实验环境下均关闭防火墙和SELinux。
(1)安装docker和docker-compse
这里只需要安装最新版docker-ce,docker-compose为依赖包自动安装。
[root@Rocky-1 ~]# yum install docker-ce -y
[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.openlab.com
# 并且将https相关配置先注释了
[root@Rocky-1 harbor]# vim harbor.yml
# 检查
[root@Rocky-1 harbor]# ./prepare
# 安装
[root@Rocky-1 harbor]# ./install.sh
(3)访问及使用
浏览器访问:http://域名或IP
默认用户名和密码:admin/HarBor12345

2、访问docker仓库
使用另一台主机进行测试。
上传镜像:
# 配置hosts解析
[root@openEuler-1 ~]# echo "192.168.121.51 www.openlab.com" >> /etc/hosts
# 加速器中添加仓库
[root@openEuler-1 ~]# vim /etc/docker/daemon.json
[root@openEuler-1 ~]# cat /etc/docker/daemon.json
{
"insecure-registries": ["www.openlab.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.openlab.com
# 给镜像打上标签并上传镜像
[root@openEuler-1 ~]# docker tag mysql:5.7 www.openlab.com/library/mysql:5.7
[root@openEuler-1 ~]# docker push www.openlab.com/library/mysql:5.7
查看web页面:

拉取镜像:
首先清空主机中的所有镜像:
[root@openEuler-1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
[root@openEuler-1 ~]# docker pull www.openlab.com/library/mysql:5.7
[root@openEuler-1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
www.openlab.com/library/mysql 5.7 5107333e08a8 15 months ago 501MB
再次查看页面:

可以看到下载次数+1。
也可以在里面创建新的项目,设置管理员。
访问级别设置为公开时,上传镜像需要docker login登录,下载则不需要。
访问级别设置为私有时,上传、下载均需要docker login登录。