環(huán)境深度容器化建設(shè)

原創(chuàng):陳斌 張少華


本期導(dǎo)讀

1.為提升部署效率持續(xù)集成測試環(huán)境從胖docker向深度容器化的改進;

2.架構(gòu)采用Rancher + Harbor,網(wǎng)絡(luò)采用pipework為容器配置固定的IP地址;

物理架構(gòu)

在測試環(huán)境建設(shè)過程中由于模塊數(shù)量快速增加,為了提高部署效率和穩(wěn)定性我們在容器化的基礎(chǔ)上進行了深度容器化的探索,深度容器化采用了Rancher + Harbor的架構(gòu),該架構(gòu)有非常優(yōu)良的性能,非常適合以pod為單位進行子系統(tǒng)級別測試環(huán)境建設(shè)。

網(wǎng)絡(luò)配置

如上圖所示,每一個Node節(jié)點對應(yīng)現(xiàn)在的一套測試環(huán)境,擁有獨立的ip。

其實現(xiàn)原理為Node節(jié)點是Dind生成容器,創(chuàng)建后使用pipework為容器配置固定的IP地址,之后可在Node中啟動多個Pod,分享使用Node的IP地址。

對比Cattle和K8S使用過程中的差異

由于我們測試需求的特殊性,目前Rancher上面的服務(wù)群并不需要頻繁的做升級,而是會頻繁的創(chuàng)建和釋放。Cattle的穩(wěn)定性和易用性要優(yōu)于K8S,但是K8S提供了更加強大的周邊功能包括資源管理、監(jiān)控、配置管理等。

Cattle:

(1)多服務(wù)應(yīng)用,每個項目都作為獨立的服務(wù)受Rancher管理,升級比較方便。缺點是需要以應(yīng)用(stack)為單位進行擴展和調(diào)度,因為我們其實是把一個應(yīng)用里的多個容器包在一起對外提供服務(wù)。

擴展方式 :stack-copy、或者通過模板創(chuàng)建(效率略低于主從容器方式)。

(2)主從容器,一個容器作為主容器,添加多個從容器,耦合關(guān)系更緊密,優(yōu)點是以服務(wù)(service)為單位進行擴展和調(diào)度。

擴展方式:由于資源對象的編號,直接scale即可。

缺點:

當(dāng)需要對該服務(wù)做升級時,會重啟所有容器,從容器越多,升級越慢。因為升級的最小操作單元就是服務(wù)。

當(dāng)在服務(wù)中使用負(fù)載均衡時,而該服務(wù)又擁有從服務(wù)的時候,你需要使用主服務(wù)作為負(fù)載均衡器的目標(biāo)。從服務(wù)不能成為目標(biāo)。

從服務(wù)不能使用links/external_links來創(chuàng)建服務(wù)別名。

內(nèi)部訪問:Cattle提供了內(nèi)部DNS解析,直接以容器名訪問。

K8S:

多容器Pod

以Pod為單位進行調(diào)度,一個Pod里面啟動多個容器,類似于Cattle的主從容器方式,但是差異在于網(wǎng)絡(luò)。

擴展方式:scale(效率不高)。

內(nèi)部訪問:Pod內(nèi)的所有容器共享網(wǎng)絡(luò)namespace,其實就是都通過-net=container(Pod創(chuàng)建時有一個sleep容器) 共享了同一個網(wǎng)絡(luò),所以端口不能沖突,容器直接以localhost(或者127.0.0.1)訪問。

缺點:

擴展效率低下。

容器之間的相互通信不是十分穩(wěn)定。

優(yōu)點:有一系列的強大的利于編排的功能,比如 initContainer、HPA、PV等都是非常好的特性。

CI 工作流

數(shù)據(jù)庫組件容器化


Mysql容器化

我們測試環(huán)境使用的mysql版本是5.6.41,所以我們制作mysql-5.6.41的鏡像,制作過程比較簡單

(1)拉取官方鏡像啟動,環(huán)境變量必須要設(shè)置。

