ইস্টিও মাল্টিক্লাস্টার ব্যবহার করে "Burst" ক্লাস্টারের মধ্যে কাজের চাপ

১. স্বাগতম

গুগলের Istio Multi Cloud Burst কোডল্যাবে আমাদের সাথে যোগ দেওয়ার জন্য ধন্যবাদ। এই কোডল্যাবটির জন্য Kubernetes, Node এবং Go-তে প্রাথমিক স্তরের ব্যবহারিক অভিজ্ঞতা প্রয়োজন।

আপনার যা যা প্রয়োজন হবে

  • গুগল ক্লাউড প্ল্যাটফর্ম অ্যাকাউন্ট (আপনার বিদ্যমান অ্যাকাউন্ট ব্যবহার করুন, অথবা আমরা বিনামূল্যে অ্যাকাউন্ট দেব)
  • আপনার ল্যাপটপে 'kubectl', 'gcloud' ইত্যাদি ইনস্টল করুন অথবা আপনি গুগল ক্লাউড শেল ব্যবহার করতে পারেন।

আপনি যা শিখবেন

  • GKE-তে কীভাবে একটি Kubernetes ক্লাস্টার তৈরি করবেন
  • Helm ব্যবহার করে Kubernetes ক্লাস্টারে Istio কীভাবে ইনস্টল করবেন
  • হেলম ব্যবহার করে কীভাবে ইস্তিও মাল্টিক্লাস্টার ইনস্টল করবেন
  • সোর্স থেকে কুবারনেটিসে একটি ওয়েব অ্যাপ্লিকেশন স্থাপন করা
  • Istio-তে ট্র্যাফিক রাউটিং নিয়ম লেখা এবং প্রয়োগ করা
  • প্রমিথিউস মেট্রিক্স
  • কুবারনেটিস ক্লাস্টারের ভিতরে কন্টেইনার ইমেজ তৈরি এবং পুশ করুন

২. প্রস্তুতি গ্রহণ

আপনি এই কোডল্যাবটি নিম্নলিখিত যেকোনো একটিতে অনুসরণ করতে পারেন:

  • গুগল ক্লাউড শেল (প্রস্তাবিত) : ব্রাউজারের মধ্যেই ব্যবহারযোগ্য শেল, এতে প্রয়োজনীয় টুলস আগে থেকেই ইনস্টল করা থাকে।
  • আপনার ল্যাপটপ (নিচের নির্দেশাবলী অনুসরণ করুন)

গুগল ক্লাউড প্ল্যাটফর্ম দিয়ে শুরু করুন

  1. আপনার যদি GCP অ্যাকাউন্ট না থাকে, তাহলে প্রশিক্ষকের কাছ থেকে আপনার বিনামূল্যের ইউজার অ্যাকাউন্ট কার্ডটি সংগ্রহ করুন।
  2. গুগল ক্লাউড কনসোলে যান এবং 'একটি প্রজেক্ট নির্বাচন করুন'-এ ক্লিক করুন: 5c2d9bf74c78f7e4.png
  3. প্রজেক্টটির 'আইডি' কোথাও লিখে রাখুন , তারপর প্রজেক্টটি বেছে নিতে সেটির উপর ক্লিক করুন: ecc5e8e97bfa6559.png

ক্লাউড শেল আপনার ব্রাউজারের ভেতরে একটি কমান্ড-লাইন শেল প্রদান করে, যেখানে আপনার প্রয়োজনীয় টুলগুলো ইনস্টল করা থাকে এবং যা আপনার গুগল ক্লাউড প্ল্যাটফর্ম অ্যাকাউন্টে স্বয়ংক্রিয়ভাবে প্রমাণীকৃত হয়। (যদি আপনি এই অনুশীলনটি ক্লাউড শেলে চালাতে না চান, তবে পরবর্তী বিভাগে চলে যান।)

ক্লাউড কনসোলে যান এবং উপরের ডানদিকের টুলবারে থাকা 'অ্যাক্টিভেট ক্লাউড শেল'-এ ক্লিক করুন:

68a17b036ce24ccb.png

ক্লাউড শেলে টুলস যোগ করুন

  1. kubectx ইনস্টল করতে , এখান থেকে ব্যাশ স্ক্রিপ্টগুলো ডাউনলোড করে $PATH-এর একটি লোকেশনে রাখুন।
  2. এই নির্দেশাবলী অনুসরণ করে 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}

ক্লাউড শেল ব্যবহার সহজ করার জন্য কিছু দ্রুত টিপস :

১. শেলটিকে একটি নতুন উইন্ডোতে বিচ্ছিন্ন করুন:

২. ফাইল এডিটর ব্যবহার: ব্রাউজারের মধ্যেই ফাইল এডিটর চালু করতে উপরের ডানদিকের পেন্সিল আইকনে ক্লিক করুন। এটি আপনার কাজে আসবে, কারণ আমরা কোডের অংশবিশেষ ফাইলে কপি করব।

৩. নতুন ট্যাব খুলুন: যদি আপনার একাধিক টার্মিনাল প্রম্পটের প্রয়োজন হয়।

৪. লেখা বড় করুন: ক্লাউড শেলের ডিফল্ট ফন্ট সাইজ পড়ার জন্য খুব ছোট হতে পারে।

লিনাক্স/উইন্ডোজে Ctrl-+ এবং ম্যাকওএস-এ ⌘-+।

ক্লাউড শেলের চেয়ে নিজের ওয়ার্কস্টেশন পরিবেশ ব্যবহারে যদি আপনি বেশি স্বাচ্ছন্দ্যবোধ করেন, তাহলে নিম্নলিখিত টুলগুলো সেট আপ করুন:

  1. gcloud: ইনস্টল করুন : (ক্লাউড শেলে আগে থেকেই ইনস্টল করা থাকে।) আপনার প্ল্যাটফর্মে gcloud ইনস্টল করার জন্য নির্দেশাবলী অনুসরণ করুন । আমরা এটি ব্যবহার করে একটি কুবারনেটিস ক্লাস্টার তৈরি করব।
  2. kubectl ইনস্টল করুন kubectl: (ক্লাউড শেলে আগে থেকেই ইনস্টল করা থাকে।) ইনস্টল করতে নিম্নলিখিত কমান্ডটি চালান:
gcloud components install kubectl

gcloud-কে প্রমাণীকরণের জন্য নিম্নলিখিত কমান্ডটি চালান। এটি আপনাকে আপনার Google অ্যাকাউন্ট দিয়ে লগ ইন করতে বলবে। তারপর, আগে থেকে তৈরি করা প্রজেক্টটিকে (উপরে দেখানো) ডিফল্ট প্রজেক্ট হিসেবে বেছে নিন। (আপনি কম্পিউট জোন কনফিগার করা বাদ দিতে পারেন):

gcloud init
  1. curl: ইনস্টল করুন : এটি বেশিরভাগ Linux/macOS সিস্টেমে আগে থেকেই ইনস্টল করা থাকে। সম্ভবত আপনার সিস্টেমে এটি আগে থেকেই আছে। অন্যথায়, এটি কীভাবে ইনস্টল করতে হয় তা জানতে ইন্টারনেটে অনুসন্ধান করুন।
  2. kubectx ইনস্টল করুন : এখান থেকে ব্যাশ স্ক্রিপ্টগুলো ডাউনলোড করে $PATH-এর একটি লোকেশনে রাখুন।
  3. এই নির্দেশাবলী অনুসরণ করে helm ইনস্টল করুন

