SSD Nodes Learn 🎉 VPS $5.50/ماہ سے
تعلیمی Matt Connorتحریر: Matt Connor

VPS پر single-node k3s کب فائدہ مند ہے؟

k3s ایک VPS پر حقیقی Kubernetes API دیتا ہے، مگر RAM کم کرتا ہے۔ install کے دوران port 80 کیوں ٹکراتا ہے، اور کب Docker Compose بہتر انتخاب ہے؟

k3s کیا ہے، اور اس کا ایک node آپ کو کیا فراہم کرتا ہے

k3s ایک مکمل Kubernetes distribution ہے جسے ایک binary میں package کیا گیا ہے۔ اسے ایک VPS پر چلانے سے آپ کو تین مشینوں پر مشتمل control plane کے بغیر حقیقی Kubernetes API ملتی ہے۔ یہ ایک certified Kubernetes distribution ہے، اس لیے یہاں apply ہونے والا manifest بعد میں managed cluster پر بھی apply ہو سکتا ہے۔ Installation ایک command سے تقریباً ایک منٹ میں مکمل ہو جاتی ہے۔ اس کے بدلے آپ کو اتنی memory کم ملتی ہے جو آپ کی applications کے لیے دستیاب نہیں رہتی، اور failure modes کا ایک ایسا مجموعہ ملتا ہے جو Docker Compose میں کبھی پیش نہیں آتا۔

SUSE نے k3s کو edge sites اور چھوٹی installations کے لیے بنایا ہے، اور upstream Kubernetes سے اس کا ہر فرق اسے کم resource استعمال کرنے والا بنانے کے لیے ہے۔ Default datastore etcd کے بجائے kine نامی shim کے پیچھے sqlite ہے، اس لیے برقرار رکھنے کے لیے etcd quorum موجود نہیں ہوتا۔ containerd الگ سے install ہونے کے بجائے binary میں embedded ہوتا ہے۔ یہی binary cluster DNS کے لیے CoreDNS، ingress controller کے طور پر Traefik، اور ServiceLB بھی فراہم کرتی ہے، جسے klipper-lb بھی کہا جاتا ہے، تاکہ کسی cloud provider کے بغیر LoadBalancer services کام کر سکیں۔ اس میں persistent volumes کے لیے local-path provisioner، metrics-server، اور pod networking کے لیے flannel بھی شامل ہیں۔ یہ سب default طور پر start ہوتے ہیں۔ اسی لیے نیچے بیان کردہ port collision اس VPS پر سب سے عام ابتدائی مسئلہ ہے جو پہلے سے کوئی کام کر رہا ہو۔

ایک single k3s node کب قابلِ غور ہے

یہ اصول استعمال کریں۔ اگر آپ کو Kubernetes API درکار ہے تو k3s چلائیں: مثلاً آپ اپنے زیرِ انتظام machine پر Kubernetes سیکھ رہے ہیں، یا مطلوبہ software صرف Helm chart شائع کرتا ہے۔ Manifest کی portability بھی اہم ہے، کیونکہ یہاں لکھا ہوا Deployment managed cluster میں بغیر تبدیلی کے منتقل ہو سکتا ہے۔ اگر آپ کو applications درکار ہیں تو Docker Compose چلائیں۔ Compose بہت کم پیچیدگی کے ساتھ وہی containers شروع کرتا ہے، اور VPS پر موجود ایک Compose file ایک سال بعد manifests کی directory کے مقابلے میں زیادہ آسانی سے پڑھی جا سکتی ہے۔

واضح رہے کہ ایک node سے کیا حاصل نہیں ہوتا۔

  • High availability نہیں ملتی۔ VPS reboot ہونے پر ہر workload رک جاتا ہے۔ Kubernetes pod کو دوسرے node پر دوبارہ schedule کرتا ہے، لیکن یہاں دوسرا node موجود نہیں ہوتا۔
  • ایسا rolling update نہیں ملتا جو service کو جاری رکھے، الا یہ کہ application ایک ہی machine پر ایک volume استعمال کرنے والے دو replicas کو برداشت کر سکے۔
  • Storage اسی machine تک محدود رہتی ہے، جیسا کہ ذیل کے local-path section میں بیان کیا گیا ہے۔
  • Control plane تقریباً 1 gigabyte RAM استعمال کرتا ہے، چاہے آپ کچھ deploy کریں یا نہ کریں۔

