docker使用手册

docker使用手册

      • 一、安装Docker
      • 二、Docker相关命令
      • 1、镜像
      • 2、容器相关操作
      • 三、Dockerfile
      • 四、Docker小项目
        • 1、dockerfile部署nginx服务
      • 五、搭建Docker私有仓库
      • 六、企业级镜像仓库Harbor
      • 前提条件
        • 为Harbor配置https访问
      • Docker故障排查

一、安装Docker

  • 基础
    在电脑上安装VMware并安装centos7
  • 换yum源
    因为centos的yum源是国外的镜像仓库,一般多比较慢,或者连不上,所以将yum源换成国内阿里的(或者其他)。参考:阿里官方切换Yum源教程 。
    如果切换yum源之后还是不能通过yum下载(比如一值ERROR12,ERROR14),那可能是网络问题,换成自己手机热点或者其他的网络试试(有时候网络问题虽然可以ping通mirrors.aliyun.com但还是yum安装出现问题,作者本人的血泪经历)
  • 安装yum源
[root@linux-node1 ~]# cd /etc/yum.repos.d/
[root@linux-node1 yum.repos.d]# wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
  • 下载docker
yum install docker-ce

docker分企业版(EE)和社区版(CE),社区版免费,企业版收钱,两个版本更新速度不一样。

  • 启动docker
systemctl start docker

二、Docker相关命令

1、镜像

  • docker pull:从dockerhub查找镜像
[root@k8s-master ~]# docker search centos   
NAME                              DESCRIPTION                                     STARS     OFFICIAL<是否为docker官方发布>   AUTOMATED
centos                            The official build of CentOS.                   6789      [OK]       
  • 查看镜像
    docker image
  • 拉取镜像
    docker pull
  • 将镜像做成离线压缩包/解压离线压缩包:
    save/load
    docker save -o centos.tar.gz centos
    docker load -i centos.tar.gz

2、容器相关操作

  • 创建容器并启动
    docker run
    创建的容器在前台执行
docker run centos<镜像名称> /bin/echo 'HE' <要在容器执行的指令>

创建并进入容器内部: -it

[root@linux-node1 ~]#docker run --name mydocker -it centos /bin/bash
[root@1b0cae722fa0 /]#

让容器后台运行

 [root@linux-node1 ~]# docker run -d --name mydocker2 centos /bin/bash

容器已经创建但是未启动

[root@linux-node2 maiyp]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS               NAMES
20273b3451bf        centos              "/bin/bash"              9 hours ago         Exited (0) 3 seconds ago                       mypdocker
[root@linux-node2 maiyp]# docker start mypdocker
mypdocker
[root@linux-node2 maiyp]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                   PORTS               NAMES
20273b3451bf        centos              "/bin/bash"              9 hours ago         Up 19 seconds                                mypdocker
  • 进入容器
    attach
    进入容器时,如果多个终端同时attach到同一个容器,所有的终端都会同步显示
docker attach mydocker

nsenter
使用nsenter可以访问另一个进程的名字空间
先获取容器的第一个进程的PID,然后通过PID进入容器

PID=$( docker inspect --format "{{ .State.Pid }}" <容器名或ID>) )
#如果容器没有启动,PID为0
nsenter --target $PID --mount --uts --ipc --net --pid

通过脚本进入容器

[root@linux-node2 maiyp]# cat docker_in.sh 
#!/bin/bash

docker_in(){
docker_nm=$1
docker_pid=$( docker inspect --format "{{ .State.Pid }}" $docker_nm)
if [ $docker_pid -eq 0 ]
then
	echo "the docker is not starting!"
	exit -1
fi
nsenter --target $docker_pid --mount --uts --ipc --net --pid
}
docker_in $1
[root@linux-node2 maiyp]# ./docker_in.sh mypdocker
[root@20273b3451bf /]# 
#主机名为容器ID前几位

通过exec进入容器

