前言

Kubernetes+GlusterFS超融合是PaaS层的经典架构。国内安装Kubernetes很多因为“科学上网”的问题,导致无法完成安装。本篇文章将告诉大家一个既不用“科学上网”,也不用私有仓库,就能很顺利安装Kubernetes的方法。同时,使GlusterFS运行在容器中,完成Kubernetes+GlusterFS的超融合搭建。

一、实践环境准备

1.服务器虚拟机准备

IP地址 节点角色 CPU Memory Hostname 磁盘
192.168.3.80 master and etcd >=2c >=2G master sda、sdb
192.168.3.81 worker and GlusterFS >=2c >=2G node1 sda、sdb
192.168.3.82 worker and GlusterFS >=2c >=2G node2 sda、sdb
192.168.3.83 worker and GlusterFS >=2c >=2G node3 sda、sdb

本实验在3台服务器主机中部署GlusterFS容器,要求GlusterFS所在主机至少具备sda、sdb两个磁盘,即sda作为系统盘,sdb作为GlusterFS数据盘。若只部署Kubernetes不部署GlusterFS,可只部署其中两个节点,且每个节点只需有sda一块盘即可。

注意:
hostname不能有大写字母,比如Master这样。

2.软件版本

系统类型 Kubernetes版本 docker版本 kubeadm版本 kubectl版本 kubelet版本
CentOS7.5.1804 v1.13 18.06.1-ce v1.13 v1.13 v1.13

注意:
这里采用的软件版本,请大家严格与我保持一致! 开源软件,版本非常敏感和重要!

3.环境初始化操作

注意:此步骤在所有节点操作

3.1 配置hostname

hostnamectl set-hostname master

每台机器上设置对应好hostname,不同的主机设置不同的hostname,只需更改master为正确的主机名即可。注意,不能有大写字母!
3.2 配置/etc/hosts
hosts文件非常重要,请在每个节点上执行:

cat <> /etc/hosts 
192.168.3.80 master
192.168.3.81 node1
192.168.3.82 node2
192.168.3.83 node3
EOF

3.3 关闭防火墙、selinux、swap
关闭防火墙

systemctl stop firewalld
systemctl disable firewalld

关闭Selinux

setenforce 0
sed -i "s/^SELINUX=enforcing/SELINUX=disabled/g" /etc/sysconfig/selinux
sed -i "s/^SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
sed -i "s/^SELINUX=permissive/SELINUX=disabled/g" /etc/sysconfig/selinux
sed -i "s/^SELINUX=permissive/SELINUX=disabled/g" /etc/selinux/config 

关闭Swap

swapoff -a
sed -i 's/.*swap.*/#&/' /etc/fstab

加载br_netfilter

modprobe br_netfilter

3.4 配置内核参数
配置sysctl内核参数

cat > /etc/sysctl.d/k8s.conf <

生效文件

sysctl -p /etc/sysctl.d/k8s.conf

修改Linux 资源配置文件,调高ulimit最大打开数和systemctl管理的服务文件最大打开数

echo "* soft nofile 655360" >> /etc/security/limits.conf
echo "* hard nofile 655360" >> /etc/security/limits.conf
echo "* soft nproc 655360"  >> /etc/security/limits.conf
echo "* hard nproc 655360"  >> /etc/security/limits.conf
echo "* soft  memlock  unlimited"  >> /etc/security/limits.conf
echo "* hard memlock  unlimited"  >> /etc/security/limits.conf
echo "DefaultLimitNOFILE=1024000"  >> /etc/systemd/system.conf 
echo "DefaultLimitNPROC=1024000"  >> /etc/systemd/system.conf

4.配置CentOS YUM源

注意:
此步骤在所有节点操作

配置国内tencent yum源地址、epel源地址、Kubernetes源地址

