بلاگ/راه‌اندازی کلاستر Kubernetes روی سرور اختصاصی و VPS با kubeadm
به‌روز شده

راه‌اندازی کلاستر Kubernetes روی سرور اختصاصی و VPS با kubeadm

1405/05/300 بازدید
راه‌اندازی کلاستر Kubernetes روی سرور اختصاصی و VPS با kubeadm

راه‌اندازی کلاستر Kubernetes روی سرور اختصاصی و VPS با kubeadm

نمایی مفهومی از کلاستر Kubernetes شامل Control Plane و Worker Nodeها راه‌اندازی کلاستر Kubernetes با kubeadm یکی از استانداردترین روش‌ها برای ساخت یک محیط واقعی و قابل‌کنترل روی زیرساخت شخصی است. برخلاف سرویس‌های مدیریت‌شده، در این روش نصب، شبکه، به‌روزرسانی و نگهداری کلاستر بر عهده شماست؛ در مقابل، کنترل بیشتری روی سیستم‌عامل، منابع سخت‌افزاری، شبکه و تنظیمات امنیتی خواهید داشت. در این راهنما یک کلاستر چندنودی روی سرورهای Ubuntu راه‌اندازی می‌کنیم. یک سرور نقش Control Plane را دارد و یک یا چند سرور به‌عنوان Worker به آن متصل می‌شوند. مراحل برای VPS و سرور اختصاصی تقریباً یکسان است، به شرط آنکه مجازی‌سازی، شبکه و منابع لازم در دسترس باشند. دستورها را ابتدا در محیط آزمایشی اجرا کنید. نسخه Kubernetes و مخزن بسته‌ها نیز باید متناسب با نسخه موردنظر شما انتخاب شوند؛ در این مقاله برای نمونه از شاخه نسخه v1.30 استفاده می‌کنیم.

معماری کلاستر موردنیاز

یک کلاستر ساده Kubernetes حداقل از این اجزا تشکیل می‌شود: - یک نود Control Plane برای اجرای API Server، Scheduler، Controller Manager و دیتابیس etcd - یک یا چند Worker Node برای اجرای Podها و بارهای کاری - یک افزونه CNI برای شبکه داخلی Podها - یک Container Runtime مانند containerd برای محیط آموزشی می‌توان از دو سرور استفاده کرد، اما در محیط عملیاتی بهتر است افزونگی Control Plane، پشتیبان‌گیری از etcd و توزیع بار API Server نیز در نظر گرفته شود. اگر با نصب و مدیریت پایه Kubernetes روی اوبونتو آشنایی کمتری دارید، این راهنمای ابزارهای Kubernetes و مدیریت کانتینرها در لینوکس اوبونتو می‌تواند نقطه شروع خوبی باشد. | نقش نود | حداقل منابع پیشنهادی | وظیفه اصلی | |---|---:|---| | Control Plane | ۲ هسته CPU، ۴ گیگابایت RAM | مدیریت وضعیت و زمان‌بندی کلاستر | | Worker سبک | ۲ هسته CPU، ۲ تا ۴ گیگابایت RAM | اجرای Podها و سرویس‌ها | | Worker عملیاتی | ۴ هسته CPU و ۸ گیگابایت RAM یا بیشتر | اجرای بارهای کاری واقعی | | Control Plane پرترافیک | ۴ هسته CPU و ۸ گیگابایت RAM یا بیشتر | مدیریت کلاستر بزرگ‌تر و پایدارتر | اعداد جدول حداقل‌های پیشنهادی هستند و باید با توجه به نوع برنامه‌ها، تعداد Podها و مصرف واقعی منابع تغییر کنند.

VPS بهتر است یا سرور اختصاصی؟

VPS برای یادگیری، محیط توسعه، آزمایش CI/CD و کلاسترهای کوچک انتخابی اقتصادی و انعطاف‌پذیر است. ساخت نود جدید یا افزایش منابع آن نیز معمولاً سریع‌تر انجام می‌شود. سرور اختصاصی برای بارهای پردازشی سنگین، دیتابیس‌ها، ذخیره‌سازی پرترافیک و سرویس‌هایی که به عملکرد پایدار دیسک و شبکه نیاز دارند مناسب‌تر است. همچنین مشکل همسایگی منابع که ممکن است در بعضی VPSها دیده شود، روی سرور اختصاصی وجود ندارد. برای شروع سریع می‌توانید نودهای موردنیاز را با سرور مجازی ابری آریانت ایجاد کنید. اگر بار کاری شما به منابع پایدار و توان پردازشی بیشتری نیاز دارد، سرور اختصاصی انتخاب مناسب‌تری خواهد بود. تفاوت‌های فنی دقیق‌تر این دو گزینه را می‌توانید در سرور اختصاصی چه تفاوتی با سرور مجازی دارد؟ بخوانید.

