0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Crossplane OCI Provider:構成、認証、Bucket demo で理解する

0
Posted at

初めに

前回の記事では、Composition の実装として Patch & TransformComposition FunctionsPipeline mode を整理しました。

そこでは、Composition は OCI API を直接呼ぶ処理ではなく、Managed Resource の desired state を作る場所だと説明しました。

今回は、その先に進みます。

実際に OCI Object Storage Bucket を作る流れを使って、OCI Provider の構成、認証、Managed Resource の状態確認を一つにつなげます。

この内容は、以前書いた Crossplane Provider for Oracle Cloud Infrastructure (OCI) 入門 の実操記録を学習の流れとして参考にしています。

ただし、実際に使う apiVersion、Provider の package tag、ProviderConfig の種類、example manifest は、必ず最新の公式 repo と quickstart を確認してください。

OCI Provider は provider release によって API group や field が変わる可能性があります。

この記事では、細かい option を全部説明するのではなく、初学者がまず覚えるべき一周に絞ります。

Crossplane core
  -> OCI Provider
    -> Secret
      -> ProviderConfig
        -> Bucket Managed Resource
          -> READY / SYNCED
            -> OCI Console
              -> delete

この記事のゴール

この記事のゴールは、OCI Provider を次の三つの単位で説明できるようになることです。

Provider
  OCI の CRD と controller を Kubernetes cluster に追加する

ProviderConfig
  どの資格情報で OCI API を呼ぶかを決める

Managed Resource
  Bucket など、OCI resource に対応する Kubernetes resource

Bucket demo で見るべき順番は、次の通りです。

1. Crossplane core が動いている
2. OCI Provider が HEALTHY になっている
3. Secret に OCI credentials が入っている
4. ProviderConfig が Secret を参照している
5. Bucket YAML が正しい ProviderConfig を参照している
6. READY / SYNCED / EXTERNAL-NAME を見る
7. OCI Console で namespace、compartment、Bucket name を確認する
8. 削除は Managed Resource から行う

この順番で見ると、どこで詰まっているかを切り分けやすくなります。


まず Crossplane core を用意する

OCI Provider を入れる前に、Crossplane core が Kubernetes cluster 上で動いている必要があります。

最初に確認するのは、kubectl が正しい cluster を向いているかです。

kubectl config current-context

そのうえで、Crossplane 用の namespace を作り、Helm で Crossplane を install します。

kubectl create namespace crossplane-system

helm repo add crossplane-stable https://charts.crossplane.io/stable
helm repo update

helm install crossplane \
  --namespace crossplane-system \
  crossplane-stable/crossplane

install したら、crossplane-system の中で controller が起動しているかを見ます。

kubectl get all -n crossplane-system

ここで大事なのは、OCI Provider の問題を見る前に、土台である Crossplane core の起動を確認することです。

kubectl context が違う cluster を向いていると、以降の Provider、Secret、ProviderConfig、Bucket の確認がすべてずれてしまいます。


OCI Provider は family provider を先に入れる

OCI Provider では、まず provider-family を入れ、その後に Object Storage などの service provider を入れる流れになります。

公式 quickstart でも、family provider を先に install することが重要だと説明されています。

理由は、service provider が family provider に依存するためです。

service provider を先に入れると、package manager が依存関係を解決しようとして、意図しない family provider image を pull する可能性があります。

Object Storage Bucket demo では、最低限次の二つを入れます。

apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
  name: oracle-provider-family-oci
spec:
  package: ghcr.io/oracle/provider-family-oci:<tag>
---
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
  name: provider-oci-objectstorage
spec:
  package: ghcr.io/oracle/provider-oci-objectstorage:<tag>

<tag> は実際に使う release に合わせます。

古い記事や手元の manifest をそのまま使うのではなく、公式 repo の docs/quickstart.md と release を見て確認してください。

apply したら、Provider の状態を確認します。

kubectl get providers

見る列は、INSTALLEDHEALTHY です。

NAME                         INSTALLED   HEALTHY
oracle-provider-family-oci   True        True
provider-oci-objectstorage   True        True

