deploy mysql operator on k8s

本文通过 mysql-operator 在kubernetes集群部署高可用的mysql statefulset。

环境准备

本文使用的开源 operator 项目 mysql-operator 配死只支持 mysql 8.0.11 以上的版本,改了下代码,支持 5.7.0 以上版本,项目地址,本文部署的是 mysql-5.7.26,使用的 dockerhub 上的镜像 mysql/mysql-server:5.7.26。

代码编译

git clone 下载该项目,进入到代码目录,执行sh hack/build.sh,编译代码得到二进制文件 mysql-agent 和 mysql-operator,将二进制文件放入 bin/linux_amd64,执行docker build -f docker/mysql-agent/Dockerfile -t $IMAGE_NAME_AGENT .docker build -f docker/mysql-operator/Dockerfile -t $IMAGE_NAME_OPERATOR .构建镜像,mysql-operator 生成的镜像为 operator 的镜像,mysql-agent 生成的是镜像,在创建mysql服务时,作为sidecar和mysql-server容器起在同一个pod中。

部署 operator

先根据 文档 部署 mysql-operator 的 Deployment,文档中是使用 helm 安装,不希望安装 helm 和 tiller 的话,可以只安装一个 helm 客户端,进入到代码目录,再执行helm template --name mysql-operator mysql-operator生成部署所需要的yaml文件,然后直接执行kubectl apply -f mysql-operator.yaml创建 operator。这个yaml创建了operator所需的CRD类型,operator 的 Deployment 和 operator 所需的 RBAC 权限等。

# change directory into mysql-operator
cd mysql-operator
# generate mysql-operator.yaml
helm template --name mysql-operator mysql-operator > mysql-operator.yaml
# deploy on kubernetes
kubectl apply -f mysql-operator.yaml
# deployed.
[[email protected]]$ kubectl get deploy -n mysql-operator
NAME             READY   UP-TO-DATE   AVAILABLE   AGE
mysql-operator   1/1     1            1           2d5h

创建 mysql 集群

本文创建的集群为3节点的 mysql,一个节点为 master,二个为 slave,master节点可读写,slave节点为只读,使用 kubernetes Local PV 作持久化存储。
首先,为每个节点创建一个PV,Local PV 需要定义nodeAffinity,约束创建的节点。

apiVersion: v1
kind: PersistentVolume
metadata:
  name: mypv0
spec:
  capacity:
    storage: 1Gi
  volumeMode: Filesystem
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Delete
  storageClassName: mysql-storage
  local:
    path: /data/mysql-data
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - 192.168.0.1

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: mypv1
spec:
  capacity:
    storage: 1Gi
  volumeMode: Filesystem
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Delete
  storageClassName: mysql-storage
  local:
    path: /data/mysql-data
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - 192.168.0.2

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: mypv2
spec:
  capacity:
    storage: 1Gi
  volumeMode: Filesystem
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Delete
  storageClassName: mysql-storage
  local:
    path: /data/mysql-data
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - 192.168.0.3
# create pv
kubectl create -f pv.yaml
# get presistence volume
[[email protected]]$ kubectl get pv
mypv-0               1Gi        RWO            Delete           Available                                                                     mysql-storage               4s
mypv-1               1Gi        RWO            Delete           Available                                                                     mysql-storage               4s
mypv-2               1Gi        RWO            Delete           Available                                                                     mysql-storage               4s

接着,需要在创建 mysql 的 namespace 下,为要创建的 mysql 创建对应的 RBAC 权限。

apiVersion: v1
kind: ServiceAccount
metadata:
  name: mysql-agent
  namespace: mysql2
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: mysql-agent
  namespace: mysql2
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: mysql-agent
subjects:
- kind: ServiceAccount
  name: mysql-agent
  namespace: mysql2

如果需要自定义 mysql 的密码,需要为其创建一个 secret,密码需要使用base64加密。linux 下执行 echo -n ‘password‘ | base64 为密码加密。

apiVersion: v1
data:
  password: cm9vdA==
kind: Secret
metadata:
  labels:
    v1alpha1.mysql.oracle.com/cluster: mysql
  name: mysql-pv-root-password
  namespace: mysql2
kubectl apply -f rbac.yaml
kubectl apply -f secret.yaml

在创建 operator 的时候,已经创建了如下的crd类型,部署mysql集群所需创建的就是 mysqlclusters 类型的资源。

