OCIリソースへのワークロード・アクセス権の付与
Kubernetesクラスタで実行されているワークロードのIDを使用して、Kubernetes Engine (OKE)を使用してワークロードに他のOCIリソースへのファイングレイン・アクセスを付与する方法をご覧ください。
Kubernetesでは、ワークロードはKubernetesクラスタで実行されているアプリケーションです。ワークロードには、1つのポッド内で1つのアプリケーション・コンポーネントを実行することも、1つのポッドのセット内で複数のアプリケーション・コンポーネントを実行することもできます。ワークロード内のすべてのポッドは同じネームスペースで実行されます。
ワークロード内のすべてのポッドにKubernetesリソースへのアクセス権を付与するには、ワークロード内のすべてのポッドが同じKubernetesサービス・アカウントを使用するように指定できます。その後、サービス・アカウントにKubernetesクラスタ・ロール権限を付与できます。ワークロード内のポッドをクラスタ・ロール権限にバインドし、ポッドにKubernetesリソースへのアクセス権を付与するサービス・アカウントです。
Oracle Cloud Infrastructureでは、Kubernetesクラスタで実行されるワークロードは、それ自体でリソースと見なされます。ワークロード・リソースは、クラスタ、ネームスペースおよびサービス・アカウントの一意の組合せによって識別されます。この一意の組合せは、ワークロード・アイデンティティと呼ばれます。IAMポリシーを定義するときにワークロード・アイデンティティを使用して、他のOCIリソース(オブジェクト・ストレージ・バケットなど)へのファイングレイン・アクセス権を付与できます。また、Oracle Cloud Infrastructure Auditを使用すると、ワークロード・アイデンティティによって行われたリクエストを追跡してコンプライアンス要件を満たすことができ、不正アクセスや疑わしいアクティビティをモニターおよびレポートできます。
ワークロード内のすべてのポッドにOCIリソースへのアクセス権を付与するには:
- サービス・アカウントのネームスペースを作成します。
- 使用するアプリケーションのサービス・アカウントを作成します。
- IAMポリシーを定義して、ワークロード・リソースに他のOCIリソースへのアクセス権を付与します。
- アプリケーションが書き込まれる言語に適したOCI SDKをダウンロードして構成します。
- アプリケーションを編集して次を指定します。
-
- ワークロード・リクエストがKubernetes Engineワークロード・アイデンティティ・プロバイダを使用して認証されること
- アクセスするOCIリソース
- アプリケーションのデプロイメント仕様を更新して、ワークロード内のすべてのポッドがサービス・アカウントを使用することを指定します。
ワークロード・アイデンティティを使用する場合は、次の点に注意してください。
- 現在、動的グループでワークロード・アイデンティティを使用することはできません。
- ワークロード・アイデンティティはOCI SDKでのみ使用でき、コンソールやAPIでは使用できません。
- 次のOCI SDKは現在、ワークロードIDをサポートしています:
- Go SDK v65.32.0 (以降)
- Java SDK v2.54.0 (以上)
- Python SDK v2.111.0 (以降)
例: Go SDKを使用したOCIリソースへのアプリケーション・ワークロード・アクセス権の付与
Kubernetesクラスタで実行されているGoアプリケーション・ワークロードに他のOCIリソースへのアクセス権を付与するには:
-
まだ実行していない場合は、ステップに従って、クラスタのkubeconfig構成ファイルを設定し、(必要に応じて)そのファイルを指すようにKUBECONFIG環境変数を設定します。自分のkubeconfigファイルを設定する必要があります。別のユーザーが設定したkubeconfigファイルを使用してクラスタにアクセスすることはできません。クラスタ・アクセスの設定を参照してください。
- クラスタのOCIDを取得します(たとえば、コンソールの「クラスタの詳細」タブを使用します)。
-
次を入力して、使用するKubernetesサービス・アカウントのネームスペースを作成します:
kubectl create namespace <namespace-name>
例:
kubectl create namespace finance
- 次を入力して、アプリケーションで使用するKubernetesサービス・アカウントを作成します:
kubectl create serviceaccount <service-account-name> --namespace <namespace-name>
例:
kubectl create serviceaccount financeserviceaccount --namespace finance
- IAMポリシーを定義して、ワークロードが必要なOCIリソースにアクセスできるようにします:
- ナビゲーション・メニューを開き、「アイデンティティとセキュリティ」をクリックします。「アイデンティティ」で、「ポリシー」をクリックします。
- ポリシーを作成するにはの説明に従って、ポリシーに名前を付けます(たとえば、
acme-oke-finance-workload-policy
)。 -
ワークロードが必要なOCIリソースにアクセスできるようにするポリシー・ステートメントを次の形式で入力します:
Allow any-user to <verb> <resource> in <location> where all { request.principal.type = 'workload', request.principal.namespace = '<namespace-name>', request.principal.service_account = '<service-account-name>', request.principal.cluster_id = '<cluster-ocid>'}
ここでは:
<namespace-name>
は、以前に作成したネームスペースの名前です。<service-account-name>
は、以前に作成したサービス・アカウントの名前です。<cluster-ocid>
は、以前に取得したクラスタのOCIDです。
例:
Allow any-user to manage objects in tenancy where all { request.principal.type = 'workload', request.principal.namespace = 'finance', request.principal.service_account = 'financeserviceaccount', request.principal.cluster_id = 'ocid1.cluster.oc1.iad.aaaaaaaaaf______jrd'}
- 「作成」をクリックして、新しいポリシーを作成します。
- OCI SDK for Goをインストールします(SDK for Goを参照)。
-
Goアプリケーション・コードで、次を追加します。
- Kubernetesエンジン・ワークロード・アイデンティティ・プロバイダ(
OkeWorkloadIdentityConfigurationProvider
) - アクセスするOCIリソース
たとえば、次のコード・スニペットは、認証にワークロードIDを使用し、Pheonix (PHX)リージョンにオブジェクト・ストレージ・サービスにバケットを作成し、バケットにファイルをアップロードします:
// ExampleObjectStorage_UploadFile shows how to create a bucket and upload a file using OKE Workload Identity func ExampleObjectStorage_UploadFile() { rp, err := auth.OkeWorkloadIdentityConfigurationProvider() if err != nil { panic(err) } c, clerr := objectstorage.NewObjectStorageClientWithConfigurationProvider(rp) c.SetRegion("us-phoenix-1") helpers.FatalIfError(clerr) ctx := context.Background() bname := helpers.GetRandomString(8) namespace := getNamespace(ctx, c) createBucket(ctx, c, namespace, bname) contentlen := 1024 * 1000 filepath, filesize := helpers.WriteTempFileOfSize(int64(contentlen)) filename := path.Base(filepath) defer func() { os.Remove(filename) }() file, e := os.Open(filepath) defer file.Close() helpers.FatalIfError(e) e = putObject(ctx, c, namespace, bname, filename, filesize, file, nil) helpers.FatalIfError(e) // Output: // get namespace // create bucket // put object
- Kubernetesエンジン・ワークロード・アイデンティティ・プロバイダ(
- テキスト・エディタでアプリケーションのデプロイメント仕様を開き、次のようにします。
serviceAccountName
を追加して、前に作成したサービス・アカウントの名前に設定します。たとえば、serviceAccountName: financeserviceaccount
です。automountServiceAccountToken
を追加して、true
に設定します。
例:
apiVersion: v1 kind: Pod metadata: name: nginx spec: serviceAccountName: financeserviceaccount automountServiceAccountToken: true containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80
- 次を入力してアプリケーションをデプロイします:
kubectl create -f <filename>
例:kubectl create -f financeworkloadidentity.yaml
例: Java SDKを使用したOCIリソースへのアプリケーション・ワークロード・アクセス権の付与
Kubernetesクラスタで実行されているJavaアプリケーション・ワークロードに他のOCIリソースへのアクセス権を付与するには:
-
まだ実行していない場合は、ステップに従って、クラスタのkubeconfig構成ファイルを設定し、(必要に応じて)そのファイルを指すようにKUBECONFIG環境変数を設定します。自分のkubeconfigファイルを設定する必要があります。別のユーザーが設定したkubeconfigファイルを使用してクラスタにアクセスすることはできません。クラスタ・アクセスの設定を参照してください。
- クラスタのOCIDを取得します(たとえば、コンソールの「クラスタの詳細」タブを使用します)。
-
次を入力して、使用するKubernetesサービス・アカウントのネームスペースを作成します:
kubectl create namespace <namespace-name>
例:
kubectl create namespace finance
- 次を入力して、アプリケーションで使用するKubernetesサービス・アカウントを作成します:
kubectl create serviceaccount <service-account-name> --namespace <namespace-name>
例:
kubectl create serviceaccount financeserviceaccount --namespace finance
- IAMポリシーを定義して、ワークロードが必要なOCIリソースにアクセスできるようにします:
- ナビゲーション・メニューを開き、「アイデンティティとセキュリティ」をクリックします。「アイデンティティ」で、「ポリシー」をクリックします。
- ポリシーを作成するにはの説明に従って、ポリシーに名前を付けます(たとえば、
acme-oke-finance-workload-policy
)。 -
ワークロードが必要なOCIリソースにアクセスできるようにするポリシー・ステートメントを次の形式で入力します:
Allow any-user to <verb> <resource> in <location> where all { request.principal.type = 'workload', request.principal.namespace = '<namespace-name>', request.principal.service_account = '<service-account-name>', request.principal.cluster_id = '<cluster-ocid>'}
ここでは:
<namespace-name>
は、以前に作成したネームスペースの名前です。<service-account-name>
は、以前に作成したサービス・アカウントの名前です。<cluster-ocid>
は、以前に取得したクラスタのOCIDです。
例:
Allow any-user to manage objects in tenancy where all { request.principal.type = 'workload', request.principal.namespace = 'finance', request.principal.service_account = 'financeserviceaccount', request.principal.cluster_id = 'ocid1.cluster.oc1.iad.aaaaaaaaaf______jrd'}
- 「作成」をクリックして、新しいポリシーを作成します。
- OCI SDK for Javaをインストールします(SDK for Javaを参照)。
- アプリケーションのpom.xmlで、
oci-java-sdk-addons-oke-workload-identity
アーティファクトを依存関係として追加します。
SDKのバージョンは2.54.0以降である必要があります。<dependency> <groupId>com.oracle.oci.sdk</groupId> <artifactId>oci-java-sdk-addons-oke-workload-identity</artifactId> <version>2.54.0</version> </dependency> <dependency> <groupId>com.oracle.oci.sdk</groupId> <artifactId>oci-java-sdk-common</artifactId> <version>2.54.0</version> </dependency>
- Javaアプリケーション・コードで、次を追加します。
- Kubernetesエンジン・ワークロード・アイデンティティ・プロバイダ(
OkeWorkloadIdentityAuthenticationDetailsProvider
) - アクセスするOCIリソース
たとえば、次のコード・スニペットは、認証にワークロードIDを使用し、Pheonix (PHX)リージョンにオブジェクト・ストレージ・サービスにバケットを作成し、バケットにファイルをアップロードします:
import com.oracle.bmc.Region; import com.oracle.bmc.auth.AuthenticationDetailsProvider; import com.oracle.bmc.auth.ConfigFileAuthenticationDetailsProvider; import com.oracle.bmc.auth.okeworkloadidentity.OkeWorkloadIdentityAuthenticationDetailsProvider; import com.oracle.bmc.objectstorage.ObjectStorage; import com.oracle.bmc.objectstorage.ObjectStorageClient; import com.oracle.bmc.objectstorage.model.BucketSummary; import com.oracle.bmc.objectstorage.requests.GetNamespaceRequest; import com.oracle.bmc.objectstorage.requests.GetObjectRequest; import com.oracle.bmc.objectstorage.requests.ListBucketsRequest; import com.oracle.bmc.objectstorage.requests.ListBucketsRequest.Builder; import com.oracle.bmc.objectstorage.responses.GetNamespaceResponse; import com.oracle.bmc.objectstorage.responses.GetObjectResponse; import com.oracle.bmc.objectstorage.responses.ListBucketsResponse; import java.io.InputStream; public class ObjectStorageSyncExample { public static void main(String[] args) throws Exception { /* Config the Container Engine for Kubernetes workload identity provider */ final OkeWorkloadIdentityAuthenticationDetailsProvider provider = new OkeWorkloadIdentityAuthenticationDetailsProvider .OkeWorkloadIdentityAuthenticationDetailsProviderBuilder() .build(); /* Configure the client to use workload identity provider*/ ObjectStorage client = ObjectStorageClient.builder().region(Region.US_PHOENIX_1).build(provider); GetNamespaceResponse namespaceResponse = client.getNamespace(GetNamespaceRequest.builder().build()); String namespaceName = namespaceResponse.getValue(); System.out.println("Using namespace: " + namespaceName); Builder listBucketsBuilder = ListBucketsRequest.builder() .namespaceName(namespaceName) .compartmentId("enter tenancy id"); String nextToken = null; do { listBucketsBuilder.page(nextToken); ListBucketsResponse listBucketsResponse = client.listBuckets(listBucketsBuilder.build()); for (BucketSummary bucket : listBucketsResponse.getItems()) { System.out.println("Found bucket: " + bucket.getName()); } nextToken = listBucketsResponse.getOpcNextPage(); } while (nextToken != null); // fetch the file from the object storage String bucketName = null; String objectName = null; GetObjectResponse getResponse = client.getObject( GetObjectRequest.builder() .namespaceName(namespaceName) .bucketName(bucketName) .objectName(objectName) .build()); // stream contents should match the file uploaded try (final InputStream fileStream = getResponse.getInputStream()) { // use fileStream } // try-with-resources automatically closes fileStream client.close(); } }
- Kubernetesエンジン・ワークロード・アイデンティティ・プロバイダ(
- テキスト・エディタでアプリケーションのデプロイメント仕様を開き、次のようにします。
serviceAccountName
を追加して、前に作成したサービス・アカウントの名前に設定します。たとえば、serviceAccountName: financeserviceaccount
です。automountServiceAccountToken
を追加して、true
に設定します。
例:
apiVersion: v1 kind: Pod metadata: name: nginx spec: serviceAccountName: financeserviceaccount automountServiceAccountToken: true containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80
- 次を入力してアプリケーションをデプロイします:
kubectl create -f <filename>
例:kubectl create -f financeworkloadidentity.yaml
例: Java SDKを使用した、異なるコンパートメント内のOCIリソースへのアプリケーション・ワークロード・アクセス権の付与
あるコンパートメント内のKubernetesクラスタで実行されているJavaアプリケーション・ワークロードに、別のコンパートメント内の他のOCIリソースへのアクセス権を付与するには:
-
まだ実行していない場合は、ステップに従って、クラスタのkubeconfig構成ファイルを設定し、(必要に応じて)そのファイルを指すようにKUBECONFIG環境変数を設定します。自分のkubeconfigファイルを設定する必要があります。別のユーザーが設定したkubeconfigファイルを使用してクラスタにアクセスすることはできません。クラスタ・アクセスの設定を参照してください。
- クラスタのOCIDを取得します(たとえば、コンソールの「クラスタの詳細」タブを使用します)。
- クラスタ管理者として、次のように入力して、使用するKubernetesサービス・アカウントのネームスペースを作成します:
kubectl create namespace <namespace-name>
例:
kubectl create namespace finance
-
クラスタ管理者として、次のように入力して、アプリケーションで使用するKubernetesサービス・アカウントを作成します:
kubectl create serviceaccount <service-account-name> --namespace <namespace-name>
例:
kubectl create serviceaccount financeserviceaccount --namespace finance
-
テナンシ管理者として、クラスタ管理者が、あるコンパートメント内のクラスタで実行されているワークロードを別のコンパートメント内の他のOCIリソースにバインドできるようにするIAMポリシーを定義します:
- ナビゲーション・メニューを開き、「アイデンティティとセキュリティ」をクリックします。「アイデンティティ」で、「ポリシー」をクリックします。
- ポリシーを作成するにはの説明に従って、ポリシーに名前を付けます(たとえば、
acme-oke-finance-workload-policy
)。 ポリシー・ステートメントを入力して、クラスタ管理者が、あるコンパートメント内のクラスタで実行されているワークロードを別のコンパートメント内の他のOCIリソースにバインドできるようにします(次の形式)。
Allow group cluster-admins to manage cluster-workload-mappings in compartment <compartment-one> Allow group cluster-admins to {CLUSTER_WORKLOAD_COMPARTMENT_BIND,CLUSTER_WORKLOAD_COMPARTMENT_UNBIND} in compartment <compartment-two>
ここでは:
<compartment-one>
は、クラスタが属するコンパートメントです<compartment-two>
は、他のOCIリソースが属するコンパートメントです
例:
グループがデフォルトのアイデンティティ・ドメインにない場合は、Allow group cluster-admins to manage cluster-workload-mappings in compartment finance Allow group cluster-admins to {CLUSTER_WORKLOAD_COMPARTMENT_BIND,CLUSTER_WORKLOAD_COMPARTMENT_UNBIND} in compartment sales
group '<identity-domain-name>'/'group-name'
の形式で、グループ名の前にアイデンティティ・ドメイン名を追加します。group id <group-ocid>
の形式で、そのOCIDを使用してグループを指定することもできます。- 「作成」をクリックして、新しいポリシーを作成します。
-
クラスタ管理者がクラスタが属するコンパートメントで、クラスタで実行されているワークロードを、他のOCIリソースが属するコンパートメントにマップするワークロード・マッピングを作成します:
oci ce workload-mapping create --namespace <namespace-name> --mapped-compartment-id <compartment-two-ocid> --cluster-id <cluster-ocid>
例:
oci ce workload-mapping create --namespace finance --mapped-compartment-id ocid1.compartment.oc1..aaaaaaaaad______fda --cluster-id ocid1.cluster.oc1.iad.aaaaaaaaaf______jrd
-
2番目のコンパートメントのリソースの管理者として、ワークロードがコンパートメント内のOCIリソースにアクセスできるようにするIAMポリシーを定義します:
- ナビゲーション・メニューを開き、「アイデンティティとセキュリティ」をクリックします。「アイデンティティ」で、「ポリシー」をクリックします。
- ポリシーを作成するにはの説明に従って、ポリシーに名前を付けます(たとえば、
acme-oke-finance-workload-policy
)。 -
ワークロードが必要なOCIリソースにアクセスできるようにするポリシー・ステートメントを次の形式で入力します:
Allow any-user to <verb> <resource> in <location> where all { request.principal.type = 'workload', request.principal.namespace = '<namespace-name>', request.principal.service_account = '<service-account-name>', request.principal.cluster_id = '<cluster-ocid>'}
ここでは:
<namespace-name>
は、以前に作成したネームスペースの名前です。<service-account-name>
は、以前に作成したサービス・アカウントの名前です。<cluster-ocid>
は、以前に取得したクラスタのOCIDです。
例:
Allow any-user to manage objects in compartment sales where all { request.principal.type = 'workload', request.principal.namespace = 'finance', request.principal.service_account = 'financeserviceaccount', request.principal.cluster_id = 'ocid1.cluster.oc1.iad.aaaaaaaaaf______jrd'}
- 「作成」をクリックして、新しいポリシーを作成します。
- OCI SDK for Javaをインストールします(SDK for Javaを参照)。SDKのバージョンは2.66.0以上(または3.18.0以上)である必要があります。
- アプリケーションのpom.xmlで、
oci-java-sdk-addons-oke-workload-identity
アーティファクトを依存関係として追加します。
SDKのバージョンは2.66.0以上(または3.18.0以上)である必要があります。<dependency> <groupId>com.oracle.oci.sdk</groupId> <artifactId>oci-java-sdk-addons-oke-workload-identity</artifactId> <version>2.66.0</version> </dependency> <dependency> <groupId>com.oracle.oci.sdk</groupId> <artifactId>oci-java-sdk-common</artifactId> <version>2.66.0</version> </dependency>
- Javaアプリケーション・コードで、次を追加します。
- Kubernetesエンジン・ワークロード・アイデンティティ・プロバイダ(
OkeWorkloadIdentityAuthenticationDetailsProvider
) - アクセスするOCIリソース
たとえば、次のコード・スニペットは、認証にワークロードIDを使用し、Pheonix (PHX)リージョンにオブジェクト・ストレージ・サービスにバケットを作成し、バケットにファイルをアップロードします:
import com.oracle.bmc.Region; import com.oracle.bmc.auth.AuthenticationDetailsProvider; import com.oracle.bmc.auth.ConfigFileAuthenticationDetailsProvider; import com.oracle.bmc.auth.okeworkloadidentity.OkeWorkloadIdentityAuthenticationDetailsProvider; import com.oracle.bmc.objectstorage.ObjectStorage; import com.oracle.bmc.objectstorage.ObjectStorageClient; import com.oracle.bmc.objectstorage.model.BucketSummary; import com.oracle.bmc.objectstorage.requests.GetNamespaceRequest; import com.oracle.bmc.objectstorage.requests.GetObjectRequest; import com.oracle.bmc.objectstorage.requests.ListBucketsRequest; import com.oracle.bmc.objectstorage.requests.ListBucketsRequest.Builder; import com.oracle.bmc.objectstorage.responses.GetNamespaceResponse; import com.oracle.bmc.objectstorage.responses.GetObjectResponse; import com.oracle.bmc.objectstorage.responses.ListBucketsResponse; import java.io.InputStream; public class ObjectStorageSyncExample { public static void main(String[] args) throws Exception { /* Config the Container Engine for Kubernetes workload identity provider */ final OkeWorkloadIdentityAuthenticationDetailsProvider provider = new OkeWorkloadIdentityAuthenticationDetailsProvider .OkeWorkloadIdentityAuthenticationDetailsProviderBuilder() .build(); /* Configure the client to use workload identity provider*/ ObjectStorage client = ObjectStorageClient.builder().region(Region.US_PHOENIX_1).build(provider); GetNamespaceResponse namespaceResponse = client.getNamespace(GetNamespaceRequest.builder().build()); String namespaceName = namespaceResponse.getValue(); System.out.println("Using namespace: " + namespaceName); Builder listBucketsBuilder = ListBucketsRequest.builder() .namespaceName(namespaceName) .compartmentId("enter tenancy id"); String nextToken = null; do { listBucketsBuilder.page(nextToken); ListBucketsResponse listBucketsResponse = client.listBuckets(listBucketsBuilder.build()); for (BucketSummary bucket : listBucketsResponse.getItems()) { System.out.println("Found bucket: " + bucket.getName()); } nextToken = listBucketsResponse.getOpcNextPage(); } while (nextToken != null); // fetch the file from the object storage String bucketName = null; String objectName = null; GetObjectResponse getResponse = client.getObject( GetObjectRequest.builder() .namespaceName(namespaceName) .bucketName(bucketName) .objectName(objectName) .build()); // stream contents should match the file uploaded try (final InputStream fileStream = getResponse.getInputStream()) { // use fileStream } // try-with-resources automatically closes fileStream client.close(); } }
- Kubernetesエンジン・ワークロード・アイデンティティ・プロバイダ(
- テキスト・エディタでアプリケーションのデプロイメント仕様を開き、次のようにします。
namespace
を追加して、前に作成したネームスペースの名前に設定します。たとえば、namespace: finance
です。serviceAccountName
を追加して、前に作成したサービス・アカウントの名前に設定します。たとえば、serviceAccountName: financeserviceaccount
です。automountServiceAccountToken
を追加して、true
に設定します。
例:
apiVersion: v1 kind: Pod metadata: name: nginx namespace: finance spec: serviceAccountName: financeserviceaccount automountServiceAccountToken: true containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80
- 次を入力してアプリケーションをデプロイします:
kubectl create -f <filename>
例:kubectl create -f financeworkloadidentity.yaml