کوبرنتیز چیست؟ معماری، تفاوت با داکر و آموزش نصب k3s روی سرور

فهرست مطالب
- کوبرنتیز چیست و چه مشکلی را حل میکند؟
- تفاوت داکر و کوبرنتیز
- معماری کوبرنتیز: لایهٔ کنترل و نودها
- مفاهیم اصلی کوبرنتیز
- انواع Service
- Ingress، Gateway API و پایان ingress-nginx
- Secret فقط base64 است
- آیا به کوبرنتیز نیاز دارید؟
- توزیعهای کوبرنتیز: kubeadm، k3s، MicroK8s و k0s
- نصب k3s روی اوبونتو، گامبهگام
- پیشنیازها و پورتها
- گام ۱: تنظیمات و نصب k3s
- گام ۲: kubectl بدون sudo
- گام ۳: فایروال
- گام ۴: Deployment و Service
- گام ۵: انتشار با Ingress و Traefik
- گام ۶: مقیاسدهی، بهروزرسانی و بازگشت
- گام ۷: افزودن نود کارگر
- حذف k3s
- دستورات پرکاربرد kubectl
- کوبرنتیز روی سرورهای داخل ایران
- میرور Docker Hub با registries.yaml
- نصب آفلاین k3s (Air-gap)
- رجیستری خصوصی یا نود خارج از ایران
- رفع خطاهای رایج کوبرنتیز
- امنیت و نگهداری کلاستر
- چرخهٔ پشتیبانی نسخهها
- سرور مناسب برای کوبرنتیز
- پرسشهای متداول
- کوبرنتیز به زبان ساده چیست؟
- تفاوت k3s و k8s چیست؟
- آیا کوبرنتیز رایگان است؟
- یادگیری کوبرنتیز را از کجا شروع کنم؟
- آیا کوبرنتیز جای داکر را میگیرد؟
- آیا کوبرنتیز روی سرور ایران نصب میشود؟
- جمعبندی
کوبرنتیز چیست؟ کوبرنتیز (Kubernetes یا K8s) نرمافزاری متنباز برای اجرا و مدیریت کانتینرها روی یک یا چند سرور است: شما مینویسید چه برنامهای با چند نسخه اجرا شود و کوبرنتیز جای اجرا، ریاستارت کانتینر خراب، توزیع بار و بهروزرسانی بدون قطعی را خودکار انجام میدهد.
در این راهنما معماری کوبرنتیز و زمان نیاز به آن را میبینید و در بخش عملی، k3s را روی Ubuntu 24.04 نصب میکنید و یک برنامه را منتشر، بهروز و بازگردانی میکنید. نکتههای سرورهای داخل ایران بخش جداگانهای دارد و دستورها در آبان ۱۴۰۵ با مستندات رسمی تطبیق داده شدهاند.
بهطور خلاصه: وضعیت مطلوب را (مثلاً «۳ نسخه از این ایمیج، پشت یک آدرس ثابت») در فایل YAML مینویسید و کوبرنتیز مدام وضعیت واقعی را به آن میرساند.
- داکر ایمیج میسازد و کانتینر را روی یک سرور اجرا میکند؛ کوبرنتیز همان ایمیجها را روی چند نود مدیریت میکند.
- برای یک سایت یا اپ کوچک، Docker Compose روی یک سرور کافی است.
- برای شروع روی سرور، k3s کمدردسر است؛ نود سرور آن طبق مستندات دستکم ۲ هستهٔ CPU و ۲ گیگابایت رم میخواهد.
- روی سرور ایران حتی ایمیجهای سیستمی k3s از Docker Hub میآیند؛ پیش از نصب، میرور یا نصب آفلاین را آماده کنید.
کوبرنتیز چیست و چه مشکلی را حل میکند؟
نام کوبرنتیز (که کوبرنتیس هم نوشته میشود) از واژهای یونانی به معنای سکاندار است و K8s شکل کوتاه آن است: ۸ حرف بین K و s. گوگل آن را در ۲۰۱۴ متنباز کرد و امروز از پروژههای بالغ (Graduated) بنیاد CNCF است.
اجرای چند کانتینر روی یک سرور با داکر ساده است. مشکل از دهها کانتینر روی چند سرور شروع میشود: هر کانتینر کجا اجرا شود، با خاموش شدن یک سرور چه شود، نسخهٔ جدید چطور بدون قطعی جایگزین شود و سرویسها با IPهای متغیر چطور همدیگر را پیدا کنند. کوبرنتیز این کارها را خودکار میکند:
- زمانبندی (Scheduling): هر کانتینر را بر اساس CPU و رمی که لازم دارد، روی سروری (نود) با ظرفیت کافی اجرا میکند.
- خودترمیمی (Self-healing): کانتینر خراب را دوباره اجرا میکند و اگر نودی از دسترس خارج شود، بهطور پیشفرض حدود ۵ دقیقه بعد کانتینرهایش را روی نودهای سالم میسازد.
- مقیاسدهی (Scaling): تعداد نسخهها را دستی یا خودکار بر اساس مصرف CPU تغییر میدهد.
- بهروزرسانی تدریجی و بازگشت (Rolling Update و Rollback): نسخهٔ جدید را کمکم جایگزین میکند و با یک دستور به نسخهٔ قبل برمیگردد.
- کشف سرویس و توزیع بار: به هر گروه کانتینر نام DNS و IP ثابت میدهد و درخواستها را بینشان پخش میکند.
کوبرنتیز پلتفرم کامل و آماده (PaaS) نیست: کد را build نمیکند (این کار CI/CD است)، دیتابیس آماده نمیدهد و ابزار لاگ و مانیتورینگ را خودتان انتخاب میکنید.
تفاوت داکر و کوبرنتیز
داکر (Docker) ایمیج میسازد و کانتینر را روی یک سرور اجرا میکند و Docker Compose چند کانتینر مرتبط را روی همان سرور بالا میآورد. کوبرنتیز همان ایمیجها را روی یک کلاستر (Cluster)، یعنی گروهی از سرورها، اجرا و مدیریت میکند؛ پس رقیب نیستند و معمولاً ایمیج با داکر ساخته و با کوبرنتیز اجرا میشود. برای چند سرور، حالت Swarm خود Docker Engine هم هست که سادهتر است، اما امکانات کمتری دارد. نصب داکر و Compose در آموزش نصب داکر روی اوبونتو آمده است.
آموزشهای قدیمی این نکته را ندارند: کوبرنتیز کانتینر را با یک محیط اجرای سازگار با رابط CRI (Container Runtime Interface)، معمولاً containerd یا CRI-O، اجرا میکند و اتصال مستقیمش به Docker Engine (به نام dockershim) از نسخهٔ 1.24 در سال ۲۰۲۲ حذف شده است. ایمیجهای داکر استاندارد OCI هستند و بدون تغییر روی کوبرنتیز اجرا میشوند.
| ویژگی | Docker Compose | کوبرنتیز |
|---|---|---|
| خرابی کانتینر | ریاستارت با restart policy | ریاستارت خودکار و جایگزینی پاد ازدسترفته |
| خرابی سرور | همهچیز متوقف میشود | پادها روی نودهای سالم دیگر ساخته میشوند |
| بهروزرسانی | معمولاً با قطعی کوتاه | تدریجی، با بازگشت یکدستوری |
معماری کوبرنتیز: لایهٔ کنترل و نودها
هر کلاستر یک لایهٔ کنترل (Control Plane) دارد که تصمیم میگیرد و نودهای کارگر (Worker Node) که کانتینرها را اجرا میکنند. در کلاستر کوچک هر دو روی یک سرورند و k3s روی نود سرور هم برنامه اجرا میکند.
| جزء | محل | وظیفه |
|---|---|---|
| kube-apiserver | لایهٔ کنترل | درِ ورود کلاستر؛ همهٔ درخواستها از API آن میگذرند |
| etcd | لایهٔ کنترل | پایگاهدادهٔ وضعیت کلاستر (در k3s تکسرور: SQLite) |
| kube-scheduler | لایهٔ کنترل | انتخاب نود برای پادهای تازه |
| kube-controller-manager | لایهٔ کنترل | کنترلرهایی که وضعیت را به حالت مطلوب میرسانند |
| kubelet | هر نود | اجرا و پایش پادهای نود |
| kube-proxy | هر نود، اختیاری | قانونهای شبکه برای Service |
| Container Runtime | هر نود | اجرای کانتینر، مثلاً containerd |
افزونهٔ شبکه (CNI) مثل Flannel به پادها IP میدهد و CoreDNS نام سرویسها را ترجمه میکند. با kubectl apply، شیء در etcd ذخیره میشود، کنترلرها پادها را تعریف میکنند، scheduler نود را برمیگزیند و kubelet کانتینر را اجرا میکند.
مفاهیم اصلی کوبرنتیز
هر چیزی در کوبرنتیز یک شیء (Object) است که در YAML تعریف میشود:
| شیء | کاربرد | مثال |
|---|---|---|
| Pod | کوچکترین واحد اجرا؛ یک یا چند کانتینر با IP مشترک | یک کانتینر وب |
| Deployment و ReplicaSet | تعداد ثابتی پاد یکسان، با بهروزرسانی تدریجی و بازگشت | اپ بدون حالت |
| StatefulSet | پادهایی با نام و دیسک ثابت | دیتابیس |
| DaemonSet | یک پاد روی هر نود | جمعآوری لاگ |
| Job و CronJob | کار یکباره یا زمانبندیشده | بکاپ شبانه |
| Service | IP و نام DNS ثابت جلوی پادها | web.default.svc.cluster.local |
| Ingress | مسیریابی HTTP بر اساس دامنه و مسیر | app.example.com |
| ConfigMap و Secret | تنظیمات و اطلاعات حساس، بیرون از ایمیج | رمز دیتابیس |
| Namespace | جداسازی منطقی منابع | dev و prod |
| PV و PVC | فضای ذخیرهٔ ماندگار و درخواست آن | ۱۰ گیگابایت دیسک |
پادها موقتیاند و هر پاد تازه IP تازه میگیرد؛ برای همین پاد را با Deployment میسازید و با Service به آن وصل میشوید. Service پادها را با برچسب (Label) پیدا میکند: هر پادی که برچسبهای انتخابگرش (Selector) را داشته باشد.
انواع Service
- ClusterIP (پیشفرض): فقط از داخل کلاستر در دسترس است؛ مثلاً برای اتصال اپ به دیتابیس.
- NodePort: پورتی ثابت روی همهٔ نودها، بهطور پیشفرض از بازهٔ 30000 تا 32767.
- LoadBalancer: انتشار با لود بالانسر بیرونی که خود کوبرنتیز ندارد؛ در ابرها لود بالانسر ارائهدهنده و در k3s، ServiceLB با پورتهای خود نودها این کار را میکند.
Ingress، Gateway API و پایان ingress-nginx
Ingress درخواستهای HTTP را بر اساس دامنه و مسیر به Serviceها میفرستد و بدون Ingress Controller کاری نمیکند؛ k3s کنترلر Traefik را خودش نصب میکند. در زمان نگارش این مطلب (آبان ۱۴۰۵) دو تغییر مهم است:
- API مربوط به Ingress منجمد شده است: حذف نمیشود، اما امکان تازهای هم نمیگیرد. جانشین پیشنهادی Gateway API است که از ۲۰۲۳ نسخهٔ پایدار v1 دارد و با منابعی مثل Gateway و HTTPRoute کار میکند. Gateway API افزونهای جداست؛ Traefik همراه k3s از آن پشتیبانی میکند، اما بهطور پیشفرض خاموش است.
- ingress-nginx بازنشسته شد: طبق اعلام رسمی کوبرنتیز، این کنترلر محبوب از مارس ۲۰۲۶ نسخهٔ جدید، رفع باگ و وصلهٔ امنیتی نمیگیرد و مخزنش فقطخواندنی است. نصبهای موجود کار میکنند، اما توصیهٔ رسمی مهاجرت به Gateway API یا کنترلری دیگر است. NGINX Ingress Controller شرکت F5 پروژهٔ جدایی است و همچنان بهروز میشود. بررسی استفاده:
kubectl get pods --all-namespaces --selector app.kubernetes.io/name=ingress-nginx
Secret فقط base64 است
base64 رمزنگاری نیست و با base64 -d برمیگردد. طبق مستندات کوبرنتیز، Secretها بهطور پیشفرض رمزنشده در etcd ذخیره میشوند و هر کس اجازهٔ ساخت پاد در یک Namespace را داشته باشد، عملاً Secretهای آن را هم میخواند. رمزنگاری در حالت ذخیره (Encryption at Rest) را روشن کنید (در k3s در گام ۱ بخش عملی)، دسترسیها را با RBAC (کنترل دسترسی بر اساس نقش) محدود کنید و Secret را در گیت نگذارید.
آیا به کوبرنتیز نیاز دارید؟
منصفانه بگوییم: بیشتر سایتها و اپهای کوچک و متوسط به آن نیاز ندارند. یک سایت وردپرسی، یک API با دیتابیسش یا یک ربات، با Docker Compose روی یک سرور مجازی سادهتر و کمهزینهتر اجرا میشود. کوبرنتیز سربار دارد: لایهٔ کنترل خودش منابع میخواهد، یادگیریاش زمان میبرد و کلاستر دستکم سالی یک بار ارتقا میخواهد.
| وضعیت شما | پیشنهاد |
|---|---|
| یک سایت یا اپ با دیتابیس | Docker Compose روی یک سرور |
| چند سرویس روی یک سرور | Compose، یا k3s تکنود برای یادگیری |
| چند سرویس و چند توسعهدهنده با استقرار مکرر | کوبرنتیز (k3s یا kubeadm) |
| تحمل خرابی یک سرور | دستکم ۳ نود سرور |
| نمیخواهید کلاستر نگه دارید | سرویس کانتینری مدیریتشده (PaaS) |
کلاستر تکنود دسترسپذیری بالا (HA) نمیدهد و حالت HA در k3s با etcd داخلی، تعداد فردی نود سرور میخواهد. برای شروع، دیتابیس اصلی را بیرون از کلاستر نگه دارید. کوبرنتیز مدیریتشدهٔ ابرهای خارجی هم معمولاً به دلیل تحریم برای کاربران ایرانی در دسترس نیست.
توزیعهای کوبرنتیز: kubeadm، k3s، MicroK8s و k0s
هر چهار توزیع زیر کوبرنتیز استاندارد اجرا میکنند و فرقشان در بستهبندی، پیشفرضها و منابع است. حداقل منابع از مستندات رسمی هر پروژه است و مصرف برنامهها جداست:
| توزیع | ویژگی | حداقل منابع | مناسب برای |
|---|---|---|---|
| kubeadm | ابزار رسمی پروژه؛ runtime و شبکه جدا نصب میشوند | ۲ گیگابایت رم هر نود؛ ۲ هسته برای لایهٔ کنترل | کلاستر استاندارد |
| k3s | یک فایل اجرایی زیر ۱۰۰ مگابایت با Traefik و ServiceLB | سرور ۲ هسته و ۲ گیگابایت؛ کارگر ۱ هسته و ۵۱۲ مگابایت | سرور مجازی و کلاستر کوچک |
| MicroK8s | بستهٔ snap شرکت Canonical | از ۵۴۰ مگابایت؛ پیشنهادی ۴ گیگابایت رم | اوبونتو و محیط توسعه |
| k0s | یک فایل اجرایی بدون وابستگی، از Mirantis | کنترلر ۱ گیگابایت؛ کارگر ۰٫۵ گیگابایت | کلاستر چندنودی با k0sctl |
برای تمرین روی لپتاپ kind و minikube کافیاند و برای سرور مجازی، k3s معمولاً کمدردسرتر است.
نصب k3s روی اوبونتو، گامبهگام
در این بخش یک کلاستر تکنود k3s روی Ubuntu 24.04 میسازید، برنامهای منتشر میکنید و در پایان یک نود کارگر اضافه میکنید. طبق جدول پشتیبانی k3s 1.36 در سایت SUSE، Ubuntu 22.04 و 26.04 هم آزموده شدهاند.
پیشنیازها و پورتها
- سروری با Ubuntu 24.04 و مجازیسازی کامل مثل KVM؛ روی OpenVZ و LXC ممکن است اجرا نشود. نود سرور طبق مستندات دستکم ۲ هسته و ۲ گیگابایت رم و ترجیحاً دیسک SSD میخواهد؛ برای تمرین، یک سرور لینوکس با ۴ گیگابایت رم راحتتر است.
- hostname یکتا برای هر نود و دسترسی SSH با کاربر دارای sudo (آموزش اتصال به سرور لینوکسی از طریق SSH).
- اگر Nginx یا Apache خود سرور روی پورتهای 80 و 443 کار میکند، Traefik همراه k3s این دو پورت را بیصدا از آن میگیرد (جدول رفع خطاها).
| پورت | جهت | کاربرد |
|---|---|---|
| 6443/tcp | کارگرها و kubectl به سرور | API کوبرنتیز |
| 8472/udp | بین نودها | Flannel با VXLAN (پیشفرض) |
| 51820/udp | بین نودها | Flannel با WireGuard |
| 10250/tcp | بین نودها | kubelet |
| 2379-2380/tcp | بین سرورها | etcd در حالت HA |
| 80 و 443/tcp | اینترنت به نودها | Traefik |
هشدار: طبق مستندات k3s، پورت 8472/udp نباید روی اینترنت باز باشد، چون شبکهٔ داخلی کلاستر را در دسترس همه میگذارد؛ 6443 را هم فقط برای IP نودها باز کنید. اگر سرور در ایران است، اول آزمون دسترسی بخش «کوبرنتیز روی سرورهای داخل ایران» را اجرا کنید.
گام ۱: تنظیمات و نصب k3s
k3s تنظیمات را از /etc/rancher/k3s/config.yaml میخواند و این فایل، برخلاف پارامترهای دستور نصب، در ارتقاها حفظ میشود. این تنظیم رمزنگاری Secretها را از اول روشن میکند:
sudo mkdir -p /etc/rancher/k3s
sudo tee /etc/rancher/k3s/config.yaml > /dev/null <<'EOF'
secrets-encryption: true
EOF
اگر نودهای بعدی از راه اینترنت عمومی وصل میشوند، خط flannel-backend: wireguard-native را هم اضافه کنید تا ترافیک بین نودها رمزنگاری شود. این گزینه فقط روی نود سرور تنظیم میشود، پس از اول تصمیم بگیرید؛ ماژول کرنل WireGuard هم باید روی همهٔ نودها باشد (آزمون: sudo modprobe wireguard بدون خطا). برای سرور ایران، فایل میرور Docker Hub را هم بسازید:
sudo mkdir -p /etc/rancher/k3s
sudo tee /etc/rancher/k3s/registries.yaml > /dev/null <<'EOF'
mirrors:
docker.io:
endpoint:
- "https://docker.arvancloud.ir"
EOF
حالا اسکریپت رسمی را اجرا کنید؛ بدون تعیین نسخه، آخرین نسخهٔ کانال stable نصب میشود که در زمان نگارش این مطلب (آبان ۱۴۰۵) v1.36.5+k3s1، یعنی کوبرنتیز 1.36، است:
curl -sfL https://get.k3s.io | sh -
اسکریپت /usr/local/bin/k3s، سرویس k3s، ابزارهای kubectl، crictl و ctr (اگر از قبل نباشند) و اسکریپت حذف را نصب میکند. یکی دو دقیقه بعد:
sudo systemctl is-active k3s
sudo kubectl get nodes
sudo kubectl get pods -A
sudo k3s secrets-encrypt status
خروجی اول active است و دومی شبیه این نمونه:
NAME STATUS ROLES AGE VERSION
k3s-1 Ready control-plane 90s v1.36.5+k3s1
پادهای coredns، local-path-provisioner، metrics-server، traefik و svclb-traefik باید Running و پادهای helm-install در وضعیت Completed باشند و دستور آخر Encryption Status: Enabled نشان دهد. اگر kubectl دیگری از قبل دارید، بنویسید sudo k3s kubectl.
گام ۲: kubectl بدون sudo
فایل دسترسی کلاستر (kubeconfig) در /etc/rancher/k3s/k3s.yaml با مجوز 600 است و دسترسی کامل مدیر میدهد. برای کاربر عادی نسخهٔ شخصی بسازید و KUBECONFIG را تنظیم کنید، چون kubectl همراه k3s بدون آن سراغ فایل /etc میرود:
mkdir -p ~/.kube
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
sudo chown $(id -u):$(id -g) ~/.kube/config
chmod 600 ~/.kube/config
echo 'export KUBECONFIG=$HOME/.kube/config' >> ~/.bashrc
source ~/.bashrc
kubectl get nodes
سراغ chmod 644 روی k3s.yaml نروید؛ دسترسی مدیر را به همهٔ کاربران سرور میدهد. k3s گواهیهای فایل اصلی را بهروز میکند، اما نسخهٔ کپی بهروز نمیشود؛ اگر بعدها خطای گواهی دیدید، کپی را تکرار کنید. با root این گام لازم نیست.
گام ۳: فایروال
مستندات k3s خاموش کردن UFW را پیشنهاد میکند و اگر روشن بماند، باز کردن 6443/tcp و مجاز کردن شبکهٔ پادها (10.42.0.0/16) و سرویسها (10.43.0.0/16) را. روشن ماندن UFW امنتر است، چون پورتهای خود سرور مثل 6443، 10250 و 8472 را از اینترنت میبندد. در این راهنما 6443 باز نمیشود و kubectl از بیرون با تونل SSH وصل میشود:
sudo ufw allow OpenSSH
sudo ufw allow from 10.42.0.0/16 to any
sudo ufw allow from 10.43.0.0/16 to any
sudo ufw enable
sudo ufw status
پورتهای 80 و 443 قانون UFW لازم ندارند، چون ServiceLB ترافیک آنها را پیش از قانونهای ورودی UFW با NAT به Traefik میرساند (بخش امنیت). اگر پورت SSH را عوض کردهاید، پیش از enable آن را باز کنید. مبانی UFW در فعالسازی فایروال در لینوکس آمده است.
گام ۴: Deployment و Service
برنامهٔ نمونه traefik/whoami است که نام پاد پاسخدهنده را برمیگرداند:
cat > app.yaml <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
labels:
app: web
spec:
replicas: 2
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: whoami
image: traefik/whoami:v1.11.0
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: /health
port: 80
resources:
requests:
cpu: 50m
memory: 32Mi
limits:
memory: 64Mi
---
apiVersion: v1
kind: Service
metadata:
name: web
spec:
selector:
app: web
ports:
- port: 80
targetPort: 80
EOF
kubectl apply -f app.yaml
kubectl get pods -o wide
kubectl get svc web
selector.matchLabelsباید باlabelsقالب پاد یکی باشد وselectorسرویس هم همین برچسب را پیدا میکند؛ ناهمخوانیشان خطای رایجی است.readinessProbeپاد را تا پاسخ 200 از/healthدر توزیع بار نمیگذارد.requestsسهم رزروشده برای زمانبندی است وlimitsسقف مصرف؛ پادی که از سقف رم بگذرد OOMKilled میشود.- تگ نسخه را صریح بنویسید، نه
latest.
دو پاد web باید 1/1 و Running باشند. Service از نوع ClusterIP فقط از داخل کلاستر و خود نودها در دسترس است؛ روی سرور امتحان کنید:
CIP=$(kubectl get svc web -o jsonpath='{.spec.clusterIP}')
for i in 1 2 3 4 5 6; do curl -s "http://$CIP/" | grep Hostname; done
معمولاً نام هر دو پاد را میبینید، چون Service هر درخواست را تصادفی به یکی از پادهای آماده میدهد.
گام ۵: انتشار با Ingress و Traefik
cat > ingress.yaml <<'EOF'
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web
spec:
ingressClassName: traefik
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 80
EOF
kubectl apply -f ingress.yaml
kubectl get ingress web
بهجای app.example.com دامنهٔ خودتان را بنویسید؛ جلوی ADDRESS باید IP سرور بیاید. پیش از تنظیم DNS، از کامپیوتر خودتان امتحان کنید (در PowerShell بنویسید curl.exe):
curl -H "Host: app.example.com" http://SERVER_IP/
پاسخ باید Hostname یکی از پادها را نشان دهد. پاسخ 404 page not found از خود Traefik است و یعنی هیچ Ingressی با این Host جور نشد. بعد از تنظیم رکورد A، آدرس در مرورگر باز میشود. برای HTTPS معتبر معمولاً cert-manager با Let’s Encrypt نصب میشود (مثلاً با Helm، مدیر بستهٔ کوبرنتیز)؛ تا آن موقع Traefik روی 443 گواهی پیشفرضی را نشان میدهد که خودش ساخته و مرورگر به آن اعتماد نمیکند.
گام ۶: مقیاسدهی، بهروزرسانی و بازگشت
kubectl scale deployment/web --replicas=4
kubectl set image deployment/web whoami=traefik/whoami:v1.12.0
kubectl rollout status deployment/web
kubectl get deployment web -o wide
kubectl rollout history deployment/web
kubectl rollout undo deployment/web
set image بهروزرسانی تدریجی را شروع میکند. پیشفرض Deployment حداکثر ۲۵ درصد پاد اضافه و ۲۵ درصد پاد ناموجود است، پس با readinessProbe سرویس معمولاً قطع نمیشود. ستون IMAGES نسخهٔ فعلی را نشان میدهد و undo به v1.11.0 برمیگردد؛ کوبرنتیز بهطور پیشفرض ۱۰ نسخهٔ قبلی را نگه میدارد.
نکته:
scaleوset imageفقط کلاستر را عوض میکنند وkubectl apply -f app.yamlبعدی، تعداد و نسخه را به مقدار فایل برمیگرداند. در کار واقعی فایل را تغییر دهید، در گیت نگه دارید وapplyکنید.
گام ۷: افزودن نود کارگر
سرور دوم را با hostname متفاوت در همان لوکیشن آماده کنید (sudo hostnamectl set-hostname k3s-2). روی سرور اول توکن را بخوانید و نود جدید را در فایروال مجاز کنید:
sudo cat /var/lib/rancher/k3s/server/node-token
sudo ufw allow from WORKER_IP
روی نود جدید (برای سرور ایران، اول registries.yaml گام ۱ را بسازید):
sudo ufw allow OpenSSH
sudo ufw allow from SERVER_IP
sudo ufw allow from 10.42.0.0/16 to any
sudo ufw allow from 10.43.0.0/16 to any
sudo ufw enable
curl -sfL https://get.k3s.io | K3S_URL=https://SERVER_IP:6443 K3S_TOKEN=PASTE_NODE_TOKEN sh -
با K3S_URL، اسکریپت سرویس k3s-agent را نصب میکند. kubectl get nodes روی سرور اول نود جدید را با ROLES برابر <none> و وضعیت Ready نشان میدهد.
هشدار: طبق مستندات k3s، هر کس توکن سرور را داشته باشد عملاً مدیر کلاستر است؛ آن را در اسکریپت یا گیت نگذارید. ترافیک بین نودها هم بدون
wireguard-nativeگام ۱ رمزنگاری نمیشود.
حذف k3s
اسکریپت حذف، k3s، پادها، پایگاهدادهٔ کلاستر و دادههای local-path را پاک میکند:
# on a server node
sudo /usr/local/bin/k3s-uninstall.sh
# on a worker (agent) node
sudo /usr/local/bin/k3s-agent-uninstall.sh
دستورات پرکاربرد kubectl
| دستور | کاربرد |
|---|---|
kubectl get pods -A |
پادهای همهٔ Namespaceها |
kubectl describe pod NAME |
جزئیات و رویدادها؛ اولین قدم عیبیابی |
kubectl logs NAME --previous |
لاگ اجرای قبلی کانتینر ریاستارتشده |
kubectl exec -it NAME -- sh |
شل داخل کانتینر (اگر ایمیج شل دارد) |
kubectl get events --sort-by=.metadata.creationTimestamp |
رویدادهای اخیر به ترتیب زمان |
kubectl port-forward svc/web 8080:80 |
دسترسی موقت محلی به سرویس |
kubectl top nodes |
مصرف CPU و رم نودها |
kubectl delete -f app.yaml |
حذف منابع تعریفشده در فایل |
کوبرنتیز روی سرورهای داخل ایران
Docker Hub آیپیهای ایران را به استناد مقررات صادرات آمریکا مسدود میکند و این در کوبرنتیز دو اثر دارد: ایمیج بدون نام رجیستری از docker.io گرفته میشود و ایمیجهای سیستمی خود k3s، از pause و coredns تا traefik، هم در docker.io/rancher هستند (فهرستشان در k3s-images.txt هر نسخه). پس بدون آمادگی، حتی اگر نصب تمام شود، پادهای سیستمی در ContainerCreating یا ImagePullBackOff میمانند.
ایمیجهای رسمی کوبرنتیز (مثلاً برای kubeadm) روی registry.k8s.io هستند که ترافیک را به Google Cloud و AWS میفرستد و خیلی از ابزارها از ghcr.io و quay.io میآیند؛ دسترسی سرورهای ایران به اینها و به GitHub همیشه برقرار نیست. پیش از نصب بسنجید:
for u in https://get.k3s.io https://update.k3s.io/v1-release/channels \
https://github.com/k3s-io/k3s/releases https://registry-1.docker.io/v2/ \
https://docker.arvancloud.ir/v2/ https://registry.k8s.io/v2/ \
https://ghcr.io/v2/ https://quay.io/v2/; do
echo "$(curl -s -o /dev/null -m 10 -w '%{http_code}' "$u") $u"
done
کد 200 یا 401 یعنی در دسترس (401 برای رجیستریها عادی است)، 403 یعنی مسدود و 000 یعنی تا ۱۰ ثانیه اتصالی برقرار نشد. اسکریپت نصب از update.k3s.io نسخه را میپرسد و فایل را از GitHub میگیرد.
میرور Docker Hub با registries.yaml
اگر سه نشانی اول باز است و Docker Hub نه، فایل registries.yaml گام ۱ کافی است: k3s آن را هنگام راهاندازی میخواند و containerd درخواستهای docker.io را اول به میرور میفرستد. چند شرکت ایرانی میرور عمومی Docker Hub دارند. نمونهٔ شناختهشدهاش میرور آروانکلاد با آدرس https://docker.arvancloud.ir است که در زمان نگارش این مطلب (آبان ۱۴۰۵) به درخواست ایمیجهای rancher و traefik/whoami پاسخ میداد؛ وضعیت امروزش را با آزمون بالا بسنجید.
- فایل را روی همهٔ نودها بسازید و اگر k3s نصب است، سرویس
k3sیاk3s-agentرا ریاستارت کنید. آزمون:sudo k3s crictl pull traefik/whoami:v1.11.0. - containerd در آخر خود
docker.ioرا هم امتحان میکند، پس خطای kubectl ممکن است 403 خود Docker Hub را نشان دهد حتی وقتی مشکل از میرور است؛ علت واقعی در/var/lib/rancher/k3s/agent/containerd/containerd.logنودی است که پاد رویش است. - این تنظیم فقط
docker.ioرا پوشش میدهد. میرور واسطهٔ شخص ثالث است؛ فقط ایمیج رسمی با تگ مشخص بگیرید.
نصب آفلاین k3s (Air-gap)
اگر get.k3s.io یا GitHub باز نمیشود، فایلها را روی سیستمی با دسترسی، مثلاً سرور لینوکسی خارج از ایران، بگیرید و منتقل کنید. با بستهٔ ایمیجهای سیستمی، k3s برای اجزای خودش به Docker Hub نیاز ندارد. دستورها برای پردازندهٔ amd64 است. مقدار V را با نسخهٔ کانال stable در https://update.k3s.io/v1-release/channels یکی کنید (بهجای + بنویسید %2B) و فایلهای گام ۱ را پیش از اجرای install.sh بسازید:
# On a machine with internet access
V=v1.36.5%2Bk3s1
curl -LO https://github.com/k3s-io/k3s/releases/download/$V/k3s
curl -LO https://github.com/k3s-io/k3s/releases/download/$V/k3s-airgap-images-amd64.tar.zst
curl -LO https://github.com/k3s-io/k3s/releases/download/$V/sha256sum-amd64.txt
curl -Lo install.sh https://get.k3s.io
scp k3s k3s-airgap-images-amd64.tar.zst sha256sum-amd64.txt install.sh user@SERVER_IP:~/
# On the server
cd ~
grep -E ' (k3s|k3s-airgap-images-amd64.tar.zst)$' sha256sum-amd64.txt | sha256sum -c -
sudo mkdir -p /var/lib/rancher/k3s/agent/images/
sudo cp k3s-airgap-images-amd64.tar.zst /var/lib/rancher/k3s/agent/images/
sudo install -m 755 k3s /usr/local/bin/k3s
chmod +x install.sh
INSTALL_K3S_SKIP_DOWNLOAD=true ./install.sh
چکسام باید برای هر دو فایل OK بدهد. برای نود کارگر همین فایلها را منتقل و دستور آخر را با K3S_URL و K3S_TOKEN اجرا کنید. ارتقا در این روش دستی است: فایلهای نسخهٔ جدید را جایگزین و اسکریپت را دوباره اجرا کنید. ایمیج برنامهها را هم میتوانید جای دیگر با docker save ذخیره و روی نود با sudo k3s ctr images import وارد کنید.
رجیستری خصوصی یا نود خارج از ایران
برای تیمها راه پایدارتر رجیستری خصوصی است که ایمیجهای لازم را نگه میدارد و در registries.yaml بهعنوان میرور docker.io، ghcr.io یا registry.k8s.io معرفی میشود. اگر کاربران بیشتر خارج از ایراناند یا کارتان مدام به GitHub وابسته است، نودها را روی سرور مجازی خارجی بگذارید.
رفع خطاهای رایج کوبرنتیز
اول kubectl describe pod NAME را بزنید و بخش Events انتهای خروجی را بخوانید.
| نشانه | علت محتمل | راهحل |
|---|---|---|
| ImagePullBackOff با 403 | رجیستری IP ایران را نمیپذیرد | میرور یا نصب آفلاین |
| ImagePullBackOff با not found | نام یا تگ ایمیج اشتباه | بررسی تگ در رجیستری |
| ImagePullBackOff با 429 | سقف دریافت Docker Hub | ورود به حساب یا میرور |
| CrashLoopBackOff | برنامه پس از شروع خارج میشود | kubectl logs NAME --previous |
| OOMKilled | مصرف رم بیشتر از limits |
افزایش limits یا رفع نشت حافظه |
| Pending با Insufficient cpu یا memory | منابع آزاد کمتر از requests | کم کردن requests یا افزودن منابع |
سایت Nginx یا Apache خود سرور بعد از نصب k3s، 404 page not found میدهد |
ServiceLB پورتهای 80 و 443 را با NAT به Traefik داده است | خط disable: traefik در config.yaml و ریاستارت k3s، یا انتقال سایت به کلاستر |
| نود NotReady | k3s-agent متوقف یا فایروال بین نودها |
sudo journalctl -u k3s-agent و جدول پورتها |
404 page not found |
Host درخواست با Ingress جور نیست | بررسی host و ingressClassName |
permission denied روی k3s.yaml |
KUBECONFIG تنظیم نشده |
گام ۲ |
کوبرنتیز دریافت ایمیج و ریاستارت کانتینر خراب را با فاصلهٔ رو به افزایش، تا سقف ۵ دقیقه، تکرار میکند؛ بعد از رفع علت، صبر کنید یا پاد را حذف کنید تا پاد تازه ساخته شود.
امنیت و نگهداری کلاستر
- API را عمومی نکنید. برای kubectl روی کامپیوتر خودتان، kubeconfig گام ۲ را کپی کنید (با root، خود
/etc/rancher/k3s/k3s.yamlرا) و تونل SSH بزنید؛ آدرس داخل فایلhttps://127.0.0.1:6443است و بدون تغییر کار میکند. نسخهٔ kubectl شما حداکثر یک نسخهٔ فرعی با سرور فاصله داشته باشد:mkdir -p ~/.kube scp user@SERVER_IP:.kube/config ~/.kube/k3s-server.yaml chmod 600 ~/.kube/k3s-server.yaml ssh -N -L 6443:127.0.0.1:6443 user@SERVER_IP # in a second terminal export KUBECONFIG=~/.kube/k3s-server.yaml kubectl get nodes - کمترین دسترسی با RBAC.
k3s.yamlرا به CI، برنامهها یا همتیمیها ندهید؛ برای هر کدام یک ServiceAccount با Role محدود به Namespace خودش بسازید. - NodePort برای سرویس داخلی نه. مثل پورتهای منتشرشدهٔ داکر، ترافیک NodePort و LoadBalancer با قانونهای NAT پیش از قانونهای ورودی UFW هدایت میشود و
ufw denyمعمولاً جلویش را نمیگیرد. سرویس داخلی را ClusterIP نگه دارید و ارتباط پادها را با NetworkPolicy، که k3s پشتیبانی میکند، محدود کنید. - بکاپ. در k3s تکسرور، پوشهٔ
/var/lib/rancher/k3s/server/db/را همراه فایل/var/lib/rancher/k3s/server/tokenنگه دارید؛ بدون توکن، بکاپ بازگردانی نمیشود. PVها و دیتابیسها بکاپ جدا میخواهند؛ دادههای StorageClass پیشفرض k3s (local-path) روی دیسک همان نود، زیر/var/lib/rancher/k3s/storage، ذخیره میشود و پاد را به همان نود میبندد. - ارتقا. اسکریپت نصب را با همان متغیرهای نصب اول دوباره اجرا کنید؛ روی کارگرها بدون
K3S_URLوK3S_TOKEN، اسکریپت بهجای کارگر یک سرور تازه نصب میکند. اول سرورها یکییکی و بعد کارگرها را ارتقا دهید و از روی نسخهٔ فرعی نپرید (از 1.35 مستقیم به 1.37 نروید)؛ با کانال هر نسخه گامبهگام بروید:curl -sfL https://get.k3s.io | INSTALL_K3S_CHANNEL=v1.37 sh -
چرخهٔ پشتیبانی نسخهها
کوبرنتیز تقریباً سالی ۳ نسخهٔ فرعی میدهد و هر نسخه حدود ۱۴ ماه وصله میگیرد (۱۲ ماه عادی و ۲ ماه نگهداری). در زمان نگارش این مطلب (آبان ۱۴۰۵)، طبق صفحهٔ انتشارهای کوبرنتیز این سه نسخه پشتیبانی میشوند و پشتیبانی 1.34 در ۵ آبان ۱۴۰۵ تمام شد:
| نسخه | پایان پشتیبانی |
|---|---|
| 1.37 | ۶ آبان ۱۴۰۶ (۲۸ اکتبر ۲۰۲۷) |
| 1.36 | ۷ تیر ۱۴۰۶ (۲۸ ژوئن ۲۰۲۷) |
| 1.35 | ۹ اسفند ۱۴۰۵ (۲۸ فوریهٔ ۲۰۲۷) |
سرور مناسب برای کوبرنتیز
برای یادگیری و کلاستر کوچک k3s، سرور مجازی لینوکس با ۲ هسته و ۲ تا ۴ گیگابایت رم کافی است. هاکان سرور، سرور مجازی را در ۵۲ لوکیشن ارائه میکند؛ در صفحهٔ خرید سرور مجازی لوکیشن نزدیک به کاربرانتان را انتخاب کنید و همهٔ نودهای یک کلاستر را در یک لوکیشن بگیرید.
با یک نود شروع کنید؛ ارتقای منابع سرویس با ثبت تیکت انجام میشود. IP سرویس تا زمانی که سرویس تمدید شود ثابت میماند، پس K3S_URL و قانونهای فایروال دست نمیخورند. برای کلاستر بزرگتر خرید سرور اختصاصی را ببینید؛ سرور اختصاصی هاکان با لینوکس، ویندوز یا هر پلتفرم مجازیسازی دلخواه تحویل داده میشود و میتوانید چند ماشین مجازی روی آن را نود کلاستر کنید؛ فقط خرابی همان سختافزار همهٔ این نودها را با هم از کار میاندازد.
پرسشهای متداول
کوبرنتیز به زبان ساده چیست؟
سیستمی که کانتینرهای شما را روی چند سرور اجرا و سالم نگه میدارد و جای اجرا، ریاستارت، توزیع بار و بهروزرسانی را خودش مدیریت میکند.
تفاوت k3s و k8s چیست؟
k3s خودِ کوبرنتیز است در قالب توزیعی سبک: اجزا در یک فایل اجرایی جمع شدهاند و در حالت تکسرور بهجای etcd از SQLite استفاده میشود. فایلهای YAML و دستورهای kubectl هماناند.
آیا کوبرنتیز رایگان است؟
بله؛ کوبرنتیز و k3s متنباز و با مجوز Apache 2.0 هستند. هزینهٔ واقعی سرورها و زمان نگهداری کلاستر است.
یادگیری کوبرنتیز را از کجا شروع کنم؟
اول داکر و ساخت ایمیج را یاد بگیرید، بعد Pod، Deployment، Service و Ingress را با kind یا minikube روی لپتاپ یا k3s روی یک سرور مجازی تمرین کنید.
آیا کوبرنتیز جای داکر را میگیرد؟
نه. داکر برای ساخت ایمیج و اجرای محلی رایج میماند و کوبرنتیز همان ایمیجها را روی کلاستر اجرا میکند؛ فقط روی نودها بهجای Docker Engine، containerd کانتینرها را اجرا میکند.
آیا کوبرنتیز روی سرور ایران نصب میشود؟
بله، اما چون Docker Hub آیپیهای ایران را مسدود میکند، پیش از نصب میرور را در registries.yaml تنظیم کنید و اگر GitHub هم باز نیست، k3s را آفلاین نصب کنید.
جمعبندی
کوبرنتیز اجرای کانتینرها روی چند سرور را خودکار میکند، اما سربار دارد؛ برای یک سایت یا اپ کوچک Docker Compose کافی است و کوبرنتیز وقتی میارزد که چند سرویس، چند سرور و چند نفر درگیر باشند. از روز اول Secretها، پورت 6443، شبکهٔ بین نودها و ارتقای منظم را جدی بگیرید.
قدم بعدی: k3s را روی یک سرور آزمایشی نصب کنید، برنامهٔ نمونه را منتشر، بهروز و بازگردانی کنید و بعد یکی از سرویسهای خودتان را با YAML تعریف کنید. جزئیات در مستندات مفاهیم کوبرنتیز و مستندات k3s آمده است.


