【Kubernetes】GKE上に配置したアプリケーションにHTTPSでアクセスできるようにする
Table Of Contents
今回自分のただのサイトを Firebase から GKE に移してみました(移す前はこの状態)
最近 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 でアクセスできるようにするのでtype
はNodePort
にします。
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 するとロードバランサが自動で作られます。
フロントエンド
HTTP と HTTPS の設定をする
フロントエンドはこのロードバランサにリスクエストを受けるときの設定(だと思っています)。
HTTPS 化等をするならここで設定します。編集を押して、HTTPS の設定をしましょう。さきほど生成した certificate も選択肢にあるはずです。
このとき SSL ポリシーは独自で TLS1.2 以上になるようにしておきました。
この設定をしないとアクセスが通らなかったので、制限がかかっているのでしょうか。
バックエンド
yaml 上の Ingress の設定で書いてあるので確認でよいはずです。今回はすべてtawa-app-service
に流していますが、パスを見て違うサービスに流すということもできるっぽいのでとても楽しそうです。
IP アドレスを固定しておく
公式とか見ると事前に固定 IP を取得してそれを yaml とかで設定すれば良さそうな感じもありますが、GUI 上で変えてもいけそうです。
タイプがエフェメラルになっていたら静的にしておくと固定されるはず(たぶん)。
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 の画面でゾーンなるものを作ります。
名前は何でもよいらしいですが、tawa.me の割当を担当してもらうというイメージでtawa-me
にしました。
NS レコードを Google Domains に設定
ゾーンの中を見るといろいろ値があります。
その中の NS レコードを Google Domains やドメインを取得したサービス上で設定する必要があります。
Google Domains であればこんな感じです。
Use custom name servers
に入れることで、Google Domains が Cloud DNS を参照するようになり、Cloud DNS の設定が使われるようになるはずです。
Cloud DNS で tawa.me の A レコードにて IP を指定
上記設定が終わればもう GCP 上で完結します。
Ingress で外部に公開している IP をここで指定すると、tawa.me
へのアクセスをこの IP に流してくれるようになるはずです(長かった)。
tawa.me -> Google Domains -> Cloud DNS -> 外部公開IP -> GKE上のService
という流れでしょうか。Heroku とか Firebase だとほぼ何も考えずにデプロイしたものに独自ドメイン当てたり自動で HTTPS 化してくれたりしてましたけれど、相当ありがたいことだったんですね…。
しばし待機
DNS の設定や HTTPS 化する certificate がアクティブになるまでそれなりに時間がかかるので、辛抱強く待ちましょう。
設定が間違っていると思いきや、単に待てばよかったという場合もあったので、むやみにいじらず少し待ってから変更していったほうがドツボにはまらず良さそうな気がしました。
まとめ
1日かけてようやく動いて、Kubernetes でいつでも遊べる! と思ったのですが、値段が高すぎたわけです。
ちょっと残念ではありますが、この記事を見ればいつでもまたできると信じて落とそうかと思います。。