Docker 教程

Docker 入门到放弃

Docker的优势

Docker 的优势: Docker 的优势就是体积小, 开源免费, 运行速度快.

Docker和虚拟机的区别

1. Docker 启动属于秒级别的。  虚拟机启动通常需要几分钟
2. 性能损耗不同,Docker 需要的资源更少
3. 隔离性不同,Docker 属于进程之间隔离,隔离性比较弱, 而虚拟机则是系统隔离。

Docker容器生命周期

Docker 容器生命周期

DockerCentos安装

yum update
uname -r
yum remove -y docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine
yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-selinux \
                  docker-engine-selinux \
                  docker-engine \
                  docker-ce

sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-selinux docker-engine-selinux docker-engine

sudo yum install -y yum-utils device-mapper-persistent-data lvm2
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum list docker-ce --showduplicates | sort -r
sudo yum install docker-ce-17.12.0.ce
systemctl start docker
systemctl status docker

Docker常用命令

docker info 				# 查看 docker 的系统信息,包括镜像和容器的数量
docker version  			# 查看 docker 的版本信息
docker [COMMAND] --help		# 帮助命令
例如:
docker exec --help 

Docker镜像命令

// 查看镜像

// 查看镜像

docker images

// pull 下载镜像

// 下载镜像

docker pull 

// 案例: 下载一个 Mysql5.7 的镜像

docker pull mysql:5.7

[root@localhost ~]# docker pull mysql:5.7           // 如果不写:5.7 就是下载的最新的版本

5.7: Pulling from library/mysql  
70e9ff4420fb: Pull complete                         // 分层下载 images 核心
7ca4383b183f: Pull complete 
3e282e7651b1: Pull complete 
1ffa0e0ca707: Pull complete 
6eb790cf6382: Pull complete 
b4b277ff2929: Pull complete 
692fe4469429: Pull complete 
c0d447d97bbd: Pull complete 
99ee594517ba: Pull complete 
a9ae52de4d77: Pull complete 
66cc05a182b5: Pull complete 
Digest: sha256:2c23f254c6b9444ecda9ba36051a9800e8934a2f5828ecc8730531db8142af83 // 签名
Status: Downloaded newer image for mysql:5.7									

// 查看所有的镜像

// 查看所有的镜像

docker images -a

// 镜像名称         // 镜像标签           // 镜像 ID          // 创建时间           // 镜像大小

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

mysql               5.7                 92034fe9a41f        8 days ago          581MB

// images 查看镜像 ID

// 查看镜像 ID

docker images -q

// search 搜索镜像

// 搜索镜像

docker search

// 搜索 Nginx 的镜像

docker search nginx

// 搜索 stars 大于 300 的镜像

docker search nginx --filter=STARS=300

// rmi -f 删除镜像

// 删除镜像

docker rmi -f

// 删除指定的镜像

docker rmi -f <IMAGE ID>

// 删除多个镜像

docker rmi -f <IMAGE ID> <IMAGE ID> <IMAGE ID>

// 删除所有的镜像

docker rmi -f $(docker ps -aq)

// tag 标记本地镜像

docker tag <镜像ID> 新镜像名:版本号

// save 保存镜像

docker save -o 保存镜像名称.tar <镜像ID>

// load 加载镜像

docker load -i 保存镜像名称.tar

// events

从服务器获取实时事件

Docker容器命令

注意

注意: 先了有镜像 -- 才能创建容器

** pull 下载镜像

docker pull centos

** run 创建容器

docker run -i -t <IMAGE ID> /bin/bash

- **-i**: 交互式操作。
- **-t**: 终端。
- **<IMAGE ID>**: centos 镜像。
- **/bin/bash**:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 /bin/bash。

退出交互方式:

第一种方案: 输入 exit

第二种方案: ctrl + d

第三种方案: ctrl + p + q  # 注意, 这样退出之后容器并不会停止

** create 创建容器

docker create --name test_nginx nginx
> `docker create`和`docker run`是Docker命令中的两个不同的操作方式,它们用于在Docker中创建和运行容器。它们的主要区别如下:
>
> 1. **创建与启动:**
>    - `docker create`:此命令用于创建一个新的容器,但并不会立即启动它。它会返回一个容器的唯一ID。
>    - `docker run`:此命令用于创建并启动一个新的容器。它会在后台创建容器,并立即启动它。
> 2. **交互性:**
>    - `docker create`:创建容器后,需要使用`docker start`命令单独启动容器,并可使用`docker attach`命令进入容器的交互式会话。
>    - `docker run`:创建并启动容器后,可以立即进入容器的交互式会话。
> 3. **命令简化:**
>    - `docker create`:通常需要使用多个命令来配置容器并启动它,例如设置端口映射、网络等。
>    - `docker run`:可以在同一命令中设置容器的配置和启动参数,使整个过程更简单。
>
> 综上所述,`docker create`主要用于创建容器,而`docker run`用于创建并立即启动容器。使用`docker run`更方便,特别是在简单的容器创建和启动任务中。如果您需要更多的灵活性,或者希望在创建容器后再启动它,那么`docker create`可能更适合您的需求。
>
> 需要注意的是,无论是`docker create`还是`docker run`,都可以使用参数来设置容器的各种配置,例如映射端口、挂载卷、环境变量等。

** 查看所有的容器

// 查看所有的容器

docker ps -a

** ps 查看已经启动的容器

** 查看已经启动的容器

docker ps

** rm -f 删除容器

> ** 删除容器
>
> 注意: 删除容器的时候的时候确保容器已经停止了, 否则会报错 Error response from daemon: You cannot remove a running container 54c09ae0c46949e25c27f29c1ffeb737421c6a3f3b9bb3c4e14da2c242da8580. Stop the container before attempting removal or force remove
>
> ** 删除容器
>
> docker rm -f  <容器ID>
>
> ** 删除多个容器
>
> docker rm -f  <容器ID> <容器ID> <容器ID>
>
> ** 删除所有的容器
>
> docker rm -f $(docker ps -aq) 

** 容器操作

docker start <容器ID>    # 启动容器

docker stop  <容器ID>    # 停止容器

docker restart <容器ID>  # 重启容器

docker kill <容器ID>     # 强制停止当前容器

** 后台启动容器

docker run -d <IMAGE ID>

** logs 查看日志

docker logs <容器ID>

**  类似于 tail -f

docker logs -f <容器ID>

** top 查看容器中进程的信息

docker top <容器ID>

** inspect 查看镜像的元数据

docker inspect <容器ID>

/*

在Docker中,镜像和容器都具有相关的元数据。元数据是描述镜像或容器的信息,例如镜像的标签、创建时间、作者、依赖关系等。元数据提供了有关镜像或容器的详细信息,使用户能够更好地了解和管理它们。

对于镜像而言,元数据可以包括以下信息:

- 镜像的唯一标识符
- 镜像的名称和标签
- 镜像的大小
- 镜像的依赖关系和层次结构
- 镜像的创建时间和作者
- 镜像的操作系统和版本信息
- 镜像的端口映射和环境变量设置

对于容器而言,元数据可以包括以下信息:

- 容器的唯一标识符
- 容器的名称
- 容器所使用的镜像的标识符
- 容器的状态(运行中、停止等)
- 容器的网络设置和端口映射
- 容器的挂载卷和目录映射
- 容器的日志输出和事件记录

*/

** attach 进入当前正在运行的容器

docker attach <容器ID>

docker exec -it <容器ID> /bin/bash

区别:

attach  当退出容器的时候, 容器也会停止

exec    当退出容器的时候, 容器不会停止  *进入容器后开启一个新的终端,可以再里面操作(常用)* 建议使用!

** cp 从主机拷贝到容器

docker cp <主机路径> <容器ID:容器路径>

[root@localhost ~]# docker exec -it 54c09ae0c469 /bin/bash
[root@54c09ae0c469 /]# cd /tmp/
[root@54c09ae0c469 tmp]# ls
anaconda-post.log  ks-script-mbvg2Y  yum.log
[root@54c09ae0c469 /]# exit 
exit
[root@localhost ~]# docker cp /root/Dockerfile 54c09ae0c469:/tmp
[root@localhost ~]# docker exec -it 54c09ae0c469 /bin/bash
[root@54c09ae0c469 tmp]# ls
Dockerfile  anaconda-post.log  ks-script-mbvg2Y  yum.log