৩. জিসিপি প্রজেক্ট সেটআপ করুন

আপনার প্রোজেক্টে GKE (Google Kubernetes Engine), GCR (Google Container Registry), এবং GCB (Google Cloud Build) API-গুলো সক্রিয় করুন:

gcloud services enable \
  cloudapis.googleapis.com \
  container.googleapis.com \
  containerregistry.googleapis.com \
  cloudbuild.googleapis.com

পরিবেশ ভেরিয়েবল সেট আপ করুন

সেটআপের সময় আমরা আমাদের গুগল ক্লাউড প্রজেক্ট নিয়ে ব্যাপকভাবে কাজ করব, তাই দ্রুত রেফারেন্সের জন্য একটি এনভায়রনমেন্ট ভেরিয়েবল সেট করে নেওয়া যাক।

export GCLOUD_PROJECT=$(gcloud config get-value project)

এই কর্মশালায় আমরা কিছু কোড এবং কনফিগারেশন ফাইল তৈরি করব, তাই চলুন একটি প্রজেক্ট ডিরেক্টরি তৈরি করে সেটিতে প্রবেশ করি।

mkdir -p src/istio-burst && \
cd src/istio-burst && \
export proj=$(pwd)

৪. 'প্রাথমিক' কুবারনেটিস ক্লাস্টার তৈরি করুন

আপনি গুগল কুবারনেটিস ইঞ্জিন (GKE) দিয়ে সহজেই একটি পরিচালিত কুবারনেটিস ক্লাস্টার তৈরি করতে পারেন।

নিম্নলিখিত কমান্ডটি একটি কুবারনেটিস ক্লাস্টার তৈরি করবে:

  • 'প্রাথমিক' নামে,
  • ইউএস-ওয়েস্ট১-এ জোনে,
  • Kubernetes-এর সর্বশেষ সংস্করণটি উপলব্ধ আছে।
  • ৪টি প্রাথমিক নোড সহ
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

(এতে প্রায় ৫ মিনিট সময় লাগতে পারে। আপনি ক্লাউড কনসোলে ক্লাস্টারটি তৈরি হতে দেখতে পারেন।)

Kubernetes ক্লাস্টার তৈরি হওয়ার পরে, gcloud ক্লাস্টারের ক্রেডেনশিয়াল ব্যবহার করে kubectl কনফিগার করে।

gcloud container clusters get-credentials $cluster --zone=$zone

এখন আপনি আপনার নতুন ক্লাস্টারে kubectl ব্যবহার করতে পারবেন।

আপনার ক্লাস্টারের Kubernetes নোডগুলির তালিকা দেখতে নিম্নলিখিত কমান্ডটি চালান (সেগুলির স্ট্যাটাস "Ready" দেখানো উচিত):

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)

৫. 'বার্স্ট' ক্লাস্টার তৈরি করুন

নিম্নলিখিত কমান্ডটি একটি কুবারনেটিস ক্লাস্টার তৈরি করবে:

  • "বার্স্ট" নামে,
  • ইউএস-ওয়েস্ট১-এ জোনে,
  • Kubernetes-এর সর্বশেষ সংস্করণটি উপলব্ধ আছে।
  • ১টি প্রাথমিক নোড সহ
  • ৫টি নোড পর্যন্ত অটোস্কেলিং সক্রিয় করা হয়েছে।
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

(এতে প্রায় ৫ মিনিট সময় লাগতে পারে। আপনি ক্লাউড কনসোলে ক্লাস্টারটি তৈরি হতে দেখতে পারেন।)

Kubernetes ক্লাস্টার তৈরি হওয়ার পরে, gcloud ক্লাস্টারের ক্রেডেনশিয়াল ব্যবহার করে kubectl কনফিগার করে।

gcloud container clusters get-credentials $cluster --zone=$zone

এখন আপনি আপনার নতুন ক্লাস্টারে kubectl ব্যবহার করতে পারবেন।

আপনার ক্লাস্টারের Kubernetes নোডগুলির তালিকা দেখতে নিম্নলিখিত কমান্ডটি চালান (সেগুলির স্ট্যাটাস "Ready" দেখানো উচিত):

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)

৬. ফায়ারওয়াল নিয়ম প্রয়োগ করুন

আমাদের দুটি ক্লাস্টারের মধ্যে যোগাযোগের জন্য একটি ফায়ারওয়াল নিয়ম তৈরি করতে হবে।

গুগল ক্লাউড প্ল্যাটফর্মে একটি ফায়ারওয়াল নিয়ম তৈরি করতে নিম্নলিখিত কমান্ডগুলি চালান যা আমাদের ক্লাস্টারগুলিকে একে অপরের সাথে যোগাযোগ করতে অনুমতি দেবে।

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

আমাদের দুটি ক্লাস্টারই সেটআপ করা হয়ে গেছে এবং সেগুলোতে আমাদের অ্যাপ্লিকেশন ও Istio ডেপ্লয় করার জন্য প্রস্তুত!

৭. ইস্তিও-এর পরিচিতি

ইস্টিও কী?

ইস্টিও হলো একটি সার্ভিস মেশ কন্ট্রোল প্লেন যার লক্ষ্য হলো "সার্ভিসগুলোকে সংযুক্ত করা, সুরক্ষিত করা, নিয়ন্ত্রণ করা এবং পর্যবেক্ষণ করা"। এটি বিভিন্ন উপায়ে এই কাজটি করে থাকে, তবে প্রধানত আপনার ডেপ্লয় করা প্রতিটি কুবারনেটিস পডের মধ্যে একটি প্রক্সি কন্টেইনার ( এনভয় ) সাইডকার হিসেবে যুক্ত করার মাধ্যমে। এই প্রক্সি কন্টেইনারটি একটি সাধারণ পলিসি ও টেলিমেট্রি হাবের ( মিক্সার ) সাথে একযোগে মাইক্রোসার্ভিসগুলোর মধ্যকার সমস্ত নেটওয়ার্ক যোগাযোগ নিয়ন্ত্রণ করে।

a25613cd581825da.png

এই নীতিগুলি আপনার Kubernetes Deployment এবং Services থেকে স্বাধীনভাবে প্রয়োগ করা যেতে পারে, যার অর্থ হলো নেটওয়ার্ক অপারেটর সংশ্লিষ্ট অ্যাপ্লিকেশনগুলি পুনরায় ডেপ্লয় না করেই নেটওয়ার্ক কার্যকলাপ পর্যবেক্ষণ করতে এবং নেটওয়ার্ক নীতিগুলি সীমাবদ্ধ, পুনঃনির্দেশিত বা পুনর্লিখন করতে পারেন।

Istio যেসব ট্র্যাফিক ম্যানেজমেন্ট ফিচার সমর্থন করে, তার মধ্যে কয়েকটি হলো:

  • সার্কিট ব্রেকার
  • শতাংশ-ভিত্তিক ট্র্যাফিক বিভাজন
  • URL পুনর্লিখন
  • TLS সমাপ্তি
  • স্বাস্থ্য পরীক্ষা
  • লোড ব্যালেন্সিং

এই কর্মশালার উদ্দেশ্যে, আমরা শতাংশ-ভিত্তিক ট্র্যাফিক বিভাজনের উপর আলোকপাত করব।

ইস্তিও পরিভাষা যা নিয়ে আমরা কাজ করব

ভার্চুয়ালসার্ভিস

