اگر شما هم با چالشهای استقرار نرمافزار در محیطهای مختلف، ناسازگاری وابستگیها و مصرف بیرویه منابع سرور مواجه هستید، قطعاً به دنبال راهکاری پایدار و مقیاسپذیر برای مدیریت برنامهها میگردید. راهاندازی کانتینرهای Docker و ارکستراسیون با Kubernetes دقیقاً همان پاسخی است که معماری مدرن نرمافزار به آن نیاز دارد. در این راهنمای جامع، از مفاهیم بنیادین کانتینرها شروع میکنیم، نحوه اجرای Docker را قدمبهقدم میآموزیم، سپس وارد دنیای Kubernetes شده و یک کلاستر واقعی را برای محیط تولید پیکربندی میکنیم. هدف نهایی، توانمندسازی شما برای استقرار برنامههای سبک، ایزوله و کاملاً مدیریتشده روی زیرساختهای VPS یا سرور اختصاصی است.
چرا کانتینرهای Docker به استاندارد صنعت تبدیل شدند؟
پیش از Docker، استقرار یک برنامه معمولاً به معنی نصب مستقیم روی سیستمعامل میزبان، مدیریت دستی وابستگیها و ریسک تداخل نسخهها بود. کانتینرها این مشکل را با بستهبندی برنامه به همراه تمام کتابخانهها، تنظیمات و runtime مورد نیازش در یک واحد ایزوله حل کردند. برخلاف ماشینهای مجازی سنتی که هر کدام یک هسته کامل سیستمعامل را اجرا میکنند، کانتینرها هسته سیستمعامل میزبان را به اشتراک میگذارند و تنها لایههای لازم برای اجرای برنامه را شامل میشوند. نتیجه این معماری، مصرف بسیار کمتر RAM و CPU، زمان راهاندازی زیر یک ثانیه و قابلیت جابهجایی آسان بین محیطهای توسعه، تست و تولید است.
تفاوت کانتینر و ماشین مجازی (VM)
درک این تفاوت برای انتخاب زیرساخت میزبانی حیاتی است. یک ماشین مجازی با Hypervisor سختافزاری مجزا میسازد و هر VM یک سیستمعامل کامل (مثلاً Ubuntu یا CentOS) را بارگذاری میکند. در مقابل، کانتینر صرفاً یک فرآیند ایزولهشده در هسته لینوکس است که با استفاده از namespace ها و cgroup ها منابع را مدیریت میکند. این یعنی روی یک سرور VPS با 4 گیگابایت RAM، میتوانید دهها کانتینر سبک اجرا کنید در حالی که اجرای همان تعداد VM عملاً غیرممکن است. برای محیطهای Docker و Kubernetes، انتخاب یک VPS با حافظه NVMe و پردازنده قوی اهمیت ویژهای دارد، زیرا I/O دیسک و لاتنسی شبکه مستقیماً روی عملکرد کانتینرها اثر میگذارد.
نصب و راهاندازی Docker روی لینوکس
برای شروع، فرض میکنیم یک سرور لینوکسی با توزیع Ubuntu 22.04 یا Debian 12 در اختیار دارید. اگر از سرویس VPS استفاده میکنید، مطمئن شوید که دسترسی root یا کاربر با sudo دارید. ابتدا مخزن رسمی Docker را اضافه کرده و سپس Docker Engine و Docker Compose را نصب کنید. دستورات زیر را بهترتیب اجرا کنید:
1 2 3 4 5 6 7 | sudo apt update && sudo apt install -y ca-certificates curl gnupg sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin sudo usermod -aG docker $USER |
پس از نصب، با خروج از ترمینال و ورود مجدد، کاربر شما به گروه docker اضافه میشود تا بدون sudo بتوانید دستورات Docker را اجرا کنید. برای اطمینان از صحت نصب، دستور docker run hello-world را تست کنید. این مرحله پایهای برای تمام مراحل بعدی راهاندازی کانتینرهای Docker و ارکستراسیون با Kubernetes است.
مدیریت تصاویر و ساخت Dockerfile
تصویر (Image) یک قالب فقطخواندنی است که کانتینر از روی آن ساخته میشود. معمولاً تصاویر پایه را از Docker Hub دریافت میکنید، اما برای برنامههای اختصاصی باید Dockerfile بنویسید. یک نمونه ساده برای اجرای یک اپلیکیشن Node.js به این صورت است:
1 2 3 4 5 6 7 | FROM node:20-alpine WORKDIR /app COPY package*.json ./ RUN npm ci --only=production COPY . . EXPOSE 3000 CMD ["node", "server.js"] |
سپس با دستور docker build -t my-app:v1 . تصویر را ساخته و با docker run -d -p 80:3000 --name my-app-container my-app:v1 آن را اجرا میکنید. همیشه از تگهای مشخص بهجای latest استفاده کنید تا سازگاری نسخهها تضمین شود. برای محیطهای توسعه، Docker Compose فایلهای yaml را برای اجرای چند سرویس بهصورت همزمان مدیریت میکند که در پروژههای real-world ضروری است.
ارکستراسیون با Kubernetes: از تککانتینر تا کلاستر مقیاسپذیر
Docker به تنهایی برای اجرای چند کانتینر روی یک هاست عالی است، اما وقتی تعداد سرویسها افزایش مییابد، به ابزاری برای زمانبندی، توزیع بار، بازیابی خودکار و مقیاسپذیری افقی نیاز دارید. Kubernetes (که به اختصار k8s نامیده میشود) استاندارد بالفعل ارکستراسیون کانتینر است. این سیستم که توسط گوگل توسعه یافته و اکنون تحت حمایت بنیاد CNCF قرار دارد، یک لایه کنترلی هوشمند روی چندین نود (سرور) ایجاد میکند و تضمین میکند که برنامه شما همیشه در وضعیت مطلوب (Desired State) باقی بماند.
معماری Kubernetes شامل دو بخش اصلی است: Control Plane (مدیریت کلاستر) و Worker Nodes (اجرای بارهای کاری). اجزای اصلی Control Plane عبارتند از API Server، etcd (پایگاه داده توزیعشده)، Scheduler و Controller Manager. روی هر Worker Node نیز kubelet، kube-proxy و Container Runtime (مانند containerd یا CRI-O) اجرا میشود. این ساختار توزیعشده، نقطه شکست واحدی ندارد و در صورت خرابی یک نود، سرویسها بهصورت خودکار روی نود دیگر بازآفرینی میشوند.
انتخاب روش استقرار Kubernetes
بسته به مقیاس پروژه و سطح تخصص تیم، سه گزینه اصلی پیش روی شماست:
| روش استقرار | مزایا | معایب | مناسب برای |
|---|---|---|---|
| Minikube / Kind | نصب آسان، عالی برای یادگیری و توسعه محلی | تکنود، بدون High Availability، منابع محدود | توسعهدهندگان، محیط تست |
| Kubeadm (خودمدیریتی) | کنترل کامل، بدون وابستگی به ارائهدهنده، هزینه پایین | مسئولیت نگهداری Control Plane، ارتقا و امنیت | تیمهای DevOps با تجربه، محیطهای Staging و Production کوچک |
| Managed Kubernetes (EKS, GKE, AKS, یا سرویسهای ایرانی) | بدون دغدغه نگهداری، SLA بالا، یکپارچگی با سرویسهای ابری | هزینه بیشتر، وابستگی به ارائهدهنده | محیطهای Production حساس، تیمهای بدون تخصص عمیق زیرساخت |
اگر از VPS اختصاصی یا چندین سرور ابری استفاده میکنید و میخواهید کلاستر خودتان را با kubeadm راهاندازی کنید، حداقل به 3 نود (یک Control Plane و دو Worker) نیاز دارید. حداقل منابع پیشنهادی برای هر نود Control Plane برابر 2 گیگابایت RAM و 2 vCPU است. برای Worker Node ها نیز بسته به بار کاری، 4 گیگابایت RAM و 4 vCPU منطقی است. همچنین استفاده از دیسکهای NVMe تأثیر چشمگیری روی سرعت etcd و pull تصاویر دارد.
راهاندازی گامبهگام کلاستر Kubernetes با kubeadm
در این بخش، یک سناریوی عملی برای استقرار کلاستر روی سه سرور VPS با سیستمعامل Ubuntu 22.04 ارائه میدهیم. ابتدا روی همه نودها (Control Plane و Worker ها) این مراحل را انجام دهید:
- غیرفعالسازی Swap:
sudo swapoff -a && sudo sed -i '/swap/d' /etc/fstab - بارگذاری ماژولهای هسته:
sudo modprobe overlay && sudo modprobe br_netfilter - تنظیم پارامترهای sysctl برای ترافیک شبکه:
sudo sysctl --system - نصب Container Runtime (مثلاً containerd) و پیکربندی آن
- نصب kubeadm، kubelet و kubectl از مخزن رسمی Kubernetes
پس از آمادهسازی همه نودها، روی نود Control Plane دستور زیر را اجرا کنید:
1 | sudo kubeadm init --pod-network-cidr=10.244.0.0/16 |
خروجی این دستور شامل یک فرمان kubeadm join است که باید روی هر Worker Node اجرا کنید. سپس برای دسترسی کاربر عادی به کلاستر، کانفیگ kubeconfig را کپی کنید:
1 2 3 | mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config |
در نهایت یک CNI (Container Network Interface) مانند Calico یا Flannel نصب کنید تا Podها بتوانند با یکدیگر ارتباط برقرار کنند. دستور برای Calico: kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.26/manifests/calico.yaml
مفاهیم کلیدی Pod، Deployment و Service
در Kubernetes، کوچکترین واحد قابل استقرار Pod نام دارد که میتواند شامل یک یا چند کانتینر باشد. برای مدیریت چرخه حیات Podها از Deployment استفاده میکنید که تعداد replica ها، استراتژی بهروزرسانی و Rollback را کنترل میکند. Service نیز یک آدرس IP پایدار و DNS برای دسترسی به مجموعهای از Podها فراهم میآورد. یک نمونه Deployment ساده برای اجرای سه نسخه از یک اپلیکیشن:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | apiVersion: apps/v1 kind: Deployment metadata: name: web-app spec: replicas: 3 selector: matchLabels: app: web template: metadata: labels: app: web spec: containers: - name: web-container image: nginx:1.25 ports: - containerPort: 80 resources: requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m" |
با اعمال این فایل از طریق kubectl apply -f deployment.yaml، سیستم بهطور خودکار سه Pod را روی نودهای مختلف توزیع میکند. این قابلیت توزیع خودکار بار و بازیابی پس از خرابی، دقیقاً همان چیزی است که راهاندازی کانتینرهای Docker و ارکستراسیون با Kubernetes را به یک راهکار حیاتی برای وبسایتها و سرویسهای با ترافیک بالا تبدیل میکند.
بهترین روشها برای استقرار در محیط Production
استقرار Docker و Kubernetes در محیط عملیاتی نیازمند رعایت اصول امنیتی و بهینهسازی منابع است. نخست، همیشه تصاویر خود را از منابع معتبر دریافت کرده و آنها را با ابزارهایی مانند Trivy یا Clair اسکن کنید. دوم، برای هر کانتینر Resource Requests و Limits تعیین کنید تا از مصرف بیش از حد یک Pod و تأثیر منفی روی سایر سرویسها جلوگیری شود. سوم، از Namespace ها برای ایزولهسازی محیطهای توسعه، تست و تولید استفاده کنید و RBAC (کنترل دسترسی مبتنی بر نقش) را برای کاربران و سرویس اکانتها فعال نمایید.
مانیتورینگ و لاگگیری نیز جزء جداییناپذیر عملیات هستند. ابزارهایی مانند Prometheus برای متریکها و Grafana برای داشبوردهای بصری، بههمراه Loki برای جمعآوری لاگها، یک پشته کامل Observability را تشکیل میدهند. برای پشتیبانگیری از دادههای etcd (مغز کلاستر) و ولومهای پایدار، زمانبندی منظم تعیین کنید و حداقل یک نسخه پشتیبان خارج از کلاستر نگهداری کنید.
نقش زیرساخت میزبانی در موفقیت کلاستر Kubernetes
کیفیت سختافزار و شبکه زیربنایی، مستقیماً بر پایداری و عملکرد کانتینرها اثر میگذارد. برای کلاسترهای Production، انتخاب یک VPS یا سرور اختصاصی با پردازندههای نسل جدید، حافظه رم DDR5 و دیسکهای NVMe ضروری است. لاتنسی شبکه بین نودها باید حداقل باشد، بنابراین سرورهای داخل یک دیتاسنتر یا منطقه ابری واحد را انتخاب کنید. همچنین Uptime تضمینی ارائهدهنده میزبانی باید بالای 99.9% باشد و امکان ارتقای عمودی (افزایش RAM و CPU) بدون توقف سرویس را فراهم کند. بسیاری از تیمها ابتدا با یک VPS اقتصادی شروع میکنند و پس از رشد ترافیک، به سرورهای Bare-Metal یا Managed Kubernetes کوچ میکنند.
جمعبندی
در این مقاله، مسیر کامل راهاندازی کانتینرهای Docker و ارکستراسیون با Kubernetes را از صفر تا محیط Production بررسی کردیم. ابتدا مزایای کانتینرها نسبت به ماشینهای مجازی را شناختیم، سپس نصب Docker و ساخت تصاویر را آموختیم، و در نهایت یک کلاستر Kubernetes واقعی با kubeadm را روی چند نود VPS پیکربندی کردیم. نکته کلیدی این است که Docker به شما امکان بستهبندی و اجرای ایزوله را میدهد، اما Kubernetes مغز متفکری است که مقیاسپذیری، خودترمیمی و توزیع هوشمند بار را مدیریت میکند. با انتخاب زیرساخت میزبانی مناسب و رعایت بهترین روشهای امنیتی و مانیتورینگ، میتوانید زیربنای فنی خود را برای رشد بلندمدت آماده کنید.
سوالات متداول
آیا برای استفاده از Kubernetes حتماً باید Docker نصب باشد؟
خیر، از نسخه 1.24 به بعد، Kubernetes پشتیبانی داخلی از Docker Shim را حذف کرد. اکنون باید از Container Runtime های سازگار با CRI مانند containerd یا CRI-O استفاده کنید. با این حال، Docker همچنان بهعنوان ابزار توسعه و ساخت تصاویر محبوب است و تصاویر ساختهشده با Docker کاملاً با containerd سازگارند.
حداقل منابع سختافزاری برای اجرای یک کلاستر Kubernetes چقدر است؟
برای یک کلاستر آزمایشی با Minikube، 2 هسته CPU و 2 گیگابایت RAM کافی است. اما برای Production با kubeadm، هر نود Control Plane به حداقل 2 هسته و 2 گیگابایت رم نیاز دارد و Worker Node ها بسته به بار کاری معمولاً بین 4 تا 8 گیگابایت رم و 4 هسته پیشنهاد میشود. همچنین دیسک NVMe با حداقل 50 گیگابایت فضای آزاد برای هر نود الزامی است.
تفاوت Docker Swarm و Kubernetes چیست و کدام را انتخاب کنم؟
Docker Swarm سادهتر است و یکپارچگی کامل با Docker CLI دارد، اما امکانات پیشرفتهای مانند Auto-scaling بر اساس متریک، Rollback خودکار پیچیده و اکوسیستم گسترده افزونهها را ندارد. Kubernetes منحنی یادگیری تندتری دارد اما استاندارد صنعت محسوب میشود و تقریباً تمام ارائهدهندگان ابری از آن پشتیبانی میکنند. برای پروژههای کوچک با ۲ تا ۳ سرویس، Swarm کافی است؛ اما برای هر چیزی که احتمال رشد دارد، Kubernetes انتخاب هوشمندانهتری است.
آیا میتوانم Kubernetes را روی یک VPS معمولی اجرا کنم؟
بله، به شرطی که VPS شما از مجازیسازی KVM یا Xen استفاده کند (نه OpenVZ) و منابع کافی (حداقل 2 هسته و 4 گیگابایت رم) داشته باشد. همچنین باید دسترسی root و امکان تغییر تنظیمات کرنل مانند بارگذاری ماژولها را داشته باشید. برخی ارائهدهندگان VPS ارزانقیمت این امکانات را محدود میکنند، بنابراین پیش از خرید، مشخصات فنی را بررسی کنید.
چگونه میتوانم امنیت کلاستر Kubernetes را افزایش دهم؟
پنج اقدام حیاتی عبارتند از: فعالسازی RBAC و استفاده از Roles با حداقل دسترسی، غیرفعالسازی دسترسی anonymous به API Server، رمزنگاری etcd با TLS، اسکن مداوم تصاویر برای آسیبپذیری و اعمال Network Policy برای محدودسازی ترافیک بین Podها. همچنین API Server را پشت یک فایروال و در صورت امکان با یک Identity Provider یکپارچه کنید.