Longhorn入門級教程!輕鬆實現持久化儲存!
介 紹
在本文中你將學會如何使用k3s在Civo上執行Longhorn。如果你還沒使用過Civo,可以到官網註冊(https://www.civo.com/ )還可以申請免費的使用額度。首先,需要一個Kubernetes叢集,然後我們將安裝Longhorn並通過一個示例來展現如何使用它。
雲原生應用程式的原理之一是它們旨在成為無狀態的,因此可以直接水平擴充套件應用程式。然而,實際情況是除非你的網站或應用程式所佔記憶體很小,否則你一定需要在某個地方儲存這些東西。
業界巨頭(如Google和Amazon)常常會有適用於本公司產品的可擴充套件儲存解決方案的自定義系統。但是對於小型公司來說,這要怎麼辦呢?
業界採用最為廣泛的Kubernetes管理平臺建立者Rancher Labs(以下簡稱Rancher)在2018年3月釋出了容器化分散式儲存專案Longhorn(現已捐獻給CNCF),這一專案填補了以上的空缺。簡而言之,Longhorn所做的是使用Kubernetes節點的現有磁碟為Kubernetes Pod提供穩定的儲存。
前期準備
在我們使用Longhorn之前,你需要有一個正在執行的Kubernetes叢集。你可以簡單地安裝一個k3s叢集(https://github.com/rancher/k3s/blob/master/README.md )或者如果你正在使用Civo的Kubernetes服務,你也可以使用它。本文將使用Civo的Kubernetes服務來建立叢集。
我們建議使用最少的Medium例項,因為我們將測試MySQL的狀態儲存,它可能會佔用大量RAM。
$ civo k8s create longhorn-test --wait
Building new Kubernetes cluster longhorn-test: \
Created Kubernetes cluster longhorn-test
你的叢集需要在每個節點上安裝open-iscsi
,所以如果你使用的不是civo的Kubernetes服務,除了上述連結的說明外,你還需要在每個節點上執行以下命令:
sudo apt-get install open-iscsi
接著,你既需要下載Kubernetes配置檔案並將其儲存到~/.kube/config
KUBECONFIG
的環境變數設定為其檔名:
cd ~/longhorn-play
civo k8s config longhorn-test > civo-longhorn-test-config
export KUBECONFIG=civo-longhorn-test-config
安裝Longhorn
在現有Kubernetes叢集上安裝Longhorn僅需2步:為Longhorn安裝controller以及擴充套件包,然後建立一個可用於pod的StorageClass。第一步:
$ kubectl apply -f https://raw.githubusercontent.com/rancher/longhorn/master/deploy/longhorn.yaml
namespace/longhorn-system created
serviceaccount/longhorn-service-account created
...
建立StorageClass需要使用另一個命令,然而作為附加步驟,你可以將新的class設定為預設,這樣你無需每次都指定它:
$ kubectl apply -f https://raw.githubusercontent.com/rancher/longhorn/master/examples/storageclass.yaml
storageclass.storage.k8s.io/longhorn created
$ kubectl get storageclass
NAME PROVISIONER AGE
longhorn rancher.io/longhorn 3s
$ kubectl patch storageclass longhorn -p \
'{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
storageclass.storage.k8s.io/longhorn patched
$ kubectl get storageclass
NAME PROVISIONER AGE
longhorn (default) rancher.io/longhorn 72s
訪問Longhorn Dashboard
Longhorn有一個十分簡潔的Dashboard,可以在上面看到已使用的空間、可用空間、volume列表等等資訊。但首先,我們需要建立身份驗證的詳細資訊:
$ htpasswd -c ./ing-auth admin
$ kubectl create secret generic longhorn-auth \
--from-file ing-auth --namespace=longhorn-system
現在,我們將建立一個Ingress
物件,可以使用k3s中內建的Traefik,並將dashboard暴露到外部。建立一個名為longhorn-ingress.yaml
的檔案,並將其放入其中:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: longhorn-ingress
annotations:
ingress.kubernetes.io/auth-type: "basic"
ingress.kubernetes.io/auth-secret: "longhorn-auth"
spec:
rules:
- host: longhorn-frontend.example.com
http:
paths:
- backend:
serviceName: longhorn-frontend
servicePort: 80
然後應用它:
$ kubectl apply -f longhorn-ingress.yaml -n longhorn-system
ingress.extensions/longhorn-ingress created
現在,你需要在/etc/hosts
檔案中新增一個條目,以將你的任意Kubernetes IP地址指向longhorn-frontend.example.com
:
echo "1.2.3.4 longhorn-frontend.example.com" >> /etc/hosts
現在,你可以在瀏覽器上訪問http://longhorn-frontend.example.com ,使用admin
和使用htpasswd
時輸入的密碼進行身份驗證之後,可以看到類似下面的內容:
使用持久化儲存安裝MySQL
在單個容器中執行MySQL毫無意義,因為當基礎節點(容器)死亡時,相關的業務也就無法執行,這時你會失去客戶、失去訂單。在這裡,我們要為它配置一個新的Longhorn持久卷。
首先,我們需要在Kubernetes中建立幾個資源。其中每個都是yaml檔案,位於一個空目錄中,或者你可以將它們全部放在一個檔案中,使用---
進行分隔。
在mysql/pv.yaml
中的一個持久卷:
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv
namespace: apps
labels:
name: mysql-data
type: longhorn
spec:
capacity:
storage: 5G
volumeMode: Filesystem
storageClassName: longhorn
accessModes:
- ReadWriteOnce
csi:
driver: io.rancher.longhorn
fsType: ext4
volumeAttributes:
numberOfReplicates: '2'
staleReplicaTimeout: '20'
volumeHandle: mysql-data
在mysql / pv-claim.yaml
中對該卷的宣告(類似於抽象請求,以便某些人可以使用該卷):
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
labels:
type: longhorn
app: example
spec:
storageClassName: longhorn
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
在mysql/pod.yaml
中還有一個可以執行MySQL並使用上述卷生命的Pod(請注意:我們在此處使用password
作為MySQL的root密碼,但在實際操作中你應該使用安全密碼,並在Kubernetes secret中儲存密碼而不是在YAML中,這裡我們只是為了簡單):
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-mysql
labels:
app: example
spec:
selector:
matchLabels:
app: example
tier: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: example
tier: mysql
spec:
containers:
- image: mysql:5.6
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: password
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pv-claim
現在,應用資料夾或者單個檔案(這取決於你之前的選擇):
$ kubectl apply -f mysql.yaml
persistentvolumeclaim/mysql-pv-claim created
persistentvolume/mysql-pv created
deployment.apps/my-mysql created
# or
kubectl apply -f ./mysql/
persistentvolumeclaim/mysql-pv-claim created
persistentvolume/mysql-pv created
deployment.apps/my-mysql created
測試MySQL是否能夠持久化儲存
我們的測試十分簡單,建立一個新的資料庫,刪除容器(Kubernetes會幫我們重新建立),然後重新連線,理想的結果是依舊可以看到我們的新資料庫。
好,現在我們來建立一個名為should_still_be_here
的資料庫:
$ kubectl get pods | grep mysql
my-mysql-d59b9487b-7g644 1/1 Running 0 2m28s
$ kubectl exec -it my-mysql-d59b9487b-7g644 /bin/bash
root@my-mysql-d59b9487b-7g644:/# mysql -u root -p mysql
Enter password:
mysql> create database should_still_be_here;
Query OK, 1 row affected (0.00 sec)
mysql> show databases;
+----------------------+
| Database |
+----------------------+
| information_schema |
| #mysql50#lost+found |
| mysql |
| performance_schema |
| should_still_be_here |
+----------------------+
5 rows in set (0.00 sec)
mysql> exit
Bye
root@my-mysql-d59b9487b-7g644:/# exit
exit
現在,我們將刪除容器:
kubectl delete pod my-mysql-d59b9487b-7g644
大約一分鐘之後,我們將再次尋找新的容器名稱,連線到該容器名稱,看看我們的資料庫是否仍然存在:
$ kubectl get pods | grep mysql
my-mysql-d59b9487b-8zsn2 1/1 Running 0 84s
$ kubectl exec -it my-mysql-d59b9487b-8zsn2 /bin/bash
root@my-mysql-d59b9487b-8zsn2:/# mysql -u root -p mysql
Enter password:
mysql> show databases;
+----------------------+
| Database |
+----------------------+
| information_schema |
| #mysql50#lost+found |
| mysql |
| performance_schema |
| should_still_be_here |
+----------------------+
5 rows in set (0.00 sec)
mysql> exit
Bye
root@my-mysql-d59b9487b-7g644:/# exit
exit
圓滿成功!我們的儲存在被殺死個各個容器中得以持久儲存