একটি ভার্চুয়ালসার্ভিস কোনো হোস্টকে অ্যাড্রেস করার সময় প্রয়োগ করার জন্য একগুচ্ছ ট্র্যাফিক রাউটিং নিয়ম নির্ধারণ করে।

গেটওয়ে

গেটওয়ে হলো মেশের প্রান্তে অবস্থিত একটি লোড ব্যালান্সার যা আগত বা বহির্গামী HTTP/TCP সংযোগ গ্রহণ করে। গেটওয়ে পোর্ট, SNI কনফিগারেশন ইত্যাদি নির্দিষ্ট করতে পারে।

গন্তব্য নিয়ম

একটি ডেস্টিনেশনরুল এমন নীতিমালা নির্ধারণ করে যা রাউটিং সম্পন্ন হওয়ার পর কোনো পরিষেবার জন্য উদ্দিষ্ট ট্র্যাফিকের ক্ষেত্রে প্রযোজ্য হয়। এগুলি লোড ব্যালান্সিং-এর কনফিগারেশন, সাইডকার থেকে কানেকশন পুলের আকার এবং আউটলায়ার ডিটেকশন সেটিংস নির্দিষ্ট করে।

ইস্টিও মাল্টিক্লাস্টার

আপনি হয়তো লক্ষ্য করেছেন, যখন আমরা আমাদের দুটি ক্লাস্টার তৈরি করেছিলাম, তখন আমাদের primary ক্লাস্টারটি অটোস্কেলিং ছাড়া ৪টি নোডের ছিল এবং burst ক্লাস্টারটি ছিল ১টি নোডের, যা অটোস্কেলিংয়ের মাধ্যমে ৫টি নোড পর্যন্ত প্রসারিত হতে পারত।

এই বিন্যাসের দুটি কারণ রয়েছে।

প্রথমে, আমরা একটি "অন-প্রেম" থেকে ক্লাউড পরিস্থিতি অনুকরণ করতে চাই। একটি অন-প্রেম পরিবেশে আপনার অটোস্কেলিং ক্লাস্টারের সুবিধা থাকে না, কারণ সেখানে একটি নির্দিষ্ট পরিকাঠামো থাকে।

দ্বিতীয়ত, Istio চালানোর জন্য (উপরে বর্ণিত) একটি ৪-নোড সেটআপ হলো ন্যূনতম প্রয়োজনীয়তা। এতে প্রশ্ন জাগে: যদি Istio-র জন্য ন্যূনতম ৪টি নোডের প্রয়োজন হয়, তবে আমাদের burst ক্লাস্টার কীভাবে ১টি নোড দিয়ে Istio চালাতে পারে? এর উত্তর হলো, Istio মাল্টিক্লাস্টার Istio পরিষেবাগুলির একটি অনেক ছোট সেট ইনস্টল করে এবং পলিসি নিয়মগুলি পুনরুদ্ধার করতে ও টেলিমেট্রি তথ্য প্রকাশ করতে প্রাইমারি ক্লাস্টারের Istio ইনস্টলেশনের সাথে যোগাযোগ করে।

৮. অ্যাপ্লিকেশন আর্কিটেকচারের সংক্ষিপ্ত বিবরণ

উপাদানগুলির সংক্ষিপ্ত বিবরণ

আমরা NodeJS এবং Redis ব্যবহার করে একটি ত্রি-স্তরীয় অ্যাপ্লিকেশন স্থাপন করব।

শ্রমিক

ওয়ার্কার অ্যাপ্লিকেশনটি NodeJS-এ লেখা এবং এটি আগত POST HTTP অনুরোধগুলো গ্রহণ করবে, সেগুলোর উপর একটি হ্যাশিং অপারেশন চালাবে এবং, যদি PREFIX নামের একটি এনভায়রনমেন্ট ভেরিয়েবল সংজ্ঞায়িত করা থাকে, তবে এটি হ্যাশের শুরুতে সেই মানটি যুক্ত করবে। হ্যাশটি গণনা করা হয়ে গেলে, অ্যাপ্লিকেশনটি নির্দিষ্ট Redis সার্ভারের " calculation " চ্যানেলে ফলাফলটি পাঠিয়ে দেয়।

আমরা পরবর্তীতে মাল্টিক্লাস্টার কার্যকারিতা প্রদর্শনের জন্য PREFIX এনভায়রনমেন্ট ভেরিয়েবল ব্যবহার করব।

তথ্যসূত্র হিসেবে: অ্যাপ্লিকেশনটি এই প্যাকেজগুলো ব্যবহার করে।

  • body-parser: এটি আমাদের http অনুরোধগুলো পার্স করতে সাহায্য করে।
  • cors: ক্রস অরিজিন রিসোর্স শেয়ারিং ব্যবহারের অনুমতি দেয়।
  • dotenv: এনভায়রনমেন্ট ভেরিয়েবল সহজে পার্স করার উপায়
  • express: সহজ ওয়েবসাইট হোস্টিং
  • ioredis: Redis ডেটাবেসের সাথে যোগাযোগের জন্য ক্লায়েন্ট লাইব্রেরি
  • morgan: সুন্দর কাঠামোগত লগ প্রদান করে

ফ্রন্টএন্ড

আমাদের ফ্রন্টএন্ডটিও একটি NodeJS অ্যাপ্লিকেশন, যা Express ব্যবহার করে একটি ওয়েব পেজ হোস্ট করে। এটি ব্যবহারকারীর দেওয়া ফ্রিকোয়েন্সি গ্রহণ করে এবং সেই হারে আমাদের worker অ্যাপ্লিকেশনে রিকোয়েস্ট পাঠায়। এই অ্যাপ্লিকেশনটি ' calculation ' নামের একটি Redis চ্যানেলে মেসেজ সাবস্ক্রাইব করে এবং একটি ওয়েব পেজে ফলাফল প্রদর্শন করে।

অ্যাপ্লিকেশনটি নিম্নলিখিত নির্ভরতাগুলো ব্যবহার করে।

  • body-parser: এটি আমাদের http অনুরোধগুলো পার্স করতে সাহায্য করে।
  • dotenv: এনভায়রনমেন্ট ভেরিয়েবল সহজে পার্স করার উপায়
  • express: সহজ ওয়েবসাইট হোস্টিং
  • ioredis: Redis ডেটাবেসের সাথে যোগাযোগের জন্য ক্লায়েন্ট লাইব্রেরি
  • morgan: সুন্দর কাঠামোগত লগ সরবরাহ করে
  • request: HTTP অনুরোধ করার অনুমতি দেয়।
  • socket.io: ওয়েব পেজ থেকে সার্ভারে দ্বিমুখী যোগাযোগের সুযোগ করে দেয়।

এই ওয়েবপেজটি স্টাইলিংয়ের জন্য বুটস্ট্র্যাপ ব্যবহার করে এবং রান করলে এটি দেখতে নিচের মতো হয়।

e5e3b9cbede4cac4.png

স্থাপত্য ডায়াগ্রাম

7ae4bc22a58f80a6.png

স্থাপনা চিত্র

আমরা আমাদের তৈরি করা দুটি ক্লাস্টারে চূড়ান্ত অ্যাপ্লিকেশনটি ডেপ্লয় করব। primary ক্লাস্টারে সমস্ত কম্পোনেন্ট ( frontend , worker এবং রেডিস) ডেপ্লয় করা থাকবে, কিন্তু burst ক্লাস্টারে শুধুমাত্র worker অ্যাপ্লিকেশনটি ডেপ্লয় করা থাকবে।

