過去の記事でGKEを使ってnginxを動かしてみましたが、httpsの通信は出来ない状態でした。nginx自体にLet's Encryptの証明書を設定してhttps通信をさせる事も出来ますが、nginx自体を自前で管理するのはしたくないです。AmbassadorというAPI Gatewayとして動作させるものがあるので利用してみました。
Ambassadorの設定をする
基本的にDeploying Ambassador to Kubernetesと同じです。下記はGKEで利用した場合の流れになります。
clusterrolebinding
を設定するkubectl create clusterrolebinding my-cluster-admin-binding --clusterrole=cluster-admin --user=$(gcloud info --format="value(config.account)")
ambassador
をローカルにダウンロードしてデプロイするcurl -O https://www.getambassador.io/yaml/ambassador/ambassador-rbac.yaml
kubectl apply -f ambassador-rbac.yaml
ambassador
のServiceを作成するambassador-service.yaml
を作成するkubectl apply -f ambassador-service.yaml
でデプロイする
# ambassador-service.yaml apiVersion: v1 kind: Service metadata: name: ambassador spec: type: LoadBalancer externalTrafficPolicy: Local ports: - port: 80 targetPort: 8080 selector: service: ambassador
- nginxのdeploymentを起動させる (過去の記事参考)
- nginxのserviceにAmbassadorのannotationsを追加する
apiVersion: v1 kind: Service metadata: name: nginx annotations: getambassador.io/config: | --- apiVersion: ambassador/v1 kind: Mapping name: nginx_mapping prefix: /nginx/ service: nginx spec: selector: name: nginx ports: - port: 80 name: http-nginx targetPort: http-nginx-port
kubectl get svc ambassador
で EXTERNAL-IPを確認する
mayu-mbp-2:kubernetes mayu$ kubectl get svc ambassador NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ambassador LoadBalancer ***** ***** 80:30294/TCP,443:32689/TCP 178m
<EXTERNAL-IP>/nginx/
にブラウザで接続するとnginxの初期画面が表示される。
cert-managerを使って証明書を準備する
基本的にはcert-managerとAmbassadorのドキュメントを参考にしています。cert-managerは Let's Encrypt
のACMEプロトコルを利用して証明書を自動更新する事が出来ます。
事前準備
- namespace
cert-manager
を作成するkubectl create namespace cert-manager
- resource validationの除外設定をしておきます。
kubectl label namespace cert-manager certmanager.k8s.io/disable-validation=true
cert-manager
の設定をダウンロードしてデプロイします。curl -O https://raw.githubusercontent.com/jetstack/cert-manager/release-0.7/deploy/manifests/cert-manager.yaml
kubectl apply -f cert-manager.yaml
証明書の作成
issuer
と Certificate
リソースを作成する必要があります。Issuerはクライアント証明書でCertificateはサーバ証明書の発行を行います。ネームスペースに閉じた証明書を利用する場合は kind: Issuer
でクラスタ全体で利用する場合は kind: ClusterIssuer
で作成をしてください。この記事ではClusterIssuerで進めます。
ClusterIssuer
リソースを作成するkubectl apply -f clusterIssuer.yaml
# clusterIssuer.yaml apiVersion: certmanager.k8s.io/v1alpha1 kind: ClusterIssuer metadata: name: letsencrypt-staging spec: acme: server: https://acme-staging-v02.api.letsencrypt.org/directory email: <mail-address> privateKeySecretRef: name: letsencrypt-staging http01: {}
Certificate
リソースを作成するkubectl apply -f certificate.yaml
# certificate.yaml apiVersion: certmanager.k8s.io/v1alpha1 kind: Certificate metadata: name: kubernetes-certificate namespace: default spec: secretName: kubernetes-cert-secret issuerRef: name: letsencrypt-staging kind: ClusterIssuer dnsNames: - <your_domain> acme: config: - http01: ingressClass: nginx domains: - <your_domain>
HTTP-01 Challengeの設定
ACME認証では HTTPかDNSを利用するかの二種類があります。
(Ambassadorのドキュメント)
- cert-managerのpodから
acme-http-domain
とacme-http-token
を取得するkubectl logs cert-manager-69568fb89d-76zm6 -n cert-manager | grep acme-http
- 下記のようなログが出力されます
I0608 21:19:28.249101 1 ingress.go:49] Looking up Ingresses for selector certmanager.k8s.io/acme-http-domain=161156668,certmanager.k8s.io/acme-http-token=1100680922
acme-challenge-service
リソースを作成します。- 先ほど取得した
acme-http-domain
とacme-http-token
を書き換えます。
- 先ほど取得した
apiVersion: v1 kind: Service metadata: name: acme-challenge-service annotations: getambassador.io/config: | --- apiVersion: ambassador/v1 kind: Mapping name: acme-challenge-mapping prefix: /.well-known/acme-challenge rewrite: "" service: acme-challenge-service spec: ports: - port: 80 targetPort: 8089 selector: certmanager.k8s.io/acme-http-domain: "161156668" #rewrite certmanager.k8s.io/acme-http-token: "1100680922" #rewrite
nginxにhttpsで通信出来てるかの確認
kubectl get svc ambassador
で EXTERNAL-IPを確認して設定したドメインに登録する<ドメイン名>/nginx/
にブラウザで接続するとhttps通信がされるようになりました。- httpで接続した際はhttpsにリダイレクトされます。
一通りやってみましたが、実施すべき事が多いですね。 消したり作ったりする場合は、クラスタ構築のパイプラインを作った方が良さそう。