[root@linux-node1 ~]# docker exec mydocker whoami
root
#不进入容器执行命令
[root@linux-node2 maiyp]# docker exec -it mypdocker /bin/bash
[root@20273b3451bf /]# 
#进入容器执行命令

使用docker exec、nsenter进入容器后,执行exit退出容器,容器并不会关闭。但是使用docker attach进入容器,输入exit退出容器后,容器也会自动终止。因为除了attach,nsenter和exec实际中都是开了一个新的shell在执行。而attach是使用容器本身启动的/bin/bash,这个shell环境退出了。那么容器就自动退出了。

  • 将容器做成离线压缩包/解压离线压缩包
    export/import
    docker export -o centos.tar centos(container)
    docker import centos.tar centos

三、Dockerfile

(1)FROM
基础镜像,必须是可以下载下来的,定制的镜像都是基于 FROM 的镜像,这里的 centos就是定制需要的基础镜像。
(2)MAINTAINER
指定镜像的作者信息
(3)RUN
指定在当前镜像构建过程中要运行的命令
包含两种模式
1、Shell
RUN (shell模式,这个是最常用的,需要记住)
RUN echo hello
2、exec模式
RUN “executable”,“param1”,“param2”
RUN [“/bin/bash”,”-c”,”echo hello”]
等价于/bin/bash -c echo hello
(4)EXPOSE指令
仅仅只是声明端口。
作用:
1、帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射。
2、在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。
3、可以是一个或者多个端口,也可以指定多个EXPOSE
格式:EXPOSE <端口1> [<端口2>…]
(5)CMD
类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:
1、CMD 在docker run 时运行。
2、RUN 是在 docker build构建镜像时运行的
作用:
为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。
CMD[“executable”,“param1”,“param2”](exec模式)
CMD command (shell模式)
CMD [“param1”,”param2”] (作为ENTRYPOINT指令的默认参数)
例如:CMD ["/usr/sbin/nginx","-g",“daemon off;”]

(6)ENTERYPOINT
类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。但是, 如果运行 docker run 时使用了 --entrypoint 选项,将覆盖 entrypoint指令指定的程序。

优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。
注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效
格式:
ENTERYPOINT [“executable”,“param1”,“param2”] (exec模式)
ENTERYPOINT command (shell模式)

可以搭配 CMD 命令使用:一般是变参才会使用 CMD ,这里的 CMD 等于是在给 ENTRYPOINT 传参,以下示例会提到。
示例:
假设已通过 Dockerfile 构建了 nginx:test 镜像:
FROM nginx
ENTRYPOINT [“nginx”, “-c”] # 定参
CMD ["/etc/nginx/nginx.conf"] # 变参

1、不传参运行
$ docker run nginx:test
容器内会默认运行以下命令,启动主进程。
nginx -c /etc/nginx/nginx.conf
2、传参运行
$ docker run nginx:test -c /etc/nginx/new.conf
容器内会默认运行以下命令,启动主进程(/etc/nginx/new.conf:假设容器内已有此文件)
nginx -c /etc/nginx/new.conf

(7)COPY
COPY…
COPY[“”…“”]
复制指令,从上下文目录中复制文件或者目录到容器里指定路径。

格式:
COPY [–chown=:] <源路径1>… <目标路径>
COPY [–chown=:] “<源路径1>”,… “<目标路径>”

<源路径>:源文件或者源目录,这里可以是通配符表达式,其通配符规则要满足 Go 的 filepath.Match 规则。例如:
COPY hom* /mydir/
COPY hom?.txt /mydir/
<目标路径>:容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建。

(8)ADD
ADD …
ADD [“”…“”]

ADD 指令和 COPY 的使用格式一致(同样需求下,官方推荐使用 COPY)。功能也类似,不同之处如下:
ADD 的优点:在执行 <源文件> 为 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,会自动复制并解压到 <目标路径>
ADD 的缺点:在不解压的前提下,无法复制 tar 压缩文件。会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。具体是否使用,可以根据是否需要自动解压来决定。
ADD vs COPY
ADD包含类似tar的解压功能
如果单纯复制文件,dockerfile推荐使用COPY

