5

kubernetes 带状态程序部署-以mysql为例

 3 years ago
source link: https://blog.csdn.net/oqqYuan1234567890/article/details/89264531
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

k8s 在部署带状态的程序相对来说比较麻烦,一个高可用的程序,应该可以在每一个node上跑,所以在程序的开发阶段就应该要考虑到部署阶段带来的问题,可以降低程序容器化

  1. 配置信息尽量写入DB,那么程序起来的时候直接从DB加载,无论从提高部署效率或者运营的角度来说,入库都是最好的选择,更新配置之后,replace pod就ok
  2. 无法入库的大文件配置,通过k8s的pv pvc来处理,参考
  3. 小文件配置,build docker的时候写入容器

k8s 支持的persistent volumes

目前支持的持久卷类型如下:(前面几项目前的网络环境难以实现)

  • GCEPersistentDisk
  • AWSElasticBlockStore
  • AzureFile
  • AzureDisk
  • FC (Fibre Channel)**
  • FlexVolume
  • Flocker
  • iSCSI
  • RBD (Ceph Block Device)
  • CephFS
  • Cinder (OpenStack block storage)
  • Glusterfs
  • VsphereVolume
  • Quobyte Volumes
  • HostPath (Single node testing only – local storage is not supported in any way and WILL NOT WORK in a multi-node cluster)
  • Portworx Volumes
  • ScaleIO Volumes
  • StorageOS

hostPath,也就是node的文件系统(貌似我最初接触docker挂在volume的时候就是这种方式,但是现在看来,在可用性真的弱)
cephfs和glusterfs都是linux生态上比较有名的分布式文件系统,使用上比nfs要复杂些,这里不展开。下面我使用的nfs,nfs相对于ceph和gluster,可用性略弱,搭建测试环境还是可以的。

https://kubernetes.io/docs/tasks/run-application/run-single-instance-stateful-application/

以mysql为例的带状态程序部署

由于这篇文章是部署完成之后写的,有一些时间数据可以能有差异,我当时使用的是default namespace,实际上namespace管理也很重要,最好在apply yaml的时候指定。

  1. 一个nfs服务,每个节点都要安装nfs client
  2. 一个kubernetes 集群,带dashboard更佳(观察部署服务状态真的很方便)
  3. 外网环境!!
  4. kubectl operation

Step1: 准备pv pvc

我的k8s 环境如下

$kubectl get nodes
NAME      STATUS    ROLES     AGE       VERSION
s01       Ready     master    7d        v1.10.3
s02       Ready     <none>    7d        v1.10.3
s03       Ready     <none>    7d        v1.10.3

mysql-pv.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: mysql-pv01
spec:
  capacity:
    storage: 20Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  nfs:
    path: /opt/nfs_data/mysql
    server: 192.168.242.133

mysql-pvc.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pv-claim
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi

在对应的namespace apply一下配置,就可以看到下面状态
kubectl apply --namespace=targetNamespace -f *.yaml

$ kubectl get pv
NAME         CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS    CLAIM                    STORAGECLASS   REASON    AGE
mysql-pv01   20Gi       RWO            Recycle          Bound     default/mysql-pv-claim                            8h
$ kubectl get pvc
NAME             STATUS    VOLUME       CAPACITY   ACCESS MODES   STORAGECLASS   AGE
mysql-pv-claim   Bound     mysql-pv01   20Gi       RWO                           8h

当你看到bound状态的时候,说明pv和pvc已经bind好,这样才可以进行下一步deployment
Note:关于pv和pvc是如何绑定的我最初看的官网的几个例子,但是都没发现有key相关的绑定,参考官方bind说明,大约就是说,容量大小和读取模式匹配就断匹配到了,我感觉bind算法说得也不是很清楚,可能要看代码才知道

Step2: deploy

mysql-deployment.yaml

apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: mysql
spec:
  selector:
    matchLabels:
      app: mysql
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - image: mysql:5.6
        name: mysql
        env:
          # Use secret in real usage
        - 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

apply 一下,等拉取镜像完成,容器创建完成后,可以看到,it may take a few minutes,

$ kubectl get deployment
NAME      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
mysql     1         1         1            1           8h
$ kubectl get pods
NAME                     READY     STATUS    RESTARTS   AGE
mysql-648d67bf7c-r9ftr   1/1       Running   0          8h

到这步,mysql就基本部署完成了,pod已经起来,
$ kubectl exec -it mysql-648d67bf7c-r9ftr -- mysql -uroot -ppassword
到这一步,就可以看到非常熟悉的mysql console啦

Step3: expose

这里使用nodePort来暴露内部mysql的端口,这样在内网环境就可以访问到容器内的pod,由于这个是单点部署,需要知道mysql这个pod运行在哪个node,才能在内网环境下访问

 mysql-svc.yaml 
apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  type: NodePort
  sessionAffinity: ClientIP
  selector:
    app: mysql
  ports:
    - port: 3306
      nodePort: 30010

mysql 这个pod运行在s02节点上,对应的IP:192.168.242.134,内网环境下可以直接通过s02节点的ip访问
mysql -h192.168.242.134 -P30010 -uroot -ppassword
接下来就可以看到mysql console了

以上步骤的最终效果

以上部署是单点部署,只是为了跑通带状态程序的部署,在高可用性上非常弱
暴露的ip,要知道mysql运行在哪个node上,才能决定连接的ip,后续可以使用clusterIp方案。
安全问题,内网环境需要隔离


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK