در این مقاله به بررسی مفهوم و شیوهی استفاده از secret در سکوی ابری آروان، انواع و همچنین اجزای سازندهی یک secret و چگونگی تعریف هریک از آنها پرداخته میشود.
پیشنیازهای استفاده از secret در سکوی ابری آروان
تنها پیشنیاز استفاه از این سیستم، داشتن حساب کاربری ابر آروان و دسترسی به سکوی ابری آروان است. بنابراین به سایت ابر آروان به نشانی arvancloud.ir بروید و یک حساب کاربری بسازید یا اگر از پیش حساب کاربری دارید، وارد آن شوید. سپس به بخش پروفایل بروید و در سربرگ API KEYS برای خود یک API KEY جدید بسازید و آن را در جایی ذخیره کنید.
برای انجام مراحل این مقاله نیاز است از command line ابر آروان استفاده کنید. پس از دانلود خط فرمان (در صورت نیاز آن را در PATH خود قرار دهید) با کمک دستور زیر در آن لاگین کنید.
arvan login
سپس API KEY دریافت کرده از سایت را در اینجا کپی کنید.
secret چیست؟
برای نگهداری اطلاعاتی مانند پسوردها، اطلاعات دسترسی، توکنها و اطلاعات حساس میتوان از secret استفاده کرد. اطلاعات موجود در secret را میتوان بهشکل volume در مسیری درون Pod قرار داد، یا بهشکل env به Pod منتقل کرد. برای نمونه، برای دسترسی یک Pod به یک پایگاه داده mysql، میتوان username و password پایگاه داده را در قالب secret و با env به Pod منتقل کرد و فرآیند در حال اجرا درون Pod، از این متغیر برای اجرای queryهای خود روی پایگاه داده استفاده کند.
هرچند میتوان این اطلاعات را بهشکل مستقیم به Pod ارسال کرد، اما از جمله مزایای استفاده از secret قابلیت استفاده از آن در چندین Pod و deployment مختلف، تنها با یک بار تعریف آن است.
ساخت secret
برای ساخت secret، باید اطلاعات مورد نیاز را در قالب yaml در یک فایل وارد و سپس با command line آن را به سکوی ابری آروان ارایه کرد. در ادامه مثالی ساده از یک secret که دادههای مورد نیاز برای اتصال به یک پایگاه دادهی mysql را داراست، بیان و هر یک از بخشهای آن توضیح داده شده است.
apiVersion: v1 kind: Secret metadata: name: db-secret type: Opaque data: password: bXlwYXNzd29yZA== stringData: hostname: mysql-svc:3306 username: root
نکته: دقت داشته باشید که indentation در فایلهای yaml مهم است و کوچکترین جابهجایی میتواند سبب برگرداندن خطا یا تنظیمات ناخواسته شود.
در ادامه فیلدهای مربوط توضیح داده شدهاند.
- kind: مشخص کنندهی نوع ماهیت است. این فیلد میتواند مقادیری مانند: Pod، secret، Service، StatefulSet و … داشته باشد. در این مثال، هدف تعریف secret است. بنابراین مقدار این فیلد، secret مشخص شده است.
- name: مشخصکنندهی نام secret است.
- type: مشخصکنندهی نوع secret است. در اینجا مقدار opaque انتخاب شده که نوع معمول برای استفاده از secret است. در ادامه توضیح کوتاهی دربارهی انواع secretها نیز، ارایه شده است.
- data: به طور کلی دادههای درون secret باید به شکل key:value ارایه شوند. دو بخش اصلی که میتوانند شامل دادهها شوند، data و stringData هستند. فرق اساسی بین این دو بخش، شیوهی ارایهی value است که در data، داده حتمن باید به شکل base64، ارایه شود. این در حالی است که، در stringData، داده بهشکل plain ارایه و فرآیند تبدیل آن به base64، بهوسیلهی سکوی ابری آروان بهشکل خودکار انجام میشود. برای نمونه، در خطوط بالا دادهای به اسم password وجود دارد که مقدار آن “bXlwYXNzd29yZA==” تعیین شده و معادل با مقدار base64 عبارت mypassword است. از طرفی در بخش stringData دو مقدار username و hostname تعریف شدهاند که مقادیر آنها بهشکل plain است.
خطوط بالا را در یک فایل به نام secret.yaml وارد و ذخیره کنید. سپس در command line با دستور زیر، secret خود را به سکوی ابری آروان ارایه کنید.
arvan paas apply -f secret.yaml
با دستور زیر میتوانید از وضعیت secret خود و اجرای آن روی سکوی ابری آروان آگاه شوید.
arvan paas get secret
خروجی مشابه زیر خواهد بود.
$ arvan paas get secret NAME TYPE DATA AGE 48a9ea4d-78c1-11ea-bd52-0a580a830057 Opaque 10 1h builder-dockercfg-rk9cm kubernetes.io/dockercfg 1 41d builder-token-4zbhx kubernetes.io/service-account-token 4 41d builder-token-v59fm kubernetes.io/service-account-token 4 41d db-secret Opaque 3 10m default-dockercfg-xkcl2 kubernetes.io/dockercfg 1 41d default-token-7chvn kubernetes.io/service-account-token 4 41d default-token-fr8q4 kubernetes.io/service-account-token 4 41d deployer-dockercfg-57cz2 kubernetes.io/dockercfg 1 41d deployer-token-d8m2w kubernetes.io/service-account-token 4 41d deployer-token-ggnnf kubernetes.io/service-account-token 4 41d mysql-phpmyadmin-parameters0sdwea Opaque 1 1h
همانطور که در خروجی بالا مشخص است، تعدادی secret از پیش ساخته درون پروژهی شما وجود دارد. این secretها مرتبط با تنظیمات پایهی پروژه هستند و به هیچ وجه نباید آنها را تغییر دهید یا پاک کنید.
برای مشاهدهی secret خود، از دستور زیر استفاده کنید.
arvan paas get secret db-secret -o yaml
خروجی مانند زیر خواهد بود.
apiVersion: v1 data: hostname: bXlzcWwtc3ZjOjMzMDY= password: bXlwYXNzd29yZA== username: cm9vdA== kind: Secret metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"v1","data":{"password":"bXlwYXNzd29yZA=="},"kind":"Secret","metadata":{"annotations":{},"name":"db-secret","namespace":"example-project"},"stringData":{"hostname":"mysql-svc:3306","username":"root"},"type":"Opaque"} creationTimestamp: 2020-04-07T12:10:11Z name: db-secret namespace: example-project resourceVersion: "31155653" selfLink: /api/v1/namespaces/solar/secrets/db-secret uid: bb517571-78c8-11ea-b7a9-fa163e633da5 type: Opaque
همانگونه که در خروجی بالا مشاهده میشود، تمامی مقادیری که به secret ارایه شد، بهشکل base64 ذخیره شدهاند. حتا مقادیر username و hostname که در تعریف secret از stringData استفاده شد نیز، بهوسیلهی سکوی ابری در قالب base64 ذخیره شدهاند.
ساخت secret از طریق Command Line
روش راحتتر برای ساخت Secret، استفاده از Command Line و دستور arvan paas create secret است که مثالی از آن در ادامه آمده است.
arvan paas create secret generic db-secret --from-literal=username=root --from-literal=password=mypassword --from-literal=hostname='mysql-svc:3306'
دستور بالا یک secret به نام db-secret، مشابه فایل yaml که پیش از این توضیح داده شد، میسازد. از جمله اجزای مهم دستور بالا کلمهی کلیدی generic است. هنگام استفاده از command line میتوان از یکی از سه گزینهی generic، tls یا docker-registry استفاده کرد.
به کمک generic میتوان مقادیر را بهوسیلهی گزینهی –from-literal بهشکل key=value به secret اختصاص داد.
اگر برای دریافت image container از یک docker registry، نیاز به تعریف secret باشد، بهجای generic از دستور docker-registry ،که در ادامه توضیح داده شده است، استفاده کنید.
ساخت Secret برای Docker Registry
در برخی از شرایط ممکن است بخواهید در Pod خود از Image Containerهایی استفاده کنید که بهشکل Public در دسترس نیستند و برای Pull کردن از آنها، نیاز به اطلاعات دسترسی و user و password است. در این شرایط میتوان از Secretای خاص در تنظیمات Pod استفاده کرد. شیوهی تعریف و استفاده از این نوع Secret در ادامه آمده است.
arvan paas create secret docker-registry private-reg --docker-server=dockerregistry-example-project.apps.ir-thr-mn1.arvan.run --docker-username=admin --docker-password=password --docker-email=user@example.com
با اجرای دستور بالا یک secret از نوع docker-registry به نام private-reg ایجاد میشود.
استفاده از Secret
در ادامه مثالی از یک Deployment مربوط به یک WordPress آمده است. اطلاعات دسترسی به پایگاه دادهی mysql، بهوسیلهی Secret و با env به Pod داده میشود. همچنین در این dDeployment از یک Image Container موجود روی یک docker registry که private است و برای دسترسی آن در بخش قبل یک secret ساخته شد، استفاده شده است. اطلاعات اتصال به Docker Registry از طریق imagePullSecrets ارایه شده است.
اطلاعات زیر را در فایلی به اسم wordpress-deploy.yaml وارد کنید. برای اطلاعات بیشتر در ارتباط با Deployment به مقالهی «استفاده از Deployment در سکوی ابری آروان» مراجعه کنید.
apiVersion: apps/v1 kind: Deployment metadata: name: wordpress-deployment labels: app: wordpress spec: replicas: 1 Strategy: type: Recreate selector: matchLabels: app: wordpress template: metadata: labels: app: wordpress spec: containers: - env: - name: WORDPRESS_DB_HOST valueFrom: secretKeyRef: key: hostname name: db-secret - name: WORDPRESS_DB_USER valueFrom: secretKeyRef: key: username name: db-secret - name: WORDPRESS_DB_PASSWORD valueFrom: secretKeyRef: key: password name: db-secret - name: WORDPRESS_DB_NAME value: shop image: dockerregistry-example-project.apps.ir-thr-mn1.arvan.run/wordpress:0.21 imagePullPolicy: IfNotPresent name: wordpress ports: - containerPort: 2368 protocol: TCP resources: limits: cpu: '1' ephemeral-storage: 2G memory: 1G requests: cpu: '1' ephemeral-storage: 2G memory: 1G imagePullSecrets: - name: private-reg
نکته: دقت داشته باشید که Indentation در فایلهای yaml مهم است و کوچکترین جابهجایی میتواند سبب برگرداندن خطا یا تنظیمات ناخواسته شود.
در ادامه فیلدهای اضافه شده به Deployment برای استفاده از Secretهای ساخته شده، توضیح داده شدهاند.
- template.spec.containers.valueFrom: این بخش مشخصکنندهی آن است که مقدار متغیر محیطی قرار است از secret خوانده شود.
- template.spec.containers.valueFrom.key: این بخش مشخصکنندهی نام key درون secretای است که قرار است متغیر محیطی، value مربوطه به آن را استفاده کند.
- template.spec.containers.valueFrom.secret: این بخش مشخصکنندهی نام secretای است که قرار است متغیر محیطی از آن استفاده کند.
- template.spec.imagePullSecrets.name: مشخصکنندهی نام secretای است که شامل اطلاعات لازم برای pull کردن image container از docker registry مربوطه است.
همچنین علاوهبر env، میتوان secret را بهشکلvolume نیز درون Pod استفاده و اصطلاحن آن را mount کرد. در ادامه توضیح کوتاهی دربارهی این شیوه داده شده است.
استفاده از Secret بهشکل Volume
یکی دیگر از روشهای استفاده از Secret، استفاده از آن در قالب Volume و Mount کردن آن درون Pod است. از جمله مزایای این روش میتوان به امکان استفاده از Secret برای ارایهی Configها یا فایلهای حاوی کلید به Pod، اشاره کرد. برای استفاده از Secret به این شکل، کافیست یک Volume برای Pod تعریف و سپس نام Secret را بهعنوان دیسک به آن ارایه کنید. در ادامه مثالی از این نوع آمده است.
فرض کنید، میخواهید محتوای db-secret را که پیش از این در بخشهای قبل تعریف شد، در Deployment دیگری در یک مسیر Mount کنید. این کار مانند آنچه در زیر آمده است، انجام میشود.
apiVersion: apps/v1 kind: Deployment metadata: name: example-deployment labels: app: example spec: replicas: 1 selector: matchLabels: app: example template: metadata: labels: app: example spec: containers: - image: example-docker:latest imagePullPolicy: IfNotPresent name: example ports: - containerPort: 2368 protocol: TCP resources: limits: cpu: '1' ephemeral-storage: 2G memory: 1G requests: cpu: '1' ephemeral-storage: 2G memory: 1G volumeMounts: - name: sec mountPath: "/opt/cfg" volumes: - name: sec secret: secretName: db-secret
در ادامه فیلدهایی که در deployment اضافه شدهاند تا بتوان از secret بهشکل volume استفاده کرد، توضیح داده شدهاند.
- template.spec.containers.volumeMount: در این بخش نام و محلی که قرار است secret مورد نظر mount شود، مشخص میشود. این بخش مانند سایر volumeها که تاکنون استفاده شدند، تعریف میشود.
- template.spec.volumes: در این بخش مشخصات secret مورد نظر ارایه میشود.
- template.spec.volumes.name: مشخصکنندهی volumeای است که قرار است secret مورد نظر در آن mount شود.
- template.spec.volumes.secret: مشخصکنندهی آن است که در volume مورد نظر قرار است که secret، در اصطلاح mount شود.
- template.spec.volumes.secret.secretName: مشخصکنندهی نام secretای است که باید استفاده شود.
پس از اجرای فایل بالا، اگر وارد Pod شوید و به مسیر تعیین شده بروید، مشاهده میکنید که هر یک از فیلدهای تعریف شده در Secret بهشکل یک فایل جداگانه در مسیر مورد نظر قرار گرفتهاند.
$ arvan paas exec -it example-69cc69856b-z224l bash root@example-69cc69856b-z224l:/# ls -lash /opt/cfg/ total 0 0 drwxrwsrwt. 3 root 1004640000 140 Apr 11 10:37 . 0 drwxr-xr-x. 1 root root 17 Apr 11 10:37 .. 0 drwxr-sr-x. 2 root 1004640000 100 Apr 11 10:37 ..2020_04_11_10_37_28.094939688 0 lrwxrwxrwx. 1 root root 31 Apr 11 10:37 ..data -> ..2020_04_11_10_37_28.094939688 0 lrwxrwxrwx. 1 root root 15 Apr 11 10:37 hostname -> ..data/hostname 0 lrwxrwxrwx. 1 root root 15 Apr 11 10:37 password -> ..data/password 0 lrwxrwxrwx. 1 root root 15 Apr 11 10:37 username -> ..data/username
انواع type در secret
در تعریف Secret در قالب yaml، باید نوع آن را مشخص کرد. این فیلد ساختار مقادیر Key و Value موجود در secret را مشخص میکند. در حالت کلی همواره میتوان از نوع Opaque استفاده کرد. سایر انواع صرفن Validation روی مقادیر Key و Value انجام میدهند تا سازندهی Secret اطمینان پیدا کند که از ساختار درستی استفاده میکند. بنابراین تفاوتی در عملکرد Secret به طور کلی ایجاد نمیکند و شما همواره میتوانید از Opaque استفاده کنید.
موارد زیر انواع دیگری هستند که از سمت سکوی ابری آروان برخی Validationها را روی Secretهای از این نوع انجام میدهند.
- io/service-account-token
- io/dockercfg
- io/dockerconfigjson
- io/basic-auth
- io/ssh-auth
- io/tls
توضیح این موارد خارج از مباحث بیان شده در این مقاله است. به طور کلی توصیه بر آن است که از همان نوع Opaque استفاده کنید، مگر آنکه با Typeها به طور کامل آشنایی داشته باشید (توجه شود که برای ساخت Secret برای Docker Registry، استفاده از cCommand Line، که در این مقاله به آن پرداخته شد، توصیه میشود).
برای کسب اطلاعات بیشتر میتوانید از مستندات OKD و Kubernetes استفاده کنید.