[[email protected]]$ kubectl get crd  | grep mysql
mysqlbackups.mysql.oracle.com                2019-05-14T02:51:11Z
mysqlbackupschedules.mysql.oracle.com        2019-05-14T02:51:11Z
mysqlclusters.mysql.oracle.com               2019-05-14T02:51:11Z
mysqlrestores.mysql.oracle.com               2019-05-14T02:51:11Z

接下来开始创建 operator 自定义资源类型(CRD)的实例 mysqlclusters。

apiVersion: mysql.oracle.com/v1alpha1
kind: Cluster
metadata:
  name: mysql
  namespace: mysql2
spec:
  # 和mysql-server镜像版本的tag一直
  version: 5.7.26
  repository: 20.26.28.56/dcos/mysql-server
  # 节点数量
  members: 3
  # 指定 mysql 密码,和之前创建的secret名称一致
  rootPasswordSecret:
    name: mysql-pv-root-password
  resources:
    agent:
      limits:
        cpu: 500m
        memory: 200Mi
      requests:
        cpu: 300m
        memory: 100Mi
    server:
      limits:
        cpu: 1000m
        memory: 1000Mi
      requests:
        cpu: 500m
        memory: 500Mi
  volumeClaimTemplate:
    metadata:
      name: mysql-pv
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "mysql-storage"
      resources:
        requests:
          storage: 1Gi
kubectl apply -f mysql.yaml

执行后,会看到 kubernetes 在该 namespace 下开始拉起 mysql 的 statefulset,并会创建一个 headless service。

[[email protected]]$ kubectl get all -n mysql2
NAME                                                      READY   STATUS    RESTARTS   AGE
pod/mysql-0                                               2/2     Running   0          8h
pod/mysql-1                                               2/2     Running   0          8h
pod/mysql-2                                               2/2     Running   0          8h

NAME              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
service/mysql     ClusterIP   None            <none>        3306/TCP   21h

NAME                     READY   AGE
statefulset.apps/mysql   1/1     21h

此时执行hack/cluster-status.sh脚本,会得到如下集群信息:

{
    "clusterName": "Cluster",
    "defaultReplicaSet": {
        "name": "default",
        "primary": "mysql-0.mysql:3306",
        "ssl": "DISABLED",
        "status": "OK_NO_TOLERANCE",
        "statusText": "Cluster is NOT tolerant to any failures. 2 members are not active",
        "topology": {
            "mysql-0.mysql:3306": {
                "address": "mysql-0.mysql:3306",
                "mode": "R/W",
                "readReplicas": {},
                "role": "HA",
                "status": "ONLINE"
            },
            "mysql-1.mysql:3306": {
                "address": "mysql-1.mysql:3306",
                "mode": "n/a",
                "readReplicas": {},
                "role": "HA",
                "status": "ONLINE"
            },
            "mysql-2.mysql:3306": {
                "address": "mysql-2.mysql:3306",
                "mode": "n/a",
                "readReplicas": {},
                "role": "HA",
                "status": "ONLINE"
            }
        },
        "topologyMode": "Single-Primary"
    },
    "groupInformationSourceMember": "mysql-0.mysql:3306"
}

通过DNS地址 mysql-0.mysql.mysql2.svc.cluster.local:3306 可以连接到数据库进行读写操作。此时一个多节点的mysql集群已经部署完成,但是,集群外部的服务还无法访问数据库。

通过 haproxy-ingress 允许外部访问

首先,headless service只能通过集群内 DNS 访问服务,要外部访问,还需要另外创建一个 Service。为了让外部可以访问到 mysql-0 的服务,我们为 mysql-0 创建一个ClusterIP 类型的服务。

kind: Service
apiVersion: v1
metadata:
  name: mysql-0
  namespace: mysql2
spec:
  selector:
    # 通过 selector 将 pod 约束到 mysql-0
   statefulset.kubernetes.io/pod-name: mysql-0
  ports:
    - protocol: TCP
      port: 3306
      targetPort: 3306

接着,需要创建一个ingress-controller,本文选用的是 haproxy-ingress
由于 mysql 服务通过 TCP 协议通信,kubernetes ingress 默认只支持 http 和 https,haproxy-ingress 提供了通过 configmap 的方法,配置 TCP 服务的端口,需要先创建一个 configmap,configmap的data中,key为HAProxy监听的端口,value 为需要转发的 service 的服务和端口。

apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql-tcp
  namespace: mysql2
data:
  "3306": "mysql2/mysql-0:3306"
kubectl apply -f mysql-0.yaml
kubectl apply -f tcp-svc.yaml

接下来创建 ingress-controller,

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  labels:
    run: haproxy-ingress
  name: haproxy-ingress-192.168.0.1-30080
  namespace: mysql2
spec:
  replicas: 1
  selector:
    matchLabels:
      run: haproxy-ingress
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        run: haproxy-ingress
    spec:
      tolerations:
      - key: app
        operator: Equal
        value: haproxy
        effect: NoSchedule
      serviceAccount: ingress-controller
      nodeSelector:
        kubernetes.io/hostname: 192.168.0.1
      containers:
      - args:
        - --tcp-services-configmap=$(POD_NAMESPACE)/mysql-tcp
        - --default-backend-service=$(POD_NAMESPACE)/mysql
        - --default-ssl-certificate=$(POD_NAMESPACE)/tls-secret
        - --ingress-class=ha-mysql
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.namespace
        image: jcmoraisjr/haproxy-ingress
        name: haproxy-ingress
        ports:
          # 和 configmap 中定义的端口对应
        - containerPort: 3306
          hostPort: 3306
          name: http
          protocol: TCP
        - containerPort: 443
          name: https
          protocol: TCP
        - containerPort: 1936
          hostPort: 30081
          name: stat
          protocol: TCP
apiVersion: v1
kind: ServiceAccount
metadata:
  name: ingress-controller

---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: ingress-controller
rules:
  - apiGroups:
      - ""
    resources:
      - configmaps
      - pods
      - secrets
      - namespaces
    verbs:
      - get
  - apiGroups:
      - ""
    resources:
      - configmaps
    verbs:
      - get
      - update
  - apiGroups:
      - ""
    resources:
      - configmaps
    verbs:
      - create
  - apiGroups:
      - ""
    resources:
      - endpoints
    verbs:
      - get
      - create
      - update

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: ingress-controller
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: ingress-controller
subjects:
  - kind: ServiceAccount
    name: ingress-controller
  - apiGroup: rbac.authorization.k8s.io
    kind: User
    name: ingress-controller

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: ingress-controller
rules:
  - apiGroups:
      - ""
    resources:
      - configmaps
      - endpoints
      - nodes
      - pods
      - secrets
    verbs:
      - list
      - watch
  - apiGroups:
      - ""
    resources:
      - nodes
    verbs:
      - get
  - apiGroups:
      - ""
    resources:
      - services
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - "extensions"
    resources:
      - ingresses
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - ""
    resources:
      - events
    verbs:
      - create
      - patch
  - apiGroups:
      - "extensions"
    resources:
      - ingresses/status
    verbs:
      - update

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: ingress-controller
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: ingress-controller
subjects:
  - kind: ServiceAccount
    name: ingress-controller
    namespace: mysql2
  - apiGroup: rbac.authorization.k8s.io
    kind: User
    name: ingress-controller
kubectl apply -f ingress-controller.yaml
kubectl apply -f ingress-rbac.yaml -n mysql2

最后创建 ingress 规则:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    ingress.kubernetes.io/ssl-redirect: "false"
    kubernetes.io/ingress.class: ha-mysql
  name: ha-mysql
spec:
  rules:
  - http:
      paths:
      - backend:
          serviceName: mysql-0
          servicePort: 3306
        path: /

此时可以通过 haproxy 的 IP + 映射端口访问到 mysql 集群。

附件

以下是上面用到的 yaml 文件:

  • rbac.yaml
  • mysql.yaml
  • secret.yaml
  • pv.yaml
  • mysql-0-svc.yaml
  • tcp-svc.yaml
  • ingress-controller.yaml
  • ingress-rbac.yaml
  • ingress.yaml

原文地址:https://www.cnblogs.com/maoqide/p/11258515.html

时间: 2024-08-11 18:32:16

deploy mysql operator on k8s的相关文章

基于Helm和Operator的K8S应用管理的分享