HEALTHY=True になるまで数分かかることがあります。

ここが False や空欄のままなら、ProviderConfig や Bucket YAML へ進む前に、ProviderRevision、package image、registry、network、pull secret を確認します。


認証情報は Secret に閉じ込める

OCI Provider が OCI API を呼ぶには、認証情報が必要です。

公式 quickstart では、主に次の認証方式が紹介されています。

API Key Authentication
Instance Principal Authentication
Workload Identity Authentication

手元で動きを理解する demo では、API Key Authentication が一番追いやすいです。

API Key の場合、tenancy OCID、user OCID、private key、fingerprint、region、auth type を credentials として Secret に入れます。

kubectl create secret generic oci-creds \
  --namespace=crossplane-system \
  --from-literal=credentials='{
    "tenancy_ocid": "REPLACE_WITH_YOUR_TENANCY_OCID",
    "user_ocid": "REPLACE_WITH_YOUR_USER_OCID",
    "private_key": "-----BEGIN RSA PRIVATE KEY-----\nREPLACE_WITH_YOUR_KEY_CONTENT\n-----END RSA PRIVATE KEY-----\n",
    "fingerprint": "REPLACE_WITH_YOUR_FINGERPRINT",
    "region": "REPLACE_WITH_YOUR_REGION",
    "auth": "ApiKey"
  }'

ここで詰まりやすいのは、private key の改行です。

JSON の中に入れるため、改行は \n として扱います。

また、OCI CLI で生成した key に追加行が含まれている場合は、その行も同じ private_key の中に含め、改行を崩さないようにします。

この Secret は Kubernetes 側の credential 入れ物です。

OCI 側の IAM policy は別途必要です。

YAML が正しくても、OCI IAM で許可されていなければ Bucket 作成は失敗します。


ProviderConfig は Secret を OCI Provider に渡す入口

次に、ProviderConfig を作ります。

ProviderConfig は、Provider がどの credentials を使って OCI API を呼ぶかを決める resource です。

ここで少し混乱しやすいのが、legacy resource と modern namespaced resource の違いです。

公式 quickstart では、次のように整理されています。

対象 ProviderConfig
*.oci.upbound.io cluster-scoped ProviderConfig.oci.upbound.io
*.oci.m.upbound.io 既定では ClusterProviderConfig.oci.m.upbound.io
namespace ごとに認証を分けたい場合 namespaced ProviderConfig.oci.m.upbound.io

まず cluster-wide に使う設定を作る場合は、次のように Secret を参照します。

apiVersion: oci.m.upbound.io/v1beta1
kind: ClusterProviderConfig
metadata:
  name: default
spec:
  credentials:
    source: Secret
    secretRef:
      name: oci-creds
      namespace: crossplane-system
      key: credentials

legacy cluster-scoped resource を使う場合は、oci.upbound.io/v1beta1ProviderConfig も必要になります。

apiVersion: oci.upbound.io/v1beta1
kind: ProviderConfig
metadata:
  name: default
spec:
  credentials:
    source: Secret
    secretRef:
      name: oci-creds
      namespace: crossplane-system
      key: credentials

team ごとに credential を分けたい場合は、namespaced ProviderConfig.oci.m.upbound.io を使います。

apiVersion: oci.m.upbound.io/v1beta1
kind: ProviderConfig
metadata:
  name: default
  namespace: team-a
spec:
  credentials:
    source: Secret
    secretRef:
      name: oci-creds
      namespace: team-a
      key: credentials

初学者向けには、最初からすべてを覚える必要はありません。

まずは次の関係だけ押さえると十分です。

Secret
  OCI credentials を持つ

ProviderConfig / ClusterProviderConfig
  Secret を参照する

Bucket
  providerConfigRef で使う ProviderConfig を選ぶ

Bucket YAML は三点だけ読む

次に、Object Storage Bucket の Managed Resource を作ります。

最初は YAML 全体を細かく読むより、次の三点だけを見ると理解しやすいです。

