noel0217 发表于 2018-1-4 13:30:10

Kubernetes+Flannel 环境中部署HBase集群

2015-12-14注:加入新节点不更改运行节点参数需求已满足,将在后续文章中陆续总结。

注:目前方案不满足加入新节点(master节点或regionserver节点)而不更改已运行节点的参数的需求,具体讨论见第六部分。

一、背景知识
  先看下HBase的组成:
https://images2015.cnblogs.com/blog/678393/201511/678393-20151130140114312-982789222.jpg
  Master:Master主要负责管理RegionServer集群,如负载均衡及资源分配等,它本身也可以以集群方式运行,但同一时刻只有一个master处于激活状态。当工作中的master宕掉后,zookeeper会切换到其它备选的master上。
  RegionServer:负责具体数据块的读写操作。
  ZooKeeper:负责集群元数据的维护并监控集群的状态以防止单点故障。部署HBase时可以使用自带的ZooKeeper也可以使用独立的集群,是HBase跑起来的先决条件。
  HDFS:写入HBase中的数据最终都持久化到了HDFS中,也是HBase运行的先决条件。

二、skyDNS部署
  skyDNS并不是必需项,但设置了skyDNS后可以为k8s的service绑定域名,进行hbase的参数设置时可以以域名代替service的IP地址。k8s环境中的skyDNS由三部分组成: 存储IP地址和域名映射关系的ETCD;进行域名解析的skyDNS;连接k8s和skyDNS的桥梁kube2sky。k8s的域名构成为 service_name.namespace.k8s_cluster_domain。k8s的文档中有对部署skyDNS的简略说明(戳这里),其中要用到Google镜像仓库中的image,国内访问不到,可以使用DockerHub上的替换方案,如:
  skyDNS: docker pull shenshouer/skydns:2015-09-22
  kube2sky: docker pull shenshouer/kube2sky:1.11
  ETCD: 只要是2.x版本的ETCD都可以,也可以和上面的保持一致使用 docker pull shenshouer/etcd:2.0.9
  pull下来之后打上tag再push到私有仓库中。
  下面创建一个service和一个pod来部署skyDNS,设定 skyDNS service 的服务地址为 172.16.40.1 (53/UDP, 53/TCP),注意该IP地址要在kube-apiserver启动时设定的service的子网范围内;k8s集群的域名后缀为 domeos.sohu,注意这个后缀的选择最好包含两部分,否则kube2sky可能会出问题(具体讨论戳这里)。
  首先创建skydns.yaml文件:
  

apiVersion: v1  
kind: Service
  
metadata:
  
name: kube-dns
  
labels:
  
app: kube-dns
  
version: v8
  
spec:
  
selector:
  
app: kube-dns
  
version: v8
  
type: ClusterIP
  
clusterIP: 172.16.40.1
  
ports:
  
- name: dns
  
port: 53
  
protocol: UDP
  
- name: dns-tcp
  
port: 53
  
protocol: TCP
  
---
  
apiVersion: v1
  
kind: ReplicationController
  
metadata:
  
name: kube-dns-v8
  
labels:
  
app: kube-dns
  
version: v8
  
spec:
  
replicas: 1
  
selector:
  
app: kube-dns
  
version: v8
  
template:
  
metadata:
  
labels:
  
app: kube-dns
  
version: v8
  
spec:
  
containers:
  
- name: etcd
  
image: 10.11.150.76:5000/openxxs/etcd:2.0.3
  
command:
  
- "etcd"
  
args:
  
- "--data-dir=/var/etcd/data"
  
- "--listen-client-urls=http://127.0.0.1:2379,http://127.0.0.1:4001"
  
- "--advertise-client-urls=http://127.0.0.1:2379,http://127.0.0.1:4001"
  
- "--initial-cluster-token=skydns-etcd"
  
volumeMounts:
  
- name: etcd-storage
  
mountPath: /var/etcd/data
  
- name: kube2sky
  
image: 10.11.150.76:5000/openxxs/kube2sky:k8s-dns
  
args:
  
- "--domain=domeos.sohu"
  
- "--kube_master_url=http://10.16.42.200:8080"
  
- name: skydns
  
image: 10.11.150.76:5000/openxxs/skydns:2015-09-22
  
args:
  
- "--machines=http://localhost:4001"
  
- "--addr=0.0.0.0:53"
  
- "--domain=domeos.sohu"
  
ports:
  
- containerPort: 53
  
name: dns
  
protocol: UDP
  
- containerPort: 53
  
name: dns-tcp
  
protocol: TCP
  
volumes:
  
- name: etcd-storage
  
emptyDir: {}
  
dnsPolicy: Default
  

  kube2sky中的 --kube_master_url 参数用于指定 kube-apiserver 的地址;kube2sky中的 --domain 和 skydns中的 --domain 要保持一致。
  然后 kubectl create -f skydns.yaml 创建服务和pod:
  

$kubectl create -f skydns.yaml  
service "kube-dns" created
  
replicationcontroller "kube-dns-v8" created
  
$kubectl get pods
  
NAME                  READY   STATUS         RESTARTS   AGE
  
kube-dns-v8-61aie       3/3       Running          0          9s
  
$kubectl get service
  
NAME                  CLUSTER_IP       EXTERNAL_IP    PORT(S)            SELECTOR                     AGE
  
kube-dns                172.16.40.1      <none>         53/UDP,53/TCP      app=kube-dns,version=v8      6m
  

  最后,重启 kubelet 加上dns相关的设置参数 --cluster_dns 和 --cluster_domain,参数值要与前面yaml文件中写的一致,如:
  

./kubelet --logtostderr=true --v=0 --api_servers=http://bx-42-200:8080 --address=0.0.0.0 --hostname_override=bx-42-198 --allow_privileged=false --pod-infra-container-image=10.11.150.76:5000/kubernetes/pause:latest --cluster_dns=172.16.40.1 --cluster_domain=domeos.sohu &  

  注意:只有在kubelet加了dns设置参数重启之后创建的pods才会使用skyDNS。
  此时进入到etcd的container中就可以发现k8s的service域名信息已被写入etcd当中了:
  

$ docker exec -it 13e243510e3e sh  
/ # etcdctl ls --recursive /
  
/skydns
  
/skydns/sohu
  
/skydns/sohu/domeos
  
/skydns/sohu/domeos/default
  
/skydns/sohu/domeos/default/kube-dns
  
/skydns/sohu/domeos/default/kubernetes
  
/skydns/sohu/domeos/default/zookeeper-1
  
/skydns/sohu/domeos/default/zookeeper-2
  
/skydns/sohu/domeos/default/zookeeper-3
  
/skydns/sohu/domeos/svc
  
/skydns/sohu/domeos/svc/default
  
/skydns/sohu/domeos/svc/default/zookeeper-2
  
/skydns/sohu/domeos/svc/default/zookeeper-2/b8757496
  
/skydns/sohu/domeos/svc/default/zookeeper-3
  
/skydns/sohu/domeos/svc/default/zookeeper-3/8687b21f
  