(9)VOLUME
定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。
作用:
1、避免重要的数据,因容器重启而丢失,这是非常致命的。
2、避免容器不断变大。
格式:
VOLUME ["<路径1>", “<路径2>”…]
VOLUME <路径>
在启动容器 docker run 的时候,我们可以通过 -v 参数修改挂载点。
VOLUME [“/data”]

(10)WORKDIR
指定工作目录。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。(WORKDIR 指定的工作目录,必须是提前创建好的)。
docker build 构建镜像过程中的,每一个 RUN 命令都是新建的一层。只有通过 WORKDIR 创建的目录才会一直存在。
格式:
WORKDIR <工作目录路径>
WORKDIR /path/to/workdir
(填写绝对路径)
(11 )ENV
设置环境变量
ENV
ENV =…
以下示例设置 NODE_VERSION =6.6.6, 在后续的指令中可以通过 $ NODE_VERSION

(12)USER
用于指定执行后续命令的用户和用户组,这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在)。
格式:
USER <用户名>[:<用户组>]
USER daemon
USER nginx
USER user
USER uid
USER user:group
USER uid:gid
USER user:gid
USER uid:group

四、Docker小项目

1、dockerfile部署nginx服务

#1.Dockerfile
vim Dockerfile >> EOF
#base image
FROM centos
#Who
MAINTAINER xxx
RUN yum install nginx -y
RUN mkdir -p /var/www/html
COPY index.html /usr/share/nginx/html
# Outside Port
EXPOSE 80
#启动nginx服务
ENTRYPOINT ["/usr/sbin/nginx","-g","daemon off;"]
<<EOF
#2.构建镜像
docker build -t "nginx/xxx:v1" .
#3.使用镜像构建容器
docker run -d --name nginx_test -p 80 nginx/xxx:v1  #此时因为容器没有进程夯住容器,所以容器是stop状态
#4. 启动容器并进入
docker start nginx_test  && docker exec -it nginx_test  /bin/bash

五、搭建Docker私有仓库

docker镜像一般是从dockerhub中下载,dockerhub是docker官方的镜像仓库。不过我们在使用的过程中,会逐渐产生适配自己环境的镜像,因此可以搭建一个私有仓库来存放镜像。私有仓库一般使用registry搭建。
私有仓库的主机IP:172.31.0.25

  1. 拉取镜像
 docker pull registry
 #从dockerhub中拉取registry镜像
  1. 构建容器
docker run -d registry -p 5000:5000 -v /opt/registry:/var/lib/registry registry:latest
#registry容器中的镜像会保留在目录/var/lib/registry中,为了防止删除容器之后,镜像也被删除。需要挂载本地目录/opt/registry到容器中,/opt/registry目录会自动在本机创建
[root@k8s-node1 docker]#  ls  /opt/registry
[root@k8s-node1 docker]# 
[root@k8s-node1 docker]# curl http://172.31.0.25:5000/v2/_catalog
{"repositories":[]}   #镜像列表还是空的
  1. 从另一台机器(172.31.0.32)上传镜像到镜像仓库中
  • 配置Docker信任仓库
修改 /etc/docker/daemon.json文件,加入"insecure-registries": ["172.31.0.25:5000"]
{
  "registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"],
  "insecure-registries": ["172.31.0.25:5000"]
}
 
# --insecure-registry   一般安全传输镜像,需要使用https协议。我们的私有仓库一般是局域中使用,所以直接使用http协议就可以了。
#注意第一行后的逗号,没加上导致docker 起不来。具体看六、Docker故障排查

#重新加载,使配置生效 && 重启服务
 systemctl daemon-reload  && systemctl restart docker.service
  • 上传镜像到私有仓库
