大家好,我是老 Z!

上篇文章实现了 MySQL 数据库在基于 KubeSphere 部署的 K8s 集群上的装置部署,部署形式采纳了图形化界面这种模式。本文将会介绍如何应用 GitOps 来部署 MySQL,部署过程波及的所有 YAML 文件都会应用 Git 进行版本治理,并存放在 Git 仓库中。因而,本文还会波及 GitOps 的根底操作。

原生 K8s 应用 GitOps 部署 MySQL

上篇文章咱们实现了通过 KubeSphere 部署单实例 MySQL,那么原生的 K8s 又该如何操作?GitOps 又是什么、又该如何实现?

什么是 GitOps(网文摘抄)

  • GitOps 是一套应用 Git 来治理基础架构和利用配置的实际,而 Git 指的是一个开源版控制系统。
  • GitOps 在运行过程中以 Git 为申明性基础架构和利用的繁多事实起源。
  • GitOps 应用 Git 拉取申请来主动治理基础架构的置备和部署。
  • Git 存储库蕴含零碎的全副状态,因而零碎状态的批改痕迹既可查看也可审计。
  • GitOps 常常被用作 K8s 和云原生利用开发的运维模式,并且能够实现对 K8s 的继续部署。
  • GitOps 是一种继续交付的形式。它的核心思想是将利用零碎的申明性基础架构和应用程序寄存在 Git 版本库中。

筹备资源配置清单-思路梳理

咱们晓得玩 K8s 的必备技能就是要手写资源配置清单,个别应用 YAML 格局的文件来创立咱们预期的资源配置。

此时咱们也要手写 MySQL 的资源配置清单?我很慌,参数我记不全啊。

NO!NO!NO!投机取巧的时刻到了,后面卖的关子在这揭开了。

后面咱们曾经通过 KubeSphere 的图形界面创立了 MySQL 的资源配置,而且 KubeSphere 一个很棒的性能就是能够间接在线编辑资源的 YAML 文件。

咱们能够在创立资源的时候,间接编辑 YAML 文件创建资源。也能够通过编辑 YAML 的形式批改已有的资源。

当然啊,你不必图形界面,间接在 K8s 底层用命令行的形式去获取 YAML 格局的输入,再编辑,也是能够的。

梳理一下 MySQL 波及的资源配置清单蕴含的资源。

  • StatefulSet(有状态正本集)
  • Service(服务)

    • 集群外部(Headless)
    • 集群内部(自定义服务)
  • ConfigMap
  • Secret

接下来咱们就别离获取这些资源配置清单。

筹备资源配置清单

ConfigMap

配置->配置字典,找到 mysql-cnf,点击右侧的三个竖点,点击编辑 YAML

关上编辑 YAML 页面,能够间接复制所有内容,也能够点击右上角的下载图标,下载文件 (也能够利用上传图标上传文件)。

获取的现网配置不能齐全的拿来就用,须要批改,把零碎主动增加的一些元数据信息清理掉。

现网的 mysql-cfm.yaml

kind: ConfigMapapiVersion: v1metadata:  name: mysql-cnf  namespace: lstack  annotations:    kubesphere.io/creator: lstackdata:  custom.cnf: |-    [mysqld]    #performance setttings    lock_wait_timeout = 3600    open_files_limit    = 65535    back_log = 1024    max_connections = 512    max_connect_errors = 1000000    table_open_cache = 1024    table_definition_cache = 1024    thread_stack = 512K    sort_buffer_size = 4M    join_buffer_size = 4M    read_buffer_size = 8M    read_rnd_buffer_size = 4M    bulk_insert_buffer_size = 64M    thread_cache_size = 768    interactive_timeout = 600    wait_timeout = 600    tmp_table_size = 32M    max_heap_table_size = 32M    

批改后的 mysql-cfm.yaml

kind: ConfigMapapiVersion: v1metadata:  name: mysql-cnf  namespace: lstackdata:  custom.cnf: |-    [mysqld]    #performance setttings    lock_wait_timeout = 3600    open_files_limit    = 65535    back_log = 1024    max_connections = 512    max_connect_errors = 1000000    table_open_cache = 1024    table_definition_cache = 1024    thread_stack = 512K    sort_buffer_size = 4M    join_buffer_size = 4M    read_buffer_size = 8M    read_rnd_buffer_size = 4M    bulk_insert_buffer_size = 64M    thread_cache_size = 768    interactive_timeout = 600    wait_timeout = 600    tmp_table_size = 32M    max_heap_table_size = 32M

Secret

配置->窃密字典,找到 mysql-secret,点击右侧的三个竖点,点击编辑 YAML

现网的 mysql-secret.yaml

kind: SecretapiVersion: v1metadata:  name: mysql-secret  namespace: lstack  annotations:    kubesphere.io/creator: lstackdata:  MYSQL_ROOT_PASSWORD: UEA4OHcwcmQ=type: Opaque

批改后的 mysql-secret.yaml

kind: SecretapiVersion: v1metadata:  name: mysql-secret  namespace: lstackdata:  MYSQL_ROOT_PASSWORD: UEA4OHcwcmQ=type: Opaque

这里要说一句,Secret 里的值是用 base64 形式加密的,所以这里的 MYSQL_ROOT_PASSWORD,要用理论的明码用 base64 的形式加密。

  • base64 解密。

    [root@ks-k8s-master-0 ~]# echo "UEA4OHcwcmQ=" | base64 -dP@88w0rd
  • base 加密。

    [root@ks-k8s-master-0 ~]# echo -n "P@88w0rd" | base64UEA4OHcwcmQ=

StatefulSet