ان میں سے کوئی بات k3s کو برا انتخاب نہیں بناتی۔ البتہ یہ اسے اس عام وجہ سے برا انتخاب بناتی ہیں جو لوگ عموماً بیان کرتے ہیں، یعنی reliability۔ اگر آپ کی اصل ضرورت متعدد machines ہے تاکہ آپ حقیقی multi-node cluster بنا سکیں، تو یہ فیصلہ پہلے کریں: اپنے hardware پر Proxmox یا rented VPS سے یہ طے ہوتا ہے کہ nodes کہاں سے آئیں گے، اس سے پہلے کہ k3s یہ طے کرے کہ ان پر کیا چلے گا۔

تعیناتی سے پہلے k3s کی RAM اور CPU لاگت

k3s پروجیکٹ اندازوں کے بجائے پیمائش شدہ اعداد و شمار شائع کرتا ہے۔ انہیں غور سے پڑھیں، کیونکہ لوگ جس عدد کا حوالہ دیتے ہیں وہ idle k3s کا عدد نہیں ہے۔

ChartPublished k3s resource use, 95th percentile, Intel 8375C, k3s v1.26.5
The data behind this chart
[
  {
    "label": "Server, sqlite datastore",
    "ram_mb": "1,596",
    "cpu_percent_of_one_core": 6
  },
  {
    "label": "Server, embedded etcd",
    "ram_mb": "1,606",
    "cpu_percent_of_one_core": 6
  },
  {
    "label": "Agent node only",
    "ram_mb": "275",
    "cpu_percent_of_one_core": 3
  }
]

اس test میں ایک server node نے 95th percentile پر 1,596 MB RAM اور ایک core کی تقریباً 6 فیصد CPU استعمال کی۔ یہ شائع شدہ اعداد و شمار ہیں، اس guide کی پیمائشیں نہیں۔ test میں k3s v1.26.5 چلایا گیا، تمام packaged components enabled تھے، اور Prometheus اور Grafana monitoring stack بھی شامل تھا۔ اس لیے یہ عدد خالی cluster کے بجائے حقیقی workload کو ظاہر کرتا ہے۔ sqlite کی جگہ embedded etcd استعمال کرنے سے یہ مقدار 1,606 MB ہو گئی۔ Agent node، جو control plane کے بغیر kubelet اور containerd چلاتا ہے، نے 275 MB استعمال کیے۔ Server کے لیے documented minimum 2 cores اور 2 GB RAM ہے۔ یہ minimum آپ کے workloads سے پہلے k3s اور اس کے packaged components کے لیے ہے۔

عملی مطلب یہ ہے: 2 GB VPS پر control plane اور اس کے bundled add-ons بہت کم وسائل چھوڑتے ہیں، اور دباؤ کے دوران سب سے پہلے kubelet pods کو evict کرتا ہے۔ ایک node پر چند چھوٹی services کے لیے 4 GB ایک مناسب کم از کم مقدار ہے۔ کسی بھی published figure، بشمول اس figure، پر بھروسا کرنے کے بجائے اپنے box کی پیمائش کریں۔

free -h
sudo k3s kubectl top node
sudo k3s kubectl get pods -A

install سے پہلے اور پھر اس وقت free -h چلائیں جب kube-system میں موجود ہر pod کی حالت Running ہو جائے۔ دونوں نتائج کا فرق آپ کے hardware پر control plane کی لاگت ظاہر کرتا ہے۔ install کے بعد پہلے ایک یا دو منٹ میں k3s kubectl top node، error: Metrics API not available واپس کرتا ہے، کیونکہ metrics-server نے ابھی کچھ scrape نہیں کیا ہوتا۔ یہ خرابی نہیں ہے۔ اگر آپ اسی box کو اس کام اور بیک وقت دوسرے کاموں کے لیے استعمال کر رہے ہیں تو VPS کے لیے RAM اور CPU کا سائز متعین کرنا والی arithmetic یہاں بھی بغیر کسی تبدیلی کے لاگو ہوتی ہے۔

کسی release سے k3s انسٹال کریں، latest سے نہیں

