基于Rainbond開發(fā)Python云原生應(yīng)用

組件開發(fā)

這里使用 基于源碼中的 Dockerfile 創(chuàng)建組件,因為這種方式能兼容所有類型的項目炬灭。

識別為 Dockerfile 類型的源碼將使用類似于 docker build -t xxx/xxx . 的命令進行鏡像構(gòu)建碰声,因此此方式是靈活性最高的源碼編譯方式

基本結(jié)構(gòu)

Python 云原生應(yīng)用的基本目錄結(jié)構(gòu)如下蔬芥,由 app.py(主程序)格了、Dockerfile(容器配置)和 requirements.txt(依賴關(guān)系)三個文件組成售淡。

.
├── app.py
├── Dockerfile
├── requirements.txt

app.py

最簡單理张、且符合 RESTfulPython Flask 主程序如下:

import json
from flask import Flask, request
from rainbond_python.parameter import Parameter
from rainbond_python.error_handler import error_handler

app = Flask(__name__)
error_handler(app)

@app.route('/demo/1.0/api', methods=['GET', 'POST', 'PUT', 'DELETE'])
def api():
    parameter = Parameter(request)

    if parameter.method == 'GET':
        return json.dumps(parameter.param_url, ensure_ascii=False), 200, []

    elif parameter.method == 'POST':
        return json.dumps(parameter.param_json, ensure_ascii=False), 200, []

    elif parameter.method == 'PUT':
        return json.dumps(parameter.param_json, ensure_ascii=False), 200, []

    elif parameter.method == 'DELETE':
        return json.dumps(parameter.param_json, ensure_ascii=False), 200, []

if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True)

requirements.txt

這個通用的 Python 項目的依賴文件析藕,根據(jù)上面的示例代碼召廷,我們的依賴如下:

Flask
gunicorn
rainbond-python

Dockerfile

這個通用的 Dockerfile 是用來構(gòu)建鏡像的文本文件,內(nèi)容包含了一條條構(gòu)建 Docker 鏡像所需的指令账胧,基于上面的示例代碼竞慢,我們的容器配置如下:

FROM python:3.8.7
WORKDIR /app
ADD . /app
RUN pip install -i https://mirrors.aliyun.com/pypi/simple/ --no-cache-dir -r requirements.txt
CMD ["gunicorn", "app:app", "-b", "0.0.0.0:8000", "--log-file", "-", "--access-logfile", "-", "--error-logfile", "-"]
EXPOSE 8000

組件調(diào)試

在不同的階段(開發(fā)、測試找爱、發(fā)布)中梗顺,我們可以使用不同的方式對組件進行調(diào)試,這些調(diào)試可以確保組件在 Rainbond 云原生平臺上被正確部署车摄。

# 開發(fā)調(diào)試
$ python3 app.py
# 測試調(diào)試
$ pip3 install -r requirements.txt
$ gunicorn app:app
# 發(fā)布調(diào)試
$ docker build -t devdocker .
$ docker run devdocker

部署組件

首先創(chuàng)建好 團隊應(yīng)用寺谤,并進入到應(yīng)用視圖中,選擇 “+ 添加組件”吮播,如下圖:

使用源碼添加組件.png

點擊 “自定義倉庫”变屁,填入 Git 倉庫地址,如果組件是統(tǒng)一管理在同一個倉庫中意狠,我們可以通過 “填寫子目錄路徑” 來指定組件所在目錄粟关,如下圖:

填寫Git倉庫地址.png

最后點擊 “新建組件” 就可以快速開始部署組件。

組件訪問策略

在組件需要 被外部訪問 時环戈,如果是企業(yè)內(nèi)網(wǎng)部署闷板,我們還需要配置組件的訪問策略澎灸,進入應(yīng)用視圖中,選擇 “網(wǎng)關(guān) > 訪問策略管理” 遮晚,如下圖:

訪問策略管理.png

找到我們剛才創(chuàng)建的組件性昭,點擊 “編輯”,并按照什么示例代碼的內(nèi)容進行配置县遣,如下圖:

編輯Http訪問策略.png

特別要注意糜颠,“域名” 要填寫一個配置好內(nèi)網(wǎng)解析的域名地址,這樣萧求,便可以通過 xxxxxx.xxxx.com/demo/1.0/api 訪問到組件的服務(wù)其兴。