利用负载->工作负载->有状态正本集,找到 mysql,点击右侧的三个竖点,点击编辑 YAML

现网的 mysql-sts.yaml

kind: StatefulSetapiVersion: apps/v1metadata:  name: mysql  namespace: lstack  labels:    app: mysql  annotations:    kubesphere.io/creator: lstackspec:  replicas: 1  selector:    matchLabels:      app: mysql  template:    metadata:      creationTimestamp: null      labels:        app: mysql      annotations:        logging.kubesphere.io/logsidecar-config: '{}'    spec:      volumes:        - name: host-time          hostPath:            path: /etc/localtime            type: ''        - name: volume-rca2zx          configMap:            name: mysql-cnf            items:              - key: custom.cnf                path: custom.cnf            defaultMode: 420      containers:        - name: lstack-mysql          image: 'mysql:5.7.38'          ports:            - name: tcp-mysql              containerPort: 3306              protocol: TCP          env:            - name: MYSQL_ROOT_PASSWORD              valueFrom:                secretKeyRef:                  name: mysql-secret                  key: MYSQL_ROOT_PASSWORD          resources:            limits:              cpu: '2'              memory: 4000Mi            requests:              cpu: 500m              memory: 500Mi          volumeMounts:            - name: host-time              mountPath: /etc/localtime            - name: data              mountPath: /var/lib/mysql            - name: volume-rca2zx              readOnly: true              mountPath: /etc/mysql/conf.d/custom.cnf              subPath: custom.cnf          terminationMessagePath: /dev/termination-log          terminationMessagePolicy: File          imagePullPolicy: IfNotPresent      restartPolicy: Always      terminationGracePeriodSeconds: 30      dnsPolicy: ClusterFirst      serviceAccountName: default      serviceAccount: default      securityContext: {}      schedulerName: default-scheduler  volumeClaimTemplates:    - kind: PersistentVolumeClaim      apiVersion: v1      metadata:        name: data        namespace: lstack        creationTimestamp: null      spec:        accessModes:          - ReadWriteOnce        resources:          requests:            storage: 5Gi        storageClassName: glusterfs        volumeMode: Filesystem      status:        phase: Pending  serviceName: mysql-1dpr  podManagementPolicy: OrderedReady  updateStrategy:    type: RollingUpdate    rollingUpdate:      partition: 0  revisionHistoryLimit: 10

批改后的 mysql-sts.yaml

kind: StatefulSetapiVersion: apps/v1metadata:  name: mysql  namespace: lstack  labels:    app: mysqlspec:  replicas: 1  selector:    matchLabels:      app: mysql  template:    metadata:      labels:        app: mysql    spec:      volumes:        - name: host-time          hostPath:            path: /etc/localtime            type: ''        - name: volume-cnf          configMap:            name: mysql-cnf            items:              - key: custom.cnf                path: custom.cnf            defaultMode: 420      containers:        - name: lstack-mysql          image: 'mysql:5.7.38'          ports:            - name: tcp-mysql              containerPort: 3306              protocol: TCP          env:            - name: MYSQL_ROOT_PASSWORD              valueFrom:                secretKeyRef:                  name: mysql-secret                  key: MYSQL_ROOT_PASSWORD          resources:            limits:              cpu: '2'              memory: 4000Mi            requests:              cpu: 500m              memory: 500Mi          volumeMounts:            - name: host-time              mountPath: /etc/localtime            - name: data              mountPath: /var/lib/mysql            - name: volume-cnf              mountPath: /etc/mysql/conf.d/custom.cnf              subPath: custom.cnf  volumeClaimTemplates:    - metadata:        name: data        namespace: lstack      spec:        accessModes:          - ReadWriteOnce        resources:          requests:            storage: 5Gi        storageClassName: glusterfs  serviceName: mysql-headless

Service

先创立 Headless 服务,利用负载->服务->,找到 mysql-xxxx(mysql),点击右侧的三个竖点,点击编辑 YAML

现网的 mysql-headless.yaml

kind: ServiceapiVersion: v1metadata:  name: mysql-1dpr  namespace: lstack  labels:    app: mysql  annotations:    kubesphere.io/alias-name: mysql    kubesphere.io/creator: lstack    kubesphere.io/serviceType: statefulservicespec:  ports:    - name: tcp-mysql      protocol: TCP      port: 3306      targetPort: 3306  selector:    app: mysql  clusterIP: None  clusterIPs:    - None  type: ClusterIP  sessionAffinity: None  ipFamilies:    - IPv4  ipFamilyPolicy: SingleStack

批改后的 mysql-headless.yaml

kind: ServiceapiVersion: v1metadata:  name: mysql-headless  namespace: lstack  labels:    app: mysqlspec:  ports:    - name: tcp-mysql      protocol: TCP      port: 3306      targetPort: 3306  selector:    app: mysql  clusterIP: None  type: ClusterIP

再看看自定义的 mysql-external 服务 ,利用负载->服务->,找到 mysql-external,点击右侧的三个竖点,点击编辑 YAML

现网的 mysql-external.yaml

kind: ServiceapiVersion: v1metadata:  name: mysql-external  namespace: lstack  labels:    app: mysql-external  annotations:    kubesphere.io/creator: lstackspec:  ports:    - name: tcp-mysql-external      protocol: TCP      port: 3306      targetPort: 3306      nodePort: 32529  selector:    app: mysql  clusterIP: 10.233.36.71  clusterIPs:    - 10.233.36.71  type: NodePort  sessionAffinity: None  externalTrafficPolicy: Cluster  ipFamilies:    - IPv4  ipFamilyPolicy: SingleStack

