この記事は SecurityCamp Advent Calendar 2025 および デジタル創作サークル UniProject Advent Calendar 2025 14 日目の記事です。
はじめに
みなさん、コンテナ、好きですよね?
昨今、マイクロサービスアーキテクチャという考え方も取り入れられ、Kubernetes などのコンテナネイティブな技術スタックも一般的になってきました。
しかし、Kubernetes もコンテナも銀の弾丸ではありません。
今回は、その Kubernetes のセキュリティについて考えてみます。
Kubernetes でなくとも潜む脅威
まずは、Kubernetes でなくとも潜む脅威(一般的に気をつけるべきこと)について考えてみましょう。
考えうることとしては、以下のとおりです。
- ノードのセキュリティ
- 最小権限の原則の徹底
詳しくみていきましょう。
ノードのセキュリティ
ノードのセキュリティがしっかりしていないと本末転倒です。
よくあるのが、
- ポート開けっぱなし
- Kube API 見えてる
とかですね。
SSH のポートは閉じているのに Kube API が空いているせいで Kubernetes にアクセスできてしまう、なんてこともあります。
確かに、完全にアクセスを禁止するというのは無理がありますが、少なくとも、イントラネットだけアクセス可能な設定にするなど対策することができます。
最小権限の原則の徹底
ノードの Ubuntu のユーザー権限はもちろんのこと、Kubernetes の RBAC も考える必要があります。
Kubernetes の RBAC には、
- Role
- ClusterRole
- RoleBinding
- ClusterRoleBinding
といったコンポーネントがあります。
ClusterRole
ClusterRole は、名前空間を跨いでクラスター全体の権限を定義するリソースです。
デフォルトで用意されているものとして、
- cluster-admin
- admin
- edit
- view
があります。
cluster-admin は全ての権限を持ちますが、これは非常によろしくなく、admin を割り当てるべきです。
admin では、任意の名前空間上の Role と RoleBinding を編集する権限を有しており、名前空間、クオータ自体へのアクセスは禁止できます。
また、edit であったとしても、secret にアクセスすることができてしまうため、注意が必要です。
これは ClusterRoleBinding で ServiceAccount や User に紐つけることができます。
Role
Role は、名前空間内のみで通用する権限を定義するリソースです。
これを定義するには、admin 以上の権限が必要です。
また、ServiceAccount や User への紐付けは RoleBinding で行えます。
そして、RoleBinding では ClusterRole の紐付けも行えます。
したがって、edit を RoleBinding で紐つけることにより、その名前空間のリソースのみ編集権限を与えるといったことが可能です。
詳しくは、こちらをご覧ください。
Kubernetes ならではの脅威
Kubernetes、コンテナだからこその脅威についてみていきましょう。
今回取り扱うのは、
- コンテナ自体の脆弱性
- コンテナブレイクアウト
- mTLS
- ファイルシステムへの侵害
です。
コンテナ自体の脆弱性
コンテナ自体に脆弱性があることもあります。
よくある話ですね。
先日も、React の RCE の脆弱性を含んだコンテナに入られたという話を聞きました...
これを防ぐ代表的な方法には
docker scan- Trivy
があります。
今回は Trivy について考えます。
Trivy とは
trivy はセキュリティスキャナです。trivy はコンテナイメージ、ファイルシステム、リポジトリに対して脆弱性や SBOM のスキャンを実行できます。
CLI で使う
このようなコマンドで DockerImage を検査することができます。
trivy image nginx:latest
2025-09-22T11:23:44.840Z INFO Detected OS: debian
2025-09-22T11:23:44.840Z INFO Detecting Debian vulnerabilities...
2025-09-22T11:23:44.858Z INFO Number of language-specific files: 0
nginx:latest (debian 12.12)
===========================
Total: 88 (UNKNOWN: 8, LOW: 72, MEDIUM: 6, HIGH: 2, CRITICAL: 0)
controlplane:~$ more nginx-tabel-format.txt
+------------------+------------------+----------+------------------------+---------------+-----------------------------------------+
| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE |
+------------------+------------------+----------+------------------------+---------------+-----------------------------------------+
| apt | CVE-2011-3374 | LOW | 2.6.1 | | It was found that apt-key in apt, |
| | | | | | all versions, do not correctly... |
...
Harbor と一緒に使う
私がお勧めするのはこの方法です。
プライベートコンテナレジストリの Harbor には Trivy と一緒に使う機能が搭載されています。
Helm でインストールするとすでにデフォルトでついてきています。
Integration Service を見ると、スキャン履歴を確認することができます。
意外とベースイメージが悪いなんてこともあるので、確認してみましょう。
コンテナブレイクアウト
入られた後に怖いものとして、コンテナブレイクアウトがあります。
これは何かというと、コンテナの殻を突き破り、ノードに出ていくという攻撃です。
これの対策としては、
- root 権限で実行しない
- コンテナランタイムのソケットをコンテナ内にマウントしない
- シェルすら含まないイメージを使ってみる
ということが挙げられます。
mTLS
mTLS はコンテナに限った話ではないものの、Kubernetes は内部ネットワークが切り離されているから大丈夫だろうと甘くみてはいけません。
この mTLS を簡単に行う方法として、Istio というものがあります。
これを用いることにより、特定の名前空間内の通信をすべて mTLS でラップすることができます。
これに関しては、別の記事で書きます。
ファイルシステムへの侵害
最後に、ファイルシステムへの侵害ですね。
これに関しては、securityContextで防ぐことができます。
apiVersion: v1
kind: Pod
metadata:
name: security-context-demo
spec:
securityContext:
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
supplementalGroups: [4000]
## ...
解説すると、
- UserID 1000 で実行する
- UserGroup 3000 で実行する
- マウントしたボリュームの所有権は 2000 で行い、補助グループとする
- supplementalGroups によって補助グループが指定されているので 4000 も補助グループとなる
これにより、ファイルシステムの権限も制限され、意図しないファイルの変更が起こりにくくなります。
最後に
今回は Kubernetes のセキュリティについて再考してみました。
コンテナだからと安心せず、しっかりと対策していきましょう。
また、当サークルでは ProxmoxVE や Kubernetes を運用しています。
もし興味がありましたら、下記 URL へ飛んでいただければと思います!
⭐︎ 公式 HP ↓
⭐︎ Discord ↓
参考文献
