Skip to content

فصل ۳ — استقرار کلاستر Kubernetes

حالا که با موفقیت یک container برنامه ساختید، گام بعدی یادگیری نحوهٔ تبدیل آن به یک سیستم توزیع‌شدهٔ کامل، قابل‌اعتماد و مقیاس‌پذیر است. برای این کار به یک کلاستر Kubernetes در حال اجرا نیاز دارید. در این نقطه، در بیشتر cloudهای عمومی سرویس‌های Kubernetes مبتنی بر cloud وجود دارند که با چند دستور خط فرمان می‌توان کلاستر ساخت. اگر تازه با Kubernetes شروع کرده‌اید، این رویکرد را به‌شدت توصیه می‌کنیم. حتی اگر در نهایت قصد دارید Kubernetes را روی bare metal اجرا کنید، راه خوبی است برای شروع سریع، یادگیری خود Kubernetes و سپس یادگیری نصب آن روی ماشین‌های فیزیکی. علاوه بر این، مدیریت کلاستر Kubernetes خودش کار پیچیده‌ای است و برای بیشتر افراد منطقی است که این مدیریت را به cloud واگذار کنند — به‌ویژه وقتی در بیشتر cloudها سرویس مدیریت رایگان است.

البته استفاده از راه‌حل مبتنی بر cloud به معنای پرداخت برای منابع cloud و داشتن اتصال شبکهٔ فعال به cloud است. به همین دلیل، توسعهٔ محلی جذاب‌تر می‌شود و در آن صورت ابزار minikube راهی آسان برای راه‌اندازی کلاستر Kubernetes محلی در یک VM روی لپ‌تاپ یا دسکتاپ شما فراهم می‌کند. اگرچه این گزینهٔ خوبی است، minikube فقط یک کلاستر تک‌node می‌سازد که تمام جنبه‌های یک کلاستر Kubernetes کامل را نشان نمی‌دهد. به همین دلیل توصیه می‌کنیم مگر اینکه واقعاً برای شرایط شما جواب ندهد، با راه‌حل مبتنی بر cloud شروع کنید. جایگزین جدیدتر اجرای کلاستر Docker-in-Docker است که می‌تواند کلاستر چند-node روی یک ماشین بسازد. این پروژه هنوز در beta است؛ پس در نظر داشته باشید ممکن است با مشکلات غیرمنتظره روبه‌رو شوید.

اگر واقعاً اصرار دارید روی bare metal شروع کنید، پیوست A در پایان کتاب دستورالعمل ساخت کلاستر از مجموعه‌ای از کامپیوترهای تک‌برد Raspberry Pi را می‌دهد. این دستورالعمل‌ها از ابزار kubeadm استفاده می‌کنند و می‌توان آن‌ها را برای ماشین‌هایی غیر از Raspberry Pi هم تطبیق داد.

نصب Kubernetes روی ارائه‌دهندهٔ Cloud عمومی

این فصل نصب Kubernetes روی سه ارائه‌دهندهٔ اصلی cloud را پوشش می‌دهد: Amazon Web Services، Microsoft Azure و Google Cloud Platform.

اگر cloud provider را برای مدیریت Kubernetes انتخاب کنید، فقط یکی از این گزینه‌ها را نصب کنید؛ وقتی کلاستر پیکربندی و آماده شد می‌توانید به بخش «کلاینت Kubernetes» بروید، مگر اینکه ترجیح دهید Kubernetes را جای دیگری نصب کنید.

Google Kubernetes Engine

Google Cloud Platform سرویس میزبانی‌شدهٔ Kubernetes-as-a-Service به نام Google Kubernetes Engine (GKE) ارائه می‌دهد. برای شروع با GKE به حساب Google Cloud Platform با billing فعال و ابزار gcloud نصب‌شده نیاز دارید.

پس از نصب gcloud، ابتدا zone پیش‌فرض را تنظیم کنید:

bash
$ gcloud config set compute/zone us-west1-a

سپس می‌توانید کلاستر بسازید:

bash
$ gcloud container clusters create kuar-cluster

این چند دقیقه طول می‌کشد. وقتی کلاستر آماده شد، credentialها را با این دستور بگیرید:

bash
$ gcloud auth application-default login

اگر به مشکل خوردید، دستورالعمل کامل ساخت کلاستر GKE در مستندات Google Cloud Platform موجود است.

نصب Kubernetes با Azure Kubernetes Service

Microsoft Azure سرویس میزبانی‌شدهٔ Kubernetes-as-a-Service را به‌عنوان بخشی از Azure Container Service ارائه می‌دهد. آسان‌ترین راه شروع با Azure Container Service استفاده از Azure Cloud Shell داخلی در پورتال Azure است. با کلیک روی آیکون shell در نوار ابزار بالا-راست می‌توانید shell را فعال کنید:

