اگر چند میکروسرویس روی یک کلاستر Kubernetes خودمیزبان دارید و دیگر نمیدانید کدام سرویس با کدام سرویس حرف میزند یا ترافیک بینشان رمزنگاری شده یا نه، وقتش است سراغ Istio بروید. در این مقاله راهاندازی Istio روی Kubernetes را قدمبهقدم روی یک کلاستر خودمیزبان (self-hosted) انجام میدهیم: نصب با Helm، فعال کردن sidecar injection، تعریف Gateway و VirtualService برای مدیریت ترافیک، و فعال کردن mTLS خودکار بین سرویسها.

سرویسمش چیست و Istio چه مشکلی را حل میکند
وقتی تعداد سرویسها از چهار پنج تا بیشتر میشود، منطق ارتباط بین آنها (retry، timeout، رمزنگاری، لاگگیری از ترافیک) را نمیشود توی کد هر سرویس تکرار کرد. سرویسمش (service mesh) این منطق را از کد اپلیکیشن جدا میکند و میگذارد روی یک لایه شبکهای کنار هر Pod.
Istio این کار را با یک پروکسی کوچک (Envoy) انجام میدهد که کنار هر Pod بهعنوان sidecar اجرا میشود. تمام ترافیک ورودی و خروجی آن Pod از این پروکسی رد میشود، بدون اینکه کد سرویس چیزی از وجود Istio بداند. یک control plane به اسم istiod این پروکسیها را کانفیگ میکند و گواهیهای mTLS را صادر و تمدید میکند.
روی کلاستر خودمیزبان (یعنی کلاستری که خودتان با kubeadm یا ابزار مشابه روی سرور راهاندازی کردهاید، نه یک سرویس مدیریتشده) این کار اهمیت بیشتری دارد چون شبکهی بین نودها را خودتان طراحی کردهاید و کسی جز شما مسئول امنیت ترافیک داخلی نیست.
پیشنیازها
قبل از شروع اینها را آماده کنید:
- یک کلاستر Kubernetes در حال اجرا (نسخه 1.28 به بالا کافی است) روی سرور مجازی یا سرور اختصاصی آریانت، با حداقل سه نود برای اینکه بشود ترافیک را بین Podهای مختلف پخش کرد. اگر هنوز کلاستر نساختهاید، راهاندازی کلاستر Kubernetes با kubeadm را قبل از این مقاله انجام دهید.
kubectlتنظیمشده و متصل به کلاستر.helmنسخه 3.- حداقل 2 vCPU و 4 گیگ رم آزاد روی هر نود کارگر، چون هر sidecar یک Envoy اضافه اجرا میکند و مصرف رم کلاستر را بالا میبرد. این عدد را با
kubectl top nodesقبل و بعد از نصب چک کنید تا غافلگیر نشوید. - یک CNI که NetworkPolicy را پشتیبانی کند (Calico یا Cilium)، چون mTLS در سطح بالاتر کار میکند ولی بهتر است شبکه هم پایهی درستی داشته باشد.
نصب Istio با Helm
Istio سه چارت اصلی دارد: base (CRDها)، istiod (control plane) و gateway (برای ترافیک ورودی). اگر با Helm کار نکردهاید، اول Helm چیست و چطور نصب برنامهها را ساده میکند را بخوانید. چارتها به ترتیب نصب میشوند:
helm repo add istio https://istio-release.storage.googleapis.com/charts
helm repo update
kubectl create namespace istio-system
helm install istio-base istio/base -n istio-system --set defaultRevision=default
helm install istiod istio/istiod -n istio-system --wait
بعد از چند ثانیه با این دستور وضعیت را چک کنید:
kubectl get pods -n istio-system
اگر Pod با نام istiod-... به وضعیت Running رسید، control plane آماده است. حالا Gateway ورودی را در namespace خودش نصب میکنیم تا مدیریت ترافیک ورودی از control plane جدا باشد:
kubectl create namespace istio-ingress
helm install istio-ingress istio/gateway -n istio-ingress
با kubectl get svc -n istio-ingress یک Service از نوع LoadBalancer یا NodePort میبینید. روی کلاستر خودمیزبان معمولا LoadBalancer واقعی ندارید، پس همان NodePort را با IP نود و پورتی که نشان میدهد باز کنید، یا با MetalLB یک IP شناور واقعی جلوی آن بگذارید.
فعال کردن Sidecar Injection
Istio فقط برای Podهایی که sidecar دارند کار میکند؛ باید به namespace بگویید کدام Podها این پروکسی را بگیرند. سادهترین راه برچسب زدن روی namespace است:
kubectl label namespace default istio-injection=enabled
از این لحظه هر Pod جدیدی که در namespace default ساخته شود، یک کانتینر دوم به اسم istio-proxy کنار خودش دارد. Podهای موجود را باید دوباره راهاندازی کنید تا sidecar بگیرند:
kubectl rollout restart deployment -n default
با kubectl get pods -n default چک کنید که ستون READY به جای 1/1 حالا 2/2 نشان میدهد؛ عدد دوم همان istio-proxy است.
Gateway و VirtualService برای مدیریت ترافیک
Gateway مشخص میکند روی کدام پورت و پروتکل ترافیک وارد مش شود، VirtualService مشخص میکند آن ترافیک به کدام سرویس و با چه قانونی برسد. مثلا برای یک سرویس به اسم checkout:
apiVersion: networking.istio.io/v1
kind: Gateway
metadata:
name: checkout-gateway
namespace: default
spec:
selector:
istio: ingress
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "checkout.example.com"
---
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: checkout-vs
namespace: default
spec:
hosts:
- "checkout.example.com"
gateways:
- checkout-gateway
http:
- route:
- destination:
host: checkout
subset: v1
weight: 90
- destination:
host: checkout
subset: v2
weight: 10
این تنظیم 10 درصد ترافیک را به نسخه v2 سرویس میفرستد و 90 درصد را به v1 — یک canary release ساده، بدون اینکه یک خط کد در خود سرویس تغییر کند. وزنها را هر بار کمی بیشتر کنید و لاگ خطای v2 را زیر نظر بگیرید؛ اگر چیزی غلط شد، کافی است وزن را برگردانید به صفر.
mTLS خودکار بین سرویسها
تا اینجا ترافیک مدیریت میشود ولی هنوز رمزنگاری نشده. Istio با یک منبع به اسم PeerAuthentication میتواند mTLS را بین تمام sidecarها اجباری کند، بدون اینکه کد سرویسها گواهی یا کلیدی مدیریت کند — istiod خودش گواهیها را صادر میکند و هر چند ساعت تمدید میکند:
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
name: default
namespace: istio-system
spec:
mtls:
mode: STRICT
با mode: STRICT هر سرویسی که sidecar ندارد دیگر نمیتواند مستقیم با سرویسهای داخل مش حرف بزند؛ این را قبل از اعمال روی کل کلاستر، اول روی یک namespace تست کنید تا سرویسی که هنوز sidecar نگرفته از کار نیفتد. برای چک کردن اینکه ارتباط رمزنگاریشده است:
istioctl proxy-config secret <pod-name> -n default
اگر گواهی معتبر با تاریخ انقضا برگرداند، یعنی آن Pod دارد از mTLS استفاده میکند.

