公式の以下手順で、Let's Encryptを使ったTLS証明書付きのIngress Controllerを作成しました。
Azure Kubernetes Service (AKS) の静的パブリック IP アドレスを使用してイングレス コントローラーを作成する
バックエンドのWebサーバコンテナにインターネットからアクセスする際に、アクセス元IPアドレスを絞りたいと思ったのですが、中々うまくいかずハマったので手順残します。
自分で作ったvNetにデプロイしたAKSを使っています。
Ingress Controller作成
- Ingress Controllerを作成します。ここがポイントで、「--set controller.service.externalTrafficPolicy=Local」を付与しないと、Ingress Controllerが受信するアクセス元のソースIPが、グローバルアドレスではなくvNetのIPになってしまいうまくIP制御できません。
helm install stable/nginx-ingress \
--namespace [Your Namespace] \
--set controller.service.loadBalancerIP="[Public IP]" \
--set controller.replicaCount=2
--set controller.service.externalTrafficPolicy=Local
DNS名を構成する
- ここは公式通りです。以下のShellを作成して実行します。
#!/bin/bash
# Public IP address of your ingress controller
IP="[Public IP]"
# Name to associate with public IP address
DNSNAME="[Your DNS Name]"
# Get the resource-id of the public ip
PUBLICIPID=$(az network public-ip list --query "[?ipAddress!=null]|[?contains(ipAddress, '$IP')].[id]" --output tsv)
# Update public ip address with DNS name
az network public-ip update --ids $PUBLICIPID --dns-name $DNSNAME
cert-manager をインストールする
- ここは公式通りです。kube-systemネームスペースに作ります。
helm install stable/cert-manager \
--namespace kube-system \
--set ingressShim.defaultIssuerName=letsencrypt-prod \
--set ingressShim.defaultIssuerKind=ClusterIssuer
CAクラスター発行者を作成する
- ここは公式通りです。yamlを作ってapplyします。kube-systemネームスペースに作ります。
cluster-issuer.yaml
apiVersion: certmanager.k8s.io/v1alpha1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-staging-v02.api.letsencrypt.org/directory
email: user@contoso.com
privateKeySecretRef:
name: letsencrypt-prod
http01: {}
kubectl apply -f cluster-issuer.yaml -n kube-system
証明書オブジェクトを作成する
- ここは公式通りです。yamlを作ってapplyします。
certificates.yaml
apiVersion: certmanager.k8s.io/v1alpha1
kind: Certificate
metadata:
name: tls-secret
spec:
secretName: tls-secret
dnsNames:
- [Your DNS Name].japaneast.cloudapp.azure.com
acme:
config:
- http01:
ingressClass: nginx
domains:
- [Your DNS Name].japaneast.cloudapp.azure.com
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
kubectl apply -f certificates.yaml -n [Your Namespace]
アプリケーションを実行する
- バックエンドのWebアプリケーションを実行します。公式手順にあるデモアプリケーションでもよいです。
Ingressルートを作成する
- Ingressルートを作成する際のマニフェストで、アノテーション「nginx.ingress.kubernetes.io/whitelist-source-range」を付与して作成します。
application.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: hello-world-ingress
annotations:
kubernetes.io/ingress.class: nginx
certmanager.k8s.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/whitelist-source-range: xxx.xxx.xxx.xxx/32,yyy.yyy.yyy.yyy/32
spec:
tls:
- hosts:
- [Your DNS Name].japaneast.cloudapp.azure.com
secretName: tls-secret
rules:
- host: [Your DNS Name].japaneast.cloudapp.azure.com
http:
paths:
- path: /
backend:
serviceName: aks-helloworld
servicePort: 80
- path: /hello-world-two
backend:
serviceName: ingress-demo
servicePort: 80
kubectl apply -f application.yaml -n [Your Namespace]
テスト
https://[Your DNS Name].japaneast.cloudapp.azure.com にアクセスして、TLS証明書とIPアドレス制御が動作していることを確認します。