昨日からKubernetesのcert-managerと戦っている。Let's Encryptをプライベートクラウド上で動かしたい。
cert-manager.io
実施するにあたり以下のQiitaの記事がとても役にたった…ありがとうございます。
Ingress Controllerはnginx controllerを使ったのでそこは読み替えたが、おおむね書いてある通りにやりました。
Kubernetes cert-managerでRoute53で作成したドメインの証明書を作成し、Ingressで利用する。 - Qiita
さてcert-managerではDNSとHTTPの2種類のチャレンジを使うことができるのだが、自分はDNSの形式で、Route53を使って認証する方法を使った。
Route53 - cert-manager Documentation
ほぼ↑に書いてある通りだったのだが、2点つまづいたことを書く。
まずAWSでIAMポリシーを作る必要があるのだが、手順では以下のように書いてある
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "route53:GetChange",
"Resource": "arn:aws:route53:::change/*"
},
{
"Effect": "Allow",
"Action": [
"route53:ChangeResourceRecordSets",
"route53:ListResourceRecordSets"
],
"Resource": "arn:aws:route53:::hostedzone/*"
},
{
"Effect": "Allow",
"Action": "route53:ListHostedZonesByName",
"Resource": "*"
}
]
}
Note: The route53:ListHostedZonesByName statement can be removed if you specify the (optional) hostedZoneID. You can further tighten the policy by limiting the hosted zone that cert-manager has access to (e.g. arn:aws:route53:::hostedzone/DIKER8JEXAMPLE).
つまりIAMポリシーの以下の部分は無くしても、zoneをちゃんと指定したら動くとのことだ。
{
"Effect": "Allow",
"Action": "route53:ListHostedZonesByName",
"Resource": "*"
}
まぁポリシーなんて動くなら狭いに越したことはないので、ドキュメント通りにこの段落は消した。
そしてIssuerをデプロイしたらchallengeリソースで権限周りでこけてしまった
% k describe challenge hogehoge-jp-tls-z8w44-2448885068-2094531131
<snip>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Started 3m12s cert-manager-challenges Challenge scheduled for processing
Warning PresentError 44s (x6 over 3m11s) cert-manager-challenges Error presenting challenge: failed to determine Route 53 hosted zone ID: AccessDenied: User: arn:aws:iam::XXXXXXX:user/hogehoge is not authorized to perform: route53:ListHostedZonesByName because no identity-based policy allows the route53:ListHostedZonesByName action
これは単に私のIssuerの設定漏れで、hostdZoneIDにRoute53のZoneIDを付与したら先に進んだ。
- dns01:
route53:
region: ap-northeast-1
+ hostedZoneID: AAAAAAAAAAAA
accessKeyID: XXXXXXXXXXXXXXXXXXX
secretAccessKeySecretRef:
name: secret
ところが次はchalengeがpending状態で止まってしまった。
% k describe challenge hogehoge-jp-tls-z8w44-2448885068-2094531131
<snip>
Reason: Waiting for DNS-01 challenge propagation: DNS record for "example.com" not yet propagated
これは以下の事象に当てはまったようだった。
https://cert-manager.io/docs/configuration/acme/dns01/#setting-nameservers-for-dns01-self-check
つまり、cert-managerはRoute53へTXTレコードを埋め込んだ後それが引けるかを確認する際、/etc/resolf.conf
の内容をみて権威ネームサーバを参照するようだが、これがうまくいっていないらしい。その原因までは掴めなかったのだが、cert-managerの環境変数でパブリックDNSを指定したらうまくいった。
spec:
containers:
- args:
- --v=2
- --cluster-resource-namespace=$(POD_NAMESPACE)
- --leader-election-namespace=kube-system
+ - --dns01-recursive-nameservers-only
+ - --dns01-recursive-nameservers=8.8.8.8:53,1.1.1.1:53
とりあえずこれで参照できるようになったよというメモ。