نصب و تنظیم این گواهیها دستی هم شدنی است؛ اگر با مدیریت گواهی SSL در Kubernetes آشنا نیستید، راهاندازی cert-manager را هم ببینید که همین کار صدور و تمدید خودکار را برای ترافیک ورودی از بیرون کلاستر انجام میدهد.
مشاهده ترافیک با Kiali و Grafana
بدون دیدن نقشهی ترافیک، نگهداری یک مش چند سرویسی سخت میشود. Istio یک سری addon آماده دارد:
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.24/samples/addons/prometheus.yaml
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.24/samples/addons/grafana.yaml
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.24/samples/addons/kiali.yaml
بعد از بالا آمدن Podها:
istioctl dashboard kiali
Kiali نقشه زندهی سرویسها را نشان میدهد: کدام سرویس چقدر درخواست به کدام سرویس دیگر میفرستد، نرخ خطا چقدر است و کدام یال قفل سبز mTLS دارد. Grafana داشبوردهای آمادهای برای تاخیر و throughput هر سرویس دارد که میتوانید بدون نوشتن یک کوئری هم اولین نگاه را بیندازید. اگر پیش از این مانیتورینگ سرور با Prometheus و Grafana را روی همین کلاستر راه انداختهاید، همان Grafana را برای داشبوردهای Istio هم میتوانید استفاده کنید.
برای مقایسه، تفاوت وضعیت قبل و بعد از Istio را اینطور میشود خلاصه کرد:
| ویژگی | بدون Istio | با Istio |
|---|---|---|
| رمزنگاری بین سرویسها | باید در کد هر سرویس پیادهسازی شود | mTLS خودکار با PeerAuthentication |
| توزیع ترافیک canary | نیاز به تغییر کد یا ingress سفارشی | وزندهی در VirtualService، بدون تغییر کد |
| مشاهده نرخ خطا بین سرویسها | باید لاگها را از هر سرویس جمع کرد | نقشه زنده در Kiali |
| مصرف منابع | کمتر | هر Pod یک sidecar اضافه دارد |
ردیف آخر جدول را جدی بگیرید: روی یک کلاستر کوچک با نودهای کمحجم، اضافه شدن یک Envoy به هر Pod میتواند منابع آزاد را سریع تمام کند. قبل از فعال کردن sidecar injection روی همه namespaceها، یک بار با kubectl top pods مصرف رم را بعد از تزریق روی یک namespace تست چک کنید.
چه زمانی به Istio نیاز دارید
اگر کل اپلیکیشنتان دو سه سرویس است که مستقیم با هم صحبت میکنند، Istio بیشتر هزینهی عملیاتی اضافه میکند تا فایده. جایی که به درد میخورد وقتی تعداد سرویسها بالا میرود و دیگر کسی در تیم نمیداند دقیقا کدام سرویس به کدام سرویس وابسته است، یا وقتی باید canary release را بدون دست زدن به کد اجرا کنید.
برای این حجم کار، نودهای کلاستر باید منابع آزاد کافی داشته باشند؛ یک سرور مجازی یا سرور اختصاصی آریانت با IPv4 و IPv6 اختصاصی و شبکهی پایدار بین نودها، بستر مناسبی برای یک کلاستر Kubernetes خودمیزبان با Istio فراهم میکند.
برای شروع یا بزرگ کردن کلاستر میتوانید از سرور مجازی ابری آریانت استفاده کنید.
جمعبندی
Istio روی یک کلاستر Kubernetes خودمیزبان سه کار اصلی انجام میدهد: ترافیک بین سرویسها را با Gateway و VirtualService قابل مدیریت میکند، با PeerAuthentication رمزنگاری mTLS را بدون تغییر کد اجباری میکند، و با Kiali نشان میدهد این ترافیک چه شکلی دارد. قبل از فعال کردن آن روی کل کلاستر، اول روی یک namespace تست کنید و مصرف منابع را با چشم خودتان ببینید.
سؤالات متداول
آیا Istio روی یک کلاستر تکنودی هم کار میکند؟ بله، control plane و sidecarها روی یک نود هم بالا میآیند، ولی چون هر Pod یک Envoy اضافه میگیرد، رم مصرفی بیشتر میشود. برای تست و یادگیری مشکلی نیست.
تفاوت istiod با ingress controller معمولی چیست؟ ingress controller فقط ترافیک ورودی از بیرون کلاستر را مدیریت میکند. istiod علاوه بر آن، ترافیک بین Podهای داخل کلاستر را هم کنترل و رمزنگاری میکند.
بعد از فعال کردن STRICT mTLS، سرویسهای قدیمی از کار میافتند؟ اگر sidecar نگرفته باشند، بله ممکن است ارتباطشان قطع شود. به همین دلیل باید اول namespace به namespace تست کنید، نه یکباره روی کل کلاستر.
برای کلاستر Kubernetes خودمیزبان چه نوع سرور لازم است؟ به شبکهی پایدار بین نودها و رم آزاد کافی برای sidecarهای اضافه نیاز دارید؛ یک سرور مجازی یا سرور اختصاصی با منابع قابل ارتقا برای این کار مناسبتر از یک سرور کوچک ثابت است.




