1 Ozone on K8S简介
将Ozone部署在K8S上,除实现自动化部署、自动扩缩容、维护等功能外,可在一台机器启动多个datanode,因为datanode重IO,CPU使用率较低,因此如果机器有多个磁盘,则可以启动多个datanode,以充分利用CPU和磁盘。
Ozone自身也提供K8S部署文件,Ozone代码里搜索k8s目录即可。本文在Ozone的K8S部署文件的基础上,增加单节点部署多个datanode、端口映射、升级、制作镜像、拉取私有镜像、集群重置等功能。本文的所有部署文件请参考[1]。提供以下service的部署文件:om、scm、s3g、datanode。
2 部署Datanode
本文的datanode使用本地磁盘做存储,K8S在1.14版本后支持使用Local PV(Local Persistent Volumes)作为本地存储。虽然K8S支持另一种本地存储hostPath,但hostPath缺点是调度器不能理解volume和pod的对应关系,当pod挂掉被重新调度时,很可能被调度到其他volume上,这就导致pod和volume的映射关系发生错误,对应到ozone的datanode上,就会发生datanode重启时读其他datanode的数据。而使用Local PV的pod,总会被调度到同一个volume上。Local PV的使用方式参考[2]。
在一台机器部署多个datanode,需要为每个datanode挂载不同目录/磁盘,目录通过PersistentVolume的{path}指定,datanode也可以通过{host}指定部署在哪台机器上,{pod_index}指定当前datanode的编号。
apiVersion: v1kind: PersistentVolumemetadata:name: datanode-pv-{pod_index}spec:capacity:storage: 1000GivolumeMode: FilesystemaccessModes:- ReadWriteOncepersistentVolumeReclaimPolicy: DeletestorageClassName: datanode-local-storage-{pod_index}local:path: {path}nodeAffinity:required:nodeSelectorTerms:- matchExpressions:- key: kubernetes.io/hostnameoperator: Invalues:- {host}
启动每个datanode共需4个文件:datanode-storageclass.yaml、datanode-pv.yaml、datanode-storageclass.yaml、datanode-service.yaml。如果启动n个datanode,则需要4n个文件,该4n个文件可通过脚本create-datanode-yaml.py自动生成。需要修改两个变量:host_list指定datanode部署在哪些机器上、dir_list指定每个datanode挂载的目录。运行该脚本,所有datanode相关的部署文件生成在result-datanode-yaml目录。
3 端口映射
Service端口映射分为两种:
一,需要映射到K8S上的IP:Port,该IP为clusterIP,由K8S master节点init时通过service-cidr指定范围,Port不占用物理机的端口,适用于在物理机上访问,例如s3gateway。
apiVersion: v1kind: Servicemetadata:name: s3gspec:clusterIP: 10.96.1.1type: NodePortports:- port: 9878targetPort: 9878name: restselector:app: ozonecomponent: s3g
二,映射到物理机的IP:Port,IP不需要填,Port占用K8S集群所有物理机的端口,通过K8S集群的任一台机器IP和Port均可访问该Service,适用于在物理机外打开UI的场景,例如om的UI。
apiVersion: v1kind: Servicemetadata:name: omspec:type: NodePortports:- port: 9874targetPort: 9874nodePort: 8081name: uiselector:app: ozonecomponent: om
4 升级
升级分为Ozone代码升级和配置升级,本文为了方便,将代码编译后的文件和配置文件ozone-site.xml均放在镜像里。升级时将以下命令的pod_name、container_name、name:tag换掉,并执行。部署文件的目录build-image提供制作镜像的脚本build-image.sh,提供下载代码、编译、拷贝配置、上传到镜像仓库等功能,配置ozone-site.xml放在build-image/ozone-config下,每次编译完后自动将配置文件拷贝到镜像里。
kubectl patch pod pod_name -p '{"spec":{"containers":[{"name": "container_name","image": "name:tag"}]}}'。
5 拉取私有镜像
拉取私有镜像时,需要配置/usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf,添加User=root,即使K8S集群是root启动,仍然需要该配置,然后执行systemctl daemon-reload、systemctl restart kubelet。原因请参考[3]。
6 集群重置
停掉ozone集群再重新部署时,每个pod的ip都发生变化,如果ozone集群的采用ip进行网络通信,重置集群后集群会不可用。因此ozone集群的通信需要使用host,该功能需要在ozone-site.xml里设置dfs.datanode.use.datanode.hostname=true,并且需要使用者自行将如下两处的getIpAddress()换成getHostName():一,datanode注册到ratis,参考[4];二,scm和datanode通信,参考[5]。因为该问题还在社区讨论中,所以相关代码还未合进社区,参考[6]。
欢迎阅读其他Ozone系列文章
参考
[1]https://github.com/runzhiwang/k8s-ozone
[2]https://kubernetes.io/blog/2019/04/04/kubernetes-1.14-local-persistent-volumes-ga/
[3]https://github.com/kubernetes/kubernetes/issues/45487
[4]https://github.com/apache/hadoop-ozone/blob/master/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/ratis/RatisHelper.java#L93
[5]https://github.com/apache/hadoop-ozone/blob/master/hadoop-hdds/client/src/main/java/org/apache/hadoop/hdds/scm/XceiverClientGrpc.java#L173
[6]https://issues.apache.org/jira/projects/HDDS/issues/HDDS-1933
欢迎关注“数据湖技术”公众号,更多精彩待续!





