引言:很多的工作和软件安装或维护机器有关,这些工作还处理环境的特殊性。这些特殊性作为全局范围的依赖关系(如已知主机文件系统的位置)、硬编码的部署架构(代码或配置的环境检查),或数据局部性(存储在特定的不在部署体系结构以内的机器上的数据)。如果你的目标是建立低维护的系统,你应该努力减少这些事情。

Docker 有三个特定的功能,以帮助建立与环境无关的系统:

  • 只读文件系统
  • 环境变量注入
  • 存储卷

处理卷是一个大主题,为了学习前两个功能,在本文的其余部分将改变对示例的需求。
WordPress 使用一个名为MySQL 的数据库程序来存储大部分数据,所以先确保运行WordPress 的容器是只读文件系统,是一个好主意。

1 只读文件系统

使用只读文件系统产生以下两个积极效果。首先,你对容器不能更改它所包含的文件产生信心;其次,你也会进一步树立信念:容器中的攻击者无法破坏文件。
为了在客户系统上使用–read-only 标志,从WordPress 镜像创建和启动一个容器:

docker run -d --name wp --read-only wordpress:4

完成这些步骤后,检查容器是否正在运行。你可使用任何先前介绍的方法,也可以直接检查容器元数据。如果指定的wp 容器正在运行,以下命令将输出为真,否则为假。

docker inspect --format "{{.State.Running}}" wp

docker inspect 命令将显示Docker 为该容器保留的所有元数据(一个JSON 文件)。
格式选项会改变元数据。除了该容器的运行状态,本例中其会滤除元数据的所有字段。这个命令将简单地输出为错误。
在这种情况下,容器没有运行。为了找出原因,检查容器中的日志:

docker logs wp

输出是这样的:

error: missing WORDPRESS_DB_HOST and MYSQL_PORT_3306_TCP environment variables
Did you forget to --link some_mysql_container:mysql or set an external db with -e WORDPRESS_DB_HOST=hostname:port?

看起来WordPress 有一个MySQL 数据库的依赖关系。数据库是一个程序,根据检索和搜索方式存储数据。好消息是,你可以使用Docker 安装MySQL,就像安装WordPress:

docker run -d --name wpdb \
-e MYSQL_ROOT_PASSWORD=ch2demo \
mysql:5

一旦启动后,会创建一个不同的WordPress 容器,并链接到这个新的数据库容器中:

再检查一次,WordPress 是否正常运行:

docker inspect --format "{{.State.Running}}" wp2

你可以得知WordPress 失败后重新启动。检查日志以确定原因:

docker logs wp2

应该有类似以下的日志:

... Read-only file system: AH00023: Couldn't create the rewrite-map mutex (file /var/lock/apache2/rewrite-map.1)

同样是WordPress 失败后重新启动,但这次的问题是,它试图写一个锁定文件到特定的位置。这是启动的必要组成部分,并无特殊。在这个示例中,需要为只读文件系统增加异常处理。你需要使用卷来做这个异常处理。使用下面的命令启动WordPress,不会有任何问题:

更新版本后你能用的脚本看上去像是这样:

SQL_CID=$(docker create -e MYSQL_ROOT_PASSWORD=ch2demo mysql:5)docker start $SQL_CID
MAILER_CID=$(docker create dockerinaction/ch2_mailer)
docker start $MAILER_CIDWP_CID=$(docker create --link $SQL_CID:mysql -p 80 \
-v /run/lock/apache2/ -v /run/apache2/ \
--read-only wordpress:4)docker start $WP_CIDAGENT_CID=$(docker create --link $WP_CID:insideweb \
--link $MAILER_CID:insidemailer \
dockerinaction/ch2_agent)docker start $AGENT_CID

恭喜你,现在你应该有了一个正在运行的WordPress 容器!通过使用只读文件系统,以及链接WordPress 到另一个运行着数据库的容器,可以确保运行WordPress 镜像的容器永远不会改变。这意味着,如果运行客户的WordPress 博客程序的机器出了问题,可轻松在其他地方启动该容器的另一个副本。
但是这一设计有两个问题。首先,数据库和WordPress 的容器运行在同一个机器上。其次,WordPress 对重要的设置,如数据库名称、管理用户、管理密码、数据库加盐等使用默认值。为了解决这个问题,你可以创建多个版本的WordPress 软件,每一个客户都有一个特殊的配置。这样做会使简单的配置脚本变成一个在创建镜像时写入文件的怪物。通过使用环境变量来注入配置则是一个更好的方式。

