[Kubernetes] cert-manager のアップグレード方法 (v0.12 to v1.5.5)

Kubernetes で Lets Encrypt の証明書更新を自動管理するために Certificate Management (cert-manager) を利用しています。Kubernetes および cert-manager が古くなってしまったので、まず cert-manager からアップグレードを試みます。

この cert-manager バージョンアップ作業は、次の記事の関連エントリとなります。

[GKE] Kubernetes を 1.18から1.22までアップグレードした記録
[GKE] Kubernetes を 1.18から1.22までアップグレードした記録
https://fand.jp/technologies/record-of-upgrading-gke-kubernetes-from-1-18-to-1-22/
GKE環境を 1.22 へバージョンアップをしたときの注意点や参考情報をまとめます。

参照ドキュメント

以下の cert-manager オフィシャルドキュメントを参照して情報整理しています。

cert-manager のインストールやアンインストールに関する情報:

kubectl apply

kubectl apply

Learn how to install cert-manager using kubectl and static manifests

cert-manager のサポート終了時期や Kubernetes の互換性に関する情報:

Supported Releases

Supported Releases

Supported releases, Kubernetes versions, OpenShift versions and upcoming release timeline

バージョン 1.4 で生じる非互換に関する情報:

Migrating Deprecated API Resources

Migrating Deprecated API Resources

cert-manager installation: Removal of deprecated APIs

cert-manager v1.5.4 を利用せずにスキップする周知情報:

Notes on the breaking change with the `class` field that happened in cert-manager v1.5.4

Notes on the breaking change with the `class` field that happened in cert-manager v1.5.4

cert-manager installation: Notes on ingress classes and safe upgrades

復習

cert-manager をどのようにセットアップしていたか。

https://cert-manager.io/docs/installation/kubectl/#installing-with-regular-manifests

マニフェストはサイト上にあるので、URLを直接指定して apply するだけの簡単な作業。

kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.8.0/cert-manager.yaml

cert-manager バージョンアップに関する重要事項の整理

今回、一気にアップグレードすることになるので、破壊的な変更(互換性がなくなる部分)を中心に確認していきます。

cert-manager のアップグレードの考え方

基本的な考え方はシンプルです。

Upgrading cert-manager

Upgrading cert-manager

cert-manager installation: Upgrading cert-manager overview

  • バージョンアップはひとつずつ(マイナーバージョンごとに)やっていくこと
  • 非互換に関する情報が度々あるので、Changelog はひとつずつ目を通したほうが良い
# インターネット上にあるマニフェスト(URL)を指定して apply してしまえばよい
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/${CERT_MANAGER_VERSION}/cert-manager.yaml

その他、やり方によってはあると望ましい知識

Cert Manager がサポートするバージョン

Supported Releases - cert-manager Documentation

2022/06/13現在のサポート情報。cert-manager v1.7 および v1.8 がサポートされている。なお、2022年7月には v1.9 がリリースされる様子。

Release Release Date End of Life Supported Kubernetes versions Supported OpenShift versions
1.8 Apr 05, 2022 Sep 07, 2022 1.19 → 1.24 4.6 → 4.11
1.7 Jan 26, 2022 Jul 06, 2022 1.18 → 1.23 4.5 → 4.10

なお、以下の表からも分かる通り、古いバージョンの cert-manager でも比較的新しい Kubernetes バージョンまで動いてくれるようです。

Release Release Date EOL Compatible Kubernetes versions Compatible OpenShift versions
1.6 Oct 26, 2021 Apr 05, 2022 1.17 → 1.22 4.4 → 4.9
1.5 Aug 11, 2021 Jan 26, 2022 1.16 → 1.22 4.3 → 4.8
1.4 Jun 15, 2021 Oct 26, 2021 1.16 → 1.21 4.3 → 4.7
1.3 Apr 08, 2021 Aug 11, 2021 1.16 → 1.21 4.3 → 4.7
1.2 Feb 10, 2021 Jun 15, 2021 1.16 → 1.21 4.3 → 4.7
1.1 Nov 24, 2020 Apr 08, 2021 1.11 → 1.21 3.11 → 4.7
1 Sep 02, 2020 Feb 10, 2021 1.11 → 1.21 3.11 → 4.7
0.16 Jul 23, 2020 Nov 24, 2020 1.11 → 1.21 3.11 → 4.7
0.15 May 06, 2020 Sep 02, 2020 1.11 → 1.21 3.11 → 4.7
0.14 Mar 11, 2020 Jul 23, 2020 1.11 → 1.21 3.11 → 4.7
0.13 Jan 21, 2020 May 06, 2020 1.11 → 1.21 3.11 → 4.7
0.12 Nov 27, 2019 Mar 11, 2020 1.11 → 1.21 3.11 → 4.7
0.11 Oct 10, 2019 Jan 21, 2020 1.9 → 1.21 3.09 → 4.7