yum install -y wget 
rm -rf  /etc/yum.repos.d/*
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.cloud.tencent.com/repo/centos7_base.repo  
wget -O /etc/yum.repos.d/epel.repo http://mirrors.cloud.tencent.com/repo/epel-7.repo  
yum clean all && yum makecache

配置国内Kubernetes源地址

cat < /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes 
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg  
EOF

5.安装依赖软件包

注意:
此步骤在所有节点操作

安装以下依赖包,方便后期使用

yum install  -y conntrack ipvsadm ipset jq sysstat curl iptables libseccomp bash-completion yum-utils device-mapper-persistent-data lvm2 net-tools conntrack-tools vim libtool-ltdl

6.时间同步配置

注意:
此步骤在所有节点操作

Kubernetes是分布式的,各个节点系统时间需要同步对应上。

yum install chrony -y
systemctl enable chronyd.service && systemctl start chronyd.service && systemctl status chronyd.service
chronyc sources

运行date命令看下系统时间,过一会儿时间就会同步。
7.配置节点间ssh互信
配置ssh互信,那么节点之间就能无密访问,方便日后执行自动化部署

ssh-keygen     # 每台机器执行这个命令, 一路回车即可
ssh-copy-id  node1    # 到master上拷贝公钥到其他节点,输入 yes和密码
ssh-copy-id  node2
ssh-copy-id  node3

8.初始化环境配置检查

  • 重启,做完以上所有操作,最好reboot重启一遍
  • ping 每个节点hostname 看是否能ping通
  • ssh 对方hostname看互信是否无密码访问成功
  • 执行date命令查看每个节点时间是否正确
  • 执行 ulimit -Hn 看下最大文件打开数是否是655360
  • cat /etc/sysconfig/selinux |grep disabled 查看下每个节点selinux是否都是disabled状态

二、docker安装

Kubernetes 是容器调度编排PaaS平台,那么docker是必不可少要安装的。最新Kubernetes 1.13 支持最新的docker版本是18.06.1,那么我们就安装最新的 docker-ce 18.06.1
具体Kubernetes changelog 文档地址:
https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.12.md#v1123

注意:此步骤在所有节点操作

  1. remove旧版本docker
    yum remove -y docker docker-ce docker-common docker-selinux docker-engine
  2. 设置docker yum源
    yum-config-manager  --add-repo  https://download.docker.com/linux/centos/docker-ce.repo
  3. 列出docker版本
    yum list docker-ce --showduplicates | sort -r
  4. 安装docker 指定18.06.1
    yum install -y docker-ce-18.06.1.ce-3.el7
  5. 配置镜像加速器和docker数据存放路径
    tee /etc/docker/daemon.json <<-'EOF'
    {  
    "registry-mirrors": ["https://q2hy3fzi.mirror.aliyuncs.com"],
    "graph": "/tol/docker-data"
    }
    EOF
  6. 启动docker
    systemctl daemon-reload && systemctl restart docker && systemctl enable docker && systemctl status docker

    查看docker 版本

    docker --version

三、安装kubeadm、kubelet、kubectl

注意:
是所有节点都得安装(包括node节点)

  1. 工具说明
    • kubeadm: 部署集群用的命令
    • kubelet: 在集群中每台机器上都要运行的组件,负责管理pod、容器的生命周期
    • kubectl: 集群管理工具
  2. yum 安装
    安装工具
    yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes

    启动kubelet

    systemctl enable kubelet && systemctl start kubelet

    注意:
    kubelet 服务会暂时启动不了,先不用管它。

四、镜像下载准备

注意:
此步骤在Master节点操作

  1. 初始化获取要下载的镜像列表
    使用kubeadm来搭建Kubernetes,那么就需要下载得到Kubernetes运行的对应基础镜像,比如:kube-proxy、kube-apiserver、kube-controller-manager等等 。那么有什么方法可以得知要下载哪些镜像呢?从kubeadm v1.11+版本开始,增加了一个kubeadm config print-default 命令,可以让我们方便的将kubeadm的默认配置输出到文件中,这个文件里就包含了搭建K8S对应版本需要的基础配置环境。另外,我们也可以执行 kubeadm config images list 命令查看依赖需要安装的镜像列表。

注意:这个列表显示的tag名字和镜像版本号,从Kubernetes v1.12+开始,镜像名后面不带amd64, arm, arm64, ppc64le 这样的标识了。

1.1 生成默认kubeadm.conf文件
执行这个命令就生成了一个kubeadm.conf文件

kubeadm config print init-defaults > kubeadm.conf      

1.2 绕过墙下载镜像方法(注意认真看,后期版本安装也可以套用这方法)
注意这个配置文件默认会从google的镜像仓库地址k8s.gcr.io下载镜像,如果你没有科学上网,那么就会下载不来。因此,我们通过下面的方法把地址改成国内的,比如用阿里的:

sed -i "s/imageRepository: .*/imageRepository: registry.aliyuncs.com\/google_containers/g" kubeadm.conf

