• Docker学习笔记


    Docker镜像、容器、工作进程关系图

    安装与卸载Docker(CentOS)

    官网安装教程地址

    安装

    如果已经安装过旧版本的docker需要先通过以下命令删除

    sudo yum remove docker \
                      docker-client \
                      docker-client-latest \
                      docker-common \
                      docker-latest \
                      docker-latest-logrotate \
                      docker-logrotate \
                      docker-engine
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    然后通过以下命令确认CentOS的版本在7及以上(这里使用的是7.6.1810版本)

    cat /etc/centos-release
    
    • 1

    然后通过以下命令安装gcc环境

    sudo yum -y install gcc
    
    sudo yum -y install gcc-c++
    
    • 1
    • 2
    • 3

    然后通过以下命令安装yum-utils

    sudo yum install -y yum-utils
    
    • 1

    然后设置stable镜像仓库(用于下载docker远程仓库中的镜像,因为在大陆所以建议采用阿里或腾讯等的源)
    这里采用阿里云的源

    sudo yum-config-manager \
        --add-repo \
        http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    
    • 1
    • 2
    • 3

    然后最好更新以下yum软件包索引
    注意:CentOS8要去掉fast

    sudo yum makecache fast
    
    • 1

    然后要安装Docker引擎

    sudo yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin
    
    • 1

    安装完以上环境后就可以启动Docker了

    sudo systemctl start docker
    
    • 1

    启动后通过以下命令测试是否启动完成

    sudo docker version
    
    • 1

    如果出现以下信息则说明安装成功
    注意:Client端和Server端的版本号要一致

    可以再使用以下命令进行验证

    sudo docker run hello-world
    
    • 1

    如果出现以下内容说明docker运行正常

    卸载

    # 停止服务
    sudo systemctl stop docker
    # 移除docker依赖
    sudo yum remove docker-ce docker-ce-cli containerd.io docker-compose-plugin
    # 移除本地配置文件和各种第三方依赖
    sudo rm -rf /var/lib/docker
    sudo rm -rf /var/lib/containerd
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    常用命令

    帮助启动类命令

    镜像命令

    列出本地主机上的镜像

    docker images
    
    • 1

    如下图所示:

    各个表格项说明:
    REPOSITORY:表示镜像的仓库源
    TAG:镜像的标签(相当于版本号)
    IMAGE ID:镜像唯一ID
    CREATED:镜像创建时间
    SIZE:镜像大小

    同一仓库源可以有多个TAG版本,代表这个仓库源的不同个版本,我们使用REPOSITORY:TAG来定义不同的镜像。如果你不指定一个镜像的版本标签,例如你只使用ubuntu,docker将默认使用ubuntu:latest镜像

    常用参数:

    -a:列出本地所有的镜像(含历史映像层)
    -q:只显示镜像ID
    
    • 1
    • 2

    查找远程仓库中的指定镜像

    docker search 镜像名称
    
    • 1

    比如查找redis镜像:

    各个表格项说明:
    NAME:镜像名称
    DESCRIPTION:镜像说明
    STARS:点赞数量
    OFFICIAL:是否是官方的
    AUTOMATED:是否是自动构建的

    常用参数:

    --limit :只列出N个镜像,默认25个
    比如:docker search --limit 5 redis
    
    • 1
    • 2

    下载镜像

    docker pull 镜像名称[:TAG]
    
    • 1

    没有TAG就是最新版
    等价于

    docker pull 镜像名字:latest
    
    • 1

    查看镜像/容器/数据卷所占的空间

    docker system df
    
    • 1

    如下:

    删除某个镜像

    docker rmi 某个镜像名字或ID
    
    • 1

    当被删除的镜像已经创建了实例容器后,需要用以下参数强制删除:

    -f
    比如:docker rmi -f redis
    
    • 1
    • 2

    强制删除多个:

    docker rmi -f 镜像名1[:TAG] 镜像名2[:TAG] ...
    
    • 1

    问题:什么是Docker虚悬镜像

    仓库名、标签都是的镜像,俗称虚悬镜像dangling image

    容器命令

    新建并启动容器

    docker run [options] image [command] [arg...]
    
    • 1

    run执行流程图

    常用选项(options,重点):

    --name="容器新名字"   为容器指定一个名称;
    -d:后台运行容器并返回容器ID,也即启动守护式容器(后台运行);
    -i:以交互模式运行容器,通常与t同时使用;
    -t:为容器重新分配一个伪输入终端,通常与-i同时使用;
    也即启动交互式容器(前台有伪终端,等待交互);
    
    -P:随机端口映射,大写P
    -p:指定端口映射,小写p
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    释义:
    1.启动一个交互式容器,比如一个centos系统

    如果使用的不是镜像的latest版本则需要在后面加上版本号

    启动完成后注意观察终端的用户名称,会变为新终端的名称。此时可以进行交互

    2.端口映射的作用

    列出当前所有正在运行的容器

    docker ps [options]
    
    • 1


    常用选项:

    -a:列出当前所有正在运行的容器+历史上运行过的
    -l:显示最近创建的容器
    -n:显示最近n个创建的容器
    -q:静默模式,只显示容器编号
    
    • 1
    • 2
    • 3
    • 4

    退出容器

    1、使用exit命令退出
    run进去容器,exit退出,容器停止
    2、ctrl+p+q
    run进去容器,ctrl+p+q退出,容器不停止

    启动已经停止的容器

    docker start 容器ID或者容器名
    
    • 1

    重启、停止、强制停止容器

    #重启
    docker restart 容器ID或者容器名
    
    • 1
    • 2
    #停止
    docker stop 容器ID或者容器名
    
    • 1
    • 2
    #强制停止
    docker kill 容器ID或者容器名
    
    • 1
    • 2

    删除已停止的容器

    一定要先停止容器才能删除

    docker rm 容器ID
    
    • 1

    常用选项

    -f:强制删除某个容器,即使正在运行
    
    一次性删除多个容器实例
    docker rm -f $(docker ps -a -q)
    docker ps -a -q | xargs docker rm
    
    • 1
    • 2
    • 3
    • 4
    • 5

    启动守护容器详解

    何为守护容器?

    在大部分的场景下,我们希望docker的服务是在后台运行的,我们可以过 -d 指定容器的后台运行模式。

    机制解析

    很重要的一点: Docker容器后台运行,就必须有一个前台进程
    容器运行的命令如果不是那些一直挂起的命令(比如运行top,tail),就是会自动退出的。

    例子:以守护容器的方式启动redis

    查看容器日志

    docker logs 容器ID
    
    • 1

    查看容器内运行的进程

    docker top 容器ID
    
    • 1

    查看容器内部细节

    docker inspect 容器ID
    
    • 1

    进入正在运行的容器并以命令行交互(重要)

    docker exec命令
    docker exec [options] 容器ID 命令行环境(bash或者/bin/bash或者/bin/sh)
    
    • 1

    常用选项

    -d:后台运行容器并返回容器ID,也即启动守护式容器(后台运行);
    -i:以交互模式运行容器,通常与t同时使用;
    -t:为容器重新分配一个伪输入终端,通常与-i同时使用;
    也即启动交互式容器(前台有伪终端,等待交互);
    
    • 1
    • 2
    • 3
    • 4
    docker attach命令
    docker attach 容器ID
    
    • 1
    两者区别

    attach直接进入容器启动命令的终端,不会启动新的进程用exit退出,导致容器的停止。
    exec是在容器中打开新的终端,并且可以启动新的进程用exit退出,不会导致容器的停止。

    推荐使用exec

    例子:进入正在运行的redis容器并以命令行形式进行交互

    从容器内拷贝命令到主机上

    docker cp 容器ID:容器内路径 目的主机路径
    
    • 1

    导入和导出容器(用于自己制作镜像)

    方式1:export和import

    注意:导入的容器会作为一个镜像!!!

    #导出
    docker export 容器ID > 文件名.tar(或者一个新文件的绝对路径,只有文件名即导入到当前目录下)
    # 导入
    cat 文件名.tar(或者一个新文件的绝对路径) | docker import - 镜像用户/镜像名:镜像版本号
    镜像用户、镜像名、镜像版本号均可自定义,注意:横杠和后面的内容直接有空格
    
    • 1
    • 2
    • 3
    • 4
    • 5

    export导出容器的内容流作为一个tar归档文件[对应import命令]
    import 从tar包中的内容创建一个新的文件系统再导入为镜像[对应export命令]

    方式2:commit

    通过该命令将一个容器处理成一个镜像

    docker commit -m="提交的信息" -a="作者" 容器ID 要创建的目标镜像名[:版本号]
    
    • 1
    两者区别

    方式一相当于先把一个容器打包成压缩包然后导入成一个镜像其本质是一个压缩包,每次都是一个整体。方式二相当于在Base镜像的基础上扩展,如下图:

    容器数据卷

    主要作用:
    1.将容器内的数据备份到宿主机对应目录中,防止数据丢失
    2.在读写权限允许的情况下,可以在宿主机目录中对映射的容器内对应文件进行修改而不必进入容器修改。简化操作

    语法:

    1.使用命令


    使用多个-v命令可以挂载多个文件或目录
    如果要设置读写权限则在后面加上即可,如下 (默认为rw)


    这里的权限限制的是容器内的目录或文件而不是宿主机

    2.使用docker-compose编排服务

    个人理解: 比如在宿主机A中有个xxx.txt文件,在容器B中有个yyy.txt文件。
    此时通过 -v命令 将宿主机A中的xxx.txt文件与容器B中的yyy.txt文件进行映射(即将容器B中的yyy.txt文件挂载到宿主机A中的xxx.txt文件)。这种映射可以是文件,也可以是目录。
    此时如果容器中对应文件是可读写的,那么当在容器B内修改yyy.txt文件的内容时宿主机A中的xxx.txt文件的内容也会相应更改,反之亦然。
    如果映射的是目录也是同理,比如在宿主机A的XXX目录中新建了一个xxx.txt文件则在容器内对应的YYY目录中也会新增一个xxx.txt文件,反之亦然。
    上述操作,即使容器已经停止了,只要再启动回来也依旧能进行同步。

    查看容器的挂载目录(文件)

    通过以下命令查看:

    docker inspect 容器ID
    
    • 1

    容器卷之间的继承

    语法:

    1.使用命令

    个人理解: 现在有两个容器B1和B2,其中容器B1已经与宿主机建立了某种映射关系。现在通过以上命令将容器B2继承容器B1的映射关系。此时容器B2与宿主机的映射关系就相同了。此时哪怕容器B1停止甚至销毁了,容器B2与宿主机之间的映射关系都不会消失。

    挂载权限问题


    如果使用命令则加上--privileged=true即可:
    在这里插入图片描述
    如果使用的是docker-compose编排服务的方式则通过以下配置开启权限:

    Dockerfile(重点)

    Dockerfile是用来构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本。
    相当于一个清单,里面包含构建当前镜像所需要的所有构建命令。

    在Dockerfile中:
    1:每条保留字指令都必须为大写字母且后面要跟随至少一个参数
    2:指令按照从上到下,顺序执行
    3:#表示注释
    4:每条指令都会创建一个新的镜像层并对镜像进行提交

    Docker执行Dockerfile的大致流程

    (1)docker从基础镜像运行一个容器
    (2)执行一条指令并对容器作出修改
    (3)执行类似docker commit的操作提交一个新的镜像层
    (4) docker再基于刚提交的镜像运行一个新容器
    (5)执行dockerfile中的下一条指令直到所有指令都执行完成

    常用保留字*

    FROM
    基础镜像,当前新镜像是基于哪个镜像的,指定一个已经存在的镜像作为模板,第一条必须是from

    MAINTAINER(已弃用)
    镜像维护者的姓名和邮箱地址

    RUN
    指定容器构建时需要运行的命令
    两种格式:
    1.shell格式:RUN <命令行命令>
    <命令行命令>等同于,在终端操作的shell命令。
    2.exec格式
    RUN [“可执行文件”,“参数1”,“参数2”]
    例如:
    RUN [ “./test.php”, “dev”, “offline”]等价于RUN ./test.php dev offline

    EXPOSE
    当前容器对外暴露出的端口

    WORKDIR
    指定在创建容器后,终端默认登录进来的工作目录,一个落脚点。即运行该容器后所在的容器内部目录

    USER
    指定该镜像以什么样的用户去执行,如果都不指定,默认是root

    ENV
    用来在构建镜像过程中设置环境变量

    VOLUME
    容器数据卷,用于数据保存和持久化工作

    ADD与COPY
    ADD:将宿主机目录下的文件拷贝进镜像里的目录且会自动处理URL和解压tar压缩包

    COPY:拷贝文件和目录到镜像中。将从构建上下文目录中<源路径>的文件/目录复制到新的一层的镜像内的<目标路径>位置

    CMD与ENTRYPOINT
    都是指定容器启动后(run之后) 要干的事情
    CMD:


    ENTRYPOINT:

    DockerNetWork(重点)

    docker在启动后会产生一个名为docker0的虚拟网桥:

    DockerNetWork的作用

    1.用于进行docker的网络管理和容器调用之间的规划
    2.容器ip变动时候可以通过服务名直接网络通信而不受到影响。docker容器的ip会因为容器的重启、重新创建等产生变动所以推荐用服务名来进行网络通信,避免写死ip

    针对第二个作用例子如下:
    我们在容器编排时,编排了两个服务mysql和redis:

    同时将它们划归到了同一个名为darkforest_net的自定义docker网络下

    此时在springboot项目的配置文件中就可以直接采用服务名来连接服务了,而无需写死ip地址:

    采用这种方式后,无论mysql和redis两个服务的ip地址如何变化,docker都能自动映射。无需手动变更ip

    docker网络模式


    设置方式

    bridge模式(常用)




    例子:
    通过ip addr命令查看宿主机中的ip分配情况:

    以同样的方式查看容器中的ip分配情况:

    可以注意到是存在对应关系的,这里描述的就是上面图中bridge上的情况。

    host模式



    none模式


    container模式


    要注意:诸如tomcat等容器会默认使用8080端口,此时如果有个tomcat容器采用这种方式共用另一个tomcat容器的网络模式则会造成端口冲突(因为ip和端口都一样)。此时可以选择更改其中一个tomcat容器的默认端口(8080)。

    自定义docker网络(常用)

    作用:将一个或一组容器划归到同一个自定义网络中(即处在同一网段),以便通过服务名实现容器间的数据互通和进行网络管理。通过创建多个自定义网络来管理多组容器

    自定义网络默认使用bridge模式

    创建和加入命令

    创建自定义网络命令:

    docker network create 自定义网络名称
    
    • 1

    docker-compose配置文件中:

    加入自定义网络选项:

    --network 自定义的网络名称
    
    • 1

    docker-compose配置文件中:

    注意点(关注)

    1.采用docker-compose配置文件的方式创建自定义网络时,网络名称会带上所在目录的前缀

    在lighthouse目录下执行该docker-compose.yml文件后查看当前所有的docker网络

    可以发现多了一个所在目录的前缀

    2.docker-compose配置文件中为容器服务配置的网络,一定要在docker-compose配置文件中创建。不能先创建再执行会报找不到网络的错,即便加上目录前缀也没用。(docker版本:20.10.21;docker-compose版本:2.12.2)

    查看docker网络

    命令:

    docker network ls
    
    • 1

    查看网络源数据

    命令:

    docker network inspect 网络ID
    
    • 1

    Docker Compose容器编排(重点)


    安装

    官网地址
    官网下载较慢,可以使用国内网站提供的镜像

    容器编排步骤




    实际生产场景中一般使用一下命令来将容器实例运行为后台服务:

    docker-compose up -d
    
    • 1

    Compose 模板文件指令

    模板文件是使用 Docker Compose 的核心,涉及到的指令关键字也比较多。默认的模板文件名称为 docker-compose.yml ,格式为YAML 格式。一个 docker-compose.yml 文件可以分为三层:

    #第一层 版本号
    version: "3.8"  #代表使用docker-compose项目的版本号
    #第二层:services 服务配置
    services:
      web:
        build: .
        ports:  #宿主机和容器的端口映射
          - "5000:5000"
        volumes:
          - .:/code
      redis:
         image: "redis:alpine"
    # 第三层 其他配置 网络、卷、全局规划
    ...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    build 指令

    指定 Dockerfile 所在文件夹的路径(可以是绝对路径,或者相对 docker-compose.yml 文件的路径)。 Compose 将会利用它自动构建这个镜像,然后使用这个镜像。

    version: "3.8" 
    services:
      web:
        build: .  #指定Dockerfile的上下文目录为当前目录
    
    • 1
    • 2
    • 3
    • 4

    如上例子:要求构建web镜像的Dockerfile与 docker-compose.yml 文件在同一目录下。

    你也可以使用 context 指令指定 Dockerfile 所在文件夹的路径。
    使用 dockerfile 指令指定 Dockerfile 文件名。
    使用 arg 指令指定构建镜像时的变量。
    如下例子:

    version: '3'
    services:
      webapp:
        build:
          context: ./dir #指定Dockerfile的上下文目录为当前目录的dir目录下
          dockerfile: Dockerfile-alternate #指定要运行的Dockerfile文件名为Dockerfile-alternate
          args: 
            buildno: 1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    command 指令

    覆盖容器启动后默认执行的命令,类似于docker run image 命令
    以下面的Dockerfile文件为例,容器启动后执行的是 java -jar apps.jar

    FROM openjdk:8-jre
    EXPOSE 8081
    ENV APP_PATH=/apps
    WORKDIR $APP_PATH
    COPY apps.jar $APP_PATH
    ENTRYPOINT ["java","-jar"]
    CMD ["apps.jar"]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    如果我们想要容器启动后执行的是 java -jar test.jar,
    在docker-compose.yml文件中使用指令 command: [“test.jar”]

    version: '3'
    services:
      webapp:
        build:
          context: ./dir #定Dockerfile的上下文目录为当前目录的dir目录下
          dockerfile: Dockerfile-alternate
          args: 
            buildno: 1
        command: ["test.jar"]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    container_name 指令(不推荐使用)

    指定容器名称。默认将会使用 所在目录名_服务名称_序号 这样的格式。

    container_name: docker-web-container
    
    • 1

    注意: 指定容器名称后,该服务将无法进行扩展(scale),因为 Docker 不允许多个容器具有相同的名称。

    depends_on 指令

    解决容器的依赖、启动先后的问题。以下例子中会先启动 redis 、db 再启动 web

    version: '3'
    
    services:
      web:
        build: .
        depends_on: # web服务依赖于db和web服务
          - db
          - redis
    
      redis:
        image: redis
    
      db:
        image: postgres
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    注意:在启动web服务时,并不会等待 redis 、db 服务进入ready状态,而只是等到它们被启动状态(running状态)。

    environment 指令

    设置环境变量,相当于 docker run -e。你可以使用数组或字典两种格式。

    只给定名称的变量会自动获取运行 Compose 的宿主机上对应变量的值,可以用来防止泄露不必要的数据。

    version: '3'
    
    services:
      mysql:
        image: mysql:5.7
        ports:
          - "3306:3306"
        environment:
          MYSQL_ROOT_PASSWORD: root  #字典格式
          
    #====================================================
        environment:
          - "MYSQL_ROOT_PASSWORD=root"  #数组格式
          - "SESSION_SECRET"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    env_file 指令

    从文件中获取环境变量,可以为单独的文件路径或列表。
    如果通过 docker-compose -f FILE 方式来指定 Compose 模板文件,则 env_file 中变量的路径会基于模板文件路径。
    如果有变量名称与 environment 指令冲突,则按照惯例,以 environment 为准

    env_file: .env
    
    env_file: #指定多个环境变量文件
      - ./common.env
      - ./.env
      - /opt/secrets.env
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    环境变量文件中每一行必须符合格式,支持 # 开头的注释行。

    环境变量文件 .env:推荐使用这种命名,因为在Linux下,这种方式命名的文件属于隐藏文件,一定程度上防止泄露不必要的数据。

    expose 指令

    用来指定镜像构建过程中容器暴露的端口号,但不映射到宿主机,只被连接的服务访问。
    该指令compose配置文件中一般不用,都在Dockerfile文件中使用EXPOSE指定。

    image 指令

    指定创建容器实例服务所依赖的镜像,一般为镜像名称或镜像 ID。如果镜像在本地不存在,Compose 将会尝试拉取这个镜像,相当于 docker run image(镜像名)。

    networks 指令

    指定启动容器时使用的网络,相当于 docker run --network
    详情见Docker network章节

    version: "3"
    services:
    
      some-service:
        networks:
         - some-network  #指定使用的网络
         - other-network
    
    networks:   #创建网络
      some-network:
      other-network:
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    ports 指令

    指定宿主机和容器端口映射,或者仅仅指定容器的端口(宿主将会随机选择端口)都可以。

    注意:当使用 HOST:CONTAINER格式来映射端口时,如果你使用的容器端口小于 60 并且没放到引号里,可能会得到错误结果,因为YAML会自动解析xx:yy这种数字格式为 60 进制。为避免出现这种问题,建议数字串都采用引号包括起来的字符串格式。

    volumes 指令

    用来指定宿主机目录(或文件)和容器目录(或文件)映射。目录(或文件)不存在时会自动创建
    详情见容器数据卷章节

    version: "3"
    
    services:
      my_src:
        image: mysql:8.0
        volumes:  #数据卷名称挂载
          - mysql_data:/var/lib/mysql
    
    volumes:  #定义数据卷名称
      mysql_data:
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    restart 指令

    指定容器退出后的重启策略为始终重启。该命令对保持服务始终运行十分有效。

    restart: always
    
    • 1
  • 相关阅读:
    LeetCode_字符串_中等_816.模糊坐标
    OSG3.6.5帮助文件档编译
    SRM供应商关系管理是什么?SRM供应商关系管理系统包含哪方面的内容?
    《MySQL实战45讲》——学习笔记16 “order by排序原理、varchar(255)“
    python逆向基础流程(纯小白教程)
    stm32—GPIO
    QLineEdit
    谷粒商城 高级篇 (九) --------- 缓存失效问题
    RabbitMq:什么是RabbitMq? ①
    SAP ABAP教程之 02 创建您的第一份 ABAP 报告 (教程含源码)
  • 原文地址:https://blog.csdn.net/qq_44973993/article/details/127558401