cert-manager API の互換性非推奨になる部分

Kubectl apply - cert-manager Documentation

Migrating Deprecated API Resources

The following cert-manager APIs were deprecated in cert-manager v1.4:

  • cert-manager.io/v1alpha2
  • cert-manager.io/v1alpha3
  • cert-manager.io/v1beta1
  • acme.cert-manager.io/v1alpha2
  • acme.cert-manager.io/v1alpha3
  • acme.cert-manager.io/v1beta1

These APIs are no longer served in cert-manager 1.6 and are fully removed in cert-manager 1.7. If you have a cert-manager installation that is using or has previously used these deprecated APIs you might need to upgrade your cert-manager custom resources and CRDs. This should be done before upgrading to cert-manager 1.6 or later.

An earlier version of this document listed a number of kubectl commands to run to migrate resources. These steps have now been encoded in cmctl upgrade migrate-api-version command. If you have already run the kubectl commands, your resources should have been migrated and there should be no need to also run the cmctl command. However, if you are not sure, you can still run the cmctl command as well- it will be a no-op if no actions are needed.

Ingress との互換性

途中、特定のバージョンでのみ Ingress 関連で問題があったようです。対策は、対象バージョンを利用せずにスキップすればいいようなので、2022/06時点では神経質になる必要はなさそう。

Notes on Ingress Class Compatibility - cert-manager Documentation

Notes on Ingress Class Compatibility

In cert-manager v1.5.4 we made a change to the HTTP-01 code which was not backwards compatible. See  Regression: HTTP-01 challenges fail with Istio, Traefik, ingress-gce and Azure AGIC.

In v1.5.5, v1.6.2 and 1.7.1 we fixed this problem.

If you have cert-manager v1.5.3 (or below) you should skip v1.5.4 and instead:

  • upgrade to v1.5.5
  • then the newest version of cert-manager 1.6
  • and then the newest version of cert-manager 1.7

and you can ignore the rest of this document.

The following notes apply to anyone upgrading from cert-manager v1.5.4, v1.6.0, v1.6.1 on Kubernetes v1.19 or later.

cert-manager のバージョン整理

バージョンアップは、マイナーバージョンごとに1つずつ実施していくことが推奨されています。

We recommend that you upgrade cert-manager one minor version at a time, always choosing the latest patch version for the minor version.

Upgrading のページを見ていれば、アップグレードに関する作業的な目線では必要事項は抑えられているように見えますが、ときどき Release Notes で確認したほうがいい情報もあったため、両方をチェックしたほうがよさそうです。

