プライベートクラウドのサービス運用環境をK8sで改善する話
by
dulltz
Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
プライベートクラウドの サービス運⽤環境を K8sで改善する話 2019/11/26 Bonfire Backend #4
Slide 2
Slide 2 text
⾃⼰紹介 鶴⽥貴⼤ @dulltz ログ基盤チーム(2017.09‒2017.12) クラウド基盤刷新チーム(2018.01-) 焚き⽕好き
Slide 3
Slide 3 text
cybozu.comというサービス 提供期間 > 8年 契約社数 > 3万5千 ユーザー数 > 130万
Slide 4
Slide 4 text
cybozu.comのインフラ
Slide 5
Slide 5 text
cybozu.com のインフラ ⾃社製プライベートクラウドでサービス運⽤ OpenStack は使っていない ⾃社製プライベートクラウドにガタがきてる 具体的な話は後述
Slide 6
Slide 6 text
cybozu.com のインフラ刷新 つらいので2018年から刷新中 Necoプロジェクト
Slide 7
Slide 7 text
インフラ刷新の進捗状況 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
Slide 8
Slide 8 text
刷新プロジェクトの⽬的 運⽤コストの低減 今回はこっちの話 スケーラビリティの向上
Slide 9
Slide 9 text
運⽤に関する2017年当時の気持ち 運⽤が⼤変 もっと⾃動化したい ⾃作過ぎる もうちょっと標準的なしくみを取り⼊れたい
Slide 10
Slide 10 text
2017年後半の運⽤ツール コンテナオーケストレーションツールが既に流⾏ K8s Apache Mesos Docker Swarm
Slide 11
Slide 11 text
なぜK8sを選択? K8sが圧倒的に流⾏っていた K8s中⼼に発展しているエコシステムが強そう 勝ち⾺に乗ろう
Slide 12
Slide 12 text
K8s導⼊の動機まとめ 課題 増⼤する運⽤コストをなんとかしたい なぜK8s? コンテナオーケストレーションツールの中で勢いが圧倒的だった
Slide 13
Slide 13 text
運⽤コスト下がった?
Slide 14
Slide 14 text
いい話1: OSアップグレード
Slide 15
Slide 15 text
旧基盤の環境 Ubuntuを使⽤ コンテナほぼ不使⽤ ホストOSの環境がアプリケーションに影響
Slide 16
Slide 16 text
旧基盤 Ubuntuアップグレード Ubuntu 14.04 から 16.04 へのアップグレード 内蔵ミドルウェアの変更が サービス運⽤に影響ないかチェックする必要あり Changelogを全部チェック 実機で実験 不具合が現れたら原因調査、改修
Slide 17
Slide 17 text
ビッグバンリリースすぎた もっと⼿軽にOSアップグレードしていきたい 変更差分を⼩さくしたい
Slide 18
Slide 18 text
旧基盤のサービス退避 サーバ停⽌にはその上のサービスの退避が伴う ⼈⼒
Slide 19
Slide 19 text
新基盤ではすべてコンテナで K8sを使う、つまりコンテナによるサービス運⽤にする CoreOS Container Linux 採⽤
Slide 20
Slide 20 text
CoreOS Container Linux コンテナを動かすための軽量OS 内蔵ミドルウェアが少ない ネットブートにかかる時間が短い
Slide 21
Slide 21 text
新基盤の継続的インテグレーション OSのブートストラップ、アップグレードを⾃動テスト化 Nested VM上に仮想的なデータセンター環境を構築 VM構築ユーティリティを開発 cybozu-go/placemat 毎⽇CIで試験しておいて、常にOSアップグレード可能な状態に
Slide 22
Slide 22 text
新基盤のOSアップグレードはこれだけ 1. 対象ノードをdrain 2. サーバーを再起動 3. 対象ノードのuncordon
Slide 23
Slide 23 text
OSアップグレード楽になった k8sノードはコンテナさえ動けばOKなのでコンテナ⽤軽量OSが 使える。内蔵ミドルウェアが少なくアップグレードも⽐較的楽 Container Linux 最⾼ サービス退避はk8sのスケジューリング機能で楽できる
Slide 24
Slide 24 text
いい話2: サービスのデプロイ
Slide 25
Slide 25 text
旧基盤のサービスデプロイ 宣⾔的なオペレーションが書けない スクリプト実⾏の順番を厳密に守る必要がある ⼿順書が⻑く複雑になりがち
Slide 26
Slide 26 text
旧基盤のサービスデプロイ 継続的デリバリが⼀部しかできていない
Slide 27
Slide 27 text
旧基盤のサービスデプロイ 開発チームから渡ってきたアーカイブファイルを SREチームがデプロイ 運⽤コストが⼀部のチームに集中しがち
Slide 28
Slide 28 text
どうしてこうなった 旧基盤は 理想状態への収束を⾏えるようなアーキテクチャになってない マルチテナンシーという概念が薄い 本番デプロイできるようになるにはadmin並の権限が必要
Slide 29
Slide 29 text
新基盤では宣⾔的なオペレーション K8sのYAML適⽤ ⻑い⼿順書からの脱却 必要に応じてカスタムコントローラも導⼊
Slide 30
Slide 30 text
新基盤ではサクッと継続的デリバリ GitOps Argo CDを使⽤中 Kustomizeで構成管理 各ツールの使い⽅は他のチームにも布教
Slide 31
Slide 31 text
新基盤ではどのチームもデプロイできる 各チーム(=テナント)に適切な権限を割り当てることで、 基盤チーム以外でもk8sのリソースを触れるように
Slide 32
Slide 32 text
テナントの権限 アプリをデプロイできるようにする うっかり他のテナントを邪魔してしまわないようにする
Slide 33
Slide 33 text
新基盤のマルチテナンシー いわゆるソフトマルチテナンシー 単⼀のk8sクラスタですべてのテナントを賄う RBAC, Admission Controller, NetworkPolicy などを利⽤ 時間余ったら最後に詳しく話します(資料の最後の⽅参照)
Slide 34
Slide 34 text
サービスデプロイ良くなった 基盤チーム以外がデプロイできるようになった GitOpsでCDできるようになった マルチテナンシー周りはまだまだ固まっていないので、 これからも改善していく
Slide 35
Slide 35 text
いい話3: 開発環境
Slide 36
Slide 36 text
旧基盤の開発環境 本番と同型のクラスタを共同利⽤ うっかり壊すと他の⼈に迷惑かけてしまう
Slide 37
Slide 37 text
新基盤はk8s 各⼈ごとに⽤意可能なK8sはいろいろある Minikube microk8s Kind GKE
Slide 38
Slide 38 text
新基盤の開発環境はKindで ⾃作CSIプラグインなど、⾃社仕様のk8sクラスタで動かすミド ルウェアを動かすようにカスタマイズ
Slide 39
Slide 39 text
開発環境よくなった 開発環境を松⽵梅で⽤意 Kind環境 ローカルPCで動く Nested VM環境 GCEインスタンスで動く K8sの下回りのミドルウェアやネットワーク構成が本番と同じ 実機環境 どうしても実機が必要なとき使う
Slide 40
Slide 40 text
いい話4: いろいろ
Slide 41
Slide 41 text
サービス公開+証明書発⾏を⾃動化 カスタムリソースを1つ作成するだけで AレコードとTLS証明書が⾃動で作成される コンポーネント Contour Cert-manager External-DNS Contour-plus
Slide 42
Slide 42 text
処理の流れ Contour⽤カス タムリソースを 作成する • ユーザが作成 Certificateと DNSEndpoint が作成される • contour-plus TLS証明書と Aレコードが 作成される • cert-manager • external-dns
Slide 43
Slide 43 text
多機能踏台サーバが使える Teleport K8sへのアクセスを管理できる GitHubを使ったSSOで権限制御ができる ターミナルの⼊出⼒を録画できる TeleportでKubernetesクラスタへのユーザーアクセスを管理する - Cybozu Inside Out
Slide 44
Slide 44 text
既存ツールの組み合わせで⾊々できる エコシステムが盛り上がっているツールを選んだメリット 勝ち⾺にのって良かった感
Slide 45
Slide 45 text
まとめ
Slide 46
Slide 46 text
運⽤コストは下がった? これまで⾯倒だったことが楽になった OSアップグレード サービスデプロイ 開発環境 その他⾊々 ⾃分たちで全部作らなくても既存ツールの組み合わせで いい感じにできるように ただしk8sの運⽤・アップグレードという新タスクも発⽣
Slide 47
Slide 47 text
おわり まだまだ模索中 他社の知⾒を教えて下さい
Slide 48
Slide 48 text
新基盤のマルチテナンシーについて詳細 1クラスタk8sですべてのテナントを賄う Soft multi-tenancy
Slide 49
Slide 49 text
RBAC テナントのスコープをnamespaceで切る 基盤チームの namespace はテナントからは⾒えない Custer-wide リソースをテナントは作成できない
Slide 50
Slide 50 text
Admission Controller 認証より後のフェーズで ユーザーからのAPIリクエストを受け⼊れるか制御する機構
Slide 51
Slide 51 text
今有効にしてる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
Slide 52
Slide 52 text
PodSecurityPolicy クラスタ全体でPodのセキュリティ設定を制御するポリシー 特権コンテナの拒否、hostのリソース使⽤の拒否などができる 運⽤⽅針:デフォルトのポリシーでは権限をある程度限定してお き、必要に応じて緩和するよう上書きする PSPは今後GAにならないらしい。そのうち⾒直す必要ありそう
Slide 53
Slide 53 text
デフォルトの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
Slide 54
Slide 54 text
緩和した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 • ホストネットワークの使⽤を許可
Slide 55
Slide 55 text
ResourceQuota, LimitRange ResourceQuota Namespaceごとに使⽤可能なリソース(CPU,RAM)の総量を設定 LimitRange Pod,PVCなどに割り当てるリソースの最⼩値/最⼤値を設定 基盤チームは無制限 テナントにはクラスタを壊さない程度の制限を設定 具体的な数値は相談しながら調整
Slide 56
Slide 56 text
NetworkPolicy Admission Controllerではない ラベルセレクタが使えるファイヤウォール Calicoの拡張NetworkPolicyを使っている 基盤チームが優先順位の⾼いポリシーを作っておく
Slide 57
Slide 57 text
基本: GlobalNetworkSetを定義 データセンターで使うサブネットを役割ごとに定義し、ラベル を付与しておく k8sクラスタ内部のサブネット BMCのサブネット 機材のサブネット 踏み台サーバのサブネット
Slide 58
Slide 58 text
基本: 外部への通信を許可 apiVersion: crd.projectcalico.org/v1 kind: GlobalNetworkPolicy metadata: name: egress-all-allow spec: order: 10000.0 types: - Egress egress: - action: Allow
Slide 59
Slide 59 text
基本: 内部への通信を遮断 apiVersion: crd.projectcalico.org/v1 kind: GlobalNetworkPolicy metadata: name: ingress-all-deny spec: order: 10000.0 types: - Ingress ingress: - action: Deny
Slide 60
Slide 60 text
クラスタ内からのアクセスを許可 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'
Slide 61
Slide 61 text
Admission Webhook APIサーバへのリクエストのバリデーション/ミューテーション を⾃作するための機構 Necoではテナントが優先順位の⾼すぎるNetworkPolicyを作れ ないようにしている 以前はGatekeeperとOpenPolicyAgentを使って実装していたが、 それは⽌めてcontroller-runtimeで作り直した
Slide 62
Slide 62 text
Admission Webhook 例 テナントが優先順位の⾼すぎるNetworkPolicyを作れないよう にする 以前はGatekeeperとOpenPolicyAgentを使って実装していたが、 ⼀旦⽌めてcontroller-runtimeで作り直した *KubeConNA2019だとGatekeeperすごい流⾏ってました
Slide 63
Slide 63 text
テナントのやりたいことにAdmin権限が 必要な時はどうする? ケースバイケースで対応中 ミドルウェアレイヤーでなんとかなったりもする
Slide 64
Slide 64 text
「CRDやオペレーターを追加したい」 基盤チームで管理する テナントには基盤チームの提供する1サービスとして提供 例: Elastic Cloud on Kubernetes
Slide 65
Slide 65 text
「ArgoCD使いたい」 ArgoCD⾃体は基盤チームが管理 ArgoCDの参照するGitソースは各テナントが管理 ArgoCD⾃体に独⾃RBAC機能があるので、 テナントのApplicationリソースの同期/閲覧権限だけテナント に渡したり
Slide 66
Slide 66 text
「基盤チームのPrometheusのデータを 使いたい」 kube-state-metricsなどがテナントから⾒えない 基盤チームのPrometheusのFederation APIに アクセスしてもらうことで対応