这里有一点要阐明 nodePort 这个参数,如果 K8s 集群可控,倡议布局一套服务端口应用标准,每个须要 nodePort 的服务都指定固定的端口,这样有利于运维的标准化。

批改后的 mysql-external.yaml(留神 nodePort 参数没有指定)。

kind: ServiceapiVersion: v1metadata:  name: mysql-external  namespace: lstack  labels:    app: mysql-externalspec:  ports:    - name: tcp-mysql-external      protocol: TCP      port: 3306      targetPort: 3306  selector:    app: mysql  type: NodePort

将 MySQL 资源配置清单提交到 Git 仓库。

通过下面的操作,咱们获取了 MySQL 的资源配置清单。

自己强迫症,喜爱分类寄存,所以我用了 4 个文件,mysql-headless.yamlmysql-sts.yaml 合并在一个文件当然你也能够放到一个配置文件里。

  • mysql-external.yaml
  • mysql-sts.yaml
  • mysql-secret.yaml
  • mysql-cfm.yaml

将资源配置清单提交到 Git 仓库

抉择 GitHub 作为主仓库,Gitee 作为同步仓库 (人工)。

本系列文档所有 k8s 的资源配置清单文件应用了一个公共仓库,生产环境倡议每种服务创立一个配置仓库,有利于更精细化的版本控制。

本文为了演示主备仓库的应用,所有抉择了 Github 和 Gitee 两种 Git 服务,理论应用中为了更好的应用体验倡议抉择 Gitee。

在 GitHub 新建一个仓库,仓库名称k8s-yaml,增加一个 README 文件初始化仓库,点击Create repository,确认创立。

将代码仓库 Clone 回本地。

$ git clone git@github.com:devops/k8s-yaml.git$ ls k8s-yaml README.md

新创建一个文件夹,用本人喜爱的文本编辑器 (举荐 vscode) 编辑 MySQL 的资源配置清单,并将文件放入新创建的文件夹。

为了当前的扩展性,这里创立了一个 single 命名的二级目录,寄存单实例的资源配置清单文件。

$ mkdir -p k8s-yaml/mysql/single$ ls -l k8s-yaml/mysql/singletotal 32-rw-r--r--  1 z  staff   646  5 11 19:23 mysql-cfm.yaml-rw-r--r--  1 z  staff   266  5 11 19:31 mysql-external.yaml-rw-r--r--  1 z  staff   134  5 11 19:23 mysql-secret.yaml-rw-r--r--  1 z  staff  1911  5 11 19:31 mysql-sts.yaml

将编辑好的资源配置文件清单,提交到 GitHub。

$ cd k8s-yaml$ git add .$ git commit -am '增加MySQL single资源配置清单'$ git push

在 GitHub 上查看,确认代码是否提交。

接下来将资源配置清单同步到 Gitee 备份仓库。

  • 本文采纳了手工推送同步的形式 (集体习惯)
  • Gitee 也反对主动同步 GitHub 的仓库 (更便捷)

在 Gitee 新建一个仓库,仓库名称k8s-yaml,类型默认公有,点击创立

创立实现后可去仓库设置中批改为开源。

创立实现后,因为咱们创立的时候,没抉择初始化仓库的配置,所以,默认会显示一个帮忙页面,通知你该如何提交代码到仓库。

因为,咱们曾经有了代码仓库,所以咱们抉择已有仓库的配置办法,将已有代码提交到 Gitee。

依据帮忙提醒操作,要留神 origin 咱们要换成 gitee

$ git remote add gitee https://gitee.com/zdevops/k8s-yaml.git$ git push -u gitee

在 Gitee 上查看,确认代码是否提交。

批改 Gitee 仓库为开源 (可选)。

Gitee 仓库->治理->仓库设置->根本信息,最初面是否开源,抉择开源仓库公开须知,三个都勾选,点击保留

批改后,你的代码仓库就是开源,所有人可见的了。

GitOps 初体验-在 K8s 集群上部署 MySQL

MySQL 资源配置清单曾经寄存到了 Git 在线仓库,接下来开启咱们的 GitOps 体验之旅。

登录 k8s 的 master 节点,执行前面的操作工作。

生产环境倡议打造独立的运维治理节点进行整个集群的治理 , 能够参考《基于 KubeSphere 玩转 k8s-运维治理节点打造手记》

装置 Git。

$ yum install git -y

创立 devops 目录,我抉择 /opt 目录作为 devops 的根目录。

$ mkdir /opt/devops$ cd /opt/devops/

从 Gitee 下载 k8s-yaml 仓库的代码。

$ git clone https://gitee.com/zdevops/k8s-yaml.git$ ls k8s-yaml/mysql  README.md

因为是同一个测试环境,先清理掉现有的 MySQL 服务。

$ kubectl get secrets -n lstack NAME                  TYPE                                  DATA   AGEdefault-token-x2gzv   kubernetes.io/service-account-token   3      31dmysql-secret          Opaque                                1      2d20h$ kubectl get configmaps -n lstack NAME               DATA   AGEkube-root-ca.crt   1      31dmysql-cnf          1      47h$ kubectl get service -n lstack NAME                                                     TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGEglusterfs-dynamic-afe88cf4-86b1-4215-833a-534c5f779a22   ClusterIP   10.233.13.188   <none>        1/TCP            2dmysql-1dpr                                               ClusterIP   None            <none>        3306/TCP         2dmysql-external                                           NodePort    10.233.36.71    <none>        3306:32529/TCP   47h$ kubectl get statefulsets -n lstack NAME    READY   AGEmysql   1/1     2d# 清理$ kubectl delete statefulsets mysql -n lstackstatefulset.apps "mysql" deleted$ kubectl delete service mysql-external -n lstackservice "mysql-external" deleted$ kubectl delete service mysql-1dpr -n lstackservice "mysql-1dpr" deleted$ kubectl delete secrets mysql-secret -n lstacksecret "mysql-secret" deleted$ kubectl delete configmaps mysql-cnf -n lstackconfigmap "mysql-cnf" deleted

