Slide 1

Slide 1 text

Docker-composeで動いていたアプリ をKubernetesに移行してみた Kubernetes Meetup Osaka #1 0

Slide 2

Slide 2 text

自己紹介 1 名前 : 松尾 所属 : 株式会社オージス総研 仕事 : インフラエンジニア 趣味 : ラーメン作り = + (CKA勉強中)

Slide 3

Slide 3 text

2 • 今回お話する内容 • なぜKubernetesを選んだか • 移行するにあたり何を考慮したか • 本題(実際にやってみた流れとか、気づき) はじめに

Slide 4

Slide 4 text

今回お話する内容 3  前提 • 動かそうとしたアプリはWeb/AP/DB/KVSで構成 • コンテナ化され、Docker-composeで動作確認済み  お話する内容 • どのようにアプリを定義するか • どこで動かすか • 実際に動かす • DBをどのように選定するか  お話しない内容 • コンテナ化 • CI/CD • 監視 • ストレージ、KVSなど

Slide 5

Slide 5 text

なぜKubernetesを選んだか 4  課題があった • パフォーマンスや可用性の要件が厳しいアプ リがあり、Docker-composeで動かしていたが オーケストレーションに難があった  Kubernetesなら解決できる可能性 • 優れたコンテナオーケストレーションツール であり、スケーリング機能もある  Kubernetesに取り組んでおきたい • コンテナオーケストレーションツールのデフ ァクトスタンダードであるKubernetesの知見 もキャッチアップしておきたい

Slide 6

Slide 6 text

移行するにあたり何を考慮したか 5 Cloud Native Trail Map オープンソースのクラウドネイティブテク ノロジーを活用するための推奨プロセス どうやって進め れば良いか? 引用 https://github.com/cncf/trailmap

Slide 7

Slide 7 text

移行するにあたり何を考慮したか 6 Cloud Native Landscape • このランドスケープは、クラウドネイティブ テクノロジーのこれまでにない地形を通る地 図として意図されています • クラウドネイティブアプリケーションをデプ ロイするには多くのルートがあり、CNCFプ ロジェクトは特によく行き届いたパスを表し ます 何から構成要素を選べ ば良いか? 引用 https://landscape.cncf.io/

Slide 8

Slide 8 text

7 • どのようにアプリを定義するか • どこで動かすか • 実際に動かす • DBをどのように選定するか 本題

Slide 9

Slide 9 text

8 引用 https://github.com/cncf/trailmap • どのようにアプリを定義するか • どこで動かすか • 実際に動かす • DBをどのように選定するか • アプリ定義をする(Helm等) • どこで動かすか決める

Slide 10

Slide 10 text

アプリ定義 9 1. Docker-composeファイルから現状把握 2. 「1.」を元に、Kubernetes構成設定ファイル (Manifest)を新規作成する 3. 構成図を書く

Slide 11

Slide 11 text

アプリ定義 - Docker-composeとは 10 • 簡易的なDockerオーケストレーシ ョンツール • 出来ない • コンテナの水平方向のスケーリング • コンテナの死活監視、障害時の自動復 旧(コントローラ) ⇒アプリケーション担当で試作した Docker-composeファイルがあるの で、それらからKubernetes構成設定 (Manifest)を作っていく Docker-composeファイル version: '3' services: DB: image: sample-DB:1.0 environment: DB_USER: xxxx DB_PASS: xxxx KVS: image: sample-KVS:1.0 command: redis --xxxx container_name: KVS WEB: image: sample-WEB:1.0 depends_on: - DB ports: - "3000:3000" command: httpd -xxxx AP: image: sample-AP:1.0 depends_on: - DB links: - DB command: appd -xxxx ports: - "2000:2000"

Slide 12

Slide 12 text

11 アプリ定義 - Docker-composeから現状把握 AP DB KVS Web

Slide 13

Slide 13 text

アプリ定義 - Manifest作成 12 • しかし、Docker-composeを読み解いて一から Manifestファイルを起こすのは初心者には難し い(ましてやHelm Chartも難しい) • 簡単に出来るツールが無いか調べた • Docker-composeファイルからManifestファイ ルを変換できる、Kubernetes公式プロジェクト ツール(Kompose)を使用してみることに

Slide 14

Slide 14 text

アプリ定義 - Manifest作成 13 • Kompose結果  何が出来た?  Docker-composeに記載されているservices単位 で、ServiceやDeploymentの変換・作成が自動 で行われた。  Serviceに関連するLabels、Selectorなどの自動 生成。  何が出来なかった?  Docker-compose側にportsやlinksの記載がない 場合はServiceが作られない。  環境変数(environment)はそのままEnvへ(秘匿 情報は必要に応じてSecretにする) KD250-M06 KubernetesOverview P40→deployment P53→service