數(shù)據(jù)存儲

在 Python 云原生開發(fā)實踐中,推薦使用 MongoDB 數(shù)據(jù)庫夸政,因此我們可以從 Docker Hub 獲取 MongoDB Docker 鏡像元旬。

添加存儲組件

首先進入到應(yīng)用視圖中,選擇 “+ 添加組件”守问,并選擇 “從源鏡像開始 > 指定鏡像”法绵,然后在 “鏡像地址” 欄輸入 mongo,如下圖:

添加存儲組件.png

點擊創(chuàng)建酪碘,接下來 Rainbond 就會開始自動部署 MongoDB 存儲組件。(PS:如果在內(nèi)網(wǎng)環(huán)境下盐茎,請耐心等待……)

配置存儲組件

首先兴垦,我們要明確我們是在開發(fā) 云原生 項目,數(shù)據(jù)庫是可選項字柠,所以探越,就算沒有這個可選項,我們的組件也不能因為這個異常窑业,而導(dǎo)致程序崩潰钦幔。

在云原生的體系中,數(shù)據(jù)庫是一個獨立的組件常柄,是原生運行在容器云平臺里的一個分布式數(shù)據(jù)庫鲤氢,真正做到了存儲和計算的完全分離

在 MongoDB 組件的 依賴 > 端口列表 中找到 27017 端口,開放 “對內(nèi)服務(wù)”西潘,修改 “使用別名” 為 MONGODB卷玉,如下圖:

編輯MongoDB別名.png

通過上一步,就可以在 依賴 > 組件連接信息 中看到 MONGODB_HOSTMONGODB_PORT 兩個變量喷市,分別是 MongoDB 組件的連接地址和端口號信息相种。

依賴存儲組件

計算組件存儲組件 分離的情況下,計算組件 需要通過 存儲組件依賴 > 組件連接信息 中的數(shù)據(jù)庫連接信息來訪問 存儲組件品姓。

計算組件 視圖的的 依賴 > 依賴組件信息 下寝并,選擇 “+ 添加依賴”箫措,并添加我們安裝在應(yīng)用內(nèi)的 存儲組件,如圖所示:

依賴存儲組件.png

接下來衬潦,我們就可以在 計算組件 中斤蔓,通過環(huán)境變量,獲取 存儲組件 的組件連接信息别渔。

操作數(shù)據(jù)庫

計算組件app.py(主程序)文件中附迷,可以簡單實現(xiàn)一個對 MongoDB 數(shù)據(jù)庫的讀取、寫入的示例:

import json
from flask import Flask, request
from rainbond_python.parameter import Parameter
from rainbond_python.db_connect import DBConnect

app = Flask(__name__)
db = DBConnect(db='demo', collection='test')

@app.route('/demo/1.0/api', methods=['GET', 'POST'])
def api():
    parameter = Parameter(request)

    if parameter.method == 'GET':
        cursor = db.mongo_collection.find()
        if not db.mongo_collection.estimated_document_count():
            return '資源為空', 204, []
        data = list(cursor)
        return str(data), 200, []

    elif parameter.method == 'POST':
        if parameter.verification(checking=parameter.param_json, verify={'name': str, 'age': int}):
            param = parameter.param_json
            insert_dict = {'name': param['name'], 'age': param['age']}
            if db.write_one_docu(docu=insert_dict):
                return '新資源被創(chuàng)建', 201, []
            else:
                return '資源無法被創(chuàng)建', 500, []
        else:
            return '請求參數(shù)錯誤', 400, []

if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True)

上面代碼中哎媚,并沒有出現(xiàn)獲取 存儲組件 連接信息的代碼喇伯,因為這部分內(nèi)容已經(jīng)被 rainbond-python 所封裝,其中 DBConnect 的初始化代碼片段如下:

import os
……
class DBConnect():
    def __init__(self, db: str, collection: str, home_kye='MONGODB_HOST', port_kye='MONGODB_PORT'):
        self.mongo_home = os.environ.get(home_kye, None)
        self.mongo_port = os.environ.get(port_kye, 27017)
……

可以看到拨与,home_kyeport_kye 的默認值對應(yīng)的正是 MONGODB_HOSTMONGODB_PORT稻据,當我們沒有賦值時,它自動會讀取這兩個環(huán)境變量买喧。

