飽き性の頭の中
【Kubernetes】GKE上に配置したアプリケーションにHTTPSでアクセスできるようにするのサムネイル

【Kubernetes】GKE上に配置したアプリケーションにHTTPSでアクセスできるようにする

2019-06-16に公開

今回自分のただのサイトを Firebase から GKE に移してみました(移す前はこの状態)

https://blog.tawa.me/entry/2019/01/03/180000
https://blog.tawa.me/entry/2019/01/03/180000

最近 Docker を使っていたのでプライベートでも使いたかったのと、毎回デプロイ先を考えるのが面倒だったので、GKE に上げてしまえばすべて解決なのではと思ったわけです。

昨日1日かけてなんとかアクセスできるようになったのはよいのですが、1日経たずすでに 200 円くらいかかっている感を感じているのです。遊びで運用するにはかなり高くついているので、敢え無く閉じようかと思っています。

一番ハマったのが、GKE で動いているアプリケーションを外部に公開するところでした。特に独自ドメインを当てて HTTPS 化するところだったのでその話をメインに書いておきます。

Deployment を設定

クラスター作ったりはいい感じにしてください。あと、デプロイしたいアプリケーションを適当に Docker イメージにまとめて Cotainer Registry に上げておきます。

そして、そのイメージを使って deployment を作りましょう。今回は、tawa-appという名前のアプリを置きました。

# deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: tawa-app-deployment
  labels:
    app: tawa-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: tawa-app
  template:
    metadata:
      labels:
        app: tawa-app
    spec:
      containers:
        - name: tawa-app
          image: gcr.io/tawa-me/tawa-app
          ports:
            - containerPort: 3000

Service と Ingress を設定

起動している Pod を外部に公開するための設定です。今回は Ingress を使って HTTPS でアクセスできるようにするのでtypeNodePortにします。

HTTPS 化のためにマネージド証明書発行

gcloud beta compute ssl-certificates create tawa-cert --domains tawa.meで発行できるのでしておきます。

その証明書の名前(tawa-cert)は Ingress の設定でingress.gcp.kubernetes.io/pre-shared-certに入れておくとよいらしいです(たぶん)。

Service と Ingress

まとめて同じ yaml に書いてます。

# service.yaml

apiVersion: v1
kind: Service
metadata:
  name: tawa-app-service
spec:
  type: NodePort
  selector:
    app: tawa-app
  ports:
    - protocol: TCP
      port: 3000
      targetPort: 3000
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: tawa-ingress
  annotations:
    kubernetes.io/ingress.allow-http: "true"
    # certificateを以下で作成しておく
    # gcloud beta compute ssl-certificates create tawa-cert --domains tawa.me
    ingress.gcp.kubernetes.io/pre-shared-cert: tawa-cert
  labels:
    app: ingress
spec:
  rules:
    - http:
        paths:
          - path: /*
            backend:
              serviceName: tawa-app-service
              servicePort: 3000

GUI 上で Ingress のロードバランサの設定(の確認)

Ingress を apply するとロードバランサが自動で作られます。

20190616145548.png

フロントエンド

HTTP と HTTPS の設定をする

フロントエンドはこのロードバランサにリスクエストを受けるときの設定(だと思っています)。

20190616150004.png

HTTPS 化等をするならここで設定します。編集を押して、HTTPS の設定をしましょう。さきほど生成した certificate も選択肢にあるはずです。

このとき SSL ポリシーは独自で TLS1.2 以上になるようにしておきました。

この設定をしないとアクセスが通らなかったので、制限がかかっているのでしょうか。

バックエンド

yaml 上の Ingress の設定で書いてあるので確認でよいはずです。今回はすべてtawa-app-serviceに流していますが、パスを見て違うサービスに流すということもできるっぽいのでとても楽しそうです。

IP アドレスを固定しておく

公式とか見ると事前に固定 IP を取得してそれを yaml とかで設定すれば良さそうな感じもありますが、GUI 上で変えてもいけそうです。

20190616150543.png

タイプがエフェメラルになっていたら静的にしておくと固定されるはず(たぶん)。

kubernetes.io/ingress.global-static-ip-name: k8s-fw-default-tawa-ingress--630497c773ccd137 という感じで、yaml にもこの固定 IP の名前を設定しておくといいんですかね(あまりわかってない)。

Google Domains から Cloud DNS に流す

Google Domains を使っているという前提で書きますが、他でドメインを取っていても同じなのではないでしょうか。この辺のドメイン周りもほぼ何もわかってなかったのですが、今回でちょっとイメージつかめた感があります。

イメージとしては、デフォルトだと Google Domains で取った Domain は Google Domains 上で解決されるけれども、一部または全部を Cloud DNS 上の設定を参照させることができるという感じでしょうか。

このあたりは素人なので言葉の使い方とかきっと間違っているとは思いますが、許して下さい。

Cloud DNS でゾーンを作る

作業としては、Cloud DNS の画面でゾーンなるものを作ります。

20190616151831.png

名前は何でもよいらしいですが、tawa.me の割当を担当してもらうというイメージでtawa-meにしました。

NS レコードを Google Domains に設定

ゾーンの中を見るといろいろ値があります。

20190616152024.png

その中の NS レコードを Google Domains やドメインを取得したサービス上で設定する必要があります。

Google Domains であればこんな感じです。