前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >docker-09

docker-09

作者头像
Tom2Code
发布2022-04-15 16:15:47
发布2022-04-15 16:15:47
33500
代码可运行
举报
文章被收录于专栏:TomTom
运行总次数:0
代码可运行

前几章算是docker的基础介绍,从第九章开始我们就要讲一点狠东西了

也不算高级的,但是是狠货

docker-01

docker-02

docker-03

docker-04

docker-05

docker-06

docker-07

docker-08

一.Dockerfile

1.1Dockerfile是什么

Dockerfile是用来构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本。 网络

官网对Dockerfile的介绍是这样的

Docker can build images automatically by reading the instructions from a Dockerfile. A Dockerfile is a text document that contains all the commands a user could call on the command line to assemble an image. Using docker build users can create an automated build that executes several command-line instructions in succession.

大概翻译:docker可以通过Dockerfile的指令自动地构建镜像。一个Dockerfile是一个文本文件,它包含了一个用户组建一个镜像所需要的全部命令。docker build指令,用户可以创建一个自动构建通过执行一系列的命令行指令。(ps:笔者英语水平不太好,即兴翻译,如果翻译不妥的地方,多担待)

1.2构建三部曲:

首先编写Dockerfile文件

第二,docker build命令构建镜像

最后docker run运行容器实例

1.3构建指令

代码语言:javascript
代码运行次数:0
复制
docker build .

老规矩,我们看一下帮助手册:

代码语言:javascript
代码运行次数:0
复制
Usage:  docker build [OPTIONS] PATH | URL | -

Build an image from a Dockerfile

Options:
      --add-host list           Add a custom host-to-IP mapping (host:ip)
      --build-arg list          Set build-time variables
      --cache-from strings      Images to consider as cache sources
      --cgroup-parent string    Optional parent cgroup for the container
      --compress                Compress the build context using gzip
      --cpu-period int          Limit the CPU CFS (Completely Fair Scheduler) period
      --cpu-quota int           Limit the CPU CFS (Completely Fair Scheduler) quota
  -c, --cpu-shares int          CPU shares (relative weight)
      --cpuset-cpus string      CPUs in which to allow execution (0-3, 0,1)
      --cpuset-mems string      MEMs in which to allow execution (0-3, 0,1)
      --disable-content-trust   Skip image verification (default true)
  -f, --file string             Name of the Dockerfile (Default is 'PATH/Dockerfile')
      --force-rm                Always remove intermediate containers
      --iidfile string          Write the image ID to the file
      --isolation string        Container isolation technology
      --label list              Set metadata for an image
  -m, --memory bytes            Memory limit
      --memory-swap bytes       Swap limit equal to memory plus swap: '-1' to enable unlimited swap
      --network string          Set the networking mode for the RUN instructions during build (default "default")
      --no-cache                Do not use cache when building the image
      --pull                    Always attempt to pull a newer version of the image
  -q, --quiet                   Suppress the build output and print image ID on success
      --rm                      Remove intermediate containers after a successful build (default true)
      --security-opt strings    Security options
      --shm-size bytes          Size of /dev/shm
  -t, --tag list                Name and optionally a tag in the 'name:tag' format
      --target string           Set the target build stage to build.
      --ulimit ulimit           Ulimit options (default [])

其实参数也不多,我们后面再对这些参数进行讲解,今天先把Dockerfile的流程打通

1.4Dockerfile内容基础知识

最最最重要的一点:

编写Dockerfile的时候,名字一定要叫做Dockerfile

没错,就是需要一字不落的!

而且首字母需要大写

然后就是基础知识:

a.每条保留字指令都必须为大写字母且后面要跟随至少一个参数

b.指令按照从上到下,顺序执行

c.#表示注释

d.每条指令都会创建一个新的镜像层并对镜像进行提交

1.5docker执行Dockerfile的大致流程

a.docker从基础镜像运行一个容器

b.执行一条指令并对容器做出修改

c.执行类似docker commit的操作提交一个新的镜像层

d.docker在基于刚刚提交的镜像运行一个新容器

e.执行Dockerfile中的下一条指令直到所有指令都执行完成

我们这里可以参看一下tomcat官方的Dockerfile的模板

代码语言:javascript
代码运行次数:0
复制
{{
  include "from"
  ;
  def is_apt:
    vendor_variant | (
      startswith("openjdk")
      or startswith("temurin")
    )
  ;
  def major:
    env.version | split(".")[0]
-}}
FROM {{ from }}

ENV CATALINA_HOME /usr/local/tomcat
ENV PATH $CATALINA_HOME/bin:$PATH
RUN mkdir -p "$CATALINA_HOME"
WORKDIR $CATALINA_HOME

# let "Tomcat Native" live somewhere isolated
ENV TOMCAT_NATIVE_LIBDIR $CATALINA_HOME/native-jni-lib
ENV LD_LIBRARY_PATH ${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}$TOMCAT_NATIVE_LIBDIR

# see https://www.apache.org/dist/tomcat/tomcat-{{ major }}/KEYS
# see also "versions.sh" (https://github.com/docker-library/tomcat/blob/master/versions.sh)
ENV GPG_KEYS {{
  # docker run --rm buildpack-deps:bullseye-curl bash -c 'wget -qO- https://www.apache.org/dist/tomcat/tomcat-10/KEYS | gpg --batch --import &> /dev/null && gpg --batch --list-keys --with-fingerprint --with-colons' | awk -F: '$1 == "pub" && $2 == "-" { pub = 1 } pub && $1 == "fpr" { fpr = $10 } $1 == "sub" { pub = 0 } pub && fpr && $1 == "uid" && $2 == "-" { print "\t\t\t#", $10; print "\t\t\t\"" fpr "\","; pub = 0 } END { print "\t\t\t# trailing comma 👀\n\t\t\tempty" }'
  {
    "10": [
      # Mark E D Thomas <markt@apache.org>
      "A9C5DF4D22E99998D9875A5110C01C5A2F6059E7",
      # trailing comma 👀
      empty
    ],
    "9": [
      # Mark E D Thomas <markt@apache.org>
      "DCFD35E0BF8CA7344752DE8B6FB21E8933C60243",
      # Mark E D Thomas <markt@apache.org>
      "A9C5DF4D22E99998D9875A5110C01C5A2F6059E7",
      # Remy Maucherat <remm@apache.org>
      "48F8E69F6390C9F25CFEDCD268248959359E722B",
      # trailing comma 👀
      empty
    ],
    "8": [
      # Andy Armstrong <andy@tagish.com>
      "79F7026C690BAA50B92CD8B66A3AD3F4F22C4FED",
      # Jean-Frederic Clere (jfclere) <JFrederic.Clere@fujitsu-siemens.com>
      "05AB33110949707C93A279E3D3EFE6B686867BA6",
      # kevin seguin <seguin@apache.org>
      "A27677289986DB50844682F8ACB77FC2E86E29AC",
      # Henri Gomez <hgomez@users.sourceforge.net>
      "47309207D818FFD8DCD3F83F1931D684307A10A5",
      # Yoav Shapira <yoavs@apache.org>
      "07E48665A34DCAFAE522E5E6266191C37C037D42",
      # Mark E D Thomas <markt@apache.org>
      "DCFD35E0BF8CA7344752DE8B6FB21E8933C60243",
      # Mark E D Thomas <markt@apache.org>
      "A9C5DF4D22E99998D9875A5110C01C5A2F6059E7",
      # Rémy Maucherat <remm@apache.org>
      "541FBE7D8F78B25E055DDEE13C370389288584E7",
      # Yoav Shapira <yoavs@computer.org>
      "F3A04C595DB5B6A5F1ECA43E3B7BBB100D811BBE",
      # Tim Whittington (CODE SIGNING KEY) <timw@apache.org>
      "9BA44C2621385CB966EBA586F72C284D731FABEE",
      # Mladen Turk (Default signing key) <mturk@apache.org>
      "F7DA48BB64BCB84ECBA7EE6935CD23C10D498E23",
      # Konstantin Kolinko (CODE SIGNING KEY) <kkolinko@apache.org>
      "765908099ACF92702C7D949BFA0C35EA8AA299F1",
      # Christopher Schultz <chris@christopherschultz.net>
      "5C3C5F3E314C866292F359A8F3AD5C94A67F707E",
      # trailing comma 👀
      empty
    ],
  } | .[major] // error("missing GPG keys")
  | sort
  | join(" ")
}}

ENV TOMCAT_MAJOR {{ major }}
ENV TOMCAT_VERSION {{ .version }}
ENV TOMCAT_SHA512 {{ .sha512 }}

