如何使用最佳实践创建生产就绪的Docker镜像?

时间:2017-07-17 08:11:26

标签: docker docker-image

创建Docker镜像对于测试环境来说是一项简单的任务。但是,当涉及到生产实施时,我们必须遵循最佳实践来克服任何安全性和工作流问题。

创建生产就绪泊坞窗图像的最佳做法是什么?

1 个答案:

答案 0 :(得分:2)

正如Create Production Docker Images in 5 Steps by DevopsAnswers中全面描述的那样,以下步骤将被视为创建生产就绪Docker镜像的综合指南。

在创建生产Docker镜像时,您应该对Docker最佳实践进行广泛的了解。

步骤1:使用重量轻的Base Docker图像

使用轻量级图像而不是使用笨重的基本图像更好一点,因为当它的尺寸较小时,使用生成的Docker图像会更方便。

如果您计划在高度关键的生产系统中使用Docker,而您无法承受几秒钟的停机时间,那么您必须首先选择的是自定义泊坞窗图像的轻量级基础图像。

第2步:减少中间层

Dockerfile中,FROMLABELRUNCMDADD等所有指示都会添加Docker镜像的新图层。因此,多次减少相同指令的使用将是最佳实践,因为它会为您提供稍小的图像。

第3步:选择特定版本 在Docker指令中选择特定版本是一种很好的做法,因为它可以为生产实现保持良好和稳定。

想象一下,如果我们使用Ubuntu:latest作为基本图像。它将使用当前可用的最新Ubuntu映像作为我们的自定义Docker镜像。此外,我们将基于相同的Ubuntu版本设置所有软件组件。 当Ubuntu在Docker Hub中使用较新的基本映像更新最新标记时,您可能会在生产Docker映像中遇到一些程序包依赖性问题或不兼容。

此外,我们应该始终尝试安装特定的软件包版本,而不是安装通用软件包。

实施例

推荐apt-get install mysql-server-5.5

不推荐apt-get install mysql-server

第4步:不要包含敏感数据

在Docker中使用敏感数据(如数据库凭据和API密钥)将是一项具有挑战性的任务。

  

不要在Docker镜像中硬编码任何登录凭据

要克服此限制,您应该有效地使用环境变量。

例如,如果您创建连接到Mysql DB的Drupal映像,我们可以将Drupal MySQL数据库设置保留为空白,如下所示。

$databases = array (
 'default' =>
 array (
 'default' =>
 array (
 'database' => '',
 'username' => '',
 'password' => '',
 'host' => '',
 'port' => '',
 'driver' => 'mysql',
 'prefix' => '',
 ),
 ),
);

现在我们可以使用ENTRYPOINT来利用环境变量来替换运行时的Drupal MySQL数据库凭证,如下所示。

#!/bin/sh
set -e

# Apache gets grumpy about PID files pre-existing
rm -f /var/run/apache2.pid

# Define Drupal home file path
DRUPAL_HOME="/var/www/html"

# Define Drupal settings file path
DRUPAL_SETTINGS_FILE="${DRUPAL_HOME}/sites/default/settings.php"

# Check the avilability of environment variables
if [ -n "$DRUPAL_MYSQL_DB" ] && [ -n "$DRUPAL_MYSQL_USER" ] && [ -n "$DRUPAL_MYSQL_PASS" ] && [ -n "$DRUPAL_MYSQL_HOST" ] ; then
 echo "Setting up Mysql DB in $DRUPAL_SETTINGS_FILE"
# Set Database
 sed -i "s/'database' *=> *''/'database' => '"$DRUPAL_MYSQL_DB"'/g" $DRUPAL_SETTINGS_FILE
# Set Mysql username
 sed -i "s/'username' *=> *''/'username' => '"$DRUPAL_MYSQL_USER"'/g" $DRUPAL_SETTINGS_FILE
# Set Mysql password
 sed -i "s/'password' *=> *''/'password' => '"$DRUPAL_MYSQL_PASS"'/g" $DRUPAL_SETTINGS_FILE
# Set Mysql host
 sed -i "s/'host' *=> *''/'host' => '"$DRUPAL_MYSQL_HOST"'/g" $DRUPAL_SETTINGS_FILE
fi

# Start Apache in foreground
tail -F /var/log/apache2/* &
exec /usr/sbin/apache2ctl -D FOREGROUND

最后,您可以在Docker运行时期间简单地定义环境变量,如下所示。

docker run -d -t -i
-e DRUPAL_MYSQL_DB='database' 
-e DRUPAL_MYSQL_USER='user' 
-e DRUPAL_MYSQL_PASS='password' 
-e DRUPAL_MYSQL_HOST='host' 
-p 80:80 
-p 443:443 
--name <container name>
<custom image>

步骤5:从非特权用户运行CMD / Entypoint

使用非特权用户运行生产系统始终是一个不错的选择,从安全角度来看也是如此。

您可以简单地将USER条目放在Dockerfile中的CMDENTRYPOINT之前,如下所示。

# Set running user of ENTRYPOINT
USER www-data

# Start entrypoint
ENTRYPOINT ["entrypoint"]