helm系列2--helm安装hadoop
helm安装hadoop参考: https://github.com/kubernetes/charts/tree/master/stable/hadoop本文文档均参照以上github上的操作步骤完成,附加了需要注意的地方、测试经验、亲和性、挂载以及扩容缩容等操作。需求:利用helm编排快速安装hadoop,可进行快速的删除并重新安装;hadoop的datanode的pod安装在指定的机器nod
helm安装hadoop
参考: https://github.com/kubernetes/charts/tree/master/stable/hadoop
本文文档均参照以上github上的操作步骤完成,附加了需要注意的地方、测试经验、亲和性、挂载以及扩容缩容等操作。
需求:利用helm编排快速安装hadoop,可进行快速的删除并重新安装;hadoop的datanode的pod安装在指定的机器node节点上;一个node节点上有且只有一个datanode的pod;能够对datanode进行扩容、缩容;暴露nameNode的服务给外界web进行访问。
分析:
1. 进行快速的删除并重新安装---数据挂载的问题;
2. datanode的pod安装在指定的机器node节点上---node亲和性解决;
3.一个node节点上有且只有一个datanode的pod---pod的反亲和性
4. 扩容、缩容---scale命令使用,但是得对hadoop的数据进行测试;
5.暴露nameNode的服务给外界web进行访问---在headlessService之外创建service服务;
1. hadoop的安装
参考文档中一个命令就启动了,其它的都是附加参数;附加参数不提,文档中介绍的够详细了,我们先说一下启动脚本需要注意的地方;
helm install --name hadoop$(./calc_resources.sh 50) stable/hadoop
其实helm环境安装好之后(可以查看我的博客),helm install就不用关心了;stable/hadoop其实是一个阿里的远程仓库(你自己搭建一个helm仓库就理解了);只需要关心. /calc_resources.sh脚本,该脚本主要是获取一些机器的参数等,执行时注意脚本的路径以及授权(chmod +x );$(. /calc_resources.sh 50)是向脚本中传递50这一参数,然后执行;
在执行脚本之前,linux环境需要安装几个工具
[root@node01 ~] yum install epel-release
[root@node01 ~] yum install bc
[root@node01 ~] yum install jq
最好先下载使用的hadoop镜像(检测是否可以下载成功)
[root@node01 ~] docker pull danisla/hadoop:2.7.3
然后直接启动就可以了,理论上应该没什么问题,你通过查看pod、statefulset、svc的状态可以看到hadoop的启动状态。
原理:
helm利用chart编排hadoop的pod和服务
hadoop的镜像不必多说,应该是将hadoop的完整安装包封装进入docker镜像中,无非是几个主要的配置文件等启动时通过挂载configMap传入进去即可;
hadoop编排主要使用了statefulset、headless Service、pvc、configMap等;也是正常有状态服务常用的编排方式,statefulset可以控制pod启动的顺序以及进行编号(所谓有状态,就是每个pod都不一样),headless Service可以获取到所有pod的域名地址进行访问,pvc进行动态挂载,configMap传递配置文件及参数(首先将configMap中挂载的文件挂载进入容器内的相关路径下;然后启动bootstrap.sh(设置环境变量,将这些临时挂载的文件放入到hadoop的相关目录下,然后根据nn、dn等进行相关的操作)等。
2. 数据挂载
因为有状态服务,所以最先考虑的是挺先进的pv与pvc的概念,但是给pass掉了;因为使用任何一个文件系统作为挂载的话,必然会有网络问题或者维护成本的问题;
这样只能考虑本地:empty、localVolume与storageClass
empty因为不会制定具体的挂载路径,跟我们需求不吻合,pass掉;storageClass技术好像很新,k8s的一些低版本好像不是很吻合,应用起来也没有运行成功,所以也放弃掉了(要是哪位大神研究明白了可以给我留个言哈);最后选择了localVolume,但是还存在一个问题,因为localVolume挂载的数据在pod删除掉之后并不会删除,这对于hdfs本身倒无所谓,因为它自身会同步;但是如何要删除掉集群,再创建时,由于数据的存在,会出现数据不同步(可能)或创建失败的问题;所以调研到了podHook【https://jimmysong.io/kubernetes-handbook/concepts/pod-hook.html】与helmHook【https://www.kubernetes.org.cn/2726.html 】;选择podHook是因为helm Hook是一个job,启动一个容器,而我们想要删除掉所有datanode的pod的挂载数据;具体的配置如何,修改了templates/hdfs-dn-statefulset.yaml文件来实现,每个pod创建时会清空挂载的数据,然后启动pod,以此来达到数据的同步或者删除;
话不多说,直接看配置文件;
[root@node01 ~] vihadoop1/templates/hdfs-dn-statefulset.yaml
containers:
- name: hdfs-dn
image: {{ .Values.image }}
lifecycle:
postStart:
exec:
command:["/bin/sh","-c","rm -rf /root/hdfs/datanode/*"]
preStop:
exec:
command:
- "/bin/bash"
- "touch"
-"/root/hdfs/datanode/preStop"
在containers参数下添加子参数lifecycle参数,lifecyle中定义了容器启动后与关闭前的操作,postStart生效了,preStop不生效,不过有一个生命周期生效就满足我的需求了;
3. datanode选择node节点
[root@node01 ~]kubectl label nodes node03cluster=hadoop --overwrite
[root@node01 ~]kubectl get nodes -l cluster=hadoop
[root@node01 ~] vi templates/hdfs-dn-statefulset.yaml
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: cluster
operator: In
values:
- hadoop
podAntiAffinity:
{{- if eq .Values.antiAffinity "hard" }}
在affinity节点下添加子节点nodeAffinity(与podAffinity同级)
4. datanode的pod不存在一个node节点上
因为pod已经定义好了pod的互斥性,只需要看是否强制性就好了;
修改value.yml中的antiAffinity:"soft"为”hard”,我们即可以搞定强制pod不在一个node节点上。
5. 扩容缩容
按顺序进行扩容或缩容(与rc的区别)
[root@node01 ~]kubectl scale statefulsethadoop-1-hadoop-hdfs-dn --replicas 2
扩容、缩容很简单,只需要更改后面的副本个数即可;
但我们需要测试扩容、缩容对于hadoop数据的影响;
测试目的:确定在扩容缩容时hadoop的文件副本数会随着增加或缩减
测试过程:
有两种方式:一是在容器外部直接调用命令进行操作;二是进入容器内部进行操作,不过本质上都是一样的
方法一:kubectl exec -n default -it hadoop-1-hadoop-hdfs-nn-0 --/usr/local/hadoop/bin/hdfs dfsadmin –report
方法二:进入容器内部
[root@node01 ~]kubectl exec -n default -ithadoop-1-hadoop-hdfs-nn-0/bin/bash
[root@node01 ~]cd /usr/local/hadoop/bin
[root@node01 ~]/usr/local/hadoop/bin:hadoop fs -ls /
[root@node01 ~]hadoop fs -put aa /
[root@node01 ~]hdfs fsck /bb -files -blocks#查看实际存活副本数
[root@node01 ~]cd /usr/local/hadoop/sbin
[root@node01 ~] ./start-balancer.sh#立刻进行副本的平衡(可能还是需要一段时间)
datanode节点掉之后,namenode会重试几百次之后断掉与datanode的连接;
6. 暴露服务
hadoop基本对外端口及api:
所有操作都是连接namenode节点进行操作;
namenode:
50015:web页面查看接口
50010:api命令操作接口
datanode:
50075:web页面访问接口
无操作接口命令
rm与nn无关,用户rm进行mapreduce任务;rm管理nm;nm数量与dn数量无关,理论上一对一即可,一个nm管理一个dn资源
我们这儿先为namenode中的50070在外端访问提供服务,只需要重新创建个service,然后将headless service粘贴过来即可,改name,将clustername:null去掉,添加type:nodeType,加nodePort;文件最后放入template中即可。
[root@node01 ~] cat nameNodeSvc.yaml
# A headless service to create DNS records
apiVersion: v1
kind: Service
metadata:
name: {{ template "hadoop.fullname" . }}-hdfs-nn-s
labels:
app: {{ template "hadoop.name" . }}
chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+""_" }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
component: hdfs-nn
spec:
type: NodePort
ports:
-name: dfs
port: 9000
protocol: TCP
-name: webhdfs
port: 50070
targetPort: 50070
nodePort: 30070
selector:
app: {{ template "hadoop.name" . }}
release: {{ .Release.Name }}
component: hdfs-nn
7.知识点
小知识1.helm安装方式
helm安装主要有四种方式:
安装仓库中的 chart,例如:helm install stable/nginx
通过tar 包安装,例如:helm install ./nginx-1.2.3.tgz
通过chart 本地目录安装,例如:helm install ./nginx
通过URL 安装,例如:helm install https://example.com/charts/nginx-1.2.3.tgz
8.注意
1.彻底删除需要添加--purge,helm del –purge hadoop
2.安装失败,需要删除时,时间会有点长,因为pod在不停的启动;假如你是个急性子,强制停止了del命令进程,必须先删除pod,再删除statefulset,再删除svc,将所有resources都删除掉;
3.挂载的hdfs/datanode中有数据时,datenode时启动不了的;
4.node亲和性,pod运行期间若node的标签发生改变,pod继续运行
5.ue以及其他的编辑器中的格式可能和linux中不一样,导致yml格式错误
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)