Silence & Solitude makes...

Pu's mind space

<转/译>如何将应用配置打包进Docker

粗译

新手开始部署他们的第一个Docker Container的时候经常会问的一个问题就是:”我该怎么把应用的配置打包进Docker容器里面?”.问题中提到的配置包括worker的数量,JVM的内存大小,或者数据库的连接串.现实中实现这些有一套标准方法,而它们各有利弊.

将配置发送到Docker打包了的应用里的三个半方法

1. 将配置烧进容器里

这可能是最简单的配置了,也就是在Dockerfile里面利用COPY指令把配置文件扔到容器里,或者通过RUN指令执行sed以及echo等命令来修改默认的配置文件.

优点:

缺点:

  • 因为配置已经烧到镜像里,未来可能的配置改动都需要修改Dockerfile并重新build来实现

2a. 利用环境变量动态地配置应用

这是一个在Docker Hub上的镜像比较常用的方法,譬如PostgreSQL的’POSTGRES_USER’和’POSTGRES_PASSWORD’这两个环境变量.

简单地说,当你启动容器docker run的时候,需要指定环境变量,而容器的进入点(Entry point)也就是启动脚本会寻找这些变量,并把他们用在相应的配置文件里.

需要提的是,启动脚本应该提供有意义的缺省值,以防用户没有提供这些环境变量.

优点:

  • 从配置角度看,这样的容器更灵活

缺点:

  • 打破了生产/开发环境的一致性要求,也就是说其他人可以通过不同的配置使得容器的行为在生产/开发环境下不一致
  • 一些复杂的配置无法映射为简单的键值对

2b. 利用环境变量动态地配置应用

和上面的一样,但是启动脚本是从网络,像是Consul或者etcd来获取配置参数.

这就使得通过环境变量来实现复杂配置成为可能.因为键值对存储器可以有多层结构.值得一提的是有很多工具可以用来抓取键值对并替换到你的配置文件中.而像confd这类工具甚至可以在配置改变时自动重新加载应用.这就使得应用的配置更加动态化.

优点:

  • 配置更动态
  • 键值存储使得复杂配置成为可能

缺点:

  • 同样违反了生产/开发环境一致性(译注:和所谓的immutable container是同一个概念)
  • KV store必须高可用,因为所有的容器配置都依赖于这个存储器

3. 将配置文件目录挂载到Docker Volumes

Docker Volume介绍略

如果配置文件正好在运行容器的文件系统上,可以通过挂载的方式提供到容器内部使用.例如

docker run -v /home/dan/my_statsd_config.conf:/etc/statsd.conf hopsoft/graphite-statsd

优点:

  • 无需修改容器就可以随意配置

缺点:

  • 违反生产/开发环境一致性要求
  • 如果要用在生产环境中,必须要保证配置文件在基础操作系统中可用.

结论

如上所述,想要配置一个容器包里的应用,方法其实很多,各有利弊.哪个最好?其实取决于你需要多大的动态配置的自由度以及你是否愿意承担额外的譬如维护一个KV store这样的负担.

译后评

个人目前倾向1和2a,但是还没有在生产环境中体验过实际会有哪些坑,所以只能是倾向.

原文地址