درباره این codelab
1. خوش آمدید
از اینکه به ما در آزمایشگاه کد Istio Multi Cloud Burst توسط Google ملحق شدید متشکریم. این آزمایشگاه کد به تجربه عملی سطح مبتدی با Kubernetes، Node و Go نیاز دارد. آنچه شما نیاز خواهید داشت
|
آنچه خواهید آموخت
- نحوه ایجاد یک خوشه Kubernetes در GKE
- نحوه نصب Istio روی خوشه Kubernetes با Helm
- نحوه نصب Istio Multicluster با Helm
- استقرار یک برنامه وب از منبع به Kubernetes
- نوشتن و اعمال قوانین مسیریابی ترافیک در ایستیو
- متریک پرومتئوس
- تصاویر ظرف را در یک خوشه Kubernetes بسازید و فشار دهید
2. در حال راه اندازی
می توانید این کد لبه را در یکی از موارد زیر دنبال کنید:
- Google Cloud Shell (توصیه می شود) : پوسته درون مرورگر، همراه با ابزارهای نصب شده
- لپ تاپ شما (دستورالعمل های زیر را دنبال کنید)
با Google Cloud Platform شروع کنید
- اگر حساب کاربری GCP ندارید، کارت حساب کاربری رایگان خود را از مربی دریافت کنید.
- به Google Cloud Console بروید و روی «انتخاب پروژه» کلیک کنید:
- "ID" پروژه را در جایی یادداشت کنید ، سپس روی پروژه کلیک کنید تا آن را انتخاب کنید:
گزینه 1: استفاده از Google Cloud Shell (توصیه می شود)
Cloud Shell یک پوسته خط فرمان را در داخل مرورگر شما با ابزارهایی که نیاز دارید نصب کرده و به طور خودکار در حساب Google Cloud Platform شما احراز هویت می شود فراهم می کند. (اگر نمی خواهید این تمرین را در Cloud Shell اجرا کنید، به بخش بعدی بروید.)
به Cloud Console بروید و روی "Activate Cloud Shell" در نوار ابزار بالا سمت راست کلیک کنید:
ابزارها را به Cloud Shell اضافه کنید
-
kubectx
**** را نصب کنید : با دانلود اسکریپت های bash از اینجا در مکانی در $PATH. -
helm
**** را نصب کنید : این دستورالعمل ها را دنبال کنید.
یا این دستورات را اجرا کنید تا هر دو را در ~/.bin
نصب کرده و به $PATH خود اضافه کنید:
mkdir -p ~/.bin && \
cd ~/.bin && \
curl -LO https://raw.githubusercontent.com/ahmetb/kubectx/master/kubectx && \
chmod +x kubectx && \
curl -LO https://raw.githubusercontent.com/ahmetb/kubectx/master/kubens && \
chmod +x kubens && \
curl -LO https://storage.googleapis.com/kubernetes-helm/helm-v2.12.0-linux-amd64.tar.gz && \
tar xzf helm-v2.12.0-linux-amd64.tar.gz && \
rm helm-v2.12.0-linux-amd64.tar.gz && \
mv linux-amd64/helm ./helm && \
rm -r linux-amd64 && \
export PATH=${HOME}/.bin:${PATH}
چند نکته سریع که می تواند استفاده از Cloud Shell را آسان تر کند:
1. پوسته را در یک پنجره جدید جدا کنید: | |
2. استفاده از ویرایشگر فایل: روی نماد مداد در بالا سمت راست کلیک کنید تا ویرایشگر فایل درون مرورگر راه اندازی شود. این برای شما مفید خواهد بود زیرا ما قطعات کد را در فایل ها کپی می کنیم. | |
3. شروع برگه های جدید: اگر به بیش از یک درخواست ترمینال نیاز دارید. | |
4. متن را بزرگتر کنید: اندازه فونت پیش فرض در Cloud Shell ممکن است برای خواندن خیلی کوچک باشد. | Ctrl-+ در Linux/Windows⌘-+ در macOS. |
گزینه 2: لپ تاپ خود را راه اندازی کنید (توصیه نمی شود)
اگر در استفاده از محیط ایستگاه کاری خود نسبت به Cloud Shell احساس راحتی می کنید، ابزارهای زیر را تنظیم کنید:
- نصب
gcloud:
(از پیش نصب شده در Cloud Shell.) دستورالعمل ها را برای نصبgcloud
بر روی پلت فرم خود دنبال کنید . ما از این برای ایجاد یک خوشه Kubernetes استفاده خواهیم کرد. - Kubectl را نصب کنید
kubectl:
(از قبل در Cloud Shell نصب شده است.) دستور زیر را برای نصب اجرا کنید:
gcloud components install kubectl
برای احراز هویت gcloud دستور زیر را اجرا کنید. از شما می خواهد که با حساب Google خود وارد شوید. سپس، پروژه از پیش ساخته شده (در بالا) را به عنوان پروژه پیش فرض انتخاب کنید. (می توانید از پیکربندی منطقه محاسبه صرفنظر کنید):
gcloud init
- Install
curl:
در اکثر سیستمهای Linux/macOS از قبل نصب شده است. احتمالاً قبلاً آن را دارید. در غیر این صورت، نحوه نصب آن را در اینترنت جستجو کنید. -
kubectx
**** را نصب کنید : با دانلود اسکریپت های bash از اینجا در مکانی در $PATH -
helm
**** را نصب کنید : این دستورالعمل ها را دنبال کنید.
3. راه اندازی پروژه GCP
GKE (Google Kubernetes Engine)، GCR (Google Container Registry) و GCB (Google Cloud Build) را در پروژه خود فعال کنید:
gcloud services enable \ cloudapis.googleapis.com \ container.googleapis.com \ containerregistry.googleapis.com \ cloudbuild.googleapis.com
تنظیم متغیرهای محیطی
ما در حین راه اندازی به طور گسترده با پروژه Google Cloud خود کار خواهیم کرد، بیایید یک متغیر محیطی را برای مرجع سریع تنظیم کنیم
export GCLOUD_PROJECT=$(gcloud config get-value project)
ما در طول این کارگاه چند کد و فایل پیکربندی ایجاد خواهیم کرد، پس بیایید یک فهرست پروژه ایجاد کنیم و آن را تغییر دهیم.
mkdir -p src/istio-burst && \ cd src/istio-burst && \ export proj=$(pwd)
4. خوشه Kubernetes "اصلی" را ایجاد کنید
میتوانید به راحتی خوشه Kubernetes مدیریت شده را با Google Kubernetes Engine (GKE) ایجاد کنید.
دستور زیر یک خوشه Kubernetes ایجاد می کند:
- به نام "اولیه"،
- در منطقه us-west1-a،
- آخرین نسخه Kubernetes موجود،
- با 4 گره اولیه
export cluster=primary
export zone=us-west1-a
gcloud container clusters create $cluster --zone $zone --username "admin" \
--cluster-version latest --machine-type "n1-standard-2" \
--image-type "COS" --disk-size "100" \
--scopes "https://www.googleapis.com/auth/compute",\
"https://www.googleapis.com/auth/devstorage.read_only",\
"https://www.googleapis.com/auth/logging.write",\
"https://www.googleapis.com/auth/monitoring",\
"https://www.googleapis.com/auth/servicecontrol",\
"https://www.googleapis.com/auth/service.management.readonly",\
"https://www.googleapis.com/auth/trace.append" \
--num-nodes "4" --network "default" \
--enable-cloud-logging --enable-cloud-monitoring --enable-ip-alias
(ممکن است حدود 5 دقیقه طول بکشد. می توانید خوشه در حال ایجاد را در Cloud Console تماشا کنید.)
پس از ایجاد خوشه Kubernetes، gcloud
kubectl
با اعتبارنامه ها به سمت خوشه پیکربندی می کند.
gcloud container clusters get-credentials $cluster --zone=$zone
اکنون باید بتوانید kubectl
با خوشه جدید خود استفاده کنید.
دستور زیر را اجرا کنید تا گره های Kubernetes خوشه خود را فهرست کنید (آنها باید وضعیت "آماده" را نشان دهند):
kubectl get nodes
نام های Kubeconfig را برای سهولت استفاده تغییر دهید
ما مرتباً بین زمینهها جابهجا میشویم، بنابراین داشتن یک نام مستعار کوتاه برای خوشههایمان مفید است.
این دستور ورودی kubeconfig را که ایجاد کردید به primary
تغییر نام می دهد
kubectx ${cluster}=gke_${GCLOUD_PROJECT}_${zone}_${cluster}
تنظیم مجوزها:
برای استقرار Istio باید یک ادمین کلاستر باشید. این دستور ایمیل مرتبط با حساب Google Cloud شما را به عنوان مدیر کلاستر تنظیم می کند
kubectl create clusterrolebinding cluster-admin-binding \ --clusterrole=cluster-admin \ --user=$(gcloud config get-value core/account)
5. خوشه "burst" را ایجاد کنید
دستور زیر یک خوشه Kubernetes ایجاد می کند:
- به نام "ترکیدن"،
- در منطقه us-west1-a،
- آخرین نسخه Kubernetes موجود،
- با 1 گره اولیه
- مقیاس خودکار تا 5 گره را فعال می کند
export cluster=burst
export zone=us-west1-a
gcloud container clusters create $cluster --zone $zone --username "admin" \
--cluster-version latest --machine-type "n1-standard-2" \
--image-type "COS" --disk-size "100" \
--scopes "https://www.googleapis.com/auth/compute",\
"https://www.googleapis.com/auth/devstorage.read_only",\
"https://www.googleapis.com/auth/logging.write",\
"https://www.googleapis.com/auth/monitoring",\
"https://www.googleapis.com/auth/servicecontrol",\
"https://www.googleapis.com/auth/service.management.readonly",\
"https://www.googleapis.com/auth/trace.append" \
--num-nodes "1" --enable-autoscaling --min-nodes=1 --max-nodes=5 \
--network "default" \
--enable-cloud-logging --enable-cloud-monitoring --enable-ip-alias
(ممکن است حدود 5 دقیقه طول بکشد. می توانید خوشه در حال ایجاد را در Cloud Console تماشا کنید.)
پس از ایجاد خوشه Kubernetes، gcloud
kubectl
با اعتبارنامه ها به سمت خوشه پیکربندی می کند.
gcloud container clusters get-credentials $cluster --zone=$zone
اکنون باید بتوانید kubectl
با خوشه جدید خود استفاده کنید.
دستور زیر را اجرا کنید تا گره های Kubernetes خوشه خود را فهرست کنید (آنها باید وضعیت "آماده" را نشان دهند):
kubectl get nodes
نام های Kubeconfig را برای سهولت استفاده تغییر دهید
این دستور ورودی kubeconfig را که اخیراً ایجاد کردهاید تغییر میدهد تا burst
kubectx ${cluster}=gke_${GCLOUD_PROJECT}_${zone}_${cluster}
تنظیم مجوزها:
برای استقرار Istio Remote باید یک ادمین کلاستر باشید. این دستور ایمیل مرتبط با حساب Google Cloud شما را به عنوان مدیر کلاستر تنظیم می کند
kubectl create clusterrolebinding cluster-admin-binding \
--clusterrole=cluster-admin \
--user=$(gcloud config get-value core/account)
6. قوانین فایروال را اعمال کنید
برای اینکه دو خوشه ما با یکدیگر ارتباط برقرار کنند، باید یک قانون فایروال ایجاد کنیم.
دستورات زیر را اجرا کنید تا یک قانون فایروال در Google Cloud Platform ایجاد کنید که به خوشههای ما امکان برقراری ارتباط را میدهد.
function join_by { local IFS="$1"; shift; echo "$*"; }
ALL_CLUSTER_CIDRS=$(gcloud container clusters list \
--filter="(name=burst OR name=primary) AND zone=$zone" \
--format='value(clusterIpv4Cidr)' | sort | uniq)
ALL_CLUSTER_CIDRS=$(join_by , $(echo "${ALL_CLUSTER_CIDRS}"))
ALL_CLUSTER_NETTAGS=$(gcloud compute instances list \
--filter="(metadata.cluster-name=burst OR metadata.cluster-name=primary) AND metadata.cluster-location=us-west1-a" \
--format='value(tags.items.[0])' | sort | uniq)
ALL_CLUSTER_NETTAGS=$(join_by , $(echo "${ALL_CLUSTER_NETTAGS}"))
gcloud compute firewall-rules create istio-multicluster-test-pods \
--allow=tcp,udp,icmp,esp,ah,sctp \
--direction=INGRESS \
--priority=900 \
--source-ranges="${ALL_CLUSTER_CIDRS}" \
--target-tags="${ALL_CLUSTER_NETTAGS}" --quiet
ما هر دو کلاستر خود را راهاندازی کردهایم و آماده هستیم تا برنامه و ایستیو خود را روی آنها مستقر کنیم!
7. مقدمه ای بر ایستیو
ایستیو چیست؟
ایستیو یک صفحه کنترل مش سرویس است که هدف آن "اتصال، ایمن سازی، کنترل و مشاهده سرویس ها" است. این کار را به روشهای مختلفی انجام میدهد، اما عمدتاً با قرار دادن یک محفظه پراکسی ( Envoy ) در هر یک از Kubernetes Pods مستقر شده شما. کانتینر پروکسی تمام ارتباطات شبکه بین میکروسرویس ها را به صورت پشت سر هم با یک خط مشی همه منظوره و هاب تله متری ( میکسر ) کنترل می کند.
این خطمشیها میتوانند مستقل از استقرار و سرویسهای Kubernetes شما اعمال شوند، به این معنی که اپراتور شبکه میتواند فعالیتهای شبکه را مشاهده کند، خطمشیهای شبکه را محدود کند، هدایت کند یا بازنویسی کند، بدون اینکه برنامههای کاربردی مرتبط را دوباره مستقر کند.
برخی از ویژگی های مدیریت ترافیک پشتیبانی ایستیو عبارتند از:
- کلیدهای مدار
- تقسیم ترافیک مبتنی بر درصد
- بازنویسی URL
- خاتمه TLS
- بررسی های سلامت
- تعادل بار
برای اهداف این کارگاه، ما بر تقسیم ترافیک مبتنی بر درصد تمرکز خواهیم کرد.
شرایط Istio ما با آنها کار خواهیم کرد
سرویس مجازی
VirtualService مجموعه ای از قوانین مسیریابی ترافیک را برای اعمال در هنگام آدرس دهی یک میزبان تعریف می کند.
دروازه
Gateway یک متعادل کننده بار است که در لبه مش کار می کند و اتصالات HTTP/TCP ورودی یا خروجی را دریافت می کند. دروازه ها می توانند پورت ها، پیکربندی های SNI و غیره را مشخص کنند.
قانون مقصد
یک DestinationRule خط مشی هایی را تعریف می کند که برای ترافیک در نظر گرفته شده برای یک سرویس پس از انجام مسیریابی اعمال می شود. آنها پیکربندی را برای متعادل کردن بار، اندازه استخر اتصال از کالسکه کناری و تنظیمات تشخیص بیرون را مشخص می کنند.
چند خوشه ایستیو
ممکن است متوجه شده باشید زمانی که ما دو خوشه خود را ایجاد کردیم، که خوشه primary
ما 4 گره بدون مقیاس خودکار، و خوشه burst
ما 1 گره با مقیاس خودکار تا 5 گره بود.
دو دلیل برای این پیکربندی وجود دارد.
ابتدا می خواهیم یک سناریوی "on-prem" را در Cloud شبیه سازی کنیم. در یک محیط on-prem، به دلیل داشتن زیرساخت ثابت، به خوشههای مقیاس خودکار دسترسی ندارید.
دوم، راه اندازی 4 گره (همانطور که در بالا تعریف شد) حداقل الزامات برای اجرای Istio است. این سوال پیش می آید: اگر Istio به حداقل 4 گره نیاز دارد، چگونه خوشه burst
ما می تواند Istio را با 1 گره اجرا کند؟ پاسخ این است که Istio Multicluster مجموعه بسیار کوچکتری از سرویس های Istio را نصب می کند و با نصب Istio در خوشه اولیه برای بازیابی قوانین خط مشی و انتشار اطلاعات تله متری ارتباط برقرار می کند.
8. نمای کلی معماری برنامه
بررسی اجمالی اجزاء
ما یک برنامه سه لایه را با استفاده از NodeJS و Redis اجرا خواهیم کرد.
کارگر
برنامه کارگر در NodeJS نوشته شده است و به درخواست های دریافتی POST HTTP گوش می دهد، عملیات هش را روی آنها انجام می دهد و اگر یک متغیر محیطی به نام PREFIX
تعریف شده باشد، هش را با آن مقدار آماده می کند. هنگامی که هش محاسبه شد، برنامه نتیجه را در کانال " calculation
" در سرور Redis مشخص شده ارسال می کند.
بعداً از متغیر محیطی PREFIX
برای نشان دادن عملکرد چند خوشه ای استفاده خواهیم کرد.
برای مرجع: اینها بسته هایی هستند که برنامه استفاده می کند.
-
body-parser:
به ما امکان میدهد تا درخواستهای http خود را تجزیه کنیم -
cors:
امکان استفاده از Cross Origin Resource Sharing را می دهد -
dotenv:
تجزیه آسان متغیرهای محیطی -
express:
میزبانی آسان وب سایت -
ioredis:
کتابخانه مشتری برای ارتباط با پایگاه های داده Redis -
morgan:
گزارش ساختاری خوبی را ارائه می دهد
Frontend
ظاهر ما همچنین یک برنامه NodeJS است که یک صفحه وب را با استفاده از express میزبانی می کند. فرکانس ورودی کاربر را می گیرد و درخواست ها را با آن نرخ به برنامه worker
ما ارسال می کند. این برنامه همچنین در پیامهایی در یک کانال Redis به نام " calculation
" مشترک میشود و نتایج را در یک صفحه وب نمایش میدهد.
این برنامه از وابستگی های زیر استفاده می کند.
-
body-parser:
به ما امکان میدهد تا درخواستهای http خود را تجزیه کنیم -
dotenv:
تجزیه آسان متغیرهای محیطی -
express:
میزبانی آسان وب سایت -
ioredis:
کتابخانه مشتری برای ارتباط با پایگاه های داده Redis -
morgan:
سیاهههای مربوط به ساختار خوبی را ارائه می دهد -
request:
امکان ایجاد درخواست های HTTP را فراهم می کند -
socket.io:
امکان ارتباط دو طرفه از صفحه وب به سرور را فراهم می کند
این صفحه وب از Bootstrap برای یک ظاهر طراحی شده استفاده می کند و در هنگام اجرا به شکل زیر است
نمودار معماری
نمودار استقرار
ما برنامه نهایی خود را در دو خوشه ای که ایجاد کردیم، مستقر خواهیم کرد. خوشه primary
همه مؤلفهها ( frontend
، worker
و Redis) روی آن مستقر شده است، اما خوشه burst
فقط برنامه worker
را دارد.
در اینجا نموداری است که این دو خوشه را توصیف می کند. جعبههایی که با رنگ قرمز مشخص شدهاند سرویسهای Kubernetes و آنهایی که به رنگ آبی هستند، Kubernetes Deployments هستند. جعبه های زرد نشان دهنده نصب ما از Istio است.
توجه کنید که چگونه خوشه burst
هنوز یک سرویس برای Redis در آن مستقر شده است، حتی اگر هیچ Deployment برای Redis در خوشه وجود نداشته باشد. ما باید این سرویس را در کلاستر داشته باشیم تا Kubernetes DNS بتواند درخواست را حل کند، اما زمانی که درخواست واقعاً انجام شد، پروکسی Istio درخواست را به استقرار Redis در خوشه primary
تغییر مسیر می دهد.
برنامه نهایی دارای یک Deployment اضافی خواهد بود که در خوشه primary
به نام istiowatcher.
این همان چیزی است که به ما امکان میدهد تا زمانی که ترافیک ما از یک آستانه خاص عبور میکند، ترافیک را بهصورت خودکار به burst
تغییر مسیر دهیم.
9. ایجاد فایل های استقرار برنامه
ما باید مجموعه ای از مانیفست های Kubernetes ایجاد کنیم تا برنامه خود را به کار بگیریم
به دایرکتوری ریشه پروژه تغییر دهید و یک پوشه جدید به نام kubernetes
ایجاد کنید
mkdir ${proj}/kubernetes && cd ${proj}/kubernetes
frontend.yaml بنویسید
با این کار هم یک Kubernetes Deployment و هم سرویس برای دسترسی به تصویر frontend ما ایجاد می شود.
موارد زیر را در frontend.yaml
قرار دهید.
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: frontend-deployment
labels:
app: frontend
spec:
replicas: 1
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
containers:
- name: frontend
image: gcr.io/istio-burst-workshop/frontend
ports:
- containerPort: 8080
readinessProbe:
initialDelaySeconds: 10
httpGet:
path: "/_healthz"
port: 8080
httpHeaders:
- name: "Cookie"
value: "istio_session-id=x-readiness-probe"
livenessProbe:
initialDelaySeconds: 10
httpGet:
path: "/"
port: 8080
httpHeaders:
- name: "Cookie"
value: "istio_session-id=x-liveness-probe"
env:
- name: PORT
value: "8080"
- name: PROCESSOR_URL
value: "http://worker-service"
- name: REDIS_URL
value: "redis-cache-service:6379"
---
apiVersion: v1
kind: Service
metadata:
name: frontend-service
spec:
type: ClusterIP
selector:
app: frontend
ports:
- name: http
port: 80
targetPort: 8080
نکات کلیدی که باید در Deployment
توجه کنید
- پورتی که برنامه روی آن اجرا می شود را
8080
مشخص کرده ایم - ما آدرس کارگر را به عنوان "
http://worker-service
" تنظیم کرده ایم و از Kubernetes ساخته شده در ویژگی DNS برای حل سرویس به دست آمده استفاده خواهیم کرد. - ما آدرس
REDIS_URL
خود را به عنوان "redis-cache-service:6379
" تنظیم کرده ایم و از Kubernetes ساخته شده در ویژگی DNS برای حل آدرس های IP حاصل استفاده خواهیم کرد. - ما همچنین کاوشگرهای
liveness
وreadiness
را روی کانتینر تنظیم کردهایم تا به کوبرنتس در زمان آمادهبودن کانتینر اطلاع دهیم.
worker-service.yaml را بنویسید
ما در حال نوشتن تعریف سرویس Kubernetes در یک فایل جداگانه از تعریف Deployment هستیم، زیرا از این سرویس در چندین خوشه استفاده خواهیم کرد، اما یک Deployment متفاوت برای هر خوشه می نویسیم.
موارد زیر را در worker-service.yaml
درج کنید
apiVersion: v1
kind: Service
metadata:
name: worker-service
spec:
type: ClusterIP
selector:
app: worker
ports:
- name: http
port: 80
targetPort: 8081
worker-primary.yaml را بنویسید
این استقرار worker
خواهد بود که ما به خوشه اولیه فشار خواهیم داد.
موارد زیر را در worker-primary.yaml
وارد کنید.
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: worker-deployment
labels:
app: worker
spec:
replicas: 1
selector:
matchLabels:
app: worker
template:
metadata:
labels:
app: worker
cluster-type: primary-cluster
spec:
containers:
- name: worker
image: gcr.io/istio-burst-workshop/worker
imagePullPolicy: Always
ports:
- containerPort: 8081
readinessProbe:
initialDelaySeconds: 10
httpGet:
path: "/_healthz"
port: 8081
httpHeaders:
- name: "Cookie"
value: "istio_session-id=x-readiness-probe"
livenessProbe:
initialDelaySeconds: 10
httpGet:
path: "/"
port: 8081
httpHeaders:
- name: "Cookie"
value: "istio_session-id=x-liveness-probe"
env:
- name: PORT
value: "8081"
- name: REDIS_URL
value: "redis-cache-service:6379"
توجه داشته باشید که در این مورد، ما از همان الگوی ارائه کاوشگرهای liveness
و readiness
و همچنین مشخص کردن متغیرهای محیطی PORT
و REDIS_URL
برای استفاده برنامه خود پیروی می کنیم.
نکته دیگری که در این استقرار باید به آن توجه کرد، عدم وجود متغیر محیطی PREFIX
است. این بدان معنی است که نتایج محاسبات ما هش های خام خواهد بود (هیچ پیشوندی برای آنها وجود ندارد).
نکته کلیدی نهایی این استقرار، برچسب cluster-type: primary-cluster
است. بعداً هنگامی که مسیریابی ترافیک را در چند کلاستر ایستیو انجام می دهیم از آن استفاده خواهیم کرد
redis.yaml بنویسید
ارتباط از کارگر ما به سمت جلو از طریق یک کانال Redis است و به این ترتیب ما باید یک برنامه Redis را در خوشه خود مستقر کنیم.
موارد زیر را در redis.yaml
قرار دهید
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: redis-cache
spec:
template:
metadata:
labels:
app: redis-cache
spec:
containers:
- name: redis
image: redis:alpine
ports:
- containerPort: 6379
readinessProbe:
periodSeconds: 5
tcpSocket:
port: 6379
livenessProbe:
periodSeconds: 5
tcpSocket:
port: 6379
volumeMounts:
- mountPath: /data
name: redis-data
resources:
limits:
memory: 256Mi
cpu: 125m
requests:
cpu: 70m
memory: 200Mi
volumes:
- name: redis-data
emptyDir: {}
این یک استقرار نیمه استاندارد از یک برنامه Redis است. این یک ظرف بر اساس تصویر redis:alpine
میایستد، پورتهای مناسب را در معرض دید قرار میدهد و محدودیتهای معقولی را برای منابع تعیین میکند.
redis-service.yaml بنویسید
ما به یک سرویس Kubernetes برای ارتباط با برنامه Redis خود نیاز داریم
موارد زیر را در redis-service.yaml
قرار دهید
apiVersion: v1
kind: Service
metadata:
name: redis-cache-service
spec:
type: ClusterIP
selector:
app: redis-cache
ports:
- port: 6379
targetPort: 6379
این سرویس به نام redis-cache-service
را برای دسترسی به Redis Deployment ما ارائه می دهد.
10. برنامه را مستقر کنید
از آنجایی که تصاویر ما به GCR فشار داده شده اند و مانیفست های Kubernetes ما نوشته شده اند، این نکته خوبی برای استقرار برنامه ما و دیدن نحوه عملکرد آن است!
دستورات زیر را برای استقرار برنامه اجرا کنید
- اطمینان حاصل کنید که در خوشه مناسبی هستیم
kubectx primary
- Redis Cache را مستقر کنید
kubectl apply -f redis.yaml
- سرویس Redis را مستقر کنید
kubectl apply -f redis-service.yaml
- استقرار frontend
kubectl apply -f frontend.yaml
- اعزام کارگر
kubectl apply -f worker-primary.yaml
- سرویس کارگر را مستقر کنید
kubectl apply -f worker-service.yaml
ما برنامه خود را در GKE مستقر کرده ایم. تبریک میگم
تست کنید
منتظر بمانید تا پادها آنلاین شوند
kubectl get pods -w
هنگامی که همه پادها "در حال اجرا هستند" Ctrl + C را فشار دهید
NAME READY STATUS RESTARTS AGE frontend-deployment-695d95fbf7-76sd8 1/1 Running 0 2m redis-cache-7475999bf5-nxj8x 1/1 Running 0 2m worker-deployment-5b9cf9956d-g975p 1/1 Running 0 2m
متوجه خواهید شد که ما ظاهر خود را از طریق LoadBalancer افشا نکردیم. دلیلش این است که بعداً از طریق Istio به برنامه دسترسی خواهیم داشت. برای آزمایش اینکه همه چیز آماده و در حال اجرا است، از kubectl port-forward.
دستور زیر را اجرا کنید تا پورت 8080 را در دستگاه محلی (یا Cloud Shell) خود به پورت 8080 که در حال اجرا استقرار frontend
است، ارسال کنید.
kubectl port-forward \
$(kubectl get pods -l app=frontend -o jsonpath='{.items[0].metadata.name}') \
8080:8080
اگر به صورت محلی اجرا می کنید : یک مرورگر وب باز کنید و به http://localhost:8080 بروید
اگر در Cloud Shell در حال اجرا هستید: روی دکمه "Web Preview" کلیک کنید و "Preview on port 8080" را انتخاب کنید.
شما باید قسمت جلویی را ببینید! و اگر عددی را در کادر "فرکانس" وارد کنید، باید شاهد ظاهر شدن هش ها باشید
تبریک؛ همه چیز در حال اجراست!
Ctrl+C
را فشار دهید تا فوروارد پورت متوقف شود.
11. برنامه نصب شده پاکسازی
ما میخواهیم Istio را در کلاستر خود اعمال کنیم و سپس برنامه خود را مجدداً مستقر کنیم، بنابراین اجازه دهید ابتدا برنامه فعلی خود را پاکسازی کنیم.
دستورات زیر را اجرا کنید تا همه Deployments و سرویس هایی که ایجاد کرده اید حذف شوند
-
redis-cache-service
را حذف کنید
kubectl delete -f redis-service.yaml
-
redis
حذف کنید
kubectl delete -f redis.yaml
-
frontend
حذف کنید
kubectl delete -f frontend.yaml
- حذف
worker
kubectl delete -f worker-primary.yaml
- حذف
worker-service
kubectl delete -f worker-service.yaml
12. Istio را روی کلاستر اولیه نصب کنید
ایستیو بگیر
نسخه های ایستیو در گیت هاب میزبانی می شود. دستورات زیر نسخه 1.0.0 istio را دانلود کرده و آن را باز می کند.
- به ریشه پروژه خود تغییر دهید
cd ${proj}
- آرشیو را دانلود کنید
curl -LO https://github.com/istio/istio/releases/download/1.0.0/istio-1.0.0-linux.tar.gz
- بایگانی را استخراج و حذف کنید
tar xzf istio-1.0.0-linux.tar.gz && rm istio-1.0.0-linux.tar.gz
قالب Istio را ایجاد کنید
با اجرای دستور Helm زیر، قالبی برای نصب Istio در کلاستر شما ایجاد می شود.
helm template istio-1.0.0/install/kubernetes/helm/istio \ --name istio --namespace istio-system \ --set prometheus.enabled=true \ --set servicegraph.enabled=true > istio-primary.yaml
این یک فایل به نام istio-primary.yaml
در فهرست فعلی شما ایجاد می کند که شامل تمام تعاریف و مشخصات مورد نیاز برای استقرار و اجرای Istio است.
به دو پارامتر --set
توجه کنید. اینها پشتیبانی Prometheus و ServiceGraph را به سیستم Istio اضافه می کنند. ما بعداً در آزمایشگاه از سرویس Prometheus استفاده خواهیم کرد.
ایستیو را مستقر کنید
برای استقرار istio ابتدا باید فضای نامی به نام istio-system
ایجاد کنیم که استقرارها و سرویسهای Istio بتوانند در آن اجرا شوند.
kubectl create namespace istio-system
و در نهایت فایل istio-primary.yaml
را که با Helm ساختیم اعمال کنید
kubectl apply -f istio-primary.yaml
فضای نام پیشفرض را برچسب بزنید
Istio با تزریق یک سرویس پروکسی sidecar به هر یک از Deployment های شما کار می کند. این کار بر اساس انتخاب انجام میشود، بنابراین باید فضای نام default
خود را با istio-injection=enabled
برچسبگذاری کنیم تا Istio بتواند به طور خودکار سایدکار را برای ما تزریق کند.
kubectl label namespace default istio-injection=enabled
تبریک میگم ما یک کلاستر با Istio آماده و در حال اجرا داریم تا بتوانیم برنامه خود را اجرا کنیم!
13. برنامه ما را با مدیریت ترافیک ایستیو مستقر کنید
فایل های پیکربندی مدیریت ترافیک Istio را ایجاد کنید
Istio مشابه Kubernetes کار می کند زیرا از فایل های yaml برای پیکربندی استفاده می کند. در این راستا، ما باید مجموعهای از فایلها را ایجاد کنیم که به Istio بگوییم چگونه ترافیک ما را در معرض دید قرار دهد و مسیریابی کند.
یک دایرکتوری به نام istio-manifests
ایجاد کنید و آن را تغییر دهید
mkdir ${proj}/istio-manifests && cd ${proj}/istio-manifests
frontend-gateway.yaml را بنویسید
این فایل خوشه Kubernetes ما را به روشی شبیه به GKE LoadBalancer نشان می دهد و تمام ترافیک ورودی را به سرویس frontend ما هدایت می کند.
یک فایل به نام frontend-gateway.yaml
ایجاد کنید و موارد زیر را وارد کنید.
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: frontend-gateway
spec:
selector:
istio: ingressgateway # use Istio default gateway implementation
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: frontend-ingress-virtual-service
spec:
hosts:
- "*"
gateways:
- frontend-gateway
http:
- route:
- destination:
host: frontend-service
port:
number: 80
redis-virtualservice.yaml را بنویسید
یک فایل با نام redis-virtualservice.yaml
ایجاد کنید و موارد زیر را وارد کنید
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: redis-virtual-service
spec:
hosts:
- redis-cache-service
gateways:
- mesh
tcp:
- route:
- destination:
host: redis-cache-service.default.svc.cluster.local
worker-virtualservice.yaml را بنویسید
یک فایل با نام worker-virtualservice.yaml
ایجاد کنید و موارد زیر را وارد کنید
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: worker-virtual-service
spec:
hosts:
- worker-service
gateways:
- mesh
http:
- route:
- destination:
host: worker-service.default.svc.cluster.local
port:
number: 80
سیاست های مدیریت ترافیک Istio را اجرا کنید
استقرار خطمشیهای Istio مانند سایر منابع Kubernetes با kubectl apply
انجام میشود.
- دروازه ما را اعمال کنید
kubectl apply -f frontend-gateway.yaml
- Redis VirtualService ما را اعمال کنید
kubectl apply -f redis-virtualservice.yaml
- از Worker VirtualService ما استفاده کنید
kubectl apply -f worker-virtualservice.yaml
استقرار برنامه
- به دایرکتوری
kubernetes
ما برگردید
cd ${proj}/kubernetes
- Redis Cache را مستقر کنید
kubectl apply -f redis.yaml
- سرویس Redis را مستقر کنید
kubectl apply -f redis-service.yaml
- استقرار frontend
kubectl apply -f frontend.yaml
- اعزام کارگر
kubectl apply -f worker-primary.yaml
- سرویس کارگر را مستقر کنید
kubectl apply -f worker-service.yaml
تأیید کنید
در این مرحله، ما برنامه خود را مجدداً در یک خوشه با خطمشیهای ایستیو و مدیریت ترافیک مستقر کردهایم.
بیایید منتظر باشیم تا همه بارهای کاری ما آنلاین شود
وقتی همه آنها آنلاین شدند، IngressGateway را که ما در frontend-ingressgateway.yaml
پیکربندی کرده ایم دریافت کنید.
$ kubectl -n istio-system get svc istio-ingressgateway NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE istio-ingressgateway LoadBalancer 10.36.3.112 35.199.158.10 80:31380/TCP,
یا به آدرس <EXTERNAL-IP> مراجعه کنید یا آن را بچرخانید و باید قسمت جلویی را ببینید!
$ curl 35.199.158.10 <!doctype html> <html> <head> <title>String Hashr</title> <!-- Bootstrap --> ...
14. Istio On "burst" Cluster را نصب کنید
ما زمان زیادی را صرف راه اندازی و استقرار در خوشه primary
خود کرده ایم، اما یک خوشه کامل دیگر برای استقرار داریم!
در این بخش باید متغیرهای پیکربندی را در هر دو خوشه خود بگیریم، بنابراین به این نکته توجه کنید که برای هر دستور به کدام خوشه اشاره می کنیم.
Istio Remote Manifest را ایجاد کنید
درست مانند زمانی که ما Istio را در خوشه primary
مستقر کردیم، از Helm برای الگوبرداری از استقرار istio remote در خوشه burst
استفاده می کنیم. قبل از اینکه بتوانیم این کار را انجام دهیم، باید اطلاعاتی در مورد خوشه primary
خود به دست آوریم
اطلاعات خوشه اولیه را جمع آوری کنید
تغییر به خوشه primary
kubectx primary
دستورات زیر آدرس های IP پادهای مختلف در خوشه اولیه را بازیابی می کند. اینها توسط Istio Remote برای برقراری ارتباط مجدد با خوشه اولیه استفاده می شوند.
export PILOT_POD_IP=$(kubectl -n istio-system get pod -l istio=pilot -o jsonpath='{.items[0].status.podIP}')
export POLICY_POD_IP=$(kubectl -n istio-system get pod -l istio-mixer-type=policy -o jsonpath='{.items[0].status.podIP}')
export STATSD_POD_IP=$(kubectl -n istio-system get pod -l istio=statsd-prom-bridge -o jsonpath='{.items[0].status.podIP}')
export TELEMETRY_POD_IP=$(kubectl -n istio-system get pod -l istio-mixer-type=telemetry -o jsonpath='{.items[0].status.podIP}')
export ZIPKIN_POD_IP=$(kubectl -n istio-system get pod -l app=jaeger -o jsonpath='{range .items[*]}{.status.podIP}{end}')
ایجاد قالب از راه دور
اکنون helm
برای ایجاد فایلی به نام istio-remote-burst.yaml
استفاده می کنیم که سپس می توانیم آن را در خوشه burst
مستقر کنیم.
به ریشه پروژه تغییر دهید
cd $proj
helm template istio-1.0.0/install/kubernetes/helm/istio-remote --namespace istio-system \ --name istio-remote \ --set global.remotePilotAddress=${PILOT_POD_IP} \ --set global.remotePolicyAddress=${POLICY_POD_IP} \ --set global.remoteTelemetryAddress=${TELEMETRY_POD_IP} \ --set global.proxy.envoyStatsd.enabled=true \ --set global.proxy.envoyStatsd.host=${STATSD_POD_IP} \ --set global.remoteZipkinAddress=${ZIPKIN_POD_IP} > istio-remote-burst.yaml
Istio Remote را روی خوشه انفجاری نصب کنید
برای نصب ایستیو روی خوشه burst
خود، باید همان مراحلی را که هنگام نصب روی خوشه primary
انجام دادیم، دنبال کنیم، اما به جای آن باید از فایل istio-remote-burst.yaml
استفاده کنیم.
kubecontext را به burst تغییر دهید
kubectx burst
فضای نام istio-system ایجاد کنید
kubectl create ns istio-system
istio-burst.yaml را اعمال کنید
kubectl apply -f istio-remote-burst.yaml
فضای نام پیش فرض را برچسب بزنید
یک بار دیگر، باید فضای نام default
را برچسب گذاری کنیم تا پروکسی به طور خودکار تزریق شود.
kubectl label namespace default istio-injection=enabled
تبریک میگم در این مرحله ما Istio Remote را روی خوشه burst
راه اندازی کرده ایم. با این حال، در این مرحله، خوشه ها هنوز قادر به برقراری ارتباط نیستند. ما باید یک فایل kubeconfig برای خوشه burst
ایجاد کنیم که بتوانیم آن را در خوشه primary
مستقر کنیم تا آنها را به هم پیوند دهیم.
kubeconfig را برای خوشه "burst" ایجاد کنید
تغییر به خوشه انفجاری
kubectx burst
تنظیم محیط
ما باید اطلاعاتی در مورد خوشه جمع آوری کنیم تا یک فایل kubeconfig
برای آن ایجاد کنیم.
- نام خوشه را دریافت کنید
CLUSTER_NAME=$(kubectl config view --minify=true -o "jsonpath={.clusters[].name}")
- نام سرور کلاستر را دریافت کنید
SERVER=$(kubectl config view --minify=true -o "jsonpath={.clusters[].cluster.server}")
- نام راز حساب
istio-multi
Service Certificate Authority را دریافت کنید
SECRET_NAME=$(kubectl get sa istio-multi -n istio-system -o jsonpath='{.secrets[].name}')
- اطلاعات مرجع صدور گواهی را که در راز قبلی ذخیره شده است دریافت کنید
CA_DATA=$(kubectl get secret ${SECRET_NAME} -n istio-system -o "jsonpath={.data['ca\.crt']}")
- توکن ذخیره شده در راز قبلی را دریافت کنید
TOKEN=$(kubectl get secret ${SECRET_NAME} -n istio-system -o "jsonpath={.data['token']}" | base64 --decode)
فایل kubeconfig بسازید
با تنظیم همه آن متغیرهای محیطی، باید فایل kubeconfig خود را ایجاد کنیم
cat <<EOF > burst-kubeconfig apiVersion: v1 clusters: - cluster: certificate-authority-data: ${CA_DATA} server: ${SERVER} name: ${CLUSTER_NAME} contexts: - context: cluster: ${CLUSTER_NAME} user: ${CLUSTER_NAME} name: ${CLUSTER_NAME} current-context: ${CLUSTER_NAME} kind: Config preferences: {} users: - name: ${CLUSTER_NAME} user: token: ${TOKEN} EOF
با این کار یک فایل جدید به نام burst-kubeconfig
در فهرست فعلی شما ایجاد می شود که می تواند توسط خوشه primary
برای احراز هویت و مدیریت خوشه burst
استفاده شود.
به خوشه اولیه برگردید
kubectx primary
با ایجاد یک راز و برچسب گذاری آن، kubeconfig را برای "burst" اعمال کنید
kubectl create secret generic burst-kubeconfig --from-file burst-kubeconfig -n istio-system
راز را برچسب بزنید تا ایستیو بداند که از آن برای احراز هویت چند خوشه ای استفاده کند
kubectl label secret burst-kubeconfig istio/multiCluster=true -n istio-system
تبریک میگم ما هر دو خوشه را احراز هویت کرده ایم و از طریق Istio Multicluster با یکدیگر در ارتباط هستیم. بیایید برنامه Cross-Cluster خود را مستقر کنیم
15. استقرار یک برنامه Cross-Cluster
ایجاد استقرار
به دایرکتوری kubernetes
تغییر دهید
cd ${proj}/kubernetes
ایجاد استقرار کارگر برای خوشه "burst": worker-burst.yaml
یک فایل با نام worker-burst.yaml
ایجاد کنید و موارد زیر را در آن قرار دهید:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: worker-deployment
labels:
app: worker
spec:
replicas: 1
selector:
matchLabels:
app: worker
template:
metadata:
labels:
app: worker
cluster-type: burst-cluster
spec:
containers:
- name: worker
image: gcr.io/istio-burst-workshop/worker
imagePullPolicy: Always
ports:
- containerPort: 8081
readinessProbe:
initialDelaySeconds: 10
httpGet:
path: "/_healthz"
port: 8081
httpHeaders:
- name: "Cookie"
value: "istio_session-id=x-readiness-probe"
livenessProbe:
initialDelaySeconds: 10
httpGet:
path: "/"
port: 8081
httpHeaders:
- name: "Cookie"
value: "istio_session-id=x-liveness-probe"
env:
- name: PORT
value: "8081"
- name: REDIS_URL
value: "redis-cache-service:6379"
- name: PREFIX
value: "bursty-"
توجه کنید که چگونه این تقریباً مشابه worker-primary.yaml است که قبلاً ایجاد کردیم. دو تفاوت کلیدی وجود دارد.
اولین تفاوت کلیدی این است که ما متغیر محیطی PREFIX
با مقدار " bursty-
" اضافه کرده ایم.
env:
- name: PORT
value: "8081"
- name: REDIS_URL
value: "redis-cache-service:6379"
- name: PREFIX
value: "bursty-"
این به این معنی است که کارگر ما در خوشه burst
تمام هشهایی را که ارسال میکند با " bursty-
" پیشوند میگذارد.
دومین تفاوت کلیدی این است که ما برچسب cluster-type
در این استقرار را از primary-cluster
به burst-cluster
تغییر داده ایم.
labels:
app: worker
cluster-type: burst-cluster
بعداً وقتی VirtualService خود را بهروزرسانی میکنیم، از این برچسب استفاده خواهیم کرد.
خدمات ایستیو را اصلاح کنید
در حال حاضر خدمات Istio ما از هر دو استقرار ما استفاده نمی کنند. 100٪ از ترافیک ما به خوشه "اصلی" هدایت می شود. بیایید آن را تغییر دهیم.
به فهرست راهنمای ما istio-manifests
تغییر دهید
cd ${proj}/istio-manifests
worker-virtualservice.yaml را ویرایش کنید تا DestinationRules را نیز شامل شود
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: worker-virtual-service
spec:
hosts:
- worker-service
gateways:
- mesh
http:
- route:
- destination:
host: worker-service.default.svc.cluster.local
subset: primary
port:
number: 80
weight: 50
- destination:
host: worker-service.default.svc.cluster.local
subset: burst
port:
number: 80
weight: 50
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: worker-destination-rule
spec:
host: worker-service
trafficPolicy:
loadBalancer:
simple: RANDOM
subsets:
- name: primary
labels:
cluster-type: primary-cluster
- name: burst
labels:
cluster-type: burst-cluster
می توانید ببینید که ما مقصد دومی را به VirtualService خود اضافه کرده ایم. همچنان به همان میزبان ارجاع می دهد ( worker-service.default.svc.cluster.local)
، اما 50% ترافیک به زیر مجموعه primary
و 50% دیگر به زیر مجموعه burst
هدایت می شود.
ما زیرمجموعه primary
را بهعنوان پیادهسازیهایی تعریف کردهایم که دارای برچسب cluster-type: primary-cluster
و زیر مجموعه burst
، توسعههایی هستند که دارای برچسب cluster-type: burst-cluster
.
این به طور موثر ترافیک ما را 50/50 بین دو خوشه تقسیم می کند.
به Cluster مستقر شود
برای burst cluster، redis-service.yaml را مستقر کنید
به burst
kubeconfig تغییر دهید
kubectx burst
به ریشه پروژه ما تغییر دهید
cd ${proj}
سپس مستقر کنید
redis-service.yaml را در خوشه burst مستقر کنید
kubectl apply -f kubernetes/redis-service.yaml
worker-burst.yaml را در خوشه burst مستقر کنید
kubectl apply -f kubernetes/worker-burst.yaml
worker-service.yaml را در خوشه burst مستقر کنید
kubectl apply -f kubernetes/worker-service.yaml
Istio VirtualServices را اعمال کنید
به kubeconfig primary
تغییر دهید
kubectx primary
سپس Deploy
kubectl apply -f istio-manifests/worker-virtualservice.yaml
تایید کنید کار می کند
برای تأیید کارکرد آن، به نقطه ورود Istio خود بروید و متوجه شوید که چگونه حدود 50٪ از هش ها با "burst-" پیشوند شده اند.
این به این معنی است که ما با موفقیت در حال صحبت کردن در میان خوشهای هستیم! سعی کنید وزن سرویس های مختلف را تغییر دهید و فایل worker-virtualservice.yaml
را اعمال کنید. این یک راه عالی برای متعادل کردن ترافیک بین خوشهها است، اما اگر بتوانیم آن را به صورت خودکار انجام دهیم، چه؟
16. استفاده از متریک پرومتئوس
مقدمه ای بر پرومتئوس
Prometheus ، یک جعبه ابزار مانیتورینگ و هشدار سیستم منبع باز است که در ابتدا در SoundCloud ساخته شد. این یک مدل داده چند بعدی با دادههای سری زمانی که با نام متریک و جفتهای کلید/مقدار شناسایی میشوند، حفظ میکند.
برای مرجع، در اینجا نمودار معماری پرومتئوس آمده است:
ایستیو، هنگامی که با Prometheus مستقر می شود، به طور خودکار معیارهای مختلف را به سرور Prometheus گزارش می دهد. ما می توانیم از این معیارها برای مدیریت خوشه های خود در پرواز استفاده کنیم.
کاوش معیارهای پرومتئوس ما
برای شروع، باید Prometheus Deployment را افشا کنیم.
به برگه Workloads در GKE بروید، به حجم کاری «prometheus» بروید.
هنگامی که جزئیات استقرار را مشاهده کردید، به Actions -> Expose بروید.
انتقال به پورت 9090
را انتخاب کنید و "Load balancer" را تایپ کنید
و "Expose" را انتخاب کنید
این یک سرویس در یک آدرس IP در دسترس عموم ایجاد می کند که می توانیم از آن برای کاوش معیارهای Prometheus خود استفاده کنیم
منتظر بمانید تا نقطه پایانی عملیاتی شود و یکبار روی آدرس IP در کنار "External endpoints" کلیک کنید.
اکنون باید به رابط کاربری Prometheus نگاه کنید.
پرومتئوس معیارهای کافی برای تبدیل شدن به کارگاه خود را ارائه می دهد. در حال حاضر، ما با بررسی متریک istio_requests_total
شروع خواهیم کرد.
اجرای آن پرس و جو دسته ای از داده ها را برمی گرداند. این معیارها در مورد تمام درخواست هایی است که از طریق مش سرویس ایستیو می گذرند، و این بسیار است! ما عبارت خود را تغییر می دهیم تا به آنچه واقعاً به آن علاقه داریم فیلتر شود:
درخواستهایی که در آن سرویس مقصد worker-service.default.svc.cluster.local
است و منبع آن frontend-deployment
محدود به 15 ثانیه گذشته است.
آن پرس و جو به نظر می رسد:
istio_requests_total{reporter="destination",
destination_service="worker-service.default.svc.cluster.local",
source_workload="frontend-deployment"}[15s]
و مجموعه ای بسیار قابل مدیریت از داده ها را برای کار به ما می دهد
اما هنوز کمی متراکم است. ما می خواهیم درخواست ها را در هر ثانیه بدانیم، نه همه درخواست ها را.
برای بدست آوردن آن، می توانیم از تابع rate
داخلی استفاده کنیم
rate(istio_requests_total{reporter="destination",
destination_service="worker-service.default.svc.cluster.local",
source_workload="frontend-deployment"}[15s])
این ما را نزدیکتر میکند، اما باید این معیارها را کمی بیشتر به یک گروه منطقی کاهش دهیم.
برای این کار میتوانیم sum
و by
کلمات کلیدی برای گروهبندی و جمعبندی نتایج خود استفاده کنیم
sum(rate(istio_requests_total{reporter="destination",
destination_service="worker-service.default.svc.cluster.local",
source_workload="frontend-deployment"}[15s])) by (source_workload,
source_app, destination_service)
کامل! ما می توانیم معیارهای دقیق مورد نیاز خود را از Prometheus بدست آوریم.
آخرین درخواست پرومتئوس ما
با همه چیزهایی که آموختیم، آخرین پرسشی که باید از پرومتئوس بپرسیم این است
sum(rate(istio_requests_total{reporter="destination",
destination_service="worker-service.default.svc.cluster.local",
source_workload="frontend-deployment"}[15s])) by (source_workload,
source_app, destination_service)
اکنون میتوانیم از HTTP API آنها برای دریافت متریک استفاده کنیم.
ما میتوانیم با درخواست http GET مانند آن، api آنها را با کوئری خود جویا شویم. <prometheus-ip-here> را جایگزین کنید
curl http://<prometheus-ip-here>/api/v1/query?query=sum\(rate\(istio_requests_total%7Breporter%3D%22destination%22%2C%0Adestination_service%3D%22worker-service.default.svc.cluster.local%22%2C%0Asource_workload%3D%22frontend-deployment%22%7D%5B15s%5D\)\)%20by%20\(source_workload%2C%0Asource_app%2C%20destination_service\)
در اینجا یک نمونه پاسخ آمده است:
{
"status": "success",
"data": {
"resultType": "vector",
"result": [
{
"metric": {
"destination_service": "worker-service.default.svc.cluster.local",
"source_app": "frontend",
"source_workload": "frontend-deployment"
},
"value": [
1544404907.503,
"18.892886390062788"
]
}
]
}
}
اکنون میتوانیم مقدار متریک خود را از JSON استخراج کنیم
پاکسازی
ما باید سرویسی را که برای افشای پرومته استفاده کردیم حذف کنیم. در Google Cloud Console، به بالای سرویسی که ایجاد کردیم بروید و روی «Delete» کلیک کنید.
مراحل بعدی:
با یافتن راهی برای کشف اینکه چگونه ترافیک در خوشه حرکت می کند و با چه سرعتی، گام بعدی ما این است که یک باینری کوچک بنویسیم که به طور دوره ای پرومتئوس را پرس و جو کند، و اگر درخواست ها در هر ثانیه به worker
بالاتر از یک آستانه خاص باشد، اعمال می شود. وزن های مختلف مقصد در سرویس مجازی کارگر ما برای ارسال تمام ترافیک به خوشه burst
. هنگامی که درخواستها در ثانیه به زیر آستانه پایینتر میرسند، همه ترافیک را به primary
بازگردانید.
17. یک Cross Cluster Burst ایجاد کنید
راه اندازی
تمام ترافیک برای worker-service را روی خوشه اصلی تنظیم کنید
ما تمام ترافیکی را که برای worker-service
به سمت خوشه primary
هدایت میشود، وضعیت «پیشفرض» برنامهمان در نظر میگیریم.
$proj/istio-manifests/worker-virtualservice.yaml
را به شکل زیر ویرایش کنید
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: worker-virtual-service
spec:
hosts:
- worker-service
gateways:
- mesh
http:
- route:
- destination:
host: worker-service.default.svc.cluster.local
subset: primary
port:
number: 80
weight: 100
- destination:
host: worker-service.default.svc.cluster.local
subset: burst
port:
number: 80
weight: 0
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: worker-destination-rule
spec:
host: worker-service
trafficPolicy:
loadBalancer:
simple: RANDOM
subsets:
- name: primary
labels:
cluster-type: primary-cluster
- name: burst
labels:
cluster-type: burst-cluster
مطمئن شوید که به خوشه primary
متصل هستید
kubectx primary
istio-manifests/worker-virtualservice.yaml را اعمال کنید
kubectl apply -f istio-manifests/worker-virtualservice.yaml
istiowacher daemon را بنویسید
ما از Go برای نوشتن این سرویس برای سرعت و قابلیت حمل آن استفاده خواهیم کرد. جریان کلی برنامه شروع به کار خواهد بود و هر ثانیه، درخواست پرومته،
یک دایرکتوری جدید در src به نام istiowatcher بسازید
mkdir -p ${proj}/src/istiowatcher && cd ${proj}/src/istiowatcher
ما istioctl
از داخل ظرف خود فراخوانی می کنیم تا صفحه کنترل Istio را از داخل خوشه دستکاری کنیم.
istiowatcher.go را بنویسید
یک فایل در آن دایرکتوری به نام istiowatcher.go
بسازید و موارد زیر را در آن قرار دهید
package main
import (
"github.com/tidwall/gjson"
"io/ioutil"
"log"
"net/http"
"os/exec"
"time"
)
func main() {
//These are in requests per second
var targetLow float64 = 10
var targetHigh float64 = 15
// This is for the ticker in milliseconds
ticker := time.NewTicker(1000 * time.Millisecond)
isBurst := false
// Our prometheus query
reqQuery := `/api/v1/query?query=sum(rate(istio_requests_total{reporter="destination",destination_service="worker-service.default.svc.cluster.local",source_workload="frontend-deployment"}[15s]))by(source_workload,source_app,destination_service)`
for t := range ticker.C {
log.Printf("Checking Prometheus at %v", t)
// Check prometheus
// Note that b/c we are querying over the past 5 minutes, we are getting a very SLOW ramp of our reqs/second
// If we wanted this to be a little "snappier" we can scale it down to say 30s
resp, err := http.Get("http://prometheus.istio-system.svc.cluster.local:9090" + reqQuery)
if err != nil {
log.Printf("Error: %v", err)
continue
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
val := gjson.Get(string(body), "data.result.0.value.1")
log.Printf("Value: %v", val)
currentReqPerSecond := val.Float()
log.Printf("Reqs per second %f", currentReqPerSecond)
if currentReqPerSecond > targetHigh && !isBurst {
applyIstio("burst.yaml")
log.Println("Entering burst mode")
isBurst = true
} else if currentReqPerSecond < targetLow && isBurst {
applyIstio("natural.yaml")
log.Println("Returning to natural state.")
isBurst = false
}
}
}
func applyIstio(filename string) {
cmd := exec.Command("istioctl", "replace", "-f", filename)
if err := cmd.Run(); err != nil {
log.Printf("Error hit applying istio manifests: %v", err)
}
}
Dockerfile را بنویسید
یک فایل جدید به نام Dockerfile
ایجاد کنید و موارد زیر را در آن قرار دهید.
FROM golang:1.11.2-stretch as base
FROM base as builder
WORKDIR /workdir
RUN curl -LO https://github.com/istio/istio/releases/download/1.0.0/istio-1.0.0-linux.tar.gz
RUN tar xzf istio-1.0.0-linux.tar.gz
RUN cp istio-1.0.0/bin/istioctl ./istioctl
FROM base
WORKDIR /go/src/istiowatcher
COPY . .
COPY --from=builder /workdir/istioctl /usr/local/bin/istioctl
RUN go get -d -v ./...
RUN go install -v ./...
CMD ["istiowatcher"]
این Dockerfile چند مرحله ای نسخه 1.0.0 ایستیو را در مرحله اول دانلود و استخراج می کند. مرحله دوم همه چیز را از دایرکتوری ما در تصویر کپی می کند، سپس istioctl
از مرحله ساخت به /usr/local/bin
کپی می کند (بنابراین می تواند توسط برنامه ما فراخوانی شود)، وابستگی ها را دریافت می کند، کد را کامپایل می کند و CMD
را تنظیم می کند. " istiowatcher
"
burst.yaml را بنویسید
این همان فایلی است که istiowatcher
زمانی اعمال میشود که درخواستها/ثانیه به worker
از frontend
از 15 بیشتر شود.
یک فایل جدید با نام burst.yaml
ایجاد کنید و موارد زیر را در آن قرار دهید.
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: worker-virtual-service
spec:
hosts:
- worker-service
gateways:
- mesh
http:
- route:
- destination:
host: worker-service.default.svc.cluster.local
subset: primary
port:
number: 80
weight: 0
- destination:
host: worker-service.default.svc.cluster.local
subset: burst
port:
number: 80
weight: 100
natural.yaml بنویسید
زمانی که درخواستها/ثانیه از frontend
به worker
به زیر 10 میرسد، این حالت "طبیعی" است که به آن باز میگردیم. در این حالت، 100٪ ترافیک به سمت خوشه primary
هدایت میشود.
یک فایل جدید با نام natural.yaml
ایجاد کنید و موارد زیر را در آن قرار دهید
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: worker-virtual-service
spec:
hosts:
- worker-service
gateways:
- mesh
http:
- route:
- destination:
host: worker-service.default.svc.cluster.local
subset: primary
port:
number: 80
weight: 100
- destination:
host: worker-service.default.svc.cluster.local
subset: burst
port:
number: 80
weight: 0
ساخت و فشار istiowacher
برای ارسال دایرکتوری فعلی به Google Could Build (GCB)، که تصویر را در GCR ساخته و برچسب گذاری می کند، موارد زیر را اجرا کنید.
gcloud builds submit -t gcr.io/${GCLOUD_PROJECT}/istiowatcher
istiowacher را مستقر کنید
به دایرکتوری kubernetes
ما تغییر دهید
cd ${proj}/kubernetes/
یک فایل استقرار بنویسید: istiowatcher.yaml
یک فایل با نام istiowatcher.yaml ایجاد کنید و موارد زیر را وارد کنید (<your-project-id> را جایگزین کنید).
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: istiowatcher-deployment
labels:
app: istiowatcher
spec:
replicas: 1
selector:
matchLabels:
app: istiowatcher
template:
metadata:
labels:
app: istiowatcher
spec:
serviceAccountName: istio-pilot-service-account
automountServiceAccountToken: true
containers:
- name: istiowatcher
image: gcr.io/<your-project-id>/istiowatcher
imagePullPolicy: Always
مستقر کنید
مطمئن شوید که در کلاستر اولیه اجرا میشویم
kubectx primary
istiowatcher.yaml
در فضای نام istio-system
قرار دهید
kubectl apply -n istio-system -f istiowatcher.yaml
نکته مهم، دستورات serviceAccountName
و automountServiceAccountToken
در yaml است. این به ما اعتبار مورد نیاز برای اجرای istioctl
از داخل خوشه را می دهد.
ما همچنین باید این را در فضای نام istio-system
مستقر کنیم تا اطمینان حاصل کنیم که اعتبار istio-pilot-service-account
داریم. (در فضای نام default
وجود ندارد).
تماشا کنید که ترافیک به طور خودکار تغییر می کند!
حالا برای لحظه جادویی! بیایید به قسمت جلویی خود برویم و req/second را به 20 برسانیم
توجه داشته باشید که چند ثانیه طول می کشد، اما ما آن را افزایش می دهیم و همه هش های ما پیشوند "bursty-" دارند!
این به این دلیل است که ما در حال نمونه برداری از پرومته در محدوده 15s
هستیم که باعث می شود زمان پاسخ ما کمی تاخیر داشته باشد. اگر میخواستیم باند خیلی محکمتری داشته باشیم، میتوانیم پرس و جو خود را به prometheus تغییر دهیم تا 5s.
18. بعدش چی؟
پاکسازی
اگر از حساب موقتی که برای این کارگاه ارائه شده استفاده می کنید، نیازی به پاکسازی ندارید.
میتوانید خوشههای Kubernetes، قانون فایروال و تصاویر موجود در GCR را حذف کنید
gcloud container clusters delete primary --zone=us-west1-a
gcloud container clusters delete burst --zone=us-west1-a
gcloud compute firewall-rules delete istio-multicluster-test-pods
gcloud container images delete gcr.io/$GCLOUD_PROJECT/istiowatcher
رو به جلو
- در چند سخنرانی ایستیو شرکت کنید!
- دریافت گواهی: برنامه بعدی خود را با Kubernetes + Istio بسازید
- یادداشت اصلی: Kubernetes، Istio، Knative: The New Open Cloud Stack - آپارنا سینها، مدیر محصول گروه برای Kubernetes، Google
- آموزش: استفاده از Istio - Lee Calcote & Girish Ranganathan، SolarWinds
- ایستیو - نمای بسته - مت ترنر، تتریت
- آیا Istio نسل بعدی فایروال نسل بعدی است که تا به حال ایجاد شده است؟ - جان مورلو، تویستلاک
- مستندات ایستیو را بخوانید
- به گروه های کاری ایستیو بپیوندید
- IstioMesh@ را در توییتر دنبال کنید