
KubernetesでHTTPS通信をやってみる①【ローカル編】

IT技術
MinikubeとIngressで自己署名証明書を使ったHTTPS通信を実現する
この記事では、ローカル環境のMinikubeを使い、自己署名証明書(オレオレ証明書)とIngressでHTTPS通信を実現する流れを見ていきます。
前編としてローカルでIngressを使ったHTTPS通信を確認し、後編ではGoogleCloud上にk8sリソースを作成して同様にHTTPS通信ができるところまで確認します。前編後編を通してk8sでのネットワーク(L4, L7)について少し詳しくなろうという試みです。
1. はじめに:なぜHTTPSが必要なのか?
現代のウェブサービスにおいて、HTTPSは必須です。ユーザーとサーバー間の通信を暗号化することで、データの盗聴や改ざんを防ぎ、安全性を確保します。
HTTPS通信を扱う際、TLS終端(TLS Termination)という概念が重要になります。これは、HTTPSの暗号化・復号の処理をどこで行うか、というもの。アプリケーション(Pod)が直接処理することも可能ですが、一般的にはIngressなどのロードバランサで一括して行うのが効率的です。これにより、アプリケーションはシンプルなHTTP通信に集中できます。
2. 全体構成図
今回作っていく環境の構成図です
右側がminikubeを使ったk8sクラスタになります。
各アイコンについて簡単に表にしました。
今回の主役は「Ingress」というリソースです。構成図からもわかるように外部からの通信と、クラスタ内部の通信の境目にあるリソースで、つまりLBのようなものになります。
これがクラスタから見て外部からの通信部分をHTTPS通信で行い、ここで暗号化された通信を復号して、以降の処理をhttpで行うようにします。
3. 環境準備
まずはMinikubeをインストールし、Kubernetesクラスターを起動します。
1minikube start
次に、Ingressコントローラを有効にします。minikubeではローカル(端末)からクラスタへの通信はデフォルトではできません。クラスタから見て外部の端末とのやりとりをしたい場合は明示的にIngressコントローラを使えるようにする必要があります。IngressコントローラはIngressリソースのルールを解釈し、実際のトラフィックをルーティングする役割を担います。
1minikube addons
opensslコマンドが利用可能かどうかも確認しておきましょう。(無ければインストールします)
1openssl version
4. 自己署名証明書の作成
HTTPS通信には、秘密鍵と証明書のペアが必要です。今回は、開発・検証目的のため、自分で署名する自己署名証明書(オレオレ証明書)を作成します。
作業ディレクトリ作成 (任意)
1mkdir -p ~/minikube-tls
2cd ~/minikube-tls
秘密鍵(tls.key)の生成
2048ビットのRSA秘密鍵を生成します。
1openssl genrsa -out tls.key 2048
証明書署名要求(tls.csr)の生成
証明書に含める情報を入力します。Common Name (CN)には、後ほどアクセスする際のホスト名(例: my-nginx.local)を指定することが最も重要です。
1openssl req -new -key tls.key -out tls.csr
質問に対して、Common Nameをmy-nginx.localとして回答します。
自己署名証明書(tls.crt)の生成
秘密鍵とCSRを使って、自己署名証明書を作成します。有効期間は365日に設定します。
1openssl x509 -req -days 365 -
これで、tls.key(秘密鍵)とtls.crt(証明書)の2つのファイルができました。
5. Kubernetesリソースのデプロイ
作成した証明書を使い、HTTPS通信を行うアプリケーションをデプロイします。
Secret: 証明書をKubernetesに安全に保存する
kubectl create secret tlsコマンドを使って、秘密鍵と証明書をmy-nginx-tls-secretという名前のSecretとして登録します。Secretは、パスワードや証明書のような機密情報を扱うためのKubernetesリソースです。
1kubectl create secret tls my-nginx-tls-secret \
2 --cert=./tls.crt \
3 --key=./tls.key
Deployment & Service: Nginxアプリケーションの準備
HTTPSリクエストを受け取るNginxアプリケーションと、それにアクセスするためのServiceを作成します。
nginx-deployment-service.yamlを作成します。
本来はDeploymentとServiceは別ファイルに分けることが多いですが、今回は簡易的に1ファイルで作成します。
1# nginx-deployment-service.yaml
2apiVersion: apps/v1
3kind: Deployment
4metadata:
5 name: nginx-deployment
6spec:
7 replicas: 1
8 selector:
9 matchLabels:
10 app: nginx
11 template:
12 metadata:
13 labels:
14 app: nginx
15 spec:
16 containers:
17 - name: nginx
18 image: nginx:latest
19 ports:
20 - containerPort: 80 # Ingressからの通信はHTTP
21---
22apiVersion: v1
23kind: Service
24metadata:
25 name: nginx-service
26spec:
27 selector:
28 app: nginx
29 ports:
30 - protocol: TCP
31 port: 80
32 targetPort: 80
33 type: ClusterIP # Ingressが内部的にアクセスするためClusterIPでOK
このファイルを適用します。
1kubectl apply -f nginx-deployment-service.yaml
Ingress: ホスト名とTLS証明書を紐づける
外部からのリクエストをNginxサービスにルーティングするためのIngressリソースを作成します。nginx-ingress.yamlを作成します。
1# nginx-ingress.yaml
2apiVersion: networking.k8s.io/v1
3kind: Ingress
4metadata:
5 name: nginx-https-ingress
6 annotations:
7 nginx.ingress.kubernetes.io/rewrite-target: /
8spec:
9 rules:
10 - host: my-nginx.local # ここに証明書で指定したホスト名を入れる
11 http:
12 paths:
13 - path: /
14 pathType: Prefix
15 backend:
16 service:
17 name: nginx-service
18 port:
19 number: 80
20 tls:
21 - hosts:
22 - my-nginx.local
23 secretName: my-nginx-tls-secret # 作成したTLS Secretの名前
このファイルを適用します。
1kubectl apply -f nginx-ingress.yaml
5. ローカルからの接続確認
最後に、PCからmy-nginx.localというホスト名でMinikubeにアクセスできるよう設定します。
hostsファイルの設定:
MinikubeのIPアドレスを確認します。
1minikube ip
手元の環境では192.168.49.2と表示されたのでこれを使います
自身のPCのhostsファイル(/etc/hosts)に以下の行を追加します。(sudo vi /etc/hosts)
1192.168.49.2 my-nginx.local
設定が終わったらhttps://my-nginx.localにアクセスしてみてください。
Chromeだと警告がでますが、アクセスを続行すると以下のようにページが表示されます
保護されていないという警告がでるのは、証明書が信頼されたCA認証局が発行したものではなく自作のものだからです。
まとめ
今回はローカルではありますが、k8s環境にてHTTPS通信を実現する流れを見ていきました。クラウドの環境だと様々なサービスが絡んで来て一見ややこしそうですが、やりたいことはすごくシンプルだということがイメージできたのではないでしょうか。
後編では実際にGoogleCloudに環境を構築して、ちゃんとしたHTTPS通信をやっていきます
ライトコードでは、エンジニアを積極採用中!
ライトコードでは、エンジニアを積極採用しています!社長と一杯しながらお話しする機会もご用意しております。そのほかカジュアル面談等もございますので、くわしくは採用情報をご確認ください。
採用情報へ

2022年7月入社。GCP、k8sに興味があって学習中。