云边日落 山外青山楼外楼,西湖歌舞几时休。 (宋·林升·题临安邸)
博主 云边日落
渝ICP备2021002886号-1渝公网安备50022502000591号博主 11月5日 在线自豪地使用 Typecho 建站搭配使用 🌻Sunny 主题当前在线 7 人
歌曲封面 未知作品
  • 歌曲封面“魔女の宅急便”~ルージュの伝言松任谷由実

渝ICP备2021002886号-1

渝公网安备50022502000591号

网站已运行 4 年 152 天 15 小时 9 分

Powered by Typecho & Sunny

8 online · 43 ms

Title

一文搞定docker

酒笙

·

·

2047次阅读
docker
Article
⚠️ 本文最后更新于2022年10月19日,已经过了764天没有更新,若内容或图片失效,请留言反馈

docker·

 大家好呀,我们今天又又又来开新坑了,今天这个坑就是Docker了,我们今天开始就要来了解一下Docker了。
博客地址: 云边日落
作者:酒笙
结尾有pdf版,需要自取。
c6948122701920d9581b2f8754023e3c.png

什么是docker

  1. docker发展史

    • 在最开始的时候,docker不叫docker,叫dotcloud。这是由几个年轻人成立的小公司,在当时这样的一个小公司混的还算不错,但是还是打不过大厂,paas市场竞争激烈,dotcloud举步维艰,最后这些年轻人不甘心,不能让自己的坚持与努力付之东流,于是便把他们的核心技术开源,也就是docker,在当时的话,docker的主要功能就是把Linux的代码打包,应用在其他开发平台中。最后这个docker就风靡全球,于是乎,dotcloud就索性改名docker了,并且就全身心的投入到了docker的开发之中
  2. docker的应用场景

    • Web应用的自动化打包和发布
    • 自动化测试和持续继承、发布
    • 在服务型环境中部署和调试数据库或其他后台应用
    • 从头编译或者拓展现有的openshift或cloud foundry平台来搭建自己的PaaS环境。
  3. docker的优势

    • docker 启动快速属于秒级别。虚拟机通常需要几分钟去启动
    • docker 需要的资源更少, docker 在操作系统级别进行虚拟化, docker 容器和内核交互,几乎没有性能损耗,性能优于通过 Hypervisor 层与内核层的虚拟化
    • docker 更轻量, docker 的架构可以共用一个内核与共享应用程序库,所占内存极小。同样的硬件环境, Docker 运行的镜像数远多于虚拟机数量,对系统的利用率非常高
    • 与虚拟机相比, docker 隔离性更弱, docker 属于进程之间的隔离,虚拟机可实现系统级别隔
    • 安全性: docker 的安全性也更弱。 Docker 的租户 root 和宿主机 root 等同,一旦容器内的用户从普通用户权限提升为root权限,它就直接具备了宿主机的root权限,进而可进行无限制的操作。虚拟机租户 root 权限和宿主机的 root 虚拟机权限是分离的,并且虚拟机利用如 Intel 的 VT-d 和 VT-x 的 ring-1 硬件隔离技术,这种隔离技术可以防止虚拟机突破和彼此交互,而容器至今还没有任何形式的硬件隔离,这使得容器容易受到攻击
    • 可管理性: docker 的集中化管理工具还不算成熟。各种虚拟化技术都有成熟的管理工具,例如 VMware vCenter 提供完备的虚拟机管理能力
    • 高可用和可恢复性: docker 对业务的高可用支持是通过快速重新部署实现的。虚拟化具备负载均衡,高可用,容错,迁移和数据保护等经过生产实践检验的成熟保障机制, VMware 可承诺虚拟机 99.999% 高可用,保证业务连续性
    • 快速创建、删除:虚拟化创建是分钟级别的, Docker 容器创建是秒级别的, Docker 的快速迭代性,决定了无论是开发、测试、部署都可以节约大量时间
    • 交付、部署:虚拟机可以通过镜像实现环境交付的一致性,但镜像分发无法体系化。 Docker 在 Dockerfile 中记录了容器构建过程,可在集群中实现快速分发部署

dockers的三个基本概念

  1. image(镜像)
  2. container(容器)
  3. repository(仓库)
  4. image(镜像)
  5. 镜像是docker运行的前提,仓库是存放镜像的地方,那么镜像就是核心了。
  6. Docker 镜像可以看作是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。
  • 我们简单来说一下,这个储存格式-联合文件系统,这是一个分层的问阿金系统,可以将不同的目录挂载到同一个虚拟文件下。那么我们docker的镜像就是使用的这样一个文件系统。
  • 下图就是镜像的存储格式,这张图是分层的,最下面一层,上面也是一层层的好像集装箱罗列在一起.这就是镜像最直观的存储方式.下面是操作系统的引导,上面是linux操作系统,再上面是一些相关的软件,如果是我们自己的程序,就可以是tomcat,jdk,再往上是应用代码,每一层是我们自己都可以控制得,最上面一层先忽略不看,因为这是和容器有关的.注意一点,docker镜像系统的每一层都是只读的,然后把每一层加载完成之后这些文件都会被看成是同一个目录,相当于只有一个文件系统.docker的这种文件系统被称之为镜像.
  1. container(容器)

    为了便于理解,大家可以把容器想象成虚拟机,每个虚拟机都有自己的文件系统,可以把图1整个一部分看成是文件系统,与虚拟机系统的区别是这里面的文件系统是一层一层的,并且最下面的n层都是只读的,只有上面一层是可写的.为什么要有可写的这层呢?大家的程序运行起来,势必会要写一些日志,写一些文件,或者对系统的某一些文件做一些修改,所以容器在最上面一层创建了可读可写的文件系统.

    在程序的运行过程中,如果要写镜像文件时,因为镜像的每一层都是只读的,它会把文件的每一层拷到文件的最上层,然后再对它进行修改,修改之后,当我们的应用读一个文件时会从顶层进行查找,如果没有才会找下一层.

    由于容器的最上一层是可以修改的,镜像是不能修改的,这样就能保证镜像可以生成多个容器独立运行,没有任何干扰.

    简要的概括就是:容器 = 镜像 + 读写层。

  2. repository(仓库)

    • Docker 仓库是集中存放镜像文件的场所。镜像构建完成后,可以很容易的在当前宿主上运行,但是, 如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry (仓库注册服务器)就是这样的服务。有时候会把仓库 (Repository) 和仓库注册服务器 (Registry) 混为一谈,并不严格区分。Docker 仓库的概念跟 Git 类似,注册服务器可以理解为 GitHub 这样的托管服务。实际上,一个 Docker Registry 中可以包含多个仓库 (Repository) ,每个仓库可以包含多个标签 (Tag),每个标签对应着一个镜像。所以说,镜像仓库是 Docker 用来集中存放镜像文件的地方类似于我们之前常用的代码仓库。

    通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本 。我们可以通过<仓库名>:<标签>的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签.。

仓库又可以分为两种形式:

  • public(公有仓库)
  • private(私有仓库)
  • Docker Registry 公有仓库是开放给用户使用、允许用户管理镜像的 Registry 服务。一般这类公开服务允许用户免费上传、下载公开的镜像,并可能提供收费服务供用户管理私有镜像。
  • 除了使用公开服务外,用户还可以在本地搭建私有 Docker RegistryDocker 官方提供了 Docker Registry镜像,可以直接使用做为私有 Registry 服务。当用户创建了自己的镜像之后就可以使用 push 命令将它上传到公有或者私有仓库,这样下次在另外一台机器上使用这个镜像时候,只需要从仓库上 pull 下来就可以了。
  • 我们主要把 Docker 的一些常见概念如 ImageContainerRepository 做了详细的阐述,也从传统虚拟化方式的角度阐述了 docker 的优势,我们从下图可以直观地看到 Docker 的架构:
    1100338-20181011200344086-1510826338.png
  • Docker 使用 C/S 结构,即客户端/服务器体系结构。 Docker 客户端与 Docker 服务器进行交互,Docker服务端负责构建、运行和分发 Docker 镜像。 Docker 客户端和服务端可以运行在一台机器上,也可以通过 RESTfulstock 或网络接口与远程 Docker 服务端进行通信。
1100338-20181011200343656-1972949758.png
  • 这张图展示了 Docker 客户端、服务端和 Docker 仓库(即 Docker HubDocker Cloud ),默认情况下Docker 会在 Docker 中央仓库寻找镜像文件,这种利用仓库管理镜像的设计理念类似于 Git ,当然这个仓库是可以通过修改配置来指定的,甚至我们可以创建我们自己的私有仓库。

docker安装

1.下载关于Docker的依赖环境

♾️ python 代码:

yum -y install yum-utils device-mapper-persistent-data lvm2

2.设置下载Docker的镜像源

♾️ python 代码:

yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

3.安装Docker

♾️ python 代码:

yum makecache fast
yum -y install docker-ce

4.启动Docker,并设置为开机自动启动,测试

♾️ python 代码:
# 启动Docker服务
systemctl start docker
# 设置开机自动启动
systemctl enable docker
# 测试
docker run hello-world
  1. 查看刚才下载的hello-word镜像
♾️ shell 代码:
docker images
卸载docker
  1. 删除依赖
♾️ shell 代码:
yum remove docker-ce docker-ce-cli containerd.io
  1. 删除资源
♾️ shell 代码:
rm -rf /var/lib/docker
rm -rf /var/lib/containerd
#  /var/lib/docker       docker工作的默认路径
阿里云镜像加速
  1. 登录阿里云

    {abtn icon="fa-heart-o" color="#f86dc5" href="https://www.aliyun.com/" radius="17px" content="阿里云"/}

  2. 在弹性计算找到容器计算服务
image-20210720101445457.png
  1. 创建账号然后点击镜像工具里面的镜像加速
image-20210720101625198.png
  1. 配置使用
♾️ shell 代码:
    sudo mkdir -p /etc/docker
    sudo tee /etc/docker/daemon.json <<-'EOF'
    {
      "registry-mirrors": ["https://vjtmk5k2.mirror.aliyuncs.com"]
    }
    EOF
    sudo systemctl daemon-reload
    sudo systemctl restart docker
  1. 查看是否配置成功
♾️ python 代码:
 cat /etc/docker/daemon.json 
    /*返回如下
    {
      "registry-mirrors": ["https://vjtmk5k2.mirror.aliyuncs.com"]
    }
    */

运行过程

运行流程图.jpg

底层原理

docker是怎样工作做的?

  • Docker Engine是一个客户端-服务器应用程序,具有以下主要组件:
  • 一个服务器,它是一种长期运行的程序,称为守护进程(dockerd命令)。
  • 一个REST API,它指定程序可以用来与守护进程对话并指示它做什么的接口。
  • 命令行接口(CLI)客户端(docker命令)。
  • Docker是一个Client Server结构的系统,Docker守护进程运行在主机上,然后通过Socket连接从客户 端访问,守护进程从客户端接受命令并管理运行在主机上的容器。
底层运行图.png

docker为什么比VM快?

  1. Docker不需要Hypervisor实现硬件资源虚拟化,运行在Docker容器上的程序直接使用的都是实际物理机的硬件资源。因此在CPU、内存利用率上Docker将会在效率上有明显优势。
  2. Docker利用的是宿主机的内核,而不需要GuestOS。因此,当新建一个容器时,Docker不需要和虚拟机一样重新加载一个操作系统内核。可避免引导寻址、加载操作系统内核返回这个比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载GuestOS,返回新增过程是分钟级别的。而Docker由于利用宿主机的操作系统,则省略了返回的过程,因此新建一个Docker容器只需要几秒钟。
图.png

docker基本命令

4a707dadbe31eacd92cfe425c5d437b6.jpg

帮助命令

♾️ shell 代码:
docker version    #版本信息
docker info         #系统信息
docker 命令 --help    #帮助命令

帮助文档地址:https://docs.docker.com/engine/reference/

镜像命令

docker images 查看本机所有镜像

♾️ shell 代码:
[root@jiusheng]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
hello-world   latest    d1165f221234   4 months ago   13.3kB

#REPOSITORY            镜像仓库源
#TAG                          镜像标签
#IMAGE ID                 镜像id
# CREATED                 镜像创建的时间
#SIZE                          镜像大小


#可选项

  -a , --all                   #列出所有镜像
  -q , --quiet              #显示镜像id

docker search 搜索镜像

♾️ shell 代码:
# 官网搜索: https://hub.docker.com/
docker search 搜索名
#搜索MySQL镜像
docker search mysql

[root@jiusheng]# docker search mysql
NAME                              DESCRIPTION                                                           STARS     OFFICIAL    AUTOMATED
mysql                             MySQL is a widely used, open-source relation…       11147        [ OK]       
mariadb                           MariaDB Server is a high performing open sou…     4228        [OK]       

#条件搜索
 --filter=STARS=5000        #搜索出来的镜像就是STARS大于5000的
 
 [root@jisuheng]# docker search mysql --filter=STARS=5000
NAME      DESCRIPTION                                                        STARS     OFFICIAL   AUTOMATED
mysql     MySQL is a widely used, open-source relation…     11147     [OK]       

 
 

docker pull 下载镜像

♾️ shell 代码:
#下载镜像 docker pull 镜像名[:tag]    下载指定版本

docker pull 镜像名    #默认下载最新版本

[root@jiusheng]# docker pull mysql
Using default tag: latest     #不填写指定版本,默认下载最新版本
latest: Pulling from library/mysql
b4d181a07f80: Pull complete                #分层下载,也就是 docker iamge核心,联合文件系统
b4d181a07f80: Pull complete               
a462b60610f5: Pull complete 
578fafb77ab8: Pull complete 
524046006037: Pull complete 
d0cbe54c8855: Pull complete 
aa18e05cc46d: Pull complete 
fd6f649b1d0a: Pull complete 
2a97d48c2fdc: Pull complete 
30f0c7db48fc: Pull complete 
f5dda8df049e: Pull complete 
671b83fd7448: Pull complete 
5d9cc55fa997: Pull complete 
Digest: sha256:18d8d109aa64673c78aebfb845b929cfdac97a553332f4310f4de8d67ceb03d2
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest
#真实地址等价于 docker pull mysql   =   docker pull  docker.io/library/mysql:latest




#下载指定版本
docker pull mysql:5.7
#具体有哪些版本可以去官网查看,不要乱写

[root@jiusheng]# docker pull mysql:5.7
5.7: Pulling from library/mysql
b4d181a07f80: Already exists      #这就是分层下载的好处,只下载不一样的。
a462b60610f5: Already exists 
578fafb77ab8: Already exists 
524046006037: Already exists 
d0cbe54c8855: Already exists 
aa18e05cc46d: Already exists 
fd6f649b1d0a: Already exists 
8a2b858b000b: Pull complete 
322182b17422: Pull complete 
070e28050a88: Pull complete 
613bdfd8796e: Pull complete 
Digest: sha256:956e11ac581cad9ac8747a9a1d61b8ffcfa6845e0f23bdbab6ba20a2ad792cbf   #这是一个签名
Status: Downloaded newer image for mysql:5.7        #版本
docker.io/library/mysql:5.7


docker rmi 删除镜像

♾️ shell 代码:
docker rmi -f 镜像id     #删除指定镜像
docker rmi -f 镜像id,镜像id    #删除多个指定镜像
docker rmi -f $(docker images -aq)      #使用递归删除所有镜像

容器命令

有了镜像之后,才可以创建容器,容器依赖于镜像。

我们这里下载一个centos的镜像

♾️ shell 代码:
docker pull centos

新建容器并启动

♾️ shell 代码:
docker run [可选参数] images

#参数说明
 
--name="Name"   #容器名字,用于区分容器
-d                  #后台方式运行
-it                    #使用交互式运行,并进入容器查看内容
-p                          #指定容器端口
    -p ip : 主机端口 : 容器端口
    -p 主机端口 :容器端口 常用
    -p 容器端口
    
-P                        随机容器端口

测试,启动并进入容器