1.3 指定kubeadm安装的Kubernetes版本
我们这次要安装的Kubernetes版本是最新的v1.13,所以我们要修改下:

sed -i "s/kubernetesVersion: .*/kubernetesVersion: v1.13.0/g" kubeadm.conf

1.4 下载需要用到的镜像
kubeadm.conf修改好后,我们执行下面命令就可以自动从国内下载需要用到的镜像了:

kubeadm config images pull --config kubeadm.conf

自动下载v1.13需要用到的镜像,执行 docker images 可以看到下载好的镜像列表:

注:除了上面的方法,还有一种方式是搭建自己的镜像仓库。不过前提你得下载好对应的版本镜像,然后上传到你镜像仓库里,然后pull下载。不过上面我提到的方法更加方便省事。

1.5 docker tag 镜像
镜像下载好后,我们还需要tag下载好的镜像,让下载好的镜像都是带有 k8s.gcr.io 标识的,目前我们从阿里下载的镜像 标识都是,如果不打tag变成k8s.gcr.io,那么后面用kubeadm安装会出现问题,因为kubeadm里面只认 google自身的模式。我们执行下面命令即可完成tag标识更换:

docker tag registry.aliyuncs.com/google_containers/kube-apiserver:v1.13.0    k8s.gcr.io/kube-apiserver:v1.13.0
docker tag registry.aliyuncs.com/google_containers/kube-controller-manager:v1.13.0    k8s.gcr.io/kube-controller-manager:v1.13.0
docker tag registry.aliyuncs.com/google_containers/kube-scheduler:v1.13.0   k8s.gcr.io/kube-scheduler:v1.13.0
docker tag registry.aliyuncs.com/google_containers/kube-proxy:v1.13.0   k8s.gcr.io/kube-proxy:v1.13.0
docker tag registry.aliyuncs.com/google_containers/pause:3.1    k8s.gcr.io/pause:3.1
docker tag registry.aliyuncs.com/google_containers/etcd:3.2.24    k8s.gcr.io/etcd:3.2.24
docker tag registry.aliyuncs.com/google_containers/coredns:1.2.6    k8s.gcr.io/coredns:1.2.6

1.6 docker rmi 清理下载的镜像
执行完上面tag镜像的命令,我们还需要把带有 registry.aliyuncs.com 标识的镜像删除,执行:

docker rmi registry.aliyuncs.com/google_containers/kube-apiserver:v1.13.0 
docker rmi registry.aliyuncs.com/google_containers/kube-controller-manager:v1.13.0
docker rmi registry.aliyuncs.com/google_containers/kube-scheduler:v1.13.0 
docker rmi registry.aliyuncs.com/google_containers/kube-proxy:v1.13.0
docker rmi registry.aliyuncs.com/google_containers/pause:3.1
docker rmi registry.aliyuncs.com/google_containers/etcd:3.2.24
docker rmi registry.aliyuncs.com/google_containers/coredns:1.2.6

1.7 查看下载的镜像列表
执行docker images命令,即可查看到,这里结果如下,您下载处理后,结果需要跟这里的一致:

注:以上操作其实可以写到一个脚本里,然后自动处理。另外两个master节点,重复上面的操作下载即可。

五、部署master节点

  1. kubeadm init 初始化master节点

    kubeadm init --kubernetes-version=v1.13.0 --pod-network-cidr=172.22.0.0/16 --apiserver-advertise-address=192.168.3.80

    这里我们定义POD的网段为: 172.22.0.0/16 ,然后api server地址就是master本机IP地址。

  2. 初始化成功后,/etc/kubernetes/ 会生成下面文件

  3. 同时最后会生成一句话
    kubeadm join 192.168.3.80:6443 --token ebkb2r.l3v58ta1upvonxfv --discovery-token-ca-cert-hash sha256:2b07db998d0a74bce9ddcd8d2c2605cbc883351bdc9336416c49bcf656aece69

    这个我们记录下,到时候添加node的时候要用到。

  4. 验证测试
    配置kubectl命令
    mkdir -p /root/.kube
    cp /etc/kubernetes/admin.conf /root/.kube/config

    执行获取pods列表命令,查看相关状态

    kubectl get pods --all-namespaces

