Kubernetesセキュリティの要塞化:生産性を落とさずクラスターを鉄壁にする実務ガイド
テックリードの私たちが日々直面するジレンマは、「開発スピードの最大化」と「セキュリティの担保」のトレードオフだ。セキュリティを厳しくしすぎればデプロイパイプラインが詰まり、逆に緩めれば一晩でクリティカルなインシデントを踏み抜く。
しかし、Kubernetes(k8s)のモダンなセキュリティ機能(RBAC、Pod Security Standards、脆弱性スキャン)を正しくコードとして落とし込み、IaC(Infrastructure as Code)とCI/CDパイプラインに完全に組み込めば、「開発者の手を煩わせず、かつ絶対に破られない要塞」を構築することは完全に可能だ。
本稿では、明日から即座にプロダクション環境へ適用できる、妥協なき実践的アプローチをコードベースで伝授する。
—
1. k8sセキュリティの脅威と対策の全体像
Kubernetesのセキュリティは、単一の城壁ではなく「多層防御(Defense in Depth)」で考える必要がある。攻撃者はしばしばアプリケーションの脆弱性を突いてコンテナ内部へ侵入(Container Escape)し、そこを踏み台にしてAPIサーバーへの不正アクセスやクラスター全体の乗っ取りを狙う。
[ 外部ネットワーク ]
│
▼
┌───────────┐ 1. 脆弱性スキャン (Image Scanning / Trivy)
│ Ingress │──────────────────────────────────┐
└───────────┘ │
│ ▼
▼ ┌──────────────┐
┌───────────┐ 2. Pod Security (PSS) │ Container │
│ Pod │──────────────────────────▶│ Registry │
└───────────┘ (Restricted / Baseline) └──────────────┘
│
▼
┌───────────┐ 3. 最小権限の原則 (RBAC)
│ API Server│◀─────────────────────────────────┘
└───────────┘
私たちが抑えるべき防衛線は以下の3点だ。
1. 供給網の防御(Supply Chain Security): 脆弱性のあるイメージを絶対にクラスターに入れない。
2. ワークロードの隔離(Pod Security): コンテナがホストや他のPodへ不正に干渉するのを防ぐ。
3. 権限の最小化(RBAC): 認証されたユーザー・サービスアカウントの権限を必要最小限に縛る。
これらを「手動運用」で維持するのは怠慢だ。すべて宣言的定義(YAML)としてGit管理し、自動化する。
—
2. 権限管理の基本:RBAC(Role-Based Access Control)の設定
「とりあえず `cluster-admin` を付与しておく」というアンチパターンは今すぐ捨てよう。サービスアカウント(ServiceAccount)および人間(User/Group)に対するRBACは、「最小権限の原則(Least Privilege)」を機械的に強制する。
以下は、CI/CDパイプラインのデプロイ用エージェントや、特定のネームスペース(`production`)でのみ操作を許可する安全なRBAC設計の模範解答だ。
実践YAML:最小権限RBAC構成
apiVersion: v1
kind: Namespace
metadata:
name: production
—
1. 専用のサービスアカウントの定義
apiVersion: v1
kind: ServiceAccount
metadata:
name: deployer-sa
namespace: production
labels:
app.kubernetes.io/managed-by: kustomize
—
2. ロール(操作許可の定義)
productionネームスペース内でのDeploymentとPodの操作に限定
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: production
name: app-deployer-role
rules:
- apiGroups: [“apps”]
resources: [“deployments”, “replicasets”]
verbs: [“get”, “list”, “watch”, “create”, “update”, “patch”, “delete”]
- apiGroups: [“” ]
resources: [“pods”, “services”, “configmaps”, “secrets”]
verbs: [“get”, “list”, “watch”, “create”, “update”, “patch”, “delete”]
—
3. ロールディング(サービスアカウントとロールの結び付け)
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: deployer-rolebinding
namespace: production
subjects:
- kind: ServiceAccount
name: deployer-sa
namespace: production
roleRef:
kind: Role
name: app-deployer-role
apiGroup: rbac.authorization.k8s.io
> テックリードの知見: `ClusterRole` と `ClusterRoleBinding` はクラスター全体に影響するため、特別な理由がない限り使用を禁止し、ネームスペース単位の `Role` と `RoleBinding` を強制すること。
—
3. Pod Security Standards(PSS)の適用
従来の Pod Security Policy (PSP) は廃止された。現在の Kubernetes における標準は Pod Security Standards (PSS) であり、アドミッションコントローラーによって強制される。
PSSには3つのレベルが存在する:
- Privileged: 制限なし(デフォルト、危険)
- Baseline: 一般的なコンテナ向けのセキュリティベースライン(特権昇格を禁止)
- Restricted: 最も厳格(Root実行の禁止、読み取り専用ルートファイルシステムなど)
本番環境のワークロードは、原則として `restricted` レベルをターゲットにすべきである。
実践YAML:ネームスペースレベルでのPSS強制設定
Kubernetes 1.25以降では、ネームスペースのラベルにポリシーを指定するだけで、アドミッション時に自動拒否・警告を行える。
apiVersion: v1
kind: Namespace
metadata:
name: secure-workload
labels:
# 違反時にPodの作成を拒否する (Enforce)
pod-security.kubernetes.io/enforce: restricted
# 違反時にログに警告を出力する (Audit)
pod-security.kubernetes.io/audit: restricted
# 違反時にkubectl実行時に警告を表示する (Warn)
pod-security.kubernetes.io/warn: restricted
# PSSのバージョンを指定 (latestを指定すると将来の厳格化に追従)
pod-security.kubernetes.io/enforce-version: “latest”
`restricted` に適合するPodマニフェストの書き方
`restricted` を有効化すると、素のままでデプロイした多くのアプリケーションは起動に失敗する。開発者が躓かないよう、セキュアなPodコンフィグのテンプレートを共有しておこう。
apiVersion: apps/v1
kind: Deployment
metadata:
name: secure-app
namespace: secure-workload
spec:
replicas: 2
selector:
matchLabels:
app: secure-app
template:
metadata:
labels:
app: secure-app
spec:
# Pod全体でのセキュリティコンテキスト
securityContext:
runAsNonRoot: true # rootユーザーでの実行を禁止
runAsUser: 10001 # 非特権UIDを指定
runAsGroup: 10001
fsGroup: 10001
seccompProfile:
type: RuntimeDefault # デフォルトのシステムコールフィルタを適用
containers:
- name: web
image: nginx:1.25-alpine
securityContext:
allowPrivilegeEscalation: false # 特権昇格の防止
readOnlyRootFilesystem: true # ルートファイルシステムを読み取り専用に
capabilities:
drop:
- ALL # すべてのLinuxケイパビリティを剥奪
resources:
limits:
cpu: “500m”
memory: “512Mi”
requests:
cpu: “100m”
memory: “128Mi”
volumeMounts:
- mountPath: /var/cache/nginx
name: cache-volume
- mountPath: /var/run
name: run-volume
volumes:
- name: cache-volume
emptyDir: {}
- name: run-volume
emptyDir: {}
—
4. 脆弱性スキャンの導入
「セキュアなコードを書く」だけでは不十分だ。ベースイメージや依存ライブラリ(npm, pip, go modules等)に潜む既知の脆弱性(CVE)を、CI/CDパイプラインとクラスター内の両方で検知・ブロックする必要がある。
ここでは、業界標準である Trivy を用いた実践的なアプローチを紹介する。
CI/CDパイプラインへの組み込み(GitHub Actionsの例)
ビルドしたコンテナイメージをレジストリにプッシュする「前」に、クリティカルな脆弱性がないかをスキャンし、検知された場合はパイプラインを即座に失敗させる。
name: Container Security Scan
on:
pull_request:
branches: [ main ]
jobs:
trivy-scan:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Build an image from Dockerfile
run: docker build -t my-app:${{ github.sha .}} .
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: ‘my-app:${{ github.sha }}’
format: ‘table’
exit-code: ‘1’ # 脆弱性が見つかったら終了コード1を返しビルドを落とす
ignore-unfixed: true # 修正パッチ未公開の脆弱性は一旦無視(運用ポリシーによる)
severity: ‘CRITICAL,HIGH’ # 許容する深刻度
—
プロの実践テクニック:生産性を爆発させるツールと設定
セキュリティを強化しても、開発者の日常的なオペレーションが重くなっては本末転倒だ。チーム全体の生産性を落とさずにガバナンスを効かせるための「プロの隠し武器」をシェアする。
1. 開発スピードを高める最強のキーボードショートカット (`kubectl`)
マウス操作や冗長なコマンド入力を排除し、指に記憶させるべきショートカット群。
- コンテキスト・ネームスペースの爆速切り替え (`kubectx` / `kubens`)
プロダクション環境の誤操作を防ぐためにも、インタラクティブな切り替えツールを導入する。
# インストール (Homebrew)
brew install kubectx
# 実行(対話形式で一瞬で切り替え)
kubens production
- エイリアスの最適化 (`~/.zshrc` や `~/.bashrc` に追加)
alias k=”kubectl”
alias kgp=”kubectl get pods”
alias kgd=”kubectl get deployments”
alias kl=”kubectl logs -f”
# 直近でエラーを起こしているポッドのログをノータイムで引く
alias kerr=”kubectl logs –tail=100 -l app.kubernetes.io/instance –max-log-requests=10″
2. 絶対入れるべきVS Code / JetBrains神プラグイン
- Kubernetes (Microsoft公式): クラスター内のリソースツリーを視覚化し、YAMLの補完、ログストリーミング、ポッドへのインタラクティブなターミナル接続をIDEから一撃で行う。
- Kyverno / Datree: CIフェーズやエディタ上で、書いたYAMLがPod Security Standardsや組織のセキュリティポリシーに準拠しているかをリアルタイムで静的解析する。
3. チーム開発のための設定共有化ルール
- Kustomize による環境差分のコード化:
`overlays/development` と `overlays/production` を用意し、セキュリティ設定(Replica数、Resource Limits、PSSラベルなど)の差異を明確に分離する。平文のままSecretsをGitに入れないよう、External Secrets Operator や SOPS (Secrets OPerationS) を組み込み、暗号化された状態のYAMLのみをリポジトリで管理する鉄の掟を作る。
—
結びにかえて
Kubernetesのセキュリティは、「一度設定して終わり」の静的なものではない。開発手法の変化や新たな脆弱性(CVE)の発見に伴い、常にアップデートし続ける必要のある動的なエンジニアリング領域だ。
しかし、今回紹介した 「最小権限のRBAC」、「Pod Security Standardsによる強制隔離」、そして 「CI/CDパイプラインにおけるTrivyスキャン」 の3点をコードベースで網羅していれば、インフラストラクチャとしての堅牢性はトップクラスの水準に達する。
セキュリティを「足枷」ではなく「開発を加速する安全なガードレール」として捉え、チーム全体のインフラ力(Rigor)を極限まで引き上げてほしい。