Slide 15

Slide 15 text

Namespace:default AP AP DESIRED:1 アプリ定義 - Komposeを元に起こした構成図 14 AP #1 KVS KVS DESIRED:1 KVS #1 DB DB DESIRED:1 DB #1 Web Web DESIRED:1 Web #1

Slide 16

Slide 16 text

15 引用 https://github.com/cncf/trailmap • どのようにアプリを定義するか • どこで動かすか • 実際に動かす • DBをどのように選定するか  アプリ定義をする • どこで動かすか決める

Slide 17

Slide 17 text

どこで動かすか - CNCF Landscape一覧 16 引用 https://landscape.cncf.io/

Slide 18

Slide 18 text

どこで動かすか - EKSとは 17  AWSのマネージドKubernetesサービス  コントロールプレーンの管理が不要  ワーカーノードをスケール可能 引用 https://eksworkshop.com/introduction/eks/eks_high_architecture/ KD250-M10-Kubernetes Architecture P5→Worker Nodes P6→Control Plane

Slide 19

Slide 19 text

どこで動かすか - EKSクラスタ作成 18 • eksctlを使用  eksctlのインストール  権限設定  eksctl create cluster ¥ --name test-cluster ¥ --version 1.12 ¥ --nodegroup-name test-workers ¥ --node-type t3.medium ¥ --nodes 3 ¥ --nodes-min 1 ¥ --nodes-max 4 ¥ --node-ami auto ※当時のEKS最新クラスタVerを使用

Slide 20

Slide 20 text

どこで動かすか - EKSクラスタ作成 19 • eksctlによって、コントロールプレーンとワーカ ーノード等が作成される 引用 https://eksworkshop.com/introduction/eks/eks_high_architecture/

Slide 21

Slide 21 text

20 • どのようにアプリを定義するか • どこで動かすか • 実際に動かす • DBをどのように選定するか 引用 https://github.com/cncf/trailmap  アプリ定義をする  どこで動かすか決める

Slide 22

Slide 22 text

実際に動かす 21 1. Manifestファイルからアプリ群を起動する 2. K8s上のステータスを確認する 3. アプリ動作確認する

Slide 23

Slide 23 text

実際に動かす - Manifestから起動 22 • Manifestファイルからアプリ群を起動する  kubectlのインストール  kubectl create –f マニフェストファイル

Slide 24

Slide 24 text

(参考)kubectlとは? 23 引用 https://blog.openshift.com/kubernetes-deep-dive-api-server-part-1/

Slide 25

Slide 25 text

実際に動かす - ステータスを確認する 24  kubectl get all NAME READY STATUS RESTARTS AGE pod/Web 1/1 Running 0 20h pod/AP 1/1 Running 0 20h pod/KVS 1/1 Running 0 20h pod/DB 1/1 Running 0 20h NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/Web ClusterIP 10.100.3.5 80/TCP 3d service/AP ClusterIP 10.100.149.242 1883:31721/TCP 45d service/kubernetes ClusterIP 10.100.0.1 443/TCP 45d NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/Web 1/1 1 1 17d deployment.apps/AP 1/1 1 1 17d deployment.apps/KVS 1/1 1 1 17d deployment.apps/DB 1/1 1 1 17d NAME DESIRED CURRENT READY AGE replicaset.apps/Web 1/1 1 1 17d replicaset.apps/AP 1/1 1 1 17d replicaset.apps/KVS 1/1 1 1 17d replicaset.apps/DB 1/1 1 1 17d KD250-M06 Kubernetes Overview P34→ReplicaSet

Slide 26

Slide 26 text

実際に動かす - アプリケーション動作確認 25 • アプリケーションの動作確認を行う • 事前にAPにログインし、AP上からテスト用の設 定をDBに登録する  Kubectl exec –it -- bash AP  ./add-command -D DB 2019-07-16T10:34:04.412456+0000 [fatal][AP]():caught exception: Unknown MySQL server host 'DB' (0) ⇒ DBに接続できない(調査するとKVSも同様)

Slide 27

Slide 27 text

Namespace:default AP AP DESIRED:1 実際に動かす - アプリケーション動作確認 26 AP #1 KVS KVS DESIRED:1 KVS #1 DB DB DESIRED:1 DB #1 Web Web DESIRED:1 Web #1 正常起動 正常起動 正常起動 正常起動 原因は? 接続不可 接続不可

