Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Oracle MySQL Operator 検証してみた

cotoc
July 01, 2019

Oracle MySQL Operator 検証してみた

・恐るることなかれ! Cloud NativeリレーショナルDB特集!! - cndjp第12回
・MySQL & PostgreSQL Casual Talks in Fukuoka vol.1

上記Meetupの登壇資料です。
Oracle MySQL Operatorの解説と検証結果を共有します。

cotoc

July 01, 2019
Tweet

More Decks by cotoc

Other Decks in Technology

Transcript

  1. 自己紹介 2 • 茂 こと(しげる こと) • 日本オラクルのソリューションエンジニア – 入社当初はOracle

    DB、Exadataを担当 – 現在はCloud Nativeソリューションの色々を担当 • cndjp(Cloud Native Developers JP) OCHaCafe(Oracle Cloud Hangout Cafe)のスタッフ @cotoc88 撮影:JapanContainerDays実行委員会 https://speakerdeck.com/cotoc
  2. OCI Cloud Native Services Monitoring Notification Service Events Oracle Functions

    Streaming Container Pipelines Resource Manager OCI Registory Oracle Container Engine for Kubernetes (OKE) Observability & Aanalysis Application Definition & Development Provisoning Orchestration & Managment Oracle Cloud Native Framework 3 オラクルが提供するクラウドネイティブサービスのポートフォリオ CNCFに認証されたフルマネージド Kubernetesサービス オープンソース・テクノロジーに基づき、 オーケストレーション、スケジューリング、 管理、業務および分析の為の完全な 統合されたサービスのセットを提供 OCIリソース運用の自動化を可能に する、Terraformベースの Infrastructure as Code プラットフォーム フルマネージドで、高スケーラビリティ、 実行時のみ課金を行うサーバーレス 実行環境 Dockerコンテナを実行環境とするオ ープンソースのFn Projectをベースと している OCI上の様々なリソースのメトリクス を監視、ダッシュボードで閲覧、および 通知 Dockerコンテナイメージを格納できる 高可用性なプライベート・コンテナ・ レジストリのプラットフォーム 高可用性、高スケーラビリティな マルチテナント型 ストリーミング・プラットフォーム マイクロサービスおよびコンテナ・アーキ テクチャ用に設計されたCI/CD開発 自動化プラットフォーム pub/subモデルにて大量の宛先に通 知可能な、高スケーラビリティな メッセージ通知プラットフォーム OCI上のリソースの状態変化を捉え、 サーバーレス実行環境のOracle Functionsなど他のサービスに連携
  3. Oracle Cloud Hangout Café2 5 Season2 テーマ キーワード Done これからはじめる!Kubernetes基礎

    Kubernetes 9/19 一体何モノなの?GraalVM 入門 GraalVM 10/31 Serverless/Fnで始める快適Developer Life FaaS/Fn Project Nov Cloud Native × Streaming はじめの一歩 Spark/Streaming Dec Cloud Native時代のモダンJavaの世界 MicroProfile/Helidon Jan 変幻自在♪ 広がるKubernetesのエコシステム Kubernetese/Service Broker クラウドネイティブ時代の開発者へお届けする オープン・スタンダードなテクノロジーをテーマに取り上げ 短時間でガッツリ学んでお持ち帰りいただくテクニカルな勉強会シリーズ!! https://ochacafe.connpass.com/ #ochacafe
  4. 本日の内容 • Kubernetes Operatorとは • MySQL Operatorとは • MySQL InnoDB

    Cluster on Kubernetes • Pod障害復旧時の動作 • その他できること – Scale – Backup – Restore 6
  5. 本日の内容 • Kubernetes Operatorとは • MySQL Operatorとは • MySQL InnoDB

    Cluster on Kubernetes • Pod障害復旧時の動作 • その他できること – Scale – Backup – Restore 7
  6. Kubernetesとは • 大量のコンテナを管理・運用を自動化する コンテナ・オーケストレーター 8 複数コンテナを自動管理するプラットフォーム ✓ リソースの抽象化、自動分散配置 ✓ 手動/自動でスケーリング

    ✓ 複数コンテナをまとめて制御 ✓ 障害時のコンテナ再立ち上げ ✓ クラスタ内/外のネットワークアクセスの管理 https://kubernetes.io/docs/concepts/overview/what-is-kubernetes/ etc…
  7. • デプロイの管理 適切なコンテナの配置 アプリの切替・更新の自動化 (rolling, blue/green, canary, etc.) • 自動復旧

    自動起動/配置による障害 からの自動復旧 コンテナ障害時にコンテ ナの数を一定に保つ 9 • スケーリング コンテナの数を手動、また は自動で増やす・減らす リソースの消費に合わせた 自動スケール Kubernetesによるコンテナ自動制御の例 >_ >_ replicas: 3 Kubernetes Cluster Kubernetes Cluster Kubernetes Cluster
  8. manifestファイルの例 • yaml形式で記述するのが主流 • 右例では以下のような構成を 定義 – 3つのPodで冗長化 – コンテナイメージは、

    cotoc/sample:v1.0 – ポート8080を公開してアプリに 流す … apiVersion: apps/v1 kind: Deployment metadata: name: cowweb spec: replicas: 3 selector: matchLabels: app: cowweb strategy: type: Recreate template: metadata: labels: app: cowweb version: v1.0 spec: containers: - name: cowweb image: cotoc/sample:v1.0 ports: - name: api containerPort: 8080 ...(以下略)... 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
  9. Kubernetesの標準機能だけでは実現が難しい… • コンテナで動作するソフトウェアが状態やデータをもつような場合、 固有の運用タスクを行う必要がある – ミドルウェアのクラスタリングを構成 – バックアップ・リストア – 異なる設定をもつPod毎の障害復旧

    • 例:データベース – マスター・スレーブ構成のDBをスケールアウトするときには 読み取り専用に設定したスレーブを追加しないといけない – バックアップ・リストアにはデータベース固有の操作が必要 13
  10. Kubernetes Operatorどんどん増えています • Kubernetes OperatorはCoreOS社(現:IBM社/Red Hat社)によって 2016年に提唱された • KubeCon +

    CloudNativeCon North America 2018、Europe 2019 でキーノートに取り上げられるなど注目度があがっている 15 参考:https://operatorhub.io
  11. Kubernetes Operatorの仕組み • Operatorは以下のコンポーネントから成り立つ – Custom Resource • ユーザーが独自に定義したリソース •

    Custom Resource Definition(CRD) はKubernetes APIを拡張する (APIエンドポイントを作成し、 Custom Resourceを取り扱える状態にする) – Custom Controller • ユーザーが独自に作成するコントローラー • Custom Resourceの内容をKubernetesに作成する 16 独自に設定した定義とコントローラーから成り立つ https://speakerdeck.com/shmurata/how-we-accomplish-noops-by-kubernetes-operator 自作したい方のためにSDK (Operator Framework)も提供されています
  12. Kubernetesのコントローラーの仕組み 17 manifestファイルで宣言した状態を維持 Observe Analyze Act 現在の状態を確認する 現在の状態と 期待する状態を比較する 状態を一致させるために

    必要な処理を行う Customer Controllerがユーザー独自 の定義(Custom Resource)に対し Reconciliation loop (突き合わせルー プ)を行います
  13. 本日の内容 • Kubernetes Operatorとは • MySQL Operatorとは • MySQL InnoDB

    Cluster on Kubernetes • Pod障害復旧時の動作 • その他できること – Scale – Backup – Restore 18
  14. MySQL Operator • Kubernetes上にMySQL InnoDB Clusterの構築、管理を簡易化する – オラクルのオープンソースプロジェクト – 2018年前半にリリース

    Version 0.3.0 α版(2019/7 現在) • MySQL 5.7、8.0~ 対応 • コア機能 – 単一コマンドでKubernetes上にMySQL InnoDB Clusterの作成/削除が可能 – バックアップ(On-demand、Schedule)リカバリ 19 Kubernetes × MySQL InnoDB Clusterでスケール・可用性構成を実現 https://github.com/oracle/mysql-operator
  15. MySQL Operatorのデプロイ ・・ RESOURCES: ==> v1/Pod(related) NAME READY STATUS RESTARTS

    AGE mysql-operator-65475db5-8292w 0/1 ContainerCreating 0 1s ==> v1/ServiceAccount NAME SECRETS AGE mysql-agent 1 2s mysql-operator 1 2s ==> v1beta1/ClusterRole NAME AGE mysql-agent 2s mysql-operator 2s ==> v1beta1/ClusterRoleBinding NAME AGE mysql-agent 1s mysql-operator 1s ==> v1beta1/CustomResourceDefinition NAME AGE mysqlbackups.mysql.oracle.com 2s mysqlbackupschedules.mysql.oracle.com 2s mysqlclusters.mysql.oracle.com 2s mysqlrestores.mysql.oracle.com 2s ==> v1beta1/Deployment NAME READY UP-TO-DATE AVAILABLE AGE mysql-operator 1/1 1 0 1s 20 $ helm install --name mysql-operator mysql-operator HelmとはKubernetesのパッケージマネージャー Kubernetesアプリケーションのパッケージ化/インストール/管理 に使用されます https://github.com/kubernetes/helm
  16. 参考:作成されるCustomResourceDefinition • mysqlclusters.mysql.oracle.com – MySQLのクラスタをコントロール (kind: Cluster) • mysqlbackups.mysql.oracle.com –

    データのバックアップをコントロール (kind: Backup) • mysqlrestores.mysql.oracle.com – データのリストアをコントロール (kind: Restore) • mysqlbackupschedules.mysql.oracle.com – 定期実行のバックアップスケジュールをコントロール (kind: BackupSchedule) 21 Custom Resource Definition(CRD) は Kubernetes APIを拡張し (APIエンドポイントを作成し、 Custom Resourceを取り扱える状態にする)
  17. 本日の内容 • Kubernetes Operatorとは • MySQL Operatorとは • MySQL InnoDB

    Cluster on Kubernetes • Pod障害復旧時の動作 • その他できること – Scale – Backup – Restore 22
  18. MySQL InnoDB Clusterとは? • MySQLネイティブの高可用性構成を構築可能(クラスタリングソフト等は不要) • DBレイヤーのフェイルオーバーだけでなく、アプリ接続先まで 自動フェイルオーバー可能 • デフォルトはシングルプライマリーモード、マルチプライマリーモードでの

    動作も可能 – シングルプライマリーモード:1台のサーバーのみが更新処理可能、残り のサーバーは読み取り専用 • プライマリノードに障害発生時は、自動的に別のインスタンスが新プライマリに昇格 – マルチプライマリーモード:全台で更新処理可能 • MySQL側でのフェイルオーバー処理が不要になる 23 MySQLの高可用性フレームワーク 参考:https://dev.mysql.com/doc/refman/8.0/en/mysql-innodb-cluster-userguide.html
  19. MySQL InnoDB Clusterアーキテクチャー 24 MySQL標準の高可用性機能 自動フェールオーバー & リカバリ、矛盾検知 S M

    S MySQL Connector Application MySQL Router MySQL Connector Application MySQL Router MySQL Shell Group Replication アプリケーションは MySQL Routerに接続 Group Replicationによる高可用性グループと メタデータの管理 運用管理タスクのための クライアント
  20. MySQL OperatorによるMySQL InnoDB Clusterの管理 MySQL Operator Op Load Balancer etcd

    API Server CR Custom Resource Application MySQL Router Request MySQL >_ manifest 25 MySQL Agent MySQL Operatorによる監視対象 ※ストレージは省略しています
  21. それぞれなにかちょっと解説 • Application: – アプリケーションが動作するコンテナ • MySQL Router: – MySQL

    Routerが動作するコンテナ(サイドカー) • アプリケーションはMySQL Router経由でDBへアクセス • MySQL: – mysqldが動作するコンテナ • MySQL Agent: – MySQL InnoDB Clusterメンバーを制御する役割のコンテナ(サイドカー) • 内部的にMySQL ShellからAdminAPIを実行し、クラスターメンバーを制御 26
  22. 参考:Podのデザインパターン • サイドカー・パターン – 1つのPodの中に主となるメインコンテナと、補助するサイドカーコンテナを配置する • Pod内のコンテナは同一のIPアドレスを共有するため、ローカルホストでアクセス可能 • Podにボリュームをアタッチすることでコンテナ間のデータ共有も可能 –

    利用例:Webサーバーコンテナとログの転送用のコンテナ 27 Main Side Car Pod 127.0.0.1 Vol Write Read コンテナを分離するメリット ✓ 個々の処理に必要なリソースを柔軟に選択 ✓ 開発の分離 ✓ 組み合わせが柔軟 ✓ 再利用可能 ✓ 独立してUpgarade可能
  23. MySQL InnoDB Clusterの作成 28 $ kubectl apply -f multi-master-cluster.yaml cluster.mysql.oracle.com/mysql

    created $ kubectl get po,svc,sts NAME READY STATUS RESTARTS AGE mysql-0 2/2 Running 0 2m46s mysql-1 2/2 Running 0 2m5s mysql-2 2/2 Running 0 78s mysql-operator-65475db5-bvr8b 1/1 Running 0 4m35s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/mysql ClusterIP None <none> 3306/TCP 86s NAME DESIRED CURRENT AGE statefulset.apps/mysql 3 3 2m46s kind: Cluster metadata: name: mysql spec: multiMaster: true members: 3 Clusterリソースを作成すると下位リソースに StatefulSet、 Headless service が作成される 最もシンプルな例
  24. データの永続化 | StatefulSet • 決められた順番でのデプロイ/削除が担保される – 0からN-1までの定義された順番でPodがデプロイ/ 起 動 /

    停止 / 削除が行われる • Pod名が変わらない – Podが他のノードに再スケジューリングされた後でも Pod名が変わらない • PVCを介し固定の永続ストレージをマウント – Pod毎に決められた永続ストレージをマウントする – Podが再起動しても変わらない 29 ステートフルなサービスに対応するためのリソース : a b c 0 1 2 デプロイ 順番 守る!! 削除
  25. 外部ストレージを使う場合 30 apiVersion: mysql.oracle.com/v1alpha1 kind: Cluster metadata: name: mysql spec:

    members: 3 config: name: mycnf rootPasswordSecret: name: mysql-root-user-secret volumeClaimTemplate: metadata: name: data spec: storageClassName: oci accessModes: - ReadWriteOnce resources: requests: storage: 50Gi : volumeClaimTemplateを使用することで、 PersisitentVolumeClaim(PVC)が定義にした がって自動生成される ベンダーが提供するVolume Provisionerを使 用するとPersisitentVolume(PV)が自動で生 成され、PVCとPVが紐づけられる PVCの定義 参考:https://speakerdeck.com/hhiroshell/ kubernetesbiao-zhun-falsesutoreziji-neng-woosaraisiyou PV、PVCって…?
  26. 各種ファイルの保存先 • my.cnf(MySQL定義ファイル)の置き場所 – ConfigMapでmy.cnfの内容を記述しPodにマウントする • データファイルの置き場所 – 用途に応じ内部ストレージか外部ストレージを使用するか選択する –

    外部ストレージを使用する場合は、KubernetesがBlock Volumeを作成しPodにマウントする • (※) この例ではOCIのVolume Provisionerがパスを切り、OCIのBlock Volumeをマウント Volume Provisionerはベンダーごとに実装が異なる 31 コンテナから見たパス ホストから見たパス my.cnf (MySQLの設定ファイル) /etc/my.cnf /var/lib/kubelet/pods/<podname>/volumes/kubernetes.i o~configmap/mysql/my.cnf データファイル/ リカバリログ /var/lib/mysql/ /var/lib/kubelet/plugins/kubernetes.io/flexvolume/oracle/ oci/mounts/ocid1.volume.oc1.phx.xxx/mysql (※)
  27. my.cnfの設定 • KubernetesのConfingMapリソースを使用 – コンテナに設定情報を渡すために使うリソース – ConfingMapに記述した設定情報を、2通りの方法で渡すことができる • コンテナの環境変数として渡す •

    設定情報が記述されたファイルを コンテナにマウントさせたように 見せる(今回はこっち) 32 $ kubectl apply –f mycnf.yaml apiVersion: v1 kind: ConfigMap metadata: name: mycnf namespace: mysql-operator data: my.cnf: | [mysqld] log_error=/var/lib/mysql/error_test.log default_authentication_plugin=mysql_native_password [mysql] prompt="innodb> " YAMLに定義を書いて適用 $ kubectl create configmap mycnf --from-file=examples/my.cnf my.cnfファイルから作成
  28. MySQLのrootパスワードの管理 • KubernetesのSecretリソースを使用 – 機密度の高いデータを保持する際に使うリソース – ConfigMapと違い、コンテナでSecretのデータを読み取ると必ずメモリ内 のみに保持されて不要になったら削除される(tmpfsが使用されている) 33 $

    kubectl create secret generic mysql-root-user-secret --from-literal=password=xxxx kubectlから直接作成 $ kubectl apply –f secret.yaml apiVersion: v1 kind: Secret metadata: name: mysql-root-user-secret namespace: mysql-operator data: password: XXXXXXX YAMLに定義を書いて適用 ※ファイルから作成、envfileから作成も可能
  29. 参考: MySQL Operatorによって設定されるシステム変数 34 mysqld --server_id=1000 --datadir=/var/lib/mysql --user=mysql --gtid_mode=ON --log-bin

    --binlog_checksum=NONE --enforce_gtid_consistency=ON --log-slave-updates=ON --binlog-format=ROW --master-info-repository=TABLE --relay-log-info-repository=TABLE --transaction-write-set-extraction=XXHASH64 --relay-log=mysql-0-relay-bin --report-host=mysql-0.mysql --log-error-verbosity=3
  30. アプリからの接続 • 35 apiVersion: extensions/v1beta1 kind: Deployment --- 略 ---

    spec: containers: - name: mysqlrouter image: mysql/mysql-router:8.0.12 env: - name: MYSQL_PASSWORD valueFrom: secretKeyRef: name: wordpress-mysql-password key: password - name: MYSQL_USER value: root - name: MYSQL_PORT value: "3306" - name: MYSQL_HOST value: mysql-wordpress-0.mysql-wordpress - name: MYSQL_INNODB_NUM_MEMBERS value: "3" command: - "/bin/bash" - "-cx" - "exec /run.sh mysqlrouter" - name: wordpress image: wordpress:4.9-php7.2-apache env: - name: WORDPRESS_DB_HOST value: 127.0.0.1:6446 - name: WORDPRESS_DB_PASSWORD valueFrom: secretKeyRef: name: wordpress-mysql-password key: password ports: - containerPort: 80 MySQL Routerは例のように自分でYAMLを定義し デプロイする必要があります Operatorにより自動的に生成されるものではありません MySQL RouterとApplicationのYAML
  31. 再掲:MySQL InnoDB Cluster on k8s MySQL Operator Op Load Balancer

    etcd API Server CR Custom Resource Application MySQL Router Request MySQL >_ manifest 36 MySQL Agent MySQL Operatorによる監視対象 ※ストレージは省略しています
  32. 参考:オンプレミスでInnoDB Clusterを構築する手順 • 1.MySQLデータベースのインストール×3台 – 1-1.バイナリの展開 – 1-2.初期データベースの作成 • 2.MySQL

    Shellからコマンドを実行しグループ・レプリケーションを構築 – 2-1.1台目 • 2-1-1.グループ・レプリケーション用のパラメーターを設定 • 2-1-2.クラスタを作成 – 2-2.2台目 • 2-2-1.グループ・レプリケーション用のパラメーターを設定 – 2-3.3台目 • 2-3-1.グループ・レプリケーション用のパラメーターを設定 – 2-4.2台目、3代目をクラスタに参加 • 3.MySQL Routerの構成×必要台数 37
  33. 本日の内容 • Kubernetes Operatorとは • MySQL Operatorとは • MySQL InnoDB

    Cluster on Kubernetes • Pod障害復旧時の動作 • その他できること – Scale – Backup – Restore 38
  34. Pod障害復旧時の動作(Kubernetes側から見た動作) 0. mysql-0 に障害発生(kill -9 mysqldプロセス) 1. kubelet(ノードの常駐プロセス)がコンテナの障害を検知し Podを落とす(SIGTERM) 2.

    kubeletがPodのステータスを変更 3. Statefulset Controllerが新しいPodオブジェクトを作る 4. Schedulerがその新しいPodオブジェクトを見てスケジュール 5. kubeletがPodを再立ち上げ 39
  35. Pod障害復旧時の動作(MySQL側から見た動作) 0. マスターに障害発生(kill -9 mysqldプロセス) 1. グループから除外される 2. スタンバイがマスターに昇格する ---

    KubernetesによりPodを起動--- 3. スタンバイとして起動 4. クラッシュリカバリー 5. 障害発生中の更新処理内容の適用 6. グループに参加 40 Master Standby として復活! 障害発生 New Master New Master
  36. Pod障害復旧時の動作(アプリ側から見た動作) 0. マスターに障害発生(kill -9 mysqldプロセス) 1. マスターへのRead,Write処理失敗 スタンバイへのReadは影響は無し 2. スタンバイがマスターへ昇格後

    アプリから再接続してWrite処理可能 – 再接続すると処理を継続できる 41 MySQL Routerの設定振り分け R/W用のポート:6446 R/O用のポート:6447 Master New Master APP Router 6446 6447 6447 マスター変更後 6446でアクセス可能に ※アプリ側の実装により動作は異なります
  37. ノード障害時の動作(Kubernetes側から見た動作) • 0. ノード障害が発生 • 1. Kubernetesのマスターが障害を検知 ノードのステータスが NotReady •

    2. PodはステータスUnknownに変化 – StatefulSetの場合アクティブな別ノードへの再スケジューリング自動的に は行われないため、手動で操作が必要 42 ノード障害時StatefulSetの再スケジューリングが行われないのは kubeletの障害など、Podの状態を判別できない場合に重複したPodを 立ち上げ同一のボリュ ー ムに対し書き込みが発生することを防ぐため
  38. 本日の内容 • Kubernetes Operatorとは • MySQL Operatorとは • MySQL InnoDB

    Cluster on Kubernetes • Pod障害復旧時の動作 • その他できること – Scale – Backup – Restore 43
  39. Operatorによる“Scale” • Clusterリソースspec.members数を変更してYAMLを適用 • kubectl scaleには現状未対応 – 今後対応される可能性あり(issue: Implement scale

    subresource #165) • StatefulSetを直接変更はできない – Cluster(Custom Resource)にした定義が優先される 44 $ kubectl apply -f multi-master-cluster.yaml cluster.mysql.oracle.com/mysql created kind: Cluster metadata: name: mysql spec: multiMaster: true members: 5 $ kubectl scale mysqlclustes --replicas=5 Error from server (NotFound): the server could not find the requested resource…
  40. Operatorによる“Backup” 45 • Backupリソースを定義したYAMLを適用 – 現在はmysqldumpのみ対応 • Enterprise Backupも対応予定 –

    Backupの取得先 • AWS S3/OCI Object Storage/Google GCS • 接続にはS3互換APIを使用する必要がある – Scheduleを指定せずオンデマンド取得も可能 $ kubectl apply –f backup.yaml backup.mysql.oracle.com/mysql-backup created apiVersion: mysql.oracle.com/v1alpha1 kind: BackupSchedule metadata: name: mysql-backup-schedule spec: schedule: '30 * * * *' backupTemplate: executor: mysqldump: databases: - name: test storageProvider: s3: endpoint:xxxxxx region: ociregion bucket: mybucket credentialsSecret: name: s3-credentials cluster: name: mysql 30分ごとにmysqlクラスターのtestデータベース にバックアップを取得する例
  41. Operatorによる“Restore” 46 • Restoreリソースを定義したYAMLを適用 $ kubectl apply –f backup.yaml restore.mysql.oracle.com/example-restore

    created apiVersion: mysql.oracle.com/v1alpha1 kind: Restore metadata: name: example-restore spec: cluster: name: mysql backup: name: mysql-backup