docker run -p 3300:3306 --name mysql ?-e MYSQL_ROOT_PASSWORD=root123 -d docker.io/mysql:5.6.41

(2)利用docker cp 將我們的配置文件復(fù)制到該容器中

docker cp ${PWD}/my.cnf mysql:/etc/mysql/

(3)利用docker commit命令 將修改部分提交,

docker commit mysql 192.168.1.251:7003/qa/mysql:5.6.41-private

(4)推送到Harbor

docker push?192.168.1.251:7003/qa/mysql:5.6.41-private

(5)啟動試一下:

docker run -p3301:3306 -e MYSQL_ROOT_PASSWORD=root@123?-e TZ=Asia/Shanghai --name mysql-p -d -v /home/demo/data2:/var/lib/mysql 192.168.1.251:7003/qa/mysql:5.6.41-private

(6)客戶端連接,使用我們啟動時指定的root的密碼,然后查看一下配置是否正確,找一個我們配置文件里的自定義選型比對一下:

(7)沒問題,完成。注意數(shù)據(jù)卷的使用,不要把數(shù)據(jù)放在容器內(nèi)部,這部分,具體使用還要再做規(guī)劃。

Mongo容器化(3.6.4)

先看下咱們的配置文件,沒有什么特殊配置,可以直接拉取官方鏡像啟動,然后看下mongo鏡像的啟動參數(shù):

環(huán)境變量:


配置文件默認(rèn)在 /etc下,啟動時?使用–config /etc/mongo/mongo.conf 來指定自定義配置,這里不需要。我們只需要直接啟動官方鏡像,把數(shù)據(jù)文件映射出來即可。

docker run -p 27000:27017 -v /home/demo/mongodata:/data --name mongo-p -d -e MONGO_INITDB_ROOT_USERNAME=admin -e MONGO_INITDB_ROOT_PASSWORD=admin?-e TZ=Asia/Shanghai?192.168.1.251:7003/qa/mongo:3.6.4

客戶端連接一下試試:

Redis容器化(3.2.12)

其實原理跟mysql類似,這里簡單寫了個Dockerfile,因為redis啟動必須指定配置文件

FROM docker.io/redis:3.2.12

MAINTAINER xxx@xxx.com

COPY redis.conf /usr/redis.conf

CMD [ "redis-server", "/usr/redis.conf" ]

對配置文件做了一點修改,把日志文件去掉了,在容器里,我們一般都是使用docker logs 查看日志,需要把日志輸出出來,而不是寫入文件里。

docker build -t 192.168.1.251:7003/qa/redis:3.2.12 .

docker run -p 6300:6379 -v /home/demo/redisdata2:/data -e TZ=Asia/Shanghai --name redis-p -d 192.168.1.251:7003/qa/redis:3.2.12

連接成功,注意這里沒設(shè)置密碼驗證。如果想要加上密碼,也非常簡單,redis支持一系列的command line,使用方式跟在配置文件里面的key值完全一樣,比如這里我們要加上密碼驗證,只需要在docker 啟動命令最后加上?


(注意docker run的啟動參數(shù)是有順序的,在鏡像名字后面的內(nèi)容都認(rèn)為是command,平時啟動鏡像,一般的參數(shù)都寫在鏡像名字之前)

應(yīng)用容器化


S2I 對接生產(chǎn)

由于生產(chǎn)使用OpenShift,原有的鏡像構(gòu)建流水線做出的鏡像雖然比較簡單易用,但無法與OpenShift兼容,所以借助OpenShift提供的鏡像構(gòu)建工具?s2i?去做鏡像。缺陷就是目前這個基礎(chǔ)鏡像太大了。

本地構(gòu)建方式:

(1)安裝s2i,并拉取基礎(chǔ)鏡像到本地

(2)拉取代碼,并切換到項目根目錄,例如:/home/work/dev/projects/hydra

(3)執(zhí)行s2i構(gòu)建:s2i build . 192.168.1.251:7003/qa/python:2.7-oc?hydra?-e GIT_REPO_NAME=hydra?(必填:通過這個環(huán)境變量來指定項目名稱,并且會影響到代碼在容器中的路徑)