فوری آغاز والی وہ command جسے ہر شخص copy کرتا ہے، اسے چلانے کے دن stable channel جس release کی طرف اشارہ کر رہا ہو، وہی انسٹال کرتی ہے۔ جس machine کو مستقل رکھنا ہو، اس کے لیے version کو pin کریں۔ k3s ہر Kubernetes minor version کے لیے ایک channel جاری کرتا ہے، اس لیے INSTALL_K3S_CHANNEL=v1.36 صرف v1.36 کے اندر patch releases کو follow کرتا ہے اور خود سے minor version تبدیل نہیں کرتا۔ August 2026 تک stable channel v1.36.3+k3s1 کی طرف اشارہ کرتا ہے۔

پہلے config file لکھیں، پھر انسٹال کریں۔ k3s شروع ہوتے وقت /etc/rancher/k3s/config.yaml پڑھتا ہے، اس لیے اس میں موجود ہر setting پہلی boot اور بعد کی تمام boots پر بھی لاگو ہوتی ہے۔

sudo mkdir -p /etc/rancher/k3s
sudo tee /etc/rancher/k3s/config.yaml >/dev/null <<'EOF'
tls-san:
  - k3s.example.com
EOF
curl -sfL https://get.k3s.io | INSTALL_K3S_CHANNEL=v1.36 sh -

کسی channel کے بجائے ایک مخصوص release کو pin کرنے کے لیے INSTALL_K3S_VERSION=v1.36.3+k3s1 استعمال کریں۔ plus sign tag کا حصہ ہے۔ اس کے بعد تصدیق کریں کہ یہ کامیابی سے شروع ہو گیا ہے۔

k3s --version
sudo systemctl status k3s
sudo k3s kubectl get node
sudo k3s kubectl get pods -A

kubectl get node کو تقریباً تیس seconds کے اندر STATUS Ready کے ساتھ ایک node دکھانا چاہیے، اور kube-system میں موجود ہر pod کو Running یا Completed حالت تک پہنچ جانا چاہیے۔ اگر کوئی node NotReady پر اٹکا رہے تو عموماً اس کا مطلب ہوتا ہے کہ container runtime شروع نہیں ہوا۔ اس لیے sudo journalctl -u k3s -n 100 --no-pager پڑھیں۔ غیر معمولی VPS image پر، کسی اور debugging سے پہلے sudo k3s check-config چلائیں۔ یہ missing kernel features کی اطلاع دیتا ہے، جو logs پڑھنے کے مقابلے میں زیادہ تیز جواب فراہم کرتا ہے۔

پورٹ 80 پہلے سے زیر استعمال کیوں ہے، اور اسے درست کرنے کے لیے کیا چھوڑنا ہوگا

یہ وہ خرابی ہے جو پہلے سے کسی سروس کی میزبانی کرنے والے VPS پر اکثر سامنے آتی ہے۔ انسٹالیشن کامیاب ہو جاتی ہے۔ اس کے بعد Traefik کو کبھی address نہیں ملتا، جبکہ پہلے سے چلنے والی site کام کرتی رہتی ہے۔ اس لیے ingress تک رسائی کی کوشش کرنے تک کچھ بھی خراب دکھائی نہیں دیتا۔

طریقۂ کار یہ ہے: شامل شدہ Traefik chart، ports 80 اور 443 پر LoadBalancer قسم کی Service بناتا ہے۔ ServiceLB اس درخواست کے جواب میں چھوٹے pods کا ایک DaemonSet بناتا ہے۔ ان pods کے ناموں میں svclb- prefix ہوتا ہے، اور یہ ہر node پر ان port numbers کو hostPort کے طور پر claim کرتے ہیں۔ hostPort، container port کو براہ راست node کے اپنے network namespace پر شائع کرتا ہے، بالکل اسی طرح جیسے docker run -p 80:80 کرتا ہے۔ اگر nginx، Caddy، Apache یا کوئی اور container پہلے ہی port 80 استعمال کر رہا ہو تو kernel اسے دوسری بار فراہم نہیں کرے گا۔ اس لیے scheduler کے پاس pod رکھنے کے لیے کوئی جگہ نہیں رہتی۔

sudo k3s kubectl -n kube-system get pods
sudo k3s kubectl -n kube-system get svc traefik
sudo ss -lntp '( sport = :80 or sport = :443 )'

آپ svclb pod کو Pending حالت میں دیکھیں گے، جبکہ service کا external address خالی ہوگا:

svclb-traefik-8f2c1a-r6k9x   0/2   Pending   0   3m
traefik   LoadBalancer   10.43.62.11   <pending>   80:31480/TCP,443:30219/TCP

