Saat men-deploy ratusan aplikasi berbasis kontainer, menyematkan kredensial statis di setiap gambar menciptakan risiko keamanan "last key" dan meningkatkan beban pemeliharaan. Anda dapat men-deploy KMS Agent sebagai sidecar di kluster ACK untuk mengambil secrets secara dinamis dari Key Management Service (KMS) menggunakan mekanisme RRSA, sehingga menghilangkan kebutuhan integrasi SDK dalam kode aplikasi.
Konsep utama
Pahami konsep-konsep berikut sebelum melanjutkan:
Apa itu KMS Agent: KMS Agent adalah layanan proxy HTTP yang mengambil secrets dari KMS dan menyimpannya dalam cache di memori. Aplikasi mengambil secrets dari agent melalui permintaan HTTP.
RAM Roles for Service Accounts (RRSA): RRSA memungkinkan Anda mengisolasi izin aplikasi di kluster ACK dengan mengikat peran RAM berbeda ke Pod berbeda. Setiap aplikasi mengasumsikan peran RAM independen untuk mengakses API Alibaba Cloud.
Kasus penggunaan
Gunakan KMS Agent dengan RRSA dalam skenario berikut:
Menghilangkan masalah "last key"
Menyimpan kredensial sensitif di KMS meningkatkan keamanan, tetapi mengakses KMS sendiri memerlukan autentikasi. Mengandalkan AccessKey statis untuk mengakses KMS menciptakan risiko keamanan baru.
Dengan mengaktifkan RRSA pada kluster ACK, setiap Pod dapat mengasumsikan peran RAM berbeda dan menggunakan kredensial keamanan sementara untuk mengakses KMS. Hal ini menerapkan prinsip hak istimewa minimal dan menghilangkan kebutuhan AccessKey statis, sehingga mencegah kebocoran kredensial.
Mengisolasi akses secret antar aplikasi dan lingkungan
Anda perlu membatasi akses ke secrets antara lingkungan pengujian dan produksi, atau antara aplikasi berbeda, untuk mencegah peningkatan hak istimewa dan akses secret tidak sah.
Dengan RRSA, setiap aplikasi berjalan di namespace terpisah dengan akun layanan dan peran RAM-nya sendiri. Memberikan izin berbeda kepada setiap peran RAM memberlakukan kontrol akses detail halus terhadap secrets KMS.
Mengurangi biaya integrasi KMS dalam skala besar
Integrasi SDK KMS tidak berskala baik untuk perusahaan dengan ratusan aplikasi. Menjamin caching, pemulihan bencana, dan standar keamanan yang konsisten di seluruh aplikasi sangat sulit, terutama ketika tim keamanan, operasi, dan pengembangan terpisah.
KMS Agent mengatasi hal ini dengan berjalan sebagai sidecar di Pod yang sama dengan aplikasi Anda. Setelah RRSA diaktifkan, agent secara otomatis melakukan autentikasi ke KMS dan menyimpan secrets dalam cache di memori. Aplikasi Anda mengambil secrets dari agent lokal tanpa perlu integrasi SDK apa pun.
Arsitektur solusi
Gambar berikut menunjukkan contoh dengan dua aplikasi: dev dan prod. Setiap aplikasi hanya dapat mengakses secrets KMS miliknya sendiri.
Batasan
Jenis kluster ACK yang didukung: Kluster ACK yang dikelola, Cluster khusus ACK, kluster terdaftar ACK, dan kluster ACK Serverless.
Kluster ACK dan instans KMS harus berada di wilayah yang sama.
Prasyarat
Docker telah diinstal dan dikonfigurasi di mesin build Anda.
kubectl telah dikonfigurasi dengan akses ke kluster ACK Anda.
Anda memiliki Akun Alibaba Cloud dengan izin RAM dan KMS yang diperlukan.
Instans KMS ada di wilayah yang sama dengan kluster ACK Anda.
Go 1.18 atau versi lebih baru telah diinstal.
Git telah diinstal.
Prosedur
Prosedur ini menjelaskan konfigurasi ACK, RAM, dan KMS yang diperlukan agar aplikasi dapat mengambil secrets melalui KMS Agent. Pengembang hanya perlu membuat secret di KMS dan membacanya secara lokal — tim operasi dan keamanan menangani penyiapan infrastruktur sebelumnya. Tidak diperlukan integrasi SDK, logika autentikasi, atau desain caching dalam kode aplikasi.
Langkah 1: Membuat executable KMS Agent
Instal Go. Untuk instruksi, lihat panduan instalasi Go.
Unduh kode sumber dan dependensi.
Unduh dan instal Git dari situs web resmi Git.
Jalankan perintah berikut untuk mengkloning repositori dan mengunduh dependensi:
git clone https://github.com/aliyun/alibabacloud-kms-agent go mod download
Di direktori root proyek, jalankan
go build .untuk mengompilasi executable. Nama executable default adalahalibabacloud-kms-agent, disimpan di direktori root proyek.Jika lingkungan build dan lingkungan deployment sama, jalankan
go build .secara langsung. Untuk build lintas platform, gunakan perintah berikut untuk menghasilkan executable 64-bit:Lingkungan build
Deploy ke macOS
Deploy ke Linux
Deploy ke Windows
macOS
go build .CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build .CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build .Linux
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build .go build .CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build .Windows
SET CGO_ENABLED=0 && SET GOOS=darwin && SET GOARCH=amd64 && go build .SET CGO_ENABLED=0 && SET GOOS=linux && SET GOARCH=amd64 && go build .go build .Di direktori root proyek, pastikan executable
alibabacloud-kms-agenttersedia.
Langkah 2: Mengaktifkan RRSA dan mengotorisasi akses ke secrets
Aktifkan RRSA untuk kluster ACK Anda.
Aktifkan saat pembuatan kluster
Saat membuat ACK managed cluster dan ACK Edge cluster, Anda dapat mengaktifkan RRSA di bagian Advanced Options (Optional) pada konfigurasi kluster.
Aktifkan di halaman informasi kluster
-
Masuk ke Konsol ACK. Di panel navigasi kiri, klik Clusters.
-
Di halaman Clusters, klik nama kluster Anda. Di panel navigasi kiri, klik Cluster Information.
Di tab Basic Information, pada bagian Security and Auditing, klik Enable di sebelah RRSA OIDC.
Di kotak dialog Enable RRSA, klik OK.
CatatanDi halaman Basic Information, ketika status kluster berubah dari Updating menjadi Running, fitur RRSA telah diaktifkan untuk kluster tersebut.
-
Buka halaman detail kluster. Di tab Basic Information, pada bagian Security and Auditing, arahkan kursor ke status aktif di sebelah RRSA OIDC untuk melihat URL penyedia dan ARN. Setelah RRSA diaktifkan, bagian ini menampilkan Provider URL dan Provider ARN RRSA OIDC. Anda memerlukan kedua nilai ini saat mengonfigurasi kebijakan kepercayaan peran RAM.
Buat peran RAM dengan penyedia identitas sebagai entitas tepercaya.
Masuk ke Konsol RAM sebagai administrator RAM. Di panel navigasi kiri, pilih .
Klik Create Role. Di halaman pembuatan, klik Switch to Policy Editor di pojok kanan atas.
Di editor, tentukan penyedia identitas OIDC. Pilih mode Visual Editor dan konfigurasikan pengaturan berikut:
CatatanUntuk informasi lebih lanjut tentang mode lainnya, lihat Membuat peran RAM untuk penyedia identitas OIDC.
Di bagian Principal, pilih IdP, lalu klik Edit.
Di kotak dialog Add Principal, konfigurasikan parameter berikut:
IdP Type: Pilih OIDC.
IdP: Setelah RRSA diaktifkan, ACK membuat penyedia identitas default bernama
ack-rrsa-<cluster_id>, dengan<cluster_id>sebagai ID kluster Anda.Action: Pertahankan nilai default
sts:AssumeRole.Condition: Tambahkan kondisi baru di samping kondisi default
oidc:issdanoidc:aud:Condition key: Pilih oidc:sub.
Operator: Pilih StringEquals.
Condition value: Masukkan
system:serviceaccount:<namespace>:<serviceAccountName>.<namespace>: Namespace tempat aplikasi berada.<serviceAccountName>: Nama akun layanan.
Contoh ini menggunakan
system:serviceaccount:rrsa-dev:dev-sa, denganrrsa-devsebagai namespace Kubernetes dandev-sasebagai akun layanan yang akan Anda buat di Langkah 3.
Di kotak dialog Create Role, atur nama peran lalu klik OK. Contoh ini menggunakan
dev-role-for-rrsa.Tinjau kebijakan kepercayaan untuk
dev-role-for-rrsa. Kebijakan ini memungkinkan akun layanan tertentu mengasumsikan peran RAM melalui RRSA setelah lolos autentikasi OIDC.{ "Statement": [ { "Action": "sts:AssumeRole", "Condition": { "StringEquals": { "oidc:aud": [ "sts.aliyuncs.com" ], "oidc:iss": [ "https://oidc-ack-cn-hongkong.oss-cn-hongkong.aliyuncs.com/cf01******" ], "oidc:sub": [ "system:serviceaccount:rrsa-dev:dev-sa" ] } }, "Effect": "Allow", "Principal": { "Federated": [ "acs:ram::5269************:oidc-provider/ack-rrsa-cf01******" ] } } ], "Version": "1" }
Buat kebijakan izin dan sambungkan ke peran RAM.
Buat kebijakan izin. Contoh ini menggunakan nama kebijakan
dev-role-for-rrsa-kms-policydan hanya mengizinkan akses ke secrets yang ditandai dengan tagenv:dev.
Konten kebijakan sebagai berikut:
{ "Version": "1", "Statement": [ { "Effect": "Allow", "Action": [ "kms:Decrypt", "kms:GetSecretValue" ], "Resource": "*", "Condition": { "StringEqualsIgnoreCase": { "kms:tag/env": [ "dev" ] } } } ] }Sambungkan kebijakan
dev-role-for-rrsa-kms-policyke perandev-role-for-rrsa.
Langkah 3: Membuat namespace dan akun layanan
Namespace membagi kluster ACK menjadi ruang virtual yang terisolasi secara logis untuk lingkungan berbeda seperti pengembangan, pengujian, dan produksi. Secara default, aplikasi di namespace berbeda tidak dapat mengakses resource satu sama lain. Akun layanan menyediakan identitas untuk Pod dan secara dinamis mengikat ke peran RAM melalui RRSA.
Buat file YAML namespace.
Buat file bernama
namespace.yamldengan konten berikut. Contoh ini membuat namespace bernamarrsa-dev.apiVersion: v1 kind: Namespace metadata: name: rrsa-devJalankan perintah berikut untuk membuat namespace:
kubectl apply -f namespace.yamlVerifikasi namespace telah dibuat:
kubectl get namespacesJika output mencakup
rrsa-dev, namespace berhasil dibuat.Buat file YAML akun layanan.
Buat file bernama
serviceaccount.yamldengan konten berikut. Contoh ini membuat akun layanan bernamadev-sadi namespacerrsa-dev.apiVersion: v1 kind: ServiceAccount metadata: name: dev-sa namespace: rrsa-devJalankan perintah berikut untuk membuat akun layanan:
kubectl apply -f serviceaccount.yamlVerifikasi akun layanan telah dibuat:
kubectl get serviceaccount -n rrsa-devJika output mencakup
dev-sa, akun layanan berhasil dibuat.
Langkah 4: Membuat image kontainer sidecar
Kemas KMS Agent sebagai kontainer sidecar untuk dideploy bersama aplikasi Anda di ACK.
Konfigurasikan parameter runtime KMS Agent di
config.toml.CatatanFile
config.tomlberada di direktoriconfigsdari kode sumber alibabacloud-kms-agent yang diperoleh di Langkah 1.[Server] HttpPort = 2025 [KMS] Region = "cn-hangzhou" [Cache] CacheType = "InMemory" CacheSize = 1000 TtlSeconds = 300 [Log] LogLevel = "Debug" LogPath = "./logs/" MaxSize = 100 MaxBackups = 2Buat
Dockerfile.Sebagai contoh, buat Dockerfile di
deploy/ack/agentuntuk men-deploy agent. Untuk konten file, lihat agent_Dockerfile.# Gunakan image centos sebagai dasar FROM centos:centos7 # Atur direktori kerja di dalam kontainer WORKDIR /usr/local/alibabacloudkmsagent # Salin binary dan konfigurasi ke kontainer COPY alibabacloud-kms-agent . COPY config.toml . # Atur entry point untuk menjalankan kms agent ENTRYPOINT ["./alibabacloud-kms-agent", "agent", "./config.toml"]Salin executable dan konfigurasi ke direktori
deploy/ack/agent:deploy/ack/agent ├── alibabacloud-kms-agent ├── config.toml ├── Dockerfile.agentBuat image sidecar dan dorong ke Container Registry:
# Buat image. docker build -t registry.cn-hangzhou.aliyuncs.com/<ns>/<repo>:kmsagent-v1.0 . # Dorong image. docker push registry.cn-hangzhou.aliyuncs.com/<ns>/<repo>:kmsagent-v1.0
Langkah 5: Membuat image kontainer aplikasi
Untuk aplikasi yang dideploy di
deploy/ack/app, buat Dockerfile di direktori tersebut:# Gunakan image centos sebagai dasar FROM centos:centos7 # Atur direktori kerja di dalam kontainer WORKDIR / # Atur entry point untuk menjalankan kms agent ENTRYPOINT ["sleep", "360000"]Buat image aplikasi dan dorong ke Container Registry:
# Buat image. docker build -t registry.cn-hangzhou.aliyuncs.com/<ns>/<repo>:app-v1.0 . # Dorong image. docker push registry.cn-hangzhou.aliyuncs.com/<ns>/<repo>:app-v1.0
Langkah 6: Men-deploy aplikasi
Template penyebaran kustom
Definisikan Deployment kustom yang menjalankan KMS Agent sebagai sidecar bersama kontainer aplikasi di Pod yang sama. Untuk informasi lebih lanjut tentang menjalankan aplikasi berbasis kontainer, lihat Membuat Penyebaran workload tanpa status.
KMS_TOKEN: Jalur penyimpanan file token SSRF yang dihasilkan oleh agent saat startup.ALIBABA_CLOUD_ROLE_ARN: ARN peran RAM.ALIBABA_CLOUD_OIDC_PROVIDER_ARN: ARN penyedia identitas OIDC (ARN kluster ACK).ALIBABA_CLOUD_OIDC_TOKEN_FILE: Jalur ke file yang berisi token OIDC.
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
namespace: rrsa-dev
spec:
replicas: 1
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
serviceAccountName: dev-sa
containers:
- name: kmsagent
image: registry-vpc.cn-hangzhou.aliyuncs.com/<ns>/<repo>:kmsagent-v1.0
env:
- name: ALIBABA_CLOUD_ROLE_ARN
value: acs:ram::<uid>:role/dev-role-for-rrsa
- name: ALIBABA_CLOUD_OIDC_PROVIDER_ARN
value: acs:ram::<uid>:oidc-provider/ack-rrsa-<ackClusterId>
- name: ALIBABA_CLOUD_OIDC_TOKEN_FILE
value: /var/run/secrets/ack.alibabacloud.com/rrsa-tokens/token
- name: KMS_TOKEN
value: file:///var/run/kmstoken/token
volumeMounts:
- name: shared-volume
mountPath: /var/run/kmstoken
- name: rrsa-oidc-token
mountPath: /var/run/secrets/ack.alibabacloud.com/rrsa-tokens
readOnly: true
command: ["/bin/sh", "-c", "./alibabacloud-kms-agent token /var/run/kmstoken/token && ./alibabacloud-kms-agent agent config.toml"]
- name: my-app
image: registry-vpc.cn-hangzhou.aliyuncs.com/<ns>/<repo>:app-v1.0
volumeMounts:
- name: shared-volume
mountPath: /var/run/kmstoken
volumes:
- name: shared-volume
emptyDir: {}
- name: rrsa-oidc-token
projected:
defaultMode: 420
sources:
- serviceAccountToken:
audience: sts.aliyuncs.com
expirationSeconds: 3600
path: tokenInjeksi OpenKruise
OpenKruise adalah ekstensi Kubernetes standar yang secara efisien mengelola kontainer aplikasi, kontainer sidecar, dan distribusi image. Untuk informasi lebih lanjut, lihat Men-deploy aplikasi cloud-native menggunakan OpenKruise.
Instal OpenKruise.
-
Masuk ke Konsol ACK. Di panel navigasi kiri, klik Clusters.
-
Di halaman Clusters, klik nama kluster Anda. Di panel navigasi kiri, klik Components and Add-ons .
Di halaman Add-ons, klik tab Manage Applications dan cari ack-kruise.
Di kolom Actions, klik Install Now.
Di halaman Install Component, konfirmasi informasi komponen lalu klik OK.
-
Konfigurasikan aturan injeksi sidecar.
Definisikan SidecarSet yang menginjeksikan sidecar KMS Agent ke Pod dengan label
app.Variabel lingkungan:
KMS_TOKEN: Jalur penyimpanan file token SSRF yang dihasilkan oleh agent saat startup.ALIBABA_CLOUD_ROLE_ARN: ARN peran RAM.ALIBABA_CLOUD_OIDC_PROVIDER_ARN: ARN penyedia identitas OIDC (ARN kluster ACK).ALIBABA_CLOUD_OIDC_TOKEN_FILE: Jalur ke file yang berisi token OIDC.
selector: memilih Pod untuk diinjeksi sidecar. Ubah pemilih label agar sesuai dengan aplikasi Anda.
apiVersion: apps.kruise.io/v1alpha1 kind: SidecarSet metadata: name: kms-agent-sidecarset namespace: rrsa-dev spec: serviceAccountName: dev-sa containers: - name: kms-agent image: registry-vpc.cn-hangzhou.aliyuncs.com/<ns>/<repo>:kmsagent-v1.0 env: - name: ALIBABA_CLOUD_ROLE_ARN value: acs:ram::<uid>:role/dev-role-for-rrsa - name: ALIBABA_CLOUD_OIDC_PROVIDER_ARN value: acs:ram::<uid>:oidc-provider/ack-rrsa-<ackClusterId> - name: ALIBABA_CLOUD_OIDC_TOKEN_FILE value: /var/run/secrets/ack.alibabacloud.com/rrsa-tokens/token - name: KMS_TOKEN value: file:///var/run/kmstoken/token volumeMounts: - name: shared-volume mountPath: /var/run/kmstoken - name: rrsa-oidc-token mountPath: /var/run/secrets/ack.alibabacloud.com/rrsa-tokens readOnly: true command: ["/bin/sh", "-c", "./alibabacloud-kms-agent token /var/run/kmstoken/token && ./alibabacloud-kms-agent agent config.toml"] # Ubah selector agar sesuai dengan Pod aplikasi Anda. selector: matchLabels: app: app volumes: - name: shared-volume emptyDir: {} - name: rrsa-oidc-token projected: defaultMode: 420 sources: - serviceAccountToken: audience: sts.aliyuncs.com expirationSeconds: 3600 path: tokenDeploy aplikasi dengan injeksi KMS Agent otomatis.
Buat Deployment dengan label
app: appagar sidecar secara otomatis diinjeksikan.apiVersion: apps/v1 kind: Deployment metadata: name: app-with-kmsagent namespace: rrsa-dev spec: replicas: 1 selector: matchLabels: app: app template: metadata: labels: app: app spec: serviceAccountName: dev-sa containers: - name: my-app image: registry-vpc.cn-hangzhou.aliyuncs.com/<ns>/<repo>:app-v1.0 volumeMounts: - name: shared-volume mountPath: /var/run/kmstoken volumes: - name: shared-volume emptyDir: {}Jalankan aplikasi berbasis kontainer Anda. Untuk informasi lebih lanjut, lihat Membuat Penyebaran workload tanpa status.
Setelah aplikasi dimulai, sidecar KMS Agent diinjeksikan ke Pod.
Di halaman Stateless, Anda dapat menemukan Deployment yang namanya diawali dengan
ack-kms-agent. Jumlah pod menunjukkan 2/2, yang mengindikasikan bahwa kontainer sidecar telah diinjeksikan dan berjalan dengan baik.
Langkah 7: Membuat dan mengambil secret
Buat secret di KMS.
Tambahkan tag
env:devsaat membuat secret. Kontainer aplikasi hanya dapat mengakses secrets dengan tag ini.Masuk ke Konsol Key Management Service. Di bilah navigasi atas, pilih wilayah. Di panel navigasi kiri, pilih .
Klik tab Generic Secrets, pilih Instance ID, lalu klik Create Secret. Konfigurasikan parameter lalu klik OK.
Parameter
Deskripsi
Secret Name
Nama kredensial kustom. Harus unik dalam wilayah saat ini.
Secret Value
Pilih Secret Key/Value atau Plain Text lalu masukkan data sensitif yang akan disimpan. Nilai maksimal 30.720 byte (30 KB).
Initial Version
Nomor versi awal. Nilai default: v1. Nilai kustom didukung.
CMK
Pilih kunci simetris yang digunakan untuk mengenkripsi nilai kredensial. Kunci dan kredensial harus berada di instans KMS yang sama.
PentingKunci dan kredensial harus berada di instans KMS yang sama, dan kunci harus berupa kunci simetris. Untuk informasi lebih lanjut tentang kunci simetris yang didukung oleh KMS, lihat Jenis dan spesifikasi kunci.
Jika menggunakan Pengguna RAM atau Peran RAM, harus memiliki izin untuk melakukan operasi GenerateDataKey menggunakan kunci master enkripsi.
Description
Deskripsi opsional kredensial untuk identifikasi dan manajemen.
Atur kebijakan akses untuk kredensial guna mengontrol Pengguna RAM atau peran mana yang dapat membaca atau mengubahnya.
Anda dapat memilih kebijakan default terlebih dahulu lalu mengubahnya sesuai kebutuhan.
Ambil nilai secret.
Gunakan perintah
curl:curl -v -H "X-KMS-Token:$(</var/run/kmstoken/token)" 'http://localhost:2025/secretsmanager/get?secretId=app/dev/secret-1'Ambil secret dalam kode aplikasi Anda melalui permintaan HTTP GET:
package main import ( "fmt" "io/ioutil" "net/http" ) func main() { url := fmt.Sprintf("http://localhost:2025/secretsmanager/get?secretId=%s", "app/dev/secret-1") token, err := ioutil.ReadFile("/var/run/kmstoken/token") if err != nil { fmt.Printf("error reading token file: %v\n", err) } req, err := http.NewRequest("GET", url, nil) if err != nil { fmt.Printf("error creating request: %v\n", err) } req.Header.Add("X-KMS-Token", string(token)) client := &http.Client{} resp, err := client.Do(req) if err != nil { fmt.Printf("error sending request: %v \n", err) } defer resp.Body.Close() body, _ := ioutil.ReadAll(resp.Body) fmt.Printf("status code %d - %s \n", resp.StatusCode, string(body)) }