[root@k8s-master ~]# docker images |grep busybox
busybox
[root@k8s-master ~]# docker tag busybox 172.31.0.25:5000/busybox:v1
[root@k8s-master ~]# docker images |grep busybox
172.31.0.25:5000/busybox                                          v1         42b97d3c2ae9   7 weeks ago     1.24MB
busybox
[root@k8s-master ~]# docker push 172.31.0.25:5000/busybox:v1
The push refers to repository [172.31.0.25:5000/busybox]
0fd05bf2930d: Pushed 
v1: digest: sha256:b862520da7361ea093806d292ce355188ae83f21e8e3b2a3ce4dbdba0a230f83 size: 527      
  1. 查看私有仓库镜像
[root@k8s-master ~]#  curl http://172.31.0.25:5000/v2/_catalog
{"repositories":["busybox"]}

登录私有仓库主机查看/opt/registry目录
[root@k8s-node1 repositories]# ll
total 0
drwxr-xr-x 5 root root 55 Oct 11 22:26 busybox
[root@k8s-node1 repositories]# pwd
/opt/registry/docker/registry/v2/repositories

六、企业级镜像仓库Harbor

Harbor是一个用于存储和分发Docker镜像的企业级Registry服务器,Harbor提供了更好的性能和安全。

前提条件

硬件

硬件 最低要求 本文使用规格
CPU 2 CPU 2 CPU
内存 4 GB 4 GB
硬盘 40 GB 40 GB

软件

软件 版本 本文使用版本
dcoker 17.06.0-ce+或更高 Docker version 20.10.8
Docker Compose 1.18.0或更高 docker-compose version 1.18.0

说明

说明 规划
内网IP 172.31.0.25
外网IP 117.xx.xx.xx
主机名 k8s-node1

为Harbor配置https访问

由于部署机器为云主机,使用443端口有风险,修改端口为1443

  1. 制作证书

-new:表示生成一个新证书签署请求

-x509:专用于CA生成自签证书,如果不是自签证书则不需要此项

-key:生成请求时用到的私钥文件

-out:证书的保存路径

-days:证书的有效期限,单位是day(天),默认是365天

  • ca证书
    生成ca.key
  openssl genrsa -out ca.key 3072    #生成一个3072位的私钥

生成数字证书ca.pem

openssl req -new -x509 -days 3650 -key ca.key -out ca.pem
  • 生成域名的证书
    生成一个3072位也就是私钥
  openssl genrsa -out harbor.key  3072  #生成一个3072位的私钥

生成一个证书请求,一会签发证书时需要的

#openssl req -new -key harbor.key -out [主机名].csr
[root@k8s-node1 /data/ssl/]# openssl req -new -key harbor.key -out k8s-node1.csr
  • 签发证书
#openssl x509 -req -in harbor.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out [主机名].pem -days 3650
[root@k8s-node1 /data/ssl/]# openssl x509 -req -in harbor.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out k8s-node1.pem -days 3650
  • 将服务器证书和密钥复制到Harbor主机上的/data/cert/文件夹中
mkdir -p /data/cert/
cp /data/ssl/k8s-node1.pem /data/cert/
cp /data/ssl/k8s-node1.key /data/cert/
  • 转换k8s-node1.pem为k8s-node1.cert,供Docker使用
[root@k8s-node1 /data/ssl/]#  openssl x509 -inform PEM -in k8s-node1.crt -out k8s-node1.cert
  • 将服务器证书,密钥和CA文件复制到Harbor主机上的Docker证书文件夹中。您必须首先创建适当的文件夹
[root@k8s-node1 /data/ssl/]#  mkdir -p /etc/docker/certs.d/k8s-node1/
[root@k8s-node1 /data/ssl/]# cp k8s-node1.cert /etc/docker/certs.d/k8s-node1/
[root@k8s-node1 /data/ssl/]# cp k8s-node1.key /etc/docker/certs.d/k8s-node1/
  • 重启docker