其中coredns pod处于Pending状态,这个先不管。
我们也可以执行 kubectl get cs 查看集群的健康状态:

六、部署calico网络 (在master上执行)

calico介绍:Calico是一个纯三层的方案,其好处是它整合了各种云原生平台(Docker、Mesos 与 OpenStack 等),每个 Kubernetes 节点上通过 Linux Kernel 现有的 L3 forwarding 功能来实现 vRouter 功能。

  1. 下载calico 官方镜像
    我们这里要下载三个镜像,分别是calico-node:v3.1.4、calico-cni:v3.1.4、calico-typha:v3.1.4
    直接运行 docker pull 下载即可
    docker pull calico/node:v3.1.4
    docker pull calico/cni:v3.1.4
    docker pull calico/typha:v3.1.4
  2. tag 这三个calico镜像
    docker tag calico/node:v3.1.4 quay.io/calico/node:v3.1.4
    docker tag calico/cni:v3.1.4 quay.io/calico/cni:v3.1.4
    docker tag calico/typha:v3.1.4 quay.io/calico/typha:v3.1.4
  3. 删除原有镜像
    docker rmi calico/node:v3.1.4
    docker rmi calico/cni:v3.1.4
    docker rmi calico/typha:v3.1.4
  4. 部署calico

4.1.下载执行rbac-kdd.yaml文件

curl https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/hosted/rbac-kdd.yaml -O
kubectl apply -f rbac-kdd.yaml

4.2 下载配置calico.yaml文件

curl https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/hosted/kubernetes-datastore/policy-only/1.7/calico.yaml -O

把ConfigMap 下的 typha_service_name 值由none变成 calico-typha,设置 Deployment 类目的 spec 下的replicas值,我们这里设置为 1。
4.3 定义POD网段
我们找到CALICO_IPV4POOL_CIDR,然后值修改成之前定义好的POD网段,我这里是172.22.0.0/16

4.4 开启bird模式
把 CALICO_NETWORKING_BACKEND 值设置为 bird ,这个值是设置BGP网络后端模式

4.5 部署calico.yaml文件
上面参数设置调优完毕,我们执行下面命令彻底部署calico

kubectl apply -f calico.yaml

查看状态

kubectl get pods --all-namespaces

这里calico-typha 没起来,那是因为我们的node 计算节点还没启动和安装。

七、部署node节点

注意:
本文档此步骤在所有节点操作,Master节点在本次环境既做Master又做node。当然,此步骤可不在Master节点执行,只在node节点执行。

  1. 下载安装镜像(在node上执行)
    node上也是需要下载安装一些镜像的,需要下载的镜像为:kube-proxy:v1.13、pause:3.1、calico-node:v3.1.4、calico-cni:v3.1.4、calico-typha:v3.1.4

1.1 下载镜像

docker pull registry.aliyuncs.com/google_containers/kube-proxy:v1.13.0
docker pull registry.aliyuncs.com/google_containers/pause:3.1
docker pull calico/node:v3.1.4
docker pull calico/cni:v3.1.4
docker pull calico/typha:v3.1.4
docker tag registry.aliyuncs.com/google_containers/kube-proxy:v1.13.0   k8s.gcr.io/kube-proxy:v1.13.0
docker tag registry.aliyuncs.com/google_containers/pause:3.1    k8s.gcr.io/pause:3.1
docker tag calico/node:v3.1.4 quay.io/calico/node:v3.1.4
docker tag calico/cni:v3.1.4 quay.io/calico/cni:v3.1.4
docker tag calico/typha:v3.1.4 quay.io/calico/typha:v3.1.4
docker rmi registry.aliyuncs.com/google_containers/kube-proxy:v1.13.0
docker rmi registry.aliyuncs.com/google_containers/pause:3.1
docker rmi calico/node:v3.1.4
docker rmi calico/cni:v3.1.4
docker rmi calico/typha:v3.1.4

1.2. 把node加入集群里
加node计算节点非常简单,在node上运行:

kubeadm join 192.168.1.11:6443 --token zs4s82.r9svwuj78jc3px43 --discovery-token-ca-cert-hash sha256:45063078d23b3e8d33ff1d81e903fac16fe6c8096189600c709e3bf0ce051ae8

