0%

Docker

Docker

安装

mac版本直接使用home brew 进行安装

1
brew install --cask docker

docker 安装成功后可以测试一下:使用 docker pull hello-world 从docker官方库拉取镜像“hello-world”。然后运行该镜像:docker run hello-world,若出现提示“Hello from Docker!” 表示docker安装成功。

Docker常用命令

  • docker pull tomcat:latest
    
    1
    2
    3
    4
    5

    从docker官方的远程仓库拉取镜像,冒号前为镜像名,冒号后为该镜像的tag(版本)

    - ```bash
    docker images 查看本地镜像
  • docker run tomcat:latest    创建容器,启动应用
    如果运行run之前本地没有该镜像,docker会自动先拉取该镜像
    
    1
    2
    3

    - ```bash
    docker ps [-a] 查看运行中的镜像; -a代表查看所有容器,不仅仅是运行中的
  • docker rm [-f] container_id    删除容器
    
    1
    2
    3

    - ```bash
    docker rmi [-f] image_name:tags 删除镜像(顺便也会删除容器)
  • Docker 官方的远程镜像仓库:hub.docker.com

  • 端口映射:容器内部署了一个tomcat,其端口为8080,但此8080端口是容器内部的端口,而非物理机上的8080端口。因此外界无从知晓如何与容器内的tomcat通信。

    • docker run -p 8000:8080 -d tomcat   -p把宿主机的8000端口映射到docker容器内的8080端口; -d代表后台运行
      
      1
      2
      3

      - ```bash
      docker stop container_id 停止容器

进入容器内部

  • docker exec [-it] container_id 命令
    exec:在容器中执行命令
    -it:以交互方式执行命令(如果是执行bash,一定要加-it参数)
    如 docker exec -it 3fa5dbee2995 bash
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    - Docker 的镜像和容器存放在宿主机的 /var/lib/docker/ 目录下

    #### 容器生命周期

    - docker create 只创建容器,不运行;docker start 可使之运行
    - docker run 创建并运行容器
    - docker kill 停止容器,容器内的应用会被杀死。如果重新 docker start,容器内会重新创建新的应用程序进程
    - docker stop 停止容器,容器内的应用程序仅仅是暂停,docker start后,容器内上次的应用程序会恢复运行

    #### Docker file 构建镜像

    - docker file 中包含了用于组合镜像的一系列命令;docker 通过读取 docker file 中的指令自动构建镜像;

    - ```bash
    docker build -t 机构/镜像名<:tags> docker_file
  • 用docker file自动部署Tomcat应用; dockerfile 没有扩展名

    • FROM tomcat:latest    #设置基准镜像
      MAINTAINER xxx        #拥有者;用于说明
      WORKDIR /usr/local/tomcat/webapps    #相当于cd;但如果当前目录不存在,WORKDIR会自动创建之
      ADD docker-web ./docker-web    #将当前宿主机的docker-web 文件复制到docker容器中的./docker-web目录,.是相对于WORKDIR的
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17

      - 上述构建过程有4步,docker在build的过程中,每执行一步,都会生成一个临时快照,输出一个镜像id。这些中间快照称为cache,可以在其他镜像构建过程中被共用以节约时间。

      - Docker file 中的命令

      - FROM-基于基准镜像

      - FROM centos #基于centos制作基准镜像
      - FROM scratch #不依赖任何基准镜像
      - FROM tomcat:latest #基于tomcat

      - 说明信息

      ```bash
      MAINTAINER xxx #说明信息,拥有者
      LABEL version="1.0" #描述版本
      LABEL description="my image" #描述信息
    • WORKDIR 设置工作目录(不存在会自动创建)

    • ADD 复制文件

      • ADD docker-web ./docker-web
      • ADD docker-web.tar.gz . ADD还会自动解压缩
      • ADD 可以抓取网络资源文件
    • ENV 设置环境常量

      • ENV JAVA_HOME /usr/local/openjdk8
      • ENV MYSQL_PWD root;
    • 运行指令

      • RUN 在构建镜像过程中执行的指令

        1
        2
        RUN yum install -y vim 直接命令格式执行
        RUN ["yum", "install", "-y", "vim"] exec命令格式
      • CMD、ENTRYPOINT 在启动容器时执行的指令

        • docker file中若有多个ENTRYPOINT 指令,只有最后一个会被执行
        • 格式同RUN
    • 使用docker file 构建一个自定义的redis镜像

      1
      2
      3
      4
      5
      6
      7
      8
      9
      FROM centos
      RUN ["yum", "install", "-y", "gcc", "gcc-c++", "net-tools", "make"]
      WORKDIR /usr/local
      ADD redis-4.0.14.tar/gz .
      WORKDIR /usr/local/redis-4.0.14/src
      RUN make && make install
      ADD redis-7000.conf .
      EXPOSE 7000
      CMD ["redis-server", "redis-7000.conf"]

    容器间的单向通信

    一般来说一个容器中只有一个应用程序,docker给不同容器都分配了虚拟ip地址,即docker内部的ip,不同容器之间可以通过对方的虚拟ip进行通信。但这么做,一旦ip发生变化,就会出现问题。

    • docker inspect container_id 查看对应容器的元数据

    • –link 可以实现单向通信;在启动一个新容器时,添加–link参数;单向通信使得容器可以使用对方容器的名字进行通信,而非虚拟ip

      1
      2
      docker run -d(后台运行) --name web(本次启动的容器名为web) --link database(通过对方容器名实现单向通信) tomcat(本次加载的镜像名)
      这时,在web容器内部,就可以使用对方容器名database进行通信,而非对方虚拟ip

    使用Bridge实现容器的双向通信

    • 查看当前docker底层网络服务: docker network ls

    • 新建网桥

      1
      docker network create -d bridge my-bridge  #新建名为mybridge的网桥
    • 将两个容器分别连接到新建的网桥

      1
      2
      3
      docker network connect my-bridge web
      docker netword connect my-bridge database
      #接着,两个容器可以分别使用对方的容器名进行通信,无需使用虚拟ip

    容器间共享数据

    • 为什么要共享数据

      如果有3个tomcat容器,每个tomcat容器中都存放了一份静态网页数据。一旦我们需要将网页数据修改,就得在3个tomcat容器中都同步修改。而如果将静态网页数据独立出来,3个tomcat容器共享一份数据,就可以只改动一份数据

    • 方法一:-v 将宿主机的一个目录挂载到容器目录

      1
      2
      3
      docker run --name 容器名 -v 宿主机路径:容器内挂载路径 镜像名
      #例子:
      docket run --name web1 -v /usr/webapps:/usr/local/tomcat/webapps tomcat
    • 方法二:通过创建一个共享容器实现挂载

      1
      2
      3
      4
      #step1 创建共享容器,将宿主机目录(内有需要共享的文件)挂载到该共享容器
      docker create --name webpage -v /usr/webapps:/usr/local/tomcat/webapps tomcat
      #共享容器webpage的挂载点
      docker run --volumes-from webpage --name t1 -d tomcat

    docker compose

    • docker compose 是一个容器编排工具。比如,一个完整的应用包含tomcat容器、ngnix容器、mysql容器等,把它们按照一定顺序部署起来,就是容器编排。docker compose的限制性是:只支持在单机上进行容器编排。

    • docker compose 使用 yml 文件进行编排

    • 创建docker-compose.yml

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      version: '3.3'    #docker compose 使用3.3版本的格式进行解析
      services:
      db: #服务名;会被docker compose用于命名新创建的容器;也被用于容器通信的容器名
      build: ./bsbdj-db/ #这是数据库的docker file的目录,docker compose会解析该dockerfile并生成镜像,创建容器
      restart: always #故障时,总是重启
      environment:
      MYSQL_ROOT_PASSWORD: root #启动mysql容器时,需要的环境变量
      app:
      build: ./bsbdj-app/
      depends_on:
      - db #说明,app容器的构建依赖于db容器
      ports:
      - "80:80" #容器内部app的端口(冒号右侧)到宿主机端口(冒号左侧)的映射
      restart: always

    • 在docker-compose.yml所在目录下,使用命令 docker-compose up,docker compose会自动编译构建镜像,并按照规则创建容器

    • docker-compose up -d 在后台编排容器;docker-compose logs 查看运行过程中的日志

    • docker-compose down 下线容器