IBM Cloud Secrets ManagerでIKS/ROKSのIngress Subdomain証明書を管理する

久しぶりの投稿です。GWに検証した内容を備忘録としてまとめました。

| 修正日 | 修正箇所 |
----|---- 
| 2022/5/24 | Step 1. に関してNoteを追加 |


# はじめに
IBM Cloudのコンテナ基盤サービスであるIKS/ROKS(OpenShift)に対し、Ingress Subdomain (xxxx.jp-tok.containers.appdomain.cloudのようなドメイン)が提供されます。
このドメインを利用してアプリを公開したり、ROKSの場合はコンソール画面にアクセスできるようになっています。

このIngress Subdomainには、Let's Encrypt発行の証明書が合わせて自動で発行されていまして、デフォルトでCertificate Managerと呼ばれる証明書管理サービスで管理されます。

・・・で、ここからが今回の記事をまとめたモチベーションですが、このCertificate Managerは2022年2月にDeprecatedが発表されました。要は今後利用できなくなるということです。

https://cloud.ibm.com/docs/certificate-manager?topic=certificate-manager-release-notes

後継のIBM Cloudサービスとして、Secrets Managerと呼ばれるサービスが指定されています。IKS/ROKSにおいても2022年4月より証明書管理はCertificate ManagerからSecrets Managerに移行するためのガイドが記載されています(注: 執筆時点では未翻訳なので英語で確認してください)。

https://cloud.ibm.com/docs/containers?topic=containers-ingress-types#migrate-secrets-mgr

上記手順になぞっていけばできますが、実際にどういう切り替え手順になるかを記載していきます。


# Secrets Managerへの移行手順
実際にここから以降のステップを記載します。GUIでは全ての操作ができないため、ibmcloud CLIでの操作を前提とします。また、IKS/ROKSに持ち込みのドメインを利用していない場合を前提とします。

## 検証環境
今回はROKS (Red Hat OpenShift on IBM Cloud) サービスで検証しました。バージョンは4.9.28_1534で、VPCベースのクラスターで試しています。

IKS (IBM Cloud Kubernetes Service) でも原則対応自体は変わらないですので、今回の手順は参考になると思います。

クラスター名が「test」というクラスターがあるものとします。また、対象となるIngress Domainは「test-4437b16c19b7f9ed01f38b8be3c782d0-i000.jp-tok.containers.appdomain.cloud」のみであるとします。

```
% ibmcloud oc clusters
OK
名前     ID                     状態     作成日       ワーカー   ロケーション   バージョン              リソース・グループ名   プロバイダー   
test   c9qbu8at0n6b6m1ogg8g   normal   1 hour ago   2          Tokyo          4.9.25_1534_openshift   test0711               vpc-gen2  
```

また、周辺サービスとして以下があるものとします。「kube-certmgr-」で始まる名前のサービスが切り替え対象のCertificate Manager、「Secrets Manager-」で始まるサービスがSecrets Managerになります。

```
% ibmcloud resource service-instances 
xxxx@gmail.com としてアカウント xxxxxxxx の すべての場所 で すべてのリソース・グループ 内の タイプ service_instance のインスタンスを取得しています...
OK
名前                                ロケーション   状態     タイプ             リソース・グループ ID    
:
Secrets Manager-test                jp-tok         active   service_instance   96393b7ca2184f1cb3ee1fd51983447b   
kube-certmgr-c9qbu8at0n6b6m1ogg8g   jp-tok         active   service_instance   96393b7ca2184f1cb3ee1fd51983447b
:
```

Secrets ManagerはROKS/IKSとは別にオーダーしておきます。今回は検証のため、無料プランのTrialプランで構成しています。

```
% ibmcloud resource service-instance "Secrets Manager-test"
xxxx@gmail.com としてアカウント xxxxxxxx の すべてのリソース・グループ のサービス・インスタンス Secrets Manager-test を取得しています...
OK
                           
名前:                   Secrets Manager-test   
ID:                     crn:v1:bluemix:public:secrets-manager:jp-tok:a/yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy:a4b59295-cfb8-4f5d-92c2-0ae075c0ca2e::   
GUID:                   a4b59295-cfb8-4f5d-92c2-0ae075c0ca2e   
場所:                   jp-tok   
サービス名:             secrets-manager   
サービス・プラン名:     trial   
リソース・グループ名:   mygrp   
状態:                   active   
:
```

## Step 1. 証明書管理の状態確認
2022年5月の時点では、どのようにROKS/IKSをオーダーしても、cloudcerts (Certificate Manager)での管理がデフォルトになっています。以下のような出力になっていることを確認します。

```
% ibmcloud ks ingress instance ls --cluster test
OK
名前                                タイプ       Is Default   状況      CRN   
kube-certmgr-c9qbu8at0n6b6m1ogg8g   cloudcerts   true         created   crn:v1:bluemix:public:cloudcerts:jp-tok:a/yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy:c179bfae-069e-4a63-bece-f770b30e80a6::
```