/skydns/sohu/domeos/svc/default/kube-dns
  
/skydns/sohu/domeos/svc/default/kube-dns/a9f11e6f
  
/skydns/sohu/domeos/svc/default/kubernetes
  
/skydns/sohu/domeos/svc/default/kubernetes/cf07aead
  
/skydns/sohu/domeos/svc/default/zookeeper-1
  
/skydns/sohu/domeos/svc/default/zookeeper-1/75512011
  
/ # etcdctl get /skydns/sohu/domeos/default/zookeeper-1
  
{"host":"172.16.11.1","priority":10,"weight":10,"ttl":30,"targetstrip":0}
  

  以 /skydns/sohu/domeos/default/zookeeper-1 这条记录为例,其对应的域名即为 zookeeper-1.default.domeos.sohu ,IP 为 172.16.11.1,服务名称为zookeeper-1,k8s的namespace为default,k8s设定的域为 domeos.sohu。在任一重启kubelet之后创建的pod中都可以以 zookeeper-1.default.domeos.sohu 的方式访问zookeeper-1服务,如:
  

[@bx_42_199 ~]# docker exec -it 0662660e8708 /bin/bash  
[iyunv@test
-3-2h0fx /]# curl zookeeper-1.default.domeos.sohu:2181  
curl: (
52) Empty reply from server  


三、HDFS集群部署
  HDFS由namenode和datanode组成,首先从DockerHub上pull合适的镜像再push到自己的私有仓库中:
  

# pull 远程images  
docker pull bioshrek
/hadoop-hdfs-datanode:cdh5  
docker pull bioshrek
/hadoop-hdfs-namenode:cdh5  
# 打上tag
  
# docker tag
<image的ID> <自己的私有仓库IP:PORT/名称:TAG>  
docker tag c89c3ebcccae
10.11.150.76:5000/hdfs-datanode:latest  
docker tag ca19d4c7e359
10.11.150.76:5000/hdfs-namenode:latest  
# push到仓库中
  
docker push
10.11.150.76:5000/hdfs-datanode:latest  
docker push
10.11.150.76:5000/hdfs-namenode:latest  

  然后创建如下hdfs.yaml文件:

https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gifhttps://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif  

1 apiVersion: v1  

2 kind: Service  

3 metadata:  

4   name: hdfs-namenode-service  

5 spec:  

6   selector:  

7   app: hdfs-namenode  

8   type: ClusterIP  

9   clusterIP: "172.16.20.1"  
10   ports:
  
11   - name: rpc
  
12       port: 4231
  
13       targetPort: 8020
  
14   - name: p1
  
15       port: 50020
  
16   - name: p2
  
17       port: 50090
  
18   - name: p3
  
19       port: 50070
  
20   - name: p4
  
21       port: 50010
  
22   - name: p5
  
23       port: 50075
  
24   - name: p6
  
25       port: 8031
  
26   - name: p7
  
27       port: 8032
  
28   - name: p8
  
29       port: 8033
  
30   - name: p9
  
31       port: 8040
  
32   - name: p10
  
33       port: 8042
  
34   - name: p11
  
35       port: 49707
  
36   - name: p12
  
37       port: 22
  
38   - name: p13
  
39       port: 8088
  
40   - name: p14
  
41       port: 8030
  
42 ---
  
43 apiVersion: v1
  
44 kind: ReplicationController
  
45 metadata:
  
46   name: hdfs-namenode-1
  
47 spec:
  
48   replicas: 1
  
49   template:
  
50   metadata:
  
51       labels:
  
52         app: hdfs-namenode
  
53   spec:
  
54       containers:
  
55         - name: hdfs-namenode
  
56         image: 10.11.150.76:5000/hdfs-namenode:latest
  
57         volumeMounts:
  
58             - name: data1
  
59               mountPath: /var/lib/hadoop-hdfs/cache/hdfs/dfs/name
  
60             - name: data2
  
61               mountPath: /home/chianyu/shared_with_docker_container/cdh5/nn
  
62         ports:
  
63             - containerPort: 50020
  
64             - containerPort: 50090
  
65             - containerPort: 50070
  
66             - containerPort: 50010
  
67             - containerPort: 50075
  
68             - containerPort: 8031
  
69             - containerPort: 8032
  
70             - containerPort: 8033
  
71             - containerPort: 8040
  
72             - containerPort: 8042
  
73             - containerPort: 49707
  
74             - containerPort: 22
  
75             - containerPort: 8088
  
76             - containerPort: 8030
  
77             - containerPort: 8020
  
78       nodeSelector:
  
79         kubernetes.io/hostname: bx-42-199
  
80       volumes:
  
81         - hostPath:
  
82             path: /data1/kubernetes/hdfs-namenode/data1
  
83         name: data1
  
84         - hostPath:
  
85             path: /data1/kubernetes/hdfs-namenode/data2
  
86         name: data2
  
87 ---
  
88 apiVersion: v1
  
89 kind: ReplicationController
  
90 metadata:
  
91   name: hdfs-datanode-1
  
92 spec:
  
93   replicas: 1
  
94   template:
  
95   metadata:
  
96       labels:
  
97         app: hdfs-datanode
  
98         server-id: "1"
  
99   spec:
  
100       containers:
  
101         - name: hdfs-datanode-1
  
102         image: 10.11.150.76:5000/hdfs-datanode:latest
  
103         volumeMounts:
  
104             - name: data1
  
105               mountPath: /var/lib/hadoop-hdfs/cache/hdfs/dfs/name
  
106             - name: data2
  
107               mountPath: /home/chianyu/shared_with_docker_container/cdh5/dn
  
108         env:
  
109             - name: HDFSNAMENODERPC_SERVICE_HOST
  
110               value: "172.16.20.1"
  
111             - name: HDFSNAMENODERPC_SERVICE_PORT
  
112               value: "4231"
  
113         ports:
  
114             - containerPort: 50020
  
115             - containerPort: 50090
  
116             - containerPort: 50070
  
117             - containerPort: 50010
  
118             - containerPort: 50075
  
119             - containerPort: 8031
  
120             - containerPort: 8032
  
121             - containerPort: 8033
  
122             - containerPort: 8040
  
123             - containerPort: 8042
  
124             - containerPort: 49707
  
125             - containerPort: 22
  
126             - containerPort: 8088
  
127             - containerPort: 8030
  
128             - containerPort: 8020
  
129       nodeSelector:
  
130         kubernetes.io/hostname: bx-42-199
  
131       volumes:
  
132         - hostPath:
  
133             path: /data1/kubernetes/hdfs-datanode1/data1
  
134         name: data1
  
135         - hostPath:
  
136             path: /data1/kubernetes/hdfs-datanode1/data2
  
137         name: data2
  
138 ---
  
139 apiVersion: v1
  
140 kind: ReplicationController
  
141 metadata:
  
142   name: hdfs-datanode-2
  
143 spec:
  
144   replicas: 1
  
145   template:
  
146   metadata:
  
147       labels:
  
148         app: hdfs-datanode
  
149         server-id: "2"
  
150   spec:
  
151       containers:
  