kubectl -n kube-system describe pod svclb-traefik-... چلانے سے وجہ براہ راست معلوم ہو جاتی ہے:

0/1 nodes are available: 1 node(s) didn't have free ports for the requested pod ports.

ss -lntp بتاتا ہے کہ port کس process کے پاس ہے۔ اس مسئلے کو حل کرنے کے ایک سے زیادہ طریقے ہیں، اور ہر طریقے میں آپ کو کچھ چھوڑنا پڑتا ہے۔

Ports k3s کے حوالے کر دیں۔ موجودہ web server کو stop اور disable کریں، پھر Traefik کو 80 اور 443 استعمال کرنے دیں۔ جب VPS صرف k3s box بننے والا ہو اور اس پر کوئی اور سروس نہ چلنی ہو تو یہی درست انتخاب ہے۔ آپ جو کچھ پہلے serve کر رہے تھے، اسے Ingress کے پیچھے منتقل کریں۔

ServiceLB کو disable کریں اور موجودہ proxy برقرار رکھیں۔ --disable=servicelb کے ساتھ انسٹال کریں۔ LoadBalancer قسم کی Service پھر بھی ایک NodePort مختص کرتی ہے۔ اس لیے Traefik کسی high port، مثلاً 31480، پر reachable رہتا ہے، اور آپ کا nginx یا Caddy 127.0.0.1:31480 کو proxy کرتا ہے۔ اس انتخاب میں آپ external address سے محروم ہو جاتے ہیں: service ہمیشہ <pending> رپورٹ کرتی ہے۔ یہ خرابی نہیں بلکہ آپ کا کیا ہوا انتخاب ہے، اگرچہ ظاہری طور پر یہ خرابی معلوم ہو سکتی ہے۔

Traefik کو disable کریں اور اپنے proxy سے route کریں۔ --disable=traefik کے ساتھ انسٹال کریں۔ اس کے بعد آپ کے پاس ingress controller نہیں ہوگا، اس لیے Ingress objects بالکل کچھ نہیں کریں گے۔ وہ API میں موجود رہیں گے، مگر ان کی نگرانی کرنے والا کوئی controller نہیں ہوگا۔ جب آپ host proxy سے NodePorts تک route کرتے ہوں تو یہ طریقہ مناسب ہے۔ اگر آپ پہلے سے جانتے ہیں کہ HTTP کو کیسے handle کرنا ہے تو یہی واضح انتخاب ہے۔ اگر آپ ابھی طے نہیں کر سکے کہ سامنے کیا ہونا چاہیے تو کسی component کو disable کرنے سے پہلے nginx، Caddy اور Traefik میں reverse proxy کے طور پر انتخاب طے کر لیں۔

دونوں flags installer کے ساتھ یا config file میں شامل کیے جا سکتے ہیں:

tls-san:
  - k3s.example.com
disable:
  - traefik
  - servicelb

انسٹالیشن کے بعد اس file میں ترمیم کر کے sudo systemctl restart k3s چلانا بھی کام کرتا ہے، کیونکہ --disable صرف انسٹالیشن کے وقت component کو چھوڑتا نہیں ہے۔ یہ پہلے سے deployed component کو بھی delete کرتا ہے، اس لیے تبدیلی چلتے ہوئے cluster پر نافذ ہو جاتی ہے۔

اگر آپ Traefik برقرار رکھنا چاہتے ہیں لیکن chart کی configuration تبدیل کرنا چاہتے ہیں تو /var/lib/rancher/k3s/server/manifests/traefik.yaml میں ترمیم نہ کریں۔ k3s ہر بار start ہونے پر اس file کو defaults کے ساتھ دوبارہ لکھ دیتا ہے۔ اس کے بجائے اسی directory میں ایک الگ file شامل کریں، کیونکہ /var/lib/rancher/k3s/server/manifests کے اندر موجود ہر چیز startup کے وقت اور disk پر اس میں تبدیلی ہونے پر خودکار طور پر apply ہو جاتی ہے۔

apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
  name: traefik
  namespace: kube-system
spec:
  valuesContent: |-
    ports:
      web:
        forwardedHeaders:
          trustedIPs:
            - 10.0.0.0/8

اس مثال میں Traefik chart کی ایک value، یعنی trusted proxy addresses، set کی گئی ہے۔ یہی طریقۂ کار chart کی ظاہر کردہ کسی بھی دوسری value کو set کرنے کے لیے استعمال کیا جا سکتا ہے، جن میں اس کے ports بھی شامل ہیں۔

