Kubernetes是一个支持弹性运行的分布式系统框架,因此在部署storm时想让Supervisor的数目支持动态变化。那么对于持久化存储就不能像zookeeper和kakfa那样直接静态创建nfs目录并挂载。
首先需要配置一个nfs目录,可参考前面两节的nfs目录创建与配置。
动态nfs存储
要使用NFS作为动态的存储服务,需要一个能够提供NFS的动态供应功能的StorageClass。
Kubernetes内置的NFS插件不支持动态供应,因此需要使用第三方的插件,例如NFS-Client Provisioner。以下是使用NFS-Client Provisioner进行动态供应的大致步骤。
首先,部署NFS-Client Provisioner。可以使用Helm chart进行部署,也可以手动部署,以下使用Helm部署。
1、下载Helm,可以从 Helm 的 GitHub 仓库的发布页面下载相应的版本。在 terminal 中执行以下命令:
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
chmod 700 get_helm.sh
./get_helm.sh
2、验证是否安装成功
helm version
3、添加stable repo
helm repo add stable https://charts.helm.sh/stable
4、安装nfs客户端Provisioner
helm install nfs-client-provisioner stable/nfs-client-provisioner --set nfs.server=192.168.45.227 --set nfs.path=/home/nfs/storm
部署Storm
部署一个storm集群需要同时部署nimbus、Supervisor以及ui提供可视化界面,因此需要同时部署运行三种不同任务的容器。由于nimbus以及Supervisor都是有状态任务,需要有各自的存储卷用以存储信息,此外如果有多个nimbus还需要进行选主,因此nimbus和Supervisor以StatefulSet对象部署,而ui则可以使用Deployment对象进行部署。
以下是部署所用的storm.yaml
文件,首先通过使用 ConfigMap 在 Kubernetes 部署时就修改 storm.yaml 文件,直接管理 storm 集群配置信息。其次通过Service方式开放ui服务,通过映射本机30080端口以访问ui界面,此外由于每次部署时ui的pod不一定都在特定Node上,因此通过亲和性的方式指定ui的pod应被部署到的Node。
---
apiVersion: v1
kind: ConfigMap
metadata:
name: storm-config
namespace: storm
data:
storm.yaml: |
storm.zookeeper.servers:
- "zookeeper-0.zk-inner-service.storm.svc.cluster.local"
- "zookeeper-1.zk-inner-service.storm.svc.cluster.local"
- "zookeeper-2.zk-inner-service.storm.svc.cluster.local"
storm.log.dir: "/apache-storm-1.2.2/log"
storm.local.dir: "/apache-storm-1.2.2/data"
nimbus.seeds:
- "storm-nimbus-0.storm-nimbus-service.storm.svc.cluster.local"
supervisor.childopts: "-Xmx1024m"
supervisor.slots.ports:
- 6700
- 6701
---
apiVersion: v1
kind: Service
metadata:
name: storm-ui-service
namespace: storm
spec:
type: NodePort
ports:
- port: 8080
nodePort: 30080
selector:
app: storm
component: ui
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: storm-ui
namespace: storm
spec:
replicas: 1
selector:
matchLabels:
app: storm
component: ui
template:
metadata:
labels:
app: storm
component: ui
spec:
containers:
- name: storm-ui
image: storm:1.2.2
ports:
- containerPort: 8080
command:
- sh
- -c
- "storm ui --config /apache-storm-1.2.2/conf/storm.yaml"
volumeMounts:
- name: config-volume
mountPath: /apache-storm-1.2.2/conf/storm.yaml # 这个路径为实际的 storm.yaml 文件的目录
subPath: storm.yaml
- name: time-zone
mountPath: /etc/localtime
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- ubuntu
volumes:
- name: config-volume
configMap:
name: storm-config
- name: time-zone
hostPath:
path: /usr/share/zoneinfo/Asia/Hong_Kong
---
apiVersion: v1
kind: Service
metadata:
name: storm-nimbus-service
namespace: storm
spec:
ports:
- port: 6627
targetPort: 6627
clusterIP: None
selector:
app: storm
component: nimbus
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: storm-nimbus
namespace: storm
spec:
serviceName: storm-nimbus-service
replicas: 1
selector:
matchLabels:
app: storm
component: nimbus
template:
metadata:
labels:
app: storm
component: nimbus
spec:
containers:
- name: storm-nimbus
image: storm:1.2.2
ports:
- containerPort: 6627
command:
- sh
- -c
- "storm nimbus --config /apache-storm-1.2.2/conf/storm.yaml"
volumeMounts:
- name: config-volume
mountPath: /apache-storm-1.2.2/conf/storm.yaml # 这个路径为实际的 storm.yaml 文件的目录
subPath: storm.yaml
- name: time-zone
mountPath: /etc/localtime
volumes:
- name: config-volume
configMap:
name: storm-config
- name: time-zone
hostPath:
path: /usr/share/zoneinfo/Asia/Hong_Kong
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: storm-supervisor
namespace: storm
spec:
serviceName: storm-slot-service
replicas: 10
selector:
matchLabels:
app: storm
component: supervisor
template:
metadata:
labels:
app: storm
component: supervisor
spec:
containers:
- name: storm-supervisor
image: storm:1.2.2
ports:
- containerPort: 6700
ports:
- containerPort: 6701
resources:
requests:
memory: "4Gi"
cpu: "4"
command:
- sh
- -c
- "storm supervisor --config /apache-storm-1.2.2/conf/storm.yaml"
volumeMounts:
- mountPath: /apache-storm-1.2.2/log # replace with the actual path
name: log-storage
- name: config-volume
mountPath: /apache-storm-1.2.2/conf/storm.yaml # 这个路径为实际的 storm.yaml 文件的目录
subPath: storm.yaml
- name: time-zone
mountPath: /etc/localtime
volumes:
- name: config-volume
configMap:
name: storm-config
- name: log-storage
persistentVolumeClaim:
claimName: log-pvc
- name: time-zone
hostPath:
path: /usr/share/zoneinfo/Asia/Hong_Kong
volumeClaimTemplates:
- metadata:
name: log-storage
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10Gi
storageClassName: nfs-client
最后查看整体storm集群:
root@ubuntu:# kubectl -n storm get po
NAME READY STATUS RESTARTS AGE
kafka-0 1/1 Running 0 20h
kafka-1 1/1 Running 0 20h
kafka-2 1/1 Running 0 20h
storm-nimbus-0 1/1 Running 0 56m
storm-supervisor-0 1/1 Running 0 56m
storm-supervisor-1 1/1 Running 0 56m
storm-supervisor-2 1/1 Running 0 56m
storm-supervisor-3 1/1 Running 0 56m
storm-supervisor-4 1/1 Running 0 56m
storm-supervisor-5 1/1 Running 0 56m
storm-supervisor-6 1/1 Running 0 56m
storm-supervisor-7 1/1 Running 0 56m
storm-supervisor-8 1/1 Running 0 55m
storm-supervisor-9 1/1 Running 0 55m
storm-ui-68779577f5-q6rtr 1/1 Running 0 56m
zookeeper-0 1/1 Running 0 24h
zookeeper-1 1/1 Running 0 24h
zookeeper-2 1/1 Running 0 24h