[root@k8s-node1 /data/ssl/]# systemctl restart docker
  1. 下载安装包
    从GitHub上下载harbor安装包,建议下载offline的压缩包,里面包含了harbor启动所用的所有docker镜像,可以快速的部署harbor。(在GitHub首页搜索harbor,在结果页面点Releases,可以选择版本)。下载传至主机目录/data/install/harbor

  2. 安装docker-compose
    搜索网上文章可知

  3. 安装harbor

 mkdir /data/install -p
 cd /data/install
 tar zxvf harbor-offline-installer-v2.3.1.tgz
 cd harbor
 vim harbor.yml
 ##harbor.yml begin(修改部分)####
hostname: k8s-node1  #修改hostname 
ui_url_protocol: https  #新增行
...
https:
  # https port for harbor, default is 443
  port: 1443    #修改端口号为1443
  # The path of cert and key files for nginx
   certificate: /data/cert/k8s-node1.pem   #修改文件路径
    private_key: /data/cert/k8s-node1key    #修改文件路径
#######  harbor.yml end ##########

###修改docker-compose.yml begin######
......
    networks:
      - harbor
    dns_search: .
    ports:
      - 80:8080
      - 1443:8443  #修改443为1443
......
###修改docker-compose.yml end######

[root@k8s-node1 /data/install/harbor/]#./prepare
[root@k8s-node1 /data/install/harbor/]#./install.sh
......
看到下面内容,说明安装成功:
[Step 5]: starting Harbor ...
Creating network "harbor_harbor" with the default driver
Creating harbor-log ... done
Creating registryctl   ... done
Creating harbor-db     ... done
Creating redis         ... done
Creating registry      ... done
Creating harbor-portal ... done
Creating harbor-core   ... done
Creating harbor-jobservice ... done
Creating nginx             ... done
✔ ----Harbor has been installed and started successfully.----
  1. 相关使用命令
docker-compose up -d # 后台启动,如果容器不存在根据镜像自动创建
docker-compose down -v # 停止容器并删除容器
docker-compose start # 启动容器,容器不存在就无法启动,不会自动创建镜像
docker-compose stop # 停止容器
  1. 访问
    外网访问
    浏览器输入117.xx.xx.xx:1443 访问,账号:admin,密码在harbor.yml中设置,默认为Harbor12345。
    docker使用手册_第1张图片
    所有基础镜像都会放在library里面,这是一个公开的镜像仓库。新建公开项目test
    docker使用手册_第2张图片

内网访问内网访问harbor的时候走的是http,所以IP写的是内网IP访问主机需要修改 /etc/docker/daemon.json

[root@k8s-master ~]# vim /etc/docker/daemon.json
{
  "registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"],  #换行的逗号别忘了
  "insecure-registries": ["172.31.0.25","k8s-node1"]    #新增
}

重启docker
[root@k8s-master ~]# systemctl daemon-reload && systemctl restart docker
[root@k8s-master ~]#docker login 172.31.0.25
Username: admin
Password: 
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
  1. 上传镜像
[root@k8s-master ~]# docker tag busybox  172.31.0.25/test/busybox:v1
[root@k8s-master ~]# docker push 172.31.0.25/test/busybox:v1
The push refers to repository [172.31.0.25/test/busybox]
0fd05bf2930d: Pushed 
v1: digest: sha256:b862520da7361ea093806d292ce355188ae83f21e8e3b2a3ce4dbdba0a230f83 size: 527

docker使用手册_第3张图片

  1. 下载镜像
[root@k8s-master ~]# docker rmi 172.31.0.25/test/busybox:v1
Untagged: 172.31.0.25/test/busybox:v1
Untagged: 172.31.0.25/test/busybox@sha256:b862520da7361ea093806d292ce355188ae83f21e8e3b2a3ce4dbdba0a230f83

[root@k8s-master ~]# docker images |grep busybox
busybox                                                           latest          42b97d3c2ae9   3 months ago    1.24MB

