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

Rancher × Hashicorp Vault で 実現する秘密情報管理

Rancher × Hashicorp Vault で 実現する秘密情報管理

2026/01/26 RancherJP #8
Rancher × Hashicorp Vault で 実現する秘密情報管理

More Decks by システム開発部広報委員会

Transcript

  1. 2026/01/26 RancherJP #8 Rancher × Hashicorp Vault で 実現する秘密情報管理 齊藤

    大貴 株式会社マイクロアド システム開発部 プラットフォームエンジニアリングユニット
  2. アウトライン • 自己紹介・会社紹介・チーム紹介 • はじめに • 実現方法の概略 • Vault の構築とシークレットのアップロード

    • K8s Master のエンドポイントの提供 • Vault と K8s クラスタを認証させる • VSO を使って K8s に Secret を作る • おまけ(運用の話など) • まとめ 2
  3. 事業内容:広告プラットフォーム DSP(Demand Side Platform) 
 SSP(Supply Side Platform) 
 「広告を出したい」

    「広告を出して欲しい」 広告主/代理店 広告代理店 広告主
 広告主 ・・・
 広告 広告A
 広告B
 広告C
 ・・・
 来訪ユーザー 
 ユーザーA
 ユーザーB
 ユーザーC
 ・・・
 メディア
 ニュース
 コスメ
 グルメ
 ・・・
 Ad 広告出稿 料 広告表 示
 ✕ リアルタイムオークション 
 数億のWEB行動データ 
 Data Management Platform 
 分析 6
  4. 数字で見るシステム ▪ レスポンス   : 0.05秒 ▪ オークション数 : 150億回 / 日 ▪

    データ処理量  : 10TB / 日 ▪ ユニークブラウザ: 4億件 ▪ 携帯端末データ : 3,000万件 ... 7
  5. Active/Standby 構成の LVS Active/Active 構成の HAProxy 複数の Kubernets クラスタ マイクロアドの

    Kubernetes 環境 haproxy-devel01 haproxy-devel02 haproxy-prod01 LVS01 Active haproxy-prod02 LVS02 Standby cluster-prod01 cluster-prod02 rancher-prod01 cluster-prod06 cluster-dev01 cluster-dev02 rancher-dev01 … 小・中規模のクラスタが複数ある • クラスタ数:10 • サーバ台数:プロキシ:4台、開発環境:約10台、本番環境:約40台 8
  6. シークレット と シークレット管理 そもそもシークレットとは...? • パスワード、トークン、秘密鍵といった「機密情報の総称」 シークレットの管理方法 • Google Password

    Manager • メモ帳 • 自分の頭 • etc... 今回登場する Hashicorp Vault も、シークレット管理に使われるプロダクトです 11 サイト1 ・user: alice ・pass: p@assw0rd サイト2 ・user: alice ・pass: pass1234 …
  7. 暗号化に関する様々な機能を提供する OSS ※ OpenBao という HashiCorp Vault の Fork プロジェクトもある

    機能(Engine)の紹介 • シークレット管理 ◦ リッチな Key-Value ストア • サービスアカウントの動的発行 • SSH key や DB ユーザの動的発行 • プライベート認証局 • 通信の暗号化 ◦ Encryption as a Service • etc… Hashicorp Vault とは 12 今回使う機能
  8. 今回話す内容 Kuberntes の Secret リソースってどう管理していますか? 「Gitに上げられないし、手動運用はつらい...」と悩んでいる方も多いはず 今回は「HashiCorp Vault + Vault

    Secrets Operator によるシークレット管理」を紹介します 併せて「Rancher から作ったクラスタで、任意の FQDN を提供する方法」も紹介します 13 kind: Secret data: secret: xxx metadata: name: secret シークレット情報を Git 管理 kind: VaultStaticSecret data: secretPath: foo/bar metadata: name: vss シークレット情報の パスを Git 管理 ※ ファイルはイメージです 同期
  9. やること • Vault サーバの構築と、シークレットのアップロード • K8s Master のエンドポイントの提供(Vault から Master

    に JWT認証する必要があり、 Master のエンドポイントの提供が必要) ◦ Rancher の ACE 機能を有効化する (ACE は Rancher から作ったクラスタで、任意のFQDNのエンドポイントを提供する機能) ◦ HAProxy で Master を集約する • Vault と K8s クラスタを認証させる • Vault Secret Operator(VSO)を使って K8s クラスタに Secret を作る (VSO は Vault 上のシークレットと、K8s の Secret リソースの橋渡しをする Operator) 15
  10. Vault クラスタ Hashicorp Vaultの構築 Vault の動作環境は主に3つ • サーバ上で直接動かす(マイクロアドの構成) • Kubernetes

    上で動かす • マネージドサービス(HCP Vault) 17 vault01.internal Standby vault02.internal Active vault03.internal Standby Client Network vault vault vault Raft でリーダ選出
  11. (参考までに)Vault を Helm でデプロイする例 K8s クラスタがある場合、Helm で簡単にインストール可能 ※ Helmfile は

    helm install のオプションなどをファイルにまとめられるツール(docker compose 的な立ち位置) 18 server: ha: enabled: true replicas: 3 raft: enabled: true repositories: - name: hashicorp url: https://helm.releases.hashicorp.com releases: - name: vault namespace: vault chart: hashicorp/vault createNamespace: true version: 0.32.0 values: - values.yaml helmfile.yaml values.yaml
  12. (参考までに)Vault を Helm でデプロイする例 19 $ kubectl exec -it -n

    vault vault-0 -- vault operator init $ kubectl exec -n vault -ti vault-0 -- vault operator unseal h... $ kubectl exec -n vault -ti vault-0 -- vault operator unseal K... $ kubectl exec -n vault -ti vault-0 -- vault operator unseal A... $ kubectl exec -n vault -ti vault-1 -- vault operator raft join \ http://vault-0.vault-internal.vault.svc:8200 $ kubectl exec -n vault -ti vault-1 -- vault operator unseal h... $ kubectl exec -n vault -ti vault-1 -- vault operator unseal K... $ kubectl exec -n vault -ti vault-1 -- vault operator unseal A... # vault-2 の Pod に対しても vault-1 の Pod と同様に実行 ... 初期化のコマンド(Seal と Unseal について) 参考: https://developer.hashicorp.com/vault/docs/deploy/kubernetes/helm/examples/ha-with-raft
  13. ACE (Authorized Cluster Endpoint) とは Rancher から作成したクラスタへ API を送ると、全てのリクエストは一度 Rancher

    サーバをプロ キシとして介す ACE (Authorized Cluster Endpoint) は、Rancher サーバ を経由せずに Downstream cluster の API サーバへ直接通信できるようにする機能 26 通常時 (Rancher Proxy 経由) ACE 有効時 経路 クライアント → Rancher → Downstream クライアント → Downstream 依存関係 Rancher が停止すると通信不可能 Rancher が停止しても通信可能 ネットワーク Rancher サーバーへのアクセスさえあれば OK クラスターの API サーバ (6443番など) への 直接疎通が必要 (別途プロキシが必要 )
  14. ACE の有効化後の KubeConfig 28 apiVersion: v1 kind: Config clusters: -

    name: "cluster01" cluster: server: "https://rancher.internal/k8s/clusters/xxx" # xxx はランダム文字列 + - name: "cluster01-fqdn" + cluster: + server: "https://cluster01.internal:6443" + certificate-authority-data: "xxx" users: - name: "cluster01" user: token: "xxx" contexts: - name: "cluster01" context: user: "cluster01" cluster: "cluster01" + - name: "cluster01-fqdn" + context: + user: "cluster01" + cluster: "cluster01-fqdn" clusters[] と contexts[] に ACE で 設定した FQDN のエントリが追加されてる
  15. HAProxy の動き 29 haproxy FQDN: rancher.internal Master Master … Worker

    Worker … FQDN: cluster01.internal Master Master … Worker Worker … FQDN: cluster02.internal Master Master … Worker Worker … L4モードで動作 (SNI で FQDN をチェックして振り分ける) ・SNI = rancher.internal ・SNI = cluster01.internal ・SNI = cluster02.internal
  16. HAProxy の設定例 30 ... frontend https_frontend bind *:6443 mode tcp

    use_backend backend_rancher if { req.ssl_sni -i rancher.internal } use_backend backend_cluster01 if { req.ssl_sni -i cluster01.internal } use_backend backend_cluster02 if { req.ssl_sni -i cluster02.internal } backend backend_rancher server rancher-master01 rancher-master01.internal:6443 server rancher-master02 rancher-master02.internal:6443 ... backend backend_cluster01 server cluster01-master01 cluster01-master01.internal:6443 server cluster01-master02 cluster01-master02.internal:6443 ... backend backend_cluster02 server cluster02-master01 cluster02-master01.internal:6443 server cluster02-master02 cluster02-master02.internal:6443 ... 受け取ったリクエストの FQDN が cluster01.internal なら backend_cluster01 のサーバにリクエストを流す ・cluster01-master01.internal:6443 ・cluster01-master02.internal:6443
  17. 任意の K8s Master のエンドポイントが提供できた🎉 これで任意の K8s Master のエンドポイントが提供できたので、 Vault サーバから通信できるようになりました

    31 FQDN: rancher.internal Master Master … Worker Worker … FQDN: cluster01.internal Master Master … Worker Worker … FQDN: cluster02.internal Master Master … Worker Worker … vault JWT 認証 haproxy
  18. Vault に登録する ServiceAccount の作成 Vault から K8s に対して JWT 認証を実施するので、

    Vault に登録するための ServiceAccount を作ります 33 apiVersion: v1 kind: ServiceAccount metadata: name: sa-vault-auth namespace: namespace1 --- apiVersion: v1 kind: Secret metadata: name: vault-auth-token namespace: namespace1 annotations: kubernetes.io/service-account.name: sa-vault-auth type: kubernetes.io/service-account-token Hashicorp Vault Kubernetes cluster ServiceAccount Token
  19. Vault に JWT 認証で使う情報を登録 35 # K8s 認証の有効化 $ vault

    auth enable -path=cluster01-namespace1 kubernetes # K8s の ServiceAccount に紐づいている Token を Vault に登録 $ vault write auth/cluster01-namespace1/config \ kubernetes_host=https://cluster01.internal:6443 \ token_reviewer_jwt=$(kubectl get secret -n namespace1 \ -o jsonpath='{.data.token}' vault-auth-token | base64 -d) \ kubernetes_ca_cert=xxx # KubeConfig に記載 # Role (ServiceAccount と Policy の紐づけ) を作成 $ vault write auth/cluster01-namespace1/role/role-vso \ bound_service_account_names=sa-vault-auth \ bound_service_account_namespaces=namespace1 \ policies=read-cluster01 \ audience=vault Hashicorp Vault Policy Kubernetes cluster ServiceAccount Token Auth Role Role の作成について:K8s の namespace1 にある sa-vault-auth に、Vault にある cluster01 のデータの読み込みを許可(read-cluster01)している
  20. Kuberntes cluster VSO(Vault Secret Operator)とは • VSO(Vault Secret Operator)は、Hashicorp 社が開発している

    K8s Operator • Vault とリアルタイムで同期して、K8s の Secret リソースを作成してくれる 37 5. Pod がマウント 1. ユーザが CR を作成 (VaultStaticSecretなど) K8s Secret (Opaque...) Pod Vault Secret Operator Hashicorp Vault kind: VaultStaticSecret data: secretPath: foo/bar metadata: name: vss 4. Secret リソースを作成 foo/bar ・key1: var1 ・key2: var2 3. 機密情報の返却 2. 機密情報の要求
  21. Vault Secret Operator のインストール 38 repositories: - name: hashicorp url:

    https://helm.releases.hashicorp.com releases: - name: vault-secrets-operator namespace: vso chart: hashicorp/vault-secrets-operator createNamespace: true version: 1.2.0 Vault Secret Operator を インストールするための helmfile cluster01 namespace: vso Vault Secret Operator namespace: namespace1 Vault KV v2 Secret Engine secret-1 ・key1: val-1 ・key2: val-2 sample-secret ・key3: val-3 ・key4: val-4
  22. VaultConnection の作成 39 apiVersion: secrets.hashicorp.com/v1beta1 kind: VaultConnection metadata: name: vault-connection

    spec: address: https://vault.internal:8200 skipTLSVerify: false どこに認証するかの設定 • Hashicorp Vault の URL • ネットワーク設定 cluster01 namespace: vso Vault Secret Operator VaultConnection namespace: namespace1 Vault KV v2 Secret Engine secret-1 ・key1: val-1 ・key2: val-2 sample-secret ・key3: val-3 ・key4: val-4
  23. VaultAuth の作成 40 apiVersion: secrets.hashicorp.com/v1beta1 kind: VaultAuth metadata: name: vault-auth

    namespace: namespace1 spec: kubernetes: audiences: - vault role: role-vso serviceAccount: sa-vault-auth method: kubernetes mount: "cluster01-namespace1" vaultConnectionRef: vso/vault-connection どうやって認証するかの設定 • どの VaultConnection を使うか • 認証方法(今回は Kubernetes 認証) • 使用する ServiceAccount cluster01 namespace: vso Vault Secret Operator VaultConnection namespace: namespace1 VaultAuth Vault KV v2 Secret Engine secret-1 ・key1: val-1 ・key2: val-2 sample-secret ・key3: val-3 ・key4: val-4
  24. VaultStaticSecret の作成 41 apiVersion: secrets.hashicorp.com/v1beta1 kind: VaultStaticSecret metadata: name: vss-sample-secret

    spec: destination: create: true name: sample-secret mount: cluster01 path: namespace1/sample-secret type: kv-v2 vaultAuthRef: vault-auth 何をどこへ同期するかの設定 • どの VaultAuth を使うか • Vault 上のシークレットのパス • 作成する Secret 名 cluster01 namespace: vso Vault Secret Operator VaultConnection namespace: namespace1 VaultAuth VaultStaticSecret-1 Vault KV v2 Secret Engine sample-secret 作成 secret-1 ・key1: val-1 ・key2: val-2 sample-secret ・key3: val-3 ・key4: val-4 ポーリング VaultStaticSecret を作ると Secret リソースが作られる
  25. Vault に障害が発生したら? 42 cluster01 namespace: vso Vault Secret Operator VaultConnection

    namespace: namespace1 VaultAuth VaultStaticSecret-1 Vault KV v2 Secret Engine sample-secret secret-1 ・key1: val-1 ・key2: val-2 sample-secret ・key3: val-3 ・key4: val-4 同期できなくなる 障害発生 作成済みの Secret リソースは そのまま残る
  26. Fleet × Helm で GitOps 44 k8s-app-sample ├─ chart │

    ├─ Chart.yaml │ ├─ templates │ │ ├─ deployment.yaml │ │ ├─ service.yaml │ │ └─ vaultStaticSecret.yaml │ └─ values.yaml ├─ fleet.yaml ├─ gitRepo.yaml └─ values ├─ cluster01.yaml └─ common.yaml apiVersion: fleet.cattle.io/v1alpha1 kind: GitRepo metadata: name: sample namespace: fleet-default spec: repo: https://x/k8s-app-sample.git branch: master bundles: - options: ./fleet.yaml targets: - clusterName: cluster01 namespace: sample helm: releaseName: sample chart: ./chart valuesFiles: - values/common.yaml # クラスタごとの個別設定 targetCustomizations: - name: cluster01 clusterName: cluster01 helm: valuesFiles: - values/cluster01.yaml ディレクトリ構成 ./gitRepo.yaml ./fleet.yaml マイクロアドでは、アプリ毎に Helm Chart を 作っており Fleet でデプロイしている Chart のデプロイの設定
  27. Fleet × Helm で GitOps VaultStaticSecret は Helm でテンプレート化しており、 Values

    で名前を指定するだけでクラスタに Secret リソースを作れるようにしている 45 {{- range $secret := .Values.vaultStaticSecret }} --- apiVersion: secrets.hashicorp.com/v1beta1 kind: VaultStaticSecret metadata: name: vss-{{ $secret }} spec: destination: create: true name: {{ $secret }} mount: {{ $.Values.cluster }} path: {{ $.Release.Namespace }}/{{ $secret }} type: kv-v2 vaultAuthRef: vault-auth {{- end }} vaultStaticSecret: - secret-1 - secret-2 - secret-3 ./chart/template/vaultStaticSecret.yaml ./values/cluster01.yaml cluster: ${ .ClusterName } ./values/common.yaml クラスタ名は .ClusterName で取得できる( 参考)
  28. VSO 以外のシークレット管理のプロダクト • ESO(External Secret Operator) ◦ HashiCorp Vault 以外のシークレットストアにも対応している汎用的な

    Operator • Sealed Secrets ◦ Secret リソースを暗号化するプロダクト 46 VSO ESO Sealed Secrets Github のスター数 559 6.3 k 8.8 k 動的シークレット 対応 非対応 非対応 シークレットの世代管理 対応 非対応 非対応 HashiCorp Vault以外の シークレットストアの対応 非対応 対応 -
  29. まとめ おさらい • Hashicorp Vault × Vault Secret Operator で安全に

    K8s シークレットを管理できる • ACE は、Rancher から作ったクラスタでも 任意の FQDN でエンドポイントを提供できるようにする機能 今後の展望 • 現在はサーバに直接 Vault をインストールしているので K8s に移行したい 48