两个节点运行的参数命令一样,运行完后,我们在master节点上运行 kubectl get nodes 命令查看node是否正常

# kubectl get nodes
NAME     STATUS   ROLES    AGE   VERSION
master   Ready    master   77m   v1.13.4
node1    Ready       57m   v1.13.4
node2    Ready       57m   v1.13.4
node3    Ready       57m   v1.13.4

到此,集群的搭建完成了90%,剩下一个是搭建dashboard。

八、部署dashboard

注意:此步骤在Master节点操作
部署dashboard之前,我们需要生成证书,不然后面会https访问登录不了。

  1. 生成私钥和证书签名请求
mkdir -p /etc/kubernetes/certs 
cd  /etc/kubernetes/certs
openssl genrsa -des3 -passout pass:x -out dashboard.pass.key 2048
openssl rsa -passin pass:x -in dashboard.pass.key -out dashboard.key

删除刚才生成的dashboard.pass.key

rm -rf dashboard.pass.key
openssl req -new -key dashboard.key -out dashboard.csr

生成了dashboard.csr

生成SSL证书

openssl x509 -req -sha256 -days 365 -in dashboard.csr -signkey dashboard.key -out dashboard.crt

dashboard.crt文件是适用于仪表板和dashboard.key私钥的证书。
创建secret

kubectl create secret generic kubernetes-dashboard-certs --from-file=/etc/kubernetes/certs -n kube-system

注意/etc/kubernetes/certs 是之前创建crt、csr、key 证书文件存放的路径
2.下载dashboard镜像、tag镜像(在全部节点上)

docker pull registry.cn-hangzhou.aliyuncs.com/kubernete/kubernetes-dashboard-amd64:v1.10.0
docker tag registry.cn-hangzhou.aliyuncs.com/kubernete/kubernetes-dashboard-amd64:v1.10.0 k8s.gcr.io/kubernetes-dashboard:v1.10.0
docker rmi registry.cn-hangzhou.aliyuncs.com/kubernete/kubernetes-dashboard-amd64:v1.10.0

下载 kubernetes-dashboard.yaml 部署文件(在master上执行)

curl https://raw.githubusercontent.com/kubernetes/dashboard/v1.10.1/src/deploy/recommended/kubernetes-dashboard.yaml -O

修改 kubernetes-dashboard-amd64:v1.10.0 为kubernetes-dashboard:v1.10.0,不然会去墙外下载dashboard镜像

sed -i "s/kubernetes-dashboard-amd64:v1.10.0/kubernetes-dashboard:v1.10.0/g" kubernetes-dashboard.yaml

3.把Secret 注释
因为上面我们已经生成了密钥认证了,我们用我们自己生成的。

4.配置443端口映射到外部主机30005上

5.创建dashboard的pod

kubectl create -f  kubernetes-dashboard.yaml

6.查看服务运行情况

kubectl get deployment kubernetes-dashboard -n kube-system
kubectl --namespace kube-system get pods -o wide
kubectl get services kubernetes-dashboard -n kube-system
netstat -ntlp|grep 30005

7.Dashboard BUG处理

vim kube-dashboard-access.yaml

添加下面内容:

apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: kubernetes-dashboard
  labels:
    k8s-app: kubernetes-dashboard
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: kubernetes-dashboard
  namespace: kube-system

执行让kube-dashboard-access.yaml 生效

kubectl create -f kube-dashboard-access.yaml

然后重新登录界面刷新下,这个问题即可解决。

Kubernetes的集群配置至此以全部完成,若只需Kubernetes环境可到此结束,需要配置Kubernetes+GlusterFS超融合环境,需要继续后续的步骤。

以上Kubernetes配置部分,完全参考宝哥技术文章:https://mp.weixin.qq.com/s/yAjZT6NfN3V4AkbG2wO1SA 只是说明了部分不明之处,详细规避一些新手易犯错误而已。

部署GlusterFS容器

Kubernetes可以通过Heketi管理GlusterFS卷的生命周期的,动态配置GlusterFS卷,Heketi会动态在集群内选择bricks创建所需的volumes,确保数据的副本会分散到集群不同的故障域内,同时Heketi还支持GlusterFS多集群管理,便于管理员对GlusterFS进行操作。Heketi要求在每个glusterfs节点上配备裸磁盘,用来创建PV和VG,基于StorageClass的动态资源供应,本文的操作步骤依据heketi的github网址官方文档。
本文的环境是在三个Kubernetes Node上部署三个GluserFS节点。