[root@k8s-master ~]# docker pull 172.31.0.25/test/busybox:v1
v1: Pulling from test/busybox
Digest: sha256:b862520da7361ea093806d292ce355188ae83f21e8e3b2a3ce4dbdba0a230f83
Status: Downloaded newer image for 172.31.0.25/test/busybox:v1
172.31.0.25/test/busybox:v1

[root@k8s-master ~]# docker images |grep busybox
172.31.0.25/test/busybox                                          v1              42b97d3c2ae9   3 months ago    1.24MB
busybox                                                           latest          42b97d3c2ae9   3 months ago    1.24MB
[root@k8s-

Docker故障排查

一般使用systemctl status docker 和 journalctl -u docker.service

  • 启动docker报错
[root@k8s-master ~]# systemctl restart docker
Job for docker.service failed because the control process exited with error code. See "systemctl status docker.service" and "journalctl -xe" for details.
  • 查看状态,但无法看到详细的报错原因
[root@k8s-master ~]# systemctl status docker.service
● docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
   Active: failed (Result: start-limit) since Mon 2021-10-11 21:54:50 CST; 5min ago
     Docs: https://docs.docker.com
  Process: 30461 ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock (code=exited, status=1/FAILURE)
 Main PID: 30461 (code=exited, status=1/FAILURE)

Oct 11 21:54:48 k8s-master systemd[1]: docker.service failed.
Oct 11 21:54:50 k8s-master systemd[1]: docker.service holdoff time over, scheduling restart.
Oct 11 21:54:50 k8s-master systemd[1]: Stopped Docker Application Container Engine.
Oct 11 21:54:50 k8s-master systemd[1]: start request repeated too quickly for docker.service
Oct 11 21:54:50 k8s-master systemd[1]: Failed to start Docker Application Container Engine.
Oct 11 21:54:50 k8s-master systemd[1]: Unit docker.service entered failed state.
Oct 11 21:54:50 k8s-master systemd[1]: docker.service failed.
Oct 11 21:54:50 k8s-master systemd[1]: start request repeated too quickly for docker.service
Oct 11 21:54:50 k8s-master systemd[1]: Failed to start Docker Application Container Engine.
Oct 11 21:54:50 k8s-master systemd[1]: docker.service failed.

  • 查看具体报错原因
[root@k8s-master ~]# journalctl -u docker.service
-- Logs begin at Mon 2021-10-11 09:49:18 CST, end at Mon 2021-10-11 21:55:56 CST. --
Oct 11 21:15:15 k8s-master systemd[1]: Starting Docker Application Container Engine...
Oct 11 21:15:15 k8s-master dockerd[16812]: unable to configure the Docker daemon with file /etc/docker/daemon.json: invalid character '"' after object key:value pair
Oct 11 21:15:15 k8s-master systemd[1]: docker.service: main process exited, code=exited, status=1/FAILURE
Oct 11 21:15:15 k8s-master systemd[1]: Failed to start Docker Application Container Engine.
Oct 11 21:15:15 k8s-master systemd[1]: Unit docker.service entered failed state.
Oct 11 21:15:15 k8s-master systemd[1]: docker.service failed.
Oct 11 21:15:18 k8s-master systemd[1]: docker.service holdoff time over, scheduling restart.
Oct 11 21:15:18 k8s-master systemd[1]: Stopped Docker Application Container Engine.
Oct 11 21:15:18 k8s-master systemd[1]: Starting Docker Application Container Engine...
Oct 11 21:15:18 k8s-master dockerd[16820]: unable to configure the Docker daemon with file /etc/docker/daemon.json: invalid character '"' after object key:value pair

#可以看到docker 无法启动是因为/etc/docker/daemon.json里有无法识别的字符,原因是文件换行之间漏掉了逗号,
{
  "registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"]
  "insecure-registries": ["172.31.0.25:5000"]
}
 

你可能感兴趣的:(Docker,docker,centos,linux)