152         - name: hdfs-datanode-2
  
153         image: 10.11.150.76:5000/hdfs-datanode:latest
  
154         volumeMounts:
  
155             - name: data1
  
156               mountPath: /var/lib/hadoop-hdfs/cache/hdfs/dfs/name
  
157             - name: data2
  
158               mountPath: /home/chianyu/shared_with_docker_container/cdh5/dn
  
159         env:
  
160             - name: HDFSNAMENODERPC_SERVICE_HOST
  
161               value: "172.16.20.1"
  
162             - name: HDFSNAMENODERPC_SERVICE_PORT
  
163               value: "4231"
  
164         ports:
  
165             - containerPort: 50020
  
166             - containerPort: 50090
  
167             - containerPort: 50070
  
168             - containerPort: 50010
  
169             - containerPort: 50075
  
170             - containerPort: 8031
  
171             - containerPort: 8032
  
172             - containerPort: 8033
  
173             - containerPort: 8040
  
174             - containerPort: 8042
  
175             - containerPort: 49707
  
176             - containerPort: 22
  
177             - containerPort: 8088
  
178             - containerPort: 8030
  
179       nodeSelector:
  
180         kubernetes.io/hostname: bx-42-199
  
181       volumes:
  
182         - name: data1
  
183         hostPath:
  
184             path: /data2/kubernetes/hdfs-datanode2/data1
  
185         - name: data2
  
186         hostPath:
  
187             path: /data2/kubernetes/hdfs-datanode2/data2
  
188 ---
  
189 apiVersion: v1
  
190 kind: ReplicationController
  
191 metadata:
  
192   name: hdfs-datanode-3
  
193 spec:
  
194   replicas: 1
  
195   template:
  
196   metadata:
  
197       labels:
  
198         app: hdfs-datanode
  
199         server-id: "3"
  
200   spec:
  
201       containers:
  
202         - name: hdfs-datanode-3
  
203         image: 10.11.150.76:5000/hdfs-datanode:latest
  
204         volumeMounts:
  
205             - name: data1
  
206               mountPath: /var/lib/hadoop-hdfs/cache/hdfs/dfs/name
  
207             - name: data2
  
208               mountPath: /home/chianyu/shared_with_docker_container/cdh5/dn
  
209         env:
  
210             - name: HDFSNAMENODERPC_SERVICE_HOST
  
211               value: "172.16.20.1"
  
212             - name: HDFSNAMENODERPC_SERVICE_PORT
  
213               value: "4231"
  
214         ports:
  
215             - containerPort: 50020
  
216             - containerPort: 50090
  
217             - containerPort: 50070
  
218             - containerPort: 50010
  
219             - containerPort: 50075
  
220             - containerPort: 8031
  
221             - containerPort: 8032
  
222             - containerPort: 8033
  
223             - containerPort: 8040
  
224             - containerPort: 8042
  
225             - containerPort: 49707
  
226             - containerPort: 22
  
227             - containerPort: 8088
  
228             - containerPort: 8030
  
229       nodeSelector:
  
230         kubernetes.io/hostname: bx-42-199
  
231       volumes:
  
232         - name: data1
  
233         hostPath:
  
234             path: /data3/kubernetes/hdfs-datanode3/data1
  
235         - name: data2
  
236         hostPath:
  
237             path: /data3/kubernetes/hdfs-datanode3/data2
  


View Code  通过 kubectl create -f hdfs.yaml 即创建一个名为hdfs-namenode-service的service,四个分别名为hdfs-namenode-1、hdfs-datanode-1、hdfs-datanode-2、hdfs-datanode-3的RC。通过 kubectl get services/rc/pods 可以看到对应的service和pod都已经正常启动了。
  下面对HDFS进行测试是否可以正常使用:
  

# 查看HDFS pods  
kubectl get pods
  

  
# 通过describe查看pods跑在哪个k8s node上
  
kubectl describe pod hdfs
-datanode-3-h4jvt  

  
# 进入容器内部
  
docker
ps | grep hdfs-datanode-3  
docker exec
-it 2e2c4df0c0a9 /bin/bash  

  
# 切换至 hdfs 用户
  

su hdfs  

  
# 创建目录
  
hadoop fs
-mkdir /test  
# 创建本地文件
  

echo "Hello" > hello  
# 将本地文件复制到HDFS文件系统中
  
hadoop fs
-put hello /test  
# 查看HDFS中的文件信息
  
hadoop fs
-ls /test  

  
# 类似的,可以 docker exec 到其它datanode中查看文件信息,如:
  
root@hdfs
-datanode-1-nek2l:/# hadoop fs -ls /test  
Found
1 items  

-rw-r--r--   2 hdfs hadoop          6 2015-11-27 08:36 /test/hello  


四、ZooKeeper集群部署
  在 fabric8/zookeeper 的image基础上进行修改,修改后Dockerfile文件内容如下:

https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gifhttps://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif  

1 FROM jboss/base-jdk:7  
2
  
3 MAINTAINER iocanel@gmail.com
  
4
  
5 USER root
  
6
  
7 ENV ZOOKEEPER_VERSION 3.4.6
  
8 EXPOSE 2181 2888 3888
  
9
  
10 RUN yum -y install wget bind-utils && yum clean all \
  
11   && wget -q -O - http://apache.mirrors.pair.com/zookeeper/zookeeper-${ZOOKEEPER_VERSION}/zookeeper-${ZOOKEEPER_VERSION}.tar.gz | tar -xzf - -C /opt \
  
12   && mv /opt/zookeeper-${ZOOKEEPER_VERSION} /opt/zookeeper \
  
13   && cp /opt/zookeeper/conf/zoo_sample.cfg /opt/zookeeper/conf/zoo.cfg \
  
14   && mkdir -p /opt/zookeeper/{data,log}
  
15
  
16 WORKDIR /opt/zookeeper
  
17 VOLUME ["/opt/zookeeper/conf", "/opt/zookeeper/data", "/opt/zookeeper/log"]
  
18
  
19 COPY config-and-run.sh ./bin/
  
20 COPY zoo.cfg ./conf/
  
21
  
22 CMD ["/opt/zookeeper/bin/config-and-run.sh"]
  


View Code  zoo.cfg 文件内容如下:

https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gifhttps://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif  

1 # The number of milliseconds of each tick  

2 tickTime=2000  
3 # The number of ticks that the initial
  
4 # synchronization phase can take
  
5 initLimit=10
  
6 # The number of ticks that can pass between
  
7 # sending a request and getting an acknowledgement
  
8 syncLimit=5
  
9 # the directory where the snapshot is stored.
  
10 dataDir=/opt/zookeeper/data
  
11 #This option will direct the machine to write the transaction log to the dataLogDir rather than the dataDir. This allows a dedicated log device to be used, and helps avoid competition between logging and snaphots.
  
12 dataLogDir=/opt/zookeeper/log
  
13
  
14 # the port at which the clients will connect
  
15 clientPort=2181
  
16 #
  
17 # Be sure to read the maintenance section of the
  
18 # administrator guide before turning on autopurge.
  