apiVersion / kind
spec.forProvider
providerConfigRef

modern namespaced resource の例として、概念を読みやすくした YAML は次の形です。

apiVersion: objectstorage.oci.m.upbound.io/v1alpha1
kind: Bucket
metadata:
  name: bucket1
  namespace: team-a
spec:
  forProvider:
    compartmentId: REPLACE_WITH_COMPARTMENT_OCID
    name: bucket1
    namespace: REPLACE_WITH_OBJECT_STORAGE_NAMESPACE
  providerConfigRef:
    kind: ProviderConfig
    name: default

metadata.namespace は、Kubernetes 側でこの Managed Resource を置く namespace です。

spec.forProvider.namespace は、OCI Object Storage の namespace です。

同じ namespace という名前でも、意味が違います。

ここは demo でも間違えやすいポイントです。

公式 example では、compartmentId を直接書く代わりに compartmentIdSelector を使う例もあります。

spec:
  forProvider:
    compartmentIdSelector:
      matchLabels:
        testing.upbound.io/example-name: compartment_label_1

Selector を使うと、別の Managed Resource から値を参照できます。

ただし、最初の Bucket demo では、まず compartmentId、Bucket name、Object Storage namespaceproviderConfigRef の対応を見るのが分かりやすいです。


apply は開始点で、作成は Provider の reconcile が行う

Bucket YAML を apply すると、すぐに OCI API が直接呼ばれるように見えるかもしれません。

実際には、流れは次のようになります。

kubectl apply
  -> Kubernetes API Server に Bucket resource が保存される
    -> OCI Provider が Bucket resource を observe する
      -> ProviderConfig から credentials を読む
        -> OCI API を呼ぶ
          -> status に結果を書く

つまり、kubectl apply は開始点です。

実際の作成、更新、状態確認は、Provider の reconcile loop が行います。

ここは Crossplane を Terraform のような一回実行の CLI として見ないために重要です。

Crossplane では、resource が Kubernetes API に残っている間、Provider が継続的に状態を見ます。


成功判定は READY / SYNCED / EXTERNAL-NAME

Bucket を apply した後は、状態を確認します。

kubectl get managed --all-namespaces
kubectl get bucket.objectstorage.oci.m.upbound.io -A

見る列は、READYSYNCEDEXTERNAL-NAME です。

NAMESPACE   NAME                                           READY   SYNCED   EXTERNAL-NAME
team-a      bucket.objectstorage.oci.m.upbound.io/bucket1  True    True     n/<namespace>/b/bucket1

READY=True は、resource が利用可能な状態に近いことを示します。

SYNCED=True は、Provider の reconcile が成功していることを示します。

EXTERNAL-NAME は、Kubernetes resource と外部 OCI resource を対応づける名前です。

OCI Object Storage Bucket では、n/<namespace>/b/<bucket> のような形で表示されます。

ここまで見えたら、次は OCI Console でも確認します。

OCI Console では、Bucket name だけでなく、Object Storage namespace、compartment、region も合わせて確認します。

Kubernetes 側と OCI 側を対応づけるときは、次の四つを並べて見ると分かりやすいです。

metadata.name
spec.forProvider.name
spec.forProvider.namespace
EXTERNAL-NAME

READY / SYNCED が False のときは describe を見る

READYSYNCEDFalse、または空欄のままなら、kubectl describe を見ます。

kubectl describe bucket.objectstorage.oci.m.upbound.io bucket1 -n team-a

特に見る場所は、Status.ConditionsEvents です。

たとえば、ProviderConfig の参照が間違っている場合は、次のような方向の message が出ます。

cannot get referenced ProviderConfig
ProviderConfig ... "default" not found

この場合、Bucket の spec.providerConfigRef.name と、ProviderConfig の metadata.name が一致しているかを確認します。

また、legacy resource と modern namespaced resource を混ぜている場合も注意が必要です。

legacy:
  objectstorage.oci.upbound.io
  ProviderConfig.oci.upbound.io