ایک node پر persistent storage

k3s ایک default StorageClass فراہم کرتا ہے جس کا نام local-path ہے اور جو Rancher کے local-path provisioner کے ذریعے کام کرتا ہے۔ جس PersistentVolumeClaim میں storageClassName نہ ہو، اسے یہی StorageClass ملتا ہے۔ Volumes /var/lib/rancher/k3s/storage میں محفوظ ہوتے ہیں، اور ہر volume کے لیے node کی اپنی disk پر ایک الگ subdirectory بنائی جاتی ہے۔

sudo k3s kubectl get storageclass
sudo k3s kubectl get pvc -A
sudo ls -l /var/lib/rancher/k3s/storage

"node کی اپنی disk پر" ہونے کے دو نتائج ہیں، اور دونوں کا اثر فوراً نہیں بلکہ بعد میں ظاہر ہوتا ہے۔

StorageClass میں volumeBindingMode: WaitForFirstConsumer استعمال ہوتا ہے، اس لیے نیا PVC اس وقت تک Pending رہتا ہے جب تک کوئی pod اسے mount نہ کرے۔ kubectl describe pvc کا output یہ دکھاتا ہے:

waiting for first consumer to be created before binding

یہ معمول کی بات ہے۔ اس لیے صرف PVC بنانا اور اس کے clear ہونے کا انتظار کرنا بے نتیجہ ہوگا۔

Bind ہونے کے بعد volume میں اس node کے لیے node affinity شامل ہو جاتی ہے جس نے اسے بنایا تھا۔ اس کے نتیجے میں اس claim کو استعمال کرنے والا ہر pod، volume کی پوری زندگی کے دوران اسی node تک محدود رہتا ہے۔ ایک node والے cluster میں آپ کو یہ مسئلہ نظر نہیں آئے گا۔ بعد میں دوسرا node شامل کرنے پر اگر کوئی pod دوسرے node پر منتقل نہ ہو تو یہ scheduler کا bug معلوم ہو سکتا ہے۔ لیکن kubectl get pv -o yaml چلانے پر nodeAffinity میں موجود hostname سے اصل وجہ معلوم ہو جاتی ہے۔

Backups کی ذمہ داری آپ کی ہے۔ VPS کو دوبارہ بنانا اس directory کو حذف کر دیتا ہے، اور نیچے دیا گیا uninstall script بھی یہی کرتا ہے۔ /var/lib/rancher/k3s/storage کا backup لیں۔ اس کے علاوہ /var/lib/rancher/k3s/server/db/state.db میں موجود sqlite datastore کو بھی backup کریں، لیکن اسے service روکنے کے بعد copy کریں کیونکہ یہ ایک live database ہے۔ متبادل طور پر cluster کو disposable سمجھیں اور ہر manifest کو git میں محفوظ رکھیں۔

Ingress اور TLS

Traefik فعال ہو تو ایک معیاری Ingress object ہی کافی ہے۔

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: hello
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt
spec:
  ingressClassName: traefik
  tls:
    - hosts:
        - hello.example.com
      secretName: hello-tls
  rules:
    - host: hello.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: hello
                port:
                  number: 80

Certificates خود بخود ظاہر نہیں ہوتے۔ عام حل cert-manager ہے، جسے اس کے شائع کردہ manifest سے install کیا جاتا ہے، اور اس کے ساتھ ایک ClusterIssuer بنایا جاتا ہے۔ August 2026 تک موجودہ version v1.21.1 ہے۔

sudo k3s kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.21.1/cert-manager.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt
spec:
  acme:
    email: you@example.com
    server: https://acme-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      name: letsencrypt-account-key
    solvers:
      - http01:
          ingress:
            ingressClassName: traefik

HTTP-01 challenge کا مطلب ہے کہ ACME (automatic certificate management environment) server public internet سے http://hello.example.com/.well-known/acme-challenge/... سے connect کرتا ہے۔ اس لیے DNS A record پہلے ہی VPS کی طرف point کرنا چاہیے، اور port 80 کو Traefik تک پہنچنا چاہیے۔ اگر آپ نے ServiceLB disabled کر کے اپنے proxy کو سامنے رکھا ہے تو اس proxy کو challenge path بھی forward کرنا ہوگا، ورنہ cert-manager Challenge object میں یہ حالت دکھا کر رک جائے گا:

