• トップ
  • ブログ一覧
  • KubernetesでHTTPS通信をやってみる①【ローカル編】
  • KubernetesでHTTPS通信をやってみる①【ローカル編】

    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通信をやっていきます

     

    ライトコードでは、エンジニアを積極採用中!

    ライトコードでは、エンジニアを積極採用しています!社長と一杯しながらお話しする機会もご用意しております。そのほかカジュアル面談等もございますので、くわしくは採用情報をご確認ください。

    採用情報へ

    たけちゃん(エンジニア)
    たけちゃん(エンジニア)
    Show more...

    おすすめ記事

    エンジニア大募集中!

    ライトコードでは、エンジニアを積極採用中です。

    特に、WEBエンジニアとモバイルエンジニアは是非ご応募お待ちしております!

    また、フリーランスエンジニア様も大募集中です。

    background