19 #
  
20 # http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
  
21 #
  
22 # The number of snapshots to retain in dataDir
  
23 #autopurge.snapRetainCount=3
  
24 # Purge task interval in hours
  
25 # Set to "0" to disable auto purge feature
  
26 #autopurge.purgeInterval=1
  


View Code  config-and-run.sh 文件内容如下:
  

#!/bin/bash  

  

echo "$SERVER_ID / $MAX_SERVERS"  
if [ ! -z "$SERVER_ID" ] && [ ! -z "$MAX_SERVERS" ]; then
  
echo "Starting up in clustered mode"
  
echo "" >> /opt/zookeeper/conf/zoo.cfg
  
echo "#Server List" >> /opt/zookeeper/conf/zoo.cfg
  
for i in $( eval echo {1..$MAX_SERVERS});do
  
HostEnv="ZOOKEEPER_${i}_SERVICE_HOST"
  
HOST=${!HostEnv}
  
FollowerPortEnv="ZOOKEEPER_${i}_SERVICE_PORT_FOLLOWERS"
  
FOLLOWERPORT=${!FollowerPortEnv}
  
ElectionPortEnv="ZOOKEEPER_${i}_SERVICE_PORT_ELECTION"
  
ELECTIONPORT=${!ElectionPortEnv}
  
if [ "$SERVER_ID" = "$i" ];then
  
echo "server.$i=0.0.0.0:$FOLLOWERPORT:$ELECTIONPORT" >> /opt/zookeeper/conf/zoo.cfg
  
else
  
echo "server.$i=$HOST:$FOLLOWERPORT:$ELECTIONPORT" >> /opt/zookeeper/conf/zoo.cfg
  
fi
  
done
  
cat /opt/zookeeper/conf/zoo.cfg
  

  
# Persists the>  
echo ${SERVER_ID} > /opt/zookeeper/data/myid
  
else
  
echo "Starting up in standalone mode"
  
fi
  

  
exec /opt/zookeeper/bin/zkServer.sh start-foreground
  

  修改完后创建镜像并push到私有仓库中(镜像名为10.11.150.76:5000/zookeeper-kb:3.4.6-1)。
  创建zookeeper.yaml文件:

https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gifhttps://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif
  

1 apiVersion: v1  

2 kind: Service  

3 metadata:  

4   name: zookeeper-1  
5   labels:
  
6       name: zookeeper-1
  
7 spec:
  
8   ports:
  
9   - name: client
  
10       port: 2181
  
11       targetPort: 2181
  
12   - name: followers
  
13       port: 2888
  
14       targetPort: 2888
  
15   - name: election
  
16       port: 3888
  
17       targetPort: 3888
  
18   selector:
  
19   name: zookeeper
  
20   server-id: "1"
  
21   type: ClusterIP
  
22   clusterIP: 172.16.11.1
  
23 ---
  
24 apiVersion: v1
  
25 kind: Service
  
26 metadata:
  
27   name: zookeeper-2
  
28   labels:
  
29       name: zookeeper-2
  
30 spec:
  
31   ports:
  
32   - name: client
  
33       port: 2181
  
34       targetPort: 2181
  
35   - name: followers
  
36       port: 2888
  
37       targetPort: 2888
  
38   - name: election
  
39       port: 3888
  
40       targetPort: 3888
  
41   selector:
  
42   name: zookeeper
  
43   server-id: "2"
  
44   type: ClusterIP
  
45   clusterIP: 172.16.11.2
  
46 ---
  
47 apiVersion: v1
  
48 kind: Service
  
49 metadata:
  
50   name: zookeeper-3
  
51   labels:
  
52       name: zookeeper-3
  
53 spec:
  
54   ports:
  
55   - name: client
  
56       port: 2181
  
57       targetPort: 2181
  
58   - name: followers
  
59       port: 2888
  
60       targetPort: 2888
  
61   - name: election
  
62       port: 3888
  
63       targetPort: 3888
  
64   selector:
  
65   name: zookeeper
  
66   server-id: "3"
  
67   type: ClusterIP
  
68   clusterIP: 172.16.11.3
  
69 ---
  
70 apiVersion: v1
  
71 kind: ReplicationController
  
72 metadata:
  
73   name: zookeeper-1
  
74 spec:
  
75   replicas: 1
  
76   template:
  
77   metadata:
  
78       labels:
  
79         name: zookeeper
  
80         server-id: "1"
  
81   spec:
  
82       volumes:
  
83         - hostPath:
  
84             path: /data1/kubernetes/zookeeper/data1
  
85         name: data
  
86         - hostPath:
  
87             path: /data1/kubernetes/zookeeper/log1
  
88         name: log
  
89       containers:
  
90         - name: server
  
91         image: 10.11.150.76:5000/zookeeper-kb:3.4.6-1
  
92         env:
  
93             - name: SERVER_ID
  
94               value: "1"
  
95             - name: MAX_SERVERS
  
96               value: "3"
  
97         ports:
  
98             - containerPort: 2181
  
99             - containerPort: 2888
  
100             - containerPort: 3888
  
101         volumeMounts:
  
102             - mountPath: /opt/zookeeper/data
  
103               name: data
  
104             - mountPath: /opt/zookeeper/log
  
105               name: log
  
106       nodeSelector:
  
107         kubernetes.io/hostname: bx-42-199
  
108 ---
  
109 apiVersion: v1
  
110 kind: ReplicationController
  
111 metadata:
  
112   name: zookeeper-2
  
113 spec:
  
114   replicas: 1
  
115   template:
  
116   metadata:
  
117       labels:
  
118         name: zookeeper
  
119         server-id: "2"
  
120   spec:
  
121       volumes:
  
122         - hostPath:
  
123             path: /data1/kubernetes/zookeeper/data2
  
124         name: data
  
125         - hostPath:
  
126             path: /data1/kubernetes/zookeeper/log2
  
127         name: log
  
128       containers:
  
129         - name: server
  
130         image: 10.11.150.76:5000/zookeeper-kb:3.4.6-1
  
131         env:
  
132             - name: SERVER_ID
  
133               value: "2"
  
134             - name: MAX_SERVERS
  
135               value: "3"
  
136         ports:
  
137             - containerPort: 2181
  
138             - containerPort: 2888
  
139             - containerPort: 3888
  
140         volumeMounts:
  
141             - mountPath: /opt/zookeeper/data
  
142               name: data
  
143             - mountPath: /opt/zookeeper/log
  
144               name: log
  
145       nodeSelector:
  
146         kubernetes.io/hostname: bx-42-199
  
147 ---
  
148 apiVersion: v1
  
149 kind: ReplicationController
  
150 metadata:
  
151   name: zookeeper-3
  
152 spec:
  
153   replicas: 1
  
154   template:
  
155   metadata:
  
156       labels:
  
157         name: zookeeper
  
158         server-id: "3"
  
159   spec:
  
160       volumes:
  
161         - hostPath:
  
162             path: /data1/kubernetes/zookeeper/data3
  
163         name: data
  
164         - hostPath:
  