From/to Latest (2022/6/12時点) Step(気になる点の抜粋) ドキュメント
v0.12 to v0.13 0.13.1 no special upgrade steps are required https://cert-manager.io/docs/installation/upgrading/upgrading-0.12-0.13
v0.13 to v0.14 0.14.3 Due to changes in the Deployment selector you will need to remove the deployments first before being able to upgrade. $ kubectl delete -n cert-manager deployment cert-manager cert-manager-cainjector cert-manager-webhook https://cert-manager.io/docs/installation/upgrading/upgrading-0.13-0.14
v0.14 to v0.15 0.15.2 Helmを使っているケース向けのアップデート。 installCRDs オプションができた等。 https://cert-manager.io/docs/installation/upgrading/upgrading-0.14-0.15/
v0.15 to v0.16 0.16.1 kubectl のバージョンが特定バージョンの時にエラーが出るという忠告がある。ほか、Helm の installCRDs オプションが必須。いずれも関係ない。 https://cert-manager.io/docs/installation/upgrading/upgrading-0.15-0.16
v0.16 to v1.0 1.0.4 The upgrade process for upgrading to v1.0 is very Kubernetes version specific. Kubernetes 1.16 以上であれば No Special requirements https://cert-manager.io/docs/installation/upgrading/upgrading-0.16-1.0#uninstall-cert-manager
v1.0 to v1.1 1.1.1 When upgrading from v1.0 to v1.1, no special upgrade steps are required 🎉
v1.1 to v1.2 1.2.0 In an effort to introduce new features whilst keeping the project maintainable, cert-manager now only supports Kubernetes down to version v1.16. This means the legacy manifests have now been removed. https://cert-manager.io/docs/installation/upgrading/upgrading-1.1-1.2
v1.2 to v1.3 1.3.3 This release updates the Venafi Cloud Issuer to use OutagePREDICT instead of DevOpsACCELERATE. The only impact to Venafi Cloud users is the change in zone syntax. あまり関係なさそう https://cert-manager.io/docs/installation/upgrading/upgrading-1.2-1.3
v1.3 to v1.4 1.4.4 Removal of the cert-manager operator package on Red Hat Marketplace. 全然関係ない https://cert-manager.io/docs/installation/upgrading/upgrading-1.3-1.4
v1.4 to v1.5 1.5.5 If you are currently using HTTP-01 challenges or the Ingress shim annotations, please read the Ingress class compatibility notes to see if your Ingress controller has any known issues with the migration to Ingress v1. 複数の特定バージョン(v1.5.4, v1.6.0, v1.6.1)にて問題があったようなので、バージョンアップステップが定められているのに注意。In v1.5.5, v1.6.2 and 1.7.1 we fixed this problem. If you intend to upgrade to Kubernetes 1.22, you must upgrade to cert-manager 1.5. https://cert-manager.io/docs/installation/upgrading/upgrading-1.4-1.5
v1.5 to v1.6 1.6.3 Following their deprecation in version 1.4, the cert-manager API versions v1alpha2, v1alpha3, and v1beta1 are no longer served. いままでv1alpha2を使っていたがいよいよ使わなくなる。 https://cert-manager.io/docs/installation/upgrading/upgrading-1.5-1.6
v1.6 to v1.7 1.7.2
v1.7 to v1.8 1.8.0

作業タイミングの都合で記事が別れていますが、 v1.5 から v1.8 へのアップグレードは次のページに記載しています。

Cert Manager アップグレード (v1.5 to v1.8)
Cert Manager アップグレード (v1.5 to v1.8)
https://fand.jp/upgrade-cert-manager-to-v-1-8/
Cert Manager を v1.5からv1.8へアップグレードします。

バックアップが必要な場合

クラスタ間のコピー等の場合ではバックアップやコピーが必要になりますが、以下のバックアップ手順を利用できます。但し、この記事では直接アップグレードで解決したためリストア手順を試すには至りませんでした。バックアップといってもコマンド一つですので、取得しておいて損はないでしょう。

Backup and Restore Resources

Backup and Restore Resources

cert-manager tutorials: Backing up your cert-manager installation

構成バックアップコマンド

# バックアップ
kubectl get --all-namespaces -oyaml issuer,clusterissuer,cert > backup.yaml

# リストア手段も書いてあるが試していない。詳細はドキュメント参照
kubectl apply -f <(awk '!/^ *(resourceVersion|uid): [^ ]+$/' backup.yaml)

1.0 Release 関連を見て学んだこと

We have released our cert-manager.io/v1 API that replaces cert-manager.io/v1alpha2. Since the legacy version for Kubernetes 1.15 and below only supports one CRD version you have to transition all resources to cert-manager.io/v1.
This makes for a fairly significant breaking change for users, as all cert-manager resources will need to be updated to reflect these changes. Ingress annotations will stay the same, this means if you only use ingress-shim you do not have to convert these resources over but it is recommended. However you should convert the (Cluster)Issuers and delete the old CRD versions.

Kubernetes 1.16 移行ならばCRDのバージョンを複数有することができるので、cert-manager のマニフェストを急いで修正する必要はないが、Kubernetes 1.15以下の場合はひとつのCRDしか持てないので、このタイミングで全てのCert Manager マニフェストを書き換える必要がある。

作業内容

v0.12 から v1.5 まで、1つずつ一気にアップグレードしました。

v0.13 to v0.14 でのみ Deployment を削除する操作が必要でしたが、それ以外は Apply のみでどんどん進んで楽でした。

# 基本的なアップグレード作業
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.8.0/cert-manager.yaml

# v0.13 to v0.14 でのみ必要だったこと
kubectl delete -n cert-manager deployment cert-manager cert-manager-cainjector cert-manager-webhook

v1.5.5 までアップグレードを終えたところで、次のバージョンからは v1aplha が使えなくなるので、Certificate のマニフェストを一通り修正して再デプロイしてから臨むことにします。

