K8S에서 MySQL 연산자 배포

으로 MySQL의 연산자 는 Kubernetes 클러스터의 고 가용성 MySQL의 statefulset의 배포.

환경 준비

본원에 사용 된 바와 같이, 오픈 소스 프로젝트 운영자 MySQL을 오퍼레이터 죽음은 5.7.0 MySQL은보다 코드에 따라 변경 8.0.11 버전, 지원을 더 지원하는 이상 프로젝트 주소 ,이 배치는 dockerhub 사용 MySQL을 5.7.26 인 미러 mysql을 / mysql을 서버 : 5.7.26.

코드 컴파일

자식 클론 코드 디렉토리 실행로 나아가서 다운로드 sh hack/build.sh바이너리로 MySQL 바이너리 에이전트와 MySQL 연산자를 얻을 수있는 컴파일 된 코드를 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을 오퍼레이터 오퍼레이터 미러 이미지의 이미지를 생성하는, 미러를 구성, MySQL- 에이전트를 생성하는 단계 MySQL의 서비스를 생성 할 때, 상기 포드로부터 동일한 용기에 사이드카의 MySQL 서버 등의 미러 이미지이다.

배포 연산자

우선에 따라 문서 문서의 배포 배포 MySQL의 연산자 조타 장치 설치를 사용하는 것입니다, 당신은 단지하는 투구 클라이언트를 설치 코드 디렉토리를 입력 한 후 실행할 수 있습니다, 조 타 장치 및 경운기를 설치하지 않으려는 helm template --name mysql-operator mysql-operator바로 다음 YAML 파일 생성 배포 필요하고, 실행 kubectl apply -f mysql-operator.yaml연산자를 생성한다. CRD의 YAML 연산자의 원하는 유형, 요구 배포 및 운영자 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.
[root@localhost]$ kubectl get deploy -n mysql-operator
NAME             READY   UP-TO-DATE   AVAILABLE   AGE
mysql-operator   1/1     1            1           2d5h

클러스터 mysql을 만들기

사용 지역 PV 영구 저장소는 Kubernetes 위해 MySQL은 3 노드, 마스터에 대한 노드, 슬레이브 두 위해 만든 이때 클러스터는 마스터 노드는 읽기 및 쓰기 수, 슬레이브 노드는 읽기 전용입니다.
첫째, 각 PV에 대한 노드를 생성, 지역 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
[root@localhost]$ 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을 생성하기위한 대응하는 RBAC 권한을 만들 수있는 공간 MySQL의에서 작성해야합니다.

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의 암호를 지정해야하는 경우, 당신은 비밀 암호가 필요합니다 base64로 암호화를 생성해야합니다. 다음 리눅스 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

운영자의 창조에서 우리는 배포 다음 CRD 타입은 MySQL 클러스터를 만드는 데 필요한 자원의 mysqlclusters 유형입니다 만들었습니다.

[root@localhost]$ 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

다음 연산자는 사용자 정의 자원 유형을 (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이 statefulset에 MySQL을 잡아 당겨 시작하고 헤드리스 서비스를 만들 것입니다 볼 수 있습니다.

[root@localhost]$ 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-유입을 통한 외부 접근

첫째, 단지 외부 액세스에 클러스터 DNS 서비스 액세스를 통해 헤드리스 서비스는, 당신은 또한 추가 서비스를 만들어야합니다. 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

다음으로, 우리는 입구 컨트롤러를 만드는 데 필요한 종이의 선택은 HAProxy-침투가 .
TCP 프로토콜 통신을 통해 MySQL의 서비스 때문에, 유입 기본 포트가 지원는 Kubernetes에만 HTTP 및 HTTPS, haproxy-유입은 TCP 서비스를 구성, ConfigMap 형을 이용하여 포트를 제공합니다, 당신은 듣고, HAProxy에 키를 ConfigMap 형을 만들 수있는 데이터를 configMap을 할 필요가 서비스에 대한 값은 서비스 및 포트를 전달합니다.

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

다음으로, 유입 컨트롤러를 만들

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

마지막으로, 진입 규칙을 만들 :

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: /

+ 이제 IP의 haproxy하여 MySQL 클러스터에 대한 포트 액세스를 매핑 할 수 있습니다.

액세서리

다음은 YAML 파일 위에 사용된다 :

추천

출처www.cnblogs.com/maoqide/p/11258515.html