165             path: /data1/kubernetes/zookeeper/log3
  
166         name: log
  
167       containers:
  
168         - name: server
  
169         image: 10.11.150.76:5000/zookeeper-kb:3.4.6-1
  
170         env:
  
171             - name: SERVER_ID
  
172               value: "3"
  
173             - name: MAX_SERVERS
  
174               value: "3"
  
175         ports:
  
176             - containerPort: 2181
  
177             - containerPort: 2888
  
178             - containerPort: 3888
  
179         volumeMounts:
  
180             - mountPath: /opt/zookeeper/data
  
181               name: data
  
182             - mountPath: /opt/zookeeper/log
  
183               name: log
  
184       nodeSelector:
  
185         kubernetes.io/hostname: bx-42-199
  


View Code  通过 kubectl create -f zookeeper.yaml 创建三个service和对应的RC。注意container中已经把ZooKeeper的data和log目录映射到了主机的对应目录上用于持久化存储。
  创建完之后即可进行测试:
  

# 进入zookeeper对应的容器后找到zkCli.sh,用该客户端进行测试  

/opt/zookeeper/bin/zkCli.sh  
[zk: localhost:
2181(CONNECTED) 0]  

  
# 连接到k8s创建的zookeeper service (三个service任意一个都行)
  
[zk: localhost:
2181(CONNECTED) 0] connect 172.16.11.2:2181  
[zk:
172.16.11.2:2181(CONNECTED) 1]  

  
# 查看目录信息
  
[zk:
172.16.11.2:2181(CONNECTED) 1] ls /  

  
[zk:
172.16.11.2:2181(CONNECTED) 2] get /zookeeper  

  
cZxid
= 0x0  
ctime
= Thu Jan 01 00:00:00 UTC 1970  
mZxid
= 0x0  
mtime
= Thu Jan 01 00:00:00 UTC 1970  
pZxid
= 0x0  
cversion
= -1  
dataVersion
= 0  
aclVersion
= 0  
ephemeralOwner
= 0x0  
dataLength
= 0  
numChildren
= 1  
[zk:
172.16.11.2:2181(CONNECTED) 3]  


五、HBase部署
  以上准备工作做好后,下面部署具有两个master和两个regionserver的HBase集群,其中两个master分别位于两个节点上,两个regionserver也分别位于两个节点上;使用独立的HDFS和ZooKeeper服务。
  首先需要创建HBase的镜像,选择的HBase版本为hbase-0.98.10.1-hadoop2。Dockerfile内容如下:
  

1 FROM centos:6.6  
2 MAINTAINER openxxs <xiaoshengxu@sohu-inc.com>
  
3
  
4 RUN yum install -y java-1.7.0-openjdk-devel.x86_64
  
5 ENV JAVA_HOME=/usr/lib/jvm/jre
  
6
  
7 RUN yum install -y nc \
  
8   && yum install -y tar \
  
9   && mkdir /hbase-setup
  
10
  
11 WORKDIR /hbase-setup
  
12
  
13 COPY hbase-0.98.10.1-hadoop2-bin.tar.gz /hbase-setup/hbase-0.98.10.1-hadoop2-bin.tar.gz
  
14 RUN tar zxf hbase-0.98.10.1-hadoop2-bin.tar.gz -C /opt/ \
  
15   && ln -s /opt/hbase-0.98.10.1-hadoop2 /opt/hbase
  
16
  
17 ADD hbase-site.xml /opt/hbase/conf/hbase-site.xml
  
18 ADD start-k8s-hbase.sh /opt/hbase/bin/start-k8s-hbase.sh
  
19 RUN chmod +x /opt/hbase/bin/start-k8s-hbase.sh
  
20
  
21 WORKDIR /opt/hbase/bin
  
22
  
23 ENV PATH=$PATH:/opt/hbase/bin
  
24
  
25 CMD /opt/hbase/bin/start-k8s-hbase.sh
  

  配置文件hbase-site.xml内容如下:
  

<?xml version="1.0"?>  
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
  
<configuration>
  
<property>
  
<name>hbase.cluster.distributed</name>
  
<value>true</value>
  
</property>
  
<property>
  
<name>hbase.master.port</name>
  
<value>@HBASE_MASTER_PORT@</value>
  
</property>
  
<property>
  
<name>hbase.master.info.port</name>
  
<value>@HBASE_MASTER_INFO_PORT@</value>
  
</property>
  
<property>
  
<name>hbase.regionserver.port</name>
  
<value>@HBASE_REGION_PORT@</value>
  
</property>
  
<property>
  
<name>hbase.regionserver.info.port</name>
  
<value>@HBASE_REGION_INFO_PORT@</value>
  
</property>
  
<property>
  
<name>hbase.rootdir</name>
  
<value>hdfs://@HDFS_PATH@/@ZNODE_PARENT@</value>
  
</property>
  
<property>
  
<name>hbase.zookeeper.quorum</name>
  
<value>@ZOOKEEPER_IP_LIST@</value>
  
</property>
  
<property>
  
<name>hbase.zookeeper.property.clientPort</name>
  
<value>@ZOOKEEPER_PORT@</value>
  
</property>
  
<property>
  
<name>zookeeper.znode.parent</name>
  
<value>/@ZNODE_PARENT@</value>
  
</property>
  
</configuration>
  

  启动脚本 start-k8s-hbase.sh 主要完成参数替换、写入/etc/hosts、启动 hbase 的功能,内容如下:
  

1 #!/bin/bash  

2  
3 export HBASE_CONF_FILE=/opt/hbase/conf/hbase-site.xml
  
4 export HADOOP_USER_NAME=hdfs
  
5 export HBASE_MANAGES_ZK=false
  
6
  
7 sed -i "s/@HBASE_MASTER_PORT@/$HBASE_MASTER_PORT/g" $HBASE_CONF_FILE
  
8 sed -i "s/@HBASE_MASTER_INFO_PORT@/$HBASE_MASTER_INFO_PORT/g" $HBASE_CONF_FILE
  
9 sed -i "s/@HBASE_REGION_PORT@/$HBASE_REGION_PORT/g" $HBASE_CONF_FILE
  
10 sed -i "s/@HBASE_REGION_INFO_PORT@/$HBASE_REGION_INFO_PORT/g" $HBASE_CONF_FILE
  
11 sed -i "s/@HDFS_PATH@/$HDFS_SERVICE:$HDFS_PORT\/$ZNODE_PARENT/g" $HBASE_CONF_FILE
  
12 sed -i "s/@ZOOKEEPER_IP_LIST@/$ZOOKEEPER_SERVICE_LIST/g" $HBASE_CONF_FILE
  
13 sed -i "s/@ZOOKEEPER_PORT@/$ZOOKEEPER_PORT/g" $HBASE_CONF_FILE
  
14 sed -i "s/@ZNODE_PARENT@/$ZNODE_PARENT/g" $HBASE_CONF_FILE
  
15
  
16 for i in ${HBASE_MASTER_LIST[@]}
  
17 do
  
