2019.10.29にCNCF(Cloud Native Computing Foundation)のSandbox ProjectとなったLonghornについて見ていきたいと思います。
1.What's Longhorn ?
Longhornは、RancherLabs社が開発したOpenEBSベースのKubernetes用の分散ブロックストレージシステムです。ストレージ種別としては、ブロックストレージです。2017年のDockerCon時に発表されて2019年10月末に、CNCFのSandbox Projectになりました。
2019年12月時点での最新バージョンはv0.7.0となります。
特徴としては、以下となります。
- 単一障害点のないエンタープライズグレード?の分散ストレージ
- ブロックストレージの増分スナップショット
- 効率的な変更ブロック検出に基づいて構築されたセカンダリストレージ(NFSまたはS3互換オブジェクトストレージ)へのバックアップ
- 繰り返しのスナップショットとバックアップ
- 自動化された無停止アップグレード。実行中のボリュームを中断することなく、Longhornソフトウェアスタック全体をアップグレード可能
- 直感的なGUIダッシュボード
現時点では、アルファ品質のソフトウェアのためフィードバック等を求めています。
インストール条件としては、以下となります。
- Docker v1.13以降
- Kubernetes v1.14以降
- open-iscsiは、Kubernetesクラスターのすべてのノードにインストールが必要
- GKEの場合、open-iscsiがすでに含まれているため、ゲストOSイメージとしてUbuntuを推奨
- Debian / Ubuntuの場合、apt-get install open-iscsiを使用してインストール
- RHEL / CentOSの場合、yum install iscsi-initiator-utilsを使用してインストール
- ホストファイルシステムは、データを保存するためにノードでファイルエクステント機能をサポート、現在は以下をサポート
- ext4
- XFS
インストール方法は、kubectl、Helm、Rancherカタログで行うことができます。
Longhornの詳細についてはこちらの資料をご参考いただければ幸いです。
こちらの資料の「Longhorn + WordPress on GKE」のハンズオンテキストは以下となります。
2.Longhorn + WordPress on GKE
GKEを利用して、実際にLonghornとアプリケーション(WordPress)を連携してみます。
GKE Prepare
GKE上にLonghorn環境を構築して、WordPressをデプロイしてみます。GKEにLonghornをインストールする場合には、ノードで利用するOSがGKEデフォルトの「コンテナ最適OS」ではなく、「Ubuntu OS」にする必要があります。
GKEのプロビジョニング時に変更します。
クラスタ構築完了後に、RBACを有効にするために、Longhornをインストールする前に次のコマンドを実行します。
name@example.comは、Googleアカウントのメールアドレスを入力します。
$ kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin --user=<name@example.com>
clusterrolebinding.rbac.authorization.k8s.io/cluster-admin-binding created
Longhorn Install
KubernetesクラスターにLonghornをインストールします。
kubectlの場合
$ kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/master/deploy/longhorn.yaml
namespace/longhorn-system created
serviceaccount/longhorn-service-account created
clusterrole.rbac.authorization.k8s.io/longhorn-role created
clusterrolebinding.rbac.authorization.k8s.io/longhorn-bind created
customresourcedefinition.apiextensions.k8s.io/engines.longhorn.rancher.io created
customresourcedefinition.apiextensions.k8s.io/replicas.longhorn.rancher.io created
customresourcedefinition.apiextensions.k8s.io/settings.longhorn.rancher.io created
customresourcedefinition.apiextensions.k8s.io/volumes.longhorn.rancher.io created
customresourcedefinition.apiextensions.k8s.io/engineimages.longhorn.rancher.io created
customresourcedefinition.apiextensions.k8s.io/nodes.longhorn.rancher.io created
customresourcedefinition.apiextensions.k8s.io/instancemanagers.longhorn.rancher.io created
configmap/longhorn-default-setting created
daemonset.apps/longhorn-manager created
service/longhorn-backend created
deployment.apps/longhorn-ui created
service/longhorn-frontend created
deployment.apps/longhorn-driver-deployer created
Longhornが、デプロイされるNamespaceは、longhorn-systemになります。確認してみます。
$ kubectl -n longhorn-system get pod
NAME READY STATUS RESTARTS AGE
csi-attacher-9df5cfb99-7qjt2 1/1 Running 0 13m
csi-attacher-9df5cfb99-d246j 1/1 Running 0 13m
csi-attacher-9df5cfb99-wq47z 1/1 Running 0 13m
csi-provisioner-5bd8d7cb74-bs9kz 1/1 Running 0 13m
csi-provisioner-5bd8d7cb74-vwrxs 1/1 Running 0 13m
csi-provisioner-5bd8d7cb74-xspb5 1/1 Running 0 13m
engine-image-ei-3827e67c-fhz8w 1/1 Running 0 15m
engine-image-ei-3827e67c-q7tpj 1/1 Running 0 15m
engine-image-ei-3827e67c-zwq8v 1/1 Running 0 15m
instance-manager-e-52b53b48 1/1 Running 0 13m
instance-manager-e-bd7d7bb1 1/1 Running 0 13m
instance-manager-e-fe19c451 1/1 Running 0 13m
instance-manager-r-346984ea 1/1 Running 0 13m
instance-manager-r-78d20189 1/1 Running 0 13m
instance-manager-r-aa6cd210 1/1 Running 0 13m
longhorn-csi-plugin-4rhb7 2/2 Running 0 13m
longhorn-csi-plugin-5nb42 2/2 Running 0 13m
longhorn-csi-plugin-v7pwc 2/2 Running 0 13m
longhorn-driver-deployer-647688999c-db8rm 1/1 Running 0 15m
longhorn-manager-cqdtn 1/1 Running 0 15m
longhorn-manager-vt2g2 1/1 Running 0 15m
longhorn-manager-zwwsm 1/1 Running 1 15m
longhorn-ui-76dfddf9cd-ktk82 1/1 Running 0 15m
Longhornダッシュボードにもアクセスしてみます。
longhorn-frontendというServiceがLoadBalancerとなっているので、EXTERNAL-IPを確認します。
$ kubectl -n longhorn-system get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
csi-attacher ClusterIP 10.12.1.41 <none> 12345/TCP 18m
csi-provisioner ClusterIP 10.12.2.61 <none> 12345/TCP 18m
longhorn-backend ClusterIP 10.12.9.174 <none> 9500/TCP 20m
longhorn-frontend LoadBalancer 10.12.6.218 34.69.255.105 80:30063/TCP 20m
表示されたEXTERNAL-IPをブラウザで開きます。
helmの場合
Helmのインストールはこちらを参照。
Helmインストール完了後、以下コマンドを実行します。
$ git clone https://github.com/longhorn/longhorn.git
Cloning into 'longhorn'...
remote: Enumerating objects: 71, done.
remote: Counting objects: 100% (71/71), done.
remote: Compressing objects: 100% (56/56), done.
remote: Total 1220 (delta 29), reused 24 (delta 11), pack-reused 1149
Receiving objects: 100% (1220/1220), 631.08 KiB | 832.00 KiB/s, done.
Resolving deltas: 100% (677/677), done.
HelmからLonghornをインストールします。
$ helm install ./longhorn/chart --name longhorn --namespace longhorn-system
NAME: longhorn
LAST DEPLOYED: Sun Nov 10 00:03:31 2019
NAMESPACE: longhorn-system
STATUS: DEPLOYED
RESOURCES:
==> v1/ClusterRole
NAME AGE
longhorn-role 1s
==> v1/ClusterRoleBinding
NAME AGE
longhorn-bind 1s
==> v1/ConfigMap
NAME AGE
longhorn-default-setting 1s
==> v1/DaemonSet
NAME AGE
longhorn-manager 1s
==> v1/Deployment
NAME AGE
longhorn-driver-deployer 1s
longhorn-ui 1s
==> v1/Pod(related)
NAME AGE
longhorn-driver-deployer-7488ccf89b-xtcbp 0s
longhorn-manager-4fxh9 0s
longhorn-manager-4nwf6 0s
longhorn-manager-hblbw 0s
longhorn-ui-5b58f6d79d-jvp2w 0s
==> v1/Service
NAME AGE
longhorn-backend 1s
longhorn-frontend 1s
==> v1/ServiceAccount
NAME AGE
longhorn-service-account 1s
==> v1/StorageClass
NAME AGE
longhorn 1s
==> v1beta1/CustomResourceDefinition
NAME AGE
engineimages.longhorn.rancher.io 1s
engines.longhorn.rancher.io 1s
instancemanagers.longhorn.rancher.io 1s
nodes.longhorn.rancher.io 1s
replicas.longhorn.rancher.io 1s
settings.longhorn.rancher.io 1s
volumes.longhorn.rancher.io 1s
NOTES:
1. Get the application URL by running these commands:
kubectl get po -n $release_namespace
Longhornが、デプロイされるNamespaceは、longhorn-systemになります。確認してみます。
$ kubectl -n longhorn-system get pod
NAME READY STATUS RESTARTS AGE
csi-attacher-9df5cfb99-4qbjj 1/1 Running 0 12m
csi-attacher-9df5cfb99-bxgqr 1/1 Running 0 12m
csi-attacher-9df5cfb99-mqzmd 1/1 Running 0 12m
csi-provisioner-5bd8d7cb74-2mdt5 1/1 Running 0 12m
csi-provisioner-5bd8d7cb74-5k7cl 1/1 Running 0 12m
csi-provisioner-5bd8d7cb74-vwzkr 1/1 Running 0 12m
engine-image-ei-3827e67c-mk9bn 1/1 Running 0 14m
engine-image-ei-3827e67c-ncz4v 1/1 Running 0 14m
engine-image-ei-3827e67c-xj4ww 1/1 Running 0 14m
instance-manager-e-14a0c272 1/1 Running 0 13m
instance-manager-e-6a1c06ef 1/1 Running 0 12m
instance-manager-e-e2299b26 1/1 Running 0 13m
instance-manager-r-19f5f4c6 1/1 Running 0 13m
instance-manager-r-53a1e7d8 1/1 Running 0 13m
instance-manager-r-90b860f6 1/1 Running 0 12m
longhorn-csi-plugin-b6rb8 2/2 Running 0 12m
longhorn-csi-plugin-cqnk5 2/2 Running 0 12m
longhorn-csi-plugin-wgnsv 2/2 Running 0 12m
longhorn-driver-deployer-7488ccf89b-xtcbp 1/1 Running 0 14m
longhorn-manager-4fxh9 1/1 Running 1 14m
longhorn-manager-4nwf6 1/1 Running 0 14m
longhorn-manager-hblbw 1/1 Running 0 14m
longhorn-ui-5b58f6d79d-jvp2w 1/1 Running 0 14m
Longhornダッシュボードにもアクセスしてみます。
longhorn-frontendというServiceがLoadBalancerとなっているので、EXTERNAL-IPを確認します。
$ kubectl -n longhorn-system get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
csi-attacher ClusterIP 10.0.1.11 <none> 12345/TCP 16m
csi-provisioner ClusterIP 10.0.0.46 <none> 12345/TCP 16m
longhorn-backend ClusterIP 10.0.11.53 <none> 9500/TCP 17m
longhorn-frontend LoadBalancer 10.0.1.213 34.84.3.65 80:30016/TCP 17m
表示されたEXTERNAL-IPをブラウザで開きます。
Rancherの場合
GKEのクラスタをRancherにインポートした状態からの手順です。
「Catalog」からLONGHORNを検索して、クリックします。
「0.6.2」を選択します。2019年11月時点では、GKEのkubernetesバージョンにLonghorn v0.7.0 が対応していないため v0.6.2 を選択します。
「L4 Balancer」を選択して、「Launch」ボタンをクリックします。
「80/tcp」をクリックします。
UIが表示されることを確認します。
Create Longhorn Volume
Kubernetesボリュームを作成する前に、まずストレージクラスを作成する必要があります。longhornというStorageClassを作成します。
$ kubectl create -f https://raw.githubusercontent.com/longhorn/longhorn/master/examples/storageclass.yaml
storageclass.storage.k8s.io/longhorn created
storageclass.yamlの内容は以下となります。
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: longhorn
provisioner: rancher.io/longhorn
parameters:
numberOfReplicas: "3"
staleReplicaTimeout: "2880"
fromBackup: ""
# diskSelector: "ssd,fast"
# nodeSelector: "storage,fast"
# recurringJobs: '[{"name":"snap", "task":"snapshot", "cron":"*/1 * * * *", "retain":1},
# {"name":"backup", "task":"backup", "cron":"*/2 * * * *", "retain":1,
# "labels": {"interval":"2m"}}]'
Longhorn StorageClassを利用したPVCを作成します。
$ vim longhorn-pvc.yaml
-------------------------------------------------------------------
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: longhorn-volv-pvc
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 10Gi
-------------------------------------------------------------------
Esc + :wq
$ kubectl create -f longhorn-pvc.yaml
persistentvolumeclaim/longhorn-volv-pvc created
この後WordPressではWordPressとMySQLそれぞれで利用できるようもう一つ作成します。
$ vim longhorn-pvc2.yaml
-------------------------------------------------------------------
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: longhorn-volv-pvc2
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 10Gi
-------------------------------------------------------------------
Esc + :wq
$ kubectl create -f longhorn-pvc2.yaml
persistentvolumeclaim/longhorn-volv-pvc2 created
pvとpvcの状況を確認します。
$ kubectl get pv,pvc
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/pvc-d2eaf832-02bc-11ea-b04c-42010a800123 10Gi RWO Delete Bound default/longhorn-volv-pvc longhorn 25m
persistentvolume/pvc-e089f32f-02bf-11ea-b04c-42010a800123 10Gi RWO Delete Bound default/longhorn-volv-pvc2 longhorn 3m25s
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/longhorn-volv-pvc Bound pvc-d2eaf832-02bc-11ea-b04c-42010a800123 10Gi RWO longhorn 25m
persistentvolumeclaim/longhorn-volv-pvc2 Bound pvc-e089f32f-02bf-11ea-b04c-42010a800123 10Gi RWO longhorn 3m27s
WordPress Deploy
WordPressに必要となるSecretを作成します。
$ kubectl create secret generic mysql --from-literal=password=longhorn
secret/mysql created
MySQLのDeploymentを作成します。その際、作成したPVC「longhorn-volv-pvc」を指定します。
$ vim mysql.yml
-----------------------------------------------------
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: mysql
labels:
app: mysql
spec:
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- image: mysql:5.6
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql
key: password
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-local-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-local-storage
persistentVolumeClaim:
claimName: longhorn-volv-pvc
-----------------------------------------------------
Esc + :wq
デプロイします。
$ kubectl create -f mysql.yml
deployment.extensions/mysql created
デプロイ状況を確認します。
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
mysql-656cf9f974-5l4bs 1/1 Running 0 3m37s
WordPressのDeploymentを作成します。その際、作成したPVC「longhorn-volv-pvc2」を指定します。
$ vim wordpress.yml
-----------------------------------------------------
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: wordpress
labels:
app: wordpress
spec:
replicas: 1
selector:
matchLabels:
app: wordpress
template:
metadata:
labels:
app: wordpress
spec:
containers:
- image: wordpress
name: wordpress
env:
- name: WORDPRESS_DB_HOST
value: mysql:3306
- name: WORDPRESS_DB_PASSWORD
valueFrom:
secretKeyRef:
name: mysql
key: password
ports:
- containerPort: 80
name: wordpress
volumeMounts:
- name: wordpress-local-storage
mountPath: /var/www/html
volumes:
- name: wordpress-local-storage
persistentVolumeClaim:
claimName: longhorn-volv-pvc2
-----------------------------------------------------
Esc + :wq
デプロイします。
$ kubectl create -f wordpress.yml
deployment.extensions/wordpress created
デプロイ状況を確認します。
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
mysql-656cf9f974-5l4bs 1/1 Running 0 15m
wordpress-7f4768b5cc-bxvcr 1/1 Running 0 44s
WordPressからMySQLに通信するためのServiceを作成します。
$ vim mysql-service.yml
-----------------------------------------------------
apiVersion: v1
kind: Service
metadata:
name: mysql
labels:
app: mysql
spec:
type: ClusterIP
ports:
- port: 3306
selector:
app: mysql
-----------------------------------------------------
Esc + :wq
$ kubectl create -f mysql-service.yml
service/mysql created
ブラウザからWordPressへアクセスするためのServiceを作成します。
$ vim wordpress-service.yml
-----------------------------------------------------
apiVersion: v1
kind: Service
metadata:
labels:
app: wordpress
name: wordpress
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
app: wordpress
-----------------------------------------------------
Esc + :wq
$ kubectl create -f wordpress-service.yml
service/wordpress created
EXTERNAL-IPを確認して、ブラウザでアクセスしてみます。
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.12.0.1 <none> 443/TCP 114m
mysql ClusterIP 10.12.7.159 <none> 3306/TCP 3m37s
wordpress LoadBalancer 10.12.12.30 34.70.77.28 80:31566/TCP 96s
Documents
- longhorn.io
- GitHub
- Longhorn Accepted into CNCF
- an open source project for microservices-based distributed block storage
- Rancherのヤツ知ってる?いや、そっちじゃなくてLonghornのほう
- CNCF Sandbox Project Longhorn
KubeCon + CloudNativeCon NA 2019
Rancher Labs Software Architect Sheng Yang、Longhornメイン開発者の登壇動画とスライド資料となります。