(4)啟動鏡像:通過上面的命令,構(gòu)建出了一個名字為 hydra,tag為latest的鏡像,要啟動這個鏡像,也非常簡單,需要指定幾個環(huán)境變量

- env:

- name:?GIT_REPO_NAME

value:?hydra

- name:?INI_CMD

value:?(測試環(huán)境一般不需要這個變量)

- name:?RUN_CMD

value:?make start_test

- name:?RUN_CMD_DIR

value:?/data/home/work/hydra/

應(yīng)用修改:

(1)測試時同一個Pod里面啟動多個容器,所以nginx 不能啟動會有端口沖突。uwsgi啟動需要將socket替換為http-socket并且端口不能沖突,由于日志管理不便,暫時舍棄。

(2)Makefile 添加用于測試環(huán)境的啟動和初始化的命令

啟動命令(RUN_CMD):start_test,先做make local_config操作,然后做啟動操作,直接runserver啟動即可

初始化命令(INI_CMD):測試一般不需要,線上一般會復(fù)制nginx配置

(3)以hydra 的修改為例子:

修改tools/config_templates/gen_config.py? 直接vim編輯,將class LocalSettings(object) 這個類里的localhost全部替換為127.0.0.1,因為localhost不走物理網(wǎng)卡,一些數(shù)據(jù)庫連接會直接在容器內(nèi)部找socket,導(dǎo)致連不上。

Makefile 根據(jù)需要啟動的服務(wù)類型添加了兩個target:

start_test:local_config

????????DJANGO_SETTINGS_MODULE="hydra.settings"?python manage.py runserver?0.0.0.0:19010?--noreload

start_celery-hydra_upload-1_test:local_config

????????DJANGO_SETTINGS_MODULE="hydra.settings"?PYTHONPATH="."?/data/home/work/hydra/.venv/bin/celery worker -A async_tasks -Q hydra,hydra_loan_notify,hydra_repay_notify -P eventlet -c?200?-l info --

logfile=/tmp/celery.log --without-heart

啟動hydra:分別傳入不同的RUN_CMD來啟動兩個服務(wù),例如:make start_test

應(yīng)用接入方式


配置修改

總體方式是——根據(jù)該項目依賴的外部服務(wù),將配置修改為通過環(huán)境變量讀取,由于之前的不規(guī)范,大部分項目都涉及如下三個文件的修改:

(1)Makefile 增加 docker_config,以hydra為例:

?(2)修改tools/config_templates/gen_config.py?

?(3)修改tools/config_templates/local_settings.py.tmpl?配置模板里面全局替換一下

項目根目錄添加啟動腳本:

entrypoint.sh 原因:部分項目需要在啟動之前先生成配置文件

根據(jù)不同項目框架 操作不同:

django項目:

#!/bin/bash

make docker_config

python manage.py runserver 0.0.0.0:8080 --noreload

flask項目:

#!/bin/bash

make docker_config

gunicorn -k gevent -c gunicorn_dev.py yin.app:app

容器化現(xiàn)存問題


日志采集

需求:

(1)持久化存儲

將日志文件持久化存儲,按hostname區(qū)分。一個pod里面通常會有小到幾個大到幾十個容器,統(tǒng)一把日志掛載到其中的stubs容器中,然后再掛載的pv上面。

缺點:

1.查看不方便,動態(tài)pv不能根據(jù)名字區(qū)分出來是哪個deploy的日志。

2.多個replicaSet副本的日志都綁到了同一個目錄下,文件眾多,查找不便。

備選方案一:阿里云logtail(收費)

備選方案二:efk?

備選方案三:graylog

當(dāng)前采取的方式是:

在stubs容器中安裝了ssh服務(wù),然后通過rsync去同步case日志。

在釋放資源之前,利用kubectl cp 持久化存儲服務(wù)日志。

去除依賴

目前自動化體系,對基礎(chǔ)庫的每日構(gòu)建、stubs更新等依賴嚴(yán)重。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容