در این مقاله به بررسی مفهوم و شیوه‌ی استفاده از 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  استفاده کنید.