利用资源配置清单一键部署 MySQL。

$ cd /opt/devops/k8s-yaml/$ lsmysql  README.md$ kubectl apply -f mysql/single/

验证后果,发现 StatefulSet 没有创立,剖析问题。

$ kubectl get statefulsets -n lstackNo resources found in lstack namespace.# 一开始我认为我脱漏了配置文件,ls看一眼,发现文件都在$ lsmysql  README.md$ cd mysql/$ lssingle$ cd single/$ lsmysql-cfm.yaml  mysql-external.yaml  mysql-secret.yaml  mysql-sts.yaml# 确认一下文件内容,发现文件也有内容$ vi mysql-sts.yaml# 再次执行,发现了端倪,为啥只有service/mysql-headless 的资源配置,没有statefulset$ kubectl apply -f mysql-sts.yaml service/mysql-headless unchanged# 再次确认,发现编辑文件的时候脱漏了一点,当一个配置文件有多种资源定义时,不同资源的配置间接须要用"---"分隔。批改配置文件再次执行,发现执行胜利。$ vi mysql-sts.yaml$ cd ..$ kubectl apply -f single/$ kubectl get statefulsets -n lstack -o wideNAME    READY   AGE   CONTAINERS     IMAGESmysql   1/1     31s   lstack-mysql   mysql:5.7.38$ kubectl get pods -n lstack -o wideNAME      READY   STATUS    RESTARTS   AGE   IP              NODE              NOMINATED NODE   READINESS GATESmysql-0   1/1     Running   0          35s   10.233.116.59   ks-k8s-master-2   <none>           <none>

回到咱们的 KubeSphere 的治理控制台,发现 mysql 的工作负载也能在界面中显示,这也验证了在原生 k8s 上的操作也会间接反馈到 KubeSphere 的治理控制台。

二次体验 GitOps

正好借着下面呈现的问题,二次体验一下 GitOps。咱们间接在部署服务器上批改了 mysql-sts.yaml,且批改后的后果验证胜利。

为了演示 GitOps 的更多场景,间接在部署服务器上批改,而后提交到在线代码仓库。

理论工作中我都是在本人的办公电脑上批改,提交到在线代码仓库,而后部署服务器拉取更新代码。

批改后的 mysql-sts.yaml,因为篇幅问题这里只演示要害局部,StatefulSet 的残缺配置见 Gitee 仓库或是前文。

---kind: StatefulSetapiVersion: apps/v1metadata:  name: mysql  namespace: lstack  labels:    app: mysql...---kind: ServiceapiVersion: v1metadata:  name: mysql-headless  namespace: lstack  labels:    app: mysqlspec:  ports:    - name: tcp-mysql      protocol: TCP      port: 3306      targetPort: 3306  selector:    app: mysql  clusterIP: None  type: ClusterIP

提交批改后的代码到代码仓库。

# 批改后查看git仓库的变动$ git diff diff --git a/mysql/single/mysql-sts.yaml b/mysql/single/mysql-sts.yamlindex f775920..1eded9c 100644--- a/mysql/single/mysql-sts.yaml+++ b/mysql/single/mysql-sts.yaml@@ -1,3 +1,4 @@+--- kind: StatefulSet apiVersion: apps/v1 metadata:@@ -68,6 +69,7 @@ spec:         storageClassName: glusterfs   serviceName: mysql-headless +--- kind: Service apiVersion: v1 metadata:# 本地提交代码变更$ git commit -am '修复mysql statefulset配置不失效问题'# push到在线代码仓库,有一个warning能够疏忽,也能够按提醒执行$ git push

查看 Gitee 在线代码仓库是否有变更。

在集体的办公电脑上,同步更新后的代码。

# 更新代码$ git pull# 同步更新后的代码到Github$ git push -u origin

查看 GitHub 在线代码仓库是否有变更。

再次体验 GitOps

模仿一个业务场景,再次体验一下 GitOps。

  • MySQL 上线运行后,因为业务量上涨,初始配置参数中的 max_connections 太小了,须要增大。
  • 配置参数调整实现后,更新线上配置,并重启服务 (生产环境数据库不要轻易重启,这种需要能够用长期批改解决)。
  • 这里只是模仿一个简略的例子,带大家体验 GitOps,理论应用中所有的配置文件都倡议应用 Git 进行版本控制。

编辑本地 Git 仓库 MySQL 资源配置清单中的 mysql-cfm.yaml 文件,批改 max_connections,从 512 变成 1024。

提交批改到 Git 在线仓库。

# 提交本地批改$ git commit -am '批改mysql-cnf中max_connections的值'# 提交到Github$ git push# 同步到Gitee$ git push -u gitee

登录运维治理节点,更新 Git 代码,并从新运行。