پیش‌نیازهای راه‌اندازی Kubernetes

پیش از نصب، موارد زیر را برای تمام نودها آماده کنید: - Ubuntu Server با دسترسی کاربر root یا کاربری دارای sudo - آدرس IP ثابت برای هر نود - ارتباط شبکه‌ای مستقیم میان نودها - نام میزبان یکتا - همگام‌سازی ساعت سیستم - دسترسی به مخازن بسته و رجیستری ایمیج‌ها - باز بودن پورت‌های لازم در فایروال در مثال این مقاله از مشخصات زیر استفاده می‌کنیم: | Hostname | IP خصوصی | نقش | |---|---|---| | k8s-control-1 | 10.10.0.10 | Control Plane | | k8s-worker-1 | 10.10.0.11 | Worker | | k8s-worker-2 | 10.10.0.12 | Worker | بهتر است ارتباط داخلی نودها از طریق شبکه خصوصی انجام شود. اگر نودها فقط IP عمومی دارند، دسترسی پورت‌ها را به IP همان نودها محدود کنید و هیچ پورت مدیریتی را بدون محدودیت در اینترنت قرار ندهید.

آماده‌سازی تمام نودها

دستورهای این بخش باید روی Control Plane و تمام Workerها اجرا شوند.

تنظیم hostname و فایل hosts

روی هر سرور نام میزبان متناسب با نقش آن را تنظیم کنید. برای نمونه، روی نود کنترل:

sudo hostnamectl set-hostname k8s-control-1

روی هر Worker نیز نام خودش را قرار دهید. سپس در فایل /etc/hosts تمام نودها را ثبت کنید:

10.10.0.10 k8s-control-1
10.10.0.11 k8s-worker-1
10.10.0.12 k8s-worker-2

با ping یا ابزارهای مشابه مطمئن شوید نودها یکدیگر را با IP خصوصی و hostname می‌بینند.

غیرفعال‌کردن Swap

Kubelet برای مدیریت درست منابع به تنظیمات مشخصی نیاز دارد و در پیکربندی رایج kubeadm باید Swap غیرفعال باشد:

sudo swapoff -a

برای جلوگیری از فعال‌شدن دوباره Swap پس از ریبوت، ورودی مربوط به آن را در /etc/fstab کامنت یا حذف کنید. سپس وضعیت را بررسی کنید:

swapon --show
free -h

خروجی swapon --show باید خالی باشد. اگر پیش‌تر Swap را روی این سرور فعال کرده‌اید، مراحل کامل ساخت و پیکربندی آن در نحوه ایجاد حافظه Swap در لینوکس اوبونتو ۲۰.۰۴ توضیح داده شده است.

فعال‌کردن ماژول‌ها و تنظیمات شبکه کرنل

ماژول‌های موردنیاز را بارگذاری کنید:

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter

سپس پارامترهای شبکه را تنظیم کنید:

cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system

فعال‌بودن ip_forward برای عبور ترافیک میان شبکه Podها و شبکه نودها ضروری است.

نصب و پیکربندی containerd

Kubernetes مستقیماً کانتینرها را اجرا نمی‌کند و به یک Container Runtime سازگار با CRI نیاز دارد. در این آموزش از containerd استفاده می‌کنیم:

sudo apt-get update
sudo apt-get install -y containerd

پیکربندی پیش‌فرض را ایجاد کنید:

sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml

در فایل /etc/containerd/config.toml گزینه SystemdCgroup را به true تغییر دهید:

SystemdCgroup = true

سپس سرویس را راه‌اندازی مجدد و فعال کنید:

sudo systemctl restart containerd
sudo systemctl enable containerd
sudo systemctl status containerd

هماهنگ‌بودن cgroup driver میان kubelet و containerd از خطاهای پایداری و رفتارهای پیش‌بینی‌نشده جلوگیری می‌کند. برای آشنایی بیشتر با مدیریت ایمیج‌ها و کانتینرها در سطح Container Runtime، مدیریت و حذف ایمیج‌ها، کانتینرها، حجم‌ها و شبکه‌های Docker را نیز مطالعه کنید.

نصب kubeadm، kubelet و kubectl

ابتدا ابزارهای لازم برای اضافه‌کردن مخزن Kubernetes را نصب کنید:

sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl gpg
sudo mkdir -p -m 755 /etc/apt/keyrings

کلید و مخزن نسخه موردنظر را اضافه کنید:

curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key \
  | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /' \
  | sudo tee /etc/apt/sources.list.d/kubernetes.list

حالا سه مؤلفه اصلی را نصب کنید:

sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

