All Products
Search
Document Center

Elastic Container Instance:Gunakan instance RAM role menggunakan operasi API

Last Updated:Apr 02, 2026

Tetapkan peran RAM ke instans Elastic Container Instance agar aplikasi yang berjalan di dalamnya dapat memanggil API layanan Alibaba Cloud lainnya menggunakan kredensial Security Token Service (STS) yang diperbarui secara otomatis—tanpa menyimpan pasangan AccessKey di instans.

Mengapa menggunakan instance RAM role

Menyematkan pasangan AccessKey langsung dalam file konfigurasi menimbulkan dua masalah: risiko kebocoran kredensial dan kebutuhan untuk memperbarui setiap instans saat izin berubah. Instance RAM role mengatasi kedua masalah tersebut:

  • Tidak ada kredensial di disk. Aplikasi mengambil token STS berumur pendek dari metadata instans pada waktu proses.

  • Pengelolaan izin terpusat. Untuk mengubah akses yang dimiliki instans, cukup perbarui peran RAM—bukan instans itu sendiri.

  • Rotasi token otomatis. Token STS kedaluwarsa dan diperbarui secara otomatis, sehingga membatasi dampak jika terjadi kebocoran.

Prasyarat

Sebelum memulai, pastikan Anda memiliki:

  • Akun Alibaba Cloud atau Pengguna RAM dengan izin untuk memanggil CreateRole, CreatePolicy, dan AttachPolicyToRole di RAM, serta CreateContainerGroup di ECI.

  • (Opsional) Jika menggunakan Pengguna RAM untuk membuat instans Elastic Container Instance, Pengguna RAM tersebut juga harus memiliki izin ram:PassRole pada peran target.

Cara kerja

  1. Buat instance RAM role dan konfigurasikan kebijakan kepercayaannya agar mengizinkan ECS mengasumsikan peran tersebut.

  2. Buat kebijakan izin dan sambungkan ke peran tersebut.

  3. (Opsional) Berikan izin kepada Pengguna RAM untuk meneruskan peran tersebut ke instans.

  4. Tetapkan peran tersebut ke instans Elastic Container Instance melalui CreateContainerGroup.

  5. Ambil kredensial STS dari metadata instans di dalam pod, lalu gunakan untuk memanggil layanan Alibaba Cloud lainnya.

Langkah 1: Buat instance RAM role

Panggil CreateRole dengan parameter berikut:

  • RoleName: Nama deskriptif untuk peran tersebut. Contoh ini menggunakan ECIRamRoleTest.

  • AssumeRolePolicyDocument: Kebijakan kepercayaan yang memberikan hak kepada ECS untuk mengasumsikan peran ini.

{
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Effect": "Allow",
      "Principal": {
        "Service": [
          "ecs.aliyuncs.com"
        ]
      }
    }
  ],
  "Version": "1"
}
Entitas tepercaya harus diatur ke Elastic Container Instance dan layanan tepercaya harus diatur ke Elastic Compute Service (ECS), yang direpresentasikan oleh pihak yang berwenang ecs.aliyuncs.com.

Langkah 2: Sambungkan kebijakan izin ke peran

2a. Buat kebijakan kustom

Panggil CreatePolicy dengan parameter berikut:

  • PolicyName: ECIRamRoleTestPolicy

  • PolicyDocument: Izin yang akan diberikan. Contoh berikut memberikan akses baca ke semua bucket Object Storage Service (OSS):

{
  "Statement": [
    {
      "Action": [
        "oss:Get*",
        "oss:List*"
      ],
      "Effect": "Allow",
      "Resource": "*"
    }
  ],
  "Version": "1"
}

Ikuti prinsip hak istimewa minimal—berikan hanya izin yang benar-benar dibutuhkan oleh aplikasi.

2b. Sambungkan kebijakan ke peran

Panggil AttachPolicyToRole dengan parameter berikut:

ParameterNilai
PolicyNameECIRamRoleTestPolicy
PolicyTypeCustom
RoleNameECIRamRoleTest

Langkah 3 (opsional): Otorisasi Pengguna RAM untuk meneruskan peran

Lewati langkah ini jika Anda menggunakan Akun Alibaba Cloud untuk membuat instans Elastic Container Instance.

Jika Pengguna RAM membuat instans Elastic Container Instance dan menetapkan peran tersebut, Pengguna RAM memerlukan izin ram:PassRole pada peran tersebut. Tanpa izin ini, Pengguna RAM tidak dapat mendelegasikan peran tersebut ke instans.

  1. Masuk ke Konsol RAM menggunakan Akun Alibaba Cloud atau Pengguna RAM dengan izin admin.

  2. Buat kebijakan kustom dengan dokumen berikut, lalu sambungkan ke Pengguna RAM. Untuk detailnya, lihat Berikan izin kepada Pengguna RAM.

{
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "ram:PassRole",
      "Resource": "acs:ram:*:*:role/ECIRamRoleTest"
    }
  ],
  "Version": "1"
}

Ganti ECIRamRoleTest dengan nama peran sebenarnya jika Anda menggunakan nama berbeda di Langkah 1.

Langkah 4: Tetapkan peran ke instans Elastic Container Instance

Saat memanggil CreateContainerGroup, atur parameter RamRoleName ke nama peran yang dibuat di Langkah 1.

