在 Rancher 容器升级后,基于环境变量的配置,自动运行应用初始化命令与数据库迁移命令

1、现阶段的升级方案,在 Rancher 容器升级后,进入 Docker 容器,在命令行中依次运行:

// 开发环境 / 测试环境
php /sobey/www/pcs-api/init --env=Development --overwrite=All
// 演示环境 / 生产环境
php /sobey/www/pcs-api/init --env=Production --overwrite=All
// 数据库迁移(日志的数据库模式,仅在第一次安装时运行)
php /sobey/www/pcs-api/yii migrate --migrationPath=@yii/log/migrations/ --interactive=0
// 数据库迁移(MySQL 5.7.7 之前的版本:innodb_large_prefix=1、innodb_file_format=BARRACUDA)
php /sobey/www/pcs-api/yii migrate --interactive=0

2、现阶段的升级方案所存在的问题在于,有时候 Rancher 容器升级后,运维人员需要在每个容器中皆粘贴运行至少 2 条命令,即第 2、4 条,很容易漏掉某个容器,进而导致程序运行错误,而且存在一定的工作量。准备基于 SHELL 脚本,自动运行命令行,以确保每个容器皆初始化成功,且节省运维人员的工作量。

3、新建 \build\c_files\config\init\pcs-api_init.sh

注:
如果未设置环境变量:PCS_API_CFG_ENV,则设置其默认值为:dev
如果已设置环境变量:PCS_API_CFG_ENV,其值为:dev,则执行命令:php /sobey/www/pcs-api/init –env=Development –overwrite=All;其值为:prod,则执行命令:php /sobey/www/pcs-api/init –env=Production –overwrite=All;否则输出:please set environment variable PCS_API_CFG_ENV dev or prod
如果未设置环境变量:PCS_API_CFG_MIGRATE,则设置其默认值为:false
如果已设置环境变量:PCS_API_CFG_MIGRATE,其值为:true,则依次执行命令:php /sobey/www/pcs-api/yii migrate –migrationPath=@yii/log/migrations/ –interactive=0、php /sobey/www/pcs-api/yii migrate –interactive=0;其值为:false,则输出:running without db migrate;否则输出:please set environment variable PCS_API_CFG_MIGRATE true or false

#!/bin/bash
env | grep PCS_API_CFG_ENV || export PCS_API_CFG_ENV="dev"
if [[ $PCS_API_CFG_ENV == "dev" ]]
then
    php /sobey/www/pcs-api/init --env=Development --overwrite=All
elif [[ $PCS_API_CFG_ENV == "prod" ]]
then
    php /sobey/www/pcs-api/init --env=Production --overwrite=All
else
    echo "please set environment variable PCS_API_CFG_ENV dev or prod"
fi
env | grep PCS_API_CFG_MIGRATE || export PCS_API_CFG_MIGRATE="false"
if [[ $PCS_API_CFG_MIGRATE == "true" ]]
then
    php /sobey/www/pcs-api/yii migrate --migrationPath=@yii/log/migrations/ --interactive=0
    php /sobey/www/pcs-api/yii migrate --interactive=0
elif [[ $PCS_API_CFG_MIGRATE == "false" ]]
then
    echo "running without db migrate"
else
    echo "please set environment variable PCS_API_CFG_MIGRATE true or false"
fi

4、删除开发环境中的数据库中的所有表,未设置环境变量:PCS_API_CFG_ENV、PCS_API_CFG_MIGRATE,以测试未设置环境变量时,默认值的设置是否生效,符合预期
注:
如果未设置环境变量:PCS_API_CFG_ENV,则设置其默认值为:dev,执行命令:php /sobey/www/pcs-api/init –env=Development –overwrite=All,如图1

图1

如果未设置环境变量:PCS_API_CFG_MIGRATE,则设置其默认值为:false,输出:running without db migrate,如图2

图2

5、删除开发环境中的数据库中的所有表,已设置环境变量:PCS_API_CFG_ENV,其值为:dev,已设置环境变量:PCS_API_CFG_MIGRATE,其值为:true,以测试已设置环境变量时,是否执行对应的命令,符合预期,如图3

图3

注:
如果已设置环境变量:PCS_API_CFG_ENV,其值为:dev,则执行命令:php /sobey/www/pcs-api/init –env=Development –overwrite=All
如果已设置环境变量:PCS_API_CFG_MIGRATE,其值为:true,则依次执行命令:php /sobey/www/pcs-api/yii migrate –migrationPath=@yii/log/migrations/ –interactive=0、php /sobey/www/pcs-api/yii migrate –interactive=0,如图4、图5

图4

 

图5

6、删除开发环境中的数据库中的所有表,已设置环境变量:PCS_API_CFG_ENV,其值为:prod,已设置环境变量:PCS_API_CFG_MIGRATE,其值为:false,以测试已设置环境变量时,是否执行对应的命令,符合预期,如图6、图7