Slide 28

Slide 28 text

Namespace:default AP AP DESIRED:1 実際に動かす - アプリケーション動作確認 27 AP #1 KVS KVS DESIRED:1 KVS #1 DB DB DESIRED:1 DB #1 Web Web DESIRED:1 Web #1 Pod間のホスト名での通信には、Serviceが必要 ※IP直指定でも通信は可能

Slide 29

Slide 29 text

(参考)Serviceとは 28  一連のPod 上で実行されているアプリケーションをネットワークサービスと して公開するための抽象的な方法。  なじみのないサービス検出メカニズムを使用するようにアプリケーションを 変更する必要はありません。Kubernetesは、ポッドに独自のIPアドレスと ポッドのセットに対する単一のDNS名を付与し、それらの間でロードバラン スをとることができます。 • An abstract way to expose an application running on a set of Pods as a network service. • No need to modify your application to use an unfamiliar service discovery mechanism. Kubernetes gives pods their own IP addresses and a single DNS name for a set of pods, and can load-balance across them. 引用 https://v1-14.docs.kubernetes.io/docs/concepts/services-networking/service/

Slide 30

Slide 30 text

(参考)Serviceの種類 29  ClusterIP • デフォルトで作成されるサービス • Pod同士からアクセス出来る • クラスタ外部からのアクセスは出来ない  Nodeport • クラスタ外からアクセス出来る • ClusterIPの機能を包含  LoadBalancer • クラウドプロバイダ側提供のLBと連携するためのもの • NodePortの機能を包含  ExternalName • クラスタ内から外部ホストを解決するためのエイリアスを提供 • RDS等と連携する時に必要 今回はClusterIP を作成 KD250-M06 Kubernetes Overview P53→Service

Slide 31

Slide 31 text

Namespace:default AP AP DESIRED:1 実際に動かす - アプリケーション動作確認 30 AP #1 KVS KVS DESIRED:1 KVS #1 DB DB DESIRED:1 DB #1 Web Web DESIRED:1 Web #1 • 動作確認する Request OK

Slide 32

Slide 32 text

まとめ – アプリ定義から実際に動かすところまで 31  Docker-composeからの移行の 場合は、Komposeを適宜使い移 行を楽にする。  作られたmanifestは要確認 (service大事)。  PodのstatusがRUNNINGとなっ ている事だけでなくアプリケー ションの動作確認まで行う。(※ )  この状態だとDBやKVSがシング ル構成なので、クラスタ構成を 組んでおきたい  (EKSの場合は)eksctlとkubectl などのCLIツールを適宜使う。 引用 https://github.com/cncf/trailmap • アプリ定義をする • どこで動かすか決める ※ KD250-M09-Kubernetes Best Practices P39→ReadinessProbe/LivenessProbe https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#define-a-tcp-liveness-probe https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#define-readiness-probes

Slide 33

Slide 33 text

32 • どのようにアプリを定義するか • どこで動かすか • 実際に動かす • DBをどのように選定するか 引用 https://github.com/cncf/trailmap  MySQL DBの信頼性やスケーラビリティをより 求めるならVitessがお勧め

Slide 34

Slide 34 text

DB選定 – 前提条件  AWSのEKS上で、今回のサンプルアプリを動作させるにあたり、DB の製品や構成を検討する。  サンプルアプリの開発条件等は下記。 • サンプルアプリの開発言語 • C++ • DB • MySQLエンジン • リクエストするための権限情報を保持 33

Slide 35

Slide 35 text

DB選定 - CNCF Landscape一覧 RDS 引用 https://landscape.cncf.io/ ※AWSのマネージドサー ビスも候補とする 34

Slide 36

Slide 36 text

DB選定 – 候補について  MySQL • 純粋なMySQLエンジンを使用 • 今回はOperatorでのクラスタ構築運用を検討  MariaDB • MySQL完全互換ではないが、サンプルアプリがMariaDBで開発さ れているため選択肢になる • GaleraClusterを用いたマルチマスタのクラスタ構成がある  Vitess • クラウドネイティブなOSS • Youtube用に開発され、スケーリングやパフォーマンスに優れて いる • MySQLに一部互換性がある  RDS • AWSのマネージドRDBサービス • MySQLエンジンのインスタンス提供有り 35

Slide 37

Slide 37 text