Setiap instans Elastic Container Instance hanya mendukung satu instance RAM role. Jika peran sudah ditetapkan, upaya menetapkan peran lain akan mengembalikan error.

Langkah 5: Ambil dan gunakan kredensial STS

Ambil token STS

Dari dalam pod, kueri titik akhir metadata instans:

curl http://100.100.100.200/latest/meta-data/ram/security-credentials/ECIRamRoleTest

Ganti ECIRamRoleTest dengan nama peran sebenarnya Anda. Responsnya akan tampak seperti:

{
  "AccessKeyId": "STS.******",
  "AccessKeySecret": "******",
  "Expiration": "2023-06-22T19:13:58Z",
  "SecurityToken": "******",
  "LastUpdated": "2023-06-22T13:13:58Z",
  "Code": "Success"
}
FieldDeskripsi
AccessKeyIdID kunci akses sementara (diawali dengan STS.)
AccessKeySecretRahasia kunci akses sementara
SecurityTokenToken sesi yang diperlukan bersama AccessKeyId dan AccessKeySecret saat memanggil API layanan
ExpirationTimestamp UTC saat token kedaluwarsa; token STS diperbarui secara otomatis dan berkala
LastUpdatedTimestamp UTC saat token terakhir diperbarui
CodeSuccess menunjukkan kredensial valid

Gunakan token STS untuk mengakses layanan Alibaba Cloud

Contoh Go berikut mengambil kredensial dari metadata instans dan menggunakannya untuk mencantumkan objek dalam bucket OSS. Kredensial dibaca dari titik akhir metadata—tidak ada pasangan AccessKey statis dalam kode.

Contoh ini menunjukkan pola pengambilan kredensial. Di lingkungan produksi, sesuaikan kode dengan kebutuhan aplikasi Anda dan rujuk dokumentasi SDK untuk layanan target.
package main

import (
	"encoding/json"
	"flag"
	"log"
	"os/exec"

	"github.com/aliyun/aliyun-oss-go-sdk/oss"
)

const (
	securityCredUrl = "http://100.100.100.200/latest/meta-data/ram/security-credentials/"
)

var (
	ossEndpoint   string
	ossBucketName string
)

func init() {
	flag.StringVar(&ossEndpoint, "endpoint", "oss-cn-hangzhou-internal.aliyuncs.com", "Titik akhir OSS (disarankan menggunakan titik akhir internal, misalnya oss-cn-hangzhou-internal.aliyuncs.com)")
	flag.StringVar(&ossBucketName, "bucket", "", "Nama bucket OSS")
}

type AssumedRoleUserCredentialsWithServiceIdentity struct {
	AccessKeyId     string `json:"AccessKeyId" xml:"AccessKeyId"`
	AccessKeySecret string `json:"AccessKeySecret" xml:"AccessKeySecret"`
	Expiration      string `json:"Expiration" xml:"Expiration"`
	SecurityToken   string `json:"SecurityToken" xml:"SecurityToken"`
	LastUpdated     string `json:"LastUpdated" xml:"LastUpdated"`
	Code            string `json:"Code" xml:"Code"`
}

func main() {
	flag.Parse()

	if ossEndpoint == "" {
		log.Fatal("Titik akhir OSS wajib diisi, misalnya oss-cn-hangzhou-internal.aliyuncs.com")
	}
	if ossBucketName == "" {
		log.Fatal("Nama bucket OSS wajib diisi")
	}

	output, err := exec.Command("curl", securityCredUrl).Output()
	if err != nil {
		log.Fatalf("Gagal mendapatkan nama peran RAM dari server metadata: %s", err)
	}

	output, err = exec.Command("curl", securityCredUrl+string(output)).Output()
	if err != nil {
		log.Fatalf("Gagal mendapatkan kredensial STS dari server metadata: %s", err)
	}

	authServiceIdentity := new(AssumedRoleUserCredentialsWithServiceIdentity)
	if err := json.Unmarshal(output, authServiceIdentity); err != nil {
		log.Fatalf("Gagal mengurai kredensial STS: %s", err)
	}

	// Buat klien OSS menggunakan kredensial STS. Di lingkungan produksi, perbarui klien
	// sebelum token kedaluwarsa untuk menghindari kegagalan akses.
	ossClient, err := oss.New(ossEndpoint, authServiceIdentity.AccessKeyId,
		authServiceIdentity.AccessKeySecret, oss.SecurityToken(authServiceIdentity.SecurityToken))
	if err != nil {
		log.Fatalf("Gagal membuat klien OSS: %s", err)
	}

	// Dapatkan handle bucket.
	bucket, err := ossClient.Bucket(ossBucketName)
	if err != nil {
		log.Fatalf("Gagal mendapatkan bucket %q: %s", ossBucketName, err)
	}

	// Cantumkan objek dalam bucket. Secara default, hingga 100 objek dikembalikan per panggilan.
	marker := ""
	for {
		lsRes, err := bucket.ListObjects(oss.Marker(marker))
		if err != nil {
			log.Fatalf("Gagal mencantumkan objek dalam bucket %q: %s", ossBucketName, err)
		}
		for _, object := range lsRes.Objects {
			log.Println("Object:", object.Key)
		}
		if lsRes.IsTruncated {
			marker = lsRes.NextMarker
		} else {
			break
		}
	}
}

Langkah selanjutnya