شکل ۳-۱. آیکون Azure Cloud Shell در پورتال Azure

shell به‌طور خودکار ابزار az را نصب و برای کار با محیط Azure شما پیکربندی می‌کند.

به‌جای آن می‌توانید رابط خط فرمان (CLI) az را روی ماشین محلی نصب کنید.

وقتی shell بالا آمد و کار کرد، می‌توانید اجرا کنید:

bash
$ az group create --name=kuar --location=westus

پس از ساخت resource group، کلاستر را با این دستور بسازید:

bash
$ az aks create --resource-group=kuar --name=kuar-cluster

این چند دقیقه طول می‌کشد. پس از ساخت کلاستر، credentialها را با این دستور بگیرید:

bash
$ az aks get-credentials --resource-group=kuar --name=kuar-cluster

اگر ابزار kubectl را ندارید، با این دستور نصب کنید:

bash
$ az aks install-cli

دستورالعمل کامل نصب Kubernetes روی Azure در مستندات Azure موجود است.

نصب Kubernetes روی Amazon Web Services

Amazon سرویس مدیریت‌شدهٔ Kubernetes به نام Elastic Kubernetes Service (EKS) ارائه می‌دهد. آسان‌ترین راه ساخت کلاستر EKS از طریق ابزار خط فرمان متن‌باز eksctl است.

پس از نصب eksctl و قرار دادن آن در path، این دستور را برای ساخت کلاستر اجرا کنید:

bash
$ eksctl create cluster --name kuar-cluster ...

برای جزئیات بیشتر گزینه‌های نصب (مثل اندازهٔ node و موارد دیگر)، help را ببینید:

bash
$ eksctl create cluster --help

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

نصب محلی Kubernetes با minikube

اگر به تجربهٔ توسعهٔ محلی نیاز دارید یا نمی‌خواهید برای منابع cloud پول بدهید، می‌توانید کلاستر سادهٔ تک‌node با minikube نصب کنید.

به‌جای آن، اگر Docker Desktop را نصب کرده‌اید، نصب Kubernetes تک‌ماشینی هم همراه آن می‌آید.

اگرچه minikube (یا Docker Desktop) شبیه‌سازی خوبی از کلاستر Kubernetes است، واقعاً برای توسعهٔ محلی، یادگیری و آزمایش در نظر گرفته شده. چون فقط در یک VM روی یک node اجرا می‌شود، قابلیت اطمینان کلاستر توزیع‌شدهٔ Kubernetes را ندارد.

علاوه بر این، برخی قابلیت‌های این کتاب به یکپارچگی با cloud provider نیاز دارند. این قابلیت‌ها یا با minikube در دسترس نیستند یا به‌صورت محدود کار می‌کنند.

برای استفاده از minikube باید hypervisor روی ماشین نصب باشد. در Linux و macOS معمولاً virtualbox است. در Windows hypervisor پیش‌فرض Hyper-V است. قبل از استفاده از minikube حتماً hypervisor را نصب کنید.

ابزار minikube را در GitHub پیدا می‌کنید. باینری برای Linux، macOS و Windows قابل دانلود است. پس از نصب minikube، کلاستر محلی را با این دستور بسازید:

bash
$ minikube start

این یک VM محلی می‌سازد، Kubernetes را provision می‌کند و پیکربندی kubectl محلی را که به آن کلاستر اشاره می‌کند ایجاد می‌کند.

وقتی کار با کلاستر تمام شد، VM را با این دستور متوقف کنید:

bash
$ minikube stop

اگر می‌خواهید کلاستر را حذف کنید:

bash
$ minikube delete

اجرای Kubernetes در Docker

رویکرد دیگری برای اجرای کلاستر Kubernetes اخیراً توسعه یافته که به‌جای اجرای همه‌چیز در virtual machine، از containerهای Docker برای شبیه‌سازی چند node Kubernetes استفاده می‌کند. پروژهٔ kind تجربهٔ خوبی برای راه‌اندازی و مدیریت کلاسترهای تست در Docker فراهم می‌کند. (kind مخفف Kubernetes IN Docker است.) kind هنوز در حال توسعه است (قبل از ۱.۰)، اما توسط کسانی که Kubernetes می‌سازند برای تست سریع و آسان به‌طور گسترده استفاده می‌شود.

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

bash
$ kind create cluster --wait 5m \
$ export KUBECONFIG="$(kind get kubeconfig-path)"
$ kubectl cluster-info
$ kind delete cluster