kubeadm کلاستر را ایجاد می‌کند، kubelet عامل اجرایی هر نود است و kubectl برای مدیریت کلاستر به کار می‌رود. نگه‌داشتن نسخه بسته‌ها مانع ارتقای ناخواسته و ناسازگاری اجزای کلاستر می‌شود.

ساخت Control Plane با kubeadm

فرایند ساخت Control Plane با kubeadm و اتصال Worker Nodeها در کلاستر Kubernetes این بخش را فقط روی سرور k8s-control-1 اجرا کنید. پیش از شروع می‌توانید ایمیج‌های لازم را دریافت کنید:

sudo kubeadm config images pull

سپس Control Plane را بسازید:

sudo kubeadm init \
  --apiserver-advertise-address=10.10.0.10 \
  --pod-network-cidr=192.168.0.0/16

مقدار --apiserver-advertise-address باید IP قابل‌دسترسی Control Plane برای Workerها باشد. مقدار --pod-network-cidr نیز باید با افزونه شبکه انتخابی هماهنگ شود. این مثال برای CNIهایی مناسب است که از این محدوده پشتیبانی می‌کنند. پس از پایان موفق عملیات، kubeadm یک دستور kubeadm join نمایش می‌دهد. آن را در محلی امن نگه دارید؛ Workerها با همین دستور به کلاستر متصل می‌شوند. برای استفاده از kubectl با کاربر فعلی، فایل پیکربندی را کپی کنید:

mkdir -p "$HOME/.kube"
sudo cp -i /etc/kubernetes/admin.conf "$HOME/.kube/config"
sudo chown "$(id -u):$(id -g)" "$HOME/.kube/config"

وضعیت نود را ببینید:

kubectl get nodes

در این مرحله احتمالاً نود NotReady است، زیرا هنوز افزونه شبکه نصب نشده است.

نصب افزونه شبکه CNI

بدون CNI، Podهای قرارگرفته روی نودهای مختلف نمی‌توانند با یکدیگر ارتباط برقرار کنند. گزینه‌هایی مانند Calico و Cilium امکانات متفاوتی در زمینه Network Policy، مشاهده‌پذیری و امنیت ارائه می‌دهند. فایل manifest افزونه انتخابی را فقط از مستندات رسمی همان پروژه دریافت کنید و مطمئن شوید محدوده شبکه آن با --pod-network-cidr سازگار است. برای نصب، معمولاً دستوری با ساختار زیر اجرا می‌شود:

kubectl apply -f <OFFICIAL-CNI-MANIFEST-URL>

به‌جای عبارت نمونه، URL نسخه مشخص و سازگار CNI را قرار دهید. استفاده از آدرس نسخه‌بندی‌شده، بازتولید نصب و کنترل تغییرات را آسان‌تر می‌کند. پس از چند دقیقه وضعیت Podهای سیستمی را بررسی کنید:

kubectl get pods -n kube-system
kubectl get nodes

نود Control Plane باید به وضعیت Ready برسد. اگر چنین نشد، لاگ Podهای CNI و وضعیت kubelet را بررسی کنید.

اتصال Worker Nodeها به کلاستر

روی هر Worker، دستور تولیدشده در خروجی kubeadm init را اجرا کنید. ساختار دستور شبیه نمونه زیر است:

sudo kubeadm join 10.10.0.10:6443 \
  --token <TOKEN> \
  --discovery-token-ca-cert-hash sha256:<HASH>

توکن و هش واقعی را از خروجی کلاستر خود بردارید و مقادیر نمونه را عیناً استفاده نکنید. اگر دستور join را گم کرده‌اید یا توکن منقضی شده است، روی Control Plane دستور جدید بسازید:

kubeadm token create --print-join-command

اکنون روی Control Plane نودها را مشاهده کنید:

kubectl get nodes -o wide

هر سه نود باید پس از آماده‌شدن شبکه در وضعیت Ready قرار بگیرند.

آزمایش عملکرد کلاستر

برای اطمینان از زمان‌بندی و اجرای صحیح Podها، یک Deployment آزمایشی ایجاد کنید:

kubectl create deployment web-test --image=nginx:stable
kubectl scale deployment web-test --replicas=2
kubectl get pods -o wide

برای دسترسی داخلی به برنامه، یک Service بسازید:

kubectl expose deployment web-test \
  --name=web-test-service \
  --port=80 \
  --target-port=80
kubectl get service web-test-service

با مشاهده ستون NODE در خروجی Podها می‌توانید ببینید هر نمونه روی کدام Worker اجرا شده است. برای حذف منابع آزمایشی نیز اجرا کنید:

kubectl delete service web-test-service
kubectl delete deployment web-test

پورت‌های مهم و تنظیم فایروال

