プライベートクラウドのサービス運用環境をK8sで改善する話
by
dulltz
×
Copy
Open
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
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に アクセスしてもらうことで対応