** cp 从容器拷贝到主机

docker cp <容器ID:容器文件路径> <主机路径>
[root@localhost docker-cp-test]# pwd
/data/docker-cp-test
[root@localhost docker-cp-test]# ls
[root@localhost docker-cp-test]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
54c09ae0c469        9f1de3c6ad53        "/bin/bash"         About an hour ago   Up About an hour                        zen_euclid
[root@localhost docker-cp-test]# docker cp 54c09ae0c469:/tmp/Dockerfile /data/docker-cp-test/
[root@localhost docker-cp-test]# ls
Dockerfile

** commit 从容器创建一个新的镜像

docker commit -a "Snake" -m "New Images" <容器ID> <自定义镜像名称:自定义标签>

[root@localhost docker-cp-test]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
54c09ae0c469        9f1de3c6ad53        "/bin/bash"         About an hour ago   Up About an hour                        zen_euclid
[root@localhost docker-cp-test]# docker commit -a "Snake" -m "New Image" 54c09ae0c469 commit_test_image:1.0
sha256:1672e2e3454419eab2427af16b6fbd66c7779c6c8af4ecee3d2fc5a6db2b20d4
[root@localhost docker-cp-test]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
commit_test_image   1.0                 1672e2e34544        8 seconds ago       191MB

** rename 容器名称

[root@localhost docker-cp-test]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
54c09ae0c469        9f1de3c6ad53        "/bin/bash"         About an hour ago   Up About an hour                        zen_euclid
[root@localhost docker-cp-test]# docker rename 54c09ae0c469 test_rename
[root@localhost docker-cp-test]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
54c09ae0c469        9f1de3c6ad53        "/bin/bash"         About an hour ago   Up About an hour                        test_rename

** diff 容器对比

docker diff命令用于比较指定容器的文件系统的状态与其基础镜像的状态之间的差异。它会列出容器中所有被添加、修改或删除的文件和目录。这对于检查容器中的文件变化以及容器的构建和运行过程中的文件系统更改非常有用。

docker diff <容器ID>

[root@localhost docker-cp-test]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
54c09ae0c469        9f1de3c6ad53        "/bin/bash"         About an hour ago   Up About an hour                        test_rename
[root@localhost docker-cp-test]# docker diff 54c09ae0c469
C /root
A /root/.bash_history
C /tmp
A /tmp/Dockerfile

** port 列出指定的容器的端口映射

