初めに
GKE(Google Kubernetes Engine)にcert-managerで無料SSL証明書を用意し、nginx-ingressでWEBアプリをドメイン指定にてルーティング表示するデプロイ環境の構築を行いたい。
順に実行すれば構築が完了出来る様に各コマンドラインの具体例を紹介する。
サンプルアプリとしてデフォルトのnginxコンテナを立ち上げ、SSL接続によるWelcome画面の表示をゴールとする。
前提
- GCPアカウントや対象プロジェクトを作成済み
- コマンドライン環境(gcloudやkubectl)をローカル導入済み
- GCPプロジェクトがコマンドラインから実行可能な状態である(アカウント操作認証済み)
- Helmをローカル環境に導入済み
- 独自ドメインを取得しレジストラの管理画面からDNS設定(Aレコード)が設定可能な状態
1) GKEクラスタ作成
% gcloud container clusters create example-cluster --machine-type=g1-small --num-nodes=1 --disk-size 10 --zone asia-northeast1-a
2)nginx-ingress導入
# 固定IP取得
% gcloud compute addresses create example-cluster-ip --region asia-northeast1
# tillerサービスアカウント
% kubectl create serviceaccount tiller --namespace kube-system
# tillerアカウントにcluster-adminの権限をバインドする(与える)
% kubectl create clusterrolebinding tiller-binding --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
# Tiller(helmのサーバサイドのサービス群)をデプロイする
% helm init --upgrade --service-account tiller
# nginx-ingressインストール (controller.publishService.enabled設定でingressが同一IPアドレスを向く)
% helm install stable/nginx-ingress --name nginx-ingress --namespace kube-system --set rbac.create=true --set controller.publishService.enabled=true
# 取得した固定IPを確認
# 独自ドメインのAレコードにも設定
% gcloud compute addresses list | grep example-cluster-ip
# 固定IP指定
% kubectl edit svc nginx-ingress-controller --namespace=kube-system
# type: LoadBalancer の直下に下記を追加する
loadBalancerIP: "取得した固定IP"
GCP管理画面のGKEのクラスタ、ワークロード、services(各システムオブジェクト含む)のステータスが全てOKで有る事を確認出来たら次へ進む。
3) depoyment, service, ingressを設定する。
- デフォルトのnginxコンテナを用意
nginx-deployment.yml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx
labels:
name: nginx
spec:
replicas: 3
template:
metadata:
labels:
name: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
resources:
requests:
cpu: 10m
nginx-service.yml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
labels:
name: nginx-service
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
name: nginx
type: NodePort
selector:
name: nginx
- 一旦非SSL版で用意
nginx-ingress.yml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
name: nginx-ingress
spec:
rules:
- host: example.com # 以降、自分で取得したドメインに読み替えて下さい
http:
paths:
- backend:
serviceName: nginx-service
servicePort: 80
path: /
kubectl apply -f nginx-deployment.yml
kubectl apply -f nginx-service.yml
kubectl apply -f nginx-ingress.yml
ブラウザでhttp://example.com
に接続し非SSL接続でnginx welcome画面が表示される所まで確認する。
4) cert-manager導入
# namespace作成
% kubectl create namespace cert-manager
% kubectl label namespace cert-manager certmanager.k8s.io/disable-validation=true
# cert-manager Helm chart
% kubectl apply -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.10/deploy/manifests/00-crds.yaml
# リポジトリ追加
% helm repo add jetstack https://charts.jetstack.io
% helm repo update
# インストール
% helm install --name cert-manager --namespace cert-manager --version v0.10.1 jetstack/cert-manager
5) SSL証明書導入
cluster-issuer.yml
apiVersion: certmanager.k8s.io/v1alpha1
kind: ClusterIssuer
metadata:
name: letsencrypt-prd
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory # 本番なので失敗時の利用制限に注意
email: 'yourmail@example.com' # 自分のメアド
privateKeySecretRef:
name: letsencrypt-prd
http01: {}
certificate.yml
apiVersion: certmanager.k8s.io/v1alpha1
kind: Certificate
metadata:
name: example-com-tls # 証明書を格納するSecretにつける名前(ドメイン-tls等)
namespace: default
spec:
secretName: example-com-tls # 証明書を格納するSecretにつける名前
issuerRef:
name: letsencrypt-prd
kind: ClusterIssuer
commonName: example.com # ドメイン
dnsNames:
- example.com
acme:
config:
- http01:
ingress: nginx-ingress # 使用しているIngressの名前
domains:
- example.com
kubectl apply -f cluster-issuer.yml
kubectl apply -f certificate.yml
- 証明書の取得状況を確認
kubectl describe -f certificate.yml
Certificate issued successfully
などと表示されれば取得完了。
6) ingressを再設定
- SSL対応版
nginx-ingress.yml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "true" # 要件に応じて任意
name: nginx-ingress
spec:
tls:
- secretName: example-com-tls
hosts:
- example.com
rules:
- host: example.com
http:
paths:
- backend:
serviceName: nginx-service
servicePort: 80
path: /
kubectl apply -f nginx-ingress.yml
再度ブラウザでhttps://example.com
にアクセスしSSL接続でnginxのwelcome画面が表示されている事を確認出来れば成功!
参考
GKEでなるべく安くKubernetesクラスタを作成してPrometheus + Grafanaを使ってみる Part2