:::note info
本手順を実施いただいた際に、Step 1.の時点で何も表示されないケースがある点情報いただきました。何も表示されない場合もStep 2.に進めることは可能です。
```
% ibmcloud ks ingress instance ls --cluster test
OK
名前                                タイプ       Is Default   状況      CRN 
```
:::


## Step 2. Secrets Managerの登録 & デフォルト設定
Secrets ManagerのID (CRN)を指定し、IKS/ROKSクラスターにSecrets Managerを登録します。その際にSecrets Managerがデフォルトとなるように「--is-default」フラグを設定します。

```
% ibmcloud ks ingress instance register --cluster test --is-default --crn crn:v1:bluemix:public:secrets-manager:jp-tok:a/yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy:a4b59295-cfb8-4f5d-92c2-0ae075c0ca2e::
OK
```

実行したら、Secrets Managerに対し、Is Defaultのフラグが「true」になっていることを確認します。

```
% ibmcloud ks ingress instance ls --cluster test  
OK
名前                                タイプ            Is Default   状況      CRN   
kube-certmgr-c9qbu8at0n6b6m1ogg8g   cloudcerts        false        created   crn:v1:bluemix:public:cloudcerts:jp-tok:a/yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy:c179bfae-069e-4a63-bece-f770b30e80a6::   
secrets-manager-test                secrets-manager   true         created   crn:v1:bluemix:public:secrets-manager:jp-tok:a/yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy:a4b59295-cfb8-4f5d-92c2-0ae075c0ca2e::
```

## Step 3. 証明書の再発行
Ingress Subdomainの証明書に関しては、現在使用している証明書から新しく再発行し直す必要があります。

まずは証明書がCertificate Manager上にあることを確認します。CRNが「crn:v1:bluemix:public:cloudcerts:」から始まっていることより、Certificate Manager上で管理されているものと判断できます。

```
% ibmcloud ks ingress secret ls --cluster test
OK
名前                                         名前空間            CRN                                                                                                                                                            有効期限                   ドメイン                                                                       状況      タイプ   
test-4437b16c19b7f9ed01f38b8be3c782d0-i000   ibm-cert-store      crn:v1:bluemix:public:cloudcerts:jp-tok:a/yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy:1209fce5-3e43-4c31-ac57-63c9e2703ede:certificate:9623b4f40969b443edd1a90dcb3d886d   2022-08-04T05:25:45+0000   test-4437b16c19b7f9ed01f38b8be3c782d0-i000.jp-tok.containers.appdomain.cloud   created   TLS   
test-4437b16c19b7f9ed01f38b8be3c782d0-i000   openshift-ingress   crn:v1:bluemix:public:cloudcerts:jp-tok:a/yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy:1209fce5-3e43-4c31-ac57-63c9e2703ede:certificate:9623b4f40969b443edd1a90dcb3d886d   2022-08-04T05:25:45+0000   test-4437b16c19b7f9ed01f38b8be3c782d0-i000.jp-tok.containers.appdomain.cloud   created   TLS   
```

この状態で、ibmcloud ks nlb-dns secret regenerate コマンドを実行し、Ingress Subdomainに対する証明書を再発行します。Secrets Manager側に証明書を再発行します。

```
% ibmcloud ks nlb-dns secret regenerate --cluster test --nlb-subdomain test-4437b16c19b7f9ed01f38b8be3c782d0-i000.jp-tok.containers.appdomain.cloud
NLB サブドメインの証明書および秘密を再生成中...
注: 変更が適用されるまで数分かかる場合があります。
OK
```

10分くらい待つと、以下の通りCRNの値が「crn:v1:bluemix:public:secrets-manager」から始まっていることより、Secrets Managerで再発行されたことが確認できます。

```
% ibmcloud ks ingress secret ls --cluster test
OK
名前                                         名前空間            CRN                                                                                                                                                                有効期限                   ドメイン                                                                       状況      タイプ   
test-4437b16c19b7f9ed01f38b8be3c782d0-i000   ibm-cert-store      crn:v1:bluemix:public:secrets-manager:jp-tok:a/yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy:a4b59295-cfb8-4f5d-92c2-0ae075c0ca2e:secret:5c2e5aa3-fa5d-c869-ce1c-d4e56a3e794e   2022-08-04T07:51:00+0000   test-4437b16c19b7f9ed01f38b8be3c782d0-i000.jp-tok.containers.appdomain.cloud   created   TLS   
test-4437b16c19b7f9ed01f38b8be3c782d0-i000   openshift-ingress   crn:v1:bluemix:public:secrets-manager:jp-tok:a/yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy:a4b59295-cfb8-4f5d-92c2-0ae075c0ca2e:secret:5c2e5aa3-fa5d-c869-ce1c-d4e56a3e794e   2022-08-04T07:51:00+0000   test-4437b16c19b7f9ed01f38b8be3c782d0-i000.jp-tok.containers.appdomain.cloud   created   TLS   
```