[root@localhost ~]# docker run -d -p 8000:80 nginx
9f6654b85aafb1e78ff84dceda82a60635f2c3857c995ca9b6ffad5f71f05d64
[root@localhost ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
9f6654b85aaf        nginx               "/docker-entrypoint.…"   3 seconds ago       Up 2 seconds        0.0.0.0:8000->80/tcp   agitated_wright
[root@localhost ~]# docker port 9f6654b85aaf
80/tcp -> 0.0.0.0:8000

** stats 显示容器资源的使用情况

OPTIONS 说明:

--all , -a 	:显示所有的容器,包括未运行的。

--format 	:指定返回值的模板文件。

--no-stream :展示当前状态就直接退出了,不再实时更新。

--no-trunc 	:显示完整的镜像信息


[root@localhost ~]# docker run -itd centos /bin/bash     # 实时更新
[root@localhost ~]# docker stats -a   # 显示所有的容器, 包括未运行的容器.
CONTAINER ID        NAME                 CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
4ca413947ffb        sharp_snyder         0.00%               524KiB / 3.682GiB   0.01%               656B / 0B           0B / 0B             1
7e71c3a470c9        happy_knuth          0.00%               0B / 0B             0.00%               0B / 0B             0B / 0B             0
94def3c4461f        quirky_lamarr        0.00%               0B / 0B             0.00%               0B / 0B             0B / 0B             0
9f6654b85aaf        agitated_wright      0.00%               0B / 0B             0.00%               0B / 0B             0B / 0B             0
b1ef448d28bd        dreamy_franklin      0.00%               0B / 0B             0.00%               0B / 0B             0B / 0B             0
192c82171734        relaxed_villani      0.00%               0B / 0B             0.00%               0B / 0B             0B / 0B             0
1387c298ddbd        youthful_tesla       0.00%               0B / 0B             0.00%               0B / 0B             0B / 0B             0
5f7d30b20401        unruffled_williams   0.00%               0B / 0B             0.00%               0B / 0B             0B / 0B             0
0c0d016bd558        test_nginx           0.00%               0B / 0B             0.00%               0B / 0B             0B / 0B             0
54c09ae0c469        test_rename          0.00%               0B / 0B             0.00%               0B / 0B             0B / 0B             0
3c6c017d5f8e        epic_feynman         0.00%               0B / 0B             0.00%               0B / 0B             0B / 0B             0
22a21cf16fe4        modest_leavitt       0.00%               0B / 0B             0.00%               0B / 0B             0B / 0B             0
5d661647db44        vibrant_cray         0.00%               0B / 0B             0.00%               0B / 0B             0B / 0B             0
edffb70ccbb0        lucid_rosalind       0.00%               0B / 0B             0.00%               0B / 0B             0B / 0B             0
bc6b7e741407        laughing_lewin       0.00%               0B / 0B             0.00%               0B / 0B             0B / 0B             0


[root@localhost ~]# docker stats -a --no-stream    # 展示当前状态就直接退出了,不再实时更新。
CONTAINER ID        NAME                 CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
4ca413947ffb        sharp_snyder         0.00%               524KiB / 3.682GiB   0.01%               656B / 0B           0B / 0B             1
7e71c3a470c9        happy_knuth          0.00%               0B / 0B             0.00%               0B / 0B             0B / 0B             0
94def3c4461f        quirky_lamarr        0.00%               0B / 0B             0.00%               0B / 0B             0B / 0B             0
9f6654b85aaf        agitated_wright      0.00%               0B / 0B             0.00%               0B / 0B             0B / 0B             0
b1ef448d28bd        dreamy_franklin      0.00%               0B / 0B             0.00%               0B / 0B             0B / 0B             0
192c82171734        relaxed_villani      0.00%               0B / 0B             0.00%               0B / 0B             0B / 0B             0
1387c298ddbd        youthful_tesla       0.00%               0B / 0B             0.00%               0B / 0B             0B / 0B             0
5f7d30b20401        unruffled_williams   0.00%               0B / 0B             0.00%               0B / 0B             0B / 0B             0
0c0d016bd558        test_nginx           0.00%               0B / 0B             0.00%               0B / 0B             0B / 0B             0
54c09ae0c469        test_rename          0.00%               0B / 0B             0.00%               0B / 0B             0B / 0B             0
3c6c017d5f8e        epic_feynman         0.00%               0B / 0B             0.00%               0B / 0B             0B / 0B             0
22a21cf16fe4        modest_leavitt       0.00%               0B / 0B             0.00%               0B / 0B             0B / 0B             0
5d661647db44        vibrant_cray         0.00%               0B / 0B             0.00%               0B / 0B             0B / 0B             0
edffb70ccbb0        lucid_rosalind       0.00%               0B / 0B             0.00%               0B / 0B             0B / 0B             0
bc6b7e741407        laughing_lewin       0.00%               0B / 0B             0.00%               0B / 0B             0B / 0B             0

[root@localhost ~]# docker stats -a --no-trunc    # 显示完整的镜像信息
CONTAINER ID                                                       NAME                 CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
4ca413947ffb38bf27463150d6749b9186dcbc0802619d0286061d72704497b0   sharp_snyder         0.00%               524KiB / 3.682GiB   0.01%               656B / 0B           0B / 0B             1
7e71c3a470c977765a38a4edb43b5bd4ea6b67f8f8fd5ef10fd4f77ed1e61878   happy_knuth          0.00%               0B / 0B             0.00%               0B / 0B             0B / 0B             0
94def3c4461f9940c656951ac6b430fef890f2d35189722fb32cfed99da7206c   quirky_lamarr        0.00%               0B / 0B             0.00%               0B / 0B             0B / 0B             0
9f6654b85aafb1e78ff84dceda82a60635f2c3857c995ca9b6ffad5f71f05d64   agitated_wright      0.00%               0B / 0B             0.00%               0B / 0B             0B / 0B             0
b1ef448d28bde43519d27908897f8c18ed2af46a950d96f829aaa1395a6859f6   dreamy_franklin      0.00%               0B / 0B             0.00%               0B / 0B             0B / 0B             0


[root@localhost ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
4ca413947ffb        centos              "/bin/bash"         16 minutes ago      Up 16 minutes                           sharp_snyder
[root@localhost ~]# docker stats 4ca413947ffb  --no-stream   # 指定容器 不实时更新
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
4ca413947ffb        sharp_snyder        0.00%               524KiB / 3.682GiB   0.01%               656B / 0B           0B / 0B             1


[root@localhost ~]# docker stats 4ca413947ffb  --no-stream  --format "{{ json . }}"   # 以 json 的格式进行输出
{"BlockIO":"0B / 0B","CPUPerc":"0.00%","Container":"4ca413947ffb","ID":"4ca413947ffb","MemPerc":"0.01%","MemUsage":"524KiB / 3.682GiB","Name":"sharp_snyder","NetIO":"656B / 0B","PIDs":"1"}

# 输出指定的字段
[root@localhost ~]# docker stats 4ca413947ffb  --no-stream  --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}"
CONTAINER           CPU %               MEM USAGE / LIMIT
4ca413947ffb        0.00%               524KiB / 3.682GiB


/*
CONTAINER ID   		容器 ID    
NAME           		容器名称
CPU %		   		容器内部使用 CPU 的百分比
MEM USAGE/LIMIT   	容器正在使用的总内存,以及允许使用的内存总量。
MEM % 				容器内部使用 内存 的百分比
NET I/O 			容器通过其网络接口发送和接收的数据量
BLOCK I/O		 	容器从主机上的块设备读取和写入的数据量。
PIDS			 	容器创建的进程或线程数。
*/

** pause/unpause

  • docker pause :暂停容器中所有的进程。

  • docker unpause :恢复容器中所有的进程。

  • [root@localhost ~]# docker run -d -p 8000:80 nginx
    [root@localhost ~]# docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
    9f6654b85aaf        nginx               "/docker-entrypoint.…"   10 minutes ago      Up 10 minutes       0.0.0.0:8000->80/tcp   agitated_wright
    [root@localhost ~]# curl http://127.0.0.1:8000/
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
    html { color-scheme: light dark; }
    body { width: 35em; margin: 0 auto;
    font-family: Tahoma, Verdana, Arial, sans-serif; }
    </style>
    </head>
    <body>
    <h1>Welcome to nginx!</h1>
    <p>If you see this page, the nginx web server is successfully installed and
    working. Further configuration is required.</p>
    
    <p>For online documentation and support please refer to
    <a href="http://nginx.org/">nginx.org</a>.<br/>
    Commercial support is available at
    <a href="http://nginx.com/">nginx.com</a>.</p>
    
    <p><em>Thank you for using nginx.</em></p>
    </body>
    </html>
    [root@localhost ~]# docker pause 9f6654b85aaf
    9f6654b85aaf
    [root@localhost ~]# curl http://127.0.0.1:8000/   # 到这里发现阻塞, 进程让终止了.
    ^C
    [root@localhost ~]# docker unpause 9f6654b85aaf
    9f6654b85aaf
    [root@localhost ~]# curl http://127.0.0.1:8000/
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
    html { color-scheme: light dark; }
    body { width: 35em; margin: 0 auto;
    font-family: Tahoma, Verdana, Arial, sans-serif; }
    </style>
    </head>
    <body>
    <h1>Welcome to nginx!</h1>
    <p>If you see this page, the nginx web server is successfully installed and
    working. Further configuration is required.</p>
    
    <p>For online documentation and support please refer to
    <a href="http://nginx.org/">nginx.org</a>.<br/>
    Commercial support is available at
    <a href="http://nginx.com/">nginx.com</a>.</p>
    
    <p><em>Thank you for using nginx.</em></p>
    </body>
    </html>
    

** update 更新容器配置

[root@localhost ~]# docker run -itd centos /bin/bash
[root@localhost ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
7e71c3a470c9        centos              "/bin/bash"         8 minutes ago       Up 8 minutes                            happy_knuth
[root@localhost ~]# docker update --memory 1024m --memory-swap 1g 7e71c3a470c9
7e71c3a470c9
[root@localhost ~]# docker stats 7e71c3a470c9
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
7e71c3a470c9        happy_knuth         0.00%               524KiB / 1GiB       0.05%               656B / 0B           0B / 0B             1
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
7e71c3a470c9        happy_knuth         0.00%               524KiB / 1GiB       0.05%               656B / 0B           0B / 0B             1
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
7e71c3a470c9        happy_knuth         0.00%               524KiB / 1GiB       0.05%               656B / 0B           0B / 0B             1
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
7e71c3a470c9        happy_knuth         0.00%               524KiB / 1GiB       0.05%               656B / 0B           0B / 0B             1
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
7e71c3a470c9        happy_knuth         0.00%               524KiB / 1GiB       0.05%               656B / 0B           0B / 0B             1
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
7e71c3a470c9        happy_knuth         0.00%               524KiB / 1GiB       0.05%               656B / 0B           0B / 0B             1
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
7e71c3a470c9        happy_knuth         0.00%               524KiB / 1GiB       0.05%               656B / 0B           0B / 0B             1
^C
[root@localhost ~]# docker update --memory 512m 7e71c3a470c9
7e71c3a470c9
[root@localhost ~]# docker stats 7e71c3a470c9
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
7e71c3a470c9        happy_knuth         0.00%               524KiB / 512MiB     0.10%               656B / 0B           0B / 0B             1
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
7e71c3a470c9        happy_knuth         0.00%               524KiB / 512MiB     0.10%               656B / 0B           0B / 0B             1
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
7e71c3a470c9        happy_knuth         0.00%               524KiB / 512MiB     0.10%               656B / 0B           0B / 0B             1

** wait 阻塞

# 阻塞运行直到容器停止,然后打印出它的退出代码
[root@localhost ~]# docker run -itd centos /bin/bash
[root@localhost ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
7e71c3a470c9        centos              "/bin/bash"         12 minutes ago      Up 12 minutes                           happy_knuth
[root@localhost ~]# docker wait 7e71c3a470c9   # 进行阻塞 , 新开一个终端,运行 docker stop 7e71c3a470c9
0  # 运行 docker stop 7e71c3a470c9 之后打印退出代码.

** kill 结束容器

docker kill <容器ID>

docker stop <容器ID> 和  docker kill <容器ID> 的区别.

docker stop 执行的顺序就是 先发送一个信号到主进程, 默认给 10s 的回收时间, 然后在结束容器 比较优雅
docker kill 执行的顺序是直接发送一个信号, 直接结束容器.

docker stop  类似于 Linux  kill
docker kill  类似于 Linux  kill -9

** export 归档文件 tar

[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              5d0da3dc9764        23 months ago       231MB
[root@localhost ~]# docker run -itd centos
de801ada02b240f775865c882e537aff398d8dc3e7f79fbc1afcb3ea7af3b3e3
[root@localhost ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
de801ada02b2        centos              "/bin/bash"         18 seconds ago      Up 17 seconds                           optimistic_perlman
[root@localhost ~]# docker export -o centos-`date +%Y%m%d`.tar de801ada02b2
[root@localhost ~]# ls
anaconda-ks.cfg  centos-20230814.tar

-o:  将输入内容写到文件。

** import 从归档文件中创建镜像

[root@localhost ~]# ls
anaconda-ks.cfg  centos-20230814.tar
[root@localhost ~]# docker import centos-20230814.tar centos2023:v1
sha256:c5c918a31ee448dbf4e75b0ab43fe49037277aa9c607aa270c432f9b45db45bc
[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos2023          v1                  c5c918a31ee4        3 seconds ago       231MB
centos              latest              5d0da3dc9764        23 months ago       231MB

Docker镜像仓库

首先: 注册一个 dockerhub 账号 https://hub-stage.docker.com/signup

== login 登录

docker login

== push 提交

需要注意的是
在 docker 使用 push 提交的时候, 镜像名一定要这样命名  <dockerhub名称>/<镜像名>:<版本号>  这个 dockerhub名称是必须要的, 否则就会出错
docker login
docker push 镜像名称

== logout 退出登录

docker logout

Docker Volume

简介

默认情况下,在容器内创建的所有文件都存储在可写容器层上。这意味着:
当该容器不再存在时,数据不会持续存在,并且如果另一个进程需要数据,则可能很难将数据从容器中取出。
容器的可写层与运行容器的主机紧密耦合。您无法轻松地将数据移动到其他地方。
写入容器的可写层需要 存储驱动程序来管理文件系统。存储驱动程序提供了一个联合文件系统,使用 Linux
内核。与使用直接写入主机文件系统的数据卷相比,这种额外的抽象会降低性能 。
Docker 有两个选项让容器在主机上存储文件,以便即使在容器停止后文件也能持久保存:volumes和 bind mounts

挂载类型

挂载类型

volumes:由 Docker(/var/lib/docker/volumes/在 Linux 上)管理的主机文件系统的一部分中。非 Docker 进程不应修改文件系统的这一部分。卷是在 Docker 中持久化数据的最佳方式
bind mounts:可以存储在主机系统的任何位置。它们甚至可能是重要的系统文件或目录。Docker 主机或 Docker 容器上的非 Docker 进程可以随时修改它们。
tmpfs mounts:挂载仅存储在主机系统的内存中,永远不会写入主机系统的文件系统

创建卷

[root@localhost ~]# docker volume create test_volume
test_volume
[root@localhost ~]# cd /var/lib/docker/volumes/   # 放创建号的卷 在这目录下
[root@localhost volumes]# ls
metadata.db  test_volume

查看所有的卷

[root@localhost volumes]# docker volume ls
DRIVER              VOLUME NAME
local               test_volume

查看指定容器卷的详情信息

[root@localhost volumes]# docker volume inspect test_volume
[
    {
        "CreatedAt": "2023-08-14T15:36:54+08:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/test_volume/_data",
        "Name": "test_volume",
        "Options": {},
        "Scope": "local"
    }
]

创建使用指定卷的容器

docker run -d -it --name=snake-nginx -p 8800:80 -v test_volume:/usr/share/nginx/html nginx

# -v 表示挂载卷
# 挂载位置 /var/lib/docker/volumes/test_volume/_data

案例

[root@localhost ~]# docker ps   # 查看正在运行的容器
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
[root@localhost ~]# docker volume create test_volume   # 创建数据卷
test_volume
[root@localhost ~]# docker volume ls
DRIVER              VOLUME NAME
local               test_volume
[root@localhost ~]# docker run -itd -p 8000:80 -v test_volume:/usr/share/nginx/html nginx  # 运行, 并挂载数据卷
e1452e347fc03e6eab51c01ba373a4224ad56b756696b1e7de73fe153333bf0f
[root@localhost ~]# curl localhost:8000         # 访问nginx
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@localhost ~]# cd /var/lib/docker/volumes/test_volume/_data/   # 数据卷位置
[root@localhost _data]# ls  # 挂载文件
50x.html  index.html
[root@localhost _data]# echo "Volume Test Data" >>  volume_test.txt  # 数据卷进行测试
[root@localhost _data]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                  NAMES
e1452e347fc0        nginx               "/docker-entrypoint.…"   About a minute ago   Up About a minute   0.0.0.0:8000->80/tcp   eloquent_kare
[root@localhost _data]# docker exec -it e1452e347fc0 /bin/bash  # 进入容器
root@e1452e347fc0:/# cat /usr/share/nginx/html/                 # 查看 volume_test.txt 是否存在
50x.html         index.html       volume_test.txt
root@e1452e347fc0:/# cat /usr/share/nginx/html/volume_test.txt
Volume Test Data
root@e1452e347fc0:/# rm -f /usr/share/nginx/html/volume_test.txt
root@e1452e347fc0:/# exit
exit
[root@localhost _data]# ls
50x.html  index.html
[root@localhost _data]# echo "<h1>Test Vloume</h1>" >> index.html   # 给nginx 最后一行添加 内容
[root@localhost _data]# curl localhost:8000
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
<h1>Test Vloume</h1>
[root@localhost _data]# docker exec -it e1452e347fc0 /bin/bash  # 进入容器.
root@e1452e347fc0:/# tail -1 /usr/share/nginx/html/index.html   # 查看容器内最后一行是否是刚写入的数据
<h1>Test Vloume</h1>
root@e1452e347fc0:/# exit                        				# 退出容器哦
exit
[root@localhost _data]# docker stop e1452e347fc0                # 停止容器
e1452e347fc0
[root@localhost _data]# docker rm -f e1452e347fc0               # 删除容器   # 注意: 这里想要删除卷, 必须要删除容器, 否则删除卷的时候会失败
e1452e347fc0
[root@localhost _data]# docker volume rm test_volume            # 删除卷
test_volume
[root@localhost _data]# ls
[root@localhost _data]# cd ..
cd: 获取当前目录时出错: getcwd: 无法访问父目录: 没有那个文件或目录
[root@localhost ..]# cd ..
[root@localhost volumes]# ls
metadata.db
[root@localhost volumes]# docker volume ls                      # 查看所有的卷.
DRIVER              VOLUME NAME
[root@localhost volumes]#

Dockerfile

Dockerfile官网文档

Dockerfile官网文档

什么是 Dockerfile?

Dockerfile 是一个用来构建镜像的文本文件,文本包含了一条条构建镜像所需要的指令和说明
说白了,就是将 docker 的命令转为 Dockerfile 命令 并且构建一个镜像出来

Dockerfile 构建步骤

1. 编写 Dockerfile 文件
2. Docker build 构建镜像
3. Docker run 以镜像运行容器实例.

DockerFile构建过程

1.每条保留字, 必须为大写字母且后面要跟随至少一个参数 FROM  ENV  RUN  WORKDIR  EXPOSE  CMD这些就是上面提到的保留字

2.指令按照从从上到下,依次执行

3.#表示注释

4.每条指令都会创建一个新的镜像层,并对镜像进行提交

Docker执行DockerFile的流程

1.docker以基础镜像运行一个容器

#以镜像启动容器,“有了类,才能new一个对象”

2.执行一条指令并对容器做出修改

3.执行类似于Docker commit的操作提交一个新的镜像层

4.Docker再基于刚刚提交的镜像运行一个新的容器

5.执行DockerFile中的下一条指令,直到所有指令执行完成

使用 Dockerfile 构建 Nginx 镜像

[root@localhost ~]# mkdir /data/Dockerfile/ -p
[root@localhost ~]# cd /data/Dockerfile/
[root@localhost Dockerfile]# vi Dockerfile
[root@localhost Dockerfile]# docker build -t nginx:v1 .
Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM nginx
 ---> 89da1fb6dcb9
Step 2/2 : RUN echo "build nginx" > /usr/share/nginx/html/index.html
 ---> Running in c9d4233fede6
Removing intermediate container c9d4233fede6
 ---> 71cd47f5d6b0
Successfully built 71cd47f5d6b0
Successfully tagged nginx:v1
[root@localhost Dockerfile]# docker images
REPOSITORY                TAG                 IMAGE ID            CREATED             SIZE
nginx                     v1                  71cd47f5d6b0        7 seconds ago       187MB
[root@localhost Dockerfile]# cat Dockerfile
FROM nginx
RUN echo "build nginx" > /usr/share/nginx/html/index.html

[root@localhost Dockerfile]# docker run -itd -p 8000:80 71cd47f5d6b0
603a38531d1bed1bc059f12d77f7b373a149997483f28fac2c5aa563d15fd57a
[root@localhost Dockerfile]# curl localhost:8000
build nginx

/*


FROM:定制的镜像都是基于 FROM 的镜像,这里的 nginx 就是定制需要的基础镜像。后续的操作都是基于 nginx。

RUN:用于执行后面跟着的命令行命令。有以下俩种格式:

shell 格式:

RUN <命令行命令>
# <命令行命令> 等同于,在终端操作的 shell 命令。
exec 格式:

RUN ["可执行文件", "参数1", "参数2"]
# 例如:
# RUN ["./test.php", "dev", "offline"] 等价于 RUN ./test.php dev offline

*/

FROM

作用:指定基础镜像,用于后续的指令构建

FROM 指定基础镜像:[version] versiondefault: latest
示例:
FROM nginx

指定基础镜像
FROM centos:7

MAINTAINER

作用:指定Dockerfile的作者/维护者。(已弃用,推荐使用LABEL指令)

MAINTAINER Snake Snake@example.com

RUN

作用: 在容器内执行命令

RUN apt-get update && apt-get install -y python3

CMD

作用: 容器启动后执行的命令(只能有一个 CMD) 如果容器启动时,增加了启动命令,则会覆盖掉 CMD 建议看一下下面的 CMD 和 ENTRYPOINT 的区别

CMD ["python3", "app.py"]

LABEL

作用:添加元数据,如版本号、描述等

LABEL version="1.0" description="My custom image"

EXPOSE

作用:声明容器需要监听的端口

EXPOSE 8080/tcp

ENV

作用: 设置环境变量

ENV DB_HOST=localhost

ADD

作用: 将文件从主机复制到容器中。自动解压缩压缩文件,从 URL 复制文件

ADD https://snake.com/test.tar.gz /var/www/

COPY

作用: 将文件从主机复制到容器中 # 建议看一下 下面的 ADD 和 COPY 的区别

COPY app.py /usr/src/app/

ENTRYPOINT

作用: 容器启动时执行的命令(可以与 CMD 结合使用)

ENTRYPOINT ["python3"] 
CMD ["app.py"]
# app.py 就是相当于一个参数进行传递到 ENTRYPOINT
# 最后呈现的效果就是  python3 app.py

VOLUME

作用: 在容器中创建挂载点,用于持久化数据

VOLUME /data

WORKDIR

作用: 设置工作目录

WORKDIR /usr/src/app

ARG

作用:定义构建时传递给镜像的参数

ARG version=latest

ONBUILD

作用:当该镜像被用作另一个构建过程的基础时,添加触发器

用于延迟构建命令的执行。简单的说,就是 Dockerfile 里用 ONBUILD 指定的命令,在本次构建镜像的过程中不会执行(假设镜像为 test-build)。当有新的 Dockerfile 使用了之前构建的镜像 FROM test-build ,这时执行新镜像的 Dockerfile 构建时候,会执行 test-build 的 Dockerfile 里的 ONBUILD 指定的命令。
ONBUILD <其它指令>

STOPSIGNAL

作用:指定用于执行指令的 shell

STOPSIGNAL SIGTERM
系统调用信号是一种在操作系统中用于通知进程发生某种事件或状态变化的机制。Docker 中的 STOPSIGNAL 关键字用于指定在停止容器时使用的系统调用信号。当 Docker 容器接收到指定的信号时,它可以执行某些操作以进行优雅的关闭和清理工作。以下是一些常用的系统调用信号及其作用:

SIGTERM (15): 默认的停止信号。当 Docker 希望停止容器时,会首先发送 SIGTERM 信号。容器可以捕获此信号并执行一些清理操作,如保存未保存的数据、关闭网络连接等。如果容器在一定时间内没有响应 SIGTERM,Docker 将发送 SIGKILL 信号来强制终止容器。

SIGINT (2): 类似于 SIGTERM,但通常由终端用户发送,例如按下 Ctrl+C。容器可以捕获此信号并执行相应的操作。

SIGQUIT (3): 类似于 SIGINT,但与之不同的是,SIGQUIT 通常会导致进程生成一个核心转储(core dump)文件,用于调试。

SIGUSR1 (10) 和 SIGUSR2 (12): 用户自定义信号。容器可以根据需要使用这些信号执行特定的操作。

在使用 STOPSIGNAL 关键字时,您可以根据应用程序的需要选择适当的信号。通常情况下,使用 SIGTERM 是一种良好的做法,因为它允许容器有时间进行清理工作,确保数据的完整性和一致性。

SHELL

作用:指定用于执行指令的 shell

SHELL ["/bin/bash", "-c"]

HEALTHCHECK

作用: 检查容器的健康状态

HEALTHCHECK CMD curl -f http://localhost/ || exit 1

RUN

可以使用多个 RUN 指令来组合多个命令。 例如:RUN apt-get update &&
apt-get install -y python3 &&
pip install requests

CMD 和 ENTRYPOINT 区别

区别

ADD 和 COPY 区别

区别

Dockerfile 实例

[root@localhost ~]# mkdir -p /data/Dockerfile/
[root@localhost ~]# yum install wget
[root@localhost ~]# cd /data/Dockerfile/
[root@localhost Dockerfile]# wget http://nginx.org/download/nginx-1.22.1.tar.gz
[root@localhost Dockerfile]# touch Dockerfile
[root@localhost Dockerfile]# ls
Dockerfile  nginx-1.22.1.tar.gz
[root@localhost Dockerfile]# pwd
/data/Dockerfile
# 下面 Dockerfile 注释部分先不用管.
[root@localhost Dockerfile]# vi Dockerfile  # 编辑 Dockerfile 文件
# Dockerfile 文件如下:
# 使用官方的 Nginx 镜像作为基础镜像
FROM nginx

# 添加作者标签
LABEL Author='Snake'

# 设置停止容器时使用的系统调用信号为 SIGTERM
STOPSIGNAL SIGTERM

# 在容器中创建一个文本文件
RUN echo "build nginx" > /usr/share/nginx/html/index.html

# 从网络上下载一个文件并添加到容器中
ADD http://nginx.org/download/nginx-1.20.2.tar.gz /root/

# 复制主机当前目录下的文件到容器中
COPY ./nginx-1.22.1.tar.gz /root/

# 创建一个挂载点用于持久化数据
VOLUME /usr/share/nginx/html/

# 设置工作目录
WORKDIR /root/

# 重命名下载的文件
RUN mv nginx-1.22.1.tar.gz run_test_nginx-1.22.1.tar.gz

# 设置运行时的用户名为 root
USER root

# 检查容器的健康状态
HEALTHCHECK CMD curl -f http://localhost/ && echo 'Check Nginx Url Successful....'|| exit 1

# 声明容器需要监听的端口
EXPOSE 80

# 设置环境变量
# ENV MY_ENV_VARIABLE=my_value

# 容器启动时执行的命令
# CMD ["echo", "hello Nginx"]

# 设置用于执行指令的 shell
# SHELL ["/bin/bash", "-c"]

# 定义构建时传递给镜像的参数
ARG build_version=1.0

# 设置容器启动时执行的命令
# ENTRYPOINT ["echo", "Hello, Docker!"]

# 使用 ONBUILD 关键字,指定在派生镜像中延迟执行的操作
# ONBUILD COPY . /app

[root@localhost Dockerfile]# docker build -t nginx:v1 .
[root@localhost Dockerfile]# docker run -itd -p 8888:80 nginx:v1
566a08f09f54c94ce0f8311ed5d2a3e1e0b14a403faca61c69ddb6d3e83a3db7
[root@localhost Dockerfile]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                            PORTS                  NAMES
566a08f09f54        nginx:v1            "/docker-entrypoint.…"   3 seconds ago       Up 2 seconds (health: starting)   0.0.0.0:8888->80/tcp   gracious_minsky
[root@localhost Dockerfile]# docker logs -f 566a08f09f54
.....
127.0.0.1 - - [15/Aug/2023:05:52:33 +0000] "GET / HTTP/1.1" 200 12 "-" "curl/7.88.1" "-"
192.168.142.1 - - [15/Aug/2023:05:52:52 +0000] "GET / HTTP/1.1" 200 12 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36" "-"

[root@localhost Dockerfile]# curl localhost:8888
build nginx


[root@localhost Dockerfile]# docker inspect 566a08f09f54
...
"Config": {
            "Hostname": "566a08f09f54",
            "Domainname": "",
            "User": "root",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "80/tcp": {}
            },
            "Tty": true,
            "OpenStdin": true,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "NGINX_VERSION=1.25.1",
                "NJS_VERSION=0.7.12",
                "PKG_RELEASE=1~bookworm"
            ],
            "Cmd": [
                "nginx",
                "-g",
                "daemon off;"
            ],
            "Healthcheck": {
                "Test": [
                    "CMD-SHELL",
                    "curl -f http://localhost/ && echo 'Check Nginx Url Successful....'|| exit 1"
                ]
            },
            "Image": "nginx:v1",
            "Volumes": {
                "/usr/share/nginx/html/": {}
            },
            "WorkingDir": "/root",
            "Entrypoint": [
                "/docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": {
                "Author": "Snake",
                "maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>"
            },
            "StopSignal": "SIGTERM"
        },
...

[root@localhost Dockerfile]# docker exec -it 566a08f09f54 bash
root@566a08f09f54:~# cd /root/
root@566a08f09f54:~# ls
nginx-1.20.2.tar.gz  run_test_nginx-1.22.1.tar.gz
root@566a08f09f54:~# exit
exit
# 查看生成的挂载位置, 使用 inspect 查询容器元数据, 查看
 "Mounts": [
            {
                "Type": "volume",
                "Name": "56ed3b0ecd4c104b944998c734e4562d762bddcdcca4910f1019905d271c8383",
                "Source": "/var/lib/docker/volumes/56ed3b0ecd4c104b944998c734e4562d762bddcdcca4910f1019905d271c8383/_data",
                "Destination": "/usr/share/nginx/html",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],

[root@localhost volumes]# cd /var/lib/docker/volumes/56ed3b0ecd4c104b944998c734e4562d762bddcdcca4910f1019905d271c8383/_data
[root@localhost _data]# ls
50x.html  index.html
[root@localhost _data]# cat index.html 
build nginx
[root@localhost _data]# echo "test index" >> index.html 
[root@localhost _data]# cat index.html 
build nginx
test index
[root@localhost _data]# curl localhost:8888
build nginx
test index

Dockerfile 运行一个 Django项目

[root@localhost _data]# mkdir /data/Dockerfile/Django/ -p
[root@localhost _data]# cd /data/Dockerfile/Django/
[root@localhost _data]# yum install git -y
[root@localhost Django]# git clone https://gitee.com/liuxiaoxiaomo/DockerDjangoTest.git
[root@localhost Django]# cat Dockerfile 
# 使用官方的 Python 镜像作为基础镜像
FROM python:3.8
# 设置环境变量,禁用缓冲,以便实时查看日志输出
ENV PYTHONUNBUFFERED 1
# 创建并设置工作目录
RUN mkdir /app
WORKDIR /app
# 复制项目的依赖文件到容器中
COPY ./DockerDjangoTest/Docker_Test /app/
RUN pip install --upgrade pip
RUN pip install -r requirements.txt
# 声明容器需要监听的端口
EXPOSE 8000
# 容器启动时执行的命令
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]

[root@localhost Django]# docker build -t django_app .
[root@localhost Django]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
django_app   latest    9cf96b08e3da   2 minutes ago   1.05GB
[root@localhost Django]# docker run -d --name test_django_app -p 8008:8000 django_app
ede96094979556fc46b19b33d7362ae5afdb9f6a174b86c0608d7d03bc35616c
[root@localhost Django]# docker ps
CONTAINER ID   IMAGE        COMMAND                   CREATED         STATUS        PORTS                                       NAMES
ede960949795   django_app   "python manage.py ru…"   2 seconds ago   Up 1 second   0.0.0.0:8008->8000/tcp, :::8008->8000/tcp   test_django_app
[root@localhost Django]# curl localhost:8008
# 获取浏览器访问 http://IP:8008/  
# 会出现一个 django 创建成功的页面.

Docker Portainer

[root@localhost Django]# docker run -ti -d --name kevin-portainer -p 9000:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock  portainer/portainer
[root@localhost Django]# docker ps
CONTAINER ID   IMAGE                 COMMAND                   CREATED         STATUS         PORTS                                                           NAMES
3a23978bb9e6   portainer/portainer   "/portainer"              5 seconds ago   Up 2 seconds   8000/tcp, 9443/tcp, 0.0.0.0:9000->9000/tcp, :::9000->9000/tcp   kevin-portainer

# 浏览器访问
http://ip:9000/

# 首次创建需要给 portainer 设置 admin 密码  -- 密码的长度必须至少为12个字符。
# 页面就自己摸索吧, 这里就不过多说了.

Docker Network

在 Docker 中,有三种默认网络(bridge、host、none)和自定义网络之间有一些明显的区别:

Bridge 网络:这是 Docker 默认的网络驱动程序。在 Bridge 网络中,每个容器都分配了自己的 IP 地址,并且容器可以相互通信。容器可以通过在同一网络中使用容器名称进行通信,而不需要使用 IP 地址。Bridge 网络还与主机网络接口进行桥接,因此容器可以通过主机网络访问外部网络。这种网络模式提供了基本的网络隔离和通信功能。

Host 网络:Host 网络模式将 Docker 容器直接连接到主机网络,容器与主机共享网络栈。这意味着容器使用主机的 IP 地址,并且容器中运行的应用程序直接使用主机网络接口。在 Host 网络模式下,容器与主机网络之间没有额外的隔离,容器中的应用程序可以通过 localhost 访问主机上的服务。这种模式适用于需要与主机和容器之间进行高性能通信的场景。

None 网络:None 网络模式意味着容器没有网络接口。容器中的应用程序将无法通过网络进行通信。这种模式适用于一些特殊场景,例如只需在容器内部执行本地计算任务,而无需与外部网络通信。

自建网络与默认网络具有以下区别:

自建网络:使用 Docker 的自定义网络功能,可以创建一个用户定义的网络。自建网络可用于在容器之间创建更复杂的网络拓扑结构,而不仅仅是简单的容器到容器通信。例如,一个应用程序可能需要将后端容器连接到前端容器,或者需要连接多个容器到同一个网络中。自建网络还可以通过指定子网和网关等参数进行更精确的网络配置。

默认网络:默认网络是 Docker 在安装时自动创建的网络。它是 Bridge 网络,并提供了基本的网络隔离和通信功能。默认网络通常用于容器之间的通信,与主机和外部网络的连接使用 Bridge 桥接。

总的来说,自建网络提供了更高级和灵活的网络配置选项,允许容器之间进行更复杂的连接和通信。而默认网络是 Docker 提供的简单网络选项,适用于基本的容器通信和与主机的网络连接。

创建网络

[root@localhost Django]# docker network create test_network
112699a0f3bd3e70c208dc6b814b14b3c77763d49d40eea1bb55512f79617ff1

查看网络

[root@localhost Django]# docker network ls
NETWORK ID     NAME           DRIVER    SCOPE
e66ac79aff6b   bridge         bridge    local
627ebeba16f1   host           host      local
84be38f15900   none           null      local
112699a0f3bd   test_network   bridge    local

配置网络

[root@localhost Django]# docker run -itd --network test_network centos 
[root@localhost Django]# docker ps
CONTAINER ID   IMAGE                 COMMAND                   CREATED             STATUS             PORTS                                                           NAMES
1ca9549c116d   centos                "/bin/bash"               3 seconds ago       Up 2 seconds                                                                       fervent_williamson
[root@localhost Django]# docker inspect 1ca9549c116d

"HostConfig": {
            "Binds": null,
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "test_network",
            .....
}

删除网络

[root@localhost Django]# docker stop 1ca9549c116d
1ca9549c116d
[root@localhost Django]# docker network rm test_network
test_network
[root@localhost Django]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
e66ac79aff6b   bridge    bridge    local
627ebeba16f1   host      host      local
84be38f15900   none      null      local

显示信息

[root@localhost Django]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
e66ac79aff6b   bridge    bridge    local
627ebeba16f1   host      host      local
84be38f15900   none      null      local
[root@localhost Django]# docker network inspect e66ac79aff6b
[
    {
        "Name": "bridge",
        "Id": "e66ac79aff6bf8bbf38ab367797a6885ed0d1c01fc62c60686ebd5f563b76f6d",
        "Created": "2023-08-15T15:39:15.967812284+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "3a23978bb9e6055c6c7b7171f05061c5c0fc128e88034eef615422663118b2e6": {
                "Name": "kevin-portainer",
                "EndpointID": "07272bbbcd38ac92d8ccdfab06366ea63cdf9d70100671a348a0bf8759b33ea2",
                "MacAddress": "02:42:ac:11:00:03",
                "IPv4Address": "172.17.0.3/16",
                "IPv6Address": ""
            },
            "ede96094979556fc46b19b33d7362ae5afdb9f6a174b86c0608d7d03bc35616c": {
                "Name": "test_django_app",
                "EndpointID": "0625a260b71c3535477e57b10b7ae5d72f81ca8aed5455811434fa71584f18af",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]

断开连接

[root@localhost Django]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
e66ac79aff6b   bridge    bridge    local
627ebeba16f1   host      host      local
84be38f15900   none      null      local
# 这个是之前启动的,默认的网络连接是 bridge
[root@localhost Django]# docker ps
CONTAINER ID   IMAGE                 COMMAND                   CREATED             STATUS             PORTS                                                           NAMES
ede960949795   django_app            "python manage.py ru…"   About an hour ago   Up About an hour   0.0.0.0:8008->8000/tcp, :::8008->8000/tcp                       test_django_app
# 断开外部网络连接
[root@localhost Django]# docker network disconnect e66ac79aff6b test_django_app #这个容器的搭建可以看我的 Dockerfile 运行一个Django的教程
[root@localhost Django]# docker ps
CONTAINER ID   IMAGE                 COMMAND                   CREATED             STATUS             PORTS                                                           NAMES
ede960949795   django_app            "python manage.py ru…"   About an hour ago   Up About an hour     

网络连接

[root@localhost Django]# docker network connect bridge test_django_app
[root@localhost Django]# docker ps
CONTAINER ID   IMAGE                 COMMAND                   CREATED             STATUS             PORTS                                                           NAMES
3a23978bb9e6   portainer/portainer   "/portainer"              About an hour ago   Up About an hour   8000/tcp, 9443/tcp, 0.0.0.0:9000->9000/tcp, :::9000->9000/tcp   kevin-portainer
ede960949795   django_app            "python manage.py ru…"   About an hour ago   Up About an hour   0.0.0.0:8008->8000/tcp, :::8008->8000/tcp                       test_django_app

删除未所有未使用的网络

[root@localhost Django]# docker network create test_network 
3893286ad006a454f82f9da0f366bb5b8461d330802fd0aa3f8af377fbd0d3cc
[root@localhost Django]# docker network ls
NETWORK ID     NAME           DRIVER    SCOPE
e66ac79aff6b   bridge         bridge    local
627ebeba16f1   host           host      local
84be38f15900   none           null      local
3893286ad006   test_network   bridge    local
[root@localhost Django]# docker network prune  # 删除所有未使用的网络!
WARNING! This will remove all custom networks not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Networks:
test_network

[root@localhost Django]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
e66ac79aff6b   bridge    bridge    local
627ebeba16f1   host      host      local
84be38f15900   none      null      local
[root@localhost Django]# 

Docker Compose

简介

Docker Compose 是一个用于定义和管理多容器 Docker 应用程序的工具。下面是 Docker Compose 常用的一些内置命令:

up:构建(如有必要)并启动容器。可以使用 -d 参数在后台运行容器。
down:停止并删除相关容器、网络和卷等资源。
start:启动已经存在的容器。
stop:停止正在运行的容器。
restart:重启容器。
pause:暂停容器的执行。
unpause:恢复暂停的容器。
ps:显示正在运行的容器。
logs:查看容器的日志输出。
exec:在容器中执行命令。
build:构建或重新构建服务的镜像。
pull:从注册表中拉取服务所需的最新镜像版本。
config:验证和查看 Compose 文件的配置。
events:实时查看容器的事件。
top:查看容器中正在运行的进程。
scale:设置服务的容器实例数目。
version:显示 Compose 文件格式版本。
help:显示 Docker Compose 命令和用法帮助。
这些是 Docker Compose 中的一些常见内置命令。使用 Docker Compose 可以根据需要定义多个服务,并使用这些命令进行管理、运行和监控这些服务的容器。你可以通过运行 docker-compose help 命令查看 Docker Compose 的完整命令列表及其用法说明。


Compose 项目是 Docker 官方的开源项目,负责实现对 Docker 容器集群的快速编排。使用前面介绍的Dockerfile我们很容易定义一个单独的应用容器。然而在日常开发工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。例如要实现一个 Web 项目,除了 Web 服务容器本身,往往还需要再加上后端的数据库服务容器;再比如在分布式应用一般包含若干个服务,每个服务一般都会部署多个实例。如果每个服务都要手动启停,那么效率之低、维护量之大可想而知。这时候就需要一个工具能够管理一组相关联的的应用容器,这就是Docker Compose。

Centos 安装 docker-compose

# 最新的下载地址 
https://github.com/docker/compose/releases
# 下载稳定版本
[root@localhost bin]# sudo curl -L "https://github.com/docker/compose/releases/download/v2.2.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100 23.5M  100 23.5M    0     0  4498k      0  0:00:05  0:00:05 --:--:-- 5671k
[root@localhost bin]# ls
docker-compose
# 设置执行权限
[root@localhost bin]# sudo chmod +x /usr/local/bin/docker-compose
# 添加软连接
[root@localhost bin]# sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
# 查看版本信息, 说明安装成功了.
[root@localhost bin]# docker-compose version
Docker Compose version v2.2.2

Yaml 教程

# 因为 docker-compose 是基于 yaml 来完成的, 如果你不会 yaml, 建议先去学习一下yaml的语法,很简单的.
# 加油!
https://www.runoob.com/w3cnote/yaml-intro.html 

编写 docker-compose 案例

# docker-compose.yml 文件
# 这里注释就是让你看的明白一点, dockerfile 文件直接看 gitee 上面的代码吧.
# https://gitee.com/liuxiaoxiaomo/DockerComposeTest
# 这是 Django 的配置文件, 下面的network ipv4 就是要修改这个文件中的地址 
# https://gitee.com/liuxiaoxiaomo/DockerComposeTest/blob/master/DockerComposeTest/DockerComposeTest/settings.py

# 指定Compose文件的版本为2.2.2,该版本支持特定的Compose语法和功能。
version: '2.2.2'

# 定义服务部分的开始。
services:
  # 定义名为"mysql"的服务,用于运行MySQL数据库。
  mysql:
    build:
      context: .  # 使用当前目录作为构建上下文。
      dockerfile: MysqlDockerfile  # 使用名为"MysqlDockerfile"的Dockerfile构建镜像。
    container_name: compose_mysql  # 指定容器的名称为"compose_mysql"。
    ports:
      - 3306:3306  # 将主机的3306端口映射到容器的3306端口。
    environment:
      MYSQL_ROOT_PASSWORD: 123456  # 设置MySQL的root用户密码为"123456"。
    
    networks:
      mynetwork:  # 连接到名为"mynetwork"的网络。
        ipv4_address: 172.25.0.2  # 分配容器的IPv4地址为172.25.0.2。

  # 定义名为"redis"的服务,用于运行Redis数据库。
  redis:
    container_name: compose_redis  # 指定容器的名称为"compose_redis"。
    build:
      context: .  # 使用当前目录作为构建上下文。
      dockerfile: RedisDockerfile  # 使用名为"RedisDockerfile"的Dockerfile构建镜像。
    ports:
      - 6379:6379  # 将主机的6379端口映射到容器的6379端口。
    networks:
      mynetwork:  # 连接到名为"mynetwork"的网络。
        ipv4_address: 172.25.0.3  # 分配容器的IPv4地址为172.25.0.3。

  # 定义名为"python_app"的服务,用于运行Python应用程序。
  python_app:
    build:
      context: .  # 使用当前目录作为构建上下文。
      dockerfile: PythonDockerfile  # 使用名为"PythonDockerfile"的Dockerfile构建镜像。
    container_name: compose_app  # 指定容器的名称为"compose_app"。
    ports:
      - 8000:8000  # 将主机的8000端口映射到容器的8000端口。
    restart: always  # 配置容器在退出时自动重新启动。
    links:
      - mysql  # 与名为"mysql"的服务建立链接。
      - redis  # 与名为"redis"的服务建立链接。
    depends_on:
      - mysql  # 在启动前依赖于"mysql"服务的可用性。
      - redis  # 在启动前依赖于"redis"服务的可用性。
    networks:
      mynetwork:  # 连接到名为"mynetwork"的网络。
        ipv4_address: 172.25.0.4  # 分配容器的IPv4地址为172.25.0.4。

# 定义名为"mynetwork"的网络,用于连接各个容器。
networks:
  mynetwork:
    driver: bridge  # 使用"bridge"驱动程序创建网络。
    ipam:
      config:
        - subnet: 172.25.0.0/24  # 指定网络的IPv4子网为172.25.0.0/24。
[root@localhost ~]# mkdir -p /data/Docker-Compose/App/ 
[root@localhost ~]# cd /data/Docker-Compose/App/ 
[root@localhost App]# yum install -y git
[root@localhost App]# git clone https://gitee.com/liuxiaoxiaomo/DockerComposeTest.git	
[root@localhost App]# cd DockerComposeTest/
[root@localhost DockerComposeTest]# docker-compose up -d
[root@localhost DockerComposeTest]# docker images
REPOSITORY                     TAG       IMAGE ID       CREATED        SIZE
dockercomposetest_mysql        latest    84c6f6795e36   2 hours ago    581MB
dockercomposetest_python_app   latest    f86b98426102   3 hours ago    1.05GB
dockercomposetest_redis        latest    8a32a42d19b0   18 hours ago   130MB
[root@localhost DockerComposeTest]# docker ps
CONTAINER ID   IMAGE                          COMMAND                   CREATED          STATUS          PORTS                                                  NAMES
9f04550a24b0   dockercomposetest_python_app   "/bin/sh -c 'sleep 1…"   16 seconds ago   Up 14 seconds   0.0.0.0:8000->8000/tcp, :::8000->8000/tcp              compose_app
8dadcbe85b66   dockercomposetest_redis        "docker-entrypoint.s…"   16 seconds ago   Up 15 seconds   0.0.0.0:6379->6379/tcp, :::6379->6379/tcp              compose_redis
838f92ecba66   dockercomposetest_mysql        "docker-entrypoint.s…"   16 seconds ago   Up 15 seconds   0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp   compose_mysql
[root@localhost DockerComposeTest]# curl -w "\n" localhost:8000
{"message": "Hello, Docker Compose Redis!"}
[root@localhost DockerComposeTest]# curl -w "\n" localhost:8000/mysql/
{'test': 'Hello, Docker Compose Mysql!'}
[root@localhost DockerComposeTest]# docker exec -it compose_mysql
"docker exec" requires at least 2 arguments.
See 'docker exec --help'.

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

Execute a command in a running container
[root@localhost DockerComposeTest]# docker exec -it compose_mysql bash
bash-4.2# mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 10
Server version: 5.7.43 MySQL Community Server (GPL)

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+---------------------+
| Database            |
+---------------------+
| information_schema  |
| docker_compose_demo |
| mysql               |
| performance_schema  |
| sys                 |
+---------------------+
5 rows in set (0.00 sec)

mysql> use docker_compose_demo;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+-------------------------------+
| Tables_in_docker_compose_demo |
+-------------------------------+
| auth_group                    |
| auth_group_permissions        |
| auth_permission               |
| auth_user                     |
| auth_user_groups              |
| auth_user_user_permissions    |
| compose_app_dockercompose     |
| django_admin_log              |
| django_content_type           |
| django_migrations             |
| django_session                |
+-------------------------------+
11 rows in set (0.00 sec)

mysql> select * from compose_app_dockercompose;
+----+------------------------------+
| id | test                         |
+----+------------------------------+
|  1 | Hello, Docker Compose Mysql! |
+----+------------------------------+
1 row in set (0.00 sec)

mysql> exit
Bye
bash-4.2# exit
exit
[root@localhost DockerComposeTest]# docker exec -it compose_redis bash
root@8dadcbe85b66:/data# redis-cli 
127.0.0.1:6379> SELECT 1
OK
127.0.0.1:6379[1]> KEYS *
1) ":1:example_key"
127.0.0.1:6379[1]> GET  ":1:example_key"
"\x80\x04\x95 \x00\x00\x00\x00\x00\x00\x00\x8c\x1cHello, Docker Compose Redis!\x94."
127.0.0.1:6379[1]> exit
root@8dadcbe85b66:/data# exit
exit

/*

到这里就全部完成了, 说明 docker-compose 运行成功.

*/

Docker错误汇总

[root@localhost ~]# docker run -d nginx
WARNING: IPv4 forwarding is disabled. Networking will not work.

解决方案:
[root@localhost ~]# echo "net.ipv4.ip_forward=1" >>/usr/lib/sysctl.d/00-system.conf
[root@localhost ~]# systemctl restart network && systemctl restart docker

删除镜像出错

# Error response from daemon: conflict: unable to delete af0a91266abf (must be forced) - image is referenced in multiple repositories
[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
runoob/centos       6.7                 af0a91266abf        3 days ago          191MB
runoob/centos       dev                 af0a91266abf        3 days ago          191MB
runoobs/centos      dev                 af0a91266abf        3 days ago          191MB
centos              6.7                 9f1de3c6ad53        4 years ago         191MB
[root@localhost ~]# docker rmi af0a91266abf
Error response from daemon: conflict: unable to delete af0a91266abf (must be forced) - image is referenced in multiple repositories
[root@localhost ~]# docker rmi runoob/centos:6.7
Untagged: runoob/centos:6.7
[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
runoob/centos       dev                 af0a91266abf        3 days ago          191MB
runoobs/centos      dev                 af0a91266abf        3 days ago          191MB
centos              6.7                 9f1de3c6ad53        4 years ago         191MB
[root@localhost ~]# docker rmi runoob/centos:dev
Untagged: runoob/centos:dev
[root@localhost ~]# docker rmi runoobs/centos:dev
Untagged: runoobs/centos:dev
Deleted: sha256:af0a91266abf175a9caf3c67bb27c3cb6562b4d83de95e7bd77b5997c8dc0686
Deleted: sha256:225581d622346d927c4b1af37e4c75482c0bd9ec111c6c1f9b0e2745a13b3c82
Deleted: sha256:f6b3e6c56497958e79489f884ffa99638387e656adade79ddb43d32c267ea079
Deleted: sha256:2f3f99ed23bcb25b0ef87b6da29a9a1323d1a3a2a9024967aa5e483fa5748b84
Deleted: sha256:8b4e334b1782164ab46f0818e513ded5ff53672b5641886043dc9dc87681cbcb
Deleted: sha256:7c1b81229bde154f0f2288dc241b4091b76b383d1ee35c8b22da99ff54ee1bb5
Deleted: sha256:b73497b882966840e867e278e2967eb1bdbc7638cea2a3bbb0a4f358cf49eca4
Deleted: sha256:26e78e871c9e4c0b03d85f0880839556270ec799844c5f34aa01983ae443a29d
Deleted: sha256:fbdd06e5ffd3d41dd87ad8f444cb6c5f2ffa1bca6648a6af191b26fc70b00ce7
Deleted: sha256:507915645cdc9c3cb5e13ee196dc134c7c282aa346d81f76757f10915a6cdbff
Deleted: sha256:4ad64ac7cbbff7f6ab5a14cb34213cb1dc7f3a59330a2f603e19d186d190ba94
Deleted: sha256:2a9f0762341fecd04442dd336c2407f5917745fddb30c152e48164195524e6ab
[root@localhost ~]# docker rmi centos:6.7
Untagged: centos:6.7
Untagged: centos@sha256:4c952fc7d30ed134109c769387313ab864711d1bd8b4660017f9d27243622df1
Deleted: sha256:9f1de3c6ad53a67037c8d8891487aa7ce203ceed2b1cee1682f2557925279f33
Deleted: sha256:69bd93b9db4e01f67316852e99bec9d8b3a657e0de17911994627360a16cb022
[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

Docker 启动出错

[root@localhost ~]# docker start docker
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
Error: failed to start containers: docker


# 解决方案:
[root@localhost ~]# vi /etc/docker/daemon.json
# 添加如下内容
{

"registry-mirrors": ["https://docker.mirrors.ustc.edu.cn"]

}

docker 运行 python 之后 pip 下载出现问题

  _start_new_thread(self._bootstrap, ())
RuntimeError: can't start new thread

[notice] A new release of pip is available: 23.0.1 -> 23.2.1
[notice] To update, run: pip install --upgrade pip

 
 # 解决方案:
 你的docker版本太老了,需要升级 docker, 具体原因要自己查一下..
 
 
# 升级方案:
# 如果是重要的数据, 记得要做备份啊!!! 备份 备份!!!
# 前提是你必须确保之前的 docker 已经删除完毕.
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
yum -y install docker-ce

有道笔记

posted @ 2023-08-11 17:21  Handsome、Snake  阅读(80)  评论(0编辑  收藏  举报