2 环境变量的注入

环境变量是通过其执行上下文提供给程序的键值对。它可以让你在改变一个程序的配置时,无须修改任何文件或更改用于启动该程序的命令。
Docker 使用环境变量来传达相关信息,包括容器的守护选项、容器的主机名,以及其他在容器中运行程序的实用信息。Docker 还为用户提供了一个机制,可将环境变量注入到一个新的容器。那些期望通过环境变量获取重要信息的程序,可在容器创建时就进行配置。幸运的是,WordPress 就是这样一个程序。

在深入WordPress 的细节之前,尝试注入和观察你的环境变量。UNIX 命令env 显示当前执行上下文(终端)中的所有环境变量。要查看注入的环境变量,请使用以下命令:

–env 标志或-e 缩写,可用于注入任何环境变量。如果变量已经由镜像或Docker 设置,则该值将被覆盖。容器内部运行程序的方式,可以依赖于这种变量。WordPress 遵循以下环境变量:

WORDPRESS_DB_HOSTWORDPRESS_DB_USERWORDPRESS_DB_PASSWORDWORDPRESS_DB_NAMEWORDPRESS_AUTH_KEYWORDPRESS_SECURE_AUTH_KEYWORDPRESS_LOGGED_IN_KEYWORDPRESS_NONCE_KEYWORDPRESS_AUTH_SALTWORDPRESS_SECURE_AUTH_SALTWORDPRESS_LOGGED_IN_SALTWORDPRESS_NONCE_SALT

提示 这个示例忽略了KEY 和SALT 变量,但任何实际的生产系统绝对应该设置这些值。

开始之前,你应该解决数据库和WordPress 容器在同一个机器上运行的问题。不是使用链接来满足WordPress 的数据库依赖,而是注入WORDPRESS_DB_HOST 变量的值:

docker create --env WORDPRESS_DB_HOST=<my database hostname> wordpress:4

这个示例会创建(并不启动)WordPress 容器。不管你在中指定的是什么,该容器都会试着连上一个MySQL 数据库。
由于远程数据库可能不会使用任何默认的用户名和密码,你就必须同时注入这些设置。假设数据库管理员是养猫爱好者且痛恨强密码:

docker create \
--env WORDPRESS_DB_HOST=<my database hostname> \
--env WORDPRESS_DB_USER=site_admin \
--env WORDPRESS_DB_PASSWORD=MeowMix42 \
wordpress:4

使用环境变量注入这一方法,能帮助你区分WordPress 容器和MySQL 容器之间的物理联系。由于数据库和客户的WordPress 网站都在同一台机器上,你仍然需要解决前面提到的第二个问题——所有的网站都使用相同的默认数据库名称。你需要为每一个独立的站点设置数据库名称以环境变量的方式注入:

你已经解决了这些问题,现在可以修改配置脚本了。首先,设置机器只能运行一个MySQL 容器:

DB_CID=$(docker run -d -e MYSQL_ROOT_PASSWORD=ch2demo mysql:5)
MAILER_CID=$(docker run -d dockerinaction/ch2_mailer)

那么网站配置脚本将是这样的:

这个新脚本将为每一位客户启动WordPress 实例和监控器,并将这些容器以及一个单独的邮件程序和MySQL 数据库彼此连接。WordPress 容器在被销毁、重新启动、升级的同时,完全不用担心数据会丢失。如图所示就是这种架构。

每个WordPress 和监控器容器使用相同的数据库和邮件服务

客户对当前交付的所有工作成果很满意。但有一件事可能会比较烦人。在早期的测试中,你发现监视器在该网站不可用时,的确可以准确通知邮件服务器,但重新启动该网站和监控器需要手动实现。要是系统在检测到故障时,能尝试自动恢复就更好了。Docker 对此提供了重启的策略,但仍不够稳定。

本文选自《Docker实战》。

想及时获得更多精彩文章,可在微信中搜索“博文视点”或者扫描下方二维码并关注。

