Kubernetes を運用していると必ずぶつかる壁、それが「証明書の管理」です。
kube-apiserver、etcd、kube-controller-manager、kube-scheduler… これらのコンポーネントがどのように安全な通信を行っているのか、全体像を把握するのは容易ではありません。
この記事では、「なぜ Kubernetes にはこんなに大量の証明書があるのか?」を理解するために、まずは TLS の基本を振り返り、その後に Kubernetes 内部の証明書の役割(CA、サーバ証明書、クライアント証明書)を紐解いていきます。
本記事は構成・執筆を Gemini 3.1 Pro に行ってもらい、筆者がレビュー・加筆しています。
1. TLS の基本:暗号化と認証の仕組み
Kubernetes の証明書を理解するには、まず通信の基盤となっている「TLS(Transport Layer Security)」の仕組みを知る必要があります。
1-1. 公開鍵と秘密鍵(非対称暗号)
TLS のベースとなるのが公開鍵暗号方式です。ここではペアになる 2つの鍵を使います。
- 公開鍵(Public Key):誰にでも配っていい鍵。南京錠のようなもの。
- 秘密鍵(Private Key):自分だけが厳重に保管する鍵。南京錠を開けるための実際の鍵。
【暗号化のルール】
- 公開鍵で暗号化したデータは、ペアとなる秘密鍵でしか復号できない。(相手に自分の公開鍵を渡し、それでデータを暗号化してもらえば、盗聴されても自分しか読めません)
- 秘密鍵で暗号化したデータは、ペアとなる公開鍵でしか復号できない(電子署名)。※ 厳密にはデータのハッシュ値を暗号化(署名)します。(「このデータは間違いなく私が作成した」という証明に使われます。)
1-2. デジタル証明書とCA(認証局)
公開鍵を渡されたとき、一つの疑問が生じます。「この公開鍵は、本当に通信したい相手(例:Google や自分の API Server)のものだろうか? 悪意のある第三者のものではないか?」
これを解決するのが CA(Certificate Authority:認証局)とデジタル証明書です。
-
証明書(Certificate /
.crt):「公開鍵」と「その所有者の情報」をセットにし、CA が自身の秘密鍵でハンコ(電子署名)を押したものです。 - CA:みんなが信頼している第三者機関(Kubernetes の場合はクラスタ自身が独自の CA を持ちます)。
クライアントは「CA の公開鍵(ルート証明書)」をあらかじめ持っており、それを使って通信相手の証明書のハンコ(署名)が正しいかを確認します。
1-3. TLS ハンドシェイクの流れ
Web サイト(HTTPS)へのアクセスや Kubernetes 内部の通信では、暗号化通信を開始する前に以下のようなやり取り(ハンドシェイク)が行われます。
- Client Hello: クライアントからサーバへ、対応している暗号スイート(暗号化方式)などを送信する。
- Server Hello & Certificate: サーバは使用する暗号スイートを決定し、自身の証明書(公開鍵を含む)をクライアントへ送信する。
- 証明書の検証: クライアントは、事前に保持している「CA の公開鍵(ルート証明書)」を使用してサーバ証明書の署名を検証し、通信相手の正当性を確認する。
- 鍵交換(Key Exchange): クライアントとサーバ間で、共通鍵を生成するためのパラメータを交換する。この際、サーバは自身の「秘密鍵」を用いてパラメータに電子署名を行い、改ざんされていないことを保証する。
- 共通鍵の生成: クライアントとサーバは、交換したパラメータを元に、それぞれの環境で独立して同一の「共通鍵」を計算・生成する。
- 暗号化通信の開始: 双方が同じ共通鍵を保持した後は、処理負荷の低い共通鍵暗号方式に切り替え、実際のデータ通信を行う。
2. Kubernetes の通信の要「mTLS(相互 TLS)」
通常の Web サイトの TLS 通信では、「クライアント(ブラウザ)がサーバ(Web サイト)の身元を確認する」という片方向の認証しか行いません。
しかし、Kubernetes クラスタ内では mTLS(Mutual TLS:相互 TLS 認証) が使われます。
これは、サーバがクライアントの身元を確認し、クライアントもまたサーバの証明書を提示して身元を証明する方式です。
「誰でも API Server にアクセスできるわけではなく、正しいクライアント証明書を持ったコンポーネント(またはユーザー)だけが通信できる」というゼロトラストな環境を作っています。
3. Kubernetes の証明書アーキテクチャ
ここからがいよいよ本題です。Kubernetes の主要コンポーネントは、自分が「サーバ」として振る舞う時と「クライアント」として振る舞う時の両方があるため、複数の証明書を持っています。
3-1. すべての信頼の根源:CA(認証局)
Kubernetes クラスタを構築する際、まず最初に作成されるのがクラスタ専用の CA(オレオレ認証局)です。
-
ca.crt(CA の証明書/公開鍵) -
ca.key(CA の秘密鍵)
すべてのコンポーネントはこの ca.crt を持っており、「この CA が署名した証明書なら信頼する」という設定になっています。
実は、CA の実体(ルート証明書)は、「公開鍵・所有者情報に自己署名を行った証明書と、その秘密鍵のペア」に過ぎません
kubeadm 等を使用して Kubernetes を構築する際、裏側で自動的に openssl などのコマンドが実行され、「このクラスタ内だけで通用する CA」が生成されます。
一般的な Web サイトでは、世界中が信頼する「公的な CA」のハンコが必要です。しかし、Kubernetes のクラスタ内部の通信では、「クラスタという会社の中だけで通用する社員証」があれば十分です。
3-2. Kubernetes クラスタの通信全体像
個別の証明書の役割を見ていく前に、まずは Kubernetes クラスタ内の通信の全体像をイメージしておきましょう。
Kubernetes のアーキテクチャは、「API Server を中心とした星型」のネットワークになっています。各コンポーネントが直接互いに通信するのではなく、基本的には必ず API Server を経由してやり取りを行います。
- 中心: API Server
- バックエンド: etcd, kubelet
- クライアント: Controller Manager, Scheduler, kubelet, kubectl
kubelet は「クライアント」であり「サーバ」でもある
kubelet は少し特殊な立ち位置にいます。普段は Node のステータスを報告する「クライアント」として API Server にアクセスしますが、kubectl logs や kubectl exec が実行された際は、API Server から通信を受け付ける「サーバ(バックエンド)」として振る舞います。そのため、API Server との間で双方向に通信が発生します。
以下の図は、誰が「サーバ」として振る舞い、誰が「クライアント」としてアクセスするのかを示した全体像です。
この「誰が誰にアクセスするのか(サーバとクライアントの関係)」という構造を頭に入れた上で、各コンポーネントが持つ証明書を順番に見ていきましょう。
3-3. kube-apiserver の証明書
API Server は、クラスタの「中央のハブ」です。みんなからリクエストを受け付け(サーバ)、同時に自分から etcd などにデータを書き込みに行きます(クライアント)。
-
サーバ証明書 (
apiserver.crt/.key):kubectl や 各 Node(kubelet)が API Server にアクセスしてくる際に、「私は本物の API Server です」と証明するために使います。 -
クライアント証明書(対 etcd 用) (
apiserver-etcd-client.crt/.key):API Server がデータの保存先である etcd にアクセスする際、「私は本物の API Server(許可されたクライアント)です」と証明して書き込みを行うために使います。 -
クライアント証明書(対 kubelet 用) (
apiserver-kubelet-client.crt/.key):kubectl logsやkubectl execを実行した際、API Server から 各 Node の kubelet へ通信しに行くためのクライアント証明書です。
3-4. etcd の証明書
クラスタのすべての状態を保存するデータベースです。絶対に不正アクセスされてはいけません。
-
サーバ証明書 (
etcd/server.crt/.key):API Server からのアクセスを受け付けるための証明書です。 -
ピア証明書 (
etcd/peer.crt/.key):etcd は通常複数台(3台や5台)でクラスタを組みます。etcd ノード同士がデータを同期・通信する際に、互いを信頼するための証明書です。
3-5. Controller Manager の証明書
Controller Manager は、Deployment や ReplicaSet など、クラスタの「あるべき姿」を維持するために常に API Server を監視し、必要な操作(Pod の作成指示など)を行います。つまり、API Server に対する強力な権限を持ったクライアントとして振る舞います。
-
クライアント証明書 (
controller-manager.crt/.key):API Server に「私は Controller Manager です」と身分を明かし、リソースを操作する権限をもらうために使います。
3-6. Scheduler の証明書
Scheduler は、新しく作成された Pod を「どの Node に配置するのが最適か」を計算し、API Server にその結果を書き込みます。こちらも API Server に対する純粋なクライアントです。
-
クライアント証明書 (
scheduler.crt/.key):API Server に「私は Scheduler です」と身分を明かし、Pod の配置先(NodeName)を更新する権限をもらうために使います。
3-7. Kubelet (Worker Node) の証明書
各 Node で Pod を動かす kubelet は、API Server と双方向に通信します。
- クライアント証明書:Node のステータスを API Server に報告するために使います(Node 追加時に CSR 機能を使って API Server の CA から自動発行されることが多いです)。
- サーバ証明書:API Server からの logs や exec のリクエストを受け付けるために使います。
3-8. 管理者(kubectl)の証明書
私たちが手元の PC から kubectl コマンドを叩くときにも、実は証明書が使われています。
~/.kube/config ファイルの中身を見ると、client-certificate-data と client-key-data という項目があります。これが「管理者としてのクライアント証明書と秘密鍵」であり、これを使って API Server の強力な操作権限を得ています。
4. 【発展】PKI ディレクトリ内の「その他の鍵」
ここまでの知識があれば、Kubernetes の主要コンポーネントにおける mTLS の仕組みはバッチリです。
しかし、実際に kubeadm 等で構築したクラスタの証明書ディレクトリ(/etc/kubernetes/pki)を ls コマンドなどで覗いてみると、これまで紹介した以外のファイルも存在することに気づくはずです。
ここでは、実運用で目にする機会の多い 2つの特殊な鍵と証明書について軽く触れておきます。
4-1. TLS 通信用ではない鍵:Service Account キーペア
ディレクトリ内には sa.key と sa.pub というファイルが存在します。
これらは拡張子が .crt ではなく、CA の署名もありません。なぜなら、これらは 通信の暗号化(TLS)に使われるものではない からです。
Pod の中から API Server にアクセスする際、Pod は「Service Account トークン」という JWT(JSON Web Token)を使って認証を行います。この sa.key は、API Server(正確には Controller Manager)がトークンを発行する際のデジタル署名に使われ、sa.pub は API Server がそのトークンの正当性を検証するために使われます。
4-2. 拡張 API 用:フロントプロキシ証明書
ディレクトリ内には front-proxy-ca.crt や front-proxy-client.crt といった証明書も存在します。
Kubernetes には、標準の API 以外にも機能を拡張できる仕組み(Aggregated API)があります。代表的なのが、kubectl top コマンドを使うために導入する Metrics Server などです。
これらの拡張 API に対し、API Server はクライアントの代わりにリクエストを転送する「プロキシ(代理人)」として振る舞います。このとき、「このリクエストは間違いなく API Server が仲介したものである」と拡張 API 側に証明するために使われるのが、このフロントプロキシ証明書です。
5. まとめ
Kubernetes の証明書ディレクトリを見ると複雑に感じますが、以下のように「役割」で分解すると非常にシンプルです。
- CA: 全ての証明書を発行し、信頼の根拠となる大元。
- サーバ証明書: 自分が通信を受け付ける際に「偽物ではないこと」を証明するもの。
- クライアント証明書: API Server などのサーバにアクセスする際に、「許可された正当なコンポーネント(または人)であること」を証明するもの。
Kubernetes はこれらを駆使した mTLS(相互認証) によって、コンポーネント間の強固なセキュリティを担保しています。クラスタ構築(kubeadm や Kubernetes The Hard Way など)を行う際、どのコンポーネントが誰と通信するのかを意識しながら証明書を設定すると、解像度がグッと上がるはずです!