IP地址 节点角色 CPU Memory Hostname 磁盘
192.168.3.80 master and etcd >=2c >=2G master sda、sdb
192.168.3.81 worker and GlusterFS >=2c >=2G node1 sda、sdb
192.168.3.82 worker and GlusterFS >=2c >=2G node2 sda、sdb
192.168.3.83 worker and GlusterFS >=2c >=2G node3 sda、sdb

注意:
Heketi要至少需要三个GlusterFS节点。

加载内核模块:每个kubernetes集群的节点运行命令:

modprobe dm_thin_pool

一、下载heketi客户端工具

注意:
此步骤在Master节点操作

Heketi提供了CLI,方便用户在Kubernetes中管理和配置GlusterFS,在Kubernetes任意一节点上下载正确版本的heketi工具。可查看https://github.com/heketi/heketi/releases下载不同的版本。

wget https://github.com/heketi/heketi/releases/download/v8.0.0/heketi-client-v8.0.0.linux.amd64.tar.gz
tar xvf heketi-client-v8.0.0.linux.amd64.tar.gz
cd heketi-client/share/heketi/kubernetes/

二、在集群内部署glusterfs-server

注意:
此步骤在Master节点操作

1.glusterfs以DaemonSet方式部署,可查看glusterfs-daemonset.json文件内容:

cat glusterfs-daemonset.json  

2.给需要部署GlusterFS节点的Node打上标签

kubectl label node 192.168.3.81 storagenode=glusterfs
node "192.168.3.81" labeled
kubectl label node 192.168.3.82 storagenode=glusterfs
node "192.168.3.82" labeled
kubectl label node 192.168.3.83 storagenode=glusterfs
node "192.168.3.83" labeled

3.部署并验证

kubectl create -f glusterfs-daemonset.json 
daemonset "glusterfs" created
kubectl get pod
NAME                             READY     STATUS    RESTARTS   AGE
glusterfs-94g22                  1/1       Running   0          2m
glusterfs-bc8tb                  1/1       Running   0          2m
glusterfs-n22c8                  1/1       Running   0          2m

三、在集群内部署heketi服务端

注意:此步骤在Master节点操作

1.查看 heketi-bootstrap.json文件内容:

cat heketi-bootstrap.json

2.根据deploy文件为Heketi创建对应的服务帐户:

kubectl create -f heketi-service-account.json
serviceaccount "heketi-service-account" created

3.为服务帐户创建集群角色绑定,以授权控制gluster的pod

kubectl create clusterrolebinding heketi-gluster-admin --clusterrole=edit --serviceaccount=default:heketi-service-account

此处授权的名称空间为default,意味着,Heketi所能操作的gluster-server之Pod也在此名称空间内,否则此角色将无法访问到gluster-server。
4.创建secret来保存Heketi服务的配置

kubectl create secret generic heketi-config-secret --from-file=./heketi.json
secrets "heketi-config-secret" created

必须将heketi.json中的glusterfs/executor设置为kubernetes,Heketi服务才能控制GlusterFS Pod。Secret必须与gluserfs Pod位于同一名称空间内才能挂载。
5.部署并验证一切正常运行:

$ kubectl create -f heketi-bootstrap.json
  service "deploy-heketi" created
  deployment "deploy-heketi" created
kubectl get pod
NAME                             READY     STATUS    RESTARTS   AGE
deploy-heketi-8465f8ff78-sb8z   1/1       Running   0          3m
glusterfs-94g22                  1/1       Running   0          28m
glusterfs-bc8tb                   1/1       Running   0          28m
glusterfs-n22c8                  1/1       Running   0          28m

6.测试Heketi服务端
既然Bootstrap Heketi服务正在运行,我们将配置端口转发,以便我们可以使用Heketi CLI与服务端进行通信。使用Heketi pod的名称,运行下面的命令:

$ kubectl port-forward  deploy-heketi-8465f8ff78-sb8z 8080:8080
$ curl http://localhost:8080/hello
   Handling connection for 8080
   Hello from heketi

四、Heketi管理gluster-server

注意:
此步骤在Master节点操作