ちなみに、Secrets ManagerのCLIプラグインをibmcloud CLIで入れておけば、以下のようにコマンドでSecrets Manager上に証明書が保存されていることが確認できます。

```
% export SECRETS_MANAGER_URL=https://a4b59295-cfb8-4f5d-92c2-0ae075c0ca2e.jp-tok.secrets-manager.appdomain.cloud
% ibmcloud secrets-manager secrets --secret-type imported_cert
...
name                                                                                id                                     secret_type     secret_group_id   state_description   expiration_date   
test-4437b16c19b7f9ed01f38b8be3c782d0-i000_openshift-ingress_c9qbu8at0n6b6m1ogg8g   5c2e5aa3-fa5d-c869-ce1c-d4e56a3e794e   imported_cert   None              Active              2022-08-04T07:51:00.000Z
```

## Step 4. 不要なCertificate Managerの登録解除
Certificate ManagerをROKSの紐付けから除外します。

```
% ibmcloud ks ingress instance ls --cluster test 
OK
名前                                タイプ            Is Default   状況      CRN   
kube-certmgr-c9qbu8at0n6b6m1ogg8g   cloudcerts        false        created   crn:v1:bluemix:public:cloudcerts:jp-tok:a/yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy:1209fce5-3e43-4c31-ac57-63c9e2703ede::   
secrets-manager-test                secrets-manager   true         created   crn:v1:bluemix:public:secrets-manager:jp-tok:a/yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy:a4b59295-cfb8-4f5d-92c2-0ae075c0ca2e::   

% ibmcloud ks ingress instance unregister --cluster test --name kube-certmgr-c9qbu8at0n6b6m1ogg8g
OK

% ibmcloud ks ingress instance ls --cluster test 
OK
名前                   タイプ            Is Default   状況      CRN   
secrets-manager-test   secrets-manager   true         created   crn:v1:bluemix:public:secrets-manager:jp-tok:a/yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy:a4b59295-cfb8-4f5d-92c2-0ae075c0ca2e:: 
```

除外後、インスタンスを削除します。Docには削除しなくても廃止されるタイミングでCertificate Managerインスタンスは自動削除されるとありますので、あくまでもオプションです。

```
% ibmcloud resource service-instance-delete kube-certmgr-c9qbu8at0n6b6m1ogg8g
xxxx@gmail.com としてアカウント xxxxxxxx のサービス・インスタンス kube-certmgr-c9qbu8at0n6b6m1ogg8g を削除しています...
ID crn:v1:bluemix:public:cloudcerts:jp-tok:a/yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy:1209fce5-3e43-4c31-ac57-63c9e2703ede:: のサービス・インスタンス kube-certmgr-c9qbu8at0n6b6m1ogg8g を本当に削除しますか? [y/N] > y
OK
ID crn:v1:bluemix:public:cloudcerts:jp-tok:a/yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy:1209fce5-3e43-4c31-ac57-63c9e2703ede:: のサービス・インスタンス kube-certmgr-c9qbu8at0n6b6m1ogg8g は正常に削除されます
```


## Hint&Tips

ROKS/IKSへの紐付けよりもCertificate Managerインスタンスを先に消してしまうと、うまくCertificate Managerの登録が解除できないので、注意です。
やってしまったらIBM Cloudサポートにチケットで問い合わせするのが良いでしょう。

```
% ibmcloud resource service-instance-delete kube-certmgr-c9qbu8at0n6b6m1ogg8g
xxxx@gmail.com としてアカウント xxxxxx のサービス・インスタンス kube-certmgr-c9qbu8at0n6b6m1ogg8g を削除しています...
ID crn:v1:bluemix:public:cloudcerts:jp-tok:a/yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy:c179bfae-069e-4a63-bece-f770b30e80a6:: のサービス・インスタンス kube-certmgr-c9qbu8at0n6b6m1ogg8g を本当に削除しますか? [y/N] > y
OK
ID crn:v1:bluemix:public:cloudcerts:jp-tok:a/yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy:c179bfae-069e-4a63-bece-f770b30e80a6:: のサービス・インスタンス kube-certmgr-c9qbu8at0n6b6m1ogg8g は正常に削除されます

% ibmcloud ks ingress instance unregister --cluster test --name kube-certmgr-c9qbu8at0n6b6m1ogg8g
FAILED
Unable to delete callback channel through resource controller. Try again later. (EDIRCDC)

Incident ID: 72bc9486-378e-4601-9063-3305a75c0a17
```