图6

图7

注:
如果已设置环境变量:PCS_API_CFG_ENV,其值为:prod,则执行命令:php /sobey/www/pcs-api/init –env=Production –overwrite=All
如果已设置环境变量:PCS_API_CFG_MIGRATE,其值为:false,则输出:running without db migrate

7、删除开发环境中的数据库中的所有表,已设置环境变量:PCS_API_CFG_ENV,其值为:,已设置环境变量:PCS_API_CFG_MIGRATE,其值为:,以测试已设置环境变量,但其值不符合规定时,是否输出对应的提示,符合预期,如图8、图9

图8

图9

注:
如果已设置环境变量:PCS_API_CFG_ENV,否则输出:please set environment variable PCS_API_CFG_ENV dev or prod
如果已设置环境变量:PCS_API_CFG_MIGRATE,否则输出:please set environment variable PCS_API_CFG_MIGRATE true or false

8、删除开发环境中的数据库中的所有表,已设置环境变量:PCS_API_CFG_ENV,其值为:dev,已设置环境变量:PCS_API_CFG_MIGRATE,其值为:true,将 PCS_API_CFG_DB_PASSWORD 的值设置为错误的密码,以测试执行对应的命令出错时的情形,符合预期,容器升级失败,如图10

图10

注:
如果已设置环境变量:PCS_API_CFG_ENV,其值为:dev,则执行命令:php /sobey/www/pcs-api/init –env=Development –overwrite=All
如果已设置环境变量:PCS_API_CFG_MIGRATE,其值为:true,则依次执行命令:php /sobey/www/pcs-api/yii migrate –migrationPath=@yii/log/migrations/ –interactive=0、php /sobey/www/pcs-api/yii migrate –interactive=0,查看容器日志,数据库密码错误,如图11

图11

9、Rancher 环境变量说明如下,现阶段如果执行数据库迁移的机器升级失败的话,即使其他机器升级成功,仍然会存在问题,此问题暂缓处理。如图12

图12

 PCS_API_CFG_ENV=dev # 环境,dev:开发环境 / 测试环境;prod:演示环境 / 生产环境,默认:dev
 PCS_API_CFG_MIGRATE=false # 数据库迁移是否执行(单机部署时,需设置为 true;集群部署时,仅需一台机器设置为 true,其他机器需设置为 false),true:是;false:否,默认:false

10、在另一个项目中,在 Rancher 中升级容器时,自动执行数据库迁移命令报错:Exception ‘yii\db\Exception’ with message ‘SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Name or service not known’,如图13

图13