開發(fā)細節(jié)

在環(huán)境中存儲配置

按照 12-factors 的第 III 條:在環(huán)境中存儲配置捻悯。我們需要把組件的配置信息存儲在環(huán)境中,在 Dockerfile(容器配置)文件中淤毛,我們添加兩個配置信息:

……
ENV SPEECH_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
ENV SERVICE_REGION=eastus
……

這樣配置后今缚,當組件部署到 Rainbond 云原生平臺后,這兩個環(huán)境配置會出現(xiàn)到組件視圖的 “環(huán)境配置” 標簽頁低淡,如下圖所示:

在環(huán)境中存儲配置.png

然后我們只需要在組件的代碼文件中姓言,通過下列代碼,即可讀取到這些配置信息:

import os
……
speech_key = os.environ.get('SPEECH_KEY', None)
service_region = os.environ.get('SERVICE_REGION', None)
……

容器中安裝依賴

有時候蔗蹋,默認的 Docker 容器里會缺少組件運行必須的依賴何荚,這時我們就需要配置安裝命令,例如猪杭,我們在 Dockerfile(容器配置)文件里編寫系統(tǒng)庫 libasound2 的安裝命令:

……
RUN apt-get update
RUN apt-get install -y libasound2
……

這樣餐塘,我們就可以缺啥補啥。

在開發(fā)機上配置環(huán)境變量

在本地開發(fā)時皂吮,我們就需要在開發(fā)機配置組件需要的環(huán)境變量戒傻,以 Ubuntu 開發(fā)機為例,通過 vim /etc/profile 打開系統(tǒng)環(huán)境變量文件涮较,并在最后加入新的環(huán)境變量稠鼻,例如:

export KEY=VALUE

然后保存文件,并通過 source /etc/profile 使編輯的配置生效狂票,還可以通過 export 查看當前系統(tǒng)的環(huán)境變量候齿,再確認一遍環(huán)境變量添加成功。

前端組件的打包腳本

如果是 React 前端項目,那么 Dockerfile(容器配置)文件可以參考下面代碼:

FROM node:lts
WORKDIR /app
ADD . /app
RUN npm install
RUN npm run build
RUN npm install -g http-server
CMD ["http-server", "./build", "-p", "6001", "-a"]
EXPOSE 6001

大致過程是:安裝Node穩(wěn)定鏡像 > 初始化項目 > 構(gòu)建項目 > 安裝http-server庫 > 運行項目慌盯,很簡單的周霉。

查看組件容器日志

如果要查看 Rainbond 部署的組件日志,我們要知道 K8s 與 Rainbond 的關(guān)系:NAMESPACE=團隊/集群亚皂、POD=應(yīng)用俱箱、Docker=組件。所以灭必,我們要查看日志的時候狞谱,基本就是查看K8s日志的路數(shù):

# 登錄集群主節(jié)點服務(wù)器
ssh -p22 xxxx@xxx.xxx.x.xxx
# 查看POD
kubectl get pod -A -o wide
# 查看某一個POD中容器的日志(一)
kubectl -n [NAMESPACE] logs --tail=100 [POD] [Docker]
# 查看某一個POD中容器的日志(二)
kubectl -n [NAMESPACE] logs -f [POD] [Docker]

其中,NAMESPACE 和 POD 的位置在下圖位置中:

命令空間與POD.png

而 Docker 則在 Rainbond 上查看禁漓,如下圖:

Rainbond中的容器ID.png

這樣就可以直接查看最原始的日志信息跟衅。

處理前端組件跨域問題

我們可以把 API 服務(wù)組件、前端 UI 組件通過同一個域名進行解析播歼,如下圖:

根本上解決跨域問題.png

這樣伶跷,哪里還會出現(xiàn)什么跨域問題。

提前構(gòu)建好基礎(chǔ)鏡像

如果構(gòu)建過程太慢秘狞,比如構(gòu)建一次要好幾分鐘叭莫,那么我們可以提前把一些環(huán)境構(gòu)建過程制作成基礎(chǔ)鏡像,只要構(gòu)建過程會加快很多烁试。

# 本地構(gòu)建鏡像
$ docker build -t demo .
# 給鏡像打tag
$ docker tag [IMAGE ID] [私有hub域名]/[項目名稱]/demo:latest
# 推送到私有hub倉庫
$ docker push [私有hub域名]/[項目名稱]/demo:latest