(参考) Operatorとは? 引用 https://coreos.com/blog/introducing-operators.html  Kubernetesは自動化のために設計されています。すぐに使用できるよう にKubernetesのコアから多くの組み込みの自動化機能を利用できます。 あなたはワークロードを展開し実行を自動化するためにKubernetesを使 用することができ、そしてKubernetesはそれを自動化することができま す。  Kubernetesのコントローラーコンセプトにより、Kubernetes自体のコー ドを変更せずにクラスターの動作を拡張できます。オペレーターは、カス タムリソースのコントローラーとして機能するKubernetes APIのクライ アントです。 36 引用 https://kubernetes.io/docs/concepts/extend-kubernetes/operator/

Slide 38

Slide 38 text

(参考) Operatorはどのように動作する? • いわゆるDBAの代わりとして宣言(manifest)された状態かどう かを監視、対応する • Go言語で開発 • バージョンαが多い印象(私見) 引用 https://blogs.oracle.com/developers/introducing-the-oracle-mysql-operator-for-kubernetes 37

Slide 39

Slide 39 text

(参考) Operatorがなぜ必要なのか? 例: MySQLのMaster-Slave構成をmanifestで組む • MySQLを定義 • ConfigMap • Secret • Statefulset • Service • データ格納用に内部ストレージ割当 • PersistentVolume • 各種設定 • ConfigMap • データ同期設定 • Pod再作成時の復帰処理を作りこみ • バックアップスケジュール Manifest 数百行 例: Master-Slave構成をOperatorで組む • MysqlClusterを定義 Manifest 数行 38

Slide 40

Slide 40 text

(参考) Operatorは、Helmとどう違う? • Helm • Manifestの塊をパッケー ジ(chart)化してインスト ール、削除などできるも の • オブジェクトを監視、管 理する機能は無い • Operator • カスタムリソースの manifestに沿ってK8sの APIにアクセスしてオブ ジェクトの状態を監視、 管理する 引用 https://helm.sh/ 引用 https://blogs.oracle.com/developers/introducing-the-oracle-mysql-operator-for-kubernetes 39

Slide 41

Slide 41 text

DB選定 – 机上比較 候補 \ 比較項目 Mysql シングル 構成 Mysql- Operator MariaDB Galera Cluster Vitess RDS (MySQL) MySQL 互換性 ◎ 同等 ◎ 同等 ○ 完全互換ではない がアプリ開発は MariaDBなので 問題なし △ 一部SQL未サポート ◎ 同等 対応言語 ○ 多数 (C++有り) ○ 多数 (C++有り) ○ 多数 (C++有り) ○ 多数 (C++有り) ○ 多数 (C++有り) サポート △ OSS △ OSS △ OSS △ OSS ○ マネージド リソース 拡張性 △ 手動で スケーリング △ 手動で スケーリング △ 手動で スケーリング ◎ LiveReSharding ○ リードレプリカ可 スケールアップ可 耐障害性 △ Podオート ヒーリングのみ ○ Failover可 ○ Failover可 ○ Failover可 ○ Failover可 ※これは製品や構成の優劣比較を行ったものではなく、あく までサンプルアプリを動かすために、どのような構成が取れ 得るか判断するために、独自に整理したもの 40

Slide 42

Slide 42 text

DB選定 – 検証方針 41  まず下記の簡易的な検証を行い比較を行った  ManifestやOperator等で問題なく構築できるか  DB初期化用のSQLが発行できるか  アプリの動作確認は問題ないか  Podを無作為に削除  自動復旧するか  データは欠損していないか  ダウンタイムはどの程度か

Slide 43

Slide 43 text

DB選定 – MySQLシングル構成検証内容 42 ns:MySQL Kubernetesクラスタ Service ns:AP AP DBアクセス MySQL  ManifestやOperator等で問題なく構築で きるか(OK)  DB初期化用のSQLが発行できるか(OK)  アプリの動作確認は問題ないか(OK)  MySQLのPodを無作為に削除(NG)  ダウンタイムが発生

Slide 44

Slide 44 text

DB選定 – MySQL Operator検証内容 43 ns:MySQL Kubernetesクラスタ Master Service MySQLクラスタ 状態監視・管理 ns:AP AP DBアクセス MySQLクラスタ Master Slave Slave Operator、 Orchestrator  ManifestやOperator等で問題なく構築で きるか(OK)  DB初期化用のSQLが発行できるか(OK)  アプリの動作確認は問題ないか(OK)  MySQLのPodを無作為に削除(NG)  Masterのpodを削除したところ7 秒程度でFailOver完了。  新PodのステータスはRunningと なっているがMasterServiceにリ クエストするとDBに繋がらず。  Orchestratorのログを見ると、 sys_operator.heartbeatテーブ ルが無いとのエラー有り。初期処理 に問題がある可能性有り。  その他の問題  環境をクリアにするため、helm delete –purge、およびEBS削除 を行った後に再度helm installし ようとしたところ、削除済みのEBS を見に行ってしまいinstallが失敗 する。削除も新規作成も出来ない状 態。  helm init等行っても同様。  pvcを作り直して解決。

