華為云 K8S 稱 CCE -- Cloud Container Engine魁索。我們部署 Byzer-lang , Byzer-Notebook。版本如下:
byzer-lang-k8s:3.3.0-2.4.0-SNAPSHOT
byzer-notebook:1.2.3
我們將需要以下華為云資源:
VPC 虛擬網(wǎng)絡(luò):部署其他云資源胳蛮。
CCE (K8S 集群): 部署 Byzer-Notebook Byzer-lang
RDS for MySQL: 存儲(chǔ) Byzer-Notebook 元數(shù)據(jù)
OBS:對(duì)象存儲(chǔ)资柔,作為 Byzer-lang 的存儲(chǔ)蛮放。
另外,華為 ELB Ingress Controller 需要一個(gè)域名隧膏,因國(guó)內(nèi)需要備案哗讥,請(qǐng)事先準(zhǔn)備。
創(chuàng)建 VPC
為簡(jiǎn)單起見胞枕,僅創(chuàng)建一個(gè)子網(wǎng)杆煞,網(wǎng)段為 192.168.0.0/24。K8S 集群腐泻,RDS for MySQL, SNAT , ELB 都部署在該 VPC决乎。
創(chuàng)建 K8S 集群
參考華為云文檔, 創(chuàng)建K8S 集群派桩。
設(shè)置客戶機(jī)构诚,以連接K8S 集群
有兩者方式, CloudShell 和客戶機(jī),都通過 kubectl 命令操作铆惑。CloudShell 通過網(wǎng)頁范嘱,但有效期僅1天且當(dāng)前僅北京一、北京四员魏、上海一丑蛤、上海二、廣州和烏蘭察布一支持使用CloudShell登錄容器逆趋。我們選擇客戶機(jī)方式。
由于客戶機(jī)訪問 CCE 走公網(wǎng)晒奕,我們?yōu)?K8S APIServer 綁定一個(gè)公網(wǎng)地址闻书。首先參考文檔購(gòu)買公網(wǎng)IP。然后進(jìn)入CCE 詳情頁面脑慧,左下角為“連接信息”魄眉,可以看到公網(wǎng)地址為空。點(diǎn)擊"綁定"闷袒,選擇剛申請(qǐng)的公網(wǎng)IP坑律。
然后回到 CCE 列表頁。點(diǎn)擊“連接”圖標(biāo)囊骤,在彈出頁面下載 config 文件晃择。存為客戶機(jī)的~/.kube/config文件冀值。執(zhí)行命令:kubectl config use-context external
設(shè)置公網(wǎng)訪問上下文。執(zhí)行命令 kubectl cluster-info
宫屠,會(huì)輸出 CCE 集群的連接信息列疗。
創(chuàng)建 Namespace Role Service Account
登錄華為云portal,找到集群浪蹂,在頁面上點(diǎn)擊創(chuàng)建 namespace抵栈。然后設(shè)置客戶機(jī)的默認(rèn) Namespace
kubectl config set-context --current --namespace=byzer
創(chuàng)建 service account
kubectl create serviceaccount byzer -n byzer
創(chuàng)建 Role byzer-admin 并賦予它在 byzer namespace 高權(quán)限
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: byzer-admin
rules:
- apiGroups: [""]
resources: ["pods","deployments", "replicas", "secrets", "configmaps","services","ingresses"]
verbs: ["*"]
綁定 Service Account byzer 到 flag-qa namespace 的 role byzer-admin
kubectl create rolebinding byer-role-binding --role=byzer-admin --serviceaccount=byzer:byzer --namespace=byzer
創(chuàng)建 OBS Bucket
根據(jù) 華為云文檔-- 快速入門操作,可以得到一個(gè) OBS Bucket 和 AKSK坤次。Byzer-lang 將使用 AKSK 訪問 OBS Bucket古劲。
配置 SNAT
默認(rèn)情況,CCE 的 Node 無法訪問Internet缰猴,造成鏡像拉取失敗产艾。Byzer 也無法拉取公網(wǎng)數(shù)據(jù)。因而洛波,我們配置 SNAT 規(guī)則胰舆。
首先,申請(qǐng) NAT蹬挤,根據(jù)你的網(wǎng)絡(luò)流量選擇規(guī)格缚窿,并選擇與 CCE相同的VPC。然后焰扳,配置 SNAT 規(guī)則倦零。
使用場(chǎng)景:選擇 VPC - 虛擬私有云;網(wǎng)段: 選擇前面創(chuàng)建的 VPC 的網(wǎng)段吨悍。
彈性公網(wǎng)IP:選擇一個(gè)可用的扫茅,注意帶寬是否符合你的流量需求。若沒有公網(wǎng)IP育瓜,需要?jiǎng)?chuàng)建一個(gè)葫隙。
最后,點(diǎn)擊確定躏仇。生成的SNAT 規(guī)則如下:
使用容器鏡像服務(wù) SWR 管理鏡像
拉取境外的鏡像恋脚,有時(shí)很慢甚至失敗。 拉取鏡像時(shí)也可能碰到 registry-1.docker.io 限流焰手。搭建 SWR 可以較好解決這一問題糟描;也能節(jié)省一筆公網(wǎng)帶寬和流量費(fèi)用。
上傳鏡像
在華為云控制臺(tái)找到 SWR书妻,點(diǎn)擊創(chuàng)建組織船响,完成后,點(diǎn)擊上傳自有鏡像。首先见间,創(chuàng)建 byzer-lang 鏡像的 tar 包聊闯。命令 docker save byzer-lang-k8s:3.3.0-2.4.0-SNAPSHOT > ./byzer.tar.gz
然后使用客戶端上傳,跟著華為云文檔指引缤剧,先登錄馅袁,再上傳。
完成后荒辕,可以在 我的鏡像頁面看到新鏡像汗销。
制作拉取鏡像的憑證
默認(rèn)情況,私有SWR需要憑證才能拉取鏡像抵窒。我們參考 K8S 文檔
首先獲取憑證弛针,創(chuàng)建為 K8S Secrets 對(duì)象,最后在 Byzer-lang 的 helm chart 聲明李皇。
獲取憑證
根據(jù)華為文檔 - 獲取長(zhǎng)期有效登錄指令
獲得AKSK削茁,并執(zhí)行docker login命令登錄你的鏡像倉(cāng)庫(kù)。登錄成功后掉房,檢查~/.docker/config.json 茧跋,多了一條 SWR 的記錄。
創(chuàng)建 Secrets
執(zhí)行命令base64 ~/.docker/config.json
卓囚,得到編碼后的 憑證瘾杭。如果輸出有多行,請(qǐng)合并為一行哪亿。
創(chuàng)建一個(gè) yaml粥烁,base64 編碼的憑證填入data.dockerconfigjson。metadata.name請(qǐng)酌情替換蝇棉。
apiVersion: v1
kind: Secret
metadata:
name: ap-southeast-3-huaweicloud
namespace: byzer
data:
.dockerconfigjson: ewxxxxxxxxx
type: kubernetes.io/dockerconfigjson
部署 Byzer-lang
我們使用 helm 部署 byzer-lang 3.3.0-2.4.0-SNAPSHOT.
下載 byzer-lang chart 并解壓
wget https://download.byzer.org/k8s-helm/byzer-lang/nightly-build/byzer-lang-helm-charts-2.4.0-SNAPSHOT.tgz
編輯 values.yaml讨阻,填寫下面的參數(shù)后,執(zhí)行 helm install byzer-lang . -f ./values.yaml
部署至 K8S
K8S 集群地址
values.yaml 文件的 clusterUrl 參數(shù)為 K8S ApiServer 地址篡殷,Byzer 的 Spark Driver Pod 啟動(dòng)時(shí)讀取它钝吮,并申請(qǐng) Executor Pod。如果你的 K8S 集群不能訪問公網(wǎng)板辽,請(qǐng)勿填寫公網(wǎng)地址奇瘦。建議填寫私有地址,避免出錯(cuò)戳气。例子如下:
clusterUrl: https://192.168.0.3:5443
華為云 OBS
Byzer-lang 使用 obs 存儲(chǔ)數(shù)據(jù)链患。配置如下
fs:
cloud:
storage:
enabled: true
defaultFS: obs://obs-byzer-1/
obs.access.key: xxx
obs.secret.key: xxx
obs.endpoint: obs.ap-southeast-3.myhuaweicloud.com
obs.impl: org.apache.hadoop.fs.obs.OBSFileSystem
fs.defaultFS的格式是: obs://<obs-bucket-name>
巧鸭,根據(jù)實(shí)際情況修改瓶您。
fs.obs.access.key
和 fs.obs.secret.key
改成你的賬號(hào)的AKSK。fs.obs.endpoint
根據(jù)OBS 所處區(qū)域,有所不同呀袱,可以在OBS 概覽頁面查詢贸毕。例如:
鏡像
我們從上面配置的 SWR 拉取 Byzer-lang 鏡像。
imagePullSecrets:
- name: ap-southeast-3-huaweicloud
spark.
kubernetes.container.image.pullSecrets: ap-southeast-3-huaweicloud
image:
repository: swr.ap-southeast-3.myhuaweicloud.com/byzer/byzer-lang-k8s
pullPolicy: Always
# Overrides the image tag whose default is the chart appVersion.
tag: "3.3.0-latest"
DeltaLake
OBS 目前不支持 DeltaLake夜赵,報(bào)下面錯(cuò)誤明棍。我們關(guān)閉DeltaLake。
The error typically occurs when the default LogStore implementation, that
is, HDFSLogStore, is used to write into a Delta table on a non-HDFS storage system.
In order to get the transactional ACID guarantees on table updates, you have to use the
correct implementation of LogStore that is appropriate for your storage system.
See https://docs.delta.io/latest/delta-storage.html for details.
java.io.IOException: The error typically occurs when the default LogStore implementation, that
is, HDFSLogStore, is used to write into a Delta table on a non-HDFS storage system.
In order to get the transactional ACID guarantees on table updates, you have to use the
correct implementation of LogStore that is appropriate for your storage system.
See https://docs.delta.io/latest/delta-storage.html for details.
io.delta.storage.internal.LogStoreErrors.incorrectLogStoreImplementationException(LogStoreErrors.java:41)
io.delta.storage.HDFSLogStore.writeInternal(HDFSLogStore.java:94)
io.delta.storage.HDFSLogStore.write(HDFSLogStore.java:68)
org.apache.spark.sql.delta.storage.LogStoreAdaptor.write(LogStore.scala:414)
org.apache.spark.sql.delta.storage.DelegatingLogStore.write(DelegatingLogStore.scala:119)
org.apache.spark.sql.delta.OptimisticTransactionImpl.doCommit(OptimisticTransaction.scala:1194)
classpath
Classpath 包含Byzer-lang 插件寇僧,Byzer-lang 主類摊腋,訪問S3 OBS Azure ADLS 的jar 。
spark:
driver.extraClassPath: local:///home/deploy/byzer-lang/plugin/mlsql-assert-3.3_2.12-0.1.0-SNAPSHOT.jar:local:///home/deploy/byzer-lang/plugin/mlsql-excel-3.3_2.12-0.1.0-SNAPSHOT.jar:local:///home/deploy/byzer-lang/plugin/mlsql-ext-ets-3.3_2.12-0.1.0-SNAPSHOT.jar:local:///home/deploy/byzer-lang/plugin/mlsql-shell-3.3_2.12-0.1.0-SNAPSHOT.jar:local:///home/deploy/byzer-lang/plugin/mlsql-mllib-3.3_2.12-0.1.0-SNAPSHOT.jar:local:///home/deploy/byzer-lang/main/byzer-lang-3.3.0-2.12-2.4.0-SNAPSHOT.jar:local:///home/deploy/byzer-lang/libs/juicefs-hadoop-1.0.0.jar:local:///home/deploy/byzer-lang/libs/byzer-objectstore-obs-3.3_2.12-0.1.0-SNAPSHOT.jar:local:///home/deploy/byzer-lang/libs/byzer-objectstore-blob-3.3_2.12-0.1.0-SNAPSHOT.jar:local:///home/deploy/byzer-lang/libs/byzer-objectstore-s3-3.3_2.12-0.1.0-SNAPSHOT.jar
executor.extraClassPath: local:///home/deploy/byzer-lang/plugin/mlsql-assert-3.3_2.12-0.1.0-SNAPSHOT.jar:local:///home/deploy/byzer-lang/plugin/mlsql-excel-3.3_2.12-0.1.0-SNAPSHOT.jar:local:///home/deploy/byzer-lang/plugin/mlsql-ext-ets-3.3_2.12-0.1.0-SNAPSHOT.jar:local:///home/deploy/byzer-lang/plugin/mlsql-shell-3.3_2.12-0.1.0-SNAPSHOT.jar:local:///home/deploy/byzer-lang/plugin/mlsql-mllib-3.3_2.12-0.1.0-SNAPSHOT.jar:local:///home/deploy/byzer-lang/main/byzer-lang-3.3.0-2.12-2.4.0-SNAPSHOT.jar:local:///home/deploy/byzer-lang/libs/juicefs-hadoop-1.0.0.jar:local:///home/deploy/byzer-lang/libs/byzer-objectstore-obs-3.3_2.12-0.1.0-SNAPSHOT.jar:local:///home/deploy/byzer-lang/libs/byzer-objectstore-s3-3.3_2.12-0.1.0-SNAPSHOT.jar:local:///home/deploy/byzer-lang/libs/byzer-objectstore-blob-3.3_2.12-0.1.0-SNAPSHOT.jar
資源配置
Byzer-lang 的資源配置即Spark 的配置嘁傀。請(qǐng)根據(jù)需要修改下面參數(shù).
spark:
driver.memory: 8g
driver.cores: 2
driver.maxResultSize: 4g
executor.memory: 4g
executor.cores: 1
executor.instances: 1
創(chuàng)建 RDS for MySQL
登錄華為云兴蒸,在頂部搜索欄搜索”rds for mysql",并選中后细办,進(jìn)入 RDS for MySQL 頁面橙凳。再點(diǎn)擊右上角“購(gòu)買數(shù)據(jù)庫(kù)實(shí)例”。參考華為云文檔笑撞。注意虛擬私有云(VPC) 必須與 K8S (CCE)一致岛啸。數(shù)據(jù)庫(kù)版本建議 8.0 或者5.7。5.6 版本比較老茴肥,可能存在兼容性問題坚踩。由于僅保存 Byzer-Notebook 元數(shù)據(jù),存儲(chǔ)空間 100GB 足夠炉爆。
創(chuàng)建后堕虹,請(qǐng)使用 root 賬號(hào)創(chuàng)建一個(gè)數(shù)據(jù)庫(kù),可以取名“ notebook"芬首;并創(chuàng)建一個(gè) Byzer-Notebook 訪問 RDS for MySQL 的 用戶赴捞。
部署 Byzer-Notebook
使用 Helm chart 部署。先下載郁稍。解壓后赦政,按照下面的指引編輯 values.yaml ,并執(zhí)行helm install byzer-notebook . -f ./values.yaml
部署至 K8S
ingress
helm chart 內(nèi)置 Nginx Ingres controller耀怜,這里不使用恢着。配置如下:
ingress:
enabled: false
鏡像
從上文配置的 SWR 拉取鏡像,我的SWR 地址為:swr.ap-southeast-3.myhuaweicloud.com
财破。請(qǐng)修改為你實(shí)際的地址掰派。
image:
repository: swr.ap-southeast-3.myhuaweicloud.com/byzer/byzer-notebook
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: "1.2.3"
Service
本例子Service為 NodePort 型。如果你使用了華為云共享型 ELB左痢,請(qǐng)配置為 NodePort 類型Service靡羡,獨(dú)享型系洛,請(qǐng)配置為 ClusterIP 型 Service。
service:
type: NodePort
port: 9002
用戶數(shù)據(jù)隔離
不同 Byzer-Notebook 用戶的 的數(shù)據(jù)略步,例如上傳的文件描扯,將被隔離,意味著 用戶A 無法查看用戶 B 的數(shù)據(jù)趟薄。我們配置下面參數(shù):
notebook:
user.home: /work/data
這意味著用戶數(shù)據(jù)被存放在 Byzer-lang 的 /work/data/{user_name} 目錄下绽诚。對(duì)于本例子,意味著 OBS Bucket 上該前綴的對(duì)象杭煎。
Byzer-lang url
Byzer-Notebook 調(diào)用 Byzer-lang 的HTTP 接口恩够,執(zhí)行 SQL,獲取結(jié)果等羡铲。在 K8S 上我們配置為 Byzer-lang 的Service玫鸟。例如:
notebook.
mlsql.engine-url: http://byzer-lang-service.byzer:9003
其中 byzer-lang-service 是 Byzer-lang的service名稱,byzer 是 Namespace犀勒。9003 為 Service 的端口屎飘。
數(shù)據(jù)庫(kù)
使用剛創(chuàng)建的 RDS for MySQL。請(qǐng)根據(jù)你的實(shí)際情況填寫端口贾费,數(shù)據(jù)庫(kù)名钦购,IP,用戶名密碼褂萧。參考如下:
notebook:
database.port: 3306
database.name: notebook
database.ip: "192.168.0.188"
database.username: "notebook"
database.password: "notebook"
配置公網(wǎng)訪問 Byzer-Notebook
由于 Notebook Pod 和 Service 網(wǎng)絡(luò)地址都是私有網(wǎng)絡(luò)押桃,公網(wǎng)無法訪問。我們使用華為云 ELB (Elastic LoadBalancer) + ELB Ingress Controller 實(shí)現(xiàn)导犹。其原理如下:
然后唱凯,跟著華為云的文檔https://support.huaweicloud.com/usermanual-cce/cce_10_0251.html,創(chuàng)建 ELB 并配置 ELB Ingress Controller谎痢。由于價(jià)格因素磕昼,選擇共享型ELB 。路由規(guī)則如下所示:
Byzer-Notebook 暫時(shí)只支持 "/" URL节猿。完成后票从,訪問域名,即可公網(wǎng)訪問 Byzer-Notebook滨嘱。