♾️ shell 代码:
[root@jiusheng]# docker run -it centos /bin/bash
[root@2d13e5147554 /]# ls    #查看容器内的centos
bin  etc   lib      lost+found  mnt  proc  run   srv  tmp  var
dev  home  lib64  media       opt  root  sbin  sys  usr
[root@2d13e5147554 /]# 

退出容器

♾️ shell 代码:
exit        #停止容器并退出
Ctrl + p + q  #容器不停止退出

列出所有运行的容器

♾️ shell 代码:
#docker ps (可选参数)
docekr ps      #列出正在运行的容器
docker ps -a #列出当前正在运行的容器和历史运行的容器
docker ps -n=?  #显示最近创建的容器,?是数字,表示显示几个
docker -p       #显示容器编号
#示例
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker ps -n=1
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS                     PORTS     NAMES
2d13e5147554   centos    "/bin/bash"   6 minutes ago   Exited (0) 4 minutes ago             heuristic_tu
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker ps -n=4
CONTAINER ID   IMAGE          COMMAND       CREATED         STATUS                     PORTS     NAMES
2d13e5147554   centos         "/bin/bash"   6 minutes ago   Exited (0) 4 minutes ago             heuristic_tu
ff7056f81cfe   d1165f221234   "/hello"      25 hours ago    Exited (0) 25 hours ago              nervous_kalam

删除容器

和前面删除镜像的方式一样,只是镜像是rmi而容器是rm,殊途同归
♾️ shell 代码:
docker rm 容器id                               #删除指定容器,同时如果容器在运行,就不能删除
docker rm -f $(docker ps -aq)          #使用递归删除所有容器
docker ps -a -q |xargs docker rm    #删除所有容器,也可写作docker ps -aq|xargs docker rm

启动和停止容器

♾️ shell 代码:
docker start 容器id              #启动容器
docker restart 容器id           #重启容器
docker stop 容器id              #停止当前运行容器
docker kill 容器id                #强制停止当前容器

其他常用命令

后台启动容器

♾️ shell 代码:
#docker run -d 镜像名
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker run -d centos
3c7893d0514ae66e0d31bc9efb725b98504467599376e494dcea47d629a13dbf
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@iZj6c5ctiawsbu90vbskdwZ ~]# 
#这里我们通过docker ps 发现容器停止了,那么是怎么一会事,我们说一说。

#docekr 容器在使用后台运行的时候,如果说没有一个前台进程,那么就会自动停止,也就是说,如果要使用后台运行,就必须要有一个前台进程!

查看日志

♾️ shell 代码:
docker logs -f -t --tail  ?容器id   #?表示数字,即你要显示多少条日志,同时-f -t可以写在一起即-tf

docker logs -f t 容器id   #显示全部日志

显示容器进程信息

♾️ shell 代码:
docker top 容器id
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker top 1ff8b6186c5f
UID                 PID                    PPID                C                   STIME               TTY                 TIME                CMD
root                22368               22349               0                   11:08               pts/0               00:00:00            /bin/bash

查看镜像元数据

♾️ shell 代码:
docker inspect top 容器id
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker ps
 CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS         PORTS     NAMES
1ff8b6186c5f   centos    "/bin/bash"   10 seconds ago   Up 9 seconds             inspiring_thompson
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker inspect 1ff8b6186c5f
[
    {
        "Id": "1ff8b6186c5f5d19b715a5c320b7ecb330f9e570e9bba2ff82bce2ceb7344262",
        "Created": "2021-07-21T03:08:39.027552726Z",
        "Path": "/bin/bash",
        "Args": [],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 22368,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2021-07-21T03:08:39.311797803Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        "Image": "sha256:300e315adb2f96afe5f0b2780b87f28ae95231fe3bdd1e16b9ba606307728f55",
        "ResolvConfPath": "/var/lib/docker/containers/1ff8b6186c5f5d19b715a5c320b7ecb330f9e570e9bba2ff82bce2ceb7344262/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/1ff8b6186c5f5d19b715a5c320b7ecb330f9e570e9bba2ff82bce2ceb7344262/hostname",
        "HostsPath": "/var/lib/docker/containers/1ff8b6186c5f5d19b715a5c320b7ecb330f9e570e9bba2ff82bce2ceb7344262/hosts",
        "LogPath": "/var/lib/docker/containers/1ff8b6186c5f5d19b715a5c320b7ecb330f9e570e9bba2ff82bce2ceb7344262/1ff8b6186c5f5d19b715a5c320b7ecb330f9e570e9bba2ff82bce2ceb7344262-json.log",
        "Name": "/inspiring_thompson",
        "RestartCount": 0,
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": null,
        "HostConfig": {
            "Binds": null,
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "default",
            "PortBindings": {},
            "RestartPolicy": {
                "Name": "no",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "CapAdd": null,
            "CapDrop": null,
            "CgroupnsMode": "host",
            "Dns": [],
            "DnsOptions": [],
            "DnsSearch": [],
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "private",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": null,
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "Runtime": "runc",
            "ConsoleSize": [
                0,
                0
            ],
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": [],
            "BlkioDeviceReadBps": null,
            "BlkioDeviceWriteBps": null,
            "BlkioDeviceReadIOps": null,
            "BlkioDeviceWriteIOps": null,
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": [],
            "DeviceCgroupRules": null,
            "DeviceRequests": null,
            "KernelMemory": 0,
            "KernelMemoryTCP": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": null,
            "OomKillDisable": false,
            "PidsLimit": null,
            "Ulimits": null,
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0,
            "MaskedPaths": [
                "/proc/asound",
                "/proc/acpi",
                "/proc/kcore",
                "/proc/keys",
                "/proc/latency_stats",
                "/proc/timer_list",
                "/proc/timer_stats",
                "/proc/sched_debug",
                "/proc/scsi",
                "/sys/firmware"
            ],
            "ReadonlyPaths": [
                "/proc/bus",
                "/proc/fs",
                "/proc/irq",
                "/proc/sys",
                "/proc/sysrq-trigger"
            ]
        },
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/f374005ba37d8dd511a5663780d1a6d9f73721853d0f865f93fa06c294099b6e-init/diff:/var/lib/docker/overlay2/95fb52765b6ea97468e0c38889f47d9e3c95d2e69d556c18798f00ebb3e2cfb1/diff",
                "MergedDir": "/var/lib/docker/overlay2/f374005ba37d8dd511a5663780d1a6d9f73721853d0f865f93fa06c294099b6e/merged",
                "UpperDir": "/var/lib/docker/overlay2/f374005ba37d8dd511a5663780d1a6d9f73721853d0f865f93fa06c294099b6e/diff",
                "WorkDir": "/var/lib/docker/overlay2/f374005ba37d8dd511a5663780d1a6d9f73721853d0f865f93fa06c294099b6e/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [],
        "Config": {
            "Hostname": "1ff8b6186c5f",
            "Domainname": "",
            "User": "",
            "AttachStdin": true,
            "AttachStdout": true,
            "AttachStderr": true,
            "Tty": true,
            "OpenStdin": true,
            "StdinOnce": true,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/bin/bash"
            ],
            "Image": "centos",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {
                "org.label-schema.build-date": "20201204",
                "org.label-schema.license": "GPLv2",
                "org.label-schema.name": "CentOS Base Image",
                "org.label-schema.schema-version": "1.0",
                "org.label-schema.vendor": "CentOS"
            }
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "236a57971cd0b33ec1fd5b3c8cd725fabd85aef3a796de461a699c42b6e289f6",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {},
            "SandboxKey": "/var/run/docker/netns/236a57971cd0",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "03ed818c13a101bd6254b5e5c18ede6f9c776efb2e65ac382f711b8f8b265b2b",
            "Gateway": "172.17.0.1",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.17.0.2",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "MacAddress": "02:42:ac:11:00:02",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "3be7a57080be0d228e4f459c30ed8bc85ab61b84ac10ddbeaa546ad97f294539",
                    "EndpointID": "03ed818c13a101bd6254b5e5c18ede6f9c776efb2e65ac382f711b8f8b265b2b",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:02",
                    "DriverOpts": null
                }
            }
        }
    }
]

进入当前正在运行的容器

我们通常都是通过后台方式运行,需要进入容器修改配置信息
♾️ shell 代码:
#方式一
docker exec -it 容器id BashShell

[root@jiusheng]# docker exec -it  1ff8b6186c5f /bin/bash
[root@1ff8b6186c5f /]# ls
bin  etc   lib      lost+found  mnt  proc  run   srv  tmp  var
dev  home  lib64  media       opt  root  sbin  sys  usr

#方式二
docker attach 容器id

[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker attach 1ff8b6186c5f
[root@1ff8b6186c5f /]# 


#区别

docker exec  进入容器后开启新的终端
docker attach  进入容器正在执行的终端,不会启动新终端

从容器拷贝数据到本机

docker cp 容器id:容器内路径 目的路径
♾️ shell 代码:
#进入容器内部
[root@1ff8b6186c5f /]# cd /home
[root@1ff8b6186c5f home]# ls
#在容器内部新建一个文件
[root@1ff8b6186c5f home]# touch jiusheng.np
[root@1ff8b6186c5f home]# exit
exit
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND       CREATED       STATUS                      PORTS     NAMES
1ff8b6186c5f   centos    "/bin/bash"   3 hours ago   Exited (0) 16 seconds ago             inspiring_thompson
3c7893d0514a   centos    "/bin/bash"   3 hours ago   Exited (0) 3 hours ago                clever_lalande
#把文件拷贝到本机
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker cp 1ff8b6186c5f:/home/jiusheng.np /home
[root@iZj6c5ctiawsbu90vbskdwZ ~]# cd /home
[root@iZj6c5ctiawsbu90vbskdwZ home]# ls
admin  jiusheng.np

#我们可以卡看到哈,在容器里面建立的jiusheng.np,我们已经复制到了本机的home目录里面。

小结

f27d6a7d3f1f098f727223b8c7b16fe8.png
勤能补拙,温故而知新
docker命令导图.png♾️ shell 代码:
attach    Attach to a running container #当前 shell 下 attach 连接指定运行镜像
build      Build an image from a Dockerfile #通过 Dockerfile 定制镜像
commit  create a new image from a container changes #提交当前容器为新的镜像
cp          copy files/folders from the containers filesystem to the host path #从容器中拷贝指定文件或者目录到宿主机中
create    Create a new container #创建一个新的容器,同 run,但不启动容器
diff         Inspect changes on a container's filesystem #查看 docker 容器变化
events    Get real time events from the server #从docker 服务获取容器实时事件
exec       Run a command in an existing container #在已存在的容器上运行命令
export   Stream the contents of a container as a tar archive #导出容器的内容流作为一个 tar 归档文件[对应import ]
history  Show the history of an image #展示一个镜像形成历史
images  List images # 列出系统当前镜像
import  create a new filesystem image from the contents of a tarball #从tar包中的内容创建一个新的文件系统映像[对应export]
info       Display system-wide information # 显示系统相关信息
inspect  Return low-level information on a container #查看容器详细信息
kill         Kill a running container #kill 指定 docker 容器
load      Load an image from a tar archive # 从一个 tar 包中加载一个镜像[对应 save]
login     Register or Login to the docker registry server # 注册或者登陆一个 docker 源服务器
logout  Log out from a Docker registry server # 从当前 Docker registry 退出
logs      Fetch the logs of a container #输出当前容器日志信息
port      Lookup the public-facing port which is NAT-ed to PRIVATE_PORT #查看映射端口对应的容器内部源端
pause   pause all processes within a container #暂停容器
ps         List containers #列出容器列表
pull        the docker registry server #从docker镜像源服务器拉取指定镜像
push      Push an image or a repository to the docker registry server # 推送指定镜像或者库镜像至docker源服务器
restart    Restart a running container #重启运行的容器
rm           Remove one or more containers # 移除一个或者多个容器
rmi           Remove one or more images #移除一个或多个镜像[无容器使用该镜像才可删除,否则需删除相关容器才可继续或 -f 强制删除]
run          Run a command in a new container #创建一个新的容器并运行一个命令
save       Save an image to a tar archive # 保存一个镜像为一个 tar 包[对应 load]
search    Search for an image on the Docker Hub #在 docker hub 中搜索镜像
start         Start a stopped containers # 启动容器
stop        Stop a running containers #停止容器
tag          Tag an image into a repository #给源中镜像打标签
top         Lookup the running processes of a container #查看容器中运行的进程信息
unpause    Unpause a paused container # 取消暂停容器
version    Show the docker version information #查看 docker 版本号
wait          Block until a container stops, then print its exit code #截取容器停止时的退出状态值

格式

♾️ shell 代码:
# 1. 拉取镜像到本地
docker pull 镜像名称[:tag]
# 举个例子 tomcat
docker pull daocloud.io/library/tomcat:8.5.15-jre8

# 2. 查看全部本地的镜像
docker images

# 3. 删除本地镜像
docker rmi 镜像的标识

# 4. 镜像的导入导出(不规范)
# 将本地的镜像导出
docker save -o 导出的路径 镜像id
# 加载本地的镜像文件
docker load -i 镜像文件
# 修改镜像名称
docker tag 镜像id 新镜像名称:版本

# 1. 运行容器
# 简单操作
docker run 镜像的标识|镜像名称[tag]
# 常用的参数
docker run -d -p  宿主机端口:容器端口 --name 容器名称 镜像的标识|镜像名称[tag]
# -d: 代表后台运行容器
# -p: 宿主机端口:容器端口: 为了映射当前Linux的端口和容器的端口
# --name 容器名称: 指定容器的名称

# 2. 查看正在运行的容器
docker ps [OPTIONS]
# OPTIONS说明:
# -a: 代表查看全部的容器,包括没有运行
# -q: 只查看容器的标识
# -f: 根据条件过滤显示的内容
# --format: 指定返回值的模板文件
# -l: 显示最近创建的容器
# -n: 列出最近创建的n个容器
# --no-trunc: 不截断输出
# -s: 显示总的文件大小

# 3. 查看容器的日志
docker logs -f 容器id
# -f: 可以滚动查看日志的最后几行

# 4. 进入到容器内部
docker exec -it 容器id bash

# 5. 删除容器(删除容器前,需要先停止容器)
docker stop 容器id
# 停止指定的容器
docker stop $(docker ps -qa)
# 停止全部容器
docker rm 镜像id
# 删除指定容器
docker rm $(docker ps -qa)
# 删除全部容器

#6. 启动容器
docker start 容器id

作业练习

安装Nginx
  1. 安装nginx

    ♾️ shell 代码:
    docker search nginx
  2. 下载镜像

    ♾️ shell 代码:
    docker pull nginx
  3. 运行镜像

    ♾️ shell 代码:
    # -d 后台运行
    # --name  给容器命名
    # -p     端口映射,本机端口:容器内部端口
    
    docker run -d --name jiusheng -p 520:80 nginx
    
    #查看是否启动
    [root@iZj6c5ctiawsbu90vbskdwZ ~]# docker ps
    CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                 NAMES
    82e88fd7529c   nginx     "/docker-entrypoint.…"   12 seconds ago   Up 10 seconds   0.0.0.0:520->80/tcp   jiusheng
    
    #查看端口是否连通
    [root@iZj6c5ctiawsbu90vbskdwZ ~]# curl localhost:520
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
     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>
  4. 进入容器

    ♾️ smalltalk 代码:
    docker exec -it jiusheng /bin/bach
  5. 端口映射概念
    ku14hfb9.png
安装tomcat
注意,在官网上的使用方法如下:
♾️ shell 代码:
docker run -it --rm tomcat:9.0
这里我们不推荐,我们一般是使用后台启动,停止了容器后,还可以查找到, 但是docker run -it --rm ,使用之后就会直接删除,查找不到,也就是说是一个即用即删的,多用于测试!
  1. 搜索tomcat镜像
♾️ xshell 代码:
docker searce tomcat
  1. 下载tomcat
♾️ shell 代码:
docker pull tomcat
  1. 启动运行
♾️ shell 代码:
docker run -d -p 250:8080 --name tomcat01 tomcat
  1. 测试访问
♾️ shell 代码:
curl localhost:250
访问ip:250
  1. 访问的通,没有出现想要的页面
♾️ shell 代码:
#进入容器
docker exec -it tomcat01 /bin/bash
#发现少了命令,同时没有web。

#原因:默认最小安装,剔除了不必要的东西,保证最小化运行环境。

#解决方法
cp -r webapps.dist/* webapps

#之后就可以访问量
部署elasticsearch简称es+kibana
♾️ shell 代码:
#官方命令
#--net somenetwork 网络配置
#"discovery.type=single-node"   集群配置,默认单节点
docker run -d --name elasticsearch --net somenetwork -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:tag
#我们做一些修改
docker run -d --name elasticsearch  -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e EC_JAVA_OPTS="=-Xms64m -Xm512m" elasticsearch:7.6.2
#去掉了网络服务
#改了名字
#增加了环境限制,别问,问就是这个非常耗内存,我的机子托不动,然后指定了版本号

docker run -d --name=es2 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m"  elasticsearch:7.6.2
  1. 查看容器占用内存
♾️ shell 代码:
    docker stats 容器id
  1. 检查是否启动成功
♾️ shell 代码:
    curl localhost:9200
    #参考
    [root@iZj6c5ctiawsbu90vbskdwZ ~]# curl localhost:9200
    {
      "name" : "62ee34017bec",
      "cluster_name" : "docker-cluster",
      "cluster_uuid" : "3OGmDOBLSOOYOeQQ23F7dQ",
      "version" : {
        "number" : "7.6.2",
        "build_flavor" : "default",
        "build_type" : "docker",
        "build_hash" : "ef48eb35cf30adf4db14086e8aabd07ef6fb113f",
        "build_date" : "2020-03-26T06:34:37.794943Z",
        "build_snapshot" : false,
        "lucene_version" : "8.4.0",
        "minimum_wire_compatibility_version" : "6.8.0",
        "minimum_index_compatibility_version" : "6.0.0-beta1"
      },
      "tagline" : "You Know, for Search"
    }
    

部署可视化面板

Portainer

这里需要主要的是,我们安装ce版本即可,因为这是开源切免费的!

官网地址:

https://documentation.portainer.io/v2.0/deploy/ceinstalldocker/

Portainer 服务器部署
♾️ shell 代码:
docker volume create portainer_data

docker run -d -p 8000:8000 -p 9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce

Portainer 仅代理部署
♾️ shell 代码:
docker run -d -p 9001:9001 --name portainer_agent --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v /var/lib/docker/volumes:/var/lib/docker/volumes portainer/agent
♾️ shell 代码:
#查看是否启动成功
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker ps
CONTAINER ID   IMAGE             COMMAND     CREATED          STATUS          PORTS                    NAMES
8b100ad7b90f   portainer/agent   "./agent"   24 seconds ago   Up 23 seconds   0.0.0.0:9001->9001/tcp   portainer_agent

访问测试

这是一个登录界面,在这里我们需要建立管理员角色
l16bsnn6.png
创建成功之后,我们进入后台界面
l16btf1s.png
这样就完安装完成了,我们也不使用,就简单的了解就好了

镜像讲解

Docker镜像加载原理

镜像是什么

镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件
UnionFS(联合文件系统)
  • Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union 文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
  • 特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件,系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录
Docker镜像加载原理
  • docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。bootfs(boot file system)主要包含bootloader和kernel, bootloader主要是引导加载kernel, Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。
  • 这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。 rootfs (root file system) ,在bootfs之上。包含的就是典型 Linux 系统中的 /dev, /proc, /bin, /etc 等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等

  • 平时我们安装进虚拟机的 CentOS 都是好几个 G ,为什么 Docker 这里才 200M ?
  • 对于一个精简的OS,rootfs 可以很小,只需要包含最基本的命令,工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供rootfs就可以了。由此可见对于不同的linux发行版, bootfs基本是一致的, rootfs会有差别, 因此不同的发行版可以公用bootfs。

分层理解

  • 我们可以去下载一个镜像,注意观察下载的日志输出,可以看到是一层一层的在下载!
为什么Docker镜像要采用这种分层的结构呢?
  • 最大的好处,我觉得莫过于是资源共享了!比如有多个镜像都从相同的Base镜像构建而来,那么宿主机只需在磁盘上保留一份base镜像,同时内存中也只需要加载一份base镜像,这样就可以为所有的容器服务了,而且镜像的每一层都可以被共享。查看镜像分层的方式可以通过 docker image inspect 命令!
所有的 Docker 镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上,创建新的镜像层。
举一个简单的例子,假如基于 Ubuntu Linux 16.04 创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加 Python包,就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创建第三个镜像层。该镜像当前已经包含 3 个镜像层,如下图所示(这只是一个用于演示的很简单的例子

在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要。下图中举了一个简单的例子,每个镜像层包含 3 个文件,而镜像包含了来自两个镜像层的 6 个文件。

上图中的镜像层跟之前图中的略有区别,主要目的是便于展示文件。
下图中展示了一个稍微复杂的三层镜像,在外部看来整个镜像只有 6 个文件,这是因为最上层中的文件7 是文件 5 的一个更新版本。

这种情况下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中。
Docker 通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统。
Linux 上可用的存储引擎有 AUFS、Overlay2、Device Mapper、Btrfs 以及 ZFS。顾名思义,每种存储引擎都基于 Linux 中对应的文件系统或者块设备技术,并且每种存储引擎都有其独有的性能特点。
Docker 在 Windows 上仅支持 windowsfilter 一种存储引擎,该引擎基于 NTFS 文件系统之上实现了分层和 CoW[1]。下图展示了与系统显示相同的三层镜像。所有镜像层堆叠并合并,对外提供统一的视图

特点

Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部!

这一层就是我们通常说的容器层,容器之下的都叫镜像层

commit

commit的作用相当于快照

提交镜像

♾️ shell 代码:
docker commit  -m="提交信息" -a="作者" 容器id 目标镜像名:[tag]

测试

  1. 启动tomcat

    ♾️ shell 代码:
    docker run -it  -p 432:8080 comcat
  2. 进入comcat

    ♾️ shell 代码:
    docker exec -it 容器id /bin/bash
  3. 拷贝数据

    ♾️ shell 代码:
    cp -r webapps.dist/* webapps
  4. 访问地址是否修改成功

    ♾️ shell 代码:
    http://47.243.161.30:432/
  5. 退出容器并提交新的修改

    ♾️ shell 代码:
    #退出容器
    exit
    
    #提交修改
    docker commit -a="jiusheng" -m="webapps" 0cee6cf8bd57 comcat02:1.1
  6. 查看是否生成成功

    ♾️ shell 代码:
    docker images
    
    comcat02                 1.1       31ea9dda1fda   8 seconds ago   677MB
    portainer/portainer-ce   latest    865cf8021627   2 weeks ago     210MB
    portainer/agent          latest    3cdf856343c6   2 weeks ago     138MB
    nginx                    latest    4cdc5dd7eaad   2 weeks ago     133MB
    tomcat                   latest    36ef696ea43d   3 weeks ago     667MB
    centos                   latest    300e315adb2f   7 months ago    209MB
    kibana                   7.6.2     f70986bc5191   16 months ago   1.01GB
    elasticsearch            7.6.2     f29a1ee41030   16 months ago   791MB
    

容器数据卷

docker数据卷概念

Docker的理念是:将运用与运行的环境打包形成容器运行 ,运行可以伴随着容器。

Docker容器产生的数据,如果不通过docker commit生成新的镜像,使得数据做为镜像的一部分保存下来,那么当容器删除后,数据自然也就没有了。

所以我们希望:数据可以持久化、容器之间(甚至容器与宿主机之间)可以数据共享。为了能保存数据可以在docker中使用卷。卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷。

卷就是目录或文件,存在于一个或多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能够绕过Union File System提供一些用于持续存储或共享数据的特性:

  • 数据卷可在容器之间共享或重用数据
  • 卷中的更改可以直接生效
  • 数据卷中的更改不会包含在镜像的更新中
  • 数据卷的生命周期一直持续到没有容器使用它为止

为什么使用数据卷

​ Docker的镜像是由一系列的只读层组合而来,当启动一个容器的时候,Docker加载镜像的所有只读层,并在最上层加入一个读写层。这个设计使得Docker可以提高镜像构建、存储和分发的效率,节省了时间和存储空间,然而也存在如下问题。

容器中的文件在宿主机上存在形式复杂,不能在宿主机上很方便的对容器中的文件进行访问

  1. 多个容器之间的数据无法共享
  2. 当删除容器时,容器产生的数据将丢失

​ 为了解决这些问题,Docker引入了数据卷(volume)机制。volume是存在一个或多个容器中的特定文件或文件夹,这个目录能够独立于联合文件系统的形式在宿主机中存在,并为数据的共享与持久提供一下便利。

  1. volume在容器创建时就初始化,在容器运行时就可以使用其中的文件
  2. volume能在不同的容器之间共享和重用
  3. volume中的数据的操作会马上生效
  4. volume中数据操作不会影响到镜像本身
  5. volume的生存周期独立于容器的生存周期,即使删除容器,volume仍然会存在,没有任何容器使用的volume也不会被Docker删除

volume命令

了解volume的命令
  • 使用帮助文档查看命令
♾️ shell 代码:
docker volume --help
  • 参数说明
♾️ shell 代码:
  create              #创建卷
  inspect         #显示一个或多个数据卷的详细信息
  ls                  #列出所有卷
  prune         #删除所有未使用的数据卷
  rm                   #删除一个或多个卷
  1. 创建一个数据卷

基本格式如下:

docker volume create 名字

♾️ shell 代码:
docker volume create jiu

此时,数据卷默认会放到/var/lib/docker/volumes路径下,会发现所新建的数据卷位置,查看命令如下:
\## 参数可以为数字“1”,字母L:大小写均可,但效果不一样
ls -1 /var/lib/docker/volumes

为什么会在这里,我们可以来看一下docker的文件目录:

docker的默认目录为/var/lib/docker/

里面的结构如下

├── containers #用来存储容器信息
├── image #用来存储镜像中间件及本身信息,大小,依赖信息
│ └── overlay2
│ ├── distribution
│ ├── imagedb
│ │ ├── content
│ │ │ └── sha256
│ │ └── metadata
│ │ └── sha256
│ ├── layerdb
│ └── repositories.json
├── network #网络信息
│ └── files
│ └── local-kv.db
├── overlay2 #存放镜像
│ └── l
├── plugins
│ ├── storage
│ │ └── blobs
│ │ └── tmp
│ └── tmp
├── swarm
├── tmp #docker临时目录
├── trust #docker信任目录
└── volumes #docker卷目录
└── metadata.db

  1. 列出所有数据卷
♾️ shell 代码:
docker volume ls
  1. 查询数据卷信息

格式:

docker volume inspect 数据卷名

♾️ shell 代码:
docker volume inspect jiu


[root@iZj6c5ctiawsbu90vbskdwZ docker]# docker volume inspect jiu
[
    {
        "CreatedAt": "2021-07-27T16:49:41+08:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/jiu/_data",   #存放位置
        "Name": "jiu",   #数据卷名
        "Options": {},
        "Scope": "local"
    }
]
  1. 删除一个数据卷

格式:

docker volume rm 数据卷名

♾️ shell 代码:
docker volume rm jiu


[root@iZj6c5ctiawsbu90vbskdwZ docker]# docker volume ls
DRIVER    VOLUME NAME
local     jiu
[root@iZj6c5ctiawsbu90vbskdwZ docker]# docker volume rm jiu
jiu
[root@iZj6c5ctiawsbu90vbskdwZ docker]# docker volume ls
DRIVER    VOLUME NAME
#可以看到已经删除成功了
  1. 删除所有没有使用的数据卷

格式:

docker volume prune

♾️ shelll 代码:
docker volume prune


#这里我们提前创建了一些数据卷
[root@iZj6c5ctiawsbu90vbskdwZ docker]# docker volume prune
WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
jiu
sheng
hahha
Total reclaimed space: 0B
#可以看到没有使用的数据均已经全部删除完毕了

数据卷的使用

数据卷目前有两种方式来进行使用,一种是直接通过命令来进行挂载,一种是通过DockerFile来进行添加

命令格式:

docker run -it -v 主机目录:容器内目录

测试

  1. 启动并挂载数据卷
♾️ shell 代码:
docker run -it -v /home/ceshi:/home centos /bin/bash
  1. 查看是否生成挂载目录测试,并成功挂载
♾️ shell 代码:
[root@iZj6c5ctiawsbu90vbskdwZ /]# cd /home/
[root@iZj6c5ctiawsbu90vbskdwZ home]# ls
admin  ceshi
[root@iZj6c5ctiawsbu90vbskdwZ home]#


[root@iZj6c5ctiawsbu90vbskdwZ ceshi]# docker inspect 1795f7f64501
[
    {
        "Id": "1795f7f64501188c8e74a8f9f5b2fb8703a84f0d7b36606f3f98ce2c06b93f3f",
        "Created": "2021-07-27T09:33:28.066660046Z",
        "Path": "/bin/bash",
        "Args": [],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 8000,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2021-07-27T09:33:28.409923354Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        "Image": "sha256:300e315adb2f96afe5f0b2780b87f28ae95231fe3bdd1e16b9ba606307728f55",
        "ResolvConfPath": "/var/lib/docker/containers/1795f7f64501188c8e74a8f9f5b2fb8703a84f0d7b36606f3f98ce2c06b93f3f/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/1795f7f64501188c8e74a8f9f5b2fb8703a84f0d7b36606f3f98ce2c06b93f3f/hostname",
        "HostsPath": "/var/lib/docker/containers/1795f7f64501188c8e74a8f9f5b2fb8703a84f0d7b36606f3f98ce2c06b93f3f/hosts",
        "LogPath": "/var/lib/docker/containers/1795f7f64501188c8e74a8f9f5b2fb8703a84f0d7b36606f3f98ce2c06b93f3f/1795f7f64501188c8e74a8f9f5b2fb8703a84f0d7b36606f3f98ce2c06b93f3f-json.log",
        "Name": "/gallant_sanderson",
        "RestartCount": 0,
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": null,
        "HostConfig": {
            "Binds": [
                "/home/ceshi:/home"            
            ],
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "default",
            "PortBindings": {},
            "RestartPolicy": {
                "Name": "no",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "CapAdd": null,
            "CapDrop": null,
            "CgroupnsMode": "host",
            "Dns": [],
            "DnsOptions": [],
            "DnsSearch": [],
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "private",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": null,
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "Runtime": "runc",
            "ConsoleSize": [
                0,
                0
            ],
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": [],
            "BlkioDeviceReadBps": null,
            "BlkioDeviceWriteBps": null,
            "BlkioDeviceReadIOps": null,
            "BlkioDeviceWriteIOps": null,
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": [],
            "DeviceCgroupRules": null,
            "DeviceRequests": null,
            "KernelMemory": 0,
            "KernelMemoryTCP": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": null,
            "OomKillDisable": false,
            "PidsLimit": null,
            "Ulimits": null,
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0,
            "MaskedPaths": [
                "/proc/asound",
                "/proc/acpi",
                "/proc/kcore",
                "/proc/keys",
                "/proc/latency_stats",
                "/proc/timer_list",
                "/proc/timer_stats",
                "/proc/sched_debug",
                "/proc/scsi",
                "/sys/firmware"
            ],
            "ReadonlyPaths": [
                "/proc/bus",
                "/proc/fs",
                "/proc/irq",
                "/proc/sys",
                "/proc/sysrq-trigger"
            ]
        },
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/9952b87bf9c7b7b84fbbdb2ac08fdc7ceb96b8cdf21c4f2d1d2f49bd8595ee1f-init/diff:/var/lib/docker/overlay2/95fb52765b6ea97468e0c38889f47d9e3c95d2e69d556c18798f00ebb3e2cfb1/diff",
                "MergedDir": "/var/lib/docker/overlay2/9952b87bf9c7b7b84fbbdb2ac08fdc7ceb96b8cdf21c4f2d1d2f49bd8595ee1f/merged",
                "UpperDir": "/var/lib/docker/overlay2/9952b87bf9c7b7b84fbbdb2ac08fdc7ceb96b8cdf21c4f2d1d2f49bd8595ee1f/diff",
                "WorkDir": "/var/lib/docker/overlay2/9952b87bf9c7b7b84fbbdb2ac08fdc7ceb96b8cdf21c4f2d1d2f49bd8595ee1f/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/home/ceshi",                   #我们可以看到这里是挂载上去了的,那我们接着来测试
                "Destination": "/home",                     #容器内的地址
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],
        "Config": {
            "Hostname": "1795f7f64501",
            "Domainname": "",
            "User": "",
            "AttachStdin": true,
            "AttachStdout": true,
            "AttachStderr": true,
            "Tty": true,
            "OpenStdin": true,
            "StdinOnce": true,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/bin/bash"
            ],
            "Image": "centos",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {
                "org.label-schema.build-date": "20201204",
                "org.label-schema.license": "GPLv2",
                "org.label-schema.name": "CentOS Base Image",
                "org.label-schema.schema-version": "1.0",
                "org.label-schema.vendor": "CentOS"
            }
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "c5803986c1107b2e97d534aab5c2725f355b7cef1c171afd8486f72d0b83a382",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {},
            "SandboxKey": "/var/run/docker/netns/c5803986c110",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "f6f8cedcc0ad532f2c01910f84e3436c1c33ec8aa0d2e47236de75bde44c8384",
            "Gateway": "172.17.0.1",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.17.0.2",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "MacAddress": "02:42:ac:11:00:02",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "3be7a57080be0d228e4f459c30ed8bc85ab61b84ac10ddbeaa546ad97f294539",
                    "EndpointID": "f6f8cedcc0ad532f2c01910f84e3436c1c33ec8aa0d2e47236de75bde44c8384",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:02",
                    "DriverOpts": null
                }
            }
        }
    }
]
  1. 在本机添加文件
♾️ shell 代码:
#生成一个jiusheng.666的文件
[root@iZj6c5ctiawsbu90vbskdwZ ceshi]# touch jiusheng.666
[root@iZj6c5ctiawsbu90vbskdwZ ceshi]# ls
jiusheng.666
  1. 到容器里面查看是否同步
♾️ shell 代码:
#可以看到是已经同步的了
[root@1795f7f64501 /]# cd /home/
[root@1795f7f64501 home]# ls
jiusheng.666
  1. 在容器内删除文件
♾️ shell 代码:
[root@1795f7f64501 home]# rm jiusheng.666 
rm: remove regular empty file 'jiusheng.666'? y
[root@1795f7f64501 home]# 
#这里我们在容器里面已经吧文件jiusheng.666删除掉了,我们去宿主机看看文件还在不在

[root@iZj6c5ctiawsbu90vbskdwZ ceshi]# ls
[root@iZj6c5ctiawsbu90vbskdwZ ceshi]# 
#可以看到是没有任何文件的,也就是说这里目录下的文件是双向绑定的,同时,你停止或者删除容器,里面的内容也是不会变得,出给你认为的去修改或者删除!

挂载之后的文件就是共享,同时不管你删除容器还是停止容器,映射出来的文件不会随之消失!

这里删除或者停止容器的测试就不在赘述了。

拓展

我们在实际使用的过程中,会发现有一些的命令会多一个ro 或者rw

这个是读取权限:

ro 只读

rw 可读可写

不设置的话,默认.rw

♾️ shell 代码:
docker run -it -v /myDataVolume:/dataVolumeContainer:ro centos

-v            #代表数据卷
/myDataVolume                #宿主机绝对路径目录
:/dataVolumeContainer        #容器内目录
centos                #镜像名
:ro            #设置权限为只读

安装MySQL

  1. 下载mysql
♾️ shell 代码:
docker pull mysql:5.6
  1. 运行容器并进行数据挂载
♾️ shell 代码:
#这是官方给的方式,我们进行就该
#my-secret-pw -d   表示密码,进行修改
#-e 是环境变量
docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
♾️ shell 代码:
docker run -p 3306:3306 --name mymysql -v $PWD/conf:/etc/mysql/conf.d -v $PWD/logs:/logs -v $PWD/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7

参数解释:
-p 3306:3306:将容器的 3306 端口映射到主机的 3306 端口。
-v $PWD/conf:/etc/mysql/conf.d:将主机当前目录下的 conf/my.cnf 挂载到容器的 /etc/mysql/my.cnf。
-v $PWD/logs:/logs:将主机当前目录下的 logs 目录挂载到容器的 /logs。
-v $PWD/data:/var/lib/mysql :将主机当前目录下的data目录挂载到容器的 /var/lib/mysql 。
-e MYSQL_ROOT_PASSWORD=123456:初始化 root 用户的密码。

l16bv1ep.png
  1. 连接看测试
    l16bvssf.png
可以看到连接成功,下面我们创建一个表来测试
l16bwlk0.png
这个时候我们来数据是否同步
l16bx8o4.png
  1. 我们停止掉原来的数据库,同时新开一个数据库
♾️ shell 代码:
docker run -p 3307:3306 --name mysql01 -v $PWD/conf:/etc/mysql/conf.d -v $PWD/logs:/logs -v $PWD/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
我们来进行连接
l16bxv20.png
我们之前创建的数据都还在
l16byho6.png
至此,我们可以很明确的知道,数据卷的使用,可以实现数据的持久化。不再一删除容器就什么都没有了!

具名和匿名挂载

什么是具名挂载和匿名挂载?

我们前面挂载数据卷的时候是通过 -v 主机路径:容器内路径 ,来进行挂载的,那么我们不指定主机的挂载路径只指定容器内路径,-v 容器内路径 那么这个就是匿名挂载, 反之如果我们吧主机路径变成别名,那么就是具名挂载在,比如: -v jiusheng:容器内路径

匿名挂载

  1. 使用匿名挂载启动nginx
♾️ shell 代码:
docker run -d -P --name nginx01 -v /etc/nginx nginx

参数解读:
-P 随机端口
-v  匿名挂载会随机生成挂载路径
  1. 使用volume查看数据卷
♾️ shell 代码:
docker volume ls


[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker volume ls
DRIVER              VOLUME NAME
local               0ba2accbb52f84f4ddd1b92995db0ce4e8adbb3f710595f26823f9f01f014c65
local               8f054507bd037b086e742d764f415df0fcbb08e7d1e71f3c83c1e112f7c28ca1
local               81e46324431241ff7b95a6cceb4b5dd85d9b9eefb03aa55d46f153b101a8502f
local               82a3da984765cbbdb73797cec9038650e035a2511a07479370587787fc331501
local               53050314ad0cf8d879280a1c1df3a587f497ae93315da31cc5d97ae7a0907f3c
local               bc56b1d4485fb0a171f5807204408a6257109311e37365bbfd79387afc940cb9
local               cb7e41c8d674d05d355c10b0a7101bf7569500b78c38d8f50ca6f87ed5c265d6
local               f4785b207baa99a0214b40816dcc51e265a5ea5a66e4f55a1ab1b6d286ab47f9
  1. 查看匿名挂载路径
♾️ shell 代码:
docker volume inspect



[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker volume inspect f4785b207baa99a0214b40816dcc51e265a5ea5a66e4f55a1ab1b6d286ab47f9
[
    {
        "CreatedAt": "2021-07-29T08:56:05+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/f4785b207baa99a0214b40816dcc51e265a5ea5a66e4f55a1ab1b6d286ab47f9/_data",
        "Name": "f4785b207baa99a0214b40816dcc51e265a5ea5a66e4f55a1ab1b6d286ab47f9",
        "Options": null,
        "Scope": "local"
    }
]

具名挂载

  1. 使用具名挂载nginx
♾️ shell 代码:
docker run -d -P --name nginx02 -v jumingguazai:/etc/nginx nginx
  1. 查看数据卷
♾️ shell 代码:
docker volume ls

[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker volume ls
DRIVER              VOLUME NAME
local               jumingguazai
  1. 查看具名挂载地址
♾️ shell 代码:
docker volume inspect jumingguazai

[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker volume inspect jumingguazai
[
    {
        "CreatedAt": "2021-07-29T10:46:44+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/jumingguazai/_data",
        "Name": "jumingguazai",
        "Options": null,
        "Scope": "local"
    }
]

我们可以看到,不管是匿名挂载还是具名挂载,默认的挂载目录地址都是在/var/lib/docker/volumes/xxx/_data

我们通过具名挂载可以方便的找到我们挂载的卷,所以大多数情况也就使用具名挂载

区分挂载类型

-v 容器内路径匿名挂载
-v 卷名:容器内路径具名挂载
-v /宿主机路径:容器内路径指定路径挂载 ,注意有/

dockerfile挂载数据卷

编写脚本
♾️ shell 代码:
FROM centos
VOLUME ["jiusheng01","jiusheng02"]
CMD echo "-------jiushengzuishuai------"
CMD /bin/bash

基本格式

♾️ shell 代码:
docker build -f 脚本名 -t 镜像名 .

创建一个自己的镜像

♾️ shell 代码:
docker build -f dockerfile -t jiu/centos .
#我这是在创建的文件里面,所以没有写绝对路径,注意!
[root@iZj6c5ctiawsbu90vbskdwZ jiusheng]# docker build -f dockerfile -t jiu/centos .
Sending build context to Docker daemon  2.048kB
Step 1/4 : FROM centos
latest: Pulling from library/centos
7a0437f04f83: Pull complete 
Digest: sha256:5528e8b1b1719d34604c87e11dcd1c0a20bedf46e83b5632cdeac91b8c04efc1
Status: Downloaded newer image for centos:latest
 ---> 300e315adb2f
Step 2/4 : VOLUME ["jiusheng01","jiusheng02"]
 ---> Running in 493198964ebc
Removing intermediate container 493198964ebc
 ---> 708ee122fc35
Step 3/4 : CMD echo "-------jiushengzuishuai------"
 ---> Running in 4fa544e52a5d
Removing intermediate container 4fa544e52a5d
 ---> 1636e3ed06f7
Step 4/4 : CMD /bin/bash
 ---> Running in 8e41d980a363
Removing intermediate container 8e41d980a363
 ---> e812a670c034
Successfully built e812a670c034
Successfully tagged jiu/centos:latest

#我这里没有centos,所以多了一个下载

查看是否构建成功

♾️ shell 代码:
docker images

[root@iZj6c5ctiawsbu90vbskdwZ jiusheng]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
jiu/centos          latest              e812a670c034        30 seconds ago      209MB
nginx               latest              08b152afcfae        6 days ago          133MB
mysql               5.7                 8cf625070931        6 days ago          448MB
centos              latest              300e315adb2f        7 months ago        209MB

运行镜像

♾️ shell 代码:
docker run -it e812a670c034 /bin/bash


[root@85a2c18ffc33 /]# ls -l
total 56
lrwxrwxrwx   1 root root    7 Nov  3  2020 bin -> usr/bin
drwxr-xr-x   5 root root  360 Jul 29 07:22 dev
drwxr-xr-x   1 root root 4096 Jul 29 07:22 etc
drwxr-xr-x   2 root root 4096 Nov  3  2020 home
drwxr-xr-x   2 root root 4096 Jul 29 07:22 jiusheng01
drwxr-xr-x   2 root root 4096 Jul 29 07:22 jiusheng02
lrwxrwxrwx   1 root root    7 Nov  3  2020 lib -> usr/lib
lrwxrwxrwx   1 root root    9 Nov  3  2020 lib64 -> usr/lib64
drwx------   2 root root 4096 Dec  4  2020 lost+found
drwxr-xr-x   2 root root 4096 Nov  3  2020 media
drwxr-xr-x   2 root root 4096 Nov  3  2020 mnt
drwxr-xr-x   2 root root 4096 Nov  3  2020 opt
dr-xr-xr-x 102 root root    0 Jul 29 07:22 proc
dr-xr-x---   2 root root 4096 Dec  4  2020 root
drwxr-xr-x  11 root root 4096 Dec  4  2020 run
lrwxrwxrwx   1 root root    8 Nov  3  2020 sbin -> usr/sbin
drwxr-xr-x   2 root root 4096 Nov  3  2020 srv
dr-xr-xr-x  13 root root    0 Jul 29 01:08 sys
drwxrwxrwt   7 root root 4096 Dec  4  2020 tmp
drwxr-xr-x  12 root root 4096 Dec  4  2020 usr
drwxr-xr-x  20 root root 4096 Dec  4  2020 var
l16bzb80.png

查看挂载地址

♾️ shell 代码:
docker inspect 85a2c18ffc33

        "Mounts": [
            {
                "Type": "volume",
                "Name": "d6f8d3df6d8bf7a8067a547550ecf24ec6d8e2217a6f66ec4b694175eca015e9",
                "Source": "/var/lib/docker/volumes/d6f8d3df6d8bf7a8067a547550ecf24ec6d8e2217a6f66ec4b694175eca015e9/_data",
                "Destination": "jiusheng02",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            },
            {
                "Type": "volume",
                "Name": "29cbc761ed2c5cfad7360e0b30918f29011d2a6b4962f50a245501b25323380b",
                "Source": "/var/lib/docker/volumes/29cbc761ed2c5cfad7360e0b30918f29011d2a6b4962f50a245501b25323380b/_data",
                "Destination": "jiusheng01",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],

#我们可以看到也是挂载到了对于的目录下,后面的操作就不在演示了

数据卷容器

定义:命名的容器挂载数据卷,其它容器通过挂载这个(父容器)实现数据共享,挂载数据卷的容器,称之为数据卷容器

容器间的传递共享

♾️ shell 代码:
docker run -it --name 子容器名 --volumes-from 父容器名 镜像名
  1. 启动一个子容器
♾️ shell 代码:
docker run -it --name jiu01 --volumes-from 85a2c18ffc33 e812a670c034
#这里直接使用上面创建的容器为父容器,估不再新建,直接创建子容器
  1. 在子容器里面创建一个文件
♾️ shell 代码:
[root@3f816b8ff216 /]# cd jiusheng01
[root@3f816b8ff216 jiusheng01]# touch jiushengya.txt
  1. 到父容器里面查看
♾️ shell 代码:
[root@85a2c18ffc33 /]# cd jiusheng01
[root@85a2c18ffc33 jiusheng01]# ls
jiushengya.txt
#数据同步共享
所有子容器数据与父容器以及父容器的其它子容器同步,同时删除容器不会删除数据,父容器停止或者删除,不会影响子容器

DocKerFile

dockerfile概念

dockerfile 是用来构建docker镜像文件的,一个命令参数脚本!

构建步骤

  1. 编写一个dockerfile文件
  2. 使用doicker build 构建一个镜像
  3. 使用docker run 运行镜像
  4. 使用docker push 发布一个镜像

Dockerfile优点

  • 易于版本化管理,Dockerfile 本身是一个文本文件,方便存放在代码仓库做版本管理,可以很方便地找到各个版本之间的变更历史
  • 过程可追溯,Dockerfile 的每一行指令代表一个镜像层,根据 Dockerfile 的内容即可很明确地查看镜像的完整构建过程
  • 屏蔽构建环境异构,使用 Dockerfile 构建镜像无须考虑构建环境,基于相同 Dockerfile 无论在哪里运行,构建结果都一致

Dockerfile构建过程解析

基础

  • 每条指令都必须大写字母,后面跟随至少一个参数
  • 指令从上到下按序执行
  • 表示注释

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

Dockerfile 书写原则

  1. 单一原则
  • 由于容器的本质是进程,一个容器代表一个进程,因此不同功能的应用应该尽量拆分为不同的容器,每个容器只负责单一业务进程。
  1. 注释信息
  • Dockerfile 也是一种代码,我们应该保持良好的代码编写习惯,晦涩难懂的代码尽量添加注释,让协作者可以一目了然地知道每一行代码的作用,并且方便扩展和使用。
  1. 保持容器最小化
  • 应该避免安装无用的软件包,比如在一个 nginx 镜像中,我并不需要安装 vim 、gcc 等开发编译工具。这样不仅可以加快容器构建速度,而且可以避免镜像体积过大。
  1. 合理选择基础镜像
  • 容器的核心是应用,因此只要基础镜像能够满足应用的运行环境即可。例如一个Java类型的应用运行时只需要JRE,并不需要JDK,因此我们的基础镜像只需要安装JRE环境即可。
  1. 使用 .dockerignore 文件
  • 在使用git时,我们可以使用.gitignore文件忽略一些不需要做版本管理的文件。同理,使用.dockerignore文件允许我们在构建时,忽略一些不需要参与构建的文件,从而提升构建效率。.dockerignore的定义类似于.gitignore。
  1. 尽量使用构建缓存
  • Docker 构建过程中,每一条 Dockerfile 指令都会提交为一个镜像层,下一条指令都是基于上一条指令构建的。如果构建时发现要构建的镜像层的父镜像层已经存在,并且下一条命令使用了相同的指令,即可命中构建缓存。

    Docker 构建时判断是否需要使用缓存的规则如下:
  • 从当前构建层开始,比较所有的子镜像,检查所有的构建指令是否与当前完全一致,如果不一致,则不使用缓存;
  • 一般情况下,只需要比较构建指令即可判断是否需要使用缓存,但是有些指令除外(例如ADD和COPY)。
  • 对于ADD和COPY指令不仅要校验命令是否一致,还要为即将拷贝到容器的文件计算校验和(根据文件内容计算出的一个数值,如果两个文件计算的数值一致,表示两个文件内容一致 ),命令和校验和完全一致,才认为命中缓存。
  • 因此,基于 Docker 构建时的缓存特性,我们可以把不轻易改变的指令放到 Dockerfile 前面(例如安装软件包),而可能经常发生改变的指令放在 Dockerfile 末尾(例如编译应用程序)。
  1. 正确设置时区
  • 我们从 Docker Hub 拉取的官方操作系统镜像大多数都是 UTC 时间(世界标准时间)。如果你想要在容器中使用中国区标准时间(东八区),请根据使用的操作系统修改相应的时区信息

    ♾️ shell 代码:
    #Dockerfile 几种常用操作系统的修改方式:
    #Ubuntu 和Debian 系统
    
    RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
    RUN echo "Asia/Shanghai" >> /etc/timezone
    
    #CentOS系统
    RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
  1. 使用国内软件源加快镜像构建速度
  • 由于我们常用的官方操作系统镜像基本都是国外的,软件服务器大部分也在国外,所以我们构建镜像的时候想要安装一些软件包可能会非常慢。
  1. 最小化镜像层数
  • 在构建镜像时尽可能地减少 Dockerfile 指令行数。例如我们要在 CentOS 系统中安装make和net-tools两个软件包,应该在 Dockerfile 中使用以下指令:
  • ♾️ shell 代码:
      RUN yum install -y make net-tools
  • 而不应该写成这样:
  • ♾️ shell 代码:
      RUN yum install -y make
      RUN yum install -y net-tools

dockerfile指令

所有的关键字都必须是大写,同时第一行不能是注释,必须是FROM

表示注释

1.FROM : 基础镜像
2.MANTAINER:镜像维护作者名和邮箱
3.RUN:容器构建需要的命令
4.EXPOSE:暴露端口
5.WORKDIR:登录后默认的工作目录
6.ENV:构建镜像过程中设置的环境变量
7.ADD:将宿主机目录下的文件拷贝进镜像并且会自动处理url和解压tar压缩包
8.COPY:将从构建上下文目录中(源路径)的文件/目录复制到新的一层的镜像内的(目标路径)位置
9.VOLUME:容器数据卷
10.CMD:指定容器启动时需要运行的命令,dockerFile中可以有多个cmd指令,但只有最后一个生效,cmd会被docker run之后的参数替换
11.ENTRYPOINT:指定一个容器启动时要运行的命令,可以有多条,都会生效
12.ONBUILD:当构建一个被继承的dockerFile时的运行命令,父镜像在被子镜像继承后,父镜像的onbuild被触发

实战测试

官方配置

Docker Hub 中 99% 镜像都是从这个基础镜像过来的 FROM scratch,然后配置需要的软件和配置来进行构建的
♾️ shell 代码:
FROM scratch    指定镜像
ADD centos-7-x86_64-docker.tar.xz /   #cenos7压缩包

LABEL \
    org.label-schema.schema-version="1.0" \
    org.label-schema.name="CentOS Base Image" \
    org.label-schema.vendor="CentOS" \
    org.label-schema.license="GPLv2" \
    org.label-schema.build-date="20201113" \
    org.opencontainers.image.title="CentOS Base Image" \
    org.opencontainers.image.vendor="CentOS" \
    org.opencontainers.image.licenses="GPL-2.0-only" \
    org.opencontainers.image.created="2020-11-13 00:00:00+00:00"

CMD ["/bin/bash"]
创建一个自己的镜像
♾️ shell 代码:
#进入home目录
cd home/
#创建DocKerFile文件
mkdir DocKerFile
#进入dockerfile
cd DocKerFile/
#随便创建一个文件名,写脚本
vim mycenos


#写入如下信息
FROM centos   
#指定镜像

MAINTAINER jiusheng<2936688581@qq.com>      #作者信息

ENV MYPATH /usr/local    #工作目录

WORKDIR $MYPATH

RUN yum -y install vim net-tools    #下载vim 和net-tools

EXPOSE 80    #暴露端口

CMD echo $MYPATH
CMD echo "-----jiusheng--"       #输出信息

CMD /bin/bash              

运行命令,构建镜像

基本格式:

注意,后面是有一个 .

docker build -f 文件路径 -t 镜像名:[tag] .

♾️ shell 代码:
[root@iZj6c5ctiawsbu90vbskdwZ DocKerFile]# docker build -f mycenos -t jiu_centos .
Sending build context to Docker daemon  2.048kB
Step 1/9 : FROM centos
 ---> 300e315adb2f
Step 2/9 : MAINTAINER jiusheng<2936688581@qq.com>
 ---> Running in 591cbf9c38f9
Removing intermediate container 591cbf9c38f9
 ---> cbdb558b172f
Step 3/9 : ENV MYPATH /usr/local
 ---> Running in f9c692dbac96
Removing intermediate container f9c692dbac96
 ---> 51316b596261
Step 4/9 : WORKDIR $MYPATH
 ---> Running in 3d4f6d2f173d
Removing intermediate container 3d4f6d2f173d
 ---> 51338bb008c2
Step 5/9 : RUN yum -y install vim net-tools
 ---> Running in cf3421730130
CentOS Linux 8 - AppStream                      6.8 MB/s | 8.3 MB     00:01    
CentOS Linux 8 - BaseOS                         4.9 MB/s | 4.5 MB     00:00    
CentOS Linux 8 - Extras                          22 kB/s | 9.8 kB     00:00    
Dependencies resolved.
================================================================================
 Package            Arch       Version                      Repository     Size
================================================================================
Installing:
 net-tools          x86_64     2.0-0.52.20160912git.el8     baseos        322 k
 vim-enhanced       x86_64     2:8.0.1763-15.el8            appstream     1.4 M
Installing dependencies:
 gpm-libs           x86_64     1.20.7-17.el8                appstream      39 k
 vim-common         x86_64     2:8.0.1763-15.el8            appstream     6.3 M
 vim-filesystem     noarch     2:8.0.1763-15.el8            appstream      48 k
 which              x86_64     2.21-12.el8                  baseos         49 k

Transaction Summary
================================================================================
Install  6 Packages

Total download size: 8.1 M
Installed size: 31 M
Downloading Packages:
(1/6): gpm-libs-1.20.7-17.el8.x86_64.rpm        395 kB/s |  39 kB     00:00    
(2/6): vim-enhanced-8.0.1763-15.el8.x86_64.rpm   13 MB/s | 1.4 MB     00:00    
(3/6): vim-filesystem-8.0.1763-15.el8.noarch.rp 909 kB/s |  48 kB     00:00    
(4/6): which-2.21-12.el8.x86_64.rpm             2.3 MB/s |  49 kB     00:00    
(5/6): vim-common-8.0.1763-15.el8.x86_64.rpm     30 MB/s | 6.3 MB     00:00    
(6/6): net-tools-2.0-0.52.20160912git.el8.x86_6 2.9 MB/s | 322 kB     00:00    
--------------------------------------------------------------------------------
Total                                           7.4 MB/s | 8.1 MB     00:01     
warning: /var/cache/dnf/appstream-02e86d1c976ab532/packages/gpm-libs-1.20.7-17.el8.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID 8483c65d: NOKEY
CentOS Linux 8 - AppStream                      1.4 MB/s | 1.6 kB     00:00    
Importing GPG key 0x8483C65D:
 Userid     : "CentOS (CentOS Official Signing Key) <security@centos.org>"
 Fingerprint: 99DB 70FA E1D7 CE22 7FB6 4882 05B5 55B3 8483 C65D
 From       : /etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
Key imported successfully
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                        1/1 
  Installing       : which-2.21-12.el8.x86_64                               1/6 
  Installing       : vim-filesystem-2:8.0.1763-15.el8.noarch                2/6 
  Installing       : vim-common-2:8.0.1763-15.el8.x86_64                    3/6 
  Installing       : gpm-libs-1.20.7-17.el8.x86_64                          4/6 
  Running scriptlet: gpm-libs-1.20.7-17.el8.x86_64                          4/6 
  Installing       : vim-enhanced-2:8.0.1763-15.el8.x86_64                  5/6 
  Installing       : net-tools-2.0-0.52.20160912git.el8.x86_64              6/6 
  Running scriptlet: net-tools-2.0-0.52.20160912git.el8.x86_64              6/6 
  Running scriptlet: vim-common-2:8.0.1763-15.el8.x86_64                    6/6 
  Verifying        : gpm-libs-1.20.7-17.el8.x86_64                          1/6 
  Verifying        : vim-common-2:8.0.1763-15.el8.x86_64                    2/6 
  Verifying        : vim-enhanced-2:8.0.1763-15.el8.x86_64                  3/6 
  Verifying        : vim-filesystem-2:8.0.1763-15.el8.noarch                4/6 
  Verifying        : net-tools-2.0-0.52.20160912git.el8.x86_64              5/6 
  Verifying        : which-2.21-12.el8.x86_64                               6/6 

Installed:
  gpm-libs-1.20.7-17.el8.x86_64                                                 
  net-tools-2.0-0.52.20160912git.el8.x86_64                                     
  vim-common-2:8.0.1763-15.el8.x86_64                                           
  vim-enhanced-2:8.0.1763-15.el8.x86_64                                         
  vim-filesystem-2:8.0.1763-15.el8.noarch                                       
  which-2.21-12.el8.x86_64                                                      

Complete!
Removing intermediate container cf3421730130
 ---> 96c4435f5f36
Step 6/9 : EXPOSE 80
 ---> Running in a5363e9470cd
Removing intermediate container a5363e9470cd
 ---> ee1bd76b09e4
Step 7/9 : CMD echo $MYPATH
 ---> Running in 110b43851555
Removing intermediate container 110b43851555
 ---> bcb634848307
Step 8/9 : CMD echo "-----jiusheng--"
 ---> Running in e8acecac7db8
Removing intermediate container e8acecac7db8
 ---> 700270977443
Step 9/9 : CMD /bin/bash
 ---> Running in 5df30afb5f3f
Removing intermediate container 5df30afb5f3f
 ---> aeeaf736a24e
Successfully built aeeaf736a24e
Successfully tagged jiu_centos:latest

查看是否构建成功

♾️ shell 代码:
[root@iZj6c5ctiawsbu90vbskdwZ DocKerFile]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
jiu_centos          latest              aeeaf736a24e        13 minutes ago      275MB
nginx               latest              08b152afcfae        9 days ago          133MB
mysql               5.7                 8cf625070931        9 days ago          448MB
centos              latest              300e315adb2f        7 months ago        209MB

测试运行

♾️ shell 代码:
docker run -it jiu_centos

[root@iZj6c5ctiawsbu90vbskdwZ DocKerFile]# docker run -it jiu_centos
#查看工作目录
[root@c2538f1711ea local]# pwd
/usr/local
#是我们设定的工作目录

#检测功能是否能用
[root@c2538f1711ea local]# ifconfig 
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.2  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:ac:11:00:02  txqueuelen 0  (Ethernet)
        RX packets 8  bytes 656 (656.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[root@c2538f1711ea local]# vim jiu

[1]+  Stopped                 vim jiu

#完全能用,构建成功

列出本地镜像的变更历史

♾️ shell 代码:
docker history 镜像名


[root@iZj6c5ctiawsbu90vbskdwZ DocKerFile]# docker history jiu_centos
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
aeeaf736a24e        26 minutes ago      /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "/bin…   0B                  
700270977443        26 minutes ago      /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "echo…   0B                  
bcb634848307        26 minutes ago      /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "echo…   0B                  
ee1bd76b09e4        26 minutes ago      /bin/sh -c #(nop)  EXPOSE 80                    0B                  
96c4435f5f36        26 minutes ago      /bin/sh -c yum -y install vim net-tools         66MB                
51338bb008c2        27 minutes ago      /bin/sh -c #(nop) WORKDIR /usr/local            0B                  
51316b596261        27 minutes ago      /bin/sh -c #(nop)  ENV MYPATH=/usr/local        0B                  
cbdb558b172f        27 minutes ago      /bin/sh -c #(nop)  MAINTAINER jiusheng<29366…   0B                  
300e315adb2f        7 months ago        /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B                  
<missing>           7 months ago        /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B                  
<missing>           7 months ago        /bin/sh -c #(nop) ADD file:bd7a2aed6ede423b7…   209MB        

CMD 和 ENTRYPOINT 区别

测试CMD

♾️ shell 代码:
# 编写dockerfile文件
[root@iZj6c5ctiawsbu90vbskdwZ DocKerFile]# vim ceshi
FROM centos
CMD ["ls","-a"]
 
 
# 构建镜像
[root@iZj6c5ctiawsbu90vbskdwZ DocKerFile]# docker build -f ceshi -t ceshiya .
Sending build context to Docker daemon  3.072kB
Step 1/2 : FROM centos
 ---> 300e315adb2f
Step 2/2 : CMD ["ls","-a"]
 ---> Running in f4f284cd463d
Removing intermediate container f4f284cd463d
 ---> c9afee7729d7
Successfully built c9afee7729d7
Successfully tagged ceshiya:latest
 
 
# run 运行 发现我们的 ls -a 命令生效
[root@iZj6c5ctiawsbu90vbskdwZ DocKerFile]# docker run ceshiya
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var

 
 
# 想追加一个命令 -l    ls -al 
[root@iZj6c5ctiawsbu90vbskdwZ DocKerFile]# docker run ceshiya -l
docker: Error response from daemon: OCI runtime create failed: container_linux.go:370: starting container process caused: exec: "-l": executable file not found in $PATH: unknown.
 
 
# cmd 的情况下 -l 替换了 CMD ["ls","-a"] 命令 -l 不是命令 所以报错

测试ENTRYPOINT

♾️ shell 代码:
# 编写dockerfile文件
[root@root dockerfile]# vi ceshi01

FROM centos
ENTRYPOINT ["ls","-a"]

 
# 构建镜像
[root@iZj6c5ctiawsbu90vbskdwZ DocKerFile]# docker build -f ceshi01 -t ceshiya01 .
Sending build context to Docker daemon  4.096kB
Step 1/2 : FROM centos
 ---> 300e315adb2f
Step 2/2 : ENTRYPOINT ["ls","-a"]
 ---> Running in 5490b3031487
Removing intermediate container 5490b3031487
 ---> 6102c6aeb29c
Successfully built 6102c6aeb29c
Successfully tagged ceshiya01:latest

 
 
# run 运行 发现我们的 ls -a 命令生效
[root@iZj6c5ctiawsbu90vbskdwZ DocKerFile]# docker run ceshiya01
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var

 
 
# 想追加一个命令 -l    ls -al 发现生效 
[root@iZj6c5ctiawsbu90vbskdwZ DocKerFile]# docker run ceshiya01 -l
total 56
drwxr-xr-x   1 root root 4096 Aug  1 03:02 .
drwxr-xr-x   1 root root 4096 Aug  1 03:02 ..
-rwxr-xr-x   1 root root    0 Aug  1 03:02 .dockerenv
lrwxrwxrwx   1 root root    7 Nov  3  2020 bin -> usr/bin
drwxr-xr-x   5 root root  340 Aug  1 03:02 dev
drwxr-xr-x   1 root root 4096 Aug  1 03:02 etc
drwxr-xr-x   2 root root 4096 Nov  3  2020 home
lrwxrwxrwx   1 root root    7 Nov  3  2020 lib -> usr/lib
lrwxrwxrwx   1 root root    9 Nov  3  2020 lib64 -> usr/lib64
drwx------   2 root root 4096 Dec  4  2020 lost+found
drwxr-xr-x   2 root root 4096 Nov  3  2020 media
drwxr-xr-x   2 root root 4096 Nov  3  2020 mnt
drwxr-xr-x   2 root root 4096 Nov  3  2020 opt
dr-xr-xr-x 109 root root    0 Aug  1 03:02 proc
dr-xr-x---   2 root root 4096 Dec  4  2020 root
drwxr-xr-x  11 root root 4096 Dec  4  2020 run
lrwxrwxrwx   1 root root    8 Nov  3  2020 sbin -> usr/sbin
drwxr-xr-x   2 root root 4096 Nov  3  2020 srv
dr-xr-xr-x  13 root root    0 Jul 29 01:08 sys
drwxrwxrwt   7 root root 4096 Dec  4  2020 tmp
drwxr-xr-x  12 root root 4096 Dec  4  2020 usr
drwxr-xr-x  20 root root 4096 Dec  4  2020 var

发布镜像

发布到官方 docker hub 上

官网

需要注册账号!

查看登录命令

♾️ shell 代码:
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker login --help

Usage:    docker login [OPTIONS] [SERVER]

Log in to a Docker registry.
If no server is specified, the default is defined by the daemon.

Options:
  -p, --password string   Password
      --password-stdin    Take the password from stdin
  -u, --username string   Username
[root@iZj6c5ctiawsbu90vbskdwZ ~]# 

登录账号

♾️ shell 代码:
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker login -u jiusheng
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
[root@iZj6c5ctiawsbu90vbskdwZ ~]# 

提交镜像

♾️ shell 代码:
docker push 信息/镜像:版本号

docker push jiusheng/centos:1.0
发布到阿里云
  1. 登录阿里云
  2. 找到容器镜像服务
l16c0n8m.png
  1. 点击个人实例
l16c19tz.png
  1. 点击创建镜像仓库
l16c1wml.png
  1. 点击本地仓库创建
l16c2om8.png
  1. 查看阿里云帮助文档
l16c3dr5.png

docker网络

初识docker0

  1. 这是我们没有安装docker时候的网络
♾️ shell 代码:
[root@iZj6c5ctiawsbu90vbskdwZ ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:16:3e:01:9e:7a brd ff:ff:ff:ff:ff:ff
    inet 172.21.27.152/18 brd 172.21.63.255 scope global dynamic eth0
       valid_lft 315359962sec preferred_lft 315359962sec
  1. 我们安装好docker之后会发现多了一个docker0
♾️ shell 代码:
[root@iZj6c5ctiawsbu90vbskdwZ ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:16:3e:01:9e:7a brd ff:ff:ff:ff:ff:ff
    inet 172.21.27.152/18 brd 172.21.63.255 scope global dynamic eth0
       valid_lft 315359848sec preferred_lft 315359848sec
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:4c:03:0f:26 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
  1. 安装Docker时,它会自动创建三个网络,bridge(创建容器默认连接到此网络)、 none 、host
l16c483a.png
  1. docker network 指令了解
♾️ shell 代码:
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker network --help

Usage:  docker network COMMAND

Manage networks

Commands:
  connect     Connect a container to a network  #   将容器连接到网络
  create      Create a network    #创建网络
  disconnect  Disconnect a container from a network   #  断开容器与网络的连接
  inspect     Display detailed information on one or more networks   #  显示一个或多个网络的详细信息
  ls          List networks    #列出所有网络
  prune       Remove all unused networks  #删除所有未使用的网络
  rm          Remove one or more networks   #删除一个或者多个网络

Run 'docker network COMMAND --help' for more information on a command.

  1. 验证一下docker0默认网络
♾️ shell 代码:
#启动一个容器
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker run -d -P --name tomcat01 tomcat
Unable to find image 'tomcat:latest' locally
latest: Pulling from library/tomcat
627b765e08d1: Pull complete 
c040670e5e55: Pull complete 
073a180f4992: Pull complete 
bf76209566d0: Pull complete 
f10db7ba7580: Pull complete 
5b2f970878fa: Pull complete 
ed434bfebf18: Pull complete 
f6c437110aa9: Pull complete 
a772951f83db: Pull complete 
752225c3768e: Pull complete 
Digest: sha256:6e40250d8fac4eca05c2067cb81f79427e4ddbaf4e78d5ecd21c35e8c5f2bfcf
Status: Downloaded newer image for tomcat:latest
6017ba277147c0b023ee2aa475108a4f8b88e8f7d182180308fc60ff0f41c714


#查看网络

[root@iZj6c5ctiawsbu90vbskdwZ ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:16:3e:01:9e:7a brd ff:ff:ff:ff:ff:ff
    inet 172.21.27.152/18 brd 172.21.63.255 scope global dynamic eth0
       valid_lft 315358148sec preferred_lft 315358148sec
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:4c:03:0f:26 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
7: veth961d52c@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether b2:82:8d:b4:75:6b brd ff:ff:ff:ff:ff:ff link-netnsid 0

#查看容器里面的网络

root@6017ba277147:/usr/local/tomcat# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
6: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

#我们可以看到容器内有一个eth0@if7的网络,同时可以发现eth0@if7和veth961d52c@if6是相互绑定的,也是成对出现的。


#查看能否ping通容器

[root@iZj6c5ctiawsbu90vbskdwZ ~]# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.095 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.078 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.041 ms

#发现可以ping通

原理

我们每启动一个容器,docker就会给我们的容器分配一个ip,docker使用的是桥接模式,使用的技术evth-pair技术

同时ip是成对出现的

evth-pair起到一个连接的桥梁,一般用来连接虚拟网络设备

  1. 在启动一个容器
♾️ shell 代码:
#查看网卡

[root@iZj6c5ctiawsbu90vbskdwZ ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:16:3e:01:9e:7a brd ff:ff:ff:ff:ff:ff
    inet 172.21.27.152/18 brd 172.21.63.255 scope global dynamic eth0
       valid_lft 315357189sec preferred_lft 315357189sec
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:4c:03:0f:26 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
7: veth961d52c@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether b2:82:8d:b4:75:6b brd ff:ff:ff:ff:ff:ff link-netnsid 0
9: veth3880b7f@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether b6:23:87:6f:bc:ef brd ff:ff:ff:ff:ff:ff link-netnsid 1
#可以看到有多了一对
  1. 容器ping容器
♾️ shell 代码:
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker exec -it tomcat02 ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.082 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.055 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.050 ms

#我们可以看到,是可以相互ping通的

网络图
l16c4xzs.png

--link

不推荐使用,只做了解

不通过ip来访问容器,直接通过容器名访问

  1. 容器和容器进行ping
♾️ shell 代码:
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker exec -it tomcat01 ping tomcat02
ping: tomcat02: Name or service not known
  1. 使用--link
♾️ shelll 代码:
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker run -d -P --name tomcat03 --link tomcat02 tomcat
4438f44dd6ff78a67892c526fcd5cf7ca7f1177699f0a3d8e24217e42515c673
  1. 查看是否可以ping通
♾️ shell 代码:
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker exec -it tomcat03 ping tomcat02
PING tomcat02 (172.17.0.3) 56(84) bytes of data.
64 bytes from tomcat02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.074 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.055 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=3 ttl=64 time=0.058 ms
#发现可以通过容器名ping通
  1. 反向是否可以ping通
♾️ shell 代码:
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker exec -it tomcat02 ping tomcat03
ping: tomcat03: Name or service not known
#发现是ping不同的,应为没有配置
  1. 查看网络信息
♾️ shell 代码:
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
f4e21fcb0d76   bridge    bridge    local
3c7452c40eb3   host      host      local
a122752ffd10   none      null      local
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker network inspect f4e21fcb0d76
[
    {
        "Name": "bridge",
        "Id": "f4e21fcb0d76f6a60dd870d02ed9604686240449350685f8100a9525fc564be1",
        "Created": "2021-08-01T16:00:00.258764824+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16"           #docker0
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "21b9e1bdfe0988f74199afb82805e502cfda94fccc8e269728c98b54f26637de": {
                "Name": "tomcat02",
                "EndpointID": "bd4419e2ca78725ddae30f95adc0d523680ff16c95960971d8fbaa823b531f1d",
                "MacAddress": "02:42:ac:11:00:03",
                "IPv4Address": "172.17.0.3/16",
                "IPv6Address": ""
            },
            "4438f44dd6ff78a67892c526fcd5cf7ca7f1177699f0a3d8e24217e42515c673": {
                "Name": "tomcat03",
                "EndpointID": "070b04e67e1dfbdeb5039b9db6d61e1ee0989953467b4edd9cc0641adbbab21f",
                "MacAddress": "02:42:ac:11:00:04",
                "IPv4Address": "172.17.0.4/16",
                "IPv6Address": ""
            },
            "6017ba277147c0b023ee2aa475108a4f8b88e8f7d182180308fc60ff0f41c714": {
                "Name": "tomcat01",
                "EndpointID": "717371bbe0ff45dd69480cd95bc1bfb41c0a02b10fef0df3a11fe46b2bf6cbe6",
                "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": {}
    }
]


#查看tomcat03
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker inspect 4438f44dd6ff
[
    {
        "Id": "4438f44dd6ff78a67892c526fcd5cf7ca7f1177699f0a3d8e24217e42515c673",
        "Created": "2021-08-01T09:41:06.910147871Z",
        "Path": "catalina.sh",
        "Args": [
            "run"
        ],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 13874,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2021-08-01T09:41:07.368939358Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        "Image": "sha256:46cfbf1293b176161813fa05bb8f7e82df1ec7def5c226c48bc48a60ed305ac7",
        "ResolvConfPath": "/var/lib/docker/containers/4438f44dd6ff78a67892c526fcd5cf7ca7f1177699f0a3d8e24217e42515c673/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/4438f44dd6ff78a67892c526fcd5cf7ca7f1177699f0a3d8e24217e42515c673/hostname",
        "HostsPath": "/var/lib/docker/containers/4438f44dd6ff78a67892c526fcd5cf7ca7f1177699f0a3d8e24217e42515c673/hosts",
        "LogPath": "/var/lib/docker/containers/4438f44dd6ff78a67892c526fcd5cf7ca7f1177699f0a3d8e24217e42515c673/4438f44dd6ff78a67892c526fcd5cf7ca7f1177699f0a3d8e24217e42515c673-json.log",
        "Name": "/tomcat03",
        "RestartCount": 0,
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": [
            "e2d063fb5a968904b5e3ec6def704cc3790f9b1efcd9ce7c0240a939383ee549"
        ],
        "HostConfig": {
            "Binds": null,
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "default",
            "PortBindings": {},
            "RestartPolicy": {
                "Name": "no",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "CapAdd": null,
            "CapDrop": null,
            "CgroupnsMode": "host",
            "Dns": [],
            "DnsOptions": [],
            "DnsSearch": [],
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "private",
            "Cgroup": "",
            "Links": [
                "/tomcat02:/tomcat03/tomcat02"               #这里可以发现tomcat03里面的配置出现了tomcat02
            ],
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": true,
            "ReadonlyRootfs": false,
            "SecurityOpt": null,
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "Runtime": "runc",
            "ConsoleSize": [
                0,
                0
            ],


#进入Tomcat03查看

[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker exec -it tomcat03 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.3    tomcat02 21b9e1bdfe09
172.17.0.4    4438f44dd6ff


#我们可以发现,这里直接就绑定了Tomcat02

自定义网络

容器互联
  1. 创建一个jiusheng网络
♾️ shell 代码:
#删除之前的所有容器
docker rm -f $(docker ps -aq)

#创建网络
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 jiusheng
db61398754c4de6d331db1788071e11ad9fa5883167cba1f0bf021bf671527c8

[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker network ls
NETWORK ID     NAME       DRIVER    SCOPE
f4e21fcb0d76   bridge     bridge    local
3c7452c40eb3   host       host      local
db61398754c4   jiusheng   bridge    local
a122752ffd10   none       null      local
  1. 查看创建网络信息
♾️ shell 代码:
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker network inspect db61398754c4
[
    {
        "Name": "jiusheng",
        "Id": "db61398754c4de6d331db1788071e11ad9fa5883167cba1f0bf021bf671527c8",
        "Created": "2021-08-01T17:58:35.111862913+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.0.0/16",
                    "Gateway": "192.168.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]
  1. 使用jiushneg网络
♾️ shell 代码:
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker run -d -P --name tomcat02 --net jiusheng tomcat
1a04efb744627d546dbb8e22ed162062c56718b24836a45ee28d5f33af83f994
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker run -d -P --name tomcat01 --net jiusheng tomcat
ecccd3d1869c3d95d6e28787765bf26eea01866bf317b4ea3fe01f8549fea281
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker ps
CONTAINER ID   IMAGE     COMMAND             CREATED          STATUS          PORTS                     NAMES
ecccd3d1869c   tomcat    "catalina.sh run"   4 seconds ago    Up 3 seconds    0.0.0.0:49160->8080/tcp   tomcat01
1a04efb74462   tomcat    "catalina.sh run"   12 seconds ago   Up 12 seconds   0.0.0.0:49159->8080/tcp   tomcat02
  1. 容器互相ping
♾️ shell 代码:
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker exec -it tomcat01 ping tomcat02
PING tomcat02 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat02.jiusheng (192.168.0.2): icmp_seq=1 ttl=64 time=0.061 ms
64 bytes from tomcat02.jiusheng (192.168.0.2): icmp_seq=2 ttl=64 time=0.051 ms
64 bytes from tomcat02.jiusheng (192.168.0.2): icmp_seq=3 ttl=64 time=0.063 ms
#发现可以直接ping通

自定义网络好处

  1. 不同集群的网络是相对的
  2. 让容器的网络基于dns的域名解析
  3. 拥有与宿主机之间安全的隔离环境
  4. 自由的选择或放弃一个网络

不同网络之间的连通

  1. 创建两个不通网络的容器
♾️ shell 代码:
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker run -d -P --name tomcat01 --net jiusheng tomcat
76ab3aba3e19257a29e6b4702a9145d7da4f59150e63de4af865cec4d8f94dfa
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker run -d -P --name tomcat02  tomcat
8ad64e755f65f210eac46fd61c4ea2251810f4307b5d84e8aa67f764b30db50b
  1. 查看是否运行
♾️ shell 代码:
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker ps
CONTAINER ID   IMAGE     COMMAND             CREATED          STATUS          PORTS                     NAMES
8ad64e755f65   tomcat    "catalina.sh run"   6 seconds ago    Up 5 seconds    0.0.0.0:49162->8080/tcp   tomcat02
76ab3aba3e19   tomcat    "catalina.sh run"   16 seconds ago   Up 15 seconds   0.0.0.0:49161->8080/tcp   tomcat01
  1. 把tomcat加入jiusheng网络
♾️ shell 代码:
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker network connect jiusheng tomcat02
  1. 查看jiusheng网络
♾️ shell 代码:
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker network inspect jiusheng
[
    {
        "Name": "jiusheng",
        "Id": "db61398754c4de6d331db1788071e11ad9fa5883167cba1f0bf021bf671527c8",
        "Created": "2021-08-01T17:58:35.111862913+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.0.0/16",
                    "Gateway": "192.168.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "76ab3aba3e19257a29e6b4702a9145d7da4f59150e63de4af865cec4d8f94dfa": {
                "Name": "tomcat01",
                "EndpointID": "dd654b8cb571b23e2fa206b08097bf35ea4ea901b420b8cfd2309bda48f18b06",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            },
            
            #我们可以看到,这里直接就把tomcat02加入了进来
            "8ad64e755f65f210eac46fd61c4ea2251810f4307b5d84e8aa67f764b30db50b": {
                "Name": "tomcat02",
                "EndpointID": "65c3a8b0634c77c689b512b5b9ee0a8473776cb63a8d45c44451f6bd41b8690f",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]
  1. 测试ping通
♾️ shell 代码:
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker exec -it tomcat01 ping tomcat02
PING tomcat02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat02.jiusheng (192.168.0.3): icmp_seq=1 ttl=64 time=0.088 ms
64 bytes from tomcat02.jiusheng (192.168.0.3): icmp_seq=2 ttl=64 time=0.061 ms
64 bytes from tomcat02.jiusheng (192.168.0.3): icmp_seq=3 ttl=64 time=0.048 ms
#发现是可以ping通的
  1. 反向ping
♾️ shell 代码:
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker exec -it tomcat02 ping tomcat01
PING tomcat01 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat01.jiusheng (192.168.0.2): icmp_seq=1 ttl=64 time=0.034 ms
64 bytes from tomcat01.jiusheng (192.168.0.2): icmp_seq=2 ttl=64 time=0.052 ms
64 bytes from tomcat01.jiusheng (192.168.0.2): icmp_seq=3 ttl=64 time=0.050 ms
#也是可以ping通的
部署redis,就不在演示了,也简单,自行百度

docker私有仓库

简介

Docker 中,当我们执行 docker pull xxx 的时候 ,它实际上是从 registry.hub.docker.com 这个地址去查找,这就是Docker公司为我们提供的公共仓库。在工作中,我们不可能把企业项目push到公有仓库进行管理。所以为了更好的管理镜像,Docker不仅提供了一个中央仓库,同时也允许我们搭建本地私有仓库。

官方私有仓库——registry

Docker 官方提供了一个搭建私有仓库的镜像 registry ,只需把镜像下载下来,运行容器并暴露5000端口,就可以使用了。
  1. 下载官方registry
♾️ shell 代码:
docker pull registry
#这里默认下载最新版本
  1. 运行下载好的镜像
♾️ shell 代码:
#查看镜像
docker images  
#运行镜像
docker run -d -v /opt/registry:/var/lib/registry -p 5000:5000 --name ck registry
#Registry服务默认会将上传的镜像保存在容器的/var/lib/registry,我们将主机的/opt/registry目录挂载到该目录,即可实现将镜像保存到主机的/opt/registry目录了。
  1. 查看是否成功运行
♾️ shell 代码:
docker ps
#访问网页ip:5000/v2
#出现{}及成功运行
l16c5wto.png
  1. 验证服务
♾️ shell 代码:
#通过push镜像来验证registry是否成功启动
#下载一个镜像
docker pull nginx
#查看镜像
docker images
#通过docker tag将该镜像标志为要推送到私有仓库
docker tag nginx:latest localhost:5000/nginx:latest
#通过 docker push 命令将 nginx 镜像 push到私有仓库中
docker push localhost:5000/nginx:latest
#访问ip:5000/v2/_catalog 查看私有仓库目录,可以看到刚上传的镜像
#下载私有仓库的镜像,使用如下命令
docker pull localhost:5000/镜像名:版本号
#例如
docker pull localhost:5000/nginx:latest
l16c6g7v.png

harbor私有仓库

docker 官方提供的私有仓库 registry,用起来虽然简单 ,但在管理的功能上存在不足。 Harbor是一个用于存储和分发Docker镜像的企业级Registry服务器,harbor使用的是官方的docker registry(v2命名是distribution)服务去完成。harbor在docker distribution的基础上增加了一些安全、访问控制、管理的功能以满足企业对于镜像仓库的需求。

下载地址

harbor仓库使用到docker-compose,所以,你需要提前安装它。
  1. 安装
♾️ shell 代码:
#选择一个文件下载
wget wget https://github.com/goharbor/harbor/releases/download/v2.5.0-rc1/harbor-offline-installer-v2.5.0-rc1.tgz -O harbor.tgz
#解压
tar zxvf harbor.tgz
#里面文件构建如下
-rw-r--r-- 1 root root      3361 Mar  4 16:37 common.sh
-rw-r--r-- 1 root root 657621862 Mar  4 16:37 harbor.v2.5.0.tar.gz
-rw-r--r-- 1 root root      9917 Mar  4 16:37 harbor.yml.tmpl
-rwxr-xr-x 1 root root      2500 Mar  4 16:37 install.sh
-rw-r--r-- 1 root root     11347 Mar  4 16:37 LICENSE
-rwxr-xr-x 1 root root      1881 Mar  4 16:37 prepare
#这里我们要修改一下harbor.yml.tmpl为harbor.yml
mv harbor.yml.tmpl ./ harbor.yml
#编辑配置文件harbor.yml
vim harbor.yml
#修改和注释一下内容
# Configuration file of Harbor
# The IP address or hostname to access admin UI and registry service.
# DO NOT use localhost or 127.0.0.1, because Harbor needs to be accessed by external clients.
hostname: 121.5.38.73    #这里就是说不能是localhost or 127.0.0.1,可以域名或者本机ip。

# http related config
http:
  # port for http, default is 80. If https enabled, this port will redirect to https port
  port: 80

# https related config
#https:    #没有配置ssl证书,所以我们需要注释掉https的参数!
  # https port for harbor, default is 443
#  port: 443
  # The path of cert and key files for nginx
#  certificate: /your/certificate/path    #ssl证书路径
#  private_key: /your/private/key/path    #ssl秘钥路径


#运行脚本install.sh部署仓库
./install.sh
#查看是否成功运行
[root@master harbor]# docker ps
CONTAINER ID   IMAGE                                COMMAND                  CREATED       STATUS                 PORTS                       NAMES
f384fc223903   goharbor/nginx-photon:v2.5.0         "nginx -g 'daemon of…"   4 hours ago   Up 4 hours (healthy)   0.0.0.0:80->8080/tcp        nginx
2fc54466355e   goharbor/harbor-jobservice:v2.5.0    "/harbor/entrypoint.…"   4 hours ago   Up 4 hours (healthy)                               harbor-jobservice
fd60b7ebe6b6   goharbor/harbor-core:v2.5.0          "/harbor/entrypoint.…"   4 hours ago   Up 4 hours (healthy)                               harbor-core
970df803c63a   goharbor/redis-photon:v2.5.0         "redis-server /etc/r…"   4 hours ago   Up 4 hours (healthy)                               redis
c9b89fd1eb00   goharbor/harbor-db:v2.5.0            "/docker-entrypoint.…"   4 hours ago   Up 4 hours (healthy)                               harbor-db
baf0553cafd7   goharbor/harbor-portal:v2.5.0        "nginx -g 'daemon of…"   4 hours ago   Up 4 hours (healthy)                               harbor-portal
731b55a6a8e3   goharbor/registry-photon:v2.5.0      "/home/harbor/entryp…"   4 hours ago   Up 4 hours (healthy)                               registry
06c3cad49a33   goharbor/harbor-registryctl:v2.5.0   "/home/harbor/start.…"   4 hours ago   Up 4 hours (healthy)                               registryctl
c8980d2fb387   goharbor/harbor-log:v2.5.0           "/bin/sh -c /usr/loc…"   4 hours ago   Up 4 hours (healthy)   127.0.0.1:1514->10514/tcp   harbor-log

#查看运行后的镜像列表
[root@master harbor]# docker images
REPOSITORY                      TAG       IMAGE ID       CREATED       SIZE
registry                        latest    8948869ebfee   7 days ago    24.2MB
goharbor/harbor-exporter        v2.5.0    70893e0bcdd3   11 days ago   90MB
goharbor/chartmuseum-photon     v2.5.0    9622027cfdc7   11 days ago   228MB
goharbor/redis-photon           v2.5.0    9a083b2a368f   11 days ago   158MB
goharbor/trivy-adapter-photon   v2.5.0    d09fd9cd6d3f   11 days ago   155MB
goharbor/notary-server-photon   v2.5.0    d36bb495692a   11 days ago   115MB
goharbor/notary-signer-photon   v2.5.0    2583d6c93a43   11 days ago   112MB
goharbor/harbor-registryctl     v2.5.0    70862e0cbb5f   11 days ago   139MB
goharbor/registry-photon        v2.5.0    44e6d030ef05   11 days ago   80.8MB
goharbor/nginx-photon           v2.5.0    c5f863149003   11 days ago   47.3MB
goharbor/harbor-log             v2.5.0    fe824554edac   11 days ago   162MB
goharbor/harbor-jobservice      v2.5.0    95908dfefed1   11 days ago   229MB
goharbor/harbor-core            v2.5.0    d96c170c3235   11 days ago   206MB
goharbor/harbor-portal          v2.5.0    76f465040c9e   11 days ago   55.6MB
goharbor/harbor-db              v2.5.0    12d465bbb41a   11 days ago   227MB
goharbor/prepare                v2.5.0    635dbac6a2f5   11 days ago   269MB
这个时候我们访问ip,就可以发现登录界面,默认 admin 用户的密码为 Harbor12345
l16c71au.png
  1. 创建新项目
    l16c7ifj.png

根据要求填写数据

l16c7tvx.png
  1. 登录仓库
♾️ shell 代码:
[root@master harbor]# docker login -u admin -p 123456 127.0.0.1
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
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. 上传镜像
♾️ shell 代码:
#通过docker tag将该镜像标志为要推送到私有仓库
docker tag nginx:latest 127.0.0.1/jiusheng/nginx:latest
#通过 docker push 命令将 nginx 镜像 push到私有仓库中
docker push 127.0.0.1/jiusheng/nginx:latest
这个时候在网页就可以查看到上传的镜像
l16c8blq.png
  1. 远程链接是仓库
♾️ shell 代码:
#Docker Registry 交互默认使用的是 HTTPS,但是搭建私有镜 我们使用的是 HTTP 服务,所以与私有镜像交互时出现错误。
[root@node ~]# docker login -u admin -p 123456 http://121.5.38.73
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
Error response from daemon: Get https://121.5.38.73/v2/: dial tcp 121.5.38.73:443: connect: connection refused
#这个时候我们要修改配置文件docker.service
vim /usr/lib/systemd/system/docker.service
#修改如下
[Unit]
*********
[Service]
ExecStart=/usr/bin/dockerd -H fd:// --insecure-registry 121.5.38.73 --containerd=/run/containerd/containerd.sock
#添加如下
--insecure-registry 121.5.38.73  #这里就是你仓库的地址,有端口的带上端口
#结果
ExecStart=/usr/bin/dockerd -H fd:// --insecure-registry 121.5.38.73 --containerd=/run/containerd/containerd.sock

#重启docker服务
systemctl daemon-reload && systemctl restart docker

#链接
[root@node ~]# docker login -u admin -p 123456 121.5.38.73
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
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. 上传镜像
♾️ shell 代码:
#这里我们没有镜像,所以下载一个centos镜像
docker pull centos
#查看镜像
docker images
#上传镜像,和之前的操作一样,只是ip不一样
docker tag centos:latest 121.5.38.73/jiusheng/centos:latest
docker push 121.5.38.73/jiusheng/centos:latest
网页即可查看到刚才的镜像
l16c8qo1.png
下载命令
♾️ shell 代码:
#命令格式喝下
docker pull ip/项目名/镜像
#示例
docker pull 121.5.38.73/jiusheng/centos:latest

docker——compose

Compose介绍

Docker Compose是一个用来定义和运行复杂应用的Docker工具。一个使用Docker容器的应用,通常由多个容器组成。使用Docker Compose不再需要使用shell脚本来启动容器。
Compose 通过一个配置文件来管理多个Docker容器,在配置文件中,所有的容器通过services来定义,然后使用docker-compose脚本来启动,停止和重启应用,和应用中的服务以及所有依赖服务的容器,非常适合组合使用多个容器进行开发的场景。

Compose和Docker兼容性

l16cdjbl.png

安装docker-compose

版本发布地址:https://github.com/docker/compose/releases

两种安装方式

  1. 从github上下载docker-compose二进制文件安装下载最新版的docker-compose文件
♾️ shell 代码:
#下载最新版的docker-compose文件 
sudo curl -L https://github.com/docker/compose/releases/download/1.16.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
  1. 若是github访问太慢,可以用daocloud下载
♾️ shell 代码:
sudo curl -L https://get.daocloud.io/docker/compose/releases/download/1.16.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
  1. 添加可执行权限
♾️ shell 代码:
sudo chmod +x /usr/local/bin/docker-compose
  1. 测试安装结果
♾️ shell 代码:
$ docker-compose --version

docker-compose version 1.16.1, build 1719ceb

2.pip安装

♾️ shell 代码:
sudo pip install docker-compose

docker-compose文件结构和示例

docker-compose文件结构

docker-compose.yml

♾️ shell 代码:
#docker-compose.yml里面的内容

version: "3"    #version:指定 docker-compose.yml 文件的写法格式
services:         #services:多个容器集合
                       #补充environment:环境变量配置,可以用数组或字典两种方式
  redis:
    image: redis:alpine    #image:指定服务所使用的镜像
    ports:                       #ports:定义宿主机端口和容器端口的映射,可使用宿主机IP+宿主机端口进行访问 宿主机端口:容器端口
    #补充 expose:定义容器用到的端口(一般用来标识镜像使用的端口,方便用ports映射)
      - "6379"
    networks:
      - frontend
    deploy:
      replicas: 2
      update_config:
        parallelism: 2
        delay: 10s
      restart_policy:
        condition: on-failure
 
  db:
    image: postgres:9.4
    volumes:                 #volumes:卷挂载路径,定义宿主机的目录/文件和容器的目录/文件的映射  宿主机路径:容器路径
    #depend_on: 规定service加载顺序,例如数据库服务需要在后台服务前运行

#extra_hosts:类似于docker里的--add-host参数 配置DNS域名解析(域名和IP的映射)
      - db-data:/var/lib/postgresql/data
    networks:
      - backend
    deploy:
      placement:
        constraints: [node.role == manager]
 
  vote:
    image: dockersamples/examplevotingapp_vote:before
    ports:
      - 5000:80
    networks:
      - frontend
    depends_on:
      - redis
    deploy:
      replicas: 2
      update_config:
        parallelism: 2
      restart_policy:
        condition: on-failure
 
  result:
    image: dockersamples/examplevotingapp_result:before
    ports:
      - 5001:80
    networks:
      - backend
    depends_on:
      - db
    deploy:
      replicas: 1
      update_config:
        parallelism: 2
        delay: 10s
      restart_policy:
        condition: on-failure
 
  worker:
    image: dockersamples/examplevotingapp_worker
    networks:
      - frontend
      - backend
    deploy:
      mode: replicated
      replicas: 1
      labels: [APP=VOTING]
      restart_policy:
        condition: on-failure
        delay: 10s
        max_attempts: 3
        window: 120s
      placement:
        constraints: [node.role == manager]
 
  visualizer:
    image: dockersamples/visualizer:stable
    ports:
      - "8080:8080"
    stop_grace_period: 1m30s
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    deploy:
      placement:
        constraints: [node.role == manager]
 
networks:
  frontend:
  backend:
 
volumes:
  db-data:

第一个compose程序

  1. 创建一个目录
♾️ shell 代码:
mkdir composetest && cd composetest
  1. 在项目目录中创建一个名为的文件app.py并配置。
♾️ shell 代码:
vim app.py
#添加如下
import time

import redis
from flask import Flask

app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)
#在此示例中,redis是应用程序网络上的redis容器的主机名。我们使用 Redis的默认端口,6379
def get_hit_count():
    retries = 5
    while True:
        try:
            return cache.incr('hits')
        except redis.exceptions.ConnectionError as exc:
            if retries == 0:
                raise exc
            retries -= 1
            time.sleep(0.5)

@app.route('/')
def hello():
    count = get_hit_count()
    return 'Hello World! I have been seen {} times.\n'.format(count)   
  1. 在目录中创建另一个名为的文件requirements.txt,并添加如下
♾️ shell 代码:
vim requirements.txt
#添加如下
flask
redis
  1. 在目录中,创建一个名为Dockerfile并配置如下内容
♾️ dockerfile 代码:
vim Dockerfile
#添加如下

# syntax=docker/dockerfile:1
FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run"]

这告诉 Docker:

  • 从 Python 3.7 映像开始构建映像。
  • 将工作目录设置为/code.
  • 设置命令使用的环境变量flask
  • 安装 gcc 和其他依赖项
  • 安装requirements.txt中的 Python 依赖项。
  • 向镜像添加元数据以描述容器正在侦听端口 5000
  • 将项目中的当前目录复制.到镜像中的workdir .
  • 将容器的默认命令设置为flask run.、
  1. 目录中创建一个名为的文件docker-compose.yml并编写如下内容
♾️ yaml 代码:
vim docker-compose.yml

#添加如下

version: "3.9"
services:
  web:
    build: .
    ports:
      - "8000:5000"
  redis:
    image: "redis:alpine"
    
#定义了两个服务:web和redis.
  1. 使用 Compose 构建并运行
♾️ shell 代码:
#使用docker-compose up,构建运行
docker-compose up

[root@node composetest]# docker-compose up
[+] Running 7/7
 ⠿ redis Pulled                                                                                   4.2s
#******省略
composetest-redis-1  | 1:M 16 Mar 2022 08:28:19.248 * Ready to accept connections
composetest-web-1    |  * Serving Flask app 'app.py' (lazy loading)
composetest-web-1    |  * Environment: production
composetest-web-1    |    WARNING: This is a development server. Do not use it in a production deployment.
composetest-web-1    |    Use a production WSGI server instead.
composetest-web-1    |  * Debug mode: off
composetest-web-1    |  * Running on all addresses.
composetest-web-1    |    WARNING: This is a development server. Do not use it in a production deployment.
composetest-web-1    |  * Running on http://172.18.0.3:5000/ (Press CTRL+C to quit)

#查看
[root@node ~]# docker ps
CONTAINER ID   IMAGE             COMMAND                  CREATED          STATUS          PORTS                    NAMES
f86849da968b   composetest_web   "flask run"              36 seconds ago   Up 35 seconds   0.0.0.0:8000->5000/tcp   composetest-web-1
3b4112182774   redis:alpine      "docker-entrypoint.s…"   36 seconds ago   Up 34 seconds   6379/tcp                 composetest-redis-1

#验证是否成功启动
[root@node ~]# curl localhost:8000
Hello World! I have been seen 1 times.
  1. 其他命令
♾️ shell 代码:
#查看命令docker-compose ps
[root@node composetest]# docker-compose ps
NAME                  COMMAND                  SERVICE             STATUS              PORTS
composetest-redis-1   "docker-entrypoint.s…"   redis               running             6379/tcp
composetest-web-1     "flask run"              web                 running             0.0.0.0:8000->5000/tcp
#停止命令docker-compose down 或者docker-compose stop
[root@node composetest]# docker-compose down
[+] Running 3/2
 ⠿ Container composetest-redis-1  Removed                                                         0.2s
 ⠿ Container composetest-web-1    Removed                                                        10.1s
 ⠿ Network composetest_default    Removed                                                         0.0s
#后台运行
docker-compose up -d

[root@node composetest]# docker-compose up -d
[+] Running 3/3
 ⠿ Network composetest_default    Created                                                         0.0s
 ⠿ Container composetest-redis-1  Started                                                         0.5s
 ⠿ Container composetest-web-1    Started                                                         0.5s
#停止并删除
docker-compose down --volumes

root@node composetest]# docker-compose down --volumes
[+] Running 3/2
 ⠿ Container composetest-redis-1  Removed                                                         0.2s
 ⠿ Container composetest-web-1    Removed                                                        10.1s
 ⠿ Network composetest_default    Removed                                                         0.0s
[root@node composetest]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

快速部署一个 wordpress博客

  1. 创建一个目录
♾️ shell 代码:
mkdir my_wordpress && cd my_wordpress
  1. 编写docker-compose.yml文件
♾️ yaml 代码:
vim docker-compose.yml
#填写如下

version: "3.9"
    
services:
  db:
    image: mysql:5.7
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: somewordpress
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress
    
  wordpress:
    depends_on:
      - db
    image: wordpress:latest
    volumes:
      - wordpress_data:/var/www/html
    ports:
      - "80:80"
    restart: always
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress
volumes:
  db_data: {}
  wordpress_data: {}
  1. 运行并查看
♾️ shell 代码:
[root@node my_wordpress]# docker-compose up -d
[+] Running 0/2
 ⠙ wordpress Pulling                                                                           
#省略                                               
 ⠿ Container my_wordpress-db-1           Started                                                  1.1s
 ⠿ Container my_wordpress-wordpress-1    Started                                                  0.7s
[root@node my_wordpress]# docker-compose ps
NAME                       COMMAND                  SERVICE             STATUS              PORTS
my_wordpress-db-1          "docker-entrypoint.s…"   db                  running             33060/tcp
my_wordpress-wordpress-1   "docker-entrypoint.s…"   wordpress           running             0.0.0.0:80->80/tcp
访问网页ip,我这里设置的80端口,所以直接ip
l16ce2xn.png

快速部署一个Typecho博客

  1. 构建目录
♾️ shell 代码:
typecho                    # 目录,随便什么名字
  -docker-compose.yml      # docker-compose配置文件
  -mysql                   # mysql数据,配置信息,日志所在目录
  -nginx
    -default.conf          # nginx配置文件
  -php  
    -Dockerfile            # php镜像的dockerfile
  -www
    -build                 #网站源码,需要创建www及可,网站源码解压得到build文件
  1. docker-compose.yml配置如下
♾️ yaml 代码:
MYSQL_ROOT_PASSWORD: root用户密码
MYSQL_DATABASE: 数据库名
MYSQL_USER: 用户名
MYSQL_PASSWORD: 数据库密码
♾️ yaml 代码:
version: "3"

services:
  nginx:
    image: nginx
    ports:
      - "80:80"
    restart: always
    volumes:
      - ./www/build:/var/www/html
      - ./nginx:/etc/nginx/conf.d
    depends_on:
      - php
    networks:
      - web
    
  php:
    build:
      context: ./php
      dockerfile: Dockerfile
    restart: always
    ports:
      - "9000:9000"
    volumes:
      - ./www/build:/var/www/html
    environment:
      - TZ=Asia/Shanghai
    depends_on:
      - mysql
    networks:
      - web

  mysql:
    image: mysql:5.7
    restart: always
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: asd745201314
      MYSQL_DATABASE: typecho
      MYSQL_USER: typecho
      MYSQL_PASSWORD: asd745201314
      
    
    volumes:
      - ./mysql:/var/lib/mysql
      - ./mysql:/var/log/mysql
      - ./mysql:/etc/mysql/conf.d
    networks:
      - web

networks:
  web:
  1. nginx/default.conf配置如下
♾️ shell 代码:
server {
    listen       80;
    server_name liuqingzheng.com;
    root /var/www/html;
    index index.php;
    access_log /var/log/nginx/typecho_access.log main;
    location ~ .*\.php(\/.*)*$ {
        fastcgi_pass   php:9000;
        fastcgi_index  index.php;
        fastcgi_param  PATH_INFO $fastcgi_path_info;
        fastcgi_param  PATH_TRANSLATED $document_root$fastcgi_path_info;
        fastcgi_param  SCRIPT_NAME $fastcgi_script_name;
        fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }

}
  1. php/Dockerfile配置如下
♾️ dockerfile 代码:
FROM php:7.3.29-fpm
MAINTAINER lqz
RUN apt-get update && docker-php-ext-install pdo_mysql && echo "output_buffering = 4096" > /usr/local/etc/php/conf.d/php.ini
  1. www/build配置如下
♾️ shell 代码:
#在www目录下,下载程序包
wget https://github.com/typecho/typecho/releases/download/v1.2.0/typecho.zip
#解压,即可得到build目录
yun install unzip -y
unzip typecho.zip && rm -rf typecho.zip
  1. 构建并运行
♾️ shell 代码:
docker-compose up -d
  1. 打开网页填写数据库

数据库名:typecho

数据库用户名:typecho

数据库密码:asd745201314

数据库root用户密码:asd745201314

数据库地址:mysql

安装提示如下内容

l16cek3n.png

进行如下处理

♾️ shell 代码:
#在网站的根目录也就是build目录下创建config.inc.php并配置文件
vim config.inc.php

#代码如下,以实际数据为准,及复制你的
<?php
// site root path
define('__TYPECHO_ROOT_DIR__', dirname(__FILE__));

// plugin directory (relative path)
define('__TYPECHO_PLUGIN_DIR__', '/usr/plugins');

// theme directory (relative path)
define('__TYPECHO_THEME_DIR__', '/usr/themes');

// admin directory (relative path)
define('__TYPECHO_ADMIN_DIR__', '/admin/');

// register autoload
require_once __TYPECHO_ROOT_DIR__ . '/var/Typecho/Common.php';

// init
\Typecho\Common::init();

// config db
$db = new \Typecho\Db('Pdo_Mysql', 'typecho_');
$db->addServer(array (
  'host' => 'mysql',  #填写的数据库地址
  'port' => 3306,     #端口
  'user' => 'typecho',  #用户名
  'password' => 'asd745201314',   #密码
  'charset' => 'utf8mb4',   #编码
  'database' => 'typecho',   #数据库名
  'engine' => 'InnoDB',
), \Typecho\Db::READ | \Typecho\Db::WRITE);
\Typecho\Db::set($db);
#上面的就是我们在yaml文件里面编写的数据。

之后在确认安装就完成了。

命令总结

♾️ shell 代码:
使用 Docker 定义和运行多容器应用程序。

用法:
  docker-compose [-f <arg>...] [--profile <name>...] [options] [COMMAND] [ARGS...]
  docker-compose -h|--帮助

选项:
  -f, --file FILE 指定一个备用的撰写文件
                              (默认:docker-compose.yml)
  -p, --project-name NAME 指定备用项目名称
                              (默认:目录名)
  --profile NAME 指定要启用的配置文件
  --verbose 显示更多输出
  --log-level LEVEL 已弃用且从 2.0 开始无法使用 - 设置日志级别(DEBUG、INFO、WARNING、ERROR、CRITICAL)
  --no-ansi 不打印 ANSI 控制字符
  -v, --version 打印版本并退出
  -H, --host HOST 要连接的守护进程套接字

  --tls 使用 TLS;由 --tlsverify 暗示
  --tlscacert CA_PATH 仅由该 CA 签名的信任证书
  --tlscert CLIENT_CERT_PATH TLS 证书文件的路径
  --tlskey TLS_KEY_PATH TLS 密钥文件的路径
  --tlsverify 使用 TLS 并验证远程
  --skip-hostname-check 不检查守护进程的主机名
                              客户端证书中指定的名称
  --project-directory PATH 指定备用工作目录
                              (默认:Compose 文件的路径)
  --compatibility 如果设置,Compose 将尝试转换 deploy
                              v3 文件中的密钥到它们的非 Swarm 等效项

命令:
  build 构建或重建服务
  bundle 从 Compose 文件生成一个 Docker 包
  config 验证并查看 Compose 文件
  create 创建服务
  down 停止和移除容器、网络、镜像和卷
  events 从容器接收实时事件
  exec 在正在运行的容器中执行命令
  help 获取有关命令的帮助
  images 镜像列表
  kill 杀死容器
  logs 查看容器的输出
  pause 暂停服务
  port 打印端口绑定的公共端口
  ps 列出容器
  pull 拉取服务镜像
  push 推送服务镜像
  restart 重启服务
  rm 删除停止的容器
  run 运行命令
  scale 设置服务的容器数量
  start 启动服务
  stop 停止服务
  top 显示正在运行的进程
  unpause 取消暂停服务
  up 创建并启动容器
  version 显示 Docker-Compose 版本信息



用法:docker compose [OPTIONS] 命令

码头工人撰写

选项:
      --ansi string 控制何时打印 ANSI 控制字符 ("never"|"always"|"auto") (默认 "auto")
      --compatibility 在向后兼容模式下运行 compose
      --env-file string 指定备用环境文件。
  -f, --file stringArray 编写配置文件
      --profile stringArray 指定要启用的配置文件
      --project-directory string 指定备用工作目录
                                   (默认:Compose 文件的路径)
  -p, --project-name 字符串 项目名称

命令:
  build 构建或重建服务
  convert 将撰写文件转换为平台的规范格式
  cp 在服务容器和本地文件系统之间复制文件/文件夹
  create 为服务创建容器。
  down 停止并移除容器、网络
  events 从容器接收实时事件。
  exec 在正在运行的容器中执行命令。
  images 列出创建的容器使用的图像
  kill 强制停止服务容器。
  logs 查看容器的输出
  ls 列出正在运行的撰写项目
  pause 暂停服务
  port 打印端口绑定的公共端口。
  ps 列出容器
  pull 拉取服务镜像
  push 推送服务镜像
  restart 重启容器
  rm 删除停止的服务容器
  run 运行命令
  start 启动服务
  stop 停止服务
  top 显示正在运行的进程
  unpause 取消暂停服务
  up 创建并启动容器
  version 显示 Docker Compose 版本信息

运行 'docker compose COMMAND --help' 以获取有关命令的更多信息。

结语

   《戏为六绝》 ——杜甫
未及前贤更勿疑,递相祖述复先谁?
别裁伪体亲风雅,转益多师是汝师

最后附上pdf,回复自取。
{hide}

{cloud title="docker" type="lz" url="https://wwu.lanzoub.com/itehe01l6t8b" password=""/}

{/hide}

现在已有 3 条评论,465 人点赞
Comment:共3条
发表
  1. 头像
    @
    青栀
    写得挺详细的,不错。::(太开心)
    · Windows · Chrome · 中国重庆联通

    👍

    💖

    💯

    💦

    😄

    🪙

    👍 0 💖 0 💯 0 💦 0 😄 0 🪙 0
  2. 头像
    @
    赞!
    · Windows · Chrome · 中国云南省电信

    👍

    💖

    💯

    💦

    😄

    🪙

    👍 0 💖 0 💯 0 💦 0 😄 0 🪙 0
    1. 头像
      @
      @落
      强(群友过来捧场)
      · Android · Chrome · 中国湖南省湘潭市湘乡市移动

      👍

      💖

      💯

      💦

      😄

      🪙

      👍 0 💖 0 💯 0 💦 0 😄 0 🪙 0
搜 索 消 息 足 迹
你还不曾留言过..
你还不曾留下足迹..
博主 不再显示
博主