从零开始学docker(四)

  1. 镜像
    1. 镜像构建
    2. 多段构建
      1. BuildKit工具镜像构建
  2. dockerCompose
    1. dockerCompose构建|运行镜像

镜像


镜像采用分层构建 联合挂载 机制 最底层为bootfs (用于系统引导的文件系统 包括bootloader和kernel 容器启动后会被卸载),然后是rootfs(位于bootfs
之上表现为docker的根文件系统 由内核挂载为只读模式,在在镜像最上面挂载可写层。)

image.png

镜像构建


# 镜像构建命令
docker image build -f DockerFile Context


NOTE

  • 注释信息 以# 开头
  • 语句顺序执行
  • 对大小写不敏感 约定俗称 关键字使用大写
  • 第一个非注释行必须为FROM 命令 通过一个已有镜像制作
  • 由于docker采用分层结构所以 每条语句都会产生新的层 ,所以尽量将语句放在一起写
  • 主要 COPY ADD 本地文件时可以使用任何指的文件夹下的内容
    docker build path|url|-

eg: docker build . 指的是当前目录 所以只能使用当前目录下的文件

  • 可在dockerfile同目录下添加.dockerignore忽略文件 类似于git的.ignore
  • 环境变量参数使用$param 或者${param}
    ${param+word}变量不为空使用word
    ${param-word} 变量为空使用默认值word
关键字 描述
FROM 镜像来源
MAINTANIER 【使用:MAINTANIER “zztzzt@email.com“】镜像作者
LABEL 使用:单行多个/多行
LABEL key=val key1=val1 …..
LABEL key=val
LABEL key1=val1
COPY 复制文件到容器 COPY src target src可以是多个为目录时则必须以/结尾
COPY [–chown=:] src… target
COPY [–chown=:] [“src”,… “target”]
ADD 添加文件到容器 使用:
ADD src … target
ADD [“src”,”src”….”target”]
VOLUME 指的用于挂载的目录挂载点 保证在容器启动时如果忘记指的会默认创建一个匿名存储卷来存储挂载点是不,这样容器消失后数据可以被保存下来. 使用:
VOLUME /date
VOLUME /date /date1
VOLUME[“/date”,”/date1”….. ]
EXPOSE 用于为容器打开指定要监听的端口实现与外部通信【EXPOSE 8080 8080/tcp 8080/udp】 tcp 和udp二选一 默认为tcp 该端口为可以暴露的接口 启动时并不会直接暴露
ENV 用于为镜像定义所需环境变量 可被dockerfile文件之后的指令所使用 和docker run –env 不同 此处是用在build过程中设置好的环境变量 【使用:ENV key=val key1=val1 ….. 】\反斜杠在此处还可用于转义空格
eg: COPY XXXXX $key1
ARG 参数 可通过–build-arg key=val 传入 也可被ENV使用
eg:
ARG author=zzt
ENV AUTHOR=${author+default}
RUN 运行sh命令在build过程【使用 :RUN 命令1 && 命令2 】 仅可运行基础镜像中存在的命令
CMD 运行命令在启动过程
仅可运行基础镜像中存在的命令
多个命令仅最后一个生效
命令可以被docker run 启动时的命令替换掉
数组写法不可使用环境变量参数
ENTRYPOINT 和CMD相比 默认情况命令不会类替换掉 如要替换
使用Docker container run –entrypoints “” container
定义多个ENTRYPOINT 最后一个生效
和CMD同时存在情况下 CMD会被当做参数交给ENTRYPOINT 执行
可通过添加entrypoint.sh 来让ENTRYPOINT 执行该文件 带入参数
USER 指定再容器中用哪个用户运行 USER user[:group] 或者USER UID[:GID]
ONBUILD 添加触发器 触发命令可以是dockerfile支持的任何命令 构建命令不会在自身文件构建是触发,在另一个镜像基于该镜像构建时会先触发该指令在处理后面的指令
HEALTHCHECK 健康检查
–interval=30s(default) 每隔30检查一次
–timeout= 30s (default) 超时时间
–start-period= 0s (default) 启动时健康检查延迟时间(等待程序启动完成)
–retries=3 (default) 允许的失败次数
SHELL 指定程序默认要使用的shell程序
SHELL [“执行工具”,”参数”,”参数”, ….]
STOPSIGNAL 指定推出时的信号值 可以是SIG< name > 也可以是与内核syscall表中的位置匹配的无符号数字,例如9。默认值为SIGTERM



  • 示例
