مدیریت خودکار اعتبارنامه های AWS ECR در یک خوشه Kubernetes

در جریان کار من با AWS ECR (رجیستری کانتینر الاستیک)، به مشکلی برخوردم: کلید دسترسی به مخزن هر شش ساعت یکبار منقضی می شود. با کار با یک خوشه آزمایشی غیر AWS Kubernetes، مجبور شدم دائماً این اعتبارنامه ها را به صورت دستی به روز کنم، فرآیندی تکراری و خسته کننده.
از این تجربه ایده ایجاد ابزاری که این فرآیند را خودکار میکند به وجود آمد: k8s-aws-ecr-secret-updater. این ابزار یک cronjob Kubernetes است که برای بهروزرسانی خودکار اعتبار دسترسی به مخزن AWS ECR طراحی شده است.
پیکربندی Cronjob
کد YAML برای ایجاد cronjob از چندین بخش تشکیل شده است که اکنون قسمت به قسمت آن ها را تجزیه و تحلیل می کنم:
نقشی که مجوز دریافت، ایجاد و حذف اسرار و دریافت و بهروزرسانی حسابهای سرویس را دارد.
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: k8sawsecrsecretupdater
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "create", "delete"]
- apiGroups: [""]
resources: ["serviceaccounts"]
verbs: ["get", "patch"]
یک جزء کلیدی این پیکربندی است k8sawseccrecretupdater نقش. این نقش برای مجوز در فضای نام Kubernetes اساسی است و به cronjob اجازه می دهد تا عملیات خاصی را روی منابع خاصی انجام دهد.
به طور خاص، k8sawseccrecretupdater نقش دارای مجوزهای زیر است:
- این مجوز برای دریافت (گرفتن)، ايجاد كردن (ايجاد كردن، و حذف (حذف) اسرار. این بسیار مهم است زیرا cronjob باید بتواند اعتبارنامه های AWS ECR را ایجاد و حذف کند، که به عنوان راز در Kubernetes ذخیره می شوند.
- این مجوز برای دریافت (گرفتن) و به روز رسانی (پچ) حساب های سرویس. cronjob باید بتواند حساب های سرویس را مدیریت کند تا اعتبارنامه AWS ECR را با سرویسی که cronjob را اجرا می کند مرتبط کند.
ایجاد یک نقش خاص برای این عملیات تضمین می کند که cronjob دقیقاً مجوزهایی را دارد که برای انجام کار خود نیاز دارد، بدون اینکه به منابع غیر ضروری دسترسی داشته باشد. این رویکرد با اصل کمترین امتیاز، یک رویه امنیتی رایج است که دسترسی به منابع را فقط به آنچه برای انجام یک کار خاص ضروری است محدود میکند. این کمک می کند تا تأثیر احتمالی یک حمله احتمالی به حداقل برسد.
ServiceAccount برای استفاده از job و cronjob.
apiVersion: v1
kind: ServiceAccount
metadata:
name: k8sawsecrsecretupdater
RoleBinding برای مرتبط کردن نقش با ServiceAccount.
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: k8sawsecrsecretupdater
subjects:
- kind: ServiceAccount
name: k8sawsecrsecretupdater
roleRef:
kind: Role
name: k8sawsecrsecretupdater
apiGroup: rbac.authorization.k8s.io
شغلی که راز را ایجاد می کند.
apiVersion: batch/v1
kind: Job
metadata:
name: k8sawsecrsecretupdater
spec:
backoffLimit: 4
template:
spec:
serviceAccountName: k8sawsecrsecretupdater
restartPolicy: Never
containers:
- name: k8sawsecrsecretupdater
image: ghcr.io/paranoiasystem/k8s-aws-ecr-secret-updater:latest
imagePullPolicy: Always
env:
- name: AWS_ACCOUNT
value: 'YourAwsAccountID'
- name: AWS_ACCESS_KEY_ID
value: YourAccessKeyID
- name: AWS_SECRET_ACCESS_KEY
value: YourSecretAccessKey
- name: AWS_REGION
value: YourRegion
CronJob که هر 6 ساعت کار را اجرا می کند.
apiVersion: batch/v1
kind: CronJob
metadata:
name: k8sawsecrsecretupdater
spec:
schedule: "0 */6 * * *"
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 1
jobTemplate:
spec:
template:
spec:
serviceAccountName: k8sawsecrsecretupdater
restartPolicy: Never
containers:
- name: k8sawsecrsecretupdater
image: ghcr.io/paranoiasystem/k8s-aws-ecr-secret-updater:latest
imagePullPolicy: Always
env:
- name: AWS_ACCOUNT
value: 'YourAwsAccountID'
- name: AWS_ACCESS_KEY_ID
value: YourAccess
- name: AWS_SECRET_ACCESS_KEY
value: YourSecretAccessKey
- name: AWS_REGION
value: YourRegion
ایجاد تصویر داکر
cronjob از یک تصویر داکر خاص برای انجام وظیفه خود استفاده می کند. این تصویر Docker از Dockerfile زیر ساخته شده است:
در Dockerfile، با شروع از یک تصویر پایه Alpine، ابزارهای لازم از جمله git، bash، curl، openssh، python3، py3-pip، py-cryptography، wget، curl، jq نصب میشوند. همچنین، kubectl و AWSCLI به ترتیب برای تعامل با Kubernetes و AWS نصب شده اند.
پس از آن، دایرکتوری کاری به /scripts تنظیم می شود و محتویات دایرکتوری /scripts محلی کپی می شود. در نهایت، یک ENTRYPOINT تعریف می شود که اسکریپت enterpoint.sh را هنگام اجرا شدن کانتینر شروع می کند.
اجرای اسکریپت
هنگامی که cronjob اجرا می شود، اسکریپت bash موجود در تصویر Docker را شروع می کند. این اسکریپت وجود یک راز به نام را بررسی می کند "regcred"
. اگر وجود داشته باشد، آن را حذف می کند و یک مورد جدید ایجاد می کند. اگر وجود نداشته باشد، آن را ایجاد می کند. در زیر فیلمنامه آمده است:
#!/bin/bash
create_secret() {
kubectl create secret docker-registry regcred \
--docker-server=${AWS_ACCOUNT}.dkr.ecr.${AWS_REGION}.amazonaws.com \
--docker-username=AWS \
--docker-password=$(aws ecr get-login-password --region ${AWS_REGION})
}
# Check if the secret exists
if kubectl get secret regcred; then
# If it exists, delete it
kubectl delete secret regcred
# Create the secret again
create_secret
else
# If it doesn't exist, create it
create_secret
fi
نصب k8s-aws-ecr-secret-updater در Kubernetes
برای استفاده از k8s-aws-ecr-secret-updater در محیط Kubernetes خود، باید چند مرحله ساده را دنبال کنید.
بیایید با شبیه سازی مخزن GitHub پروژه در سیستم محلی خود شروع کنیم:
git clone https://github.com/paranoiasystem/k8s-aws-ecr-secret-updater
در مرحله بعد، باید آن را باز کرده و ویرایش کنید install.yaml فایل موجود در مخزن در این فایل باید مقادیر زیر را تنظیم کنید:
- AWS_ACCOUNT: شناسه حساب AWS شما.
- AWS_ACCESS_KEY_ID: کلید دسترسی AWS شما.
- AWS_SECRET_ACCESS_KEY: کلید دسترسی مخفی AWS شما.
- AWS_REGION: منطقه AWS که ECR شما در آن قرار دارد.
پس از انجام این تغییرات، فایل install.yaml را ذخیره کرده و از آن خارج شوید.
حالا برای نصب k8s-aws-ecr-secret-updater در خوشه Kubernetes خود، باید دستور زیر را اجرا کنید:
kubectl apply -n <destination_namespace> -f install.yaml
به یاد داشته باشید که جایگزین کنید مقصد_نام فضای با فضای نام Kubernetes جایی که می خواهید cronjob را نصب کنید.
نتیجه گیری
این ابزار نیاز به به روز رسانی دستی اعتبارنامه ها، صرفه جویی در زمان و کاهش خطر خطا را برطرف می کند. امیدوارم این مقاله و ابزاری که من ایجاد کردم بتواند به هر کسی که با یک مشکل مشابه در مدیریت اعتبارنامه AWS ECR در یک خوشه Kubernetes سر و کار دارد کمک کند.