$ git pull$ kubectl apply -f mysql/single/# 查看ConfigMap的变动$ kubectl get configmaps mysql-cnf -n lstack -o yamlapiVersion: v1data:  custom.cnf: |-    [mysqld]    #performance setttings    lock_wait_timeout = 3600    open_files_limit    = 65535    back_log = 1024    max_connections = 1024    max_connect_errors = 1000000    table_open_cache = 1024    table_definition_cache = 1024    thread_stack = 512K    sort_buffer_size = 4M    join_buffer_size = 4M    read_buffer_size = 8M    read_rnd_buffer_size = 4M    bulk_insert_buffer_size = 64M    thread_cache_size = 768    interactive_timeout = 600    wait_timeout = 600    tmp_table_size = 32M    max_heap_table_size = 32Mkind: ConfigMapmetadata:  annotations:    kubectl.kubernetes.io/last-applied-configuration: |      {"apiVersion":"v1","data":{"custom.cnf":"[mysqld]\n#performance setttings\nlock_wait_timeout = 3600\nopen_files_limit    = 65535\nback_log = 1024\nmax_connections = 1024\nmax_connect_errors = 1000000\ntable_open_cache = 1024\ntable_definition_cache = 1024\nthread_stack = 512K\nsort_buffer_size = 4M\njoin_buffer_size = 4M\nread_buffer_size = 8M\nread_rnd_buffer_size = 4M\nbulk_insert_buffer_size = 64M\nthread_cache_size = 768\ninteractive_timeout = 600\nwait_timeout = 600\ntmp_table_size = 32M\nmax_heap_table_size = 32M"},"kind":"ConfigMap","metadata":{"annotations":{},"name":"mysql-cnf","namespace":"lstack"}}  creationTimestamp: "2022-05-12T07:20:07Z"  name: mysql-cnf  namespace: lstack  resourceVersion: "8928391"  uid: 1b7322cf-f11e-445d-a2ba-b42a90ade469# 重启mysql pod使配置失效$ kubectl delete -f mysql/single/mysql-sts.yaml $ kubectl apply -f mysql/single/mysql-sts.yaml # 查看mysql容器外部配置是否更新$ kubectl exec  mysql-0  -n lstack -- cat /etc/mysql/conf.d/custom.cnf[mysqld]#performance setttingslock_wait_timeout = 3600open_files_limit    = 65535back_log = 1024max_connections = 1024max_connect_errors = 1000000table_open_cache = 1024table_definition_cache = 1024thread_stack = 512Ksort_buffer_size = 4Mjoin_buffer_size = 4Mread_buffer_size = 8Mread_rnd_buffer_size = 4Mbulk_insert_buffer_size = 64Mthread_cache_size = 768interactive_timeout = 600wait_timeout = 600tmp_table_size = 32M

切记! 下面的例子只是让大家体验 GitOps,生产环境不要轻易重启数据库服务器,除非你晓得本人在干什么。

当初通过验证,咱们的 MySQL 的配置可用且比较稳定,咱们把这个好的状态记录下来,防止当前批改变更弄坏了,再找不回原来正确的配置。

在咱们的个人电脑上给以后的 Git 代码打个 Tag,记录以后的状态 (也能够通过在线仓库的治理界面操作)。

# 打tag -a tag名字 -m tag形容$ git tag -a v0.1  -m 'mysql version v0.1'# 查看现有tag$ git tag -lv0.1# 查看tag详细信息$ git show v0.1tag v0.1Tagger: devops <devops@163.com>Date:   Thu May 12 18:15:34 2022 +0800mysql version v0.1commit 180f97ac96da504a0b46eb4871ef423f64fde093 (HEAD -> main, tag: v0.1, origin/main, origin/HEAD, gitee/main)Author: devops <devops@163.com>Date:   Thu May 12 17:48:18 2022 +0800    批改mysql-cnf中max_connections的值diff --git a/mysql/single/mysql-cfm.yaml b/mysql/single/mysql-cfm.yamlindex e24d96d..50d1778 100644--- a/mysql/single/mysql-cfm.yaml+++ b/mysql/single/mysql-cfm.yaml@@ -10,7 +10,7 @@ data:     lock_wait_timeout = 3600     open_files_limit    = 65535     back_log = 1024-    max_connections = 512+    max_connections = 1024     max_connect_errors = 1000000     table_open_cache = 1024     table_definition_cache = 1024     # 将tag推送到近程服务器$ git push -u origin --tags$ git push -u gitee --tags# 线上服务器验证(图略)

运维治理服务器更新代码,并切换到指定 tag(留神!应用 Git 肯定要养成每次操作前 git pull 这种习惯)。

## 更新代码$ git pull## 切换到v0.1$ git checkout -b v0.1

通过下面的几波操作,咱们能够看到,咱们所有的配置变更都采纳了 Git 治理,残缺的记录了配置的全生命周期治理,通过给仓库打分支或是 tag,能够不便咱们切换到任意已记录状态。

高可用部署 MySQL(预留占坑)

临时没有高可用部署的需要,因而不波及高可用模式的 MySQL 的部署,然而有一些思考留着占坑。

目前的做法

  • 不给本人找麻烦,有高可用需要间接买云服务商的 RDS。
  • 切实须要本人搭建,在 K8s 集群之外部署主从。

当前可能的方向

  • K8s 上的 MySQL 主从部署
  • Operator
  • Helm

遗留问题

此局部内容也是运维 MySQL 必备的技能,有些内容我也没有教训无奈分享,有些内容会在 << 基于 KubeSphere 的 K8s 生产实践之路 >> 系列文档中介绍。

  • MySQL 数据库备份
  • MySQL 高可用部署
  • MySQL 平安加固
  • MySQL 调优

MySQL 性能 (基准) 测试

运维肯定要做到对本人的运维环境成竹在胸,MySQL 上线前肯定要进行性能 (基准测试),有助于理解咱们的数据库服务器能达到的现实状态。本次介绍的只是皮毛,只是通知大家一些根本入门的常识,更细节、更深刻的内容请参考其余更业余的文档。

性能 (基准) 测试工具装置