#注释
FROM image:tag
MAINTANIER 镜像作者
LABEL key1=val1 key2=val2
WORKDIR /home/docker
COPY ./testfile /home/
ADD  ./testfile1 /home/
VOLUME /date0
VOLUME /date1 /date2
VOLUME ["/date3","/date4"]
USER zzt:zztgroup
EXPOSE 80
EXPOSE 8080/tcp 9090/udp
SHELL ["/bin/bash", "-c"]
RUN touch file
STOPSIGNAL SIGSTOP
CMD ["java","-server" ,"-jar","xxxx.jar"]
# CMD ["<command>","param1","param2"....]
HEALTHCHECK --interval=30s --timeout= 30s --start-period= 0s --retries=3 CMD curl -f http://localhost:8080/ ||exit 1

多段构建


>docker版本大于17.05 >多段构建时后面镜像可以基于之前镜像作为基础镜像 在镜像中为要构建的镜像添加AS标签进行关联 构建时默认不指定--target 标签时会全部构建 并且只有最后一个会获得imageName和tag 指定标签后 会从第一个开始构建直到指定的标签为止。比如 docker image build -f Dockerfile_state -t myweb1:v1 --target Myweb2 ./ 会从myweb1一直构建到myweb2 后面则不进行构建
FROM openjdk:8 AS Myweb1
LABEL  name="Myweb1" \
       author=zzt
LABEL createtime =2023.01.11

FROM Myweb1 AS Myweb2
LABEL  name1="Myweb2" \
       author=zzt
LABEL createtime =2023.01.11

FROM Myweb1 AS Myweb3
LABEL  name1="Myweb3" \
       author=zzt
LABEL createtime =2023.01.11

FROM Myweb1 AS Myweb4
LABEL  name1="Myweb4" \
       author=zzt
LABEL createtime =2023.01.11

BuildKit工具镜像构建

  • docker版本大于18.06
  • 通过docker daemon.json添加 {“features”: { “buildkit” : true }} 或者命令行输入$DOCKER_BUILDKIT=1 docker build .
  • 支持 # syntax=docker/dockerfile:1.2 文件开始添加 指的使用dockerfile的版本语法

dockerCompose

 一个可以一次多个容器的工具使用yml作为配置。 compose-version兼容版本映射关系

dockerCompose构建|运行镜像

#构建镜像
docker compose -f MyDockerCompose.yml --profile dev  build
#启动镜像
docker compose -f MyDockerCompose.yml --profile dev  up
#启动镜像 后台运行
docker compose -f MyDockerCompose.yml --profile dev  up -d

示例

version: "3.9" #指定兼容的版本信息

services:
  myweb: #你的服务名
    # container_name: myweb-compose #容器名称 如果指定则副本数量只能是1个
    profiles:
      - dev
      - pro
#构建信息定义
    build: #指定服务是构建还是镜像 build image 2者不可同时出现
      context: . #指定上下文 docker build path的path   . 当前目录
      dockerfile: ./Dockerfile #dockerfile文件
      args: #参数 相当于 docker build --build-arg
        stoptime: 10
        stoptime1: 10
      labels: #标签 可以写入到镜像中
        version: "v1"
        redisversion: "7.0.7"
      tags: #镜像标签 可多个
        - "myweb:v1"
      platforms: #镜像平台 linux/arm64/v8  windows/amd64 osx
        - "linux/amd64"
#部署信息定义
    deploy:
      mode: replicated # 部署模式 replicated(指定个数副本) 和 global (每个物理节点一个)
      replicas: 2 # replicated副本模式时候指定副本个数
      restart_policy: #重启策略 
        condition: on-failure #重启条件 none,on-failure,any
        delay: 0s #等待重启时间间隔
        max_attempts: 3 #重启允许失败次数 condition =any 是不允许指定
        window: 1m #等待重启成功的空窗期
      rollback_config: #回滚配置
        parallelism: 1 #每次回滚的容器数.0全部容器同时回滚
        delay: 0s #每组容器回滚的等待时间 默认0s
        failure_action: pause #失败后要做的操作 continue or pause
        monitor: 1m # 失败后每次更新任务到监控的时间 默认0S  允许单位(ns|us|ms|s|m|h)
        max_failure_ratio: 0 # 回滚失败率 默认0
        order: stop-first #回滚期间的操作顺序 stop-first(先停止再启动) start-first(先启动再停止)
      update_config: #更新配置
        parallelism: 1 #每次更新的容器数.0全部容器同时回滚
        delay: 0s #每组容器更新的等待时间 默认0s
        failure_action: pause #失败后要做的操作 continue or pause
        monitor: 1m # 失败后每次更新任务到监控的时间 默认0S  允许单位(ns|us|ms|s|m|h)
        max_failure_ratio: 0 # 更新失败率 默认0
        order: stop-first #更新期间的操作顺序 stop-first(先停止再启动) start-first(先启动再停止)
      endpoint_mode: vip #访问集群服务的方式 vip(虚拟ip) dnsrr(轮询)2种
      labels:
        mylable: "lable"
