【云原生-Docker】通过 Dockerfile 创建镜像(上)
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
🍁博客主页
👉@不会压弯的小飞侠
✨欢迎关注
👉点赞
👍收藏
⭐留言
✒
✨系列专栏
👉Docker学习专栏
✨学习社区
👉不会压弯的小飞侠
✨知足上进不负野心。
🔥欢迎大佬指正一起学习一起加油
目录
🍁关于 Dockerfile
Dockerfile 是 Docker 中用于定义镜像自动化构建流程的配置文件在 Dockerfile 中包含了构建镜像过程中需要执行的命令和其他操作。通过 Dockerfile 我们可以更加清晰、明确的给定 Docker 镜像的制作过程而由于其仅是简单、小体积的文件在网络等其他介质中传递的速度极快能够更快的帮助我们实现容器迁移和集群部署。
Dockerfile 的定义就是针对一个名为 Dockerfile 的文件其虽然没有扩展名但本质就是一个文本文件所以通过常见的文本编辑器或者 IDE 创建和编辑它。
Dockerfile 的内容很简单主要以两种形式呈现一种是注释行另一种是指令行。
下面展示一些 内联代码片
。
# Comment
INSTRUCTION arguments
在 Dockerfile 中拥有一套独立的指令语法其用于给出镜像构建过程中所要执行的过程。Dockerfile 里的指令行就是由指令与其相应的参数所组成。
🍁环境搭建与镜像构建
Dockerfile 的作用和其实际运转的机制可以用一个我们开发中的常见流程来比较。在一个完整的开发、测试、部署过程中程序运行环境的定义通常是由开发人员来进行的因为它们更加熟悉程序运转的各个细节更适合搭建适合程序的运行环境。在这样的前提下为了方便测试和运维搭建相同的程序运行环境常用的做法是由开发人员编写一套环境搭建手册帮助测试人员和运维人员了解环境搭建的流程。
而 Dockerfile 就很像这样一个环境搭建手册因为其中包含的就是一个构建容器的过程。而比环境搭建手册更好的是Dockerfile 在容器体系下能够完成自动构建既不需要测试和运维人员深入理解环境中各个软件的具体细节也不需要人工执行每一个搭建流程。
🍁编写 Dockerfile
Dockerfile 的体积远小于镜像包更容易进行快速迁移和部署。
环境构建流程记录了 Dockerfile 中能够直观的看到镜像构建的顺序和逻辑。
使用 Dockerfile 来构建镜像能够更轻松的实现自动部署等自动化流程。
在修改环境搭建细节时修改 Dockerfile 文件要比从新提交镜像来的轻松、简单。
这是用于构建 Docker 官方所提供的 Redis 镜像的 Dockerfile 文件。
FROM debian:stretch-slim
# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added
RUN groupadd -r redis && useradd -r -g redis redis
# grab gosu for easy step-down from root
# https://github.com/tianon/gosu/releases
ENV GOSU_VERSION 1.10
RUN set -ex; \
\
fetchDeps=" \
ca-certificates \
dirmngr \
gnupg \
wget \
"; \
apt-get update; \
apt-get install -y --no-install-recommends $fetchDeps; \
rm -rf /var/lib/apt/lists/*; \
\
wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch"; \
wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch.asc"; \
export GNUPGHOME="$(mktemp -d)"; \
gpg --keyserver ha.pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4; \
gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu; \ gpgconf --kill all; \
rm -r "$GNUPGHOME" /usr/local/bin/gosu.asc; \
chmod +x /usr/local/bin/gosu; \
gosu nobody true; \ \
apt-get purge -y --auto-remove $fetchDeps
ENV REDIS_VERSION 3.2.12
ENV REDIS_DOWNLOAD_URL http://download.redis.io/releases/redis-3.2.12.tar.gz
ENV REDIS_DOWNLOAD_SHA 98c4254ae1be4e452aa7884245471501c9aa657993e0318d88f048093e7f88fd
# for redis-sentinel see: http://redis.io/topics/sentinel
RUN set -ex; \
\
buildDeps=' \
wget \
\
gcc \
libc6-dev \
make \
'; \
apt-get update; \
apt-get install -y $buildDeps --no-install-recommends; \
rm -rf /var/lib/apt/lists/*; \
\
wget -O redis.tar.gz "$REDIS_DOWNLOAD_URL"; \
echo "$REDIS_DOWNLOAD_SHA *redis.tar.gz" | sha256sum -c -; \
mkdir -p /usr/src/redis; \
tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1; \
rm redis.tar.gz; \
\
# disable Redis protected mode [1] as it is unnecessary in context of Docker
# (ports are not automatically exposed when running inside Docker, but rather explicitly by specifying -p / -P)
# [1]: https://github.com/antirez/redis/commit/edd4d555df57dc84265fdfb4ef59a4678832f6da grep -q '^
#define CONFIG_DEFAULT_PROTECTED_MODE 1$' /usr/src/redis/src/server.h; \ sed -ri 's!^(#define CONFIG_DEFAULT_PROTECTED_MODE) 1$!\1 0!' /usr/src/redis/src/server.h; \
grep -q '^#define CONFIG_DEFAULT_PROTECTED_MODE 0$' /usr/src/redis/src/server.h; \
# for future reference, we modify this directly in the source instead of just supplying a default configuration flag because apparently "if you specify any argument to redis-server, [it assumes] you are going to specify everything"
# see also https://github.com/docker-library/redis/issues/4
#issuecomment-50780840
# (more exactly, this makes sure the default behavior of "save on SIGTERM" stays functional by default)
\
make -C /usr/src/redis -j "$(nproc)"; \
make -C /usr/src/redis install; \
\
rm -r /usr/src/redis; \
\
apt-get purge -y --auto-remove $buildDeps
RUN mkdir /data && chown redis:redis /data
VOLUME /dataWORKDIR /data
COPY docker-entrypoint.sh /usr/local/bin/
ENTRYPOINT ["docker-entrypoint.sh"]
EXPOSE 6379
CMD ["redis-server"]
🍁Dockerfile 的结构
总体上来说可以将 Dockerfile 理解为一个由上往下执行指令的脚本文件。当调用构建命令让 Docker 通过我给出的 Dockerfile 构建镜像时Docker 会逐一按顺序解析 Dockerfile 中的指令并根据它们不同的含义执行不同的操作。
如果进行细分可以将 Dockerfile 的指令简单分为五大类。
基础指令用于定义新镜像的基础和性质。
控制指令是指导镜像构建的核心部分用于描述镜像在构建过程中需要执行的命令。
引入指令用于将外部文件直接引入到构建镜像内部。
执行指令能够为基于镜像所创建的容器指定在启动时需要执行的脚本或命令。
配置指令对镜像以及基于镜像所创建的容器可以通过配置指令对其网络、用户等内容进行配置。
这五类命令并非都会出现在一个 Dockerfile 里但却对基于这个 Dockerfile 所构建镜像形成不同的影响。