خدمات مدیریت کلیدی در Kubernetes – قسمت 2

به سری ما در مورد خدمات مدیریت کلیدی (KMS) در Kubernetes خوش آمدید! در قسمت 1 ، ما زمینه را گذاشتیم. اکنون ، در قسمت 2 ، ما در حال غوطه ور شدن به مفهوم مهم رمزگذاری در حالت استراحت هستیم.
رمزگذاری در حالت استراحت دقیقاً چیست؟
به عبارت ساده ، رمزگذاری در حالت استراحت در Kubernetes به نحوه سرور API قبل از ذخیره در ETCD ، داده ها را رمزگذاری می کندبشر به عنوان مغز خوشه Kubernetes خود فکر کنید – این جایی است که تمام داده های پیکربندی خوشه ای شما ، حالت و اسرار زندگی می کنند.
به طور پیش فرض ، سرور API Kubernetes منابع را در ETCD ذخیره می کند متن سادهبشر این بدان معناست که اگر کسی دسترسی غیرمجاز به ETCD شما را بدست آورد ، می تواند تمام داده های حساس شما ، از جمله رازها را بدون هیچ تلاشی بخواند. این یک خطر امنیتی قابل توجه است.
در حالی که رمزگذاری در استراحت مربوط به هر منبع Kubernetes است ، در این سری ، ما همچنان به آن توجه خواهیم کرد اسرار به دلیل ماهیت ذاتی آنها.
خبر خوب این است که Kubernetes راهی برای رمزگذاری این داده ها قبل از بازدید و غیره فراهم می کند. این در درجه اول از طریق --encryption-provider-config
استدلال به kube-apiserver
فرآیند ، که به یک پرونده پیکربندی اشاره می کند.
معرفی رمزنگاری کنفرانس
در Kubernetes ، رمزگذاری در رفتار استراحت با استفاده از یک EncryptionConfiguration
منبع این پیکربندی قدرتمند به شما امکان می دهد تا مشخص کنید که کدام منابع باید رمزگذاری شوند و با استفاده از کدام ارائه دهندگان رمزگذاری.
بیایید برای درک ساختار آن به یک پیکربندی مثال نگاه کنیم:
# CAUTION: This is an example configuration and should NOT be used for production clusters without careful consideration.
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
- configmaps
- pandas.awesome.bears.example # An example custom resource API
providers:
# The 'identity' provider stores resources as plain text (no encryption).
# If listed first, it means data is NOT encrypted.
- identity: {}
- aesgcm:
keys:
- name: key1
secret: c2VjcmV0IGlzIHNlY3VyZQ== # Base64 encoded key
- name: key2
secret: dGhpcyBpcyBwYXNzd29yZA== # Base64 encoded key
- aescbc:
keys:
- name: key1
secret: c2VjcmV0IGlzIHNlY3VyZQ== # Base64 encoded key
- name: key2
secret: dGhpcyBpcyBwYXNzd29yZA== # Base64 encoded key
- secretbox:
keys:
- name: key1
secret: YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM0NTY= # Base64 encoded key
- resources:
- events
providers:
- identity: {} # Do not encrypt Events
- resources:
- '*.apps' # Wildcard match (Kubernetes 1.27+)
providers:
- aescbc:
keys:
- name: key2
secret: c2VjcmV0IGlzIHNlY3VyZSwgb3IgaXMgYXQ/Cg==
- resources:
- '*.*' # Wildcard match (Kubernetes 1.27+)
providers:
- aescbc:
keys:
- name: key3
secret: c2VjcmV0IGlzIHNlY3VyZSwgSSB0aGluaw==
غذای اصلی از EncryptionConfiguration
:
-
resources
: این آرایه مشخص می کند که از منابع Kubernetes می خواهید رمزگذاری را برای آن استفاده کنید. شما می توانید منابع خاص را هدف قرار دهید (به عنوان مثال ،secrets
) ، یا از مسابقات Wildcard استفاده کنید (به عنوان مثال ،'*.apps'
با'*.*'
) موجود در Kubernetes 1.27 و بعد. -
providers
: این یک لیست سفارش داده شده از ارائه دهندگان رمزگذاری است. Kubernetes سعی در استفاده از اولین ارائه دهنده در لیست برای رمزگذاری داده های جدید دارد. هنگام رمزگشایی ، ارائه دهندگان را به ترتیب تلاش می کند تا یک نفر موفق شود. -
identity
: {}: این ارائه دهنده معنی دارد بدون رمزگذاری؛ داده ها در متن ساده ذخیره می شوند. اگر این اولین ارائه دهنده یک منبع باشد ، به این معنی است که داده های جدید برای آن منبع رمزگذاری نمی شوند. -
aesgcm, aescbc, secretbox
: اینها الگوریتم های رمزگذاری متفاوت هستند. شما کلیدهای نامگذاری شده را تعریف می کنید (base64
رمزگذاری شده) برای هر یک.
نسخه ی نمایشی: رمزگذاری اسرار در Minikube
بیایید با استفاده از یک خوشه minikube برای دیدن رمزگذاری در حالت استراحت در یک نمونه عملی قدم بزنیم.
1. خوشه minikube خود را شروع کنید:
اطمینان حاصل کنید که خوشه Minikube شما در حال اجرا است.
2. ایجاد کنید EncryptionConfiguration
پرونده:
یک پرونده به نام ایجاد کنید encryption-conf.yaml
با محتوای زیر:
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets # We are only encrypting secrets for this demo
providers:
- aescbc: # Using AES-CBC encryption
keys:
- name: key1
# IMPORTANT: This is a randomly generated key.
# Use a strong, unique, and base64-encoded key in production.
secret: lvAp17Ae2o/yTdxz2qyC6zjVzuS+sBdhkwCccgsSsUg=
- identity: {} # Fallback to identity (plaintext) if AES-CBC fails, or for older data
درک پیکربندی نسخه ی نمایشی:
-
ما به طور خاص هدف قرار می دهیم
secrets
برای رمزگذاری -
ما در حال استفاده از
aescbc
ارائه دهنده با یک کلید واحد به نام Key1. به یاد داشته باشید که از یک کلید واقعاً تصادفی و قوی برای محیط های تولید استفاده کنید! درsecret
مقدار باید Base64 رمزگذاری شود. -
در
identity: {}
ارائه دهنده به عنوان یک برگشتی گنجانده شده است. این برای چرخش صاف و رمزگشایی داده های قدیمی بسیار مهم است ، یا اگر ارائه دهنده رمزگذاری اولیه با یک مسئله روبرو شود.
3. سرور API را پیکربندی کنید تا از پیکربندی رمزگذاری استفاده کنید:
اکنون ، ما باید بگوییم kube-apiserver
برای استفاده از این پرونده پیکربندی. در Minikube ، می توانید با اصلاح تعریف POD سرور API به این هدف برسید.
اول ، پیدا کردن kube-apiserver
تعریف POD (معمولاً در آن است /etc/kubernetes/manifests/
در گره هواپیمای کنترل).
بعد ، شما باید اصلاح کنید kube-apiserver
مانیفست غلاف استاتیک شامل موارد --encryption-provider-config
استدلال کنید و دایرکتوری حاوی خود را سوار کنید encryption-conf.yaml
پرونده
در اینجا مثالی از چگونگی kube-apiserver
قطعه مانیفست غلاف به دنبال اصلاح است:
apiVersion: v1
kind: Pod
metadata:
labels:
component: kube-apiserver
tier: control-plane
name: kube-apiserver
namespace: kube-system
spec:
containers:
- command:
- kube-apiserver
# ... other kube-apiserver arguments
- --encryption-provider-config=/etc/kubernetes/enc/encryption-conf.yaml # <--- Add this line
volumeMounts:
- mountPath: /etc/kubernetes/enc # <--- Mount path for your config file
name: enc-vol
readOnly: true
# ... other volume mounts
volumes:
- hostPath:
path: /etc/kubernetes/encryption # <--- Host path where your config file lives
type: DirectoryOrCreate
name: enc-vol
# ... other volumes
مهم: شما باید خود را قرار دهید encryption-conf.yaml
پرونده در /etc/kubernetes/encryption
دایرکتوری در Minikube VM (یا گره کنترل هواپیمای کنترل برای یک خوشه کامل) برای hostPath
میزان صدا برای کار صحیح.
پس از صرفه جویی در تغییرات ، kube-apiserver
POD با استفاده از پیکربندی رمزگذاری جدید ، به طور خودکار مجدداً راه اندازی می شود.
4. ایجاد یک راز:
بیایید یک راز جدید در یک فضای نام آزمایش ایجاد کنیم:
kubectl create namespace test
kubectl -n=test create secret generic new-secret --from-literal=key1=supersecret
5. راز را بازیابی کنید (همانطور که توسط kubectl
):
حال ، بیایید راز را با استفاده از kubectl
:
kubectl get secret new-secret -o yaml -n test
خروجی مشابه این را دریافت خواهید کرد:
apiVersion: v1
data:
key1: c3VwZXJzZWNyZXQ= # Still base64 encoded!
kind: Secret
metadata:
creationTimestamp: "2025-05-31T10:50:26Z"
name: new-secret
namespace: test
resourceVersion: "6614"
uid: a8655bde-be5f-4624-b905-61524de56ebe
type: Opaque
توجه کنید که data
زمینه هنوز نشان می دهد مقدار رمزگذاری شده BASE64بشر این بسیار مهم است: kubectl
همیشه اسرار را به شکل رمزگذاری شده Base64 خود نشان می دهد. این خروجی به ما نمی گوید که آیا راز در حالت استراحت در ETCD رمزگذاری شده است یا خیر.
6. رمزگذاری در ETCD را تأیید کنید:
اینجاست که جادو اتفاق می افتد! ما مستقیماً بازرسی خواهیم کرد که راز در ETCD ذخیره می شود.
ابتدا ، به etcd-minikube
غلاف:
kubectl -n=kube-system exec -it etcd-minikube -- sh
سپس ، استفاده کنید etcdctl
برای بازیابی مقدار خام راز از ETC:
ETCDCTL_API=3 etcdctl --cacert /var/lib/minikube/certs/etcd/ca.crt --cert /var/lib/minikube/certs/etcd/server.crt --key /var/lib/minikube/certs/etcd/server.key get /registry/secrets/test/new-secret
خروجی را مشاهده خواهید کرد که چیزی شبیه به این است:
/registry/secrets/test/new-secret
k8s:enc:aescbc:v1:key1:??|??
این تفاوت کلیدی است!
-
بدون
EncryptionConfiguration
، داده های موجود در ETCD به راحتی قابل خواندن خواهد بود. -
با
EncryptionConfiguration
کاربردی ، یک رشته رشته غیرقابل خواندن و زباله را با آن مشاهده می کنیدk8s:enc:aescbc:v1:key1:
بشر
این پیشوند به شما می گوید:
-
k8s:enc
: این داده ها توسط Kubernetes رمزگذاری شده است. -
aescbc
: الگوریتم رمزگذاری مورد استفاده AES-CBC است. -
v1
: نسخه طرح رمزگذاری. -
key1
: کلید خاص (Key1 از ماEncryptionConfiguration
) که برای رمزگذاری استفاده شده است.
این تأیید می کند که راز شما اکنون است رمزگذاری شده در استراحت در ETCD!