检查glusterfs 及heketi服务端pod的运行情况:

kubectl get pod 
NAME                             READY     STATUS    RESTARTS   AGE
deploy-heketi-8465f8ff78-sb8zv   1/1       Running   0          20m
glusterfs-6pf8q                  1/1       Running   0          45m
glusterfs-kn6jf                  1/1       Running   9           45m
glusterfs-m2jt4                  1/1       Running   0          45m
kubectl get svc
NAME                         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
deploy-heketi             ClusterIP   10.254.238.186                   8080/TCP   1h

设置HEKETI_CLI_SERVER环境变量:

export HEKETI_CLI_SERVER=http://10.254.238.186:8080  

注意:
10.254.238.186:8080是执行kubectl get svc命令获取的heketi service的CLUSTER-IP及PORT(S)值,可根据环境信息进行替换

在示例文件中topology-sample.json称为拓朴文件,它提供了运行gluster Pod的kubernetes节点IP,每个节点上相应的磁盘块设备,修改hostnames/manage,设置为与kubectl get nodes所显示的Name字段的值,通常为Node IP,修改hostnames/storage下的IP,为存储网络的IP地址,也即Node IP。

$ cat topology-sample.json 
{
  "clusters": [
    {
      "nodes": [
        {
          "node": {
            "hostnames": {
              "manage": [
                "192.168.3.81"
              ],
              "storage": [
                "192.168.3.81"
              ]
            },
            "zone": 1
          },
          "devices": [
            "/dev/sdb"
          ]
        },
        {
          "node": {
            "hostnames": {
              "manage": [
                "192.168.3.82"
              ],
              "storage": [
                "192.168.3.82"
              ]
            },
            "zone": 1
          },
          "devices": [
            "/dev/sdb"
          ]
        },
        {
          "node": {
            "hostnames": {
              "manage": [
                "192.168.3.83"
              ],
              "storage": [
                "192.168.3.83"
              ]
            },
            "zone": 1
          },
          "devices": [
            "/dev/sdb"
          ]
        }
      ]
    }
  ]
}

加载topology-sample.json,配置GlusterFS集群:

heketi-cli topology load --json=topology-sample.json  
   Creating cluster ... ID: 224a5a6555fa5c0c930691111c63e863
     Allowing file volumes on cluster.
     Allowing block volumes on cluster.
     Creating node 10.30.1.15 ... ID: 7946b917b91a579c619ba51d9129aeb0
            Adding device /dev/sdb ... OK
     Creating node 10.30.1.16 ... ID: 5d10e593e89c7c61f8712964387f959c
            Adding device /dev/sdb ... OK
     Creating node 10.30.1.17 ... ID: de620cb2c313a5461d5e0a6ae234c553
            Adding device /dev/sdb ... OK

GlusterFS集群配置成功后,查看拓扑结构

heketi-cli topology info 

返回结果显示出每个磁盘设备的ID,对应VG的ID,总空间、已用空间、空余空间等信息。

五、Heketi管理GlusterFS的简单示例。

注意:此步骤在Master节点操作

配置StorageClass实现Kubernetes为提交的PersistentVolumeClaim自动配置存储。
参考链接:
https://github.com/gluster/gluster-kubernetes/blob/master/docs/examples/hello_world/README.md
1.创建一个StorageClass

 $ cat gluster-storage-class.yaml 
    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: gluster-heketi                        #-------存储类的名字
    provisioner: kubernetes.io/glusterfs
    parameters:
      resturl: "http://10.254.238.186:8080"      #----heketi service的cluster ip 和端口
      restuser: "admin"                #---heketi的认证用户,这里随便填,因为没有启用鉴权模式 
      gidMin: "40000"
      gidMax: "50000"
      volumetype: "replicate:3"            #---请的默认为3副本模式,因为目前有三个gluster节点。

2.创建一个pvc

    cat gluster-pvc.yaml 
    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: gluster1
      annotations:
        volume.beta.kubernetes.io/storage-class: gluster-heketi    #----上面创建的存储类的名称
    spec:
      accessModes:
        - ReadWriteMany
      resources:
        requests:
          storage: 2Gi

PVC的定义一旦生成,系统便会触发发Heketi进行相应的操作,主要是为GlusterFS创建brick及volume,查看pvc已自动绑定