工具选型 (sysbench)

  • 云厂商展现自家数据库产品性能都用这个工具
  • 据说很多 DBA 也喜爱用

sysbench 工具装置

  • 装置工具
# 导入软件源$ curl -s https://packagecloud.io/install/repositories/akopytov/sysbench/script.rpm.sh | sudo bash# 装置sysbench$ yum install sysbench -y
  • 验证-执行命令查看版本
$ sysbench --versionsysbench 1.0.20

性能 (基准) 测试

测试计划

  • 测试参数
  • 指标
    线程数8/16/32
    单表数据量100000
    表数量16

    性能指标

    指标阐明
    TPSTransactions Per Second ,即数据库每秒执行的事务数,以 commit 胜利次数为准。
    QPSQueries Per Second ,即数据库每秒执行的 SQL 数(含 insert、select、update、delete 等)。
    RTResponse Time ,响应工夫。包含均匀响应工夫、最小响应工夫、最大响应工夫、每个响应工夫的查问占比。比拟须要重点关注的是,前 95-99% 的最大响应工夫。因为它决定了大多数状况下的短板。
    Concurrency Threads并发量,每秒可解决的查问申请的数量。

筹备测试数据

应用咱们在 k8s 上创立的数据库,波及数据库操作命令,须要终端登录到容器内运行。

提前创立测试用数据库 sbtest,并赋予 root 从任意 IP 远程管理所有数据库的权限。

生产环境千万不要这么搞,肯定要遵循最小化准则!

# bashroot@mysql-0:/# mysql -u root -pEnter password:Welcome to the MySQL monitor.  Commands end with ; or \g.Your MySQL connection id is 4Server version: 5.7.38 MySQL Community Server (GPL)Copyright (c) 2000, 2022, Oracle and/or its affiliates.Oracle is a registered trademark of Oracle Corporation and/or itsaffiliates. Other names may be trademarks of their respectiveowners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql> create database sbtest;Query OK, 1 row affected (0.02 sec)mysql> grant all privileges on *.* to 'root'@'%' identified by 'P@88w0rd' with grant option;Query OK, 0 rows affected, 1 warning (0.02 sec)
  • 测试数据库是否能连贯
# 装置mysql客户端,上面的示例是在k8s节点上装置的,因为零碎是最小化装置,所有会装置很多依赖。理论测试能够起一个mysql的pod或是用其余的mysql客户端工具。$ yum install mysql -y# 测试MySQL服务连通性 -h 是k8s节点的IP -P 是mysql内部服务的端口号$ mysql -h 192.168.9.91 -P 32529 -u root -pEnter password: Welcome to the MariaDB monitor.  Commands end with ; or \g.Your MySQL connection id is 5Server version: 5.7.38 MySQL Community Server (GPL)Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.MySQL [(none)]> 
  • 筹备测试数据
$ sysbench --db-driver=mysql --mysql-host=192.168.9.91 --mysql-port=32529 --mysql-user=root --mysql-password=P@88w0rd --mysql-db=sbtest --table-size=100000 --tables=16 --threads=8 --events=999999999 --report-interval=10 --time=100 /usr/share/sysbench/oltp_common.lua preparesysbench 1.0.20 (using bundled LuaJIT 2.1.0-beta2)Initializing worker threads...Creating table 'sbtest6'...Creating table 'sbtest2'...Creating table 'sbtest8'...Creating table 'sbtest3'...Creating table 'sbtest7'...Creating table 'sbtest5'...Creating table 'sbtest1'...Creating table 'sbtest4'...Inserting 100000 records into 'sbtest3'Inserting 100000 records into 'sbtest6'Inserting 100000 records into 'sbtest1'Inserting 100000 records into 'sbtest4'Inserting 100000 records into 'sbtest7'Inserting 100000 records into 'sbtest5'Inserting 100000 records into 'sbtest2'Inserting 100000 records into 'sbtest8'Creating a secondary index on 'sbtest3'...Creating table 'sbtest11'...Inserting 100000 records into 'sbtest11'Creating a secondary index on 'sbtest5'...Creating a secondary index on 'sbtest1'...Creating a secondary index on 'sbtest6'...Creating a secondary index on 'sbtest4'...Creating a secondary index on 'sbtest7'...Creating a secondary index on 'sbtest2'...Creating a secondary index on 'sbtest8'...Creating table 'sbtest13'...Inserting 100000 records into 'sbtest13'Creating table 'sbtest9'...Inserting 100000 records into 'sbtest9'Creating table 'sbtest14'...Creating table 'sbtest12'...Inserting 100000 records into 'sbtest14'Inserting 100000 records into 'sbtest12'Creating table 'sbtest15'...Inserting 100000 records into 'sbtest15'Creating table 'sbtest16'...Creating table 'sbtest10'...Inserting 100000 records into 'sbtest16'Inserting 100000 records into 'sbtest10'Creating a secondary index on 'sbtest11'...Creating a secondary index on 'sbtest13'...Creating a secondary index on 'sbtest9'...Creating a secondary index on 'sbtest12'...Creating a secondary index on 'sbtest14'...Creating a secondary index on 'sbtest15'...Creating a secondary index on 'sbtest10'...Creating a secondary index on 'sbtest16'...
  • 执行测试-8 线程测试