なお、v1.5 まで終えた時点で、以下の通り v1alpha2 でデプロイしていたリソース(Lets encrypt でサイト証明書を多数作成している)が一通り cert-manager.io/v1 に変わっている、かつもともとデプロイしていた古いマニフェストは kubectl.kubernetes.io/last-applied-configuration の値としてJSONデータがあるので、保持してくれているようです(この辺、アップグレード時の挙動の理解不足)

❯ kubectl get --all-namespaces -oyaml issuer,clusterissuer,cert | grep apiVersion

apiVersion: v1
- apiVersion: cert-manager.io/v1
        {"apiVersion":"cert-manager.io/v1alpha2","kind":"ClusterIssuer","metadata":{"annotations":...
- apiVersion: cert-manager.io/v1
        {"apiVersion":"cert-manager.io/v1alpha2","kind":"ClusterIssuer","metadata":{"annotations":...
- apiVersion: cert-manager.io/v1
        {"apiVersion":"cert-manager.io/v1alpha2","kind":"Certificate","metadata":{"annotations":...

# grep の都合で kubectl.kubernetes.io/last-applied-configuration は見えないが、JSON部分がそれ

アップグレード作業の実行例

ここまで整理情報をもとに、あとは kubectl apply -f ...yml を繰り返していくだけなので退屈な作業となります。全体的に問題が起きることはなく順調でしたので、ここでは 0.16 から 1.0 へアップグレード作業ログを参考として記載します。若干長いログですが特別有益な情報はないので、「作業はこんな感じなのね」程度に参照してください。

$ kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.0.4/cert-manager.yaml
customresourcedefinition.apiextensions.k8s.io/certificaterequests.cert-manager.io configured
customresourcedefinition.apiextensions.k8s.io/certificates.cert-manager.io configured
customresourcedefinition.apiextensions.k8s.io/challenges.acme.cert-manager.io configured
customresourcedefinition.apiextensions.k8s.io/clusterissuers.cert-manager.io configured
customresourcedefinition.apiextensions.k8s.io/issuers.cert-manager.io configured
customresourcedefinition.apiextensions.k8s.io/orders.acme.cert-manager.io configured
namespace/cert-manager unchanged
serviceaccount/cert-manager-cainjector configured
serviceaccount/cert-manager configured
serviceaccount/cert-manager-webhook configured
clusterrole.rbac.authorization.k8s.io/cert-manager-cainjector configured
clusterrole.rbac.authorization.k8s.io/cert-manager-controller-issuers configured
clusterrole.rbac.authorization.k8s.io/cert-manager-controller-clusterissuers configured
clusterrole.rbac.authorization.k8s.io/cert-manager-controller-certificates configured
clusterrole.rbac.authorization.k8s.io/cert-manager-controller-orders configured
clusterrole.rbac.authorization.k8s.io/cert-manager-controller-challenges configured
clusterrole.rbac.authorization.k8s.io/cert-manager-controller-ingress-shim configured
clusterrole.rbac.authorization.k8s.io/cert-manager-view configured
clusterrole.rbac.authorization.k8s.io/cert-manager-edit configured
clusterrolebinding.rbac.authorization.k8s.io/cert-manager-cainjector configured
clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-issuers configured
clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-clusterissuers configured
clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-certificates configured
clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-orders configured
clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-challenges configured
clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-ingress-shim configured
role.rbac.authorization.k8s.io/cert-manager-cainjector:leaderelection configured
role.rbac.authorization.k8s.io/cert-manager:leaderelection configured
role.rbac.authorization.k8s.io/cert-manager-webhook:dynamic-serving configured
rolebinding.rbac.authorization.k8s.io/cert-manager-cainjector:leaderelection configured
rolebinding.rbac.authorization.k8s.io/cert-manager:leaderelection configured
rolebinding.rbac.authorization.k8s.io/cert-manager-webhook:dynamic-serving configured
service/cert-manager configured
service/cert-manager-webhook configured
deployment.apps/cert-manager-cainjector configured
deployment.apps/cert-manager configured
deployment.apps/cert-manager-webhook configured
mutatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook configured
validatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook configured
$ kubectl -n cert-manager get -f https://github.com/cert-manager/cert-manager/releases/download/v1.0.4/cert-manager.yaml
NAME                                                                                CREATED AT
customresourcedefinition.apiextensions.k8s.io/certificaterequests.cert-manager.io   2020-01-17T09:28:41Z
customresourcedefinition.apiextensions.k8s.io/certificates.cert-manager.io          2020-01-17T09:28:42Z
customresourcedefinition.apiextensions.k8s.io/challenges.acme.cert-manager.io       2020-01-17T09:28:42Z
customresourcedefinition.apiextensions.k8s.io/clusterissuers.cert-manager.io        2020-01-17T09:28:43Z
customresourcedefinition.apiextensions.k8s.io/issuers.cert-manager.io               2020-01-17T09:28:44Z
customresourcedefinition.apiextensions.k8s.io/orders.acme.cert-manager.io           2020-01-17T09:28:44Z

NAME                     STATUS   AGE
namespace/cert-manager   Active   2y147d

NAME                                     SECRETS   AGE
serviceaccount/cert-manager-cainjector   1         2y147d
serviceaccount/cert-manager              1         2y147d
serviceaccount/cert-manager-webhook      1         2y147d

NAME                                                                           CREATED AT
clusterrole.rbac.authorization.k8s.io/cert-manager-cainjector                  2020-01-17T09:28:45Z
clusterrole.rbac.authorization.k8s.io/cert-manager-controller-issuers          2020-01-17T09:28:48Z
clusterrole.rbac.authorization.k8s.io/cert-manager-controller-clusterissuers   2020-01-17T09:28:48Z
clusterrole.rbac.authorization.k8s.io/cert-manager-controller-certificates     2020-01-17T09:28:48Z
clusterrole.rbac.authorization.k8s.io/cert-manager-controller-orders           2020-01-17T09:28:48Z
clusterrole.rbac.authorization.k8s.io/cert-manager-controller-challenges       2020-01-17T09:28:49Z
clusterrole.rbac.authorization.k8s.io/cert-manager-controller-ingress-shim     2020-01-17T09:28:49Z
clusterrole.rbac.authorization.k8s.io/cert-manager-view                        2020-01-17T09:28:50Z
clusterrole.rbac.authorization.k8s.io/cert-manager-edit                        2020-01-17T09:28:50Z

NAME                                                                                  ROLE                                                 AGE
clusterrolebinding.rbac.authorization.k8s.io/cert-manager-cainjector                  ClusterRole/cert-manager-cainjector                  2y147d
clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-issuers          ClusterRole/cert-manager-controller-issuers          2y147d
clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-clusterissuers   ClusterRole/cert-manager-controller-clusterissuers   2y147d
clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-certificates     ClusterRole/cert-manager-controller-certificates     2y147d
clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-orders           ClusterRole/cert-manager-controller-orders           2y147d
clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-challenges       ClusterRole/cert-manager-controller-challenges       2y147d
clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-ingress-shim     ClusterRole/cert-manager-controller-ingress-shim     2y147d

NAME                                                                  CREATED AT
role.rbac.authorization.k8s.io/cert-manager-webhook:dynamic-serving   2022-06-12T14:08:07Z

NAME                                                                         ROLE                                        AGE
rolebinding.rbac.authorization.k8s.io/cert-manager-webhook:dynamic-serving   Role/cert-manager-webhook:dynamic-serving   32m

NAME                           TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
service/cert-manager           ClusterIP   10.0.12.214   <none>        9402/TCP   2y147d
service/cert-manager-webhook   ClusterIP   10.0.15.67    <none>        443/TCP    2y147d

NAME                                      READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/cert-manager-cainjector   1/1     1            1           41m
deployment.apps/cert-manager              1/1     1            1           41m
deployment.apps/cert-manager-webhook      1/1     1            1           41m

NAME                                                                             WEBHOOKS   AGE
mutatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook   1          2y147d

NAME                                                                               WEBHOOKS   AGE
validatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook   1          2y147d
❯ kubectl get -n cert-manager pod
NAME                                      READY   STATUS    RESTARTS   AGE
cert-manager-6cd8cb4b7c-2xlm5             1/1     Running   0          3m8s
cert-manager-cainjector-685b87b86-2fx2p   1/1     Running   0          3m8s
cert-manager-webhook-76978fbd4c-8ss5h     1/1     Running   0          3m7s

まとめ

この記事では cert-manager のアップグレード作業に関する必要情報を記載しました。Changelog を読むのは大事なのとあわせて、Kubernetes のバージョン変化に関する知識も補完できるので、手間ですが大事な作業だと感じました。