اجرای Kubernetes روی Raspberry Pi

اگر می‌خواهید با کلاستر Kubernetes واقع‌گرایانه آزمایش کنید اما نمی‌خواهید هزینهٔ زیادی بدهید، کلاستر Kubernetes بسیار خوبی را می‌توان روی کامپیوترهای Raspberry Pi با هزینهٔ نسبتاً کم ساخت. جزئیات ساخت چنین کلاستری خارج از محدودهٔ این فصل است، اما در پیوست A در پایان کتاب آمده است.

کلاینت Kubernetes

کلاینت رسمی Kubernetes ابزار kubectl است: ابزار خط فرمانی برای تعامل با API Kubernetes. kubectl برای مدیریت بیشتر objectهای Kubernetes مثل Pod، ReplicaSet و Service استفاده می‌شود. kubectl همچنین برای کاوش و تأیید سلامت کلی کلاستر به‌کار می‌رود.

از ابزار kubectl برای کاوش کلاستری که تازه ساختید استفاده می‌کنیم.

بررسی وضعیت کلاستر

اولین کاری که می‌توانید انجام دهید بررسی نسخهٔ کلاستری است که اجرا می‌کنید:

bash
$ kubectl version

این دو نسخهٔ متفاوت نمایش می‌دهد: نسخهٔ ابزار kubectl محلی و نسخهٔ سرور API Kubernetes.

اگر این نسخه‌ها متفاوت باشند نگران نباشید. ابزارهای Kubernetes با نسخه‌های مختلف API Kubernetes سازگار عقب‌رو و جلورو هستند، به‌شرطی که برای ابزار و کلاستر در محدودهٔ دو minor version بمانید و قابلیت‌های جدیدتر را روی کلاستر قدیمی‌تر امتحان نکنید. Kubernetes از مشخصات semantic versioning پیروی می‌کند که minor version عدد میانی است (مثلاً ۵ در ۱.۵.۲).

حالا که ارتباط با کلاستر Kubernetes برقرار است، کلاستر را عمیق‌تر کاوش می‌کنیم.

ابتدا یک تشخیص ساده برای کلاستر بگیرید. راه خوبی است برای تأیید اینکه کلاستر به‌طور کلی سالم است:

bash
$ kubectl get componentstatuses

خروجی باید شبیه این باشد:

NAME                  STATUS     MESSAGE                 ERROR
scheduler             Healthy    ok
controller-manager    Healthy    ok
etcd-0                Healthy    {"health": "true"}

با تغییر و بهبود Kubernetes در طول زمان، گاهی خروجی دستور kubectl تغییر می‌کند. اگر خروجی دقیقاً مثل مثال‌های کتاب نبود نگران نباشید.

اینجا componentهایی را می‌بینید که کلاستر Kubernetes را می‌سازند. controller-manager مسئول اجرای controllerهای مختلفی است که رفتار در کلاستر را تنظیم می‌کنند؛ مثلاً اطمینان از اینکه همهٔ replicaهای یک service در دسترس و سالم هستند. scheduler مسئول قرار دادن Podهای مختلف روی nodeهای مختلف کلاستر است. در نهایت سرور etcd ذخیرهٔ کلاستر است که همهٔ objectهای API در آن نگه‌داری می‌شوند.

فهرست کردن nodeهای worker Kubernetes

بعد می‌توانید همهٔ nodeهای کلاستر را فهرست کنید:

bash
$ kubectl get nodes
NAME         STATUS                    AGE      VERSION
kubernetes   Ready,master              45d      v1.12.1
node-1       Ready                     45d      v1.12.1
node-2       Ready                     45d      v1.12.1
node-3       Ready                     45d      v1.12.1

می‌بینید این یک کلاستر چهار-node است که ۴۵ روز است بالا بوده. در Kubernetes، nodeها به master nodeهایی که containerهایی مثل API server، scheduler و غیره را برای مدیریت کلاستر دارند و worker nodeهایی که containerهای شما روی آن‌ها اجرا می‌شوند تقسیم می‌شوند. Kubernetes معمولاً کار را روی master nodeها schedule نمی‌کند تا workloadهای کاربر به عملکرد کلی کلاستر آسیب نزند.

با دستور kubectl describe اطلاعات بیشتری دربارهٔ یک node خاص مثل node-1 بگیرید:

bash
$ kubectl describe nodes node-1

ابتدا اطلاعات پایه دربارهٔ node را می‌بینید:

Name:                             node-1
Role:
Labels:                           beta.kubernetes.io/arch=arm
                                  beta.kubernetes.io/os=linux
                                  kubernetes.io/hostname=node-1

