KubeflowのHTTPS通信化

以下の記事では、Windows環境にKubeflowのインストール方法をシェアしているので、Kubeflowのインストールがまだであれば、こちらの記事を参照してください。

venoda.hatenablog.com


インストール時点では、HTTPS通信となっていないため、実運用へのせるためにはHTTPS通信にする必要があると思います。この記事ではIngressを使用してKubeflowのアクセスをHTTPS通信にする方法をシェアします。

注意点としては、SSL証明書は自己証明書という形で進めます。




1. Ingressの作成

1. Nginx Ingress Controllerのインストール

Ingressを使用するための前準備として、NGINX Ingress ControllerをKubernetesにデプロイします。

helmを使用してNGINX Ingress Controllerをデプロイするので、helmをインストールしていない場合は、helmをインストールしてください。

helm.sh


NGINX Ingress Controllerのデプロイは、簡単で下記のコマンドでデプロイすることができます。

github.com

$ helm upgrade --install ingress-nginx ingress-nginx \
  --repo https://kubernetes.github.io/ingress-nginx \
  --namespace ingress-nginx --create-namespace


2. Ingressの作成

以下の記事でKubeflowをインストールして、Kubeflowへアクセスするときは、ポートフォワードしてアクセスをしていました。

venoda.hatenablog.com


Ingress経由でアクセスできるように、KubeflowのServiceとIngressを紐づけるマニフェストファイルを定義し、Ingress経由でアクセスできる設定を作成します。


マニフェストファイルは下記のように定義します。

# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  # Ingressの名前を指定する
  name: kubeflow-entrypoint
  namespace: istio-system
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            # アクセスするService名を指定する
            name: istio-ingressgateway
            port:
              number: 80


マニフェストファイルが定義できたら、実際にマニフェストファイルを適用します。

$ kubectl apply -f ingress.yaml


Ingressが作成されているかを確認します。

ADDRESSの箇所にlocalhostと表示されたらアクセスできるはずです。(表示されるまで数分程度時間がかかります。)

$ kubectl get ingress -n istio-system
NAME                  CLASS    HOSTS   ADDRESS     PORTS   AGE
kubeflow-entrypoint   <none>   *       localhost   80      83s


実際に、下記のURLでKubeflowにアクセスができます。

http://localhost:80


ポートフォワードしなくてもKubeflowにアクセスすることができました。



2. HTTPS通信化

1. 自己証明書の作成

HTTPSを利用する場合は、証明書と秘密鍵が必要になります。

正規にはサーバ証明書を購入する必要があるのですが、今回は自己証明書を使用してHTTPS化します。


下記のopensslコマンドを使用して、自己証明書を作成することができます。

何かしらの入力が求められたら基本的にすべてEnterで進んで問題ありません。

$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -out kubeflow.crt -keyout kubeflow.key


コマンドを実行すると、下記の2ファイルが作成されます。

  • kubeflow.key
  • kubeflow.crt


補足として、作成した証明書の中身は下記のコマンドで確認することができます。

# 証明書の内容を表示
$ openssl x509 -text -noout -in kubeflow.crt

# 証明書に含まれる公開鍵の確認
$ openssl x509 -in kubeflow.crt -pubkey -noout

# 秘密鍵の確認
$ openssl rsa -text -noout -in kubeflow.key


2. 証明書のSecret化

Kubernetes上で証明書を使用するために、Secretを作成します。

# Secretの作成
$ kubectl create  -n istio-system secret tls cert-secret --key kubeflow.key --cert kubeflow.crt

# 作成したSecretの確認
$ kubectl get secret -n istio-system cert-secret -o yaml



3. Ingressの修正

Ingressマニフェストファイルを下記のように修正します。

# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  # Ingressの名前を指定する
  name: kubeflow-entrypoint
  namespace: istio-system
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
    # ここの行を追加するとhttps強制できる
    kubernetes.io/ingress.allow-http: "false"
spec:
  # 作成したSecretを指定する
  tls:
  - secretName: cert-secret
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            # アクセスするService名を指定する
            name: istio-ingressgateway
            port:
              number: 80


マニフェストファイルが修正できたら、実際にマニフェストファイルを適用します。

$ kubectl apply -f ingress.yaml


Ingressが修正されているかを確認します。

PORTSのところに、Secretを設定する前はなかった443が追加されていることがわかります。

$ kubectl get ingress -n istio-system
NAME                  CLASS    HOSTS   ADDRESS     PORTS     AGE
kubeflow-entrypoint   <none>   *       localhost   80, 443   44m


4. ブラウザにアクセス

設定した内容でブラウザから、Kubeflowにアクセスしてみます。

HTTPS通信化したので、下記のURLでアクセスできます。

https://localhost:443


自己証明書を使用しているのでブラウザの設定によっては警告が出ると思いますが、気にせずアクセスします。


実際にHTTPSでKubeflowにアクセスすることができました。