$ sysbench --db-driver=mysql --mysql-host=192.168.9.91 --mysql-port=32529 --mysql-user=root --mysql-password=P@88w0rd --mysql-db=sbtest --table-size=100000 --tables=16 --threads=8 --events=999999999 --report-interval=10 --time=100  /usr/share/sysbench/oltp_read_write.lua runsysbench 1.0.20 (using bundled LuaJIT 2.1.0-beta2)Running the test with following options:Number of threads: 8Report intermediate results every 10 second(s)Initializing random number generator from current timeInitializing worker threads...Threads started![ 10s ] thds: 8 tps: 88.46 qps: 1782.38 (r/w/o: 1249.19/355.46/177.73) lat (ms,95%): 267.41 err/s: 0.00 reconn/s: 0.00[ 20s ] thds: 8 tps: 84.31 qps: 1678.47 (r/w/o: 1173.42/336.43/168.62) lat (ms,95%): 277.21 err/s: 0.00 reconn/s: 0.00[ 30s ] thds: 8 tps: 70.20 qps: 1413.82 (r/w/o: 990.21/283.20/140.40) lat (ms,95%): 369.77 err/s: 0.00 reconn/s: 0.00[ 40s ] thds: 8 tps: 47.30 qps: 946.00 (r/w/o: 662.20/189.20/94.60) lat (ms,95%): 484.44 err/s: 0.00 reconn/s: 0.00[ 50s ] thds: 8 tps: 43.80 qps: 875.99 (r/w/o: 613.19/175.20/87.60) lat (ms,95%): 484.44 err/s: 0.00 reconn/s: 0.00[ 60s ] thds: 8 tps: 60.70 qps: 1213.08 (r/w/o: 849.69/242.00/121.40) lat (ms,95%): 411.96 err/s: 0.00 reconn/s: 0.00[ 70s ] thds: 8 tps: 53.90 qps: 1078.22 (r/w/o: 754.42/216.00/107.80) lat (ms,95%): 376.49 err/s: 0.00 reconn/s: 0.00[ 80s ] thds: 8 tps: 56.49 qps: 1127.98 (r/w/o: 790.11/224.88/112.99) lat (ms,95%): 397.39 err/s: 0.00 reconn/s: 0.00[ 90s ] thds: 8 tps: 50.60 qps: 1014.59 (r/w/o: 709.56/203.82/101.21) lat (ms,95%): 434.83 err/s: 0.00 reconn/s: 0.00[ 100s ] thds: 8 tps: 54.70 qps: 1093.12 (r/w/o: 765.22/218.50/109.40) lat (ms,95%): 390.30 err/s: 0.00 reconn/s: 0.00SQL statistics:    queries performed:        read:                            85582        write:                           24452        other:                           12226        total:                           122260    transactions:                        6113   (61.10 per sec.)    queries:                             122260 (1221.96 per sec.)    ignored errors:                      0      (0.00 per sec.)    reconnects:                          0      (0.00 per sec.)General statistics:    total time:                          100.0494s    total number of events:              6113Latency (ms):         min:                                   35.63         avg:                                  130.89         max:                                  951.86         95th percentile:                      390.30         sum:                               800129.59Threads fairness:    events (avg/stddev):           764.1250/4.14    execution time (avg/stddev):   100.0162/0.01
  • 执行测试-16 线程测试

    $ sysbench --db-driver=mysql --mysql-host=192.168.9.91 --mysql-port=32529 --mysql-user=root --mysql-password=P@88w0rd --mysql-db=sbtest --table-size=100000 --tables=16 --threads=16 --events=999999999 --report-interval=10 --time=100  /usr/share/sysbench/oltp_read_write.lua runsysbench 1.0.20 (using bundled LuaJIT 2.1.0-beta2)Running the test with following options:Number of threads: 16Report intermediate results every 10 second(s)Initializing random number generator from current timeInitializing worker threads...Threads started![ 10s ] thds: 16 tps: 114.41 qps: 2310.22 (r/w/o: 1621.18/458.63/230.41) lat (ms,95%): 369.77 err/s: 0.00 reconn/s: 0.00[ 20s ] thds: 16 tps: 106.35 qps: 2111.86 (r/w/o: 1474.74/424.41/212.71) lat (ms,95%): 383.33 err/s: 0.00 reconn/s: 0.00[ 30s ] thds: 16 tps: 80.40 qps: 1612.01 (r/w/o: 1129.21/322.00/160.80) lat (ms,95%): 623.33 err/s: 0.00 reconn/s: 0.00[ 40s ] thds: 16 tps: 63.40 qps: 1266.80 (r/w/o: 886.80/253.20/126.80) lat (ms,95%): 539.71 err/s: 0.00 reconn/s: 0.00[ 50s ] thds: 16 tps: 57.20 qps: 1145.91 (r/w/o: 802.74/228.78/114.39) lat (ms,95%): 549.52 err/s: 0.00 reconn/s: 0.00[ 60s ] thds: 16 tps: 69.91 qps: 1408.31 (r/w/o: 987.57/280.92/139.81) lat (ms,95%): 511.33 err/s: 0.00 reconn/s: 0.00[ 70s ] thds: 16 tps: 78.00 qps: 1547.22 (r/w/o: 1080.51/310.70/156.00) lat (ms,95%): 484.44 err/s: 0.00 reconn/s: 0.00[ 80s ] thds: 16 tps: 79.50 qps: 1599.87 (r/w/o: 1122.58/318.29/159.00) lat (ms,95%): 520.62 err/s: 0.00 reconn/s: 0.00[ 90s ] thds: 16 tps: 67.80 qps: 1354.83 (r/w/o: 947.62/271.61/135.60) lat (ms,95%): 539.71 err/s: 0.00 reconn/s: 0.00[ 100s ] thds: 16 tps: 73.90 qps: 1474.10 (r/w/o: 1030.80/295.50/147.80) lat (ms,95%): 502.20 err/s: 0.00 reconn/s: 0.00SQL statistics:  queries performed:      read:                            110950      write:                           31700      other:                           15850      total:                           158500  transactions:                        7925   (79.00 per sec.)  queries:                             158500 (1580.05 per sec.)  ignored errors:                      0      (0.00 per sec.)  reconnects:                          0      (0.00 per sec.)General statistics:  total time:                          100.3103s  total number of events:              7925Latency (ms):       min:                                   41.24       avg:                                  202.44       max:                                 1198.81       95th percentile:                      511.33       sum:                              1604328.52Threads fairness:  events (avg/stddev):           495.3125/4.03  execution time (avg/stddev):   100.2705/0.03
  • 执行测试-32 线程测试