می‌بینید این node سیستم‌عامل Linux دارد و روی پردازندهٔ ARM اجرا می‌شود.

بعد اطلاعاتی دربارهٔ عملکرد خود node-1:

Conditions:
  Type           Status LastHeartbeatTime   Reason                     Message
  ----           ------ -----------------   ------                     -------
  OutOfDisk      False Sun, 05 Feb 2017…    KubeletHasSufficientDisk   kubelet…
  MemoryPressure False Sun, 05 Feb 2017…    KubeletHasSufficientMemory kubelet…
  DiskPressure   False Sun, 05 Feb 2017…    KubeletHasNoDiskPressure   kubelet…
  Ready          True   Sun, 05 Feb 2017…   KubeletReady               kubelet…

این وضعیت‌ها نشان می‌دهند node فضای کافی disk و memory دارد و به master Kubernetes گزارش می‌دهد سالم است. بعد اطلاعاتی دربارهٔ ظرفیت ماشین:

Capacity:
 alpha.kubernetes.io/nvidia-gpu:         0
 cpu:                                    4
 memory:                                 882636Ki
 pods:                                   110
Allocatable:
 alpha.kubernetes.io/nvidia-gpu:         0
 cpu:                                    4
 memory:                                 882636Ki
 pods:                                   110

سپس اطلاعاتی دربارهٔ نرم‌افزار روی node، از جمله نسخهٔ Docker در حال اجرا، نسخه‌های Kubernetes و kernel لینوکس و موارد بیشتر:

System Info:
 Machine ID:                9122895d0d494e3f97dda1e8f969c85c
 System UUID:               A7DBF2CE-DB1E-E34A-969A-3355C36A2149
 Boot ID:                   ba53d5ee-27d2-4b6a-8f19-e5f702993ec6
 Kernel Version:            4.15.0-1037-azure
 OS Image:                  Ubuntu 16.04.5 LTS
 Operating System:          linux
 Architecture:              amd64
 Container Runtime Version: docker://3.0.4
 Kubelet Version:           v1.12.6
 Kube-Proxy Version:        v1.12.6
PodCIDR:                    10.244.1.0/24

در نهایت اطلاعاتی دربارهٔ Podهایی که الان روی این node اجرا می‌شوند:

Non-terminated Pods:            (3 in total)
  Namespace   Name        CPU Requests CPU Limits Memory Requests Memory Limits
  ---------   ----        ------------ ---------- --------------- -------------
  kube-system kube-dns... 260m (6%)     0 (0%)     140Mi (16%)     220Mi (25%)
  kube-system kube-fla... 0 (0%)        0 (0%)     0 (0%)          0 (0%)
  kube-system kube-pro... 0 (0%)        0 (0%)     0 (0%)          0 (0%)
