当前位置: > Linux服务器 > Docker >

创建镜像 - 创建与定制 mysql 镜像

时间:2017-02-18 02:26来源:linux.it.net.cn 作者:IT

创建镜像 - 创建与定制 mysql 镜像

本文通过制作与定制 MySQL 镜像为案例,一方面说明创建镜像简单,另一方面解释 Docker image 的内容,直观描述 docker build 命令与 Dockerfile 主要配置。这些基本能满足日常工作需要,需要完整的命令和配置说明可参考官方文档或网上的翻译。

1、docker images?

docker images 使得软件实现拿来即用。docker images 中包含什么呢?

先得看官方关于 docker 的描述1:

这里写图片描述

其中:

  • KERNEL 是每个 Linux 操作系统都有的, image 不包含。
  • DEBIAN-image 代表我们常见的 Linux 系统(不含 KERNEL),如 CentOS, Ubuntu,Debian 等又称为 Linux 发行版。这些除了包含 KERNEL 外,包含大量操作系统扩展、各种管理工具、开发工具、图像界面支持等。通常都是庞然大物,命令行版本的文件系统也有几百兆。这些镜像大约 100~200M。
  • BUSY BOX-image 代表精简的 Linux 系统, 如 Alpine, busybox, CoreOS 等,仅支持一些最基本 Linux 命令和一个简单应用包管理,以及以满足云应用需求的支持。这些镜像 5~10M。
  • ADD EMACS-image 代表 Emacs 这样的基础应用,它仅在基础操作系统文件基础上添加了自己的代码和依赖包;
  • ADD APACHE-image 代表 Apache web 应用,建立在已有 emacs 镜像基础上,即文件系统添加了 apache 及其依赖包。这样形成多层叠加的文件系统,尽管 APACHE-image 仅包含自己的内容,但启动后,我们可以访问基础操作系统、emacs 提供的程序和软件包。
  • WRITEBLE COTAINER 是镜像中程序在与主机(Host)隔离环境下运行进程产生的中间文件。

因此:

image 是文件(增量)与环境(context)配置文件的集合。

这个定义太枯燥,我们来看它的生成过程:

2、mysql 镜像制作

2.1 Dockerfile 文件

docker build 默认使用 Dockerfile 文件创建镜像。mysql 官方 docker 构建(mysql5.7)的 Dockerfile 文件内容是2:

FROM debian:jessie

# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added
RUN groupadd -r mysql && useradd -r -g mysql mysql

# add gosu for easy step-down from root
ENV GOSU_VERSION 1.7
RUN set -x \
    && apt-get update && apt-get install -y --no-install-recommends ca-certificates wget && rm -rf /var/lib/apt/lists/* \
    && wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture)" \
    && wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture).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 \
    && rm -r "$GNUPGHOME" /usr/local/bin/gosu.asc \
    && chmod +x /usr/local/bin/gosu \
    && gosu nobody true \
    && apt-get purge -y --auto-remove ca-certificates wget

RUN mkdir /docker-entrypoint-initdb.d

# FATAL ERROR: please install the following Perl modules before executing /usr/local/mysql/scripts/mysql_install_db:
# File::Basename
# File::Copy
# Sys::Hostname
# Data::Dumper
RUN apt-get update && apt-get install -y perl pwgen --no-install-recommends && rm -rf /var/lib/apt/lists/*

# gpg: key 5072E1F5: public key "MySQL Release Engineering <mysql-build@oss.oracle.com>" imported
RUN apt-key adv --keyserver ha.pool.sks-keyservers.net --recv-keys A4A9406876FCBD3C456770C88C718D3B5072E1F5

ENV MYSQL_MAJOR 5.7
ENV MYSQL_VERSION 5.7.17-1debian8

RUN echo "deb http://repo.mysql.com/apt/debian/ jessie mysql-${MYSQL_MAJOR}" > /etc/apt/sources.list.d/mysql.list

# the "/var/lib/mysql" stuff here is because the mysql-server postinst doesn't have an explicit way to disable the mysql_install_db codepath besides having a database already "configured" (ie, stuff in /var/lib/mysql/mysql)
# also, we set debconf keys to make APT a little quieter
RUN { \
        echo mysql-community-server mysql-community-server/data-dir select ''; \
        echo mysql-community-server mysql-community-server/root-pass password ''; \
        echo mysql-community-server mysql-community-server/re-root-pass password ''; \
        echo mysql-community-server mysql-community-server/remove-test-db select false; \
    } | debconf-set-selections \
    && apt-get update && apt-get install -y mysql-server="${MYSQL_VERSION}" && rm -rf /var/lib/apt/lists/* \
    && rm -rf /var/lib/mysql && mkdir -p /var/lib/mysql /var/run/mysqld \
    && chown -R mysql:mysql /var/lib/mysql /var/run/mysqld \
# ensure that /var/run/mysqld (used for socket and lock files) is writable regardless of the UID our mysqld instance ends up having at runtime
    && chmod 777 /var/run/mysqld

# comment out a few problematic configuration values
# don't reverse lookup hostnames, they are usually another container
RUN sed -Ei 's/^(bind-address|log)/#&/' /etc/mysql/mysql.conf.d/mysqld.cnf \
    && echo '[mysqld]\nskip-host-cache\nskip-name-resolve' > /etc/mysql/conf.d/docker.cnf

VOLUME /var/lib/mysql

COPY docker-entrypoint.sh /usr/local/bin/
RUN ln -s usr/local/bin/docker-entrypoint.sh /entrypoint.sh # backwards compat
ENTRYPOINT ["docker-entrypoint.sh"]

EXPOSE 3306
CMD ["mysqld"]

其中3:

  • FROM debian:jessie 表示在操作系统 debian:jessie 版本基础上构建。docker 会创建容器,加载它的文件系统
  • RUN groupadd … 表示运行虚拟容器中命令文件,所有产生的文件变化在新的层(不会修改 debian:jessie 镜像内容)
  • ENV 设置环境变量

官方 ENV 案例与解释:

FROM busybox
ENV foo /bar
WORKDIR ${foo}   # WORKDIR /bar
ADD . $foo       # ADD . /bar
COPY \$foo /quux # COPY $foo /quux
  • VOLUME [“/data”] 指令创建挂载点 以允许本地 host 或 其他容器挂载卷。

VOLUME /var/lib/mysql 在 mysql 容器运行加载时,会将 /var/lib/mysql 目录下所有文件拷贝到新的容器的卷。这将加速当前程序读写速度(仅在当前文件系统操作)。

  • COPY 从本地拷贝到容器文件系统。

官方的一些案例

COPY hom* /mydir/        # adds all files starting with "hom"
COPY hom?.txt /mydir/    # ? is replaced with any single character, e.g., "home.txt"

COPY test relativeDir/   # adds "test" to `WORKDIR`/relativeDir/
COPY test /absoluteDir/  # adds "test" to /absoluteDir/


  • WORKDIR

    指定当前容器文件系统的当前目录。

     

  • ADD 官方描述与 COPY 类似,只是 ADD 支持 remote file URL。

  • ENTRYPOINT [“docker-entrypoint.sh”] 指定执行命令前的配置或其他工作。

  • EXPOSE 3306 指定暴露对外服务端口。

  • CMD [“mysqld”] 指定默认执行的容器服务。

2.2 制作镜像

利用上述文件,使用命令 docker build <path> -t <image-name>:<tag> 就可以构建镜像,例如:

当前目录下包含 Dockerfile 和 docker-entrypoint.sh ,执行
sudo docker build . -t mysql:1.0-yours

从 Dockerfile 配置看出, Dockerfile 包含两大类指令,

  • 一类 RUN、ADD、COPY 等,在原镜像基础上制作了新的文件系统(增量);
  • 一类 FROM、ENV、WORDIR、ENTRYPOINT、VOLUME、EXPOSE、CMD等,配置镜像执行期间的环境与默认行为。

当然,你可能和我一样不熟悉 debian:jessie 环境, 熟悉 ubuntu 可以看创建 Mysql 容器4。

3、定制镜像

制定前准备

是否需要定制镜像,从那个起点定制镜像并不是一件容易的决策。

是否需要定制镜像?

  • 无论 mysql,redis,nginx 都有官方镜像,直接拉下来用可解决多数问题
  • 如果你不喜欢官方的,Git 上有很多非官方镜像可用

当然,发布程序、定制官方镜像,以方便使用是定制镜像的理由。

从那个基础镜像开始?

  • 以操作系统为基础,你得选择你熟悉的 CentOS、Ubuntu、Debian 还是精简的 Alpine、CoreOS。熟悉程度与镜像体积是两难的选择。
  • 以应用程序为基础,也是比较难的。例如,java 应用即可用 Maven 构建(嵌入服务器),也可以用 jetty,tomcat 为基础添加应用程序构建。

没有特殊情况,不必从操作系统构建

定制 mysql

一句话,pull 官方镜像,编写 my.cnf ,然后写 Dockerfile,例如:

FROM mysql:5.7
COPY my.cnf /etc/mysql/conf.d
ENV MYSQL_ROOT_PASSWORD root

然后:

docker build . --rm=true -t yours/mysql:5.7


检查能力

你能否参考Docker mysql 主从配置详解及实例 完成 mysql 主从配置呢?

小结

本文介绍了 mysql 官方的 Dockerfile ,并以此为案例介绍了镜像配置,构建的要点。尽管网上中文资料很多,仍然建议你以官方文档为基础,发展变化毕竟太快。

【参考】

  1. What is Docker? https://www.docker.com/what-docker ↩
  2. Docker Official Image packaging for MySQL https://github.com/docker-library/mysql ↩
  3. Dockerfile reference https://docs.docker.com/engine/reference/builder/ ↩
  4. Creating a MySQL Docker Container http://txt.fliglio.com/2013/11/creating-a-mysql-docker-container/ ↩

(责任编辑:IT)
------分隔线----------------------------
栏目列表
推荐内容