1. 程式人生 > >Alodi:為了保密我開發了一個系統

Alodi:為了保密我開發了一個系統

每天都在愉快的造輪子,這次可以一鍵建立測試環境

咖啡君維護了幾十個不同型別專案,其中有相當一部分專案是對保密性有很高要求的,也就是說下個版本要上線的內容是不能提前洩露的,就像蘋果新產品的介紹網站決不允許在產品釋出之前流出一樣,這種保密內容除了在制度上加以約束外,還需要一些技術手段來保障

本次要介紹的Aloid系統就對保密有著一定的作用,這個系統的主要作用是快速生成臨時環境,這個臨時環境會有一定的有效期,過期自動清除,當然你也可以手動清除,同時這個環境會有唯一的隨機訪問地址,只有知道這個隨機地址的人才能訪問

涉及技術

整個專案基於Django構建,前後端框架程式碼可以通過這篇文章獲取,通過框架程式碼可以快速構建專案,新增自己需要的功能,需要說明的是框架程式碼並非這個專案原始碼

subprocess

編譯部署難免要跟系統命令打交道,在調研了幾種python執行系統命令的方法後選擇了subprocess,subprocess作為os.systemos.popen的替代模組,功能更為強大,且為python自帶模組,不需額外安裝,使用方便

在需要頻繁執行系統命令的情況下,可以寫一個類似下邊這樣的方法封裝命令執行和返回輸出,使程式碼簡潔易讀

import shlex, subprocess

def runCmd(tid, msg, cmd):
    try:
        p = subprocess.Popen(shlex.split(cmd), stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        while p.poll() == None:
            out = p.stdout.readline().strip()
            if out:
                print('---->' + out.decode())

        res = ' 失敗 ~_~' if p.returncode else ' 完成 ^_^'
        print('---->' + msg + res)

        return p.returncode
    except Exception as e:
        print('---->Shell Exec Error:%s' % str(e))
        return 999

kubernetes-api

所有環境跑在kubernetes之上,建立或銷燬臨時環境都需要與kubernetes做互動,我選擇了使用kubernetes python sdk來完成

from kubernetes import client, config

class KubeApi:
    def __init__(self, namespace='alodi'):
        config.load_kube_config("/ops/coffee/kubeconfig.yaml")
        self.namespace = namespace

    def create_deployment(self, RAND, PROJ, ENVT):
        api_instance = client.AppsV1Api()
        body = client.V1Deployment(
            api_version="apps/v1",
            kind="Deployment",
            metadata=client.V1ObjectMeta(name=RAND),
            spec=client.V1DeploymentSpec(
                replicas=1,
                selector={'matchLabels': {'app': RAND}},
                template=client.V1PodTemplateSpec(
                    metadata=client.V1ObjectMeta(labels={"app": RAND}),
                    spec=client.V1PodSpec(
                        containers=[client.V1Container(
                            name=RAND,
                            image="k8s-harbor.blz.netease.com/alodi/" + RAND,
                            env=[{"name": "ENVT", "value": ENVT}, {"name": "PROJ", "value": PROJ}],
                            ports=[client.V1ContainerPort(container_port=80)],
                        )]
                    )
                ),
            )
        )

        try:
            r = api_instance.create_namespaced_deployment(
                namespace=self.namespace, body=body
            )

            return True, "Deployment created: %s" % r
        except Exception as e:
            return False, 'Deployment created: ' + str(e)

    def delete_deployment(self, RAND):
        api_instance = client.AppsV1Api()
        body = client.V1DeleteOptions(
            propagation_policy='Foreground',
            grace_period_seconds=5)

        try:
            r = api_instance.delete_namespaced_deployment(
                namespace=self.namespace,
                name=RAND,
                body=body
            )

            return True, "Deployment deleted. %s" % r
        except Exception as e:
            return False, 'Deployment deleted: ' + str(e)

load_kube_config載入的配置檔案為kubernetes主伺服器上的~/.kube/config檔案,這個檔案內包含了叢集相關資訊,通過這個配置檔案可以免認證操作叢集修改資源,要妥善保管這個配置檔案,當然也可以通過token的方式自己實現認證

另外需要特別注意的是sdk的版本與kubernetes的版本有對應關係,且不同資源的操作對kubernetes的api版本要求也不同,使用時多參考官方文件

介於篇幅原因這裡只貼了兩個deployment的操作示例,其他更多示例可以單獨找我獲取

介面展示

整個專案除了使用者管理之類的常規頁面外,主要有三個頁面構成,由這三個頁面完成了主要流程的執行和展示

專案管理頁:在這個頁面內可以新建、編輯和刪除專案

同時也可以在專案管理頁建立臨時環境,這裡主要選擇使用的資料環境和程式碼TAG

當填寫相關資訊點選Build & Deploy按鈕後會跳轉到任務詳情頁,這個頁面實時展示部署過程的日誌輸出,右上角有個爬蟲的按鈕,可以終止部署

部署列表頁:可以在部署列表頁檢視到部署歷史記錄,當這個環境正在執行時可以點選銷燬按鈕來銷燬專案,清除kubernetes的資源佔用

寫在最後

  1. 我們寫了很多專案,也造了很多輪子,目的都是為了讓我們的工作更輕鬆,達到“一杯咖啡、輕鬆運維”的願景
  2. 專案程式碼暫不開源,但專案裡邊用到的技術大都有專門的文章介紹,文章都附帶有程式碼,有些甚至提供有Demo,完全可以快速搞定自己的需求
  3. 如果有任何問題歡迎與我聯絡,一起溝通交流,共同成長,期待加我好友~

相關文章推薦閱讀: