پرش به مطلب اصلی

ساخت اپلیکیشن Multi-Zone

ایجاد یک اپلیکیشن و پیاده‌سازی آن در چند زون برای افزایش دسترس‌پذیری و پایداری سرویس، در ۳ دیتاسنتر «بامداد»، «فروغ» و «سیمین» آروان‌کلاد امکان‌پذیر است. برای این کار، می‌توانید هم از پنل کاربری و هم از CLI و مانیفست استفاده کنید.

برای ساخت اپلیکیشن‌های Multi-Zone به نکات زیر توجه کنید:

  • در این شیوه‌ی پیاده‌سازی دیسک‌ها (Persistent Volume) در زون‌های مختلف با یک‌دیگر سینک نمی‌شوند و برای این کار باید سازوکارهایی را در سطح اپلیکیشن به‌کار بگیرد؛ مانند استفاده از Redis و Kafka
  • در پنل کاربری فقط اپلیکیشن‌های بدون دیسک (Stateless) امکان Multi Zone شدن را دارند. برای Multi Zone کردن اپلیکیشن‌های Stateful باید از طریق Kubectl یا helm استفاده کنید.

ساخت اپلیکیشن مالتی‌زون از طریق CLI

کوبرنتیز می‌تواند به‌طور خودکار، پادها را میان نودهای مختلف یک کلاستر توزیع کند. اما ممکن است برای کاهش تاثیر اختلال‌ها بخواهید شیوه‌ی پخش پادها در هر زون یا نود را مشخص کنید. مثلن تعیین کنید زمانی که تنها دو پاد دارید هر دوی آن‌ها در یک دیتاسنتر قرار نگیرند یا علاوه‌براین که توزیع پادها میان دیتاسنترها به‌شکل مساوی انجام می‌شود هیچ دیتاسنتری بیش از ۲ پاد نداشته باشد.

به این منظور، مفاهیم Affinity و Topology Spread Constraints در کوبرنتیز طراحی شده است.

  • Anti-Affinity

    در کوبرنتیز Affinity / Anti-Affinity شیوه‌ی قرار گرفتن پادها را نسبت‌به یک‌دیگر کنترل می‌کند. برای اطمنیان از قرار نگرفتن پادهای مشابه در یک زون باید از Affinity استفاده کنید. برای نمونه، Deployment زیر را در نظر بگیرید:

apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node-role.kubernetes.io/cloud-container-g2
operator: In
values:
- "true"
- key: topology.kubernetes.io/zone
operator: In
values:
- bamdad
- simin
- forough
containers:
- name: my-app
image: my-app-image

در بخش affinity، که تعیین‌کننده‌ی وضعیت توزیع پادها نسبت به یک‌دیگر است، podAntiAffinity تضمین می‌کند پادها باهم در یک توپولوژی مانند زون قرار نگیرند.

  • requiredDuringSchedulingIgnoredDuringExecution

    مشخص می‌کند که Anti Affinity باید هنگام برنامه‌ریزی (Scheduling) رعایت شود، اما می تواند در زمان اجرا نادیده گرفته شود. برای نمونه، اگر یک نود از دسترس خارج شود و پاد دوباره اسکجول شود، قانون نیازی به ارزیابی دوباره ندارد. به این حالت، Hard Anti-Affinity گفته می‌شود و اگر این شروط برقرار نشوند، پاد اسکجول نخواهد شد.

    از طرف دیگر PreferredDuringSchedulingIgnoredDuringExecution که با نام Soft Anti-Affinity شناخته می‌شود. در این حالت Scheduler سعی می‌کند قوانین را اجرا کند اما اگر شروط برقرار نباشند پاد اسکجول می‌شود.

    توجه داشته باشید Soft Anti-Affinity انعطاف‌پذیری بیش‌تری را فراهم می‌کند. اگر با وجود Hard Anti-Affinity اجرای قانون امکان‌پذیر نباشد ممکن است اپلیکیشن از دسترس خارج شود.

  • labelSelector

    پادهایی که قانون Anti-Affinity باید روی آن‌ها اعمال شود را مشخص می‌کند.

  • topologyKey: topology.kubernetes.io/zone

    دامنه‌ی اعمال قانون Anti-Affinity را مشخص می‌کند. کلید "topology.kubernetes.io/zone" بیانگر این است که پادها باید در سطح زون توزیع شوند.

  • Pod Topology Spread Constraints

    زمانی‌که یک نود راه‌اندازی می‌شود یک برچسب به آن اضافه می‌شود که می‌تواند شامل اطلاعات دیتاسنتر یا زون باشد. اگر کلاسترتان در چند زون قرار گرفته باشد می‌توانید از این برچسب‌ها در کنار مفهومی به نام Pod Topology Spread Constraints استقاده کنید تا شیوه‌ی توزیع و قرارگیری پادها در زون‌ها را تعیین کنید.

    برای نمونه، دیپلویمنت زیر را در نظر بگیرید:

apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: ng
name: ng
namespace: myproject
spec:
replicas: 3
selector:
matchLabels:
app: ng
template:
metadata:
creationTimestamp: null
labels:
app: ng
name: ng
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node-role.kubernetes.io/cloud-container-g2
operator: In
values:
- "true"
- key: topology.kubernetes.io/zone
operator: In
values:
- bamdad
- simin
- forough
containers:
- image: nginx:latest
imagePullPolicy: IfNotPresent
name: ng
ports:
- containerPort: 80
name: http
protocol: TCP
resources:
limits:
cpu: "1"
ephemeral-storage: 1G
memory: 2G
requests:
cpu: "1"
ephemeral-storage: 1G
memory: 2G
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
tolerations:
- effect: NoSchedule
key: role
operator: Equal
value: cloud-container-g2
topologySpreadConstraints:
- labelSelector:
matchLabels:
app: ng
name: ng
maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: DoNotSchedule
  • topologyKey

    مشخص می‌کند پادها در چه سطحی توزیع شوند. برای نمونه در این مثال تنظمیات در سطح Zone اعمال می‌شوند.

  • whenUnsatisfiable

    این متغیر تعیین می‌کند اگر زمانی شروط موردنظر برقرار نبود چه اقدامی انجام شود. مقدار DoNotSchedule که در این نمونه استفاده شده به این معناست که اگر شروط برقرار نبود، پاد اسکجول نشود. این پارامتر می‌تواند مقدار ScheduleAnyway را نیز بپذیرد. در این حالت حتا اگر شروط برقرار نباشد، پاد راه‌اندازی می‌شود.

  • maxSkew

    بیش‌ترین تفاوت مجاز را بین تعداد پادهای دامنه‌ی تعریف‌شده در topologyKey، که در این‌جا زون است، مشخص می‌کند. یعنی در این نمونه، تعداد پادها در هر زون می‌تواند حداکثر یکی بیش‌تر از زون دیگر باشد.

  • labelSelector

    برای انتخاب پادها بر اساس برچسب‌شان استفاده می‌شود. در واقع، تعیین می‌کند این قوانین روی کدام پادها اعمال شود. برای نمونه، در این مثال، پادهای با برچسب app: ng و name: ng در نظر گرفته می‌شود.

ساخت اپلیکیشن مالتی‌زون از طریق پنل کاربری

هنگام ساخت اپلیکیشن با داکر ایمیج در پنل کاربری، می‌توانید در تب تنظیمات، جزییات مربوط به منطقه‌ی پیاده‌سازی اپلیکیشن را تعیین کنید.

از روش داکر ایمیج، فقط اپلیکیشن‌های بدون دیسک (Stateless) قابلیت استفاده از Multi Zone را دارند. برای Multi Zone کردن اپلیکیشن‌های Stateful می‌توانید از طریق Kubectl یا روش helm اقدام کنید.

  • انتخاب خودکار منطقه:

    با فعال کردن این قابلیت، منطقه‌ای که اپلیکیشن در آن استقرار می‌یابد به‌طور خودکار انتخاب می‌شود. شما می‌توانید با غیرفعال کردن این قابلیت، منطقه(های) مورد نظر خودتان را انتخاب کنید.

    • تعداد رپلیکا:

      اگر انتخاب خودکار منطقه را غیرفعال کرده باشید می‌توانید در این بخش تعداد نمونه‌هایی که می‌خواهید از پادتان ساخته شود را تعیین کنید.

    • MaxSkew:

      این مقدار حداکثر اختلاف رپلیکاها را میان Zoneها مشخص می‌کند.

  • رفتار پشتیبانی

    • DoNotSchedule:

      این گزینه به برنامه‌ریز (Scheduler) می‌گوید اگر یکی از زون‌های انتخاب‌شده به هر دلیلی از دسترس خارج شد پاد روی Zone جدیدی برنامه‌ریزی (Schedule) نشود. از این حالت زمانی استفاده می‌شود که رعایت دقیق قوانین تعیین‌شده اهمیت بیش‌تری دارد و پاد نباید تا زمانی که شرایط برآورده نشده برنامه‌ریزی شود.

    • ScheduleAnyway:

      این گزینه به برنامه‌ریز (Scheduler) می‌گوید که پاد را در هر حالتی برنامه‌ریزی (Schedule) کند، حتی اگر قوانین تعیین شده رعایت نشود. هم‌چنین اگر یک زون از دسترس خارج شود پاد روی Zone تکراری برنامه‌ریزی (Schedule) می‌شود.به عبارت دیگر، استفاده از این روش ممکن است باعث ایجاد توزیع نامتوازنی از پادها شود. این حالت زمانی استفاده می‌شود که انعطاف در برنامه‌ریزی مهم‌تر از توزیع متوازن پاد‌ها باشد.