[TOC]
概述
這次的實(shí)戰(zhàn)目標(biāo)如下:
將已有的python示例程序部署到OpenShift上. 為此, 需要做的事情有:
- 對(duì)原有python示例程序做優(yōu)化和調(diào)整, 使得可以部署到OpenShift上.
- 基于OpenShift上自帶模板(templates: openshift上的一種CI/CD全流程定義) - Django + PostgreSQL 進(jìn)行修改生成新的模板.
- 基于新的模板, 填入python示例程序的git地址, 自動(dòng)進(jìn)行: 構(gòu)建(build), 部署(deployment)和對(duì)外服務(wù)(service, route). 查看部署結(jié)果.
OpenShift簡(jiǎn)介
OpenShift v3(開源版本叫做: okd)是一個(gè)PAAS(平臺(tái)及服務(wù))系統(tǒng),旨在盡可能準(zhǔn)確地公開底層Docker格式的容器鏡像和Kubernetes 理念,并著重于開發(fā)人員輕松組合應(yīng)用程序。例如,安裝Ruby,推送代碼并添加MySQL。
OpenShift基于Docker和Kubernetes, 并針對(duì)以下方面進(jìn)行了開發(fā)和優(yōu)化:
- CI/CD 流程(基于jenkins的pipeline, S2I等)
- UI界面
- 安全加固(如容器內(nèi)使用非root用戶等)
- 監(jiān)控功能(基于EFK技術(shù)棧的日志監(jiān)控和基于Prometheus的metrics監(jiān)控等)
- 提供更安全 經(jīng)過RedHat認(rèn)證的基礎(chǔ)鏡像/模板等.(包括: java, python等運(yùn)行時(shí), mysql, mongo等db, apache, wildfly等中間件, jenkins等CI/CD, elasticsearch, kibana等監(jiān)控鏡像)
:notebook:
OpenShift有多個(gè)產(chǎn)品線, 包括:
Python示例程序簡(jiǎn)介
這是一個(gè)Django項(xiàng)目 - Learning Log(《Python編程:從入門到實(shí)踐》的教學(xué)案例),數(shù)據(jù)庫可以基于sqlite或Postgresql.
:notebook:
這個(gè)應(yīng)用的功能如下:
- 這是一個(gè)名為"學(xué)習(xí)筆記"的Web應(yīng)用程序, 讓用戶能夠記錄感興趣的主題, 并在學(xué)習(xí)每個(gè)主題的過程中添加日志條目.
- "學(xué)習(xí)筆記"的主頁對(duì)這個(gè)網(wǎng)站進(jìn)行描述, 并邀請(qǐng)用戶注冊(cè)或登陸.
用戶登陸后, 就可以創(chuàng)建新主題/添加新條目以及閱讀既有的條目.
實(shí)戰(zhàn)步驟
python示例程序修改
:notebook:
針對(duì)Django應(yīng)用需要修改的代碼其實(shí)不多, 都集中在
settings.py中.
刪除heroku部署的相關(guān)代碼: https://github.com/east4ming/learning_log/commit/1119c62d33766538601a711a4473f0ab64dd8f3e
-
Django
settings.py文件修改內(nèi)容:修改
ALLOW_HOSTS為*(配置為*, 表示允許所有hosts, 如果不配置, OpenShift自動(dòng)分配的域名和地址會(huì)無法訪問python示例程序): https://github.com/east4ming/learning_log/commit/534c1283eb9c430c1739d71ce0984cee6c776d04DJANGO SECRET 改為通過系統(tǒng)變量(
os.getenv方式)獲取 (OpenShift的原模板 Django + PostgreSQL 包含這一變量): https://github.com/east4ming/learning_log/commit/dd6695db345c333f1d193261fef3a35a2b926c97-
修改
DATABASES相關(guān)代碼, 改為兼容sqlite和postgresql. https://github.com/east4ming/learning_log/commit/5dceef61b999cfe0abc45ed371f487c2e428a4c6 新增的database.py(settings.py的DATABASES部分調(diào)用該文件)代碼如下:import os from django.conf import settings engines = { 'sqlite': 'django.db.backends.sqlite3', 'postgresql': 'django.db.backends.postgresql_psycopg2', } def config(): service_name = os.getenv('DATABASE_SERVICE_NAME', '').upper().replace('-', '_') if service_name: engine = engines.get(os.getenv('DATABASE_ENGINE'), engines['sqlite']) else: engine = engines['sqlite'] name = os.getenv('DATABASE_NAME') if not name and engine == engines['sqlite']: name = os.path.join(settings.BASE_DIR, 'db.sqlite3') return { 'ENGINE': engine, 'NAME': name, 'USER': os.getenv('DATABASE_USER'), 'PASSWORD': os.getenv('DATABASE_PASSWORD'), 'HOST': os.getenv('{}_SERVICE_HOST'.format(service_name)), 'PORT': os.getenv('{}_SERVICE_PORT'.format(service_name)), }
-
(可選) 添加OpenShift相關(guān)腳本,變量: https://github.com/east4ming/learning_log/commit/095a59973bc6a6c5886f3debf56dde16e4ef2f96
-
conf/reload.py 用于
APP_CONFIG變量, 可以調(diào)整WSGI相關(guān)配置. - openshift/scripts/run-in-container.sh 用于在openshift的部署容器中較為方便地運(yùn)行一些命令(如創(chuàng)建超級(jí)用戶等)(不用該腳本, 直接進(jìn)行容器用shell命令行也是一樣的效果)
-
conf/reload.py 用于
針對(duì)OpenShift 模板Django + PostgreSQL進(jìn)行修改生成新模板
:notebook:
關(guān)于 OpenShift Templates(模板)的說明, 請(qǐng)參見: https://docs.openshift.com/container-platform/3.11/dev_guide/dev_tutorials/quickstarts.html
模板簡(jiǎn)介
模板由一組服務(wù)(service),構(gòu)建配置(build config)和部署配置(deployment config)構(gòu)成。模板引用必要的鏡像和源存儲(chǔ)庫來構(gòu)建和部署應(yīng)用程序。
順便簡(jiǎn)單介紹一下模板編寫時(shí)的相關(guān)參數(shù):
簡(jiǎn)單模板示例:
apiVersion: v1
kind: Template
metadata:
name: redis-template
annotations:
description: "Description"
iconClass: "icon-redis"
tags: "database,nosql"
objects:
- apiVersion: v1
kind: Pod
metadata:
name: redis-master
spec:
containers:
- env:
- name: REDIS_PASSWORD
value: ${REDIS_PASSWORD}
image: dockerfile/redis
name: master
ports:
- containerPort: 6379
protocol: TCP
parameters:
- description: Password used for Redis authentication
from: '[A-Z0-9]{8}'
generate: expression
name: REDIS_PASSWORD
labels:
redis: master
描述
模板描述告知用戶模板的功能,并幫助他們?cè)赪eb控制臺(tái)中搜索時(shí)找到它。模板名稱之外的其他元數(shù)據(jù)是可選的,但有用。除了一般描述性信息之外,元數(shù)據(jù)還包括一組標(biāo)簽(label)。有用的標(biāo)簽包括模板與之相關(guān)的語言的名稱(例如, java,php,ruby等)。
見上文代碼片段的
metadata部分.
標(biāo)簽
模板可以包含一組 標(biāo)簽。這些標(biāo)簽將添加到實(shí)例化模板時(shí)創(chuàng)建的每個(gè)對(duì)象。以這種方式定義標(biāo)簽使用戶可以輕松查找和管理從特定模板創(chuàng)建的所有對(duì)象。
見上文代碼片段的
labels部分.
參數(shù)
參數(shù)允許值由用戶提供或在實(shí)例化模板時(shí)生成。然后,只要引用參數(shù),該值就會(huì)被替換??梢栽趯?duì)象列表字段的任何字段中定義引用。這對(duì)于生成隨機(jī)密碼或允許用戶提供自定義模板所需的主機(jī)名或其他特定于用戶的值非常有用??梢酝ㄟ^兩種方式引用參數(shù):
- 通過在模板中的任何字符串字段中以${PARAMETER_NAME}形式放置值來作為字符串值。
- 作為json / yaml值,通過在${{PARAMETER_NAME}}格式中放置值代替模板中的任何字段。
見上文代碼片段的
parameters部分.
對(duì)象列表
模板的主要部分是在實(shí)例化模板時(shí)將創(chuàng)建的對(duì)象列表。這可以是任何 有效的API對(duì)象,例如 BuildConfig,DeploymentConfig,Service等。該對(duì)象將被精確地創(chuàng)建為這里所定義,和在之前的創(chuàng)建取代的任何參數(shù)值。這些對(duì)象的定義可以引用先前定義的參數(shù).
見上文代碼片段的
objects部分.
修改模板并導(dǎo)入
:notebook:
針對(duì)python的官方quickstart模板有3個(gè):
- django (1個(gè)pod, 數(shù)據(jù)庫使用sqlite)
- django + postgresql (2個(gè)pod, 數(shù)據(jù)庫使用postgresql, 但是數(shù)據(jù)庫數(shù)據(jù)沒有持久化)
- django + postgresql persistent (2個(gè)pod, 數(shù)據(jù)庫使用postgresql, 數(shù)據(jù)庫數(shù)據(jù)進(jìn)行持久化)
本次使用第三個(gè), 源模板鏈接:django-postgresql-persistent.json
順便說明一下, 模板文件幾百行, 看起來挺嚇人的, 但是實(shí)際上大部分都是自動(dòng)生成的. 可以通過CLI等工具生成, 或者對(duì)現(xiàn)成的模板做微調(diào).
修改后的模板django-postgresql-persistent.json. 部分說明:
- 本次模板共創(chuàng)建了以下幾類對(duì)象:
-
Secret- 密鑰對(duì)象(存儲(chǔ)加密信息, 本例中存儲(chǔ): 數(shù)據(jù)庫用戶名和密碼, django secret key) -
Service- 服務(wù)(容器內(nèi)端口對(duì)外暴露并提供負(fù)載均衡). 這個(gè)模板有2個(gè):- django應(yīng)用的
Service - postgresql數(shù)據(jù)庫的
Service(提供給django使用)
- django應(yīng)用的
-
Route- 路由(對(duì)外暴露提供服務(wù), 通常是域名) -
ImageStream- 鏡像流(OpenShift特有, 定義如何構(gòu)建該應(yīng)用, 包含: 代碼庫地址, 基礎(chǔ)鏡像等信息) -
DeploymentConfig- 部署配置(包含: pod數(shù)量及重啟策略, 可用性探針, 運(yùn)行時(shí)環(huán)境變量, 資源閑置等信息)- django 應(yīng)用的DC
- postgresql 數(shù)據(jù)庫的DC
-
PersistentVolumeClaim- 持久性存儲(chǔ)聲明(包含: 存儲(chǔ)大小/讀寫的聲明)
-
- 新增內(nèi)容:
- 新增
env和參數(shù):ENABLE_PIPENV(這個(gè)參數(shù)基礎(chǔ)鏡像就有, 這兒列出來設(shè)置為true使之生效)
- 新增
- 修改內(nèi)容:
- 根據(jù)自己的代碼倉(cāng)庫信息, 對(duì)參數(shù)的默認(rèn)值做了部分修改. (可選, 不修改也行, 填的時(shí)候手動(dòng)填寫也可以)
- git倉(cāng)庫相關(guān)信息
- pip index url信息(只有使用pip方式才生效, 因?yàn)槲矣玫氖莗ipenv方式, 實(shí)際上沒生效) - 改為阿里的源.
- 基礎(chǔ)鏡像從python3.5改為了3.6(沒啥影響, 只因?yàn)槲冶镜赜玫谋容^新)
- 對(duì)Django pod的可用性探針 -
readinessProbe和livenessProbe進(jìn)行了修改, 改為了自己的測(cè)試URI(就是/), 另外超時(shí)時(shí)間放長(zhǎng)一點(diǎn).
- 根據(jù)自己的代碼倉(cāng)庫信息, 對(duì)參數(shù)的默認(rèn)值做了部分修改. (可選, 不修改也行, 填的時(shí)候手動(dòng)填寫也可以)
- 修改完之后, 導(dǎo)入該模板到OpenShift:
oc create -f .\openshift\templates\django-postgresql-persistent.json(也可以通過UI導(dǎo)入: Catalog → Custom Add → Import YAML/JSON)
構(gòu)建 部署并驗(yàn)證應(yīng)用
-
在OpenShift 的 Catalog頁面點(diǎn)擊新導(dǎo)入的模板 - Learning Log. 如下圖:
OpenShift Catalog
-
點(diǎn)擊Next:
OpenShift Template Info
-
填寫相關(guān)的配置信息:
OpenShift Template Conf

