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

プライベートクラウドのサービス運用環境をK8sで改善する話

Aa97a6ad2c4c8422f5580f4f9d5b5744?s=47 dulltz
November 26, 2019

 プライベートクラウドのサービス運用環境をK8sで改善する話

Aa97a6ad2c4c8422f5580f4f9d5b5744?s=128

dulltz

November 26, 2019
Tweet

Transcript

  1. プライベートクラウドの サービス運⽤環境を K8sで改善する話 2019/11/26 Bonfire Backend #4

  2. ⾃⼰紹介 – 鶴⽥貴⼤ @dulltz – ログ基盤チーム(2017.09‒2017.12) – クラウド基盤刷新チーム(2018.01-) – 焚き⽕好き

  3. cybozu.comというサービス – 提供期間 > 8年 – 契約社数 > 3万5千 –

    ユーザー数 > 130万
  4. cybozu.comのインフラ

  5. cybozu.com のインフラ – ⾃社製プライベートクラウドでサービス運⽤ – OpenStack は使っていない – ⾃社製プライベートクラウドにガタがきてる –

    具体的な話は後述
  6. cybozu.com のインフラ刷新 – つらいので2018年から刷新中 – Necoプロジェクト

  7. インフラ刷新の進捗状況 – Done: 本番含め3データセンターでk8sクラスタ稼働中 – ⾃作k8s管理ツールCKEがCertifiedに Cybozu Kubernetes Engine -

    CNCF Cloud Native Interactive Landscape – WIP: Rook/Ceph – LVサポートのためにissue/PR出したり – WIP: サービス移⾏プロジェクトManeki – Cybozuにおける⼤規模インフラ基盤の移⾏プロジェクト Manekiの紹介 - Speaker Deck
  8. 刷新プロジェクトの⽬的 – 運⽤コストの低減 – 今回はこっちの話 – スケーラビリティの向上

  9. 運⽤に関する2017年当時の気持ち – 運⽤が⼤変 – もっと⾃動化したい – ⾃作過ぎる – もうちょっと標準的なしくみを取り⼊れたい

  10. 2017年後半の運⽤ツール – コンテナオーケストレーションツールが既に流⾏ – K8s – Apache Mesos – Docker

    Swarm
  11. なぜK8sを選択? – K8sが圧倒的に流⾏っていた – K8s中⼼に発展しているエコシステムが強そう – 勝ち⾺に乗ろう

  12. K8s導⼊の動機まとめ – 課題 増⼤する運⽤コストをなんとかしたい – なぜK8s? コンテナオーケストレーションツールの中で勢いが圧倒的だった

  13. 運⽤コスト下がった?

  14. いい話1: OSアップグレード

  15. 旧基盤の環境 – Ubuntuを使⽤ – コンテナほぼ不使⽤ – ホストOSの環境がアプリケーションに影響

  16. 旧基盤 Ubuntuアップグレード – Ubuntu 14.04 から 16.04 へのアップグレード – 内蔵ミドルウェアの変更が

    サービス運⽤に影響ないかチェックする必要あり – Changelogを全部チェック – 実機で実験 – 不具合が現れたら原因調査、改修
  17. ビッグバンリリースすぎた – もっと⼿軽にOSアップグレードしていきたい – 変更差分を⼩さくしたい

  18. 旧基盤のサービス退避 – サーバ停⽌にはその上のサービスの退避が伴う – ⼈⼒

  19. 新基盤ではすべてコンテナで – K8sを使う、つまりコンテナによるサービス運⽤にする – CoreOS Container Linux 採⽤

  20. CoreOS Container Linux – コンテナを動かすための軽量OS – 内蔵ミドルウェアが少ない – ネットブートにかかる時間が短い

  21. 新基盤の継続的インテグレーション – OSのブートストラップ、アップグレードを⾃動テスト化 – Nested VM上に仮想的なデータセンター環境を構築 – VM構築ユーティリティを開発 cybozu-go/placemat –

    毎⽇CIで試験しておいて、常にOSアップグレード可能な状態に
  22. 新基盤のOSアップグレードはこれだけ 1. 対象ノードをdrain 2. サーバーを再起動 3. 対象ノードのuncordon

  23. OSアップグレード楽になった – k8sノードはコンテナさえ動けばOKなのでコンテナ⽤軽量OSが 使える。内蔵ミドルウェアが少なくアップグレードも⽐較的楽 – Container Linux 最⾼ – サービス退避はk8sのスケジューリング機能で楽できる

  24. いい話2: サービスのデプロイ

  25. 旧基盤のサービスデプロイ – 宣⾔的なオペレーションが書けない – スクリプト実⾏の順番を厳密に守る必要がある – ⼿順書が⻑く複雑になりがち

  26. 旧基盤のサービスデプロイ – 継続的デリバリが⼀部しかできていない

  27. 旧基盤のサービスデプロイ – 開発チームから渡ってきたアーカイブファイルを SREチームがデプロイ – 運⽤コストが⼀部のチームに集中しがち

  28. どうしてこうなった 旧基盤は – 理想状態への収束を⾏えるようなアーキテクチャになってない – マルチテナンシーという概念が薄い – 本番デプロイできるようになるにはadmin並の権限が必要

  29. 新基盤では宣⾔的なオペレーション – K8sのYAML適⽤ – ⻑い⼿順書からの脱却 – 必要に応じてカスタムコントローラも導⼊

  30. 新基盤ではサクッと継続的デリバリ – GitOps – Argo CDを使⽤中 – Kustomizeで構成管理 – 各ツールの使い⽅は他のチームにも布教

  31. 新基盤ではどのチームもデプロイできる – 各チーム(=テナント)に適切な権限を割り当てることで、 基盤チーム以外でもk8sのリソースを触れるように

  32. テナントの権限 – アプリをデプロイできるようにする – うっかり他のテナントを邪魔してしまわないようにする

  33. 新基盤のマルチテナンシー – いわゆるソフトマルチテナンシー – 単⼀のk8sクラスタですべてのテナントを賄う – RBAC, Admission Controller, NetworkPolicy

    などを利⽤ – 時間余ったら最後に詳しく話します(資料の最後の⽅参照)
  34. サービスデプロイ良くなった – 基盤チーム以外がデプロイできるようになった – GitOpsでCDできるようになった – マルチテナンシー周りはまだまだ固まっていないので、 これからも改善していく

  35. いい話3: 開発環境

  36. 旧基盤の開発環境 – 本番と同型のクラスタを共同利⽤ – うっかり壊すと他の⼈に迷惑かけてしまう

  37. 新基盤はk8s – 各⼈ごとに⽤意可能なK8sはいろいろある – Minikube – microk8s – Kind –

    GKE
  38. 新基盤の開発環境はKindで – ⾃作CSIプラグインなど、⾃社仕様のk8sクラスタで動かすミド ルウェアを動かすようにカスタマイズ

  39. 開発環境よくなった – 開発環境を松⽵梅で⽤意 – Kind環境 – ローカルPCで動く – Nested VM環境

    – GCEインスタンスで動く – K8sの下回りのミドルウェアやネットワーク構成が本番と同じ – 実機環境 – どうしても実機が必要なとき使う
  40. いい話4: いろいろ

  41. サービス公開+証明書発⾏を⾃動化 – カスタムリソースを1つ作成するだけで AレコードとTLS証明書が⾃動で作成される コンポーネント – Contour – Cert-manager –

    External-DNS – Contour-plus
  42. 処理の流れ Contour⽤カス タムリソースを 作成する • ユーザが作成 Certificateと DNSEndpoint が作成される •

    contour-plus TLS証明書と Aレコードが 作成される • cert-manager • external-dns
  43. 多機能踏台サーバが使える – Teleport – K8sへのアクセスを管理できる – GitHubを使ったSSOで権限制御ができる – ターミナルの⼊出⼒を録画できる –

    TeleportでKubernetesクラスタへのユーザーアクセスを管理する - Cybozu Inside Out
  44. 既存ツールの組み合わせで⾊々できる – エコシステムが盛り上がっているツールを選んだメリット – 勝ち⾺にのって良かった感

  45. まとめ

  46. 運⽤コストは下がった? – これまで⾯倒だったことが楽になった – OSアップグレード – サービスデプロイ – 開発環境 –

    その他⾊々 – ⾃分たちで全部作らなくても既存ツールの組み合わせで いい感じにできるように – ただしk8sの運⽤・アップグレードという新タスクも発⽣
  47. おわり – まだまだ模索中 – 他社の知⾒を教えて下さい

  48. 新基盤のマルチテナンシーについて詳細 – 1クラスタk8sですべてのテナントを賄う – Soft multi-tenancy

  49. RBAC – テナントのスコープをnamespaceで切る – 基盤チームの namespace はテナントからは⾒えない – Custer-wide リソースをテナントは作成できない

  50. Admission Controller – 認証より後のフェーズで ユーザーからのAPIリクエストを受け⼊れるか制御する機構

  51. 今有効にしてるadmission controller https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#is-there-a-recommended- set-of-admission-controllers-to-use を参考に – NamespaceLifecycle – LimitRanger –

    ServiceAccount – Priority – DefaultTolerationSeconds – DefaultStorageClass – PersistentVolumeClaimResize – MutatingAdmissionWebhook – ValidatingAdmissionWebhook – ResourceQuota – StorageObjectInUseProtection – NodeRestriction – PodSecurityPolicy
  52. PodSecurityPolicy – クラスタ全体でPodのセキュリティ設定を制御するポリシー – 特権コンテナの拒否、hostのリソース使⽤の拒否などができる – 運⽤⽅針:デフォルトのポリシーでは権限をある程度限定してお き、必要に応じて緩和するよう上書きする – PSPは今後GAにならないらしい。そのうち⾒直す必要ありそう

  53. デフォルトのPSP spec: privileged: false allowPrivilegeEscalation: false requiredDropCapabilities: - ALL volumes:

    - 'configMap' - 'emptyDir' - 'projected' - 'secret' - 'downwardAPI’ - 'persistentVolumeClaim' hostNetwork: false hostIPC: false hostPID: false runAsUser: rule: 'MustRunAsNonRoot' seLinux: rule: 'RunAsAny' supplementalGroups: rule: 'MustRunAs' ranges: - min: 1 max: 65535 fsGroup: rule: 'MustRunAs' ranges: - min: 1 max: 65535 readOnlyRootFilesystem: true • 以下を不許可 • すべてのCapability • ホストのプロセス/ネットワーク/ファ イルシステムへのアクセス • rootによる実⾏を禁⽌ • ルートファイルシステムは read-only
  54. 緩和したPSP spec: privileged: false allowPrivilegeEscalation: false requiredDropCapabilities: - ALL volumes:

    - 'configMap' - 'emptyDir' - 'projected' - 'secret' - 'downwardAPI’ - 'persistentVolumeClaim’ hostNetwork: true hostPorts: - max: 7472 min: 7472 hostIPC: false hostPID: false runAsUser: rule: 'MustRunAsNonRoot' seLinux: rule: 'RunAsAny' supplementalGroups: rule: 'MustRunAs' ranges: - min: 1 max: 65535 fsGroup: rule: 'MustRunAs' ranges: - min: 1 max: 65535 readOnlyRootFilesystem: true Metallb(ロードバランサー実装)のPSP • ホストネットワークの使⽤を許可
  55. ResourceQuota, LimitRange – ResourceQuota – Namespaceごとに使⽤可能なリソース(CPU,RAM)の総量を設定 – LimitRange – Pod,PVCなどに割り当てるリソースの最⼩値/最⼤値を設定

    – 基盤チームは無制限 – テナントにはクラスタを壊さない程度の制限を設定 – 具体的な数値は相談しながら調整
  56. NetworkPolicy – Admission Controllerではない – ラベルセレクタが使えるファイヤウォール – Calicoの拡張NetworkPolicyを使っている – 基盤チームが優先順位の⾼いポリシーを作っておく

  57. 基本: GlobalNetworkSetを定義 – データセンターで使うサブネットを役割ごとに定義し、ラベル を付与しておく – k8sクラスタ内部のサブネット – BMCのサブネット –

    機材のサブネット – 踏み台サーバのサブネット
  58. 基本: 外部への通信を許可 apiVersion: crd.projectcalico.org/v1 kind: GlobalNetworkPolicy metadata: name: egress-all-allow spec:

    order: 10000.0 types: - Egress egress: - action: Allow
  59. 基本: 内部への通信を遮断 apiVersion: crd.projectcalico.org/v1 kind: GlobalNetworkPolicy metadata: name: ingress-all-deny spec:

    order: 10000.0 types: - Ingress ingress: - action: Deny
  60. クラスタ内からのアクセスを許可 apiVersion: crd.projectcalico.org/v1 kind: GlobalNetworkPolicy metadata: name: ingress-cluster-allow spec: order:

    9900.0 types: - Ingress ingress: - action: Allow source: selector: role == 'cluster'
  61. Admission Webhook – APIサーバへのリクエストのバリデーション/ミューテーション を⾃作するための機構 – Necoではテナントが優先順位の⾼すぎるNetworkPolicyを作れ ないようにしている – 以前はGatekeeperとOpenPolicyAgentを使って実装していたが、

    それは⽌めてcontroller-runtimeで作り直した
  62. Admission Webhook 例 – テナントが優先順位の⾼すぎるNetworkPolicyを作れないよう にする – 以前はGatekeeperとOpenPolicyAgentを使って実装していたが、 ⼀旦⽌めてcontroller-runtimeで作り直した –

    *KubeConNA2019だとGatekeeperすごい流⾏ってました
  63. テナントのやりたいことにAdmin権限が 必要な時はどうする? ケースバイケースで対応中 ミドルウェアレイヤーでなんとかなったりもする

  64. 「CRDやオペレーターを追加したい」 – 基盤チームで管理する – テナントには基盤チームの提供する1サービスとして提供 – 例: Elastic Cloud on

    Kubernetes
  65. 「ArgoCD使いたい」 – ArgoCD⾃体は基盤チームが管理 – ArgoCDの参照するGitソースは各テナントが管理 – ArgoCD⾃体に独⾃RBAC機能があるので、 テナントのApplicationリソースの同期/閲覧権限だけテナント に渡したり

  66. 「基盤チームのPrometheusのデータを 使いたい」 – kube-state-metricsなどがテナントから⾒えない – 基盤チームのPrometheusのFederation APIに アクセスしてもらうことで対応