然后將 Dockerfile(容器配置)文件的第一行改為:

FROM [私有hub域名]/[項目名稱]/demo:latest

這樣雇初,原本可能要幾分鐘的構(gòu)建過程,現(xiàn)在只需要幾十秒就可以完成减响,非常棒抵皱!

模擬服務(wù)器環(huán)境調(diào)試

在云原生平臺部署組件之前,最好模擬服務(wù)器環(huán)境在本地測試一下:

# 本地構(gòu)建鏡像
$ docker build -t demo .
# 查看打包的鏡像
$ docker images
# 運行鏡像
$ docker run -p 6008:6008 demo
# 運行鏡像(指定環(huán)境變量)
$ docker run -e "KEY=xxx" -p 6008:6008 demo
# 運行鏡像(后臺運行)
$ docker run -d -p 6008:6008 demo
# 查看運行中的容器
$ docker ps
# 暫停運行中的容器
$ docker stop <CONTAINER ID>
# 關(guān)閉運行中的容器
$ docker rm <CONTAINER ID>
# 刪除鏡像
$ docker rmi <IMAGE ID>

這樣可以避免在云原生平臺不方便調(diào)試的問題辩蛋。

查看網(wǎng)關(guān)容器Nginx配置

在 Rainbond 平臺配置網(wǎng)關(guān)后,可以進入網(wǎng)關(guān)容器移盆,查看配置的域名規(guī)則生成的 Nginx 配置是否正確:

# 找到網(wǎng)關(guān)容器的NAME
$ kubectl get pod -A -o wide
# 進入網(wǎng)關(guān)容器
$ kubectl -n rbd-system exec -it <網(wǎng)關(guān)容器NAME> bash
# 輸出default_servers.conf內(nèi)容
$ cat /run/nginx/conf/http/default/default_servers.conf
# 退出網(wǎng)關(guān)容器
$ exit

這樣就可以確認 Rainbond 平臺配置的網(wǎng)關(guān)規(guī)則是否正確悼院。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市咒循,隨后出現(xiàn)的幾起案子据途,更是在濱河造成了極大的恐慌,老刑警劉巖叙甸,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件颖医,死亡現(xiàn)場離奇詭異,居然都是意外死亡裆蒸,警方通過查閱死者的電腦和手機熔萧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人佛致,你說我怎么就攤上這事贮缕。” “怎么了俺榆?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵感昼,是天一觀的道長。 經(jīng)常有香客問我罐脊,道長定嗓,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任萍桌,我火速辦了婚禮宵溅,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘梗夸。我一直安慰自己层玲,他們只是感情好,可當我...
    茶點故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布反症。 她就那樣靜靜地躺著辛块,像睡著了一般。 火紅的嫁衣襯著肌膚如雪铅碍。 梳的紋絲不亂的頭發(fā)上润绵,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天,我揣著相機與錄音胞谈,去河邊找鬼尘盼。 笑死,一個胖子當著我的面吹牛烦绳,可吹牛的內(nèi)容都是我干的卿捎。 我是一名探鬼主播,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼径密,長吁一口氣:“原來是場噩夢啊……” “哼午阵!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起享扔,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤底桂,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后惧眠,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體籽懦,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年氛魁,在試婚紗的時候發(fā)現(xiàn)自己被綠了暮顺。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片厅篓。...
    茶點故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖拖云,靈堂內(nèi)的尸體忽然破棺而出贷笛,到底是詐尸還是另有隱情,我是刑警寧澤宙项,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布乏苦,位于F島的核電站,受9級特大地震影響尤筐,放射性物質(zhì)發(fā)生泄漏汇荐。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一盆繁、第九天 我趴在偏房一處隱蔽的房頂上張望掀淘。 院中可真熱鬧,春花似錦油昂、人聲如沸革娄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽拦惋。三九已至,卻和暖如春安寺,著一層夾襖步出監(jiān)牢的瞬間厕妖,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工挑庶, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留言秸,地道東北人。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓迎捺,卻偏偏與公主長得像举畸,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子凳枝,可洞房花燭夜當晚...
    茶點故事閱讀 42,828評論 2 345

推薦閱讀更多精彩內(nèi)容