2019/1/22 下午3:49:43CHANNEL_PUB_API_CFG_MIGRATE=true
2019/1/22 下午3:49:43Yii Migration Tool (based on Yii v2.0.15.1)
2019/1/22 下午3:49:43
2019/1/22 下午3:49:43Exception 'yii\db\Exception' with message 'SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Name or service not known'
2019/1/22 下午3:49:43
2019/1/22 下午3:49:43in /sobey/www/channel-pub-api/vendor/yiisoft/yii2/db/Connection.php:624
2019/1/22 下午3:49:43
2019/1/22 下午3:49:43Stack trace:
2019/1/22 下午3:49:43#0 /sobey/www/channel-pub-api/vendor/yiisoft/yii2/db/Connection.php(996): yii\db\Connection->open()
2019/1/22 下午3:49:43#1 /sobey/www/channel-pub-api/vendor/yiisoft/yii2/db/Connection.php(983): yii\db\Connection->getMasterPdo()
2019/1/22 下午3:49:43#2 /sobey/www/channel-pub-api/vendor/yiisoft/yii2/db/Command.php(253): yii\db\Connection->getSlavePdo()
2019/1/22 下午3:49:43#3 /sobey/www/channel-pub-api/vendor/yiisoft/yii2/db/Command.php(1143): yii\db\Command->prepare(true)
2019/1/22 下午3:49:43#4 /sobey/www/channel-pub-api/vendor/yiisoft/yii2/db/Command.php(399): yii\db\Command->queryInternal('fetchAll', NULL)
2019/1/22 下午3:49:43#5 /sobey/www/channel-pub-api/vendor/yiisoft/yii2/db/mysql/Schema.php(312): yii\db\Command->queryAll()
2019/1/22 下午3:49:43#6 /sobey/www/channel-pub-api/vendor/yiisoft/yii2/db/mysql/Schema.php(125): yii\db\mysql\Schema->findColumns(Object(yii\db\TableSchema))
2019/1/22 下午3:49:43#7 /sobey/www/channel-pub-api/vendor/yiisoft/yii2/db/Schema.php(744): yii\db\mysql\Schema->loadTableSchema('CHANNEL_PUB_API...')
2019/1/22 下午3:49:43#8 /sobey/www/channel-pub-api/vendor/yiisoft/yii2/db/Schema.php(194): yii\db\Schema->getTableMetadata('{{%migration}}', 'schema', true)
2019/1/22 下午3:49:43#9 /sobey/www/channel-pub-api/vendor/yiisoft/yii2/console/controllers/MigrateController.php(210): yii\db\Schema->getTableSchema('{{%migration}}', true)
2019/1/22 下午3:49:43#10 /sobey/www/channel-pub-api/vendor/yiisoft/yii2/console/controllers/BaseMigrateController.php(875): yii\console\controllers\MigrateController->getMigrationHistory(NULL)
2019/1/22 下午3:49:43#11 /sobey/www/channel-pub-api/vendor/yiisoft/yii2/console/controllers/BaseMigrateController.php(166): yii\console\controllers\BaseMigrateController->getNewMigrations()
2019/1/22 下午3:49:43#12 [internal function]: yii\console\controllers\BaseMigrateController->actionUp(0)
2019/1/22 下午3:49:43#13 /sobey/www/channel-pub-api/vendor/yiisoft/yii2/base/InlineAction.php(57): call_user_func_array(Array, Array)
2019/1/22 下午3:49:43#14 /sobey/www/channel-pub-api/vendor/yiisoft/yii2/base/Controller.php(157): yii\base\InlineAction->runWithParams(Array)
2019/1/22 下午3:49:43#15 /sobey/www/channel-pub-api/vendor/yiisoft/yii2/console/Controller.php(148): yii\base\Controller->runAction('', Array)
2019/1/22 下午3:49:43#16 /sobey/www/channel-pub-api/vendor/yiisoft/yii2/base/Module.php(528): yii\console\Controller->runAction('', Array)
2019/1/22 下午3:49:43#17 /sobey/www/channel-pub-api/vendor/yiisoft/yii2/console/Application.php(180): yii\base\Module->runAction('migrate', Array)
2019/1/22 下午3:49:43#18 /sobey/www/channel-pub-api/vendor/yiisoft/yii2/console/Application.php(147): yii\console\Application->runAction('migrate', Array)
2019/1/22 下午3:49:43#19 /sobey/www/channel-pub-api/vendor/yiisoft/yii2/base/Application.php(386): yii\console\Application->handleRequest(Object(yii\console\Request))
2019/1/22 下午3:49:43#20 /sobey/www/channel-pub-api/yii(23): yii\base\Application->run()
2019/1/22 下午3:49:43#21 {main}

11、\build\c_files\config\init\channel-pub-api_init.sh,SHELL 脚本如下:

#!/bin/bash
env | grep CHANNEL_PUB_API_CFG_ENV || export CHANNEL_PUB_API_CFG_ENV="dev"
if [[ $CHANNEL_PUB_API_CFG_ENV == "dev" ]]
then
    php /sobey/www/channel-pub-api/init --env=Development --overwrite=All
elif [[ $CHANNEL_PUB_API_CFG_ENV == "prod" ]]
then
    php /sobey/www/channel-pub-api/init --env=Production --overwrite=All
else
    echo "please set environment variable CHANNEL_PUB_API_CFG_ENV dev or prod"
fi
env | grep CHANNEL_PUB_API_CFG_MIGRATE || export CHANNEL_PUB_API_CFG_MIGRATE="false"
if [[ $CHANNEL_PUB_API_CFG_MIGRATE == "true" ]]
then
    php /sobey/www/channel-pub-api/yii migrate --migrationPath=@yii/log/migrations/ --interactive=0
    php /sobey/www/channel-pub-api/yii migrate --interactive=0
    php /sobey/www/channel-pub-api/yii qq-tp-app/init-sync
    php /sobey/www/channel-pub-api/yii qq-cw-app/init-sync
    php /sobey/www/channel-pub-api/yii weibo-weibo-connect-web-app/init-sync
elif [[ $CHANNEL_PUB_API_CFG_MIGRATE == "false" ]]
then
    echo "running without db migrate"
else
    echo "please set environment variable CHANNEL_PUB_API_CFG_MIGRATE true or false"
fi

12、升级失败,回滚至老版本,手动执行命令,全部成功

13、对比两个项目的差异,原因在于:\build\c_files\config\init 目录中的文件执行顺序的差异导致的,要想确保命令行成功执行,需要确保 config0.sh 文件执行后,pcs-api_init.sh/channel-pub-api_init.sh 文件再执行,但是在 channel-pub-api 中,却是 channel-pub-api_init.sh 先于 config0.sh 之前执行,如图14

图14

14、在两个项目中,将 pcs-api_init.sh/channel-pub-api_init.sh 皆重命名为 console_init.sh,以确保 config0.sh 文件执行后,console_init.sh 文件再执行,如图15

图15

15、在 pcs-api 升级后,查看日志,符合预期,如图16

图16

16、在 channel-pub-api 升级后,查看日志,符合预期,如图17

图17

 

永夜