华为云 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 虚拟网络:部署其他云资源。
-
CCE (K8S 集群): 部署 Byzer-Notebook Byzer-lang
-
RDS for MySQL: 存储 Byzer-Notebook 元数据
-
OBS:对象存储,作为 Byzer-lang 的存储。
另外,华为 ELB Ingress Controller 需要一个域名,因国内需要备案,请事先准备。
创建 VPC
为简单起见,仅创建一个子网,网段为 192.168.0.0/24。K8S 集群,RDS for MySQL, SNAT , ELB 都部署在该 VPC。
image.png
创建 K8S 集群
参考华为云文档, 创建K8S 集群。
设置客户机,以连接K8S 集群
有两者方式, CloudShell 和客户机,都通过 kubectl 命令操作。CloudShell 通过网页,但有效期仅1天且当前仅北京一、北京四、上海一、上海二、广州和乌兰察布一支持使用CloudShell登录容器。我们选择客户机方式。
由于客户机访问 CCE 走公网,我们为 K8S APIServer 绑定一个公网地址。首先参考文档购买公网IP。然后进入CCE 详情页面,左下角为“连接信息”,可以看到公网地址为空。点击"绑定",选择刚申请的公网IP。
然后回到 CCE 列表页。点击“连接”图标,在弹出页面下载 config 文件。存为客户机的~/.kube/config文件。执行命令:kubectl config use-context external
设置公网访问上下文。执行命令 kubectl cluster-info
,会输出 CCE 集群的连接信息。
创建 Namespace Role Service Account
登录华为云portal,找到集群,在页面上点击创建 namespace。然后设置客户机的默认 Namespace
kubectl config set-context --current --namespace=byzer
创建 service account
kubectl create serviceaccount byzer -n byzer
创建 Role byzer-admin 并赋予它在 byzer namespace 高权限
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
创建 OBS Bucket
根据 华为云文档-- 快速入门操作,可以得到一个 OBS Bucket 和 AKSK。Byzer-lang 将使用 AKSK 访问 OBS Bucket。
配置 SNAT
默认情况,CCE 的 Node 无法访问Internet,造成镜像拉取失败。Byzer 也无法拉取公网数据。因而,我们配置 SNAT 规则。
首先,申请 NAT,根据你的网络流量选择规格,并选择与 CCE相同的VPC。然后,配置 SNAT 规则。
使用场景:选择 VPC - 虚拟私有云;网段: 选择前面创建的 VPC 的网段。
弹性公网IP:选择一个可用的,注意带宽是否符合你的流量需求。若没有公网IP,需要创建一个。
image.png
最后,点击确定。生成的SNAT 规则如下:
image.png
使用容器镜像服务 SWR 管理镜像
拉取境外的镜像,有时很慢甚至失败。 拉取镜像时也可能碰到 registry-1.docker.io 限流。搭建 SWR 可以较好解决这一问题;也能节省一笔公网带宽和流量费用。
上传镜像
在华为云控制台找到 SWR,点击创建组织,完成后,点击上传自有镜像。首先,创建 byzer-lang 镜像的 tar 包。命令 docker save byzer-lang-k8s:3.3.0-2.4.0-SNAPSHOT > ./byzer.tar.gz
然后使用客户端上传,跟着华为云文档指引,先登录,再上传。
完成后,可以在 我的镜像页面看到新镜像。
制作拉取镜像的凭证
默认情况,私有SWR需要凭证才能拉取镜像。我们参考 K8S 文档
首先获取凭证,创建为 K8S Secrets 对象,最后在 Byzer-lang 的 helm chart 声明。
获取凭证
根据华为文档 - 获取长期有效登录指令
获得AKSK,并执行docker login命令登录你的镜像仓库。登录成功后,检查~/.docker/config.json ,多了一条 SWR 的记录。
创建 Secrets
执行命令base64 ~/.docker/config.json
,得到编码后的 凭证。如果输出有多行,请合并为一行。
创建一个 yaml,base64 编码的凭证填入data.dockerconfigjson。metadata.name请酌情替换。
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,填写下面的参数后,执行 helm install byzer-lang . -f ./values.yaml
部署至 K8S
K8S 集群地址
values.yaml 文件的 clusterUrl 参数为 K8S ApiServer 地址,Byzer 的 Spark Driver Pod 启动时读取它,并申请 Executor Pod。如果你的 K8S 集群不能访问公网,请勿填写公网地址。建议填写私有地址,避免出错。例子如下:
clusterUrl: https://192.168.0.3:5443
华为云 OBS
Byzer-lang 使用 obs 存储数据。配置如下
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>
,根据实际情况修改。
fs.obs.access.key
和 fs.obs.secret.key
改成你的账号的AKSK。fs.obs.endpoint
根据OBS 所处区域,有所不同,可以在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,报下面错误。我们关闭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 的配置。请根据需要修改下面参数.
spark:
driver.memory: 8g
driver.cores: 2
driver.maxResultSize: 4g
executor.memory: 4g
executor.cores: 1
executor.instances: 1
创建 RDS for MySQL
登录华为云,在顶部搜索栏搜索”rds for mysql",并选中后,进入 RDS for MySQL 页面。再点击右上角“购买数据库实例”。参考华为云文档。注意虚拟私有云(VPC) 必须与 K8S (CCE)一致。数据库版本建议 8.0 或者5.7。5.6 版本比较老,可能存在兼容性问题。由于仅保存 Byzer-Notebook 元数据,存储空间 100GB 足够。
创建后,请使用 root 账号创建一个数据库,可以取名“ notebook";并创建一个 Byzer-Notebook 访问 RDS for MySQL 的 用户。
部署 Byzer-Notebook
使用 Helm chart 部署。先下载。解压后,按照下面的指引编辑 values.yaml ,并执行helm install byzer-notebook . -f ./values.yaml
部署至 K8S
ingress
helm chart 内置 Nginx Ingres controller,这里不使用。配置如下:
ingress:
enabled: false
镜像
从上文配置的 SWR 拉取镜像,我的SWR 地址为:swr.ap-southeast-3.myhuaweicloud.com
。请修改为你实际的地址。
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,请配置为 NodePort 类型Service,独享型,请配置为 ClusterIP 型 Service。
service:
type: NodePort
port: 9002
用户数据隔离
不同 Byzer-Notebook 用户的 的数据,例如上传的文件,将被隔离,意味着 用户A 无法查看用户 B 的数据。我们配置下面参数:
notebook:
user.home: /work/data
这意味着用户数据被存放在 Byzer-lang 的 /work/data/{user_name} 目录下。对于本例子,意味着 OBS Bucket 上该前缀的对象。
Byzer-lang url
Byzer-Notebook 调用 Byzer-lang 的HTTP 接口,执行 SQL,获取结果等。在 K8S 上我们配置为 Byzer-lang 的Service。例如:
notebook.
mlsql.engine-url: http://byzer-lang-service.byzer:9003
其中 byzer-lang-service 是 Byzer-lang的service名称,byzer 是 Namespace。9003 为 Service 的端口。
数据库
使用刚创建的 RDS for MySQL。请根据你的实际情况填写端口,数据库名,IP,用户名密码。参考如下:
notebook:
database.port: 3306
database.name: notebook
database.ip: "192.168.0.188"
database.username: "notebook"
database.password: "notebook"
配置公网访问 Byzer-Notebook
由于 Notebook Pod 和 Service 网络地址都是私有网络,公网无法访问。我们使用华为云 ELB (Elastic LoadBalancer) + ELB Ingress Controller 实现。其原理如下:
image.png
然后,跟着华为云的文档https://support.huaweicloud.com/usermanual-cce/cce_10_0251.html,创建 ELB 并配置 ELB Ingress Controller。由于价格因素,选择共享型ELB 。路由规则如下所示:
Byzer-Notebook 暂时只支持 "/" URL。完成后,访问域名,即可公网访问 Byzer-Notebook。
网友评论