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

「Kubernetes による Cloud Native な開発」と「VM 時代の開発」Jul...

「Kubernetes による Cloud Native な開発」と「VM 時代の開発」July Tech Festa 2019 / jtf2019-k8s-amsy810

「Kubernetes による Cloud Native な開発」と「VM 時代の開発」July Tech Festa 2019
Masaya Aoyama(青山 真也)
Twitter: @amsy810
CyberAgent

Masaya Aoyama (@amsy810)

December 08, 2019
Tweet

More Decks by Masaya Aoyama (@amsy810)

Other Decks in Technology

Transcript

  1. Publicity (一部抜粋)   書籍 『Kubernetes 完全ガイド』 『みんなの Docker/K8s』  基調講演 『Japan

    Container Days v18.04』 『Google Cloud K8s Day』   招待講演 『情報処理学会 コンピュータシステムシンポジウム』         『AWS Dev Day Tokyo』 『IBM Think Japan』 『JEITA 委員会』   登壇 『KubeCon + CNCon China 2019』 『Open Source Summit 2019』 等  資格 『CKAD #2』 『CKA #138』 Masaya Aoyama (@amsy810) Infrastructure Engineer Community   Co-chair 『Cloud Native Days Tokyo (旧 Japan Container Days)』  Organizer 『Cloud Native Meetup Tokyo』   『Kubernetes Meetup Tokyo』   『KubeCon Japanese exchange meeting』   Contribute to OpenStack and Kubernetes 主業務: K8s as a Service の実装 K8s / CloudNative 関連のアーキテクト + CREATIONLINE / DENSO - 技術アドバイザ + SAKURA Internet Research Center – 客員研究員
  2. ຊ೔͸ Kubernetes ʹ͢ΔͱҰੲલͷ VM Ͱͷ։ൃͱൺ΂ͯ ͲͷลΓ͕ҟͳΔͷ͔ͱ͍͏࣠Ͱೖ໳ηογϣϯΛ͠·͢ ʢ͍͍࿩͕ϝΠϯʣ ͳ͓ɺຊ೔঺հ͢Δ࿩ͷରൺ͸ҰྫͰ͢ ɹ* VM

    Ͱ΋͜͏͢Ε͹Ͱ͖Δ… ɹ* VM Ͱ΋·ͩ͜͏ͳ͍ͬͯͳ͍… ͸͋Δͱࢥ͍·͢ɻ Πϝʔδͱͯ͠͸ɺԼهͷରൺͰ঺հ͠·͢ ɹ* Ұੲલͷ VM ࣌୅ͷ։ൃ ɹ* ݱࡏͷ։ൃ
  3. Cloud Nativeͱ͸ʁ Cloud native technologies empower organizations to build and

    run scalable applications in modern, dynamic environments such as public, private, and hybrid clouds. Containers, service meshes, microservices, immutable infrastructure, and declarative APIs exemplify this approach. These techniques enable loosely coupled systems that are resilient, manageable, and observable. Combined with robust automation, they allow engineers to make high-impact changes frequently and predictably with minimal toil. The Cloud Native Computing Foundation seeks to drive adoption of this paradigm by fostering and sustaining an ecosystem of open source, vendor-neutral projects. We democratize state-of-the-art patterns to make these innovations accessible for everyone. CNCF Cloud Native Defenition v1.0, CNCF, 2018-11-28 (https://github.com/cncf/toc/blob/master/DEFINITION.md)
  4. Cloud Nativeͱ͸ʁ Cloud native technologies empower organizations to build and

    run scalable applications in modern, dynamic environments such as public, private, and hybrid clouds. Containers, service meshes, microservices, immutable infrastructure, and declarative APIs exemplify this approach. These techniques enable loosely coupled systems that are resilient, manageable, and observable. Combined with robust automation, they allow engineers to make high-impact changes frequently and predictably with minimal toil. The Cloud Native Computing Foundation seeks to drive adoption of this paradigm by fostering and sustaining an ecosystem of open source, vendor-neutral projects. We democratize state-of-the-art patterns to make these innovations accessible for everyone. CNCF Cloud Native Defenition v1.0, CNCF, 2018-11-28 (https://github.com/cncf/toc/blob/master/DEFINITION.md) •  疎結合なシステム •  復元力がある •  管理しやすい •  可観測である •  堅牢な自動化により、頻繁かつ期待通りに最 小限の労力で大きな変更が可能 OpenかつScalableなシステムを実現
  5. Cloud Native ͸ Kubernetesʁ 誤解されることがあるので改めて伝えますが、「違います」 Kubernetes != Cloud Native • 

    Kubernetes を使うだけで Cloud Native になるわけではない •  もちろんレール(お作法)に乗ることで近づきはします •  VM でも Cloud Native な開発をすることも可能です •  その他のマネージド・サービスを利用して Cloud Native な開発にすることも可能です •  CloudRun、Cloud Functions •  ECS、Fargate、Lambda
  6. [VM] 仮想化レベルの違いと隔離性 VM 毎に Kernel が⽤意されて実⾏されるため 隔離性が⾼い  完全仮想化 / 準仮想化

    によって厳密な隔離性は異なる VM VM VM Hypervisor appA appB appB appC appA Kernel Kernel Kernel Baremetal
  7. [CloudNative] 仮想化レベルの違いと隔離性 Docker (runC) Kernel appA appB appC Container Container

    Container Baremetal ⼀般的なコンテナランタイムの runC(プロセス型)の場合、 Kernel を共有しているため 隔離性が低い(ただし ⾼速な起動・低オーバーヘッド) cgroups:リソース使⽤量の制御 linux namespace:リソースの分離 隔離性の⾼いコンテナランタイムは存在 •  gVisor(サンドボックス型) •  nabla-containers(ユニカーネル型) •  Firecracker(microVM 型) •  kata-containers(VM 型) おすすめ「ユビキタスデータセンターOSの⽂脈におけるコンテナ実⾏環境の分類」 https://hb.matsumoto-r.jp/entry/2019/02/08/135354
  8. [CloudNative] ライフサイクル VM を「停⽌しないでください」 は実際ある コンテナの場合は「停⽌しないでください」は極⼒極⼒ NG Kubernetes や Docker の場合、

    コンテナは様々なタイミングで気軽に停⽌される 終了時には SIGTERM が通知されるため、 アプリケーションがハンドリングできるように開発する
  9. [VM] インフラ構成のコード化 Bootstrap & Orchestrate  Terraform  CloudFormation / Heat Configuration

     Chef / Ansible / Puppet / Salt  Packer Deploy  Jenkins / Capistrano パターン 1 •  Terraform で VM を起動 •  CAPS でセットアップ •  Jenkins でアプリのデプロイ ・イメージビルド時間:0 min ・デプロイ時間:10 min〜60 min ・同⼀環境になることが保証されない ・複数のツールの習得が必要
  10. [VM] インフラ構成のコード化 Bootstrap & Orchestrate  Terraform  CloudFormation / Heat Configuration

     Chef / Ansible / Puppet / Salt  Packer Deploy  Jenkins / Capistrano パターン 2 •  Packer で VM イメージのビルド •  Terraform で VM を起動 •  Jenkins でアプリのデプロイ ・イメージビルド時間:10 min - 30 min ・デプロイ時間:5 min ・同⼀環境になることが保証される ・複数のツールの習得が必要
  11. [CloudNative] インフラ構成のコード化 Bootstrap & Orchestrate  Kubernetes Manifests Configuration  Dockerfile  Kubernetes

    Manifests Deploy  Kubernetes Manifests パターン 1 •  Dockerfile でイメージのビルド •  K8s Manifest でコンテナを起動 •  ミドルウェア •  アプリケーション •  サービス間の接続性も管理 ・イメージビルド時間:1 min - 10 min ・デプロイ時間:5 sec – 1 min ・同⼀環境になることが保証される ・少ない数のツールの習得で⼗分   イメージ化がとても容易
  12. [CloudNative] インフラ構成のコード化 FROM centos:7 RUN yum -y install epel-release RUN

    yum -y install nginx COPY nginx.conf /etc/nginx/ ENTRYPOINT ["nginx", "-g", "daemon off;"] Build Once, Run Anywhere ΠϝʔδͷϏϧυ Docker Image Dockerfile
  13. [CloudNative] インフラ構成のコード化 Kubernetes apiVersion: apps/v1 kind: Deployment metadata: name: sample-deployment

    spec: replicas: 3 template: spec: containers: - name: app-container image: nginx:1.16
  14. [VM] 起動時間とスケーラビリティ VM の場合、起動時間は 1 分 〜 3 分程度 モノリシックなアプリケーション構成の場合には、

    特定の機能だけスケールアウトが必要な状態でも 全体をスケールさせる必要がある
  15. [CloudNative] 起動時間とスケーラビリティ コンテナの場合、起動時間は 1 sec 〜 5 sec 程度  ≒

    プロセスを⽴ち上げるのに近しい 合わせてマイクロサービス化を⾏っている場合、 特定の機能だけをスケーリングするため ・より早い⽴ち上がりが可能 ・集約率が向上するケースも
  16. [CloudNative] アプリのビルドとバージョン管理 Code Repository Docker Registry CI - test, build

    Kubernetes CI - update manifests Manifest Repository CD - depoy v1 v2 v3 v1 v2 v3 GItOps の場合:
  17. [VM] ローリングアップデート VM VM VM LB •  ロードバランサのメンバーから対象 VM を外す

    •  アプリケーションを停⽌ •  VM 上にアプリケーションをデプロイ •  アプリケーションを起動 •  ロードバランサのメンバーから対象 VM を追加 appA1 appA1 appA1
  18. [VM] ローリングアップデート VM VM VM LB appA2 appA1 appA1 • 

    ロードバランサのメンバーから対象 VM を外す •  アプリケーションを停⽌ •  VM 上にアプリケーションをデプロイ •  アプリケーションを起動 •  ロードバランサのメンバーから対象 VM を追加
  19. [VM] ローリングアップデート VM VM VM LB •  ロードバランサのメンバーから対象 VM を外す

    •  アプリケーションを停⽌ •  VM 上にアプリケーションをデプロイ •  アプリケーションを起動 •  ロードバランサのメンバーから対象 VM を追加 appA2 appA1 appA1
  20. [VM] ローリングアップデート VM VM VM LB •  ロードバランサのメンバーから対象 VM を外す

    •  アプリケーションを停⽌ •  VM 上にアプリケーションをデプロイ •  アプリケーションを起動 •  ロードバランサのメンバーから対象 VM を追加 ・闇の独⾃スクリプトを利⽤しがち ・アップデートの細かい制御が困難   ・更新間隔   ・タイムアウト   ・失敗時のロールバック appA2 appA1 appA1
  21. [CloudNative] ローリングアップデート Kubernetes の場合にはマニフェストを書き換えて 「kubectl apply」コマンドで再適⽤するだけ あとは Kubernetes が⾃動的にアップデート処理を⾏う Kubernetes

    appA:1 appA:1 LB appA:1 apiVersion: apps/v1 kind: Deployment metadata: name: sample-deployment spec: replicas: 3 strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 0 maxSurge: 1 template: spec: containers: - name: app-container image: app:A1
  22. [CloudNative] ローリングアップデート Kubernetes appA:1 appA:1 apiVersion: apps/v1 kind: Deployment metadata:

    name: sample-deployment spec: replicas: 3 strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 0 maxSurge: 1 template: spec: containers: - name: app-container image: appA:2 LB appA:2 Kubernetes の場合にはマニフェストを書き換えて 「kubectl apply」コマンドで再適⽤するだけ あとは Kubernetes が⾃動的にアップデート処理を⾏う
  23. [CloudNative] LoadBalancer との連携 起動したコンテナには ラベル が付与されている Kubernetes や周辺エコシステムでは ラベルを元に様々な処理を⾏う apiVersion:

    apps/v1 kind: Deployment metadata: name: sample-deployment spec: replicas: 3 template: metadata: labels: {app: a} spec: containers: - name: app-container image: app:A
  24. [CloudNative] LoadBalancer との連携 ⾃動的に LoadBalancer を作成し、⾃動的に連携を⾏う •  コンテナやノードの追加時にも⾃動的にメンバ更新 •  ローリングアップデート時のメンバ管理

    開発者も管理が可能 apiVersion: v1 kind: Service metadata: name: sample-svc spec: type: LoadBalancer ports: - name: "http-port" protocol: "TCP" port: 8080 targetPort: 80 selector: app: a LB app: a
  25. [VM] IP Address の管理 VM ごとに IP アドレスを把握・管理し、Ansible / Chef

    などで構成管理を実⾏ 基本的には IP Address の管理からは逃れづらい  IP Address 管理のスプレッドシートから脱却したい
  26. [CloudNative] IP Address の管理 Kubernetes では IP Address を⼀切管理しない Kubernetes

    内部の通信は サービスディスカバリによって成⽴ apiVersion: v1 kind: Service metadata: name: sample-svc spec: type: LoadBalancer ports: - name: "http-port" protocol: "TCP" port: 8080 targetPort: 80 selector: app: a LB (name: sample-svc) http://sample-svc.default.svc.cluster.local
  27. [CloudNative] IP Address の管理 Kubernetes 外部の通信も external-dns を利⽤して グローバル IP

    と外部 DNS に⾃動登録させることが可能 1.  ロードバランサにグローバル IP が⾃動的に払い出される 2.  外部の DNS に⾃動的にグローバル IP と登録 LB xxx.xxx.xxx.xxx 外部 DNS
  28. [CloudNative] IP Address の管理 Kubernetes 外部の通信も external-dns を利⽤して グローバル IP

    と外部 DNS に⾃動登録させることが可能 1.  ロードバランサにグローバル IP が⾃動的に払い出される 2.  外部の DNS に⾃動的にグローバル IP と登録 LB xxx.xxx.xxx.xxx 外部 DNS amsy.dev => xxx.xxx.xxx.xxx
  29. [CloudNative] IP Address の管理 Kubernetes 外部の通信も external-dns を利⽤して グローバル IP

    と外部 DNS に⾃動登録させることが可能 1.  ロードバランサにグローバル IP が⾃動的に払い出される 2.  外部の DNS に⾃動的にグローバル IP と登録 さらに cert-manager を利⽤することで ACME を利⽤して証明書の⾃動発⾏/更新も可能 LB xxx.xxx.xxx.xxx 外部 DNS amsy.dev => xxx.xxx.xxx.xxx
  30. [VM] 証明書の管理 SSL 終端やパスベースの振り分けはリバースプロキシの Nginx を⽴てて運⽤  (クラウド環境の場合は L7 LB を利⽤することも)

    VM の証明書管理は Chef / Ansible などで更新処理 Nginx Nginx Nginx LB VM VM VM appA 証明書の設定 パスベースのルーティング スケーリングの管理 appB appC
  31. [CloudNative] 証明書 L7 LoadBalancer も Manifest で管理  Nginx と⾃動連携するものもある apiVersion:

    networking.k8s.io/v1beta1 kind: Ingress metadata: name: sample-ingress spec: rules: - host: sample.example.com http: paths: - path: /path1/* backend: serviceName: sample-ingress-svc-1 servicePort: 8888 - path: /path2/* backend: serviceName: sample-ingress-svc-2 servicePort: 8888 tls: - hosts: - sample.example.com secretName: tls-sample Kubernetes L7 LB appA appB appC appA appA appC appB appC appC Nginx Nginx Nginx L4 LB
  32. [CloudNative] 証明書 証明書はすべて Secret リソースで管理 更新はファイルを変更して 「kubectl apply」で登録するだけ apiVersion: v1

    kind: Secret metadata: name: tls-sample type: kubernetes.io/tls data: tls.crt: LS0tLS1CRUd...= tls.key: LS0tLS1CRUd...= apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: sample-ingress spec: rules: - host: sample.example.com http: paths: - path: /path1 backend: serviceName: sample-ingress-svc-1 servicePort: 8888 - path: /path2/* backend: serviceName: sample-ingress-svc-2 servicePort: 8888 tls: - hosts: - sample.example.com secretName: tls-sample
  33. [CloudNative] ⾃動回復・セルフヒーリング Kubernetes では あるべき理想の状態(Desired State)へと収束させる 何か問題が発⽣した場合でも、Reconcile loop により セルフヒーリングされる

    ※ 厳密には Controller も API を⽤いて変更します。 reconcile() { … } 登録 (via API Request) Watch クラスタの状態 コンテナの作成・削除 Controller 登録された時に、ただ起動させるだけではない
  34. [CloudNative] ⾃動回復・セルフヒーリング 例えば、コンテナ(Pod)を 3 つ起動させる ReplicaSet リソースの場合 Observe Diff Act

    Observe: 現状を確認 Diff: 理想と現実の差分を計算 Act: 差分に対する処理を実施 クラスタの状態 理想の状態 reconcile() { … } Controller
  35. [CloudNative] ⾃動回復・セルフヒーリング たとえば 2 つしかコンテナ(Pod)が起動していない場合… Observe: 理想=3、現状=2 Observe Diff Act

    Observe: 現状を確認 Diff: 理想と現実の差分を計算 Act: 差分に対する処理を実施 クラスタの状態 理想の状態 reconcile() { … } Controller
  36. [CloudNative] ⾃動回復・セルフヒーリング たとえば 2 つしかコンテナ(Pod)が起動していない場合… Diff: 1 つコンテナ(Pod)が⾜りない Observe Diff

    Act Observe: 現状を確認 Diff: 理想と現実の差分を計算 Act: 差分に対する処理を実施 クラスタの状態 理想の状態 reconcile() { … } Controller
  37. [CloudNative] ⾃動回復・セルフヒーリング たとえば 2 つしかコンテナ(Pod)が起動していない場合… Act: 1つ nginx:1.12 のコンテナ(Pod)を作成する Observe

    Diff Act Observe: 現状を確認 Diff: 理想と現実の差分を計算 Act: 差分に対する処理を実施 クラスタの状態 理想の状態 reconcile() { … } Controller
  38. [CloudNative] ステートフルなアプリケーション Kubernetes では Controller の仕組みを利⽤して、 Database の⾃動管理を⾏うことが可能(にはなっている) ※ 厳密には

    Controller も API を⽤いて変更します。 reconcile() { … } 登録 (via API Request) 監視 MySQL Cluster の管理 reconcile() { … } Controller 独⾃のリソースに対してどのような処理をするか Controller を書くことで運⽤が容易に (運⽤ナレッジのプログラム化)
  39. [CloudNative] ステートフルなアプリケーション Database on Kubernetes を実現するエコシステムは沢⼭ある •  MySQL Operator(presslabs, oracle)

    •  Vitess Operator 現実的にはコンテナの短いライフサイクルの影響で ステートフルなアプリケーションには向かないことも多い 現時点では OSS で提供されている Operator(Controller)の成熟度が⾼くはない プロダクションでステートフルなアプリケーションを動かすには注意が必要 軽量な KVS、Queue 辺りからはじめて、RDB などはその後が良さそう