本文由3月7日晚李平辉,Rancher Labs 研发工程师所做的技术分享整理而成.李平辉熟悉应用容器化解决方案设计和实施,熟悉持续集成方案,关注并参与K8S生态的发展,负责Rancher中国区持续集成服务研发.搜索微信号RancherLabsChina,添加Rancher小助手为好友,可加入官方技术交流群,实时参加下一次分享~? ? ?? 大家好,今天我们分享的内容是基于Helm和Operator的K8S应用管理.我们知道,Kubernetes基于服务粒度提供了多种资源描述类型.描述一个应用系

基于Helm和Operator的K8S应用管理

https://blog.csdn.net/RancherLabs/article/details/79483013 大家好,今天我们分享的内容是基于Helm和Operator的K8S应用管理. 我们知道,Kubernetes基于服务粒度提供了多种资源描述类型.描述一个应用系统尤其是微服务架构系统,需要组合使用大量的Kubernetes资源.针对有状态应用,常常还需要复杂的运维管理操作以及更多的领域知识. 今晚的分享就将介绍如何用Helm这一Kubernetes应用包管理的社区主导方案来简化应用

使用Yearning 做MYSQL审计docker+K8S部署

下载percona-toolkit (可选) 工作目录 /apps/work/docker/sql-audit 下载percona-toolkit 套件 wget https://www.percona.com/downloads/percona-toolkit/3.0.13/binary/tarball/percona-toolkit-3.0.13_x86_64.tar.gz tar -xvf percona-toolkit-3.0.13_x86_64.tar.gz cd percona-to

Deploy MySQL driver in Eclipse project

put mysql-connector-java-5.x.x-bin.jar into WEB-INF\lib. Right click project name, Build Path -> Configure Build Path -> Java Build Path -> Libraries Click 'Add External JARs', dialog 'JAR Selection' pops up, chose the path where mysql-connector-

如何基于 k8s 开发高可靠服务?容器云牛人有话说

?? k8s 是当前主流的容器编排服务,它主要解决「集群环境」下「容器化应用」的「管理问题」,主要包括如下几方面:?? 容器集群管理 编排? 调度? 访问? ? 基础设施管理 计算资源? 网络资源? 存储资源?? k8s 的强大依赖于它良好的设计理念和抽象,吸引了越来越多的开发者投入到 k8s 社区,把 k8s 作为基础设施运行服务的公司也逐步增多.?在设计理念方面,k8s 只有 APIServer 与 etcd (存储) 通信,其他组件在内存中维护状态,通过 APIServer 持久化数据.管

基于k8s、docker、jenkins构建springboot服务

Jenkins + github + docker + k8s + springboot 本文介绍基于k8s.docker.jenkins.springboot构建docker服务. 环境准备 server-1 k8s-master Centos7 ip地址10.12.5.110 server-2 k8s-node Centos7 ip地址10.12.5.115 两台服务执行如下命令 $ setenforce 0 $ systemctl stop firewalld $ systemctl di

(转)Kubernetes Operator 快速入门教程

https://www.qikqiak.com/post/k8s-operator-101/ 在 Kubernetes 的监控方案中我们经常会使用到一个Promethues Operator的项目,该项目可以让我们更加方便的去使用 Prometheus,而不需要直接去使用最原始的一些资源对象,比如 Pod.Deployment,随着 Prometheus Operator 项目的成功,CoreOS 公司开源了一个比较厉害的工具:Operator Framework,该工具可以让开发人员更加容易的

MySQL系列之一键安装脚本----单实例/多实例

最近在搞MySQL,由于经常测试一些东西.因此,就写了一个一键安装脚本. 脚本用途: 用于在CentOS/RHEL 6.x系统上快速部署出Mysql的单实例或者多实例环境 脚本说明: 该脚本运行情况良好 针对脚本中,每一步命令执行的正误判断以及提醒非常醒目,可协助执行者快速定位错误源 脚本诸多内容都以声明变量,增加了脚本的灵活性和扩展性 脚本以做模块化处理,对应功能对应函数,方便SA快速更改和了解该脚本 该脚本使用注意事项: 1.能够通公网或者mysql源码包已经放置到/usr/local/sr

单机使用tungsten 同步mysql数据到mongodb

[注意],当前的测试环境仅仅是一台服务器. 部署测试的tungten版本是2.1.2-xxxx; Requirements: mysql配置 To change the Tungsten user to use the new password format complete the following steps mysql>set session old_passwords=0; 设置二进制日志格式=row; 主mysql端服务器执行命令: ./tools/tungsten-installe