modern namespaced:
  objectstorage.oci.m.upbound.io
  ClusterProviderConfig.oci.m.upbound.io
  ProviderConfig.oci.m.upbound.io

ProviderConfig が正しくても、Secret の namespace、Secret の key、private key の改行、OCI IAM policy が原因で失敗することもあります。

describe は、次にどこを見るべきかを決めるための入口です。


demo では成功画面だけでなく、判断材料を見せる

Bucket demo を見せるときは、単に「作れました」で終わらせない方が理解しやすいです。

見せる順番は、次のようにすると自然です。

1. Provider が HEALTHY
2. Secret が存在する
3. ProviderConfig が Secret を参照している
4. Bucket YAML を apply する
5. kubectl get で READY / SYNCED / EXTERNAL-NAME を見る
6. 必要なら kubectl describe で conditions / events を見る
7. OCI Console で Bucket name、namespace、compartment を確認する

この順番にすると、Crossplane の責任範囲と OCI 側の実体がつながって見えます。

特に、READY / SYNCED と OCI Console を両方見るのがポイントです。

Kubernetes 側の状態だけではなく、外部 resource が本当に OCI 側にあることを確認できます。


初学者が詰まりやすい四か所

OCI Provider の Bucket demo では、詰まりやすい場所がだいたい決まっています。

一つ目は、version と apiVersion です。

provider release によって API group や field が変わる可能性があるため、古い manifest をそのまま使わないようにします。

二つ目は、scope です。

*.oci.upbound.io*.oci.m.upbound.io では、ProviderConfig の見方が変わります。

三つ目は、Secret です。

Secret の namespace、key、private key の改行が違うと、ProviderConfig は存在していても認証に失敗します。

四つ目は、OCI IAM です。

Kubernetes 側の YAML が正しくても、OCI 側で compartment に対する権限がなければ作成できません。

この四つを先に知っておくと、demo で失敗しても落ち着いて切り分けられます。


削除は Managed Resource から行う

最後に削除です。

ここで大事なのは、Provider を先に消さないことです。

Provider は controller でもあります。

Managed Resource が残っている状態で Provider を消すと、削除や状態合わせを行う controller がいなくなり、後片付けが難しくなることがあります。

順番は、まず Bucket などの Managed Resource からです。

kubectl delete -f examples/namespaced/objectstorage/v1alpha1/bucket.yaml

kubectl get bucket.objectstorage.oci.m.upbound.io -A

Bucket が消えたことを確認してから、Provider 関連を削除します。

kubectl delete providers/provider-oci-objectstorage

# 作成した ProviderConfig / ClusterProviderConfig を削除する
kubectl delete clusterproviderconfig.oci.m.upbound.io/default
kubectl delete providerconfig.oci.upbound.io/default
kubectl delete providerconfig.oci.m.upbound.io/default -n team-a

kubectl delete providers/oracle-provider-family-oci

上の ProviderConfig / ClusterProviderConfig は、実際に作成したものだけ削除します。

実運用では、削除が本当に外部 OCI resource まで消す操作なのか、あるいは Kubernetes 側の管理だけ外す操作なのかを事前に確認します。

特に managementPoliciesdeletionPolicy を使う場合は、どの操作を controller に許可しているかを確認してください。


まとめ

今回は、OCI Provider の構成、認証、Bucket demo を一つの流れとして整理しました。

覚える単位は、次の三つです。

Provider
  CRD と controller を追加する

ProviderConfig
  OCI credentials への参照を持つ

Managed Resource
  Bucket などの OCI resource を Kubernetes resource として表す

Bucket demo の順番は、次のように見ると分かりやすいです。

Crossplane core
  -> family provider
    -> service provider
      -> Secret
        -> ProviderConfig
          -> Bucket YAML
            -> READY / SYNCED
              -> OCI Console
                -> delete

この一周を理解すると、OCI Provider を単なる YAML collection ではなく、Kubernetes API と OCI API をつなぐ controller として見られるようになります。

次は、この流れを既存 OCI resource の取り込み、Observe-only、Platform API、GitOps の観点へ広げて見ていきます。


参考

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?