Docker基础入门

一、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镜像的rmprune子命令。

(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在后台允许时的标准操作包括:

  1. 检查本地是否存在指定的镜像,不存在就从公有仓库下载;
  2. 利用镜像创建一个容器,并启动该容器;
  3. 分配一个文件系统给容器,并在只读的镜像层外面挂载一层可读写层;
  4. 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中;
  5. 从网桥的地址池配置一个IP地址给容器;
  6. 执行用户指定的应用程序;
  7. 执行完毕后被自动终止;

(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. 数据卷可以在容器之间共享和重用,容器间传递数据将变得高效与方便;
  2. 对数据卷内数据的修改会立马生效,无论是容器内操作还是本地操作;
  3. 对数据卷的共享不会影响镜像,解耦开应用和数据;
  4. 卷会一直存在,直到没有容器使用,可以安全地卸载它。

(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选项支持三种类型的数据卷,包括:

  1. volume:普通数据卷,映射到主机/var/lib/docker/volumes路径下;
  2. bind:绑定数据卷,映射到主机指定路径下;
  3. 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通过两种方式为容器公开连接信息:

  1. 更新环境变量
  2. 更新/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登录。

相关推荐
桂月二二6 分钟前
云原生Serverless平台:无服务器计算的架构革命
云原生·架构·serverless
weixin_307779138 分钟前
Azure云生态系统详解:核心服务、混合架构与云原生概念
云原生·数据库架构·azure
DevSecOps选型指南10 分钟前
2025软件供应链安全案例︱证券行业云原生DevSecOps敏捷安全实践
安全·云原生·代码审计·开发安全·软件供应链安全厂商
精致懒洋洋2 小时前
安装Docker环境并实战应用Docker部署nginx服务(详细教程)
docker
矛取矛求2 小时前
Docker 实践与应用举例
docker
他不爱吃香菜2 小时前
HTTPS工作原理与安全机制详解(仅供参考)
运维·网络·信息与通信
cdut_suye3 小时前
全面剖析 Linux 进程管理与 PCB 机制
java·linux·运维·服务器·c++·人工智能·python
程序员的世界你不懂3 小时前
移动Android和IOS自动化中常见问题
android·运维·自动化
zzyh1234563 小时前
springcloudalibaba负载均衡组件
运维·负载均衡
桂月二二3 小时前
云原生容器编排:Kubernetes的架构演进与实践
云原生·架构·kubernetes