Waiting for HTTP-01 challenge propagation: wrong status code '404', expected '200'

sudo k3s kubectl describe certificate hello-tls اور sudo k3s kubectl get order,challenge -A سے certificate issuance monitor کریں۔

kubeconfig اور API server نجی کیوں رہتا ہے

k3s انتظامی credentials کو /etc/rancher/k3s/k3s.yaml میں لکھتا ہے۔ یہ فائل root کی ملکیت ہوتی ہے اور پہلے سے mode 600 کے ساتھ لکھی جاتی ہے۔ اس میں cluster-admin حقوق والا client certificate موجود ہوتا ہے، اس لیے جو بھی اسے پڑھ سکتا ہے، پورے cluster پر اختیار رکھتا ہے۔

sudo k3s kubectl get node
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
kubectl get node

الگ سے نصب کیا گیا kubectl، جس میں KUBECONFIG set نہ ہو، The connection to the server localhost:8080 was refused - did you specify the right host or port? کے ساتھ ناکام ہو جاتا ہے، کیونکہ وہ ایسے default پر واپس چلا جاتا ہے جس کا k3s سے کوئی تعلق نہیں۔ KUBECONFIG set کریں، یا sudo k3s kubectl استعمال کریں، جو خود درست فائل پڑھ لیتا ہے۔

آپ دیکھیں گے کہ عام صارف کو kubectl چلانے کے قابل بنانے کے لیے --write-kubeconfig-mode 644 تجویز کیا جاتا ہے۔ سمجھیں کہ اس سے کیا ہوتا ہے: cluster-admin credential مشین کے ہر local account کے لیے قابلِ مطالعہ ہو جاتا ہے۔ صرف ایک administrator والے سرور پر یہ قابلِ قبول سمجھوتا ہو سکتا ہے۔ مشترکہ سرور پر ایسا نہیں ہے۔ فائل copy کرنے سے اسے عام کیے بغیر ایک صارف کو access مل جاتا ہے:

mkdir -p ~/.kube
sudo install -o $USER -g $USER -m 600 /etc/rancher/k3s/k3s.yaml ~/.kube/config

اس فائل میں server: والی سطر https://127.0.0.1:6443 پڑھتی ہے۔ اپنے laptop سے kubectl استعمال کرنے کے لیے 6443 کو internet پر نہ کھولیں۔ Public Kubernetes API مستقل ہدف بن جاتا ہے، اور exposed API کی وجہ سے چھوٹے clusters کسی اور کے لیے cryptocurrency mine کرنے لگتے ہیں۔ اسے SSH کے ذریعے tunnel کریں اور فائل میں موجود address کو تبدیل نہ کریں:

ssh -N -L 6443:127.0.0.1:6443 user@your-vps
KUBECONFIG=./k3s.yaml kubectl get node

اگر API تک private network address کے ذریعے پہنچنا ضروری ہو تو tls-san کے ساتھ installation کریں اور اس میں وہ name یا address درج کریں، پھر copy کی گئی فائل کی server: والی سطر کو اسی کے مطابق تبدیل کریں۔ SAN (subject alternative name) entry کے بغیر kubectl connection مسترد کر دیتا ہے:

x509: certificate is valid for 127.0.0.1, 10.43.0.1, not 203.0.113.10

Cluster کے لیے دستاویزی inbound ports یہ ہیں: API کے لیے TCP 6443، nodes کے درمیان flannel VXLAN کے لیے UDP 8472، اور kubelet metrics کے لیے TCP 10250۔ Single-node cluster پر ان میں سے کسی port کو بھی internet کے لیے کھلا رکھنے کی ضرورت نہیں۔

containerd، Docker نہیں ہے

k3s اپنا embedded containerd چلاتا ہے، اور یہ Docker کے ساتھ image store شیئر نہیں کرتا۔ آپ نے ابھی docker build سے جو image build کی ہے، وہ k3s کو نظر نہیں آتی۔ اس لیے pod ErrImagePull کے ساتھ fail ہو جاتا ہے، حالانکہ docker images اسے فہرست میں دکھاتا ہے۔ اسے واضح طور پر import کریں:

docker save myapp:0.1 | sudo k3s ctr images import -
sudo k3s crictl images