Allocated resources:
  (Total limits may be over 100 percent, i.e., overcommitted.
  CPU Requests CPU Limits       Memory Requests Memory Limits
  ------------ ----------       --------------- -------------
  260m (6%)     0 (0%)          140Mi (16%)     220Mi (25%)
No events.

از این خروجی Podهای روی node (مثلاً Pod kube-dns که سرویس DNS کلاستر را فراهم می‌کند)، CPU و memory درخواستی هر Pod از node و مجموع منابع درخواستی را می‌بینید. شایان ذکر است Kubernetes هم request و هم limit بالایی برای منابع هر Pod روی ماشین را ردیابی می‌کند. تفاوت request و limit در فصل ۵ با جزئیات توضیح داده می‌شود، اما به‌اختصار: منابع درخواستی یک Pod روی node تضمین می‌شوند، در حالی که limit یک Pod حداکثر مقدار منبعی است که Pod می‌تواند مصرف کند. limit یک Pod می‌تواند از request بالاتر باشد؛ در آن صورت منابع اضافی به‌صورت best-effort تأمین می‌شوند و روی node تضمین نمی‌شوند.

componentهای کلاستر

یکی از جنبه‌های جالب Kubernetes این است که بسیاری از componentهایی که کلاستر Kubernetes را می‌سازند در واقع با خود Kubernetes deploy می‌شوند. چند مورد را می‌بینیم. این componentها از مفاهیمی استفاده می‌کنند که در فصل‌های بعد معرفی می‌شوند. همهٔ این componentها در namespace kube-system اجرا می‌شوند.¹

Kubernetes Proxy

Kubernetes proxy مسئول مسیریابی ترافیک شبکه به serviceهای load-balanced در کلاستر Kubernetes است. برای انجام کارش، proxy باید روی هر node کلاستر باشد. Kubernetes object API به نام DaemonSet دارد که بعداً در کتاب یاد می‌گیرید و در بسیاری از کلاسترها برای این کار استفاده می‌شود. اگر کلاستر شما Kubernetes proxy را با DaemonSet اجرا کند، proxyها را با این دستور می‌بینید:

bash
    $ kubectl get daemonSets --namespace=kube-system kube-proxy
    NAME         DESIRED   CURRENT   READY     NODE-SELECTOR    AGE
    kube-proxy   4         4         4         <none>           45d

بسته به نحوهٔ راه‌اندازی کلاستر، DaemonSet برای kube-proxy ممکن است نام دیگری داشته باشد یا اصلاً از DaemonSet استفاده نکند. در هر صورت container kube-proxy باید روی همهٔ nodeهای کلاستر در حال اجرا باشد.

Kubernetes DNS

Kubernetes همچنین سرور DNS اجرا می‌کند که نام‌گذاری و discovery برای serviceهای تعریف‌شده در کلاستر را فراهم می‌کند. این سرور DNS هم به‌صورت service تکرارشونده روی کلاستر اجرا می‌شود. بسته به اندازهٔ کلاستر ممکن است یک یا چند سرور DNS در کلاستر ببینید. سرویس DNS به‌صورت deployment Kubernetes اجرا می‌شود که این replicaها را مدیریت می‌کند:

bash
$ kubectl get deployments --namespace=kube-system core-dns
NAME       DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
core-dns   1         1         1            1           45d

همچنین service Kubernetes برای load balancing سرور DNS وجود دارد:

bash
$ kubectl get services --namespace=kube-system core-dns
NAME       CLUSTER-IP   EXTERNAL-IP   PORT(S)         AGE
core-dns   10.96.0.10   <none> 53/UDP,53/TCP    45d

این نشان می‌دهد سرویس DNS کلاستر آدرس ۱۰.۹۶.۰.۱۰ دارد. اگر به container داخل کلاستر login کنید، می‌بینید این در فایل /etc/resolv.conf container پر شده است.

با Kubernetes ۱.۱۲، Kubernetes از سرور DNS kube-dns به سرور DNS core-dns منتقل شد. به همین دلیل اگر کلاستر Kubernetes قدیمی‌تر دارید ممکن است kube-dns ببینید.

Kubernetes UI

component نهایی Kubernetes یک GUI است. UI به‌صورت یک replica اجرا می‌شود، اما همچنان برای قابلیت اطمینان و upgradeها توسط deployment Kubernetes مدیریت می‌شود. این سرور UI را با این دستور می‌بینید:

bash
$ kubectl get deployments --namespace=kube-system kubernetes-dashboard
NAME                   DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
kubernetes-dashboard   1         1         1            1           45d

dashboard هم service برای load balancing دارد:

bash
$ kubectl get services --namespace=kube-system kubernetes-dashboard
NAME                   CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes-dashboard   10.99.104.174   <nodes>       80:32551/TCP   45d

می‌توانید با kubectl proxy به این UI دسترسی پیدا کنید. Kubernetes proxy را با این دستور راه بیندازید:

bash
$ kubectl proxy

این سروری روی localhost:8001 بالا می‌آورد. اگر در مرورگر به http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/ بروید، باید رابط وب Kubernetes را ببینید. می‌توانید با این رابط کلاستر را کاوش کنید و containerهای جدید بسازید. جزئیات کامل این رابط خارج از محدودهٔ کتاب است و با بهبود dashboard به‌سرعت در حال تغییر است.

برخی providerها dashboard Kubernetes را به‌طور پیش‌فرض نصب نمی‌کنند؛ پس اگر در کلاستر نمی‌بینید نگران نباشید. مستندات نصب dashboard برای این کلاسترها در https://kubernetes.io/docs/tasks/access-application-cluster/web-ui-dashboard/ موجود است.

خلاصه

امیدواریم در این نقطه یک کلاستر Kubernetes (یا سه تا!) در حال اجرا داشته باشید و با چند دستور کلاستری که ساختید را کاوش کرده باشید. بعد زمان بیشتری صرف کاوش رابط خط فرمان آن کلاستر Kubernetes می‌کنیم و یاد می‌گیرید ابزار kubectl را مسلط شوید. در بقیهٔ کتاب از kubectl و کلاستر تست برای کاوش objectهای مختلف در API Kubernetes استفاده می‌کنید.


¹ همان‌طور که در فصل بعد یاد می‌گیرید، namespace در Kubernetes موجودیتی برای سازمان‌دهی منابع Kubernetes است. می‌توانید آن را مثل پوشه در filesystem تصور کنید.