用Docker构建与环境无关的系统相关推荐

  1. Docker构建python环境

    Docker构建python环境 --潘登同学的Linux笔记 文章目录 Docker构建python环境 --潘登同学的Linux笔记 Docker网络管理 创建Python容器 创建数据库容器 部 ...

  2. 利用Docker构建开发环境

    最近接触PAAS相关的知识,在研发过程中开始使用Docker搭建了自己完整的开发环境,感觉生活在PAAS时代的程序员真是幸福,本文会简要介绍下Docker是什么,如何利用Docker来搭建自己的开发环 ...

  3. 用Docker构建LNMP环境(上)

    利用docker搭建lnmp环境(上) 小知识: docker镜像运行之后变成容器(docker run) Registry 是Docker镜像的中央存储仓库(pull/push) https://g ...

  4. 生死簿后台管理系统(一)——使用Docker构建开发环境

    最近有个段子非常火,说有个程序员梦见自己被阎王召见,让他帮忙开发一个后台管理系统.在一笑而过之后,我觉得如果要是能把这个系统做出来,应该颇具娱乐性,也顺便了解一下高并发以及大数据的相关技术--每天要上 ...

  5. docker搭建java测试环境_基于docker构建测试环境

    目录 0x01介绍 0x02 镜像基本操作 0x03 容器基本操作 0x04 容器的修改与保存 0x05 使用Dockerfile定制镜像 0x01介绍 Docker 是一个开源的应用容器引擎,基于 ...

  6. docker的php教程https,Docker搭建php环境教程详解

    本文关键详细介绍了Docker构建php环境实例教程详细说明,原文中根据实例编码详细介绍的十分详尽,对大伙儿的学习培训或是工作中具备一定的参照学习培训使用价值,必须的盆友能够参照下 docker 安裝 ...

  7. docker mysql开发环境_Docker 构建PHP+Apache+MySQL 开发环境

    文章目錄 通过Docker 构建PHP+Apache+MySQL 开发环境,所有的服务(Apache,MySQL)和语言环境(PHP)都将在容器中运行,代码编写在宿主机内编写,并在宿主机的浏览器进行查 ...

  8. Jenkins+git+docker构建持续化集成环境

    CI/CD介绍 发布流程设计 Jenkins服务器 192.168.100.109 Git/Harbor 192.168.100.110 Docker 192.168.100.111 工具 版本 Ce ...

  9. Docker构建指定系统架构的官方镜像

    Docker 构建指定系统架构的官方镜像 比如我的系统是麒麟v10,麒麟v10的系统内核是 arm64 架构的,我想要安装 mysql 镜像,但 mysql 的 docker 并没有提供 arm64 ...

  10. docker 灵活的构建 PHP 环境

    使用docker搭建灵活的线上php环境 有时候你可能不太需要一些别人已经集成了的包或者镜像 我们就可以使用以下方式自己动手逐一构建自己所需要的环境结构 并在最后实现一键自动化部署 一步一步点亮doc ...

最新文章

  1. UML应用开发详解--视频
  2. C++ 复数类加减法运算重载为成员函数形式
  3. Twitter的分布式自增ID算法snowflake (Java版)
  4. Linux救援模式实战
  5. 201521123009 《Java程序设计》第1周学习总结
  6. MySQL · BUG分析 · Rename table 死锁分析
  7. BigDecimal 加减乘除
  8. for循环中包含跨服务查询优化
  9. Android混淆规则
  10. 【Linux】一步一步学Linux——stty命令(243)
  11. 吉他学习笔记--更新中
  12. SLA、BFD、NQA、ACl 笔记
  13. 笔记本使用的几大盲区
  14. CVPR 2018 | 旷视科技人体姿态估计冠军论文——级联金字塔网络CPN
  15. Apache Tomcat 文件包含漏洞(CNVD-2020-10487)修复方法
  16. pdsh@xxxx: localhost: connect: Connection refused
  17. 天气预报接口应该怎么开通?
  18. 怎么更改Visual Studio项目名字
  19. 计算机编程的11种趋势:
  20. jQuery弹出插件thickbox使用心得

热门文章

  1. 软件构建中的设计(一)
  2. Cesium.js学习第二天(立方体)
  3. Linux下MariaDB 安装及root密码设置(修改)
  4. VMware 12PRO安装Mac OS X 10.10.5
  5. 敏捷转型历程 - Sprint3 一团糟的演示会
  6. A计划 hdu2102(bfs一般题)
  7. Feature部署EventHandler注意事项
  8. LeetCode每日一题——只出现一次的数字 III
  9. Java 常用类 -Math
  10. 缓冲文件系统和非缓冲文件系统