{{ if java_variant == "jdk" then ( -}}
RUN set -eux; \
  \
{{ if is_apt then ( -}}
  savedAptMark="$(apt-mark showmanual)"; \
  apt-get update; \
  apt-get install -y --no-install-recommends \
    ca-certificates \
    curl \
    dirmngr \
    gnupg \
  ; \
{{ ) else ( -}}
# http://yum.baseurl.org/wiki/YumDB.html
  if ! command -v yumdb > /dev/null; then \
    yum install -y yum-utils; \
    yumdb set reason dep yum-utils; \
  fi; \
# a helper function to "yum install" things, but only if they aren't installed (and to set their "reason" to "dep" so "yum autoremove" can purge them for us)
  _yum_install_temporary() { ( set -eu +x; \
    local pkg todo=''; \
    for pkg; do \
      if ! rpm --query "$pkg" > /dev/null 2>&1; then \
        todo="$todo $pkg"; \
      fi; \
    done; \
    if [ -n "$todo" ]; then \
      set -x; \
      yum install -y $todo; \
      yumdb set reason dep $todo; \
    fi; \
  ) }; \
  _yum_install_temporary gzip tar; \
{{ ) end -}}
  \
  ddist() { \
    local f="$1"; shift; \
    local distFile="$1"; shift; \
    local mvnFile="${1:-}"; \
    local success=; \
    local distUrl=; \
    for distUrl in \
# https://issues.apache.org/jira/browse/INFRA-8753?focusedCommentId=14735394#comment-14735394
      "https://www.apache.org/dyn/closer.cgi?action=download&filename=$distFile" \
# if the version is outdated (or we're grabbing the .asc file), we might have to pull from the dist/archive :/
      "https://downloads.apache.org/$distFile" \
      "https://www-us.apache.org/dist/$distFile" \
      "https://www.apache.org/dist/$distFile" \
      "https://archive.apache.org/dist/$distFile" \
# if all else fails, let's try Maven (https://www.mail-archive.com/users@tomcat.apache.org/msg134940.html; https://mvnrepository.com/artifact/org.apache.tomcat/tomcat; https://repo1.maven.org/maven2/org/apache/tomcat/tomcat/)
      ${mvnFile:+"https://repo1.maven.org/maven2/org/apache/tomcat/tomcat/$mvnFile"} \
    ; do \
      if curl -fL -o "$f" "$distUrl" && [ -s "$f" ]; then \
        success=1; \
        break; \
      fi; \
    done; \
    [ -n "$success" ]; \
  }; \
  \
  ddist 'tomcat.tar.gz' "tomcat/tomcat-$TOMCAT_MAJOR/v$TOMCAT_VERSION/bin/apache-tomcat-$TOMCAT_VERSION.tar.gz" "$TOMCAT_VERSION/tomcat-$TOMCAT_VERSION.tar.gz"; \
  echo "$TOMCAT_SHA512 *tomcat.tar.gz" | sha512sum --strict --check -; \
  ddist 'tomcat.tar.gz.asc' "tomcat/tomcat-$TOMCAT_MAJOR/v$TOMCAT_VERSION/bin/apache-tomcat-$TOMCAT_VERSION.tar.gz.asc" "$TOMCAT_VERSION/tomcat-$TOMCAT_VERSION.tar.gz.asc"; \
  export GNUPGHOME="$(mktemp -d)"; \
  for key in $GPG_KEYS; do \
    gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
  done; \
  gpg --batch --verify tomcat.tar.gz.asc tomcat.tar.gz; \
  tar -xf tomcat.tar.gz --strip-components=1; \
  rm bin/*.bat; \
  rm tomcat.tar.gz*; \
  command -v gpgconf && gpgconf --kill all || :; \
  rm -rf "$GNUPGHOME"; \
  \
# https://tomcat.apache.org/tomcat-9.0-doc/security-howto.html#Default_web_applications
  mv webapps webapps.dist; \
  mkdir webapps; \
# we don't delete them completely because they're frankly a pain to get back for users who do want them, and they're generally tiny (~7MB)
  \
  nativeBuildDir="$(mktemp -d)"; \
  tar -xf bin/tomcat-native.tar.gz -C "$nativeBuildDir" --strip-components=1; \
{{ if is_apt then ( -}}
  apt-get install -y --no-install-recommends \
    dpkg-dev \
    gcc \
    libapr1-dev \
    libssl-dev \
    make \
  ; \
{{ ) else ( -}}
  _yum_install_temporary \
    apr-devel \
    gcc \
    make \
    openssl11-devel \
  ; \
{{ ) end -}}
  ( \
    export CATALINA_HOME="$PWD"; \
    cd "$nativeBuildDir/native"; \
{{ if is_apt then ( -}}
    gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
{{ ) else "" end -}}
    aprConfig="$(command -v apr-1-config)"; \
    ./configure \
{{ if is_apt then ( -}}
      --build="$gnuArch" \
{{ ) else "" end -}}
      --libdir="$TOMCAT_NATIVE_LIBDIR" \
      --prefix="$CATALINA_HOME" \
      --with-apr="$aprConfig" \
      --with-java-home="$JAVA_HOME" \
      --with-ssl=yes \
    ; \
    nproc="$(nproc)"; \
    make -j "$nproc"; \
    make install; \
  ); \
  rm -rf "$nativeBuildDir"; \
  rm bin/tomcat-native.tar.gz; \
  \
{{ if is_apt then ( -}}
# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies
  apt-mark auto '.*' > /dev/null; \
  [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \
  find "$TOMCAT_NATIVE_LIBDIR" -type f -executable -exec ldd '{}' ';' \
    | awk '/=>/ { print $(NF-1) }' \
    | xargs -rt readlink -e \
    | sort -u \
    | xargs -rt dpkg-query --search \
    | cut -d: -f1 \
    | sort -u \
    | tee "$TOMCAT_NATIVE_LIBDIR/.dependencies.txt" \
    | xargs -r apt-mark manual \
  ; \
  \
  apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
  rm -rf /var/lib/apt/lists/*; \
{{ ) else ( -}}
# mark any explicit dependencies as manually installed
  find "$TOMCAT_NATIVE_LIBDIR" -type f -executable -exec ldd '{}' ';' \
    | awk '/=>/ && $(NF-1) != "=>" { print $(NF-1) }' \
    | xargs -rt readlink -e \
    | sort -u \
    | xargs -rt rpm --query --whatprovides \
    | sort -u \
    | tee "$TOMCAT_NATIVE_LIBDIR/.dependencies.txt" \
    | xargs -r yumdb set reason user \
  ; \
  \
# clean up anything added temporarily and not later marked as necessary
  yum autoremove -y; \
  yum clean all; \
  rm -rf /var/cache/yum; \
{{ ) end -}}
  \
# sh removes env vars it doesn't support (ones with periods)
# https://github.com/docker-library/tomcat/issues/77
  find ./bin/ -name '*.sh' -exec sed -ri 's|^#!/bin/sh$|#!/usr/bin/env bash|' '{}' +; \
  \
# fix permissions (especially for running as non-root)
# https://github.com/docker-library/tomcat/issues/35
  chmod -R +rX .; \
  chmod 777 logs temp work; \
  \
# smoke test
  catalina.sh version
{{ ) else ( -}}
COPY --from=tomcat:{{ .version }}-jdk{{ java_version }}-{{ vendor_variant }} $CATALINA_HOME $CATALINA_HOME
RUN set -eux; \
{{ if is_apt then ( -}}
  apt-get update; \
  xargs -rt apt-get install -y --no-install-recommends < "$TOMCAT_NATIVE_LIBDIR/.dependencies.txt"; \
  rm -rf /var/lib/apt/lists/*
{{ ) else ( -}}
  xargs -rt yum install -y < "$TOMCAT_NATIVE_LIBDIR/.dependencies.txt"; \
  yum clean all; \
  rm -rf /var/cache/yum
{{ ) end -}}
{{ ) end -}}

# verify Tomcat Native is working properly
RUN set -eux; \
  nativeLines="$(catalina.sh configtest 2>&1)"; \
  nativeLines="$(echo "$nativeLines" | grep 'Apache Tomcat Native')"; \
  nativeLines="$(echo "$nativeLines" | sort -u)"; \
  if ! echo "$nativeLines" | grep -E 'INFO: Loaded( APR based)? Apache Tomcat Native library' >&2; then \
    echo >&2 "$nativeLines"; \
    exit 1; \
  fi

EXPOSE 8080
CMD ["catalina.sh", "run"]

200多行,我们不会展开讲解,但是我们可以讲一些关键字

注意,Dockerfile的关键字必须大写!!!attention please

  • FROM

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

  • MAINTAINER

镜像维护者的姓名和邮件地址

  • RUN

容器构建时需要运行的命令

两种格式:

1.shell格式

2.exec格式

RUN是在docker build时运行

  • EXPOSE

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

  • WORKDIR

指定在创建容器后,终端默认登录进来的工作目录,一个落脚点

  • USER

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

  • ENV

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

  • ADD

将宿主机目录下的文件拷贝进镜像且会自动处理url和解压tar压缩包

  • COPY

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

  • VOLUME

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

  • CMD

指定容器启动后的要干的事情

注意:Dockerfile中可以有多个cmd指令,但是只有最后一个生效,cmd会被docker run之后的参数替代

CMD和RUN的对比:CMD是在docker run的时候执行

RUN是在docker build的时候执行

  • ENTRYPOINT

也是用来指定一个容器启动时要运行的命令

类似于CMD,但是该指令不会被docker run后面的命令覆盖,而且这些命令行参数会被当做参数送给ENTRYPOINT指定的程序

优点:在执行docker run的时候可以指定ENTRYPOINT运行所需的参数

注意:Dockerfile中如果存在多个ENTRYPOINT指令,仅最后一个生效

ok,今天的介绍就暂时到这里,谢谢大家的观看,

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-03-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Tom的小院 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档