悲しいことにこの記事を書いている時点(2018/02/08)ですでにkube-legoはDEPRECATEDな状態。
kube-lego is in maintenance mode only. There is no plan to support any new features. The latest Kubernetes release that kube-lego officially supports is 1.8. The officially endorsed successor is cert-manager.
Kubernetes1.8までしか正式にはサポートせず、cert-managerに引き継がれる模様。
1.9はすでにリリースされていて、ちょうど今日GKEも全リージョン1.9対応が完了済み ![]()
なので自分自身この構成で運用はすることなく終わるけど一応できたことのメモ。
基本的にHelmを使う。
やりたかったこと
NGINX Ingress Controllerを使うと、
各IngressでそのコントローラのService(type: LoadBalancer)を共有する形になり、GKEでいうとTCP LoadBalancerを共有し、IPも同じになる模様。
(それによるデメリットがどれほどかは明確にわかってない)
それを避けるために、複数のNGINX Ingress Controllerをデプロイする方法と、
そのとき苦戦したkube-lego側の設定のメモ。
環境
- Host: GKE
- Master version/Node version: 1.8.5-gke.0
- Helm: v2.8.0
- chart: stable/nginx-ingress:0.9.1
- chart: stable/kube-lego:0.4.0
- image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.10.2
- image: jetstack/kube-lego:master-3418 (後述)
構成
-
NGINX Ingress Controller
- namespace:
ingress-nginx
- namespace:
-
kube-lego
- namespace:
kube-lego
- namespace:
-
通常の系統
-
nginx-ingress/kube-lego
-
-
別系統(社内用系統なイメージ)
-
nginx-ingress-inhouse/kube-lego-inhouse
-
手順
(helmのセットアップ手順は省略)
namespace作成
# ingress-nginx
curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/namespace.yaml \
| kubectl apply -f -
# kube-lego
curl https://raw.githubusercontent.com/jetstack/kube-lego/master/examples/nginx/lego/00-namespace.yaml \
| kubectl apply -f -
必須ではないけど、公式の命名に準じる。
nginx-ingressのセットアップ
helm install stable/nginx-ingress \
--name nginx-ingress \
--namespace ingress-nginx \
--set controller.replicaCount=2
replicaCount は任意で。
nginx-ingress-inhouseのセットアップ
helm install stable/nginx-ingress \
--name nginx-ingress-inhouse \
--namespace ingress-nginx \
--set controller.ingressClass=nginx-inhouse \
--set controller.replicaCount=2
ingressClass をデフォルトのnginxとは別名に指定する。
kube-legoのセットアップ
helm install stable/kube-lego \
--name kube-lego \
--namespace kube-lego \
--set image.tag=master-3418 \
--set config.LEGO_LOG_LEVEL=debug \
--set config.LEGO_EMAIL=email@example.com \
--set config.LEGO_URL=https://acme-v01.api.letsencrypt.org/directory
LEGO_LOG_LEVEL は任意で。
LEGO_EMAIL は自分のものに要変更。
LEGO_URL はまず指定せずにセットアップを検証してから(staging用apiになる)、本番用apiで構築する。
image.tag=master-3418 は後述。
kube-legoinhouseのセットアップ
helm install stable/kube-lego \
--name kube-lego-inhouse \
--namespace kube-lego \
--set nameOverride=kube-lego-inhouse \
--set image.tag=master-3418 \
--set config.LEGO_LOG_LEVEL=debug \
--set config.LEGO_EMAIL=email@example.com \
--set config.LEGO_URL=https://acme-v01.api.letsencrypt.org/directory \
--set config.LEGO_SUPPORTED_INGRESS_CLASS=nginx-inhouse \
--set config.LEGO_DEFAULT_INGRESS_CLASS=nginx-inhouse \
--set config.LEGO_DEFAULT_INGRESS_PROVIDER=nginx \
--set config.LEGO_SECRET_NAME=kube-lego-inhouse-account \
--set config.LEGO_SERVICE_NAME_NGINX=kube-lego-inhouse-nginx \
--set config.LEGO_INGRESS_NAME_NGINX=kube-lego-inhouse-nginx
--set config.LEGO_SERVICE_SELECTOR=kube-lego-inhouse \
LEGO_SUPPORTED_INGRESS_CLASS で nginx-inhouse ingress classを対象に取るように変更。
LEGO_DEFAULT_INGRESS_CLASS, LEGO_DEFAULT_INGRESS_PROVIDER は、kube-legoがACMEチャレンジのパス用に生成するingressの kubernetes.io/ingress.class, kubernetes.io/ingress.provider annotationの値に使われる。
LEGO_SECRET_NAME, LEGO_SERVICE_NAME_NGINX, LEGO_INGRESS_NAME_NGINX はkube-legoが生成するリソースの名前を主系統と重複させないために設定。
LEGO_SERVICE_SELECTORも、主系統用とは別に設定。
苦戦したのが、これらのうち LEGO_DEFAULT_INGRESS_PROVIDER などの項目が、helmがデフォルトで参照する jetstack/kube-lego:0.1.5 イメージではまだ対応していない点。
最新バージョンのイメージを使うために https://hub.docker.com/r/jetstack/kube-lego/tags/ を参照しつつ最新の image.tag=master-3418 (2018/02/08時点)を指定。
nginx-ingress系統にingress追加
例
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: web-nginx
namespace: default
annotations:
kubernetes.io/ingress.class: nginx
kubernetes.io/tls-acme: "true"
spec:
rules:
- host: example.com
http:
paths:
- path: /
backend:
serviceName: web
servicePort: 80
tls:
- hosts:
- example.com
secretName: web-tls
name, namespace, serviceName, servicePort, secretName などは適宜命名。
example.com は要変更。
kubernetes.io/ingress.classがnginxなので主系統のnginx-ingress, kube-legoが捕捉して処理される。
nginx-ingress-inhouse系統にingress追加
例
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: admin-nginx-inhouse
namespace: default
annotations:
kubernetes.io/ingress.class: nginx-inhouse
kubernetes.io/ingress.provider: nginx
kubernetes.io/tls-acme: "true"
spec:
rules:
- host: admin.example.com
http:
paths:
- path: /
backend:
serviceName: admin-service
servicePort: 80
tls:
- hosts:
- admin.example.com
secretName: admin-tls
kubernetes.io/ingress.classがnginx-inhouseなのでnginx-ingress-inhouse, kube-lego-inhouseに捕捉される。
嵌ったのが、 kubernetes.io/ingress.provider: nginx を指定しないと、ingress.classがprovider名としても適用され、結果としてkube-legoのnginx providerの処理にのらず
disable provider no TLS hosts found
と出てkube-legoが動作してくれなかった。
(ソースコード的にはこのあたり。provider名での分岐に入ってくれない)
おわり
annotation.kubernetes.io/ingress.provider が鍵。
且つそれがlatestイメージではサポートされていない罠。
そしていずれにせよDEPRECATEDな悲しみ。
次はcert-managerの方を調べる。