এখানে দুটি ক্লাস্টারের একটি ডায়াগ্রাম দেওয়া হলো। লাল রঙে চিহ্নিত বক্সগুলো হলো কুবারনেটিস সার্ভিসেস, আর নীল রঙেরগুলো হলো কুবারনেটিস ডিপ্লয়মেন্টস। হলুদ বক্সগুলো আমাদের ইস্টিও ইনস্টলেশনকে নির্দেশ করে।

561db37c510944bd.png

লক্ষ্য করুন, ক্লাস্টারে কোনো রেডিস ডিপ্লয়মেন্ট না থাকা সত্ত্বেও burst ক্লাস্টারে এখনও রেডিসের একটি সার্ভিস ডিপ্লয় করা আছে। ক্লাস্টারে এই সার্ভিসটি থাকা প্রয়োজন যাতে কুবারনেটিস ডিএনএস অনুরোধটি রিজলভ করতে পারে, কিন্তু যখন প্রকৃতপক্ষে অনুরোধটি করা হয়, তখন ইস্টিও প্রক্সি অনুরোধটিকে primary ক্লাস্টারের রেডিস ডিপ্লয়মেন্টে রি-রাউট করে দেয়।

চূড়ান্ত অ্যাপ্লিকেশনটিতে primary ক্লাস্টারে istiowatcher. আমাদের ট্র্যাফিক একটি নির্দিষ্ট সীমা অতিক্রম করলে, এটিই স্বয়ংক্রিয়ভাবে ট্র্যাফিককে burst ডায়নামিকভাবে রি-রাউট করার সুযোগ দেবে।

8f6183bdfc3f813c.png

৯. অ্যাপ্লিকেশন ডেপ্লয়মেন্ট ফাইল তৈরি করুন

আমাদের অ্যাপ্লিকেশনটি ডেপ্লয় করার জন্য এক সেট কুবারনেটিস ম্যানিফেস্ট তৈরি করতে হবে।

প্রজেক্টের রুট ডিরেক্টরিতে প্রবেশ করুন এবং kubernetes নামে একটি নতুন ফোল্ডার তৈরি করুন।

mkdir ${proj}/kubernetes && cd ${proj}/kubernetes

frontend.yaml লিখুন

এটি আমাদের ফ্রন্টএন্ড ইমেজ অ্যাক্সেস করার জন্য একটি কুবারনেটিস ডিপ্লয়মেন্ট এবং সার্ভিস উভয়ই তৈরি করবে।

নিম্নলিখিতটি 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-কে জানাতে সাহায্য করার জন্য আমরা কন্টেইনারটিতে liveness এবং readiness প্রোবও সেট করেছি।

worker-service.yaml লিখুন

আমরা কুবারনেটিস সার্ভিস ডেফিনিশনটি ডিপ্লয়মেন্ট ডেফিনিশন থেকে আলাদা একটি ফাইলে লিখছি, কারণ আমরা এই সার্ভিসটি একাধিক ক্লাস্টারে পুনরায় ব্যবহার করব, কিন্তু প্রতিটি ক্লাস্টারের জন্য একটি ভিন্ন ডিপ্লয়মেন্ট লিখব।

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"

এখানে লক্ষ্য করুন, আমরা livenessreadiness প্রোব সরবরাহ করার পাশাপাশি আমাদের অ্যাপ্লিকেশনের ব্যবহারের জন্য PORT এবং REDIS_URL এনভায়রনমেন্ট ভেরিয়েবল নির্দিষ্ট করার একই পদ্ধতি অনুসরণ করছি।

এই ডেপ্লয়মেন্টের ক্ষেত্রে আরেকটি লক্ষণীয় বিষয় হলো PREFIX এনভায়রনমেন্ট ভেরিয়েবলের অনুপস্থিতি। এর মানে হলো, আমাদের গণনার ফলাফলগুলো সরাসরি হ্যাশ হিসেবে থাকবে (এগুলোর আগে কোনো প্রিফিক্স থাকবে না)।

