একটি VPS-এ single-node k3s কখন ব্যবহার করবেন
একটি VPS-এ k3s চালালে আসল Kubernetes API পান, তবে RAM কমে এবং install-এর সময় port 80 সংঘাত হতে পারে। Docker Compose কখন এখনও ভালো পছন্দ, তা জানুন।
k3s কী, এবং এর একটি node আপনাকে কী দেয়
k3s হলো একটি binary হিসেবে প্যাকেজ করা পূর্ণাঙ্গ Kubernetes distribution। এটি একটি VPS-এ চালালে তিনটি মেশিনের control plane ছাড়াই প্রকৃত Kubernetes API পাওয়া যায়। এটি একটি certified Kubernetes distribution। তাই এখানে প্রয়োগ করা manifest পরে managed cluster-এও প্রয়োগ করা যাবে। ইনস্টল করতে একটি command লাগে এবং সময় লাগে প্রায় এক মিনিট। এর বিনিময়ে আপনার application-এর জন্য উপলভ্য memory কমে যায়। এছাড়া কিছু failure mode যুক্ত হয়, যেগুলো Docker Compose ব্যবহার করলে কখনো দেখা যায় না।
SUSE edge site এবং ছোট installation-এর জন্য k3s তৈরি করে। Upstream Kubernetes থেকে প্রতিটি পার্থক্যের উদ্দেশ্য হলো এটিকে ছোট রাখা। Default datastore হিসেবে etcd-এর পরিবর্তে kine নামের একটি shim-এর পেছনে sqlite ব্যবহৃত হয়। তাই etcd quorum রক্ষণাবেক্ষণ করতে হয় না। containerd আলাদাভাবে ইনস্টল না করে binary-এর মধ্যে embedded থাকে। একই binary cluster DNS-এর জন্য CoreDNS, ingress controller হিসেবে Traefik, cloud provider ছাড়াই LoadBalancer service চালানোর জন্য ServiceLB (এটিকে klipper-lb-ও বলা হয়), persistent volume-এর জন্য local-path provisioner, metrics-server এবং pod networking-এর জন্য flannel-ও সরবরাহ করে। এগুলোর প্রতিটিই default হিসেবে চালু হয়। তাই আগে থেকেই অন্য কাজ করা একটি VPS-এ নিচে বর্ণিত port collision-ই সবচেয়ে সাধারণ প্রথম সমস্যা।
একটি k3s node কখন উপযুক্ত
এই নিয়মটি অনুসরণ করুন। আপনি যখন Kubernetes API ব্যবহার করতে চান, তখন k3s চালান: আপনি নিজের নিয়ন্ত্রণে থাকা একটি মেশিনে Kubernetes শিখছেন, অথবা আপনার প্রয়োজনীয় software শুধু একটি Helm chart প্রকাশ করে। Manifest-এর বহনযোগ্যতাও গুরুত্বপূর্ণ, কারণ এখানে লেখা একটি Deployment কোনো পরিবর্তন ছাড়াই managed cluster-এ নেওয়া যায়। আপনি যখন application-গুলো চালানোই মূল লক্ষ্য, তখন Docker Compose চালান। Compose অনেক কম উপাদান ব্যবহার করে একই container চালু করে। এক বছর পর একটি VPS-এ থাকা Compose file পড়া manifest-এর একটি directory পড়ার চেয়ে সহজ।
একটি node কী দেয় না, তা স্পষ্টভাবে বুঝুন।
- High availability নেই। VPS reboot হলে সব workload বন্ধ হয়ে যায়। Kubernetes একটি pod-কে অন্য node-এ পুনরায় schedule করতে পারে, কিন্তু এখানে অন্য কোনো node নেই।
- এমন rolling update নেই যা service চালু রাখে, যদি না application একই মেশিনে একটি volume ভাগ করে নেওয়া দুইটি replica সহ্য করতে পারে।
- Storage এই মেশিনের সঙ্গেই আবদ্ধ থাকে। এর কারণ নিচের local-path section-এ বর্ণনা করা হয়েছে।
- আপনি কোনো workload deploy না করলেও একটি control plane প্রায় এক gigabyte RAM ব্যবহার করে।
এগুলোর কোনোটিই k3s-কে খারাপ পছন্দ করে না। তবে reliability-এর জন্য k3s বেছে নেওয়া খারাপ সিদ্ধান্ত। মানুষ সাধারণত এই কারণটিই উল্লেখ করে। আপনার প্রকৃত লক্ষ্য যদি কয়েকটি মেশিন নিয়ে একটি বাস্তব multi-node cluster তৈরি করা হয়, তাহলে সেই সিদ্ধান্ত আগে নিতে হবে: k3s কোন জিনিস চালাবে তা নির্ধারণ করার আগে নিজের hardware-এ Proxmox নাকি ভাড়া করা VPS ব্যবহার করে node-গুলো কোথা থেকে আসবে, তা ঠিক করুন।
কোনো কিছু deploy করার আগে k3s কত RAM ও CPU ব্যবহার করে
k3s project অনুমানের বদলে পরিমাপ করা পরিসংখ্যান প্রকাশ করে। এগুলো মনোযোগ দিয়ে পড়ুন, কারণ মানুষ যে সংখ্যাটি সাধারণত উল্লেখ করে, সেটি idle k3s-এর ব্যবহার নয়।
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
}
]ওই পরীক্ষায় একটি server node 95th percentile-এ 1,596 MB RAM এবং একটি core-এর প্রায় 6 শতাংশ ব্যবহার করেছে। এগুলো প্রকাশিত পরিসংখ্যান; এই guide থেকে নেওয়া measurement নয়। পরীক্ষায় k3s v1.26.5 চালানো হয়েছিল এবং সব packaged component-এর সঙ্গে Prometheus ও Grafana monitoring stack সক্রিয় ছিল। তাই এই সংখ্যায় খালি cluster নয়, বাস্তব workload-ও অন্তর্ভুক্ত। sqlite-এর বদলে embedded etcd ব্যবহার করলে RAM ব্যবহার বেড়ে 1,606 MB হয়। Agent node-এ control plane থাকে না; সেখানে kubelet ও containerd চলে এবং RAM ব্যবহার হয় 275 MB। একটি server-এর documented minimum হলো 2 cores এবং 2 GB RAM। এই minimum-এর মধ্যে আপনার workload ছাড়াই k3s ও তার packaged component অন্তর্ভুক্ত থাকে।
বাস্তবে এর অর্থ হলো: 2 GB VPS-এ control plane এবং bundled add-on চালানোর পর খুব কম RAM অবশিষ্ট থাকে। চাপ বাড়লে প্রথম যে ঘটনা ঘটে, তা হলো kubelet pod evict করে। কয়েকটি ছোট service-সহ একটি node-এর জন্য 4 GB একটি স্বাচ্ছন্দ্যপূর্ণ minimum। কোনো published figure-এর ওপর, এমনকি এই সংখ্যাটির ওপরও, নির্ভর না করে নিজের machine-এ measurement নিন।
free -h
sudo k3s kubectl top node
sudo k3s kubectl get pods -AInstall করার আগে এবং kube-system-এর প্রতিটি pod-এর status Running হওয়ার পরে আবার free -h চালান। দুই measurement-এর পার্থক্য আপনার hardware-এ control plane-এর ব্যবহার দেখায়। Install-এর পর প্রথম এক বা দুই মিনিটে k3s kubectl top node, error: Metrics API not available ফেরত দেয়, কারণ metrics-server তখনও কোনো data scrape করেনি। এটি কোনো fault নয়। একই machine-এ k3s এবং অন্যান্য কাজ একসঙ্গে চালানোর জন্য sizing করলে VPS-এর জন্য RAM ও CPU নির্ধারণ-এর arithmetic এখানে কোনো পরিবর্তন ছাড়াই প্রযোজ্য।
একটি release-এ pin করে k3s ইনস্টল করুন, latest-এ নয়
সবার কপি করা quick start লাইনটি আপনি যেদিন চালান, সেদিন stable channel যে release নির্দেশ করে সেটিই ইনস্টল করে। যে মেশিন দীর্ঘদিন চালানোর পরিকল্পনা আছে, সেখানে version pin করুন। k3s প্রতিটি Kubernetes minor version-এর জন্য একটি করে channel প্রকাশ করে। তাই INSTALL_K3S_CHANNEL=v1.36 v1.36-এর ভেতরের patch release অনুসরণ করবে এবং আপনার অজান্তে minor version পরিবর্তন করবে না। August 2026 অনুযায়ী stable channel v1.36.3+k3s1 নির্দেশ করছে।
প্রথমে config file লিখুন, তারপর ইনস্টল করুন। k3s চালু হওয়ার সময় /etc/rancher/k3s/config.yaml পড়ে। তাই এতে থাকা সব সেটিং প্রথম boot এবং পরবর্তী প্রতিটি boot-এ প্রয়োগ হবে।
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 ব্যবহার করুন। + চিহ্নটি tag-এর অংশ। এরপর k3s সফলভাবে চালু হয়েছে কি না যাচাই করুন।
k3s --version
sudo systemctl status k3s
sudo k3s kubectl get node
sudo k3s kubectl get pods -Akubectl get node-এ প্রায় ত্রিশ সেকেন্ডের মধ্যে STATUS Ready-সহ একটি node দেখানো উচিত। kube-system-এর প্রতিটি pod-এর অবস্থা Running অথবা Completed হওয়া উচিত। কোনো node NotReady অবস্থায় আটকে থাকলে সাধারণত container runtime চালু হয়নি। তাই sudo journalctl -u k3s -n 100 --no-pager পড়ুন। অস্বাভাবিক VPS image হলে অন্য কিছু debug করার আগে sudo k3s check-config চালান। এটি অনুপস্থিত kernel feature জানায়, তাই log পড়ার চেয়ে দ্রুত কারণ শনাক্ত করা যায়।
80 port ইতিমধ্যে ব্যবহৃত হচ্ছে কেন এবং এটি ঠিক করতে কী ছাড়তে হবে
আগে থেকেই কোনো সেবা চালু থাকা VPS-এ এই সমস্যাটি বেশি দেখা যায়। ইনস্টলেশন সফল হয়। এরপর Traefik কোনো address পায় না, অথচ আগে থেকে চালু থাকা site কাজ করতে থাকে। তাই ingress-এ অনুরোধ পাঠানোর চেষ্টা না করা পর্যন্ত কিছুই নষ্ট মনে হয় না।
কারণটি হলো: bundled Traefik chart 80 এবং 443 port-এ LoadBalancer ধরনের একটি Service তৈরি করে। ServiceLB এই অনুরোধের জবাবে svclb- prefix-যুক্ত ছোট pod-এর একটি DaemonSet তৈরি করে। এই pod-গুলো প্রতিটি node-এ hostPort হিসেবে ওই port number দখল করে। hostPort container port-কে সরাসরি node-এর নিজস্ব network namespace-এ প্রকাশ করে, ঠিক যেমন docker run -p 80:80 করে। nginx, Caddy, Apache বা অন্য কোনো container আগে থেকেই 80 port ধরে রাখলে kernel একই port দ্বিতীয়বার বরাদ্দ করে না। ফলে scheduler-এর কাছে pod বসানোর কোনো node থাকে না।
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/TCPkubectl -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 কোন process port-টি ধরে রেখেছে তা জানায়। এই সমস্যা সমাধানের একাধিক উপায় আছে, এবং প্রতিটি উপায়ে আপনাকে কিছু ছাড়তে হবে।
port k3s-কে দিন। বিদ্যমান web server বন্ধ করে disable করুন। এরপর Traefik-কে 80 এবং 443 port ব্যবহার করতে দিন। VPS-টি যদি শুধু k3s-এর জন্য ব্যবহৃত হয় এবং আগে থেকে চালু থাকা সব service Ingress-এর পেছনে সরানো হয়, তাহলে এটিই সঠিক পদ্ধতি।
ServiceLB disable করে বিদ্যমান proxy রাখুন। --disable=servicelb দিয়ে ইনস্টল করুন। LoadBalancer ধরনের Service তখনও একটি NodePort বরাদ্দ করে। তাই Traefik 31480-এর মতো একটি উচ্চ port-এ reachable থাকবে এবং আপনার nginx বা Caddy 127.0.0.1:31480-এ proxy করবে। এতে external address ছাড়তে হবে: service সবসময় <pending> দেখাবে। এটি ত্রুটি নয়; এটি আপনার বেছে নেওয়া configuration-এর ফল।
Traefik disable করে নিজের proxy দিয়ে route করুন। --disable=traefik দিয়ে ইনস্টল করুন। তখন কোনো ingress controller থাকবে না। ফলে Ingress object একেবারেই কিছু করবে না। এগুলো API-তে থাকবে, কিন্তু কোনো controller এগুলো monitor করবে না। Host proxy থেকে NodePort-এ route করলে এটি ঠিক আছে। HTTP কীভাবে পরিচালনা করবেন তা আগে থেকেই জানা থাকলে এটিই সঠিক সিদ্ধান্ত। কোন proxy সামনে থাকবে তা নিয়ে অনিশ্চিত হলে, কিছু disable করার আগে reverse proxy হিসেবে nginx, Caddy এবং Traefik-এর মধ্যে নির্বাচন ঠিক করুন।
দুটি flag installer-এ অথবা config file-এ দিতে হবে:
tls-san:
- k3s.example.com
disable:
- traefik
- servicelbইনস্টলেশনের পরে ওই file সম্পাদনা করে sudo systemctl restart k3s চালালেও কাজ হবে। কারণ --disable শুধু ইনস্টলেশনের সময় কোনো component বাদ দেয় না। আগে থেকেই deployed থাকা component-ও এটি মুছে ফেলে। তাই চলমান cluster-এও পরিবর্তনটি কার্যকর হয়।
Traefik রেখে chart কীভাবে configured হবে তা পরিবর্তন করতে /var/lib/rancher/k3s/server/manifests/traefik.yaml সম্পাদনা করবেন না। k3s প্রতিবার start হওয়ার সময় ওই file-টি default দিয়ে পুনরায় লিখে। এর পরিবর্তে একই directory-তে আলাদা একটি file যোগ করুন। কারণ /var/lib/rancher/k3s/server/manifests-এর ভেতরের যেকোনো configuration startup-এর সময় এবং disk-এ file পরিবর্তিত হলে স্বয়ংক্রিয়ভাবে প্রয়োগ হয়।
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 address, নির্ধারণ করা হয়েছে। একই পদ্ধতিতে chart যে কোনো exposed value নির্ধারণ করা যায়, যার মধ্যে port-ও রয়েছে।
একটি নোডে persistent storage
k3s-এর সঙ্গে local-path নামের একটি ডিফল্ট StorageClass থাকে। এটি Rancher's local-path provisioner দ্বারা পরিচালিত। কোনো storageClassName ছাড়া তৈরি করা PersistentVolumeClaim স্বয়ংক্রিয়ভাবে এটি ব্যবহার করে। ভলিউমগুলো /var/lib/rancher/k3s/storage-এ থাকে। প্রতিটি ভলিউমের জন্য নোডের নিজস্ব ডিস্কে একটি আলাদা subdirectory তৈরি হয়।
sudo k3s kubectl get storageclass
sudo k3s kubectl get pvc -A
sudo ls -l /var/lib/rancher/k3s/storage“নোডের নিজস্ব ডিস্কে” থাকার দুটি ফল আছে। এগুলো এখন নয়, পরে সমস্যার কারণ হয়।
StorageClass-এ volumeBindingMode: WaitForFirstConsumer ব্যবহার করা হয়। তাই কোনো pod বাস্তবে ভলিউম mount না করা পর্যন্ত নতুন PVC Pending অবস্থায় থাকে। kubectl describe pvc চালালে দেখা যাবে:
waiting for first consumer to be created before bindingএটি স্বাভাবিক আচরণ। তাই শুধু একটি PVC তৈরি করে অপেক্ষা করলে এর অবস্থা Pending থেকে পরিবর্তিত হবে না।
Bound হওয়ার পরে ভলিউমে সেই নোডের জন্য node affinity যুক্ত থাকে, যে নোডে ভলিউমটি তৈরি হয়েছে। ফলে ওই claim ব্যবহারকারী প্রতিটি pod ভলিউমটির সম্পূর্ণ lifetime জুড়ে সেই নোডেই চলতে বাধ্য হয়। একটি নোড থাকলে বিষয়টি বোঝা যায় না। পরে দ্বিতীয় নোড যোগ করলে কোনো pod অন্য নোডে যেতে না চাইলে scheduler-এর ত্রুটি মনে হতে পারে। kubectl get pv -o yaml চালালে nodeAffinity-এ hostname দেখা যাবে।
Backup নেওয়ার দায়িত্ব আপনার। VPS পুনর্নির্মাণ করলে ওই directory মুছে যায়। নিচের uninstall script চালালেও directory-টি মুছে যায়। /var/lib/rancher/k3s/storage backup করুন। পাশাপাশি service বন্ধ থাকা অবস্থায় /var/lib/rancher/k3s/server/db/state.db-এ থাকা sqlite datastore-ও copy করে backup করুন, কারণ এটি একটি চলমান database। বিকল্প হিসেবে cluster-কে disposable ধরে নিতে পারেন এবং প্রতিটি manifest git-এ সংরক্ষণ করতে পারেন।
Ingress এবং TLS
Traefik চালু থাকলে একটি standard 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: 80Certificate নিজে থেকে তৈরি হয় না। সাধারণ সমাধান হলো প্রকাশিত manifest থেকে cert-manager install করা এবং একটি ClusterIssuer তৈরি করা। August 2026 অনুযায়ী v1.21.1 বর্তমান version।
sudo k3s kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.21.1/cert-manager.yamlapiVersion: 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: traefikHTTP-01 challenge-এর অর্থ হলো ACME (automatic certificate management environment) server public Internet থেকে http://hello.example.com/.well-known/acme-challenge/...-এ সংযোগ করে। তাই DNS A record আগে থেকেই VPS-এর দিকে নির্দেশ করতে হবে এবং port 80-কে Traefik পর্যন্ত পৌঁছাতে হবে। আপনি যদি ServiceLB disabled করে Traefik-এর সামনে নিজের 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 কেন private থাকে
k3s admin credential লিখে /etc/rancher/k3s/k3s.yaml-এ। এই ফাইলের মালিক root এবং default হিসেবে এর mode 600 থাকে। এতে cluster-admin অধিকারসহ একটি client certificate থাকে। তাই যে কেউ এটি পড়তে পারলে পুরো cluster-এর নিয়ন্ত্রণ পেয়ে যায়।
sudo k3s kubectl get node
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
kubectl get nodeআলাদাভাবে install করা kubectl-এ KUBECONFIG সেট না থাকলে The connection to the server localhost:8080 was refused - did you specify the right host or port?-এ ব্যর্থ হয়। কারণ এটি এমন একটি default ব্যবহার করে, যার k3s-এর সঙ্গে কোনো সম্পর্ক নেই। KUBECONFIG সেট করুন, অথবা sudo k3s kubectl ব্যবহার করুন। এটি নিজে থেকেই সঠিক ফাইল পড়ে।
সাধারণ user যেন kubectl চালাতে পারে, সে জন্য --write-kubeconfig-mode 644 ব্যবহারের পরামর্শ দেখতে পাবেন। এর প্রভাব বুঝে নিন: এতে cluster-admin credential মেশিনের প্রতিটি local account-এর পড়ার উপযোগী হয়। single-admin মেশিনে এটি গ্রহণযোগ্য সমঝোতা হতে পারে। shared মেশিনে এটি নিরাপদ নয়। ফাইলটি copy করলে সেটি প্রকাশ না করেই একজন user-কে access দেওয়া যায়:
mkdir -p ~/.kube
sudo install -o $USER -g $USER -m 600 /etc/rancher/k3s/k3s.yaml ~/.kube/configওই ফাইলের server: line-টি https://127.0.0.1:6443 পড়ে। laptop থেকে kubectl ব্যবহার করতে 6443 internet-এর জন্য খুলবেন না। একটি public Kubernetes API সবসময় আক্রমণের লক্ষ্য থাকে। এটি exposed থাকলে ছোট cluster অন্যের জন্য cryptocurrency mining-এ ব্যবহৃত হতে পারে। SSH দিয়ে tunnel তৈরি করুন এবং ফাইলের address অপরিবর্তিত রাখুন:
ssh -N -L 6443:127.0.0.1:6443 user@your-vps
KUBECONFIG=./k3s.yaml kubectl get nodeprivate network address ব্যবহার করে API-তে পৌঁছাতেই হলে tls-san দিয়ে install করুন এবং সেখানে সেই name বা address উল্লেখ করুন। এরপর copied file-এর server: line-টি মিলিয়ে edit করুন। 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-এর documented inbound port হলো API-এর জন্য TCP 6443, node-গুলোর মধ্যে flannel VXLAN-এর জন্য UDP 8472, এবং kubelet metrics-এর জন্য TCP 10250। single-node cluster-এ এগুলোর কোনোটি internet-এর জন্য open করার প্রয়োজন নেই।
containerd, Docker নয়
k3s নিজস্ব embedded containerd চালায় এবং Docker-এর সঙ্গে image store শেয়ার করে না। আপনি এইমাত্র docker build দিয়ে তৈরি করা image k3s দেখতে পায় না। তাই docker images সেটি তালিকাভুক্ত করলেও pod ErrImagePull ত্রুটি নিয়ে ব্যর্থ হয়। Image-টি স্পষ্টভাবে import করুন:
docker save myapp:0.1 | sudo k3s ctr images import -
sudo k3s crictl imagesএরপর ওই container-এ :latest tag ব্যবহার এড়িয়ে চলুন। কারণ :latest ডিফল্টভাবে Always-এর একটি imagePullPolicy ব্যবহার করে, ফলে kubelet যেকোনো অবস্থায় registry-তে যায়। অন্য যেকোনো tag-এর ডিফল্ট মান IfNotPresent। এটি আপনার import করা image ব্যবহার করে। একই VPS-এ দুটিই চালানো যায়। মনে রাখুন, VPS-এ সাধারণ Docker installation এবং k3s একই মেশিনে পৃথক image store ও পৃথক iptables rule বজায় রাখে।
k3s কীভাবে সরাবেন
ইনস্টলার একটি uninstall script লিখে রাখে। আংশিক অপসারণের কোনো ব্যবস্থা নেই এবং এটি পূর্বাবস্থায় ফেরানো যায় না।
sudo /usr/local/bin/k3s-uninstall.shএটি service বন্ধ করে সরিয়ে দেয়, datastore মুছে ফেলে, persistent volume-এর data মুছে ফেলে, node configuration সরিয়ে দেয় এবং ইনস্টলার যোগ করা tools সরিয়ে দেয়। Agent node-এ script-টি এর পরিবর্তে k3s-agent-uninstall.sh। আগে /var/lib/rancher/k3s/storage-এর অধীনে থাকা সবকিছু server-এর বাইরে কপি করুন, কারণ directory-টি script-এর সঙ্গে সরিয়ে যাবে। এরপর ip link show এবং sudo ss -lntp ব্যবহার করে যাচাই করুন, কোনো process port বা interface ধরে রেখেছে কি না। অবশিষ্ট cni0 বা flannel.1 interface পরবর্তী reboot-এ সরে যাবে।
Kubernetes-এর একটি node কাজের তুলনায় অতিরিক্ত জটিল মনে হওয়ায় সেটি সরিয়ে নেওয়া স্বাভাবিক সিদ্ধান্ত; এটি ব্যর্থতা নয়। সাধারণত সেই workload-গুলো Compose-এ ফিরিয়ে নিতে একটি বিকেলই যথেষ্ট।
ব্যর্থতার ধরন এবং আপনি যে বার্তাগুলো দেখবেন
Node NotReady, অথবা k3s বারবার restart হচ্ছে। প্রথমে sudo journalctl -u k3s -n 200 --no-pager পড়ুন। ছোট VPS-এ সাধারণ কারণ হলো kernel-এর out-of-memory killer প্রক্রিয়াটি বন্ধ করে দিচ্ছে। dmesg-এ এটি k3s-server-এর নাম থাকা একটি line হিসেবে দেখা যায়। নথিভুক্ত 2 GB minimum বাস্তবিকই সর্বনিম্ন সীমা।
Pod Pending অবস্থায় আটকে আছে। kubectl describe pod প্রতিবার কারণটি উল্লেখ করে। Insufficient memory অথবা Insufficient cpu অর্থ হলো node-এ আর পর্যাপ্ত জায়গা নেই। didn't have free ports হলো উপরে বর্ণিত hostPort সংঘর্ষ। PVC-তে waiting for first consumer দেখা গেলে বুঝবেন WaitForFirstConsumer সঠিকভাবে কাজ করছে।
ImagePullBackOff। হয় tag-টি node যে registry-গুলোতে পৌঁছাতে পারে, সেগুলোর কোনোটিতেই নেই, অথবা আপনি Docker দিয়ে image তৈরি করেছেন কিন্তু সেটি containerd-এ import করেননি।
Traefik উত্তর দিচ্ছে, কিন্তু app দিচ্ছে না। 404 page not found-এর response body Traefik নিজেই পাঠায়। এর অর্থ request পৌঁছেছে, কিন্তু কোনো router-এর সঙ্গে মেলেনি। Ingress-এর host আপনার টাইপ করা name-এর সঙ্গে মেলে কি না এবং ingressClassName হলো traefik কি না পরীক্ষা করুন।
Host name resolve করতে পারলেও cluster DNS ব্যর্থ হচ্ছে। sudo k3s kubectl -n kube-system logs -l k8s-app=kube-dns দিয়ে CoreDNS পরীক্ষা করুন। plugin/loop: Loop ... detected for zone "."-এর মতো message CoreDNS-কে start হতে বাধা দেয়। এর কারণ হলো CoreDNS এমন একটি resolver-এ forwarding করছে, যেটি আবার CoreDNS-এ forwarding করে। /etc/resolv.conf-এ loopback address থাকলে এমনটি ঘটে। --resolv-conf /run/systemd/resolve/resolv.conf দিয়ে k3s-কে প্রকৃত upstream file ব্যবহার করতে নির্দেশ দিন।
FAQ
একটি single VPS-এ k3s চালানো কি সার্থক?
আপনি Kubernetes API ব্যবহার করতে চাইলে এটি সার্থক: নিজের নিয়ন্ত্রণাধীন মেশিনে Kubernetes শেখা, manifest হিসেবে deployment portable রাখা, শুধু Helm chart প্রকাশ করে এমন software চালানো, অথবা পরে managed cluster-এ স্থানান্তর করবেন এমন কিছু তৈরি করা। আপনি শুধু container চালাতে চাইলে এটি সার্থক নয়, কারণ Docker Compose অনেক কম রক্ষণাবেক্ষণে একই কাজ করে এবং প্রায় এক gigabyte বেশি free RAM রাখে। একটি node কোনো high availability দেয় না, তাই reliability কখনো এটি বেছে নেওয়ার কারণ নয়।
আমার k3s LoadBalancer service Pending অবস্থায় থাকে কেন?
ServiceLB svclb- pod তৈরি করে। এগুলো node-এ service-এর port-গুলোকে hostPort হিসেবে দাবি করে। তাই port-গুলো free থাকলেই pod schedule হয়। 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টি free করুন, অথবা --disable=servicelb দিয়ে reinstall করে service যে NodePort বরাদ্দ করে, সেখানে proxy করুন।
একটি VPS-এ k3s-এর কত RAM প্রয়োজন?
নথিভুক্ত হিসাবে একটি server node-এর জন্য ন্যূনতম 2 cores এবং 2 GB প্রয়োজন। এটি আপনার workload চালানোর আগে k3s ও তার packaged component-গুলোর জন্য প্রয়োজনীয় RAM। প্রকল্পটির নিজস্ব profiling-এ monitoring stack চালু থাকা অবস্থায় একটি server node-এর ব্যবহার 1,596 MB মাপা হয়েছে। তাই 2 GB-কে সর্বনিম্ন সীমা এবং 4 GB-কে এমন প্রথম আকার হিসেবে ধরুন যেখানে একটি node স্বচ্ছন্দে চলে। Install-এর আগে free -h দিয়ে মাপ নিন এবং kube-system-এর প্রতিটি pod Running দেখানোর পরে আবার মাপ নিন।
একই VPS-এ Docker এবং k3s চালাতে পারি কি?
হ্যাঁ, এবং এগুলো আলাদা থাকে। k3s নিজের embedded containerd ব্যবহার করে। তাই docker build দিয়ে তৈরি image docker save myapp:0.1 | sudo k3s ctr images import - চালানো না পর্যন্ত k3s সেটি দেখতে পায় না। উভয়ই নিজেদের iptables rule এবং bridge network তৈরি করে। মোট memory পর্যবেক্ষণ করুন, কারণ Docker, k3s এবং আপনার container-গুলো একসঙ্গে 2 GB-এর মেশিনে ধরে নাও চলতে পারে।
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 tool-গুলো সরিয়ে দেয়। রাখতে চান এমন data আগে মেশিনের বাইরে copy করুন, কারণ এই কাজ undo করা যায় না। অবশিষ্ট cni0 বা flannel.1 network interface পরবর্তী reboot-এ সরিয়ে যাবে।