$ sysbench --db-driver=mysql --mysql-host=192.168.9.91 --mysql-port=32529 --mysql-user=root --mysql-password=P@88w0rd --mysql-db=sbtest --table-size=100000 --tables=16 --threads=32 --events=999999999 --report-interval=10 --time=100  /usr/share/sysbench/oltp_read_write.lua runsysbench 1.0.20 (using bundled LuaJIT 2.1.0-beta2)Running the test with following options:Number of threads: 32Report intermediate results every 10 second(s)Initializing random number generator from current timeInitializing worker threads...Threads started![ 10s ] thds: 32 tps: 140.10 qps: 2825.04 (r/w/o: 1981.25/560.39/283.39) lat (ms,95%): 450.77 err/s: 0.00 reconn/s: 0.00[ 20s ] thds: 32 tps: 124.41 qps: 2515.49 (r/w/o: 1763.43/503.24/248.82) lat (ms,95%): 549.52 err/s: 0.00 reconn/s: 0.00[ 30s ] thds: 32 tps: 95.90 qps: 1887.10 (r/w/o: 1316.70/378.60/191.80) lat (ms,95%): 733.00 err/s: 0.00 reconn/s: 0.00[ 40s ] thds: 32 tps: 81.80 qps: 1656.59 (r/w/o: 1164.89/328.10/163.60) lat (ms,95%): 707.07 err/s: 0.00 reconn/s: 0.00[ 50s ] thds: 32 tps: 82.60 qps: 1638.41 (r/w/o: 1143.51/329.70/165.20) lat (ms,95%): 657.93 err/s: 0.00 reconn/s: 0.00[ 60s ] thds: 32 tps: 94.34 qps: 1905.84 (r/w/o: 1336.62/380.65/188.58) lat (ms,95%): 623.33 err/s: 0.00 reconn/s: 0.00[ 70s ] thds: 32 tps: 87.86 qps: 1739.86 (r/w/o: 1215.31/348.73/175.82) lat (ms,95%): 634.66 err/s: 0.00 reconn/s: 0.00[ 80s ] thds: 32 tps: 84.40 qps: 1705.48 (r/w/o: 1196.49/340.20/168.80) lat (ms,95%): 759.88 err/s: 0.00 reconn/s: 0.00[ 90s ] thds: 32 tps: 80.50 qps: 1580.71 (r/w/o: 1101.70/318.00/161.00) lat (ms,95%): 612.21 err/s: 0.00 reconn/s: 0.00[ 100s ] thds: 32 tps: 81.40 qps: 1661.90 (r/w/o: 1167.00/332.10/162.80) lat (ms,95%): 707.07 err/s: 0.00 reconn/s: 0.00SQL statistics:    queries performed:        read:                            133924        write:                           38264        other:                           19132        total:                           191320    transactions:                        9566   (95.33 per sec.)    queries:                             191320 (1906.56 per sec.)    ignored errors:                      0      (0.00 per sec.)    reconnects:                          0      (0.00 per sec.)General statistics:    total time:                          100.3457s    total number of events:              9566Latency (ms):         min:                                   51.94         avg:                                  335.14         max:                                 1405.78         95th percentile:                      657.93         sum:                              3205913.85Threads fairness:    events (avg/stddev):           298.9375/5.15    execution time (avg/stddev):   100.1848/0.14

MySQL 容器性能监控图。

清理测试数据 (为了保证数据更精准,倡议每次测试前都清理数据,筹备数据,测试)。

$ sysbench --db-driver=mysql --mysql-host=192.168.9.91 --mysql-port=32529 --mysql-user=root --mysql-password=P@88w0rd --mysql-db=sbtest --table-size=100000 --tables=16 --threads=32 --events=999999999 --report-interval=10 --time=100  /usr/share/sysbench/oltp_read_write.lua cleanupsysbench 1.0.20 (using bundled LuaJIT 2.1.0-beta2)Dropping table 'sbtest1'...Dropping table 'sbtest2'...Dropping table 'sbtest3'...Dropping table 'sbtest4'...Dropping table 'sbtest5'...Dropping table 'sbtest6'...Dropping table 'sbtest7'...Dropping table 'sbtest8'...Dropping table 'sbtest9'...Dropping table 'sbtest10'...Dropping table 'sbtest11'...Dropping table 'sbtest12'...Dropping table 'sbtest13'...Dropping table 'sbtest14'...Dropping table 'sbtest15'...Dropping table 'sbtest16'...

测试后果

后果汇总比照。

压测线程数量TPSQPS提早
8611221130
16791580202
32951906335

倡议依据测试后果,调优!

总结

本文具体介绍了 Git 罕用操作、如何将代码在多个在线代码仓库中存储并放弃同步,还介绍了 GitOps 的基本概念并演示了如何用 GitOps 理念在原生 K8s 上部署 MySQL 服务。最初,演示了 MySQL 罕用性能测试工具 sysbench 的装置和根底应用。

我多年的一些运维教训和运维思路贯通了全文。

本文由博客一文多发平台 OpenWrite 公布!