এই ডেপ্লয়মেন্টের শেষ গুরুত্বপূর্ণ বিষয়টি হলো ` cluster-type: primary-cluster লেবেলটি। আমরা পরবর্তীতে Istio মাল্টিক্লাস্টারে ট্র্যাফিক রাউটিং করার সময় এটি ব্যবহার করব।

redis.yaml লিখুন

আমাদের ওয়ার্কার থেকে ফ্রন্টএন্ডে যোগাযোগ একটি রেডিস চ্যানেলের মাধ্যমে হয়, এবং সেই কারণে আমাদের ক্লাস্টারে একটি রেডিস অ্যাপ্লিকেশন ডেপ্লয় করতে হবে।

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:alpine ইমেজের উপর ভিত্তি করে একটি কন্টেইনার তৈরি করে, প্রয়োজনীয় পোর্টগুলো উন্মুক্ত করে এবং যুক্তিসঙ্গত রিসোর্স সীমা নির্ধারণ করে।

redis-service.yaml লিখুন

আমাদের Redis অ্যাপ্লিকেশনের সাথে যোগাযোগের জন্য একটি Kubernetes Service প্রয়োজন।

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 Deployment অ্যাক্সেস করার জন্য redis-cache-service নামক একটি পরিষেবা প্রদান করে।

১০. অ্যাপ্লিকেশনটি স্থাপন করুন

আমাদের ইমেজগুলো GCR-এ পুশ করা হয়ে গেলে এবং Kubernetes ম্যানিফেস্টগুলো লেখা হয়ে গেলে, এখন আমাদের অ্যাপ্লিকেশনটি ডিপ্লয় করে দেখা যাক এটি কেমন কাজ করে!

অ্যাপ্লিকেশনটি ডিপ্লয় করতে নিম্নলিখিত কমান্ডগুলো চালান।

  1. আমরা সঠিক ক্লাস্টারে আছি কিনা তা নিশ্চিত করুন।
kubectx primary
  1. রেডিস ক্যাশে স্থাপন করুন
kubectl apply -f redis.yaml
  1. রেডিস সার্ভিস স্থাপন করুন
kubectl apply -f redis-service.yaml
  1. ফ্রন্টএন্ড স্থাপন করুন
kubectl apply -f frontend.yaml
  1. কর্মী মোতায়েন করুন
kubectl apply -f worker-primary.yaml
  1. কর্মী পরিষেবা মোতায়েন করুন
kubectl apply -f worker-service.yaml

আমরা আমাদের অ্যাপ্লিকেশনটি GKE-তে ডেপ্লয় করেছি। অভিনন্দন!

পরীক্ষা

পডগুলো অনলাইনে আসার জন্য অপেক্ষা করুন।

kubectl get pods -w

একবার সবগুলো পড "Running" হয়ে গেলে 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

আপনি লক্ষ্য করবেন যে আমরা আমাদের ফ্রন্টএন্ডকে কোনো লোডব্যালান্সারের মাধ্যমে উন্মুক্ত করিনি। এর কারণ হলো, পরবর্তীতে আমরা ইস্তিও (Istio)-এর মাধ্যমে অ্যাপ্লিকেশনটি অ্যাক্সেস করব। সবকিছু ঠিকঠাক চলছে কিনা তা পরীক্ষা করার জন্য, আমরা kubectl port-forward. আপনার লোকাল (বা ক্লাউড শেল) মেশিনের পোর্ট ৮০৮০-কে frontend ডিপ্লয়মেন্ট চালিত পোর্ট ৮০৮০-তে ফরওয়ার্ড করতে নিম্নলিখিত কমান্ডটি চালান।

kubectl port-forward \
$(kubectl get pods -l app=frontend -o jsonpath='{.items[0].metadata.name}') \
8080:8080

আপনি যদি স্থানীয়ভাবে চালাচ্ছেন : একটি ওয়েব ব্রাউজার খুলুন এবং http://localhost:8080- এ যান।

আপনি যদি ক্লাউড শেলে চালাচ্ছেন: 'ওয়েব প্রিভিউ' বোতামে ক্লিক করুন এবং 'পোর্ট ৮০৮০-তে প্রিভিউ' নির্বাচন করুন।

bdb5dc75f415be11.png

আপনার ফ্রন্টএন্ড দেখা উচিত! এবং আপনি যদি 'ফ্রিকোয়েন্সি' বক্সে একটি সংখ্যা প্রবেশ করান, তাহলে দেখবেন হ্যাশ চিহ্নগুলো দেখা যেতে শুরু করেছে।

1caafaffab26897a.png

অভিনন্দন; সবকিছু এখন চালু হয়ে গেছে!

পোর্ট ফরওয়ার্ডিং বন্ধ করতে Ctrl+C চাপুন।

১১. ডেপ্লয় করা অ্যাপ্লিকেশন পরিষ্কার করা

আমরা আমাদের ক্লাস্টারে Istio প্রয়োগ করব এবং তারপর আমাদের অ্যাপ্লিকেশনটি পুনরায় স্থাপন করব, তাই প্রথমে আমাদের বর্তমান অ্যাপ্লিকেশনটি গুছিয়ে নেওয়া যাক।

আপনার এইমাত্র তৈরি করা সমস্ত Deployment এবং সার্ভিস মুছে ফেলার জন্য নিম্নলিখিত কমান্ডগুলি চালান।

  1. redis-cache-service মুছে ফেলুন
kubectl delete -f redis-service.yaml
  1. redis মুছুন
kubectl delete -f redis.yaml
  1. frontend মুছুন
kubectl delete -f frontend.yaml
  1. worker মুছে ফেলুন
kubectl delete -f worker-primary.yaml
  1. worker-service মুছে ফেলুন
kubectl delete -f worker-service.yaml

১২. প্রাইমারি ক্লাস্টারে Istio ইনস্টল করুন

গেট ইস্তিও

Istio-এর রিলিজগুলো GitHub-এ হোস্ট করা হয়। নিচের কমান্ডগুলো istio-এর 1.0.0 সংস্করণটি ডাউনলোড এবং আনপ্যাক করবে।

  1. আপনার প্রোজেক্টের রুটে যান।
cd ${proj}
  1. আর্কাইভটি ডাউনলোড করুন
curl -LO https://github.com/istio/istio/releases/download/1.0.0/istio-1.0.0-linux.tar.gz
  1. আর্কাইভটি এক্সট্র্যাক্ট করুন এবং মুছে ফেলুন
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 প্যারামিটার লক্ষ্য করুন। এগুলো Istio সিস্টেমে Prometheus এবং ServiceGraph সাপোর্ট যোগ করে। আমরা ল্যাবের পরবর্তী অংশে Prometheus সার্ভিসটি ব্যবহার করব।

ইস্তিও স্থাপন করুন

Istio ডিপ্লয় করার জন্য আমাদের প্রথমে istio-system নামে একটি নেমস্পেস তৈরি করতে হবে, যেখানে Istio ডিপ্লয়মেন্ট এবং সার্ভিসগুলো চলতে পারবে।

kubectl create namespace istio-system

এবং সবশেষে, Helm দিয়ে তৈরি করা istio-primary.yaml ফাইলটি প্রয়োগ করুন।

kubectl apply -f istio-primary.yaml

লেবেল ডিফল্ট নেমস্পেস

Istio আপনার প্রতিটি Deployment-এ একটি সাইডকার প্রক্সি সার্ভিস ইনজেক্ট করার মাধ্যমে কাজ করে। এটি ঐচ্ছিকভাবে করা হয়, তাই আমাদের default নেমস্পেসকে istio-injection=enabled দিয়ে লেবেল করতে হবে, যাতে Istio স্বয়ংক্রিয়ভাবে আমাদের জন্য সাইডকারটি ইনজেক্ট করতে পারে।

kubectl label namespace default istio-injection=enabled

অভিনন্দন! আমাদের অ্যাপ্লিকেশনটি ডেপ্লয় করার জন্য Istio সহ একটি ক্লাস্টার চালু ও চালু হয়ে গেছে!

১৩. Istio ট্র্যাফিক ম্যানেজমেন্ট ব্যবহার করে আমাদের অ্যাপ্লিকেশনটি স্থাপন করুন

Istio ট্র্যাফিক ম্যানেজমেন্ট কনফিগারেশন ফাইল তৈরি করুন

Istio অনেকটা Kubernetes-এর মতোই কাজ করে, কারণ এটি কনফিগারেশনের জন্য yaml ফাইল ব্যবহার করে। সেই সূত্রে, আমাদের ট্র্যাফিক কীভাবে প্রকাশ ও রাউট করতে হবে, তা Istio-কে জানানোর জন্য এক সেট ফাইল তৈরি করতে হবে।

istio-manifests নামে একটি ডিরেক্টরি তৈরি করুন এবং এর ভেতরে প্রবেশ করুন।

mkdir ${proj}/istio-manifests && cd ${proj}/istio-manifests

frontend-gateway.yaml লিখুন

এই ফাইলটি আমাদের কুবারনেটিস ক্লাস্টারকে একটি GKE লোডব্যালান্সারের অনুরূপ পদ্ধতিতে উন্মুক্ত করবে এবং সমস্ত আগত ট্র্যাফিক আমাদের ফ্রন্টএন্ড সার্ভিসে পাঠিয়ে দেবে।

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 ট্র্যাফিক ম্যানেজমেন্ট পলিসি স্থাপন করুন

অন্যান্য Kubernetes রিসোর্সের মতোই kubectl apply ব্যবহার করে Istio পলিসিগুলো স্থাপন করা হয়।

  1. আমাদের গেটওয়ে প্রয়োগ করুন
kubectl apply -f frontend-gateway.yaml
  1. আমাদের Redis VirtualService প্রয়োগ করুন
kubectl apply -f redis-virtualservice.yaml
  1. আমাদের কর্মী ভার্চুয়াল পরিষেবাতে আবেদন করুন
kubectl apply -f worker-virtualservice.yaml

অ্যাপ্লিকেশন স্থাপন করুন

  1. আমাদের kubernetes ডিরেক্টরিতে ফিরে যান
cd ${proj}/kubernetes
  1. রেডিস ক্যাশে স্থাপন করুন
kubectl apply -f redis.yaml
  1. রেডিস সার্ভিস স্থাপন করুন
kubectl apply -f redis-service.yaml
  1. ফ্রন্টএন্ড স্থাপন করুন
kubectl apply -f frontend.yaml
  1. কর্মী মোতায়েন করুন
kubectl apply -f worker-primary.yaml
  1. কর্মী পরিষেবা মোতায়েন করুন
kubectl apply -f worker-service.yaml

যাচাই করুন

এই পর্যায়ে আমরা Istio এবং ট্র্যাফিক ম্যানেজমেন্ট পলিসি সহ একটি ক্লাস্টারে আমাদের অ্যাপ্লিকেশনটি পুনরায় স্থাপন করেছি।

আমাদের সমস্ত ওয়ার্কলোড অনলাইন হওয়া পর্যন্ত অপেক্ষা করা যাক।

তারা সবাই অনলাইন হয়ে গেলে, frontend-ingressgateway.yaml এ আমরা কনফিগার করা IngressGateway-টি নিন।

$ 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) করুন এবং আপনি ফ্রন্টএন্ড দেখতে পাবেন!

$ curl 35.199.158.10
<!doctype html>
<html>

<head>
    <title>String Hashr</title>
    <!-- Bootstrap -->
...

১৪. 'বার্স্ট' ক্লাস্টারে Istio ইনস্টল করুন

আমরা আমাদের primary ক্লাস্টারে সেটআপ এবং ডেপ্লয়মেন্ট নিয়ে অনেক সময় ব্যয় করছি, কিন্তু আমাদের কাছে ডেপ্লয় করার জন্য সম্পূর্ণ আরেকটি ক্লাস্টার রয়েছে!

এই অংশে আমাদের উভয় ক্লাস্টার থেকেই কনফিগারেশন ভেরিয়েবল সংগ্রহ করতে হবে, তাই প্রতিটি কমান্ডের জন্য আমরা কোন ক্লাস্টারকে নির্দেশ করছি সেদিকে বিশেষভাবে মনোযোগ দিন।

Istio রিমোট ম্যানিফেস্ট তৈরি করুন

primary ক্লাস্টারে Istio ডেপ্লয় করার মতোই, আমরা Helm ব্যবহার করে burst ক্লাস্টারে istio remote-এর ডেপ্লয়মেন্ট টেমপ্লেট করব। তবে, এটি করার আগে আমাদের primary ক্লাস্টার সম্পর্কে কিছু তথ্য সংগ্রহ করতে হবে।

প্রাথমিক ক্লাস্টার তথ্য সংগ্রহ করুন

primary ক্লাস্টারে পরিবর্তন করুন

kubectx primary

নিম্নলিখিত কমান্ডগুলো প্রাইমারি ক্লাস্টারের বিভিন্ন পডের আইপি অ্যাড্রেসগুলো সংগ্রহ করে। 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 ক্লাস্টারে Istio ইনস্টল করার জন্য, primary ক্লাস্টারে ইনস্টল করার মতোই একই ধাপগুলো অনুসরণ করতে হবে, তবে এক্ষেত্রে istio-remote-burst.yaml ফাইলটি ব্যবহার করতে হবে।

কিউবকনটেক্সটকে বার্স্ট-এ পরিবর্তন করুন

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

অভিনন্দন! এই পর্যায়ে আমরা burst ক্লাস্টারে Istio Remote সেট আপ করেছি। কিন্তু, এই মুহূর্তে ক্লাস্টারগুলো এখনও একে অপরের সাথে যোগাযোগ করতে পারছে না। burst ক্লাস্টারকে একসাথে সংযুক্ত করার জন্য আমাদের একটি kubeconfig ফাইল তৈরি করতে হবে, যা আমরা primary ক্লাস্টারে ডেপ্লয় করতে পারব।

'বার্স্ট' ক্লাস্টারের জন্য কিউবকনফিগ তৈরি করুন

বার্স্ট ক্লাস্টারে পরিবর্তন করুন

kubectx burst

পরিবেশ তৈরি করুন

ক্লাস্টারটির জন্য একটি kubeconfig ফাইল তৈরি করতে আমাদের ক্লাস্টারটি সম্পর্কে কিছু তথ্য সংগ্রহ করতে হবে।

  1. ক্লাস্টারের নামটি পান
CLUSTER_NAME=$(kubectl config view --minify=true -o "jsonpath={.clusters[].name}")
  1. ক্লাস্টার সার্ভারের নাম পান
SERVER=$(kubectl config view --minify=true -o "jsonpath={.clusters[].cluster.server}")
  1. istio-multi সার্ভিস অ্যাকাউন্টের সার্টিফিকেট অথরিটির সিক্রেটের নাম জানুন
SECRET_NAME=$(kubectl get sa istio-multi -n istio-system -o jsonpath='{.secrets[].name}')
  1. পূর্ববর্তী গোপনীয়তায় সংরক্ষিত সার্টিফিকেট অথরিটির ডেটা পান।
CA_DATA=$(kubectl get secret ${SECRET_NAME} -n istio-system -o "jsonpath={.data['ca\.crt']}")
  1. পূর্ববর্তী গোপনীয়তায় সংরক্ষিত টোকেনটি নিন।
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

একটি সিক্রেট তৈরি করে এবং সেটিকে লেবেল দিয়ে 'burst'-এর জন্য kubeconfig প্রয়োগ করুন।

kubectl create secret generic burst-kubeconfig --from-file burst-kubeconfig -n istio-system

সিক্রেটটিকে লেবেল করুন যাতে Istio মাল্টিক্লাস্টার অথেনটিকেশনের জন্য এটি ব্যবহার করতে পারে।

kubectl label secret burst-kubeconfig istio/multiCluster=true -n istio-system

অভিনন্দন! আমরা উভয় ক্লাস্টারকে প্রমাণীকৃত করেছি এবং তারা Istio Multicluster-এর মাধ্যমে একে অপরের সাথে যোগাযোগ করছে। চলুন এবার আমাদের অ্যাপ্লিকেশনটি ক্রস-ক্লাস্টারে ডেপ্লয় করি।

১৫. একটি ক্রস-ক্লাস্টার অ্যাপ্লিকেশন স্থাপন করুন

ডিপ্লয়মেন্ট তৈরি করুন

kubernetes ডিরেক্টরিতে পরিবর্তন করুন

cd ${proj}/kubernetes

'বার্স্ট' ক্লাস্টারের জন্য ওয়ার্কার ডিপ্লয়মেন্ট তৈরি করুন: 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 ফাইলটির প্রায় হুবহু অনুরূপ। দুটি প্রধান পার্থক্য রয়েছে।

প্রথম প্রধান পার্থক্যটি হলো আমরা " bursty- " মান সহ PREFIX এনভায়রনমেন্ট ভেরিয়েবলটি যুক্ত করেছি।

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 পরিষেবাগুলি পরিবর্তন করুন

এই মুহূর্তে আমাদের Istio সার্ভিসগুলো আমাদের দুটি ডেপ্লয়মেন্টেরই সুবিধা নিতে পারছে না। আমাদের সমস্ত ট্র্যাফিক 'প্রাইমারি' ক্লাস্টারে রাউট করা হচ্ছে। চলুন, এটা পরিবর্তন করা যাক।

আমাদের istio-manifests ডিরেক্টরিতে পরিবর্তন করুন

cd ${proj}/istio-manifests

DestinationRules অন্তর্ভুক্ত করতে 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: 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) নির্দেশ করছে, কিন্তু ৫০% ট্র্যাফিক primary সাবসেটে এবং বাকি ৫০% burst সাবসেটে পাঠানো হচ্ছে।

আমরা primary সাবসেটকে সেইসব ডিপ্লয়মেন্ট হিসেবে সংজ্ঞায়িত করেছি যাদের লেবেল cluster-type: primary-cluster এবং burst সাবসেটকে সেইসব ডিপ্লয়মেন্ট হিসেবে সংজ্ঞায়িত করেছি যাদের লেবেল ' cluster-type: burst-cluster

এর ফলে আমাদের ট্র্যাফিক কার্যকরভাবে দুটি ক্লাস্টারের মধ্যে ৫০/৫০ অনুপাতে ভাগ হয়ে যায়।

ক্লাস্টারে স্থাপন করুন

বার্স্ট ক্লাস্টারে redis-service.yaml ডিপ্লয় করুন।

burst কিউবকনফিগ-এ পরিবর্তন করুন

kubectx burst

আমাদের প্রকল্পের মূলে পরিবর্তন করুন

cd ${proj}

তারপর মোতায়েন করুন

বার্স্ট ক্লাস্টারে redis-service.yaml ডিপ্লয় করুন।

kubectl apply -f kubernetes/redis-service.yaml

বার্স্ট ক্লাস্টারে worker-burst.yaml ডিপ্লয় করুন।

kubectl apply -f kubernetes/worker-burst.yaml

বার্স্ট ক্লাস্টারে worker-service.yaml ডিপ্লয় করুন।

kubectl apply -f kubernetes/worker-service.yaml

Istio VirtualServices প্রয়োগ করুন

primary কিউবকনফিগ পরিবর্তন করুন

kubectx primary

তারপর মোতায়েন করুন

kubectl apply -f istio-manifests/worker-virtualservice.yaml

এটি কাজ করে কিনা যাচাই করুন

এটি কাজ করছে কিনা তা যাচাই করতে, আপনার Istio Ingress পয়েন্টে যান এবং লক্ষ্য করুন যে প্রায় ৫০% হ্যাশের শুরুতে 'burst-' উপসর্গটি রয়েছে।

78fb6e235e9f4a07.png

এর মানে আমরা সফলভাবে বিভিন্ন ক্লাস্টারের মধ্যে যোগাযোগ স্থাপন করতে পারছি! বিভিন্ন সার্ভিসের ওয়েট পরিবর্তন করে worker-virtualservice.yaml ফাইলটি প্রয়োগ করে দেখুন। ক্লাস্টারগুলোর মধ্যে ট্র্যাফিকের ভারসাম্য রক্ষার জন্য এটি একটি চমৎকার উপায়, কিন্তু যদি আমরা এটি স্বয়ংক্রিয়ভাবে করতে পারতাম?

১৬. প্রোমিথিউস মেট্রিক্সের সদ্ব্যবহার

প্রমিথিউসের একটি ভূমিকা

প্রমিথিউস হলো একটি ওপেন-সোর্স সিস্টেম মনিটরিং ও অ্যালার্টিং টুলকিট, যা মূলত সাউন্ডক্লাউডে তৈরি করা হয়েছিল। এটি একটি বহুমাত্রিক ডেটা মডেল বজায় রাখে, যেখানে মেট্রিকের নাম এবং কী/ভ্যালু পেয়ার দ্বারা চিহ্নিত টাইম সিরিজ ডেটা থাকে।

তথ্যসূত্র হিসেবে, এখানে প্রমিথিউস আর্কিটেকচার ডায়াগ্রামটি দেওয়া হলো:

601e1155a825e0c2.png

প্রোমিথিউসের সাথে ডেপ্লয় করা হলে ইস্টিও স্বয়ংক্রিয়ভাবে প্রোমিথিউস সার্ভারে বিভিন্ন মেট্রিক রিপোর্ট করে। আমরা এই মেট্রিকগুলো ব্যবহার করে তাৎক্ষণিকভাবে আমাদের ক্লাস্টারগুলো পরিচালনা করতে পারি।

আমাদের প্রমিথিউস মেট্রিক্স অন্বেষণ করা

শুরু করার জন্য, আমাদের প্রমিথিউস ডিপ্লয়মেন্টটি উন্মুক্ত করতে হবে।

GKE-এর Workloads ট্যাবে যান এবং বিস্তারিত দেখে 'prometheus' ওয়ার্কলোডটি খুঁজুন।

b4a7a3cd67db05b3.png

একবার আপনি ডেপ্লয়মেন্টের বিবরণ দেখতে পেলে, অ্যাকশনস -> এক্সপোজ-এ যান।

c04a482e55bdfd41.png

পোর্ট 9090 এ ফরওয়ার্ড করতে বেছে নিন এবং 'লোড ব্যালেন্সার' টাইপ করুন।

d5af3ba22a7a6ebb.png

এবং 'এক্সপোজ' বেছে নিন

এটি একটি সর্বজনীনভাবে অ্যাক্সেসযোগ্য আইপি অ্যাড্রেসে একটি সার্ভিস তৈরি করবে, যা আমরা আমাদের প্রোমিথিউস মেট্রিক্স অন্বেষণ করতে ব্যবহার করতে পারব।

এন্ডপয়েন্টটি চালু হওয়া পর্যন্ত অপেক্ষা করুন, এবং চালু হয়ে গেলে 'External endpoints'-এর পাশে থাকা আইপি অ্যাড্রেসটিতে ক্লিক করুন। b1e40ad90851da29.png

এখন আপনার প্রমিথিউস ইউআই (Prometheus UI) দেখার কথা।

ed273552270337ec.png

প্রমিথিউস নিজেই একটি কর্মশালা হওয়ার মতো যথেষ্ট মেট্রিক সরবরাহ করে। তবে আপাতত, আমরা istio_requests_total মেট্রিকটি অন্বেষণ করার মাধ্যমে শুরু করব।

ওই কোয়েরিটি চালালে প্রচুর ডেটা ফেরত আসে। এগুলো হলো Istio সার্ভিস মেশের মধ্য দিয়ে যাওয়া সমস্ত রিকোয়েস্টের মেট্রিক্স, এবং এর পরিমাণ অনেক! আমরা আমাদের এক্সপ্রেশনটি পরিবর্তন করে ফিল্টার করে শুধু প্রয়োজনীয় তথ্যগুলোই নেব:

যেসব অনুরোধের গন্তব্য পরিষেবা হলো worker-service.default.svc.cluster.local এবং যার উৎস হলো frontend-deployment শেষ ১৫ সেকেন্ডের মধ্যে সীমাবদ্ধ।

কোয়েরিটি দেখতে এইরকম:

istio_requests_total{reporter="destination",
destination_service="worker-service.default.svc.cluster.local",
source_workload="frontend-deployment"}[15s]

এবং এটি আমাদের কাজ করার জন্য আরও অনেক বেশি সহজবোধ্য ডেটাসেট প্রদান করে।

19d551fd5eac3785.png

কিন্তু এটি এখনও কিছুটা জটিল। আমরা প্রতি সেকেন্ডে অনুরোধের সংখ্যা জানতে চাই, সমস্ত অনুরোধ নয়।

সেটি পেতে, আমরা বিল্ট-ইন rate ফাংশনটি ব্যবহার করতে পারি।

rate(istio_requests_total{reporter="destination",
destination_service="worker-service.default.svc.cluster.local",
source_workload="frontend-deployment"}[15s])

dbb9dc063a18da9b.png

এটি আমাদের লক্ষ্যের কাছাকাছি নিয়ে যাচ্ছে, কিন্তু আমাদের এই পরিমাপকগুলোকে আরও কমিয়ে একটি যৌক্তিক শ্রেণিতে আনতে হবে।

এটি করার জন্য আমরা আমাদের ফলাফলগুলোকে দলবদ্ধ করতে ও যোগফল বের করতে 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)

898519966930ec56.png

চমৎকার! আমরা প্রোমিথিউস থেকে আমাদের প্রয়োজনীয় সঠিক মেট্রিকগুলো পেতে পারি।

আমাদের চূড়ান্ত প্রমিথিউস কোয়েরি

আমরা যা কিছু শিখেছি, তার ভিত্তিতে প্রমিথিউসকে আমাদের শেষ যে প্রশ্নটি করতে হবে তা হলো...

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 অনুরোধ পাঠিয়ে আমরা আমাদের কোয়েরি দিয়ে তাদের এপিআই-তে কোয়েরি করতে পারি। <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 থেকে আমাদের মেট্রিক মানটি বের করতে পারি।

পরিষ্কার-পরিচ্ছন্নতা

আমরা এইমাত্র প্রমিথিউস এক্সপোজ করার জন্য যে সার্ভিসটি ব্যবহার করেছি, সেটি ডিলিট করতে হবে। গুগল ক্লাউড কনসোলে, এইমাত্র তৈরি করা সার্ভিসটির একদম উপরে যান এবং "ডিলিট" বাটনে ক্লিক করুন।

d58cb51b4c922751.png

পরবর্তী পদক্ষেপ:

ক্লাস্টারের মধ্য দিয়ে ট্র্যাফিক কীভাবে এবং কী হারে চলাচল করছে তা জানার একটি উপায় বের করার পর, আমাদের পরবর্তী পদক্ষেপ হলো একটি ছোট বাইনারি লেখা, যা পর্যায়ক্রমে প্রোমিথিউসকে কোয়েরি করবে। যদি worker প্রতি সেকেন্ডে অনুরোধের সংখ্যা একটি নির্দিষ্ট থ্রেশহোল্ড অতিক্রম করে, তবে আমাদের ওয়ার্কার ভার্চুয়াল সার্ভিসে বিভিন্ন ডেস্টিনেশন ওয়েট প্রয়োগ করে সমস্ত ট্র্যাফিক burst ক্লাস্টারে পাঠিয়ে দেবে। আবার, প্রতি সেকেন্ডে অনুরোধের সংখ্যা একটি নিম্ন থ্রেশহোল্ডের নিচে নেমে গেলে, সমস্ত ট্র্যাফিক primary ফেরত পাঠিয়ে দেবে।

১৭. একটি ক্রস ক্লাস্টার বার্স্ট তৈরি করুন

সেটআপ

ওয়ার্কার-সার্ভিসের সমস্ত ট্র্যাফিক প্রাইমারি ক্লাস্টারে সেট করুন।

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

রাইট ইস্তিওওয়াচার ডেমন

এর গতি এবং বহনযোগ্যতার জন্য আমরা এই সার্ভিসটি লিখতে Go ব্যবহার করব। অ্যাপ্লিকেশনটির সামগ্রিক কার্যপ্রবাহ হবে চালু হওয়া এবং প্রতি সেকেন্ডে প্রোমিথিউসকে কোয়েরি করা।

src-এর মধ্যে istiowatcher নামে একটি নতুন ডিরেক্টরি তৈরি করুন।

mkdir -p ${proj}/src/istiowatcher && cd ${proj}/src/istiowatcher

ক্লাস্টারের ভেতর থেকে Istio কন্ট্রোল প্লেনকে নিয়ন্ত্রণ করার জন্য আমরা আমাদের কন্টেইনারের ভেতর থেকে istioctl কল করব।

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 নামে একটি নতুন ফাইল তৈরি করুন এবং এর মধ্যে নিম্নলিখিত বিষয়বস্তু যুক্ত করুন।

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"]

এই বহু-পর্যায়ের ডকারফাইলটি প্রথম পর্যায়ে Istio-এর 1.0.0 রিলিজটি ডাউনলোড এবং এক্সট্র্যাক্ট করে। দ্বিতীয় পর্যায়ে এটি আমাদের ডিরেক্টরি থেকে সবকিছু ইমেজে কপি করে, তারপর বিল্ড পর্যায় থেকে istioctl /usr/local/bin এ কপি করে (যাতে আমাদের অ্যাপ্লিকেশন এটিকে কল করতে পারে), ডিপেন্ডেন্সিগুলো সংগ্রহ করে, কোড কম্পাইল করে এবং CMD " istiowatcher " হিসেবে সেট করে।

burst.yaml লিখুন

frontend থেকে worker প্রতি সেকেন্ডে অনুরোধের সংখ্যা ১৫ অতিক্রম করলে istiowatcher এই ফাইলটি প্রয়োগ করবে।

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 প্রতি সেকেন্ডে অনুরোধের সংখ্যা ১০-এর নিচে নেমে আসে, তখন আমরা এই অবস্থাটিকে 'স্বাভাবিক' অবস্থা হিসেবে বিবেচনা করব। এই অবস্থায়, ১০০% ট্র্যাফিক 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

বিল্ড এবং পুশ istiowatcher

বর্তমান ডিরেক্টরিটি গুগল ক্লাউড বিল্ড (GCB)-এ পাঠাতে নিম্নলিখিতটি চালান, যা GCR-এ ছবিটি বিল্ড ও ট্যাগ করবে।

gcloud builds submit -t gcr.io/${GCLOUD_PROJECT}/istiowatcher

istiowatcher স্থাপন করুন

আমাদের 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

istio-system নেমস্পেসে istiowatcher.yaml ডিপ্লয় করুন।

kubectl apply -n istio-system -f istiowatcher.yaml

yaml ফাইলে থাকা serviceAccountName এবং automountServiceAccountToken ডিরেক্টিভগুলো বিশেষভাবে লক্ষণীয়। এগুলো আমাদেরকে ক্লাস্টারের ভেতর থেকে istioctl চালানোর জন্য প্রয়োজনীয় ক্রেডেনশিয়াল প্রদান করে।

istio-pilot-service-account এর ক্রেডেনশিয়ালগুলো আমাদের কাছে আছে কিনা তা নিশ্চিত করার জন্য, আমাদের এটি istio-system নেমস্পেসের মধ্যে ডেপ্লয় করতে হবে। (এটি default নেমস্পেসে বিদ্যমান নেই)।

দেখুন ট্র্যাফিক স্বয়ংক্রিয়ভাবে পরিবর্তিত হয়ে যাচ্ছে!

এবার সেই জাদুকরী মুহূর্ত! চলুন আমাদের ফ্রন্টএন্ডে গিয়ে req/second বাড়িয়ে ২০ করে দিই।

লক্ষ্য করুন, এতে কয়েক সেকেন্ড সময় লাগে, কিন্তু এরপর এটি গতি পায় এবং আমাদের সব হ্যাশের শুরুতে 'bursty-' উপসর্গটি যুক্ত হয়ে যায়!

এর কারণ হলো, আমরা 15s পরিসরে প্রমিথিউস থেকে স্যাম্পলিং করছি, যা আমাদের প্রতিক্রিয়ার সময়কে কিছুটা বিলম্বিত করে। যদি আমরা আরও সংকীর্ণ একটি পরিসর চাইতাম, তাহলে আমরা প্রমিথিউসের জন্য আমাদের কোয়েরিটি পরিবর্তন করে 5s.

১৮. এরপর কী?

পরিষ্কার-পরিচ্ছন্নতা

আপনি যদি এই কর্মশালার জন্য প্রদত্ত অস্থায়ী অ্যাকাউন্টটি ব্যবহার করেন, তাহলে আপনাকে পরিষ্কার করার প্রয়োজন নেই।

আপনি GCR-এ আপনার Kubernetes ক্লাস্টার, ফায়ারওয়াল নিয়ম এবং ইমেজগুলি মুছে ফেলতে পারেন।

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

ভবিষ্যতে