shibatch's journey

日々考えていることをつらつら書くだけです

Kubernetesでcert-managerを利用したときにつまづいたこと2点

昨日から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 

とりあえずこれで参照できるようになったよというメモ。