اس container پر :latest tag استعمال نہ کریں، کیونکہ :latest بطور ڈیفالٹ Always کے imagePullPolicy پر set ہوتا ہے، اور kubelet پھر بھی registry سے image حاصل کرنے کی کوشش کرتا ہے۔ کسی بھی دوسرے tag کا default IfNotPresent ہوتا ہے، جو آپ کی import کی ہوئی image استعمال کرتا ہے۔ ایک ہی VPS پر دونوں کو چلایا جا سکتا ہے۔ یہ بات سمجھنا مفید ہے کہ VPS پر عام Docker installation اور k3s، دونوں اسی machine پر اپنا الگ image store اور اپنے الگ iptables rules رکھتے ہیں۔

k3s کو کیسے ہٹائیں

installer ایک uninstall script لکھتا ہے۔ جزوی removal یا undo کی سہولت موجود نہیں ہے۔

sudo /usr/local/bin/k3s-uninstall.sh

یہ service کو روکتا اور ہٹاتا ہے، datastore حذف کرتا ہے، persistent volume data حذف کرتا ہے، node configuration ہٹاتا ہے، اور installer کے شامل کردہ tools بھی ہٹا دیتا ہے۔ agent node پر script اس کے بجائے k3s-agent-uninstall.sh ہوتی ہے۔ پہلے /var/lib/rancher/k3s/storage کے اندر موجود ہر چیز کو اس machine سے باہر copy کر لیں، کیونکہ یہ directory بھی حذف ہو جاتی ہے۔ اس کے بعد ip link show اور sudo ss -lntp سے تصدیق کریں کہ کوئی process ports یا interfaces پر قبضہ برقرار نہیں رکھے ہوئے۔ باقی رہ جانے والا cni0 یا flannel.1 interface اگلے reboot پر ختم ہو جاتا ہے۔

یہ فیصلہ کرنا کہ Kubernetes کا ایک node کام کی ضرورت سے زیادہ پیچیدہ نکلا، ناکامی نہیں بلکہ ایک معمول کا نتیجہ ہے۔ ان workloads کو واپس Compose پر منتقل کرنا عموماً ایک دوپہر میں مکمل ہو جاتا ہے۔

خرابی کی صورتیں اور وہ strings جو آپ دیکھیں گے

Node NotReady، یا k3s مسلسل restart ہو رہا ہے۔ پہلے sudo journalctl -u k3s -n 200 --no-pager پڑھیں۔ چھوٹے VPS پر عام وجہ kernel کا out-of-memory killer ہوتا ہے، جو process کو ختم کر دیتا ہے۔ یہ dmesg میں ایسی line کے طور پر ظاہر ہوتا ہے جس میں k3s-server کا نام ہوتا ہے۔ دستاویز شدہ 2 GB minimum حقیقی کم از کم حد ہے۔

Pod Pending میں پھنسا ہوا ہے۔ kubectl describe pod ہر بار اس کی وجہ بتاتا ہے۔ Insufficient memory یا Insufficient cpu کا مطلب ہے کہ node پر مزید گنجائش نہیں ہے۔ didn't have free ports اوپر بیان کردہ hostPort collision ہے۔ PVC پر waiting for first consumer کا مطلب ہے کہ WaitForFirstConsumer درست طور پر کام کر رہا ہے۔

ImagePullBackOff۔ یا تو tag کسی ایسے registry میں موجود نہیں جس تک node رسائی حاصل کر سکتا ہو، یا آپ نے image کو Docker سے build کیا اور اسے containerd میں import نہیں کیا۔

Traefik جواب دیتا ہے، مگر app جواب نہیں دیتی۔ 404 page not found کا response body خود Traefik سے آتا ہے۔ اس کا مطلب ہے کہ request پہنچ گئی، مگر کسی router سے match نہیں ہوئی۔ تصدیق کریں کہ Ingress کا host آپ کے درج کیے ہوئے نام سے match کرتا ہے، اور ingressClassName، traefik ہے۔

Cluster DNS ناکام ہے، جبکہ host نام resolve کر لیتا ہے۔ sudo k3s kubectl -n kube-system logs -l k8s-app=kube-dns سے CoreDNS چیک کریں۔ plugin/loop: Loop ... detected for zone "." جیسا message CoreDNS کو start ہونے سے روک دیتا ہے۔ ایسا اس لیے ہوتا ہے کہ CoreDNS ایسے resolver کو forward کر رہا ہوتا ہے جو request دوبارہ اسی کی طرف forward کرتا ہے۔ /etc/resolv.conf میں loopback address یہی مسئلہ پیدا کرتا ہے۔ --resolv-conf /run/systemd/resolve/resolv.conf کے ذریعے k3s کو اصل upstream file استعمال کرنے کے لیے configure کریں۔