Slide 45

Slide 45 text

DB選定 - MariaDB Galera Cluster検証内容 44 ns:MySQL Kubernetesクラスタ Service ns:AP AP DBアクセス MySQLマルチマスタ Master1 Master2 Master3  ManifestやOperator等で問題 なく構築できるか(OK)  DB初期化用のSQLが発行でき るか(OK)  アプリの動作確認は問題ないか (OK)  Podを無作為に削除(OK)  自動復旧するか(OK)  データは欠損していないか (OK)  ダウンタイムはどの程度か (podは10秒程度で再作成 されるがデータ同期が完了 するまではクラスタに参加 しない)  データが永続化されていないの で定期バックアップ取得等の対 策が必要。 負荷分散 • PVは無し • 障害時は他podから 全データをコピー

Slide 46

Slide 46 text

DB選定 - Vitess検証内容 45 Kubernetesクラスタ MySQLクラスタ 状態監視・管理 ns:AP AP DBアクセス MySQLクラスタ Master Slave Slave Operator、 Orchestrator  ManifestやOperator等で問題 なく構築できるか(OK)  DB初期化用のSQLが発行でき るか(NG)  初期化用のSQLの半分が実 行エラー。  アプリの動作確認は問題ないか (NG)  アプリ起動せず  rpc error: code = FailedPrecondition desc = SELECT_LOCK disallowed outside transaction (CallerID: xxxx) while executing "select xxxx from yyyy lock in share mode” ns:Vitess ns:Vitess

Slide 47

Slide 47 text

DB選定 – RDS検証内容 46 ns:MySQL Kubernetesクラスタ ns:AP AP DBアクセス  問題なく構築できるか(OK)  DB初期化用のSQLが発行でき るか(OK)  アプリの動作確認は問題ないか (OK)  RDSのMasterNode再起動(OK)  自動復旧するか(OK)  データは欠損していないか (OK)  ダウンタイムはどの程度か (30秒程度) RDS ExternalName Service AWS Cloud

Slide 48

Slide 48 text

DB選定 – 比較結果 候補 \ 比較項目 Mysql シングル 構成 Mysql- Operator MariaDB Galera Cluster Vitess RDS (MySQL) MySQL 互換性 ◎ 同等 ◎ 同等 ○ 完全互換ではないが アプリ開発は MariaDBなので問題 なし △ 一部SQL未サポート ◎ 同等 対応言語 ○ 多数 (C++有り) ○ 多数 (C++有り) ○ 多数 (C++有り) ○ 多数 (C++有り) ○ 多数 (C++有り) サポート △ OSS △ OSS △ OSS △ OSS ○ マネージド リソース 拡張性 △ 手動で スケーリング △ 手動で スケーリング △ 手動で スケーリング ◎ LiveReSharding ○ リードレプリカ可 スケールアップ可 耐障害性 △ Podオート ヒーリングのみ ○ Failover可 ○ Failover可 ○ Failover可 ○ Failover可 サンプル アプリ 検証状況 ○ • 動作確認OK • ダウンタイム約 10秒発生 × • 動作確認OK • Failover後のpod に欠損テーブル 有り ○ • 動作確認OK • Failover約10秒 • データ未永続化 × • AP起動せず • DB初期化用SQLスク リプトも一部しか実 行できず ○ • 動作確認OK • Failover約30秒 ※これは製品や構成の優劣比較を行ったものではなく、 あくまでサンプルアプリを動かすために、どのような構 成が取れ得るか判断するために、独自に整理したもの 47

Slide 49

Slide 49 text

まとめ – DBをどのように選定するか 48 • 今回のサンプルアプリで言えば、 現状はMySQLのシングル構成か 、MariaDB Galera Cluster、 RDSのいずれかが選択肢となる。 • MariaDB Galera Cluster構成 は、現状データを永続化でき ていない(課題) • 永続化もしくは定期バックア ップ取得などの対策が必要 • 今後はVitessを試行することも検 討していきたい。 • K8s上できちんとMySQLのクラス タ構成を組める選択肢は、今後も 情報収集していきたい。 引用 https://github.com/cncf/trailmap

Slide 50

Slide 50 text

ご静聴ありがとうございました 49