18    arr=(${i//:/ })
  
19    echo "${arr} ${arr}" >> /etc/hosts
  
20 done
  
21
  
22 for i in ${HBASE_REGION_LIST[@]}
  
23 do
  
24    arr=(${i//:/ })
  
25    echo "${arr} ${arr}" >> /etc/hosts
  
26 done
  
27
  
28 if [ "$HBASE_SERVER_TYPE" = "master" ]; then
  
29   /opt/hbase/bin/hbase master start > logmaster.log 2>&1
  
30 elif [ "$HBASE_SERVER_TYPE" = "regionserver" ]; then
  
31   /opt/hbase/bin/hbase regionserver start > logregion.log 2>&1
  
32 fi
  

  其中导出HADOOP_USER_NAME为hdfs用户,否则会报Permission Denied的错误;HBASE_MANAGES_ZK=false表示不使用HBase自带的ZooKeeper;HBASE_MASTER_LIST为HBase集群中除当前master外的其余master的服务地址和pod名的对应关系;HBASE_REGION_LIST为HBase集群中除当前regionserver外的其余regionserver的服务地址和pod名的对应关系;最后根据 HBASE_SERVER_TYPE 的取值来确定是启master还是regionserver。
  准备好这些文件后即可创建HBase的image:
  

docker build -t 10.11.150.76:5000/openxxs/hbase:1.0 .  
docker push
10.11.150.76:5000/openxxs/hbase:1.0  

  随后创建hbase.yaml文件,内容如下:

https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gifhttps://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif  

1 apiVersion: v1  

2 kind: Service  

3 metadata:  

4   name: hbase-master-1  
5 spec:
  
6   selector:
  
7   app: hbase-master
  
8   server-id: "1"
  
9   type: ClusterIP
  
10   clusterIP: "172.16.30.1"
  
11   ports:
  
12   - name: rpc
  
13       port: 60000
  
14       targetPort: 60000
  
15   - name: info
  
16       port: 60001
  
17       targetPort: 60001
  
18 ---
  
19 apiVersion: v1
  
20 kind: Service
  
21 metadata:
  
22   name: hbase-master-2
  
23 spec:
  
24   selector:
  
25   app: hbase-master
  
26   server-id: "2"
  
27   type: ClusterIP
  
28   clusterIP: "172.16.30.2"
  
29   ports:
  
30   - name: rpc
  
31       port: 60000
  
32       targetPort: 60000
  
33   - name: info
  
34       port: 60001
  
35       targetPort: 60001
  
36 ---
  
37 apiVersion: v1
  
38 kind: Service
  
39 metadata:
  
40   name: hbase-region-1
  
41 spec:
  
42   selector:
  
43   app: hbase-region
  
44   server-id: "1"
  
45   type: ClusterIP
  
46   clusterIP: "172.16.30.3"
  
47   ports:
  
48   - name: rpc
  
49       port: 60010
  
50       targetPort: 60010
  
51   - name: info
  
52       port: 60011
  
53       targetPort: 60011
  
54 ---
  
55 apiVersion: v1
  
56 kind: Service
  
57 metadata:
  
58   name: hbase-region-2
  
59 spec:
  
60   selector:
  
61   app: hbase-region
  
62   server-id: "2"
  
63   type: ClusterIP
  
64   clusterIP: "172.16.30.4"
  
65   ports:
  
66   - name: rpc
  
67       port: 60010
  
68       targetPort: 60010
  
69   - name: info
  
70       port: 60011
  
71       targetPort: 60011
  
72 ---
  
73 apiVersion: v1
  
74 kind: Pod
  
75 metadata:
  
76   name: hbase-master-1
  
77   labels:
  
78   app: hbase-master
  
79   server-id: "1"
  
80 spec:
  
81   containers:
  
82   - name: hbase-master-1
  
83       image: 10.11.150.76:5000/openxxs/hbase:1.0
  
84       ports:
  
85         - containerPort: 60000
  
86         - containerPort: 60001
  
87       env:
  
88         - name: HBASE_SERVER_TYPE
  
89         value: master
  
90         - name: HBASE_MASTER_PORT
  
91         value: "60000"
  
92         - name: HBASE_MASTER_INFO_PORT
  
93         value: "60001"
  
94         - name: HBASE_REGION_PORT
  
95         value: "60010"
  
96         - name: HBASE_REGION_INFO_PORT
  
97         value: "60011"
  
98         - name: HDFS_SERVICE
  
99         value: "hdfs-namenode-service.default.domeos.sohu"
  
100         - name: HDFS_PORT
  
101         value: "4231"
  
102         - name: ZOOKEEPER_SERVICE_LIST
  
103         value: "zookeeper-1.default.domeos.sohu,zookeeper-2.default.domeos.sohu,zookeeper-3.default.domeos.sohu"
  
104         - name: ZOOKEEPER_PORT
  
105         value: "2181"
  
106         - name: ZNODE_PARENT
  
107         value: hbase
  
108         - name: HBASE_MASTER_LIST
  
109         value: "172.16.30.2:hbase-master-2"
  
110         - name: HBASE_REGION_LIST
  
111         value: "172.16.30.3:hbase-region-1 172.16.30.4:hbase-region-2"
  
112   restartPolicy: Always
  
113   nodeSelector:
  
114   kubernetes.io/hostname: bx-42-199
  
115 ---
  
116 apiVersion: v1
  
117 kind: Pod
  
118 metadata:
  
119   name: hbase-master-2
  
120   labels:
  
121   app: hbase-master
  
122   server-id: "2"
  
123 spec:
  
124   containers:
  
125   - name: hbase-master-1
  
126       image: 10.11.150.76:5000/openxxs/hbase:1.0
  
127       ports:
  
128         - containerPort: 60000
  
129         - containerPort: 60001
  
130       env:
  
131         - name: HBASE_SERVER_TYPE
  
132         value: master
  
133         - name: HBASE_MASTER_PORT
  
134         value: "60000"
  
135         - name: HBASE_MASTER_INFO_PORT
  
136         value: "60001"
  
137         - name: HBASE_REGION_PORT
  
138         value: "60010"
  
139         - name: HBASE_REGION_INFO_PORT
  
140         value: "60011"
  
141         - name: HDFS_SERVICE
  
142         value: "hdfs-namenode-service.default.domeos.sohu"
  
143         - name: HDFS_PORT
  
144         value: "4231"
  
145         - name: ZOOKEEPER_SERVICE_LIST
  
146         value: "zookeeper-1.default.domeos.sohu,zookeeper-2.default.domeos.sohu,zookeeper-3.default.domeos.sohu"
  
147         - name: ZOOKEEPER_PORT
  
148         value: "2181"
  
149         - name: ZNODE_PARENT
  
150         value: hbase
  
151         - name: HBASE_MASTER_LIST
  
152         value: "172.16.30.1:hbase-master-1"
  
153         - name: HBASE_REGION_LIST
  
154         value: "172.16.30.3:hbase-region-1 172.16.30.4:hbase-region-2"
  
155   restartPolicy: Always
  
156   nodeSelector:
  
157   kubernetes.io/hostname: bx-42-198
  
158 ---
  
159 apiVersion: v1
  
160 kind: Pod
  
161 metadata:
  
162   name: hbase-region-1
  
163   labels:
  
164       app: hbase-region-1
  
165       server-id: "1"
  
166 spec:
  
167   containers:
  
168   - name: hbase-region-1
  
169       image: 10.11.150.76:5000/openxxs/hbase:1.0
  
170       ports:
  
171         - containerPort: 60010
  
172         - containerPort: 60011
  
173       env:
  
174         - name: HBASE_SERVER_TYPE
  
175         value: regionserver
  
176         - name: HBASE_MASTER_PORT
  
177         value: "60000"
  
178         - name: HBASE_MASTER_INFO_PORT
  
179         value: "60001"
  
180         - name: HBASE_REGION_PORT
  
181         value: "60010"
  
182         - name: HBASE_REGION_INFO_PORT
  
183         value: "60011"
  
184         - name: HDFS_SERVICE
  
185         value: "hdfs-namenode-service.default.domeos.sohu"
  
186         - name: HDFS_PORT
  
187         value: "4231"
  
188         - name: ZOOKEEPER_SERVICE_LIST
  
189         value: "zookeeper-1.default.domeos.sohu,zookeeper-2.default.domeos.sohu,zookeeper-3.default.domeos.sohu"
  
190         - name: ZOOKEEPER_PORT
  
191         value: "2181"
  
192         - name: ZNODE_PARENT
  
193         value: hbase
  
194         - name: HBASE_MASTER_LIST
  
195         value: "172.16.30.1:hbase-master-1 172.16.30.2:hbase-master-2"
  
196         - name: HBASE_REGION_LIST
  
197         value: "172.16.30.4:hbase-region-2"
  
198   restartPolicy: Always
  
199   nodeSelector:
  
200   kubernetes.io/hostname: bx-42-199
  
201 ---
  
202 apiVersion: v1
  
203 kind: Pod
  
204 metadata:
  
205   name: hbase-region-2
  
206   labels:
  
207       app: hbase-region-2
  
208       server-id: "2"
  
209 spec:
  
210   containers:
  
211   - name: hbase-region-2
  
212       image: 10.11.150.76:5000/openxxs/hbase:1.0
  
213       ports:
  
214         - containerPort: 60010
  
215         - containerPort: 60011
  
216       env:
  
217         - name: HBASE_SERVER_TYPE
  
218         value: regionserver
  
219         - name: HBASE_MASTER_PORT
  
220         value: "60000"
  
221         - name: HBASE_MASTER_INFO_PORT
  
222         value: "60001"
  
223         - name: HBASE_REGION_PORT
  
224         value: "60010"
  
225         - name: HBASE_REGION_INFO_PORT
  
226         value: "60011"
  
227         - name: HDFS_SERVICE
  
228         value: "hdfs-namenode-service.default.domeos.sohu"
  
229         - name: HDFS_PORT
  
230         value: "4231"
  
231         - name: ZOOKEEPER_SERVICE_LIST
  
232         value: "zookeeper-1.default.domeos.sohu,zookeeper-2.default.domeos.sohu,zookeeper-3.default.domeos.sohu"
  
233         - name: ZOOKEEPER_PORT
  
234         value: "2181"
  
235         - name: ZNODE_PARENT
  
236         value: hbase
  
237         - name: HBASE_MASTER_LIST
  
238         value: "172.16.30.1:hbase-master-1 172.16.30.2:hbase-master-2"
  
239         - name: HBASE_REGION_LIST
  
240         value: "172.16.30.3:hbase-region-1"
  
241   restartPolicy: Always
  
242   nodeSelector:
  
243   kubernetes.io/hostname: bx-42-198
  


View Code  说明:该yaml文件共创建了两个master服务、两个regionserver服务,以及对应的两个master Pods和两个regionserver Pods;Pod的restartPolicy设为Always表示如果该Pod挂掉的话将一直尝试重新启动它;以环境变量的形式将参数传递进Pod中,其中HDFS_SERVICE为HDFS服务经过skyDNS之后的对应域名,若未设置skyDNS则此处值设为HDFS服务对应的IP地址,ZOOKEEPER_SERVICE_LIST同理;HBASE_MASTER_LIST的值格式为 <master服务IP地址>:<master对应Pod名>,多个项之间以空格分隔,HBASE_REGION_LIST同理。
  接着就可以创建和查看HBase服务了:
  

# 创建  
$kubectl create
-f hbase.yaml  
service
"hbase-master-1" created  
service
"hbase-master-2" created  
service
"hbase-region-1" created  
service
"hbase-region-2" created  
pod
"hbase-master-1" created  
pod
"hbase-master-2" created  
pod
"hbase-region-1" created  
pod
"hbase-region-2" created  

  
# 查看pods
  
$kubectl get pods
  
NAME                  READY   STATUS         RESTARTS   AGE
  
hbase
-master-1          1/1       Running          0          5s  
hbase
-master-2          0/1       Pending          0          5s  
hbase
-region-1          1/1       Running          0          5s  
hbase
-region-2          0/1       Pending          0          5s  
hdfs
-datanode-1-nek2l   1/1       Running          3          7d  
hdfs
-datanode-2-vkbbt   1/1       Running          3          7d  
hdfs
-datanode-3-h4jvt   1/1       Running          3          7d  
hdfs
-namenode-1-cl0pj   1/1       Running          3          7d  
kube
-dns-v8-x8igc       3/3       Running          0          4h  
zookeeper
-1-ojhmy       1/1       Running          0          12h  
zookeeper
-2-cr73i       1/1       Running          0          12h  
zookeeper
-3-79ls0       1/1       Running          0          12h  

  
# 查看service
  
$kubectl get service
  
NAME                  CLUSTER_IP       EXTERNAL_IP    PORT(S)                                                                                                                                    SELECTOR                     AGE
  
hbase
-master-1          172.16.30.1      <none>         60000/TCP,60001/TCP                                                                                                                        app=hbase-master,server-id=1   17m  
hbase
-master-2          172.16.30.2      <none>         60000/TCP,60001/TCP                                                                                                                        app=hbase-master,server-id=2   17m  
hbase
-region-1          172.16.30.3      <none>         60010/TCP,60011/TCP                                                                                                                        app=hbase-region,server-id=1   17m  
hbase
-region-2          172.16.30.4      <none>         60010/TCP,60011/TCP                                                                                                                        app=hbase-region,server-id=2   17m  
hdfs
-namenode-service   172.16.20.1      <none>         4231/TCP,50020/TCP,50090/TCP,50070/TCP,50010/TCP,50075/TCP,8031/TCP,8032/TCP,8033/TCP,8040/TCP,8042/TCP,49707/TCP,22/TCP,8088/TCP,8030/TCP   app=hdfs-namenode            7d  
kube
-dns                172.16.40.1      <none>         53/UDP,53/TCP                                                                                                                              app=kube-dns,version=v8      10h  
kubernetes
172.16.0.1       <none>         443/TCP                                                                                                                                    <none>                         12d  
zookeeper
-1             172.16.11.1      <none>         2181/TCP,2888/TCP,3888/TCP                                                                                                                   name=zookeeper,server-id=1   13h  
zookeeper
-2             172.16.11.2      <none>         2181/TCP,2888/TCP,3888/TCP                                                                                                                   name=zookeeper,server-id=2   13h  
zookeeper
-3             172.16.11.3      <none>         2181/TCP,2888/TCP,3888/TCP                                                                                                                   name=zookeeper,server-id=3   13h  

  通过ZooKeeper的zkCli.sh可以看到/hbase下对应的master和rs的记录(显示乱码是由于系统显示时编码的原因,无影响):
  

ls /hbase  
[meta
-region-server, backup-masters, table, draining, region-in-transition, table-lock, running, master, namespace, hbaseid, online-snapshot, replication, splitWAL, recovering-regions, rs]  
[zk: localhost:
2181(CONNECTED) 1] ls /hbase/rs  
[
172.27.0.0,60010,1448896399329, 172.28.0.115,60010,1448896360650]  
[zk: localhost:
2181(CONNECTED) 2] get /hbase/master  

?master:60000??E*?O=PBUF  

  
base
-master-1???????*  
cZxid
= 0x100000186  
ctime
= Mon Nov 30 15:12:42 UTC 2015  
mZxid
= 0x100000186  
mtime
= Mon Nov 30 15:12:42 UTC 2015  
pZxid
= 0x100000186  
cversion
= 0  
dataVersion
= 0  
aclVersion
= 0  
ephemeralOwner
= 0x151563a5e37001a  
dataLength
= 60  
numChildren
= 0  

  可以通过docker exec进入到HBase对应的容器中进行表操作以测试HBase的工作状态:
  

# 进入198的hbase-master-2容器中  
[@bx_42_198
/opt/scs/openxxs]# docker exec -it f131fcf15a72 /bin/bash  

  
# 使用hbase shell对hbase进行操作
  
[iyunv@hbase
-master-2 bin]# hbase shell  

2015-11-30 15:15:58,632 INFO Configuration.deprecation: hadoop.native.lib is deprecated. Instead, use io.native.lib.available  
HBase Shell; enter
'help<RETURN>' for list of supported commands.  
Type
"exit<RETURN>" to leave the HBase Shell  
Version
0.98.10.1-hadoop2, rd5014b47660a58485a6bdd0776dea52114c7041e, Tue Feb 10 11:34:09 PST 2015  

  
# 通过status查看状态,这里显示的
2 dead 是之前测试时遗留的记录,无影响  
hbase(main):
001:0> status  

2015-11-30 15:16:03,551 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java>
2 servers, 2 dead, 1.5000 average load  

  
# 创建表
  
hbase(main):
002:0> create 'test','id','name'  
0 row(s) in 0.8330 seconds
  

  
=> Hbase::Table - test
  

  
# 查看表
  
hbase(main):003:0> list
  
TABLE
  
member
  
test
  
2 row(s) in 0.0240 seconds
  

  
=> ["member", "test"]
  

  
# 插入数据
  
hbase(main):004:0> put 'test','test1','id:5','addon'
  
0 row(s) in 0.1540 seconds
  

  
# 查看数据
  
hbase(main):005:0> get 'test','test1'
  
COLUMN                                       CELL
  
id:5                                          timestamp=1448906130803, value=addon
  
1 row(s) in 0.0490 seconds
  

  
# 进入199的hbase-master-1容器中查看从198上插入的数据
  
hbase(main):001:0> get 'test','test1'

  
2015-11-30 18:01:23,944 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java>  
COLUMN                                       CELL
  
id:5                                          timestamp=1448906130803, value=addon
  
1 row(s) in 0.2430 seconds
  

  从以上结果可以看出HBase算是在k8s中以不怎么完善的方式跑起来了。

六、讨论
  不得不维护/etc/hosts记录的原因是HBase中master之间、regionserver之间、master与regionserver之间都是通过hostname来彼此识别对方的,而k8s的DNS只针对service并没有对Pod进行解析。而如果把master和regionserver放在同一个Pod下的话存在磁盘资源共享冲突的问题(还没仔细研究)。Github讨论中下面的这段话很直白地说明了HBase对hostname的依赖:
  

1. Master uses ZooKeeper to run master election, the winner puts its  

hostname:port in ZooKeeper.  

2. RegionServers will register themselves to the winning Master through its  

hostname registered in ZooKeeper.  

3. We have a RegionServer with meta table/region (which stores Region ->  
RegionServer map), it stores its
hostname:port in ZooKeeper.  

4. When a client starts a request to HBase, it gets the hostname of the  
RegionServer with meta table from ZooKeeper, scan the meta table, and
find  
out the
hostname of the RegionServer it interests, and finally talks to the  
RegionServer through
hostname.  

  为解决这个问题目前尝试过的方法如下:
  1. 配置skyDNS:skyDNS只针对service进行解析,无法解析Pod的名称。如果向skyDNS中插入hostname的相关记录并动态维护的话或许可以解决该问题,目前正在尝试中。
  2. 更改创建 ReplicationController、Server、Pod、Container 时的各种设置参数,如 name、generateName等,然并卵。
  3. 创建container后启动 master 前通过脚本更改 hostname:Docker只允许在Create Container时进行hostname的修改(docker run自身有一个hostname的参数可以指定Container的hostname),但在容器运行之后并不允许修改,修改则报如下错误:docker Error: hostname: you must be root to change the hostname. 这个错误有些误导,事实上是docker的机制不允许你去修改hostname而不是权限问题,用root也没法改。
  4. 修改HBase参数使其上报到ZK中的值不是hostname而是IP地址:这个一度是前景光明的解决方案,但将hostname写入ZK在HBase中是硬编码在代码中的,并没有参数可以去设置此项。有人给出了个patch(戳这里),但测试结果并不好。
  关于第五部分HBase部署方案的说明:选择使用单Pod而不是ReplicationController,是因为k8s会在RC中Container的hostname后面加上随机字符以区分彼此,而单Pod的Pod name和hostname是一致的;restartPolicy设为Always算是为单Pod方式鲁棒性提供点小小的补偿吧;如果将Pod name设置为对应service的IP或域名怎样?然而hostname并不允许带点号;写入 /etc/hosts 中的IP选择了service的而非Pod的,因为Pod中的IP在运行前并不能获取到,而且在重启Pod后也会发生改变,而service的IP是不变的,因此选择了 serviceIP:PodName 这种对应关系。
  最根本的解决方案是让k8s支持hostname(或者说Pod)的DNS解析,前面配置ZooKeeper同样存在hostname这个问题(戳这里),后面将要部署的Kafka也会有这个问题。k8s的开发团队已经进行了许多讨论并准备解决这个问题了(戳这里),希望下个版本会有相关设置。
  关于Pod和hostname的DNS更多讨论可以参考:戳这里,这里,还有这里,再戳,戳,别再戳了。
页: [1]
查看完整版本: Kubernetes+Flannel 环境中部署HBase集群