بازکردن پورت‌ها باید براساس نقش نود و فقط برای شبکه‌های مورداعتماد انجام شود. مهم‌ترین پورت API Server، پورت TCP شماره 6443 است که Workerها و مدیران کلاستر به آن متصل می‌شوند. Control Plane همچنین برای etcd و اجزای کنترلی به پورت‌های دیگری نیاز دارد. Workerها نیز از پورت‌هایی مانند kubelet و محدوده NodePort استفاده می‌کنند. فهرست دقیق ممکن است با نسخه Kubernetes، توپولوژی کلاستر و CNI تغییر کند؛ بنابراین جدول پورت‌های مستندات رسمی نسخه نصب‌شده را مبنا قرار دهید. هیچ‌گاه پورت etcd یا kubelet را برای تمام اینترنت باز نکنید. قواعد فایروال را به IP خصوصی نودها، شبکه مدیریت و مبدأهای ضروری محدود کنید. برای پیاده‌سازی این قواعد در سطح سیستم‌عامل می‌توانید از راهنمای پایه قواعد و فرمان‌های فایروال iptables کمک بگیرید.

خطاهای رایج در راه‌اندازی کلاستر

نود در وضعیت NotReady باقی مانده است

ابتدا وضعیت Podهای سیستمی و kubelet را بررسی کنید:

kubectl get pods -n kube-system -o wide
sudo systemctl status kubelet
sudo journalctl -u kubelet --no-pager -n 100

نصب‌نشدن CNI، ناسازگاری محدوده Pod، فعال‌بودن Swap یا مشکل containerd از علت‌های رایج هستند.

Worker نمی‌تواند Join شود

دسترسی Worker به IP و پورت 6443 را بررسی کنید. اختلاف ساعت سیستم‌ها، توکن منقضی‌شده، DNS نادرست یا مسدودبودن ترافیک توسط فایروال نیز می‌تواند فرایند اتصال را مختل کند. اگر یک تلاش ناقص وضعیت نود را به‌هم زده است، پس از بررسی علت می‌توان روی Worker فرمان زیر را اجرا و سپس join را تکرار کرد:

sudo kubeadm reset

این دستور همه تنظیمات شبکه و فایل‌های باقی‌مانده را لزوماً پاک نمی‌کند؛ پیش از استفاده در سرور عملیاتی، اثر آن را بررسی کنید.

Podها به اینترنت یا یکدیگر دسترسی ندارند

فعال‌بودن net.ipv4.ip_forward، وضعیت CNI، routeها و قواعد فایروال را کنترل کنید. هم‌پوشانی CIDR شبکه Podها با شبکه خصوصی سرورها یا VPN نیز می‌تواند باعث اختلال شود.

نکات ضروری برای محیط عملیاتی

راه‌اندازی کلاستر Kubernetes با kubeadm پایان کار نیست. برای استفاده عملیاتی باید موارد زیر نیز طراحی شوند: - چند Control Plane و یک Load Balancer برای حذف نقطه شکست واحد - پشتیبان‌گیری منظم و آزمایش بازیابی etcd - مانیتورینگ نودها، Podها و ظرفیت منابع - جمع‌آوری متمرکز لاگ‌ها - تعریف Network Policy و محدودکردن ارتباط سرویس‌ها - مدیریت امن Secretها - نصب Ingress Controller و مدیریت گواهی TLS - برنامه مشخص برای ارتقای Kubernetes - محدودکردن دسترسی با RBAC - استفاده از Persistent Volume و راهکار ذخیره‌سازی متناسب با بار کاری برای انتشار سرویس‌های عمومی نیز بهتر است ترافیک ورودی پشت لایه‌ای امن و قابل‌کنترل قرار بگیرد. در پروژه‌های پرترافیک، استفاده از شبکه توزیع محتوا می‌تواند تحویل محتوای ثابت را سریع‌تر و فشار مستقیم روی سرویس‌های کلاستر را کمتر کند.

جمع‌بندی

در این آموزش، نودها را آماده کردیم، Swap را غیرفعال کردیم، containerd و ابزارهای Kubernetes را نصب کردیم و با kubeadm یک Control Plane ساختیم. سپس با نصب CNI، Workerها را به کلاستر متصل و اجرای یک برنامه آزمایشی را بررسی کردیم. kubeadm مسیر استاندارد و منعطفی برای ساخت Kubernetes روی VPS و سرور اختصاصی فراهم می‌کند، اما مدیریت چرخه عمر کلاستر همچنان بر عهده تیم زیرساخت است. پیش از انتقال سرویس‌های حساس، افزونگی، امنیت شبکه، مانیتورینگ، پشتیبان‌گیری و فرایند ارتقا را آزمایش و مستند کنید.