介 绍
在本文中你将学会如何使用 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
圆满成功! 我们的存储在被杀死个各个容器中得以持久保存.
来源: https://www.cnblogs.com/rancherlabs/p/12190718.html