-
點(diǎn)擊Create. 會(huì)自動(dòng)創(chuàng)建django-psql-persistent應(yīng)用. 此時(shí), OpenShift會(huì)進(jìn)行如下的動(dòng)作:
創(chuàng)建PVC
創(chuàng)建Secret
-
創(chuàng)建Build 流程, 我是之前有部分代碼有問題, 或者連不上pipenv的源, 構(gòu)建了4次才成功. (構(gòu)建也是會(huì)啟動(dòng)一個(gè)專門的構(gòu)建容器, 構(gòu)建成功后輸出一個(gè)構(gòu)建后部署的鏡像, 同時(shí)構(gòu)建鏡像自動(dòng)銷毀). 對(duì)于: python pipenv django, build流程大致如下:
- 下載pipenv及相關(guān)依賴包(如virtualenv等)
- pipenv根據(jù)
Pipfile.lock安裝應(yīng)用所需依賴包 - Django執(zhí)行static文件移動(dòng)和數(shù)據(jù)庫migrate.
- 推送build完成的鏡像到鏡像庫
OpenShift
-
Deployment部署應(yīng)用, 包括: postgresql和django應(yīng)用鏡像. (pod那個(gè)圈是藍(lán)色就是成功了)
OpenShift Template Deploy
- 最終部署成功后, 在OpenShift上的Overview顯示如下:

-
通過上圖的URL訪問: http://django-psql-persistent-learning-log.192.168.2.6.nip.io/
OpenShift Learning Log
更多細(xì)節(jié)展示:
容器的環(huán)境變量:

容器的日志:

容器的終端:

應(yīng)用的services:

應(yīng)用的route:

:thinking:感悟
K8S概念就很復(fù)雜了, OpenShift又在這上面添加了很多新概念, 比如: build, S2I, ImageStream ... 真的不容易理解.
還有就是其實(shí)開發(fā)人員需要頻繁調(diào)試, 修改代碼, 每次修改都得走一遍CI/CD流程. 真的挺耗時(shí)的.
目前OpenShift這種容器平臺(tái)還是需要進(jìn)一步提升易用性, 畢竟, 開發(fā)人員更多精力的是要放在寫代碼上, 構(gòu)建部署越便捷越簡(jiǎn)單越好.
道阻且長(zhǎng)啊.