FAQ

کیا ایک ہی VPS پر k3s چلانا مفید ہے؟

یہ اس وقت مفید ہے جب آپ Kubernetes API استعمال کرنا چاہتے ہوں: اپنے زیرِ انتظام machine پر اسے سیکھنا، deployments کو manifests کی صورت میں قابلِ منتقلی رکھنا، ایسا software چلانا جو صرف Helm chart فراہم کرتا ہو، یا ایسی چیز بنانا جسے بعد میں managed cluster میں منتقل کرنا ہو۔ اگر آپ کا مقصد صرف containers چلانا ہے تو یہ مفید نہیں، کیونکہ Docker Compose یہ کام بہت کم انتظامی محنت اور تقریباً ایک gigabyte زیادہ free RAM کے ساتھ کر دیتا ہے۔ ایک node high availability فراہم نہیں کرتا، اس لیے reliability اسے منتخب کرنے کی وجہ نہیں بنتی۔

میری k3s LoadBalancer service Pending کیوں رہتی ہے؟

ServiceLB ایسے svclb- pods بناتا ہے جو node پر service کے ports کو hostPort کے طور پر claim کرتے ہیں، اس لیے وہ صرف وہاں schedule ہوتے ہیں جہاں یہ ports خالی ہوں۔ اگر nginx یا کوئی دوسرا proxy پہلے ہی port 80 استعمال کر رہا ہو تو pod Pending رہتا ہے اور service کو کبھی external address نہیں ملتا۔ kubectl -n kube-system describe pod svclb-...، 0/1 nodes are available: 1 node(s) didn't have free ports for the requested pod ports رپورٹ کرتا ہے۔ port خالی کریں، یا --disable=servicelb کے ساتھ دوبارہ install کریں اور service کے مختص کیے جانے والے NodePort پر proxy کریں۔

VPS پر k3s کو کتنی RAM درکار ہوتی ہے؟

server node کے لیے documented minimum 2 cores اور 2 GB ہے، اور یہ آپ کے workloads سے پہلے k3s اور اس کے bundled components کے لیے کافی ہوتا ہے۔ project کی اپنی profiling میں monitoring stack کے ساتھ server node کا استعمال 1,596 MB ناپا گیا، اس لیے 2 GB کو کم از کم حد اور 4 GB کو وہ پہلا سائز سمجھیں جس پر ایک node اطمینان سے چلتا ہے۔ install سے پہلے free -h کے ذریعے اپنے system کی پیمائش کریں، پھر kube-system میں ہر pod کے Running پڑھنے کے بعد دوبارہ پیمائش کریں۔

کیا میں ایک ہی VPS پر Docker اور k3s چلا سکتا ہوں؟

جی ہاں، اور دونوں الگ رہتے ہیں۔ k3s اپنا embedded containerd استعمال کرتا ہے، اس لیے docker build سے بنائی گئی image اسے اس وقت تک نظر نہیں آتی جب تک آپ docker save myapp:0.1 | sudo k3s ctr images import - نہ چلائیں۔ دونوں اپنے iptables rules اور اپنے bridge networks بھی بناتے ہیں۔ memory total پر نظر رکھیں، کیونکہ Docker، k3s اور آپ کے containers مل کر 2 GB کے system میں نہیں سما سکیں گے۔

میں k3s کو مکمل طور پر کیسے ہٹاؤں؟

server node پر sudo /usr/local/bin/k3s-uninstall.sh یا agent پر sudo /usr/local/bin/k3s-agent-uninstall.sh چلائیں۔ یہ service روکتا ہے، datastore حذف کرتا ہے، /var/lib/rancher/k3s/storage کے تحت persistent volume data حذف کرتا ہے، اور bundled tools ہٹا دیتا ہے۔ جس data کو محفوظ رکھنا ہو اسے پہلے system سے باہر copy کر لیں، کیونکہ واپس کرنے کا کوئی طریقہ نہیں ہے۔ بچا ہوا cni0 یا flannel.1 network interface اگلے reboot پر غائب ہو جاتا ہے۔

#kubernetes#k3s#docker-compose#ingress#sizing