内容简介:最近由于需要部署有状态服务,没有云环境的支持,不能很好的通过cloud provider调用云磁盘EBS,所以在node节点部署了一套glusterFS分布式文件存储系统,用来提供非结构化数据存储,存储图片,大文件等等.Kubernetes中使用GlusterFS作为持久化存储,要提供storageClass使用需要依赖Heketi工具。Heketi是一个具有resetful接口的glusterfs管理程序,作为kubernetes的Storage存储的external provisioner。 “Hek
说明
最近由于需要部署有状态服务,没有云环境的支持,不能很好的通过cloud provider调用云磁盘EBS,所以在node节点部署了一套glusterFS分布式文件存储系统,用来提供非结构化数据存储,存储图片,大文件等等.
Kubernetes中使用GlusterFS作为持久化存储,要提供storageClass使用需要依赖Heketi工具。Heketi是一个具有resetful接口的glusterfs管理程序,作为kubernetes的Storage存储的external provisioner。 “Heketi提供了一个RESTful管理界面,可用于管理GlusterFS卷的生命周期。借助Heketi,像OpenStack Manila,Kubernetes和OpenShift这样的云服务可以动态地配置GlusterFS卷和任何支持的持久性类型。Heketi将自动确定整个集群的brick位置,确保将brick及其副本放置在不同的故障域中。Heketi还支持任意数量的GlusterFS集群,允许云服务提供网络文件存储,而不受限于单个GlusterFS集群。
heketi:提供基于RESTful接口管理glusterfs的功能,可以方便的创建集群管理glusterfs的node,device,volume;与k8s结合可以创建动态的PV,扩展glusterfs存储的动态管理功能。主要用来管理glusterFS volume的生命周期,初始化时候就要分配好裸磁盘(未格式化)设备.
注意事项
modprobe dm_thin_pool
基础设施要求:
-
正在运行的Kubernetes集群,至少有三个node节点,每个节点至少有一个可用的裸块设备(如EBS卷或本地磁盘,就是没有格式化的).
-
用于运行GlusterFS节点必须为GlusterFS通信打开相应的端口(如果开启了防火墙的情况下,没开防火墙就不需要这些操作)。在每个节点上运行以下命令
iptables -N heketi` `iptables -A heketi -p tcp -m state --state NEW -m tcp --dport ``24007` `-j ACCEPT` `iptables -A heketi -p tcp -m state --state NEW -m tcp --dport ``24008` `-j ACCEPT` `iptables -A heketi -p tcp -m state --state NEW -m tcp --dport ``2222` `-j ACCEPT` `iptables -A heketi -p tcp -m state --state NEW -m multiport --dports ``49152``:``49251` `-j ACCEPT` `service iptables save`
Heketi安装
Heketi是由golang编写,直接静态编译运行二进制即可也可以通过yum安装以及 docker 部署,主要会产生db文件存储cluster、node、device、volume等信息。
#/bin/bash`
`wget -c https:``//github.com/heketi/heketi/releases/download/v8.0.0/heketi-v8.0.0.linux.amd64.tar.gz`
`tar xzf heketi-v8.``0.0``.linux.amd64.tar.gz`
`mkdir -pv /data/heketi/{bin,conf,data}`
`cp heketi/heketi.json /data/heketi/conf/`
`cp heketi/{heketi,heketi-cli} /data/heketi/bin/`
`mv heketi-v8.``0.0``.linux.amd64.tar.gz /tmp/`
创建ssh-key
我们glusterFS部署在k8s集群外,所以heketi通过ssh管理glusterFS。需要创建免秘钥登陆到所有glusterFS节点。
$ sudo ssh-keygen -f /data/heketi/conf/heketi_key -t rsa -N '' # 将公钥放到所有GlusterFS节点 $ sudo ssh-copy-id -i /data/heketi/conf/heketi_key.pub root@node1 $ ...
配置文件修改
参考 https://github.com/heketi/heketi/blob/master/client/cli/go/topology-sample.json
{`
`"_port_comment"``: ``"Heketi Server Port Number"``,`
`"port"``: ``"18080"``,`
`"_use_auth"``: ``"Enable JWT authorization. Please enable for deployment"``,`
`# 开启认证`
`"use_auth"``: ``true``,`
`"_jwt"``: ``"Private keys for access"``,`
`"jwt"``: {`
`"_admin"``: ``"Admin has access to all APIs"``,`
`# admin用户的key`
`"admin"``: {`
`"key"``: ``"adminkey"`
`},`
`"_user"``: ``"User only has access to /volumes endpoint"``,`
`"user"``: {`
`"key"``: ``"userkey"`
`}`
`},`
`"_glusterfs_comment"``: ``"GlusterFS Configuration"``,`
`"glusterfs"``: {`
`"_executor_comment"``: [`
`"Execute plugin. Possible choices: mock, ssh"``,`
`"mock: This setting is used for testing and development."``,`
`" It will not send commands to any node."``,`
`"ssh: This setting will notify Heketi to ssh to the nodes."``,`
`" It will need the values in sshexec to be configured."``,`
`"kubernetes: Communicate with GlusterFS containers over"``,`
`" Kubernetes exec api."`
`],`
`# 修改执行插件为ssh,并配置ssh的所需证书,注意要能对集群中的机器免密ssh登陆,使用ssh-copy-id把pub key拷到每台glusterfs服务器上`
`# heketi 通过ssh远程控制glusterfs的volume周期管理。`
`"executor"``: ``"ssh"``,`
`"_sshexec_comment"``: ``"SSH username and private key file information"``,`
`"sshexec"``: {`
`# ssh-keygen 生成,然后拷贝到glusterfs所在机器`
`"keyfile"``: ``"/data/heketi/conf/id_rsa"``,`
`"user"``: ``"root"``,`
`"port"``: ``"22"``,`
`# 每创建一个volume,heketi会刷新fstab配置保证机器自启动会自动挂载。`
`"fstab"``: ``"/etc/fstab"`
`},`
`"_kubeexec_comment"``: ``"Kubernetes configuration"``,`
`"kubeexec"``: {`
`"host"` `:``"[https://kubernetes.host:8443"](https://kubernetes.host:8443/)``,`
`"cert"` `: ``"/path/to/crt.file"``,`
`"insecure"``: ``false``,`
`"user"``: ``"kubernetes username"``,`
`"password"``: ``"password for kubernetes user"``,`
`"namespace"``: ``"OpenShift project or Kubernetes namespace"``,`
`"fstab"``: ``"Optional: Specify fstab file on node. Default is /etc/fstab"`
`},`
`"_db_comment"``: ``"Database file name"``,`
`# 修改heketi默认db路径`
`"db"``: ``"/data/heketi/data/heketi.db"``,`
`"_loglevel_comment"``: [`
`"Set log level. Choices are:"``,`
`" none, critical, error, warning, info, debug"``,`
`"Default is warning"`
`],`
`"loglevel"` `: ``"debug"`
`}`
`}`
注意:
- 需要说明的是,heketi有三种executor,分别为mock、ssh、kubernetes,建议在测试环境使用mock,生产环境使用ssh,当glusterfs以容器的方式部署在kubernetes上时,才使用kubernetes。我们这里将glusterfs和heketi独立部署,使用ssh的方式。
- 使用docker部署的时候,还需将/var/lib/heketi/mounts 挂载至容器里面, heketi 会将此目录作为 gluster volume的挂载点。
[root``@k8s1` `~]# more /etc/fstab` `#` `# /etc/fstab` `# Created by anaconda on Sun Oct ``15` `15``:``19``:``00` `2017` `#` `# Accessible filesystems, by reference, are maintained under ``'/dev/disk'` `# See man pages fstab(``5``), findfs(``8``), mount(``8``) and/or blkid(``8``) ``for` `more info` `#` `UUID=eb448abb-``3012``-4d8d-bcde-94434d586a31 / ext4 defaults ``1` `1` `UUID=63b64b3a-``2961``-``4798``-b7f1-cc97484ee49f /data ext4 defaults ``1` `1` `/dev/mapper/vg_fd3a11426117508af77aa38e9565ce65-brick_4b7854340fa8ee78106b1b1446abf078 /var/lib/heketi/mounts/vg_fd3a11426117508af77aa38e9565ce65/brick_4b` `7854340fa8ee78106b1b1446abf078 xfs rw,inode64,noatime,nouuid ``1` `2` `/dev/mapper/vg_fd3a11426117508af77aa38e9565ce65-brick_1904166cdf0846ee649ccefe66ce1e50 /var/lib/heketi/mounts/vg_fd3a11426117508af77aa38e9565ce65/brick_19` `04166cdf0846ee649ccefe66ce1e50 xfs rw,inode64,noatime,nouuid ``1` `2`
systemd配置
# cat /usr/lib/system/systemd/heketi.service` `[Unit]` `Description=RESTful based volume management framework ``for` `GlusterFS` `Before=network-online.target` `After=network-online.target` `Documentation=https:``//github.com/heketi/heketi` `[Service]` `Type=simple` `LimitNOFILE=``65536` `ExecStart=/data/heketi/bin/heketi --config=/data/heketi/conf/heketi.json` `KillMode=process` `Restart=on-failure` `RestartSec=``5` `SuccessExitStatus=``15` `StandardOutput=syslog` `StandardError=syslog` `[Install]` `WantedBy=multi-user.target`
启动heketi服务
$ sudo systemctl start heketi $sudo systemctl enable heketi $sudo systemctl status heketi
Heketi管理GlusterFS
添加cluster
$ sudo heketi-cli --user admin --server http://10.111.209.188:18080 --secret adminkey --json cluster create
{"id":"d102a74079dd79aceb3c70d6a7e8b7c4","nodes":[],"volumes":[],"block":true,"file":true,"blockvolumes":[]}
将3个glusterfs节点作为node添加到cluster
由于我们开启了heketi认证,所以每次执行heketi-cli操作时,都需要带上一堆的认证字段,比较麻烦,我在这里创建一个别名来避免相关操作:
$ sudo alias heketi-cli='heketi-cli --server "[http://192.168.75.175:18080"](http://192.168.75.175:18080/) --user "admin" --secret "adminkey"'
添加节点
$sudo heketi-cli --json node add --cluster "d102a74079dd79aceb3c70d6a7e8b7c4" --management-host-name k8s1 --storage-host-name 10.111.209.188 --zone 1 $sudo heketi-cli --json node add --cluster "d102a74079dd79aceb3c70d6a7e8b7c4" --management-host-name k8s1 --storage-host-name 10.111.209.189 --zone 1 $sudo heketi-cli --json node add --cluster "d102a74079dd79aceb3c70d6a7e8b7c4" --management-host-name k8s3 --storage-host-name 10.111.209.190 --zone 1
注意: 如果heketi 运行账号为非root,需要保证有sudo权限。
添加device
机器只是作为gluster的运行单元,volume是基于device创建的。同时需要特别说明的是,目前heketi仅支持使用裸分区或裸磁盘(未格式化)添加为device,不支持文件系统。
# --node参数给出的id是上一步创建node时生成的,这里只给出一个添加的示例,实际配置中,要添加每一个节点的每一块用于存储的硬盘` $ sudo heketi-cli -json device add -name="/dev/vdc1" --node ``"2e4dc73fb2657586e7a9e64e39c8f01a" $ sudo heketi-cli node list` Id:2e4dc73fb2657586e7a9e64e39c8f01a Cluster:d102a74079dd79aceb3c70d6a7e8b7c4 Id:43a661a917c42dfe9b6659b8c9d848e9 Cluster:d102a74079dd79aceb3c70d6a7e8b7c4 Id:ce5a9e2983d067051b6ccad0a4bd0988 Cluster:d102a74079dd79aceb3c70d6a7e8b7c4
生产实际配置
以上ad-hoc命令均可通过配置文件创建然后导入:
$ sudo cat /data/heketi/conf/topology.json
{
"clusters": [
{
"nodes": [
{
"node": {
"hostnames": {
"manage": [
"k8s1"
],
"storage": [
"10.111.209.188"
]
},
"zone": 1
},
"devices": [
"/dev/vdc1"
]
},
{
"node": {
"hostnames": {
"manage": [
"k8s2"
],
"storage": [
"10.111.209.189"
]
},
"zone": 1
},
"devices": [
"/dev/vdc1"
]
},
{
"node": {
"hostnames": {
"manage": [
"k8s3"
],
"storage": [
"10.111.209.190"
]
},
"zone": 1
},
"devices": [
"/dev/vdc1"
]
}
]
}
]
}
创建:
$ sudo heketi-cli topology load --json topology.json
添加volume
这里仅仅是做一个测试,实际使用中,会由kubernetes自动创建pv.
创建一个大小为3G,副本为2的volume
$ sudo heketi-cli volume create --size 3 --replica 2 Name: vol_685f9aea1896f53f30a22a9d15de1680 Size: 3 Volume Id: 685f9aea1896f53f30a22a9d15de1680 Cluster Id: d102a74079dd79aceb3c70d6a7e8b7c4 Mount: 10.111.209.188:vol_685f9aea1896f53f30a22a9d15de1680 Mount Options: backup-volfile-servers=10.111.209.190,10.111.209.189 Block: false Free Size: 0 Reserved Size: 0 Block Hosting Restriction: (none) Block Volumes: [] Durability Type: replicate Distributed+Replica: 2
kubernetes storageclass 配置
创建storageclass
添加storageclass-glusterfs.yaml文件,内容如下:
--- apiVersion: v1 kind: Secret metadata: name: heketi-secret namespace: default data: # base64 encoded password. E.g.: echo -n "mypassword" | base64 key: YWRtaW5rZXk= type: kubernetes.io/glusterfs --- apiVersion: storage.k8s.io/v1beta1 kind: StorageClass metadata: name: glusterfs provisioner: kubernetes.io/glusterfs allowVolumeExpansion: true parameters: resturl: "http://10.111.209.188:18080" clusterid: "6fd6bf78b84315e12abcf8b6db6b1a40" restauthenabled: "true" restuser: "admin" #secretNamespace: "default" #secretName: "heketi-secret" restuserkey: "adminkey" gidMin: "40000" gidMax: "50000" volumetype: "replicate:2" # kubectl apply -f glusterfs-storageclass.yml secret/heketi-secret created storageclass.storage.k8s.io/glusterfs created # kubectl get sc NAME PROVISIONER AGE glusterfs (default) kubernetes.io/glusterfs 2m19s
注意:
- storageclass.beta.kubernetes.io/is-default-class : "true" #表示此storageClass作为default sc,创建pvc不指定sc时,默认使用此sc.
- reclaimPolicy: Retain #表示pv回收策略为保留,删除pvc时将不删除pv。
更详细的用法参考: https://kubernetes.io/docs/concepts/storage/storage-classes/#glusterfs
创建pvc
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: glusterfs-mysql1
namespace: default
annotations:
volume.beta.kubernetes.io/storage-class: "glusterfs"
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
# kubectl create -f glusterfs-pvc.yaml
persistentvolumeclaim/glusterfs-mysql1 created
# kubectl get pv,pvc
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/pvc-11aa48c5-fe0f-11e8-9803-00163e13b711 1Gi RWX Retain Bound default/glusterfs-mysql1 glusterfs 2m
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/glusterfs-mysql1 Bound pvc-11aa48c5-fe0f-11e8-9803-00163e13b711 1Gi RWX glusterfs 2m20s
创建pod,使用pvc
---
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
name: mysql
namespace: default
spec:
replicas: 1
template:
metadata:
labels:
name: mysql
spec:
containers:
- name: mysql
image: mysql:5.7
imagePullPolicy: IfNotPresent
env:
- name: MYSQL_ROOT_PASSWORD
value: root123456
ports:
- containerPort: 3306
volumeMounts:
- name: gluster-mysql-data
mountPath: "/var/lib/mysql"
volumes:
- name: gluster-mysql-data
persistentVolumeClaim:
claimName: glusterfs-mysql1
# kubectl create -f /etc/kubernetes/mysql-deployment.yaml
deployment.extensions/mysql created
# kubectl exec -it mysql-84786cf494-hb2ss -- df -PHT /var/lib/mysql
Filesystem Type Size Used Avail Use% Mounted on
10.111.209.188:vol_426e62366141c789dac33f2e68dfb13b fuse.glusterfs 1.1G 266M 798M 25% /var/lib/mysql
创建statefulset
---
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: nginx
spec:
selector:
matchLabels:
app: nginx # has to match .spec.template.metadata.labels
serviceName: "nginx"
replicas: 3 # by default is 1
template:
metadata:
labels:
app: nginx # has to match .spec.selector.matchLabels
spec:
terminationGracePeriodSeconds: 10
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "glusterfs"
resources:
requests:
storage: 1Gi
# kubectl apply -f nginx-statefulset.yml
service/nginx created
statefulset.apps/nginx created
# kubectl get pod,pv,pvc
NAME READY STATUS RESTARTS AGE
pod/nginx-0 1/1 Running 0 116s
pod/nginx-1 1/1 Running 0 98s
pod/nginx-2 1/1 Running 0 91s
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/pvc-5ac3eba9-fe12-11e8-a19e-00163e14b18f 1Gi RWO Retain Bound default/www-nginx-0 glusterfs 99s
persistentvolume/pvc-65f27519-fe12-11e8-a19e-00163e14b18f 1Gi RWO Retain Bound default/www-nginx-1 glusterfs 93s
persistentvolume/pvc-69b31512-fe12-11e8-a19e-00163e14b18f 1Gi RWO Retain Bound default/www-nginx-2 glusterfs 86s
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/www-nginx-0 Bound pvc-5ac3eba9-fe12-11e8-a19e-00163e14b18f 1Gi RWO glusterfs 116s
persistentvolumeclaim/www-nginx-1 Bound pvc-65f27519-fe12-11e8-a19e-00163e14b18f 1Gi RWO glusterfs 98s
persistentvolumeclaim/www-nginx-2 Bound pvc-69b31512-fe12-11e8-a19e-00163e14b18f 1Gi RWO glusterfs 91s
我们可以看到RECLAIM POLICY: Retain ,经过测试
- 删除pvc,pv status会变成Released状态,且不会被删除
- 删除pv, 通过heketi-cli volume list查看,volume不会被删除
kubernetes pv和gluster volume不一致时,可使用heketi来统一管理volume.此文档heketi和glusterfs都在kubernetes集群外部署。对于支持AWS EBS的磁盘,可通过EBS storageClass方式将glusterFS heketi部署在容器中管理.参考 https://github.com/gluster/gluster-kubernetes
参考文档
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 动态为表添加存储时间字段
- react hooks 实现动态表单存储
- 在 Kubernetes 中,如何动态配置本地存储?
- UNPIVOT逆透视以及动态逆透视存储过程
- 如何为kubernetes提供ceph类型的动态存储卷
- 技术动态 | eBay开源分布式知识图谱存储Beam,支持类SPARQL查询
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
HTML Dog
Patrick Griffiths / New Riders Press / 2006-11-22 / USD 49.99
For readers who want to design Web pages that load quickly, are easy to update, accessible to all, work on all browsers and can be quickly adapted to different media, this comprehensive guide represen......一起来看看 《HTML Dog》 这本书的介绍吧!