kubectl get pvc
NAME              STATUS    VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS     AGE
gluster1          Bound     pvc-6784c33b-7acb-11e8-bdec-000c29774d39   2G         RWX            gluster-heketi   6m

创建pvc后查看服务器上发生的变化:

$ vgs
  VG                                  #PV #LV #SN Attr   VSize  VFree 
  vg_06a31aebc9e80ff7a53908942e82236d   1   1   0 wz--n- 19.87g 18.83g
$  lvs
  LV                       VG               Attr      LSize  Pool                                Origin Data%  Move Log Copy%  Convert   
    brick_c2e5e57f2574bec14c8821ef3e163d2a vg_06a31aebc9e80ff7a53908942e82236d Vwi-aotz-  2.00g tp_c2e5e57f2574bec14c8821ef3e163d2a          0.70   

由此可见:一个pvc对应3个brick,一个brick对应一个LV。
3.部署一个nginx Pod来挂载pvc

$ cat heketi-nginx.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod1
  labels:
    name: nginx-pod1
spec:
  containers:
  - name: nginx-pod1
    image: gcr.io/google_containers/nginx-slim:0.8
    ports:
    - name: web
      containerPort: 80
    volumeMounts:
    - name: gluster-vol1
      mountPath: /usr/share/nginx/html
  volumes:
  - name: gluster-vol1
    persistentVolumeClaim:
      claimName: gluster1   #上面创建的pvc
$ kubectl create -f nginx-pod.yaml
   pod "nginx-pod1" created

查看Pod

kubectl get pod -o wide
NAME                             READY     STATUS    RESTARTS   AGE       IP                NODE
deploy-heketi-8465f8ff78-sb8z   1/1       Running   0          39m       192.168.150.218   10.30.1.16
glusterfs-94g22                  1/1       Running   1          1h       10.30.1.17         10.30.1.17
glusterfs-bc8tb                  1/1       Running   2          1h       10.30.1.15         10.30.1.15
glusterfs-n22c8                  1/1       Running   3         1h       10.30.1.16         10.30.1.16
nginx-pod1                       1/1       Running   0            2m        192.168.47.207    10.30.1.15

到nginx容器中创建一个index.html文件,验证存储

$ kubectl exec -it nginx-pod1 /bin/sh
    # cd /usr/share/nginx/html
    # echo 'Hello World from GlusterFS!!!' > index.html
    # ls
    index.html
    # exit

测试运行的nginx Pod正常性:

$ curl http://192.168.47.207
Hello World from GlusterFS!!!

现在进入到gluster Pod 三个Pod中的任意一个Pod都行, 看看刚刚创建的index.html文件:
进入到10.30.1.15上的pod查看,先查看在10.30.1.15的vg名称:vg_c88262b05d49d3ef1b94a31636a549a7 进入到Pod 查看此VG的挂载点:

[root@ubuntu15 /]# mount |grep vg_c8826
  /dev/mapper/vg_c88262b05d49d3ef1b94a31636a549a7-brick_451f81bc629344f71fab63a30fab1773 on /var/lib/heketi/mounts/vg_c88262b05d49d3ef1b94a31636a549a7/brick_451f81bc629344f71fab63a30fab1773 type xfs (rw,noatime,nouuid,attr2,inode64,logbsize=256k,sunit=512,swidth=512,noquota)

根据它的挂载位置,cd到挂载目录,查看创建的文件:

[root@ubuntu15 brick]# pwd /var/lib/heketi/mounts/vg_c88262b05d49d3ef1b94a31636a549a7/brick_451f81bc629344f71fab63a30fab1773/brick
[root@ubuntu15 brick]# cat index.html 
Hello World from GlusterFS!!! 

通过gluster volume info查看到volume类型为Replicate,并且有三个副本,因此在三个gluster Pod中对应挂载点都会看到此文件。
此文仅用于理解Heketi如何动态管理GluseterFS来完成动态资源供应,还不能直接用于生产环境 。

参考地址:
https://github.com/gluster/gluster-kubernetes/blob/master/docs/examples/hello_world/README.md
https://github.com/heketi/heketi/blob/master/docs/admin/install-kubernetes.md
https://mp.weixin.qq.com/s/yAjZT6NfN3V4AkbG2wO1SA
https://blog.51cto.com/newfly/2134514?source=dra