• 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
    

    圆满成功!我们的存储在被杀死个各个容器中得以持久保存。

  • 相关阅读:
    Array的 map() 和 reduce()
    欧几里得算法求解最大公约数
    JavaScript Function
    JavaScript Hoisting(提升)
    activemq的事务消息
    Spring整合Activemq
    10张图带你深入理解Docker容器和镜像
    Thread类的interrupt方法
    简单工厂、工厂方法、抽象工厂笔记
    设计模式之观察者模式
  • 原文地址:https://www.cnblogs.com/rancherlabs/p/12190718.html
Copyright © 2020-2023  润新知