#存储卷信息定义   
    volumes: 
      - type: volume #type包括 volume, bind, tmpfs 
        source: mydata #存储卷或者地址 tmpfs类型时无效
        target: //home/docker/data0001 #挂载到容器内地址
        read_only: false #存储卷是只读的
        volume:
          nocopy: true
      - type: bind #type包括 volume, bind, tmpfs 
        source: /home/docker/data0002 #tmpfs类型时无效
        target: /data #挂载到容器内地址
        read_only: true #存储卷是只读的
        bind:
          propagation: private #绑定类型传播机制 rprivate, private, rshared, shared, rslave, slave
          create_host_path: true # 自动创建本地路径
          selinux: Z #z (shared) or Z (private)
    # volumes_from: # 从某个容器或服务名复制来相同的挂载信息
    #   - service_name
    #   - service_name:ro
    #   - container:container_name
    #   - container:container_name:rw
#网络信息定义
    ports:
      # - "3000"
      # - "3000-3005"
      - "8080-8090:8080"
      # - "9090-9091:8080-8081"
      # - "49100:22"
      # - "127.0.0.1:8001:8001"
      # - "127.0.0.1:5000-5010:5000-5010"
      # - "6060:6060/udp"
    expose: #容器可暴露端口
      - "8080"
    networks: #网络配置 可指定多个顶层networks的key
      - myweb-network1
      # - myweb-network2
    command: ["java","-jar","demo.jar"] #命令 相当于docker run xxxcontainer command
    # entrypoint: xxxx.sh
    # entrypoint:  # 会覆盖镜像中的entrypoint指令
    #   - java
    #   - -jar
    #   - demo.jar
    # env_file: #添加环境变量通过文件 文件格式 key=val #用于注释
    #    - .env  
    environment: #添加环境变量  environment和env_file同时出现优先取environment
       - aaa=bbb
    # extends: #从另一个compose文件扩展
    #   file: xxxx.yml
    #   service: xxxx
    healthcheck: #健康检查
      disable: true #禁用健康检查
      test: ["CMD", "curl", "-f", "http://localhost:8080"]  # test如果使用list则第一个必须是NONE, CMD or CMD-SHELL中的一个
      # test: ["CMD-SHELL", "curl -f http://localhost:8080||exit 1"]
      # test: curl -f http://localhost:8080||exit 1 
      interval: 1m30s
      timeout: 10s
      retries: 3
      start_period: 40s

  mywebmvntemplate:
    profiles:
      - dev
      - pro
    build:
      context: .
      dockerfile: ./Dockerfile_v1
      tags:
        - "myweb_mvn_template:v1"
  mywebbytemp:
    profiles:
      - dev
      - pro
    depends_on: # 指定相互之间的依赖 简单写法|添加条件写法
      - mywebmvntemplate
#     depends_on:
#       mywebmvntemplate:
# # 依赖条件 service_started service_healthy service_completed_successfully
#         condition: service_healthy
    build:
      context: .
      dockerfile: ./Dockerfile_v2
      tags:
        - "mywebbytemp:v1"
    ports:
      - "9090:8080"
  myimageapp:
    profiles:
      - dev
      - pro
    image: mywebbytemp:v1
    depends_on:
      # - mywebmvntemplate
      - mywebbytemp
    ports:
      - "9091:8080"

volumes: #顶层位置可以存储卷被多个服务使用 mydata值为空 会根据默认配置创建存储卷
  mydata:
    name: "my-data" #自定义卷名称
    labels:
      - "key=val"
      - "key2=val2"
    #external: true #external为true则不会自动创建mydata没有时会报错

networks: #顶层网络配置
  myweb-network1:
    name: myweb-network1
    external: false #为true时不创建该网络找不到该网络报错
    driver: overlay #网络驱动汇总
    attachable: true # 是否连接到该网络
    labels:
      - "key1=val1"
      - "key2=val2"