অ্যান্থোস সার্ভিস মেশ ওয়ার্কশপ: ল্যাব গাইড

১. আলফা ওয়ার্কশপ

ওয়ার্কশপ কোডল্যাবের লিঙ্ক bit.ly/asm-workshop

২. সংক্ষিপ্ত বিবরণ

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

9a033157f44308f3.png

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

এজেন্ডা

  • মডিউল ০ - পরিচিতি এবং প্ল্যাটফর্ম সেটআপ
  • ভূমিকা এবং স্থাপত্য
  • সার্ভিস মেশ এবং ইস্টিও/এএসএম-এর পরিচিতি
  • ল্যাব: পরিকাঠামো স্থাপন: ব্যবহারকারীর কর্মপ্রবাহ
  • বিরতি
  • প্রশ্নোত্তর
  • মডিউল ১ - ASM ব্যবহার করে অ্যাপ্লিকেশন ইনস্টল, সুরক্ষিত এবং মনিটর করুন
  • রেপো মডেল: ইনফ্রাস্ট্রাকচার এবং কুবারনেটিস রেপো সম্পর্কে ব্যাখ্যা
  • ল্যাব: নমুনা অ্যাপ্লিকেশন স্থাপন করুন
  • বিতরণকৃত পরিষেবা এবং পর্যবেক্ষণযোগ্যতা
  • দুপুরের খাবার
  • ল্যাব: স্ট্যাকড্রাইভারের সাহায্যে পর্যবেক্ষণযোগ্যতা
  • প্রশ্নোত্তর
  • মডিউল ২ - ডেভঅপ্স - ক্যানারি রোলআউট, পলিসি/আরবিএসি
  • মাল্টি ক্লাস্টার পরিষেবা আবিষ্কার এবং নিরাপত্তা/নীতি
  • ল্যাব: মিউচুয়াল টিএলএস
  • ক্যানারি ডেপ্লয়মেন্ট
  • ল্যাব: ক্যানারি ডেপ্লয়মেন্ট
  • সুরক্ষিত মাল্টি ক্লাস্টার গ্লোবাল লোড ব্যালেন্সিং
  • বিরতি
  • ল্যাব: অনুমোদন নীতি
  • প্রশ্নোত্তর
  • মডিউল ৩ - ইনফ্রা অপস - প্ল্যাটফর্ম আপগ্রেড
  • বিতরণকৃত পরিষেবা বিল্ডিং ব্লক
  • ল্যাব: পরিকাঠামো স্কেলিং
  • পরবর্তী পদক্ষেপ

স্লাইড

এই কর্মশালার স্লাইডগুলো নিম্নলিখিত লিঙ্কে পাওয়া যাবে:

এএসএম কর্মশালার স্লাইড

পূর্বশর্ত

এই কর্মশালায় অংশগ্রহণ করার আগে নিম্নলিখিত বিষয়গুলো আবশ্যক:

  1. একটি GCP সংস্থা নোড
  2. একটি বিলিং অ্যাকাউন্ট আইডি (আপনার ব্যবহারকারীকে অবশ্যই এই বিলিং অ্যাকাউন্টের বিলিং অ্যাডমিন হতে হবে)
  3. আপনার ব্যবহারকারীর জন্য সংস্থা স্তরে সংস্থা প্রশাসক IAM ভূমিকা

৩. পরিকাঠামো স্থাপন - প্রশাসনিক কর্মপ্রবাহ

বুটস্ট্র্যাপ ওয়ার্কশপ স্ক্রিপ্ট ব্যাখ্যা করা হয়েছে

ওয়ার্কশপের প্রাথমিক পরিবেশ তৈরি করার জন্য bootstrap_workshop.sh নামের একটি স্ক্রিপ্ট ব্যবহার করা হয়। আপনি এই স্ক্রিপ্টটি ব্যবহার করে নিজের জন্য একটি একক পরিবেশ তৈরি করতে পারেন, অথবা একাধিক ব্যবহারকারীর জন্য একাধিক পরিবেশ তৈরি করতে পারেন, যদি আপনি এই ওয়ার্কশপটি একাধিক ব্যবহারকারীকে প্রশিক্ষণ হিসেবে দেন।

বুটস্ট্র্যাপ ওয়ার্কশপ স্ক্রিপ্টটির জন্য ইনপুট হিসেবে নিম্নলিখিত বিষয়গুলো প্রয়োজন:

  • প্রতিষ্ঠানের নাম (উদাহরণস্বরূপ yourcompany.com ) - এটি সেই প্রতিষ্ঠান যেখানে আপনি কর্মশালার জন্য পরিবেশ তৈরি করেন।
  • বিলিং আইডি (উদাহরণস্বরূপ 12345-12345-12345 ) - কর্মশালা চলাকালীন ব্যবহৃত সমস্ত রিসোর্সের বিল করার জন্য এই বিলিং আইডিটি ব্যবহার করা হয়।
  • ওয়ার্কশপ নম্বর (উদাহরণস্বরূপ 01 ) - এটি একটি দুই অঙ্কের সংখ্যা। যদি আপনি একদিনে একাধিক ওয়ার্কশপ করেন এবং সেগুলোকে আলাদাভাবে ট্র্যাক করতে চান, তবে এটি ব্যবহৃত হয়। ওয়ার্কশপ নম্বরগুলো প্রজেক্ট আইডি তৈরি করতেও ব্যবহৃত হয়। আলাদা ওয়ার্কশপ নম্বর থাকলে প্রতিবার অনন্য প্রজেক্ট আইডি পাওয়া নিশ্চিত করা সহজ হয়। ওয়ার্কশপ নম্বরের পাশাপাশি, প্রজেক্ট আইডির জন্য বর্তমান তারিখও ( YYMMDD ফরম্যাটে) ব্যবহৃত হয়। তারিখ এবং ওয়ার্কশপ নম্বরের সমন্বয়ে অনন্য প্রজেক্ট আইডি তৈরি হয়।
  • প্রারম্ভিক ব্যবহারকারী নম্বর (উদাহরণস্বরূপ 1 ) - এই নম্বরটি ওয়ার্কশপের প্রথম ব্যবহারকারীকে নির্দেশ করে। উদাহরণস্বরূপ, আপনি যদি ১০ জন ব্যবহারকারীর জন্য একটি ওয়ার্কশপ তৈরি করতে চান, তাহলে আপনি প্রারম্ভিক ব্যবহারকারী নম্বর হিসেবে ১ এবং শেষ ব্যবহারকারী নম্বর হিসেবে ১০ রাখতে পারেন।
  • শেষ ব্যবহারকারী নম্বর (উদাহরণস্বরূপ 10 ) - এই নম্বরটি ওয়ার্কশপের সর্বশেষ ব্যবহারকারীকে নির্দেশ করে। উদাহরণস্বরূপ, আপনি যদি ১০ জন ব্যবহারকারীর জন্য একটি ওয়ার্কশপ তৈরি করতে চান, তাহলে আপনি শুরুর ব্যবহারকারী নম্বর হিসেবে ১ এবং শেষের ব্যবহারকারী নম্বর হিসেবে ১০ রাখতে পারেন। আপনি যদি একটি একক পরিবেশ সেট আপ করেন (উদাহরণস্বরূপ নিজের জন্য), তাহলে শুরুর এবং শেষের ব্যবহারকারী নম্বর একই রাখুন। এতে একটি একক পরিবেশ তৈরি হবে।
  • অ্যাডমিন জিসিএস বাকেট (উদাহরণস্বরূপ my-gcs-bucket-name ) - একটি জিসিএস বাকেট ওয়ার্কশপ সম্পর্কিত তথ্য সংরক্ষণের জন্য ব্যবহৃত হয়। বুটস্ট্র্যাপ ওয়ার্কশপ স্ক্রিপ্ট চলাকালীন তৈরি হওয়া সমস্ত রিসোর্স সুষ্ঠুভাবে মুছে ফেলার জন্য cleanup_workshop.sh স্ক্রিপ্টটি এই তথ্য ব্যবহার করে। ওয়ার্কশপ তৈরি করা অ্যাডমিনদের অবশ্যই এই বাকেটে রিড/রাইট পারমিশন থাকতে হবে।

বুটস্ট্র্যাপ ওয়ার্কশপ স্ক্রিপ্টটি উপরে প্রদত্ত মানগুলি ব্যবহার করে এবং একটি র‍্যাপার স্ক্রিপ্ট হিসাবে কাজ করে যা setup-terraform-admin-project.sh স্ক্রিপ্টটিকে কল করে। setup-terraform-admin-project.sh স্ক্রিপ্টটি একজন ব্যবহারকারীর জন্য ওয়ার্কশপ পরিবেশ তৈরি করে।

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

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

ADMIN_USER এর জন্য নিম্নলিখিত সাংগঠনিক স্তরের অনুমতিগুলি প্রয়োজন:

  • মালিক - প্রতিষ্ঠানের সকল প্রকল্পের জন্য প্রকল্প মালিকের অনুমতি।
  • ফোল্ডার অ্যাডমিন - প্রতিষ্ঠানের মধ্যে ফোল্ডার তৈরি এবং মুছে ফেলার ক্ষমতা। প্রতিটি ব্যবহারকারী প্রকল্পের মধ্যে তাদের সমস্ত রিসোর্স সহ একটি একক ফোল্ডার পায়।
  • সংগঠন প্রশাসক
  • প্রজেক্ট ক্রিয়েটর - প্রতিষ্ঠানে প্রজেক্ট তৈরি করার ক্ষমতা।
  • প্রজেক্ট ডিলিটার - অর্গানাইজেশন থেকে প্রজেক্ট মুছে ফেলার ক্ষমতা।
  • প্রজেক্ট আইএএম অ্যাডমিন - প্রতিষ্ঠানের সকল প্রজেক্টে আইএএম রুল তৈরি করার ক্ষমতা।

এগুলোর পাশাপাশি, ADMIN_USER অবশ্যই ওয়ার্কশপের জন্য ব্যবহৃত বিলিং আইডির বিলিং অ্যাডমিনিস্ট্রেটরও হতে হবে।

কর্মশালা পরিচালনাকারী ব্যবহারকারীর স্কিমা এবং অনুমতিসমূহ

আপনি যদি আপনার প্রতিষ্ঠানে (নিজেকে ছাড়া) অন্য ব্যবহারকারীদের জন্য এই ওয়ার্কশপটি তৈরি করার পরিকল্পনা করেন, তবে আপনাকে অবশ্যই MY_USERs এর জন্য একটি নির্দিষ্ট ব্যবহারকারী নামকরণের পদ্ধতি অনুসরণ করতে হবে। bootstrap_workshop.sh স্ক্রিপ্ট চলাকালীন, আপনি একটি শুরুর এবং একটি শেষের ব্যবহারকারী নম্বর প্রদান করেন। এই নম্বরগুলো নিম্নলিখিত ব্যবহারকারীর নামগুলো তৈরি করতে ব্যবহৃত হয়:

  • user<3 digit user number>@<organization_name>

উদাহরণস্বরূপ, যদি আপনি আপনার yourcompany.com নামক প্রতিষ্ঠানে স্টার্ট ইউজার নম্বর ১ এবং এন্ড ইউজার নম্বর ৩ দিয়ে বুটস্ট্র্যাপ ওয়ার্কশপ স্ক্রিপ্টটি চালান, তাহলে নিম্নলিখিত ইউজারদের জন্য ওয়ার্কশপ এনভায়রনমেন্টগুলো তৈরি হবে:

  • user001@yourcompany.com
  • user002@yourcompany.com
  • user003@yourcompany.com

setup_terraform_admin_project.sh স্ক্রিপ্ট চলাকালীন তৈরি করা নির্দিষ্ট প্রজেক্টগুলোর জন্য এই ইউজারনেমগুলোকে প্রজেক্ট ওনার (Owner) রোল দেওয়া হয়। বুটস্ট্র্যাপ স্ক্রিপ্ট ব্যবহার করার সময় আপনাকে অবশ্যই এই ইউজার নামকরণের স্কিমাটি মেনে চলতে হবে। GSuite-এ কীভাবে একসাথে একাধিক ইউজার যুক্ত করতে হয়, তা জানতে দেখুন।

কর্মশালার জন্য প্রয়োজনীয় সরঞ্জাম

এই ওয়ার্কশপটি ক্লাউড শেল থেকে শুরু করার জন্য ডিজাইন করা হয়েছে। এই ওয়ার্কশপের জন্য নিম্নলিখিত টুলগুলো প্রয়োজন।

আপনার নিজের জন্য ওয়ার্কশপ সেট আপ করুন (একক ব্যবহারকারী সেটআপ)

  1. ক্লাউড শেল খুলুন এবং এর ভেতরে নিচের সমস্ত কাজ সম্পাদন করুন। নিচের লিঙ্কে ক্লিক করুন।

মেঘের খোলস

  1. নিশ্চিত করুন যে আপনি উদ্দিষ্ট অ্যাডমিন ব্যবহারকারী হিসেবে gcloud-এ লগ ইন করেছেন।
gcloud config list
 
  1. একটি WORKDIR তৈরি করুন এবং ওয়ার্কশপ রিপোটি ক্লোন করুন।
mkdir asm-workshop
cd asm-workshop
export WORKDIR=`pwd`
git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-workshop.git asm
 
  1. আপনার প্রতিষ্ঠানের নাম, বিলিং আইডি, ওয়ার্কশপ নম্বর এবং ওয়ার্কশপের জন্য একটি অ্যাডমিন জিসিএস বাকেট নির্ধারণ করুন। উপরের বিভাগগুলিতে ওয়ার্কশপ সেট আপ করার জন্য প্রয়োজনীয় অনুমতিগুলি পর্যালোচনা করুন।
gcloud organizations list
export ORGANIZATION_NAME=<ORGANIZATION NAME>

gcloud beta billing accounts list
export ADMIN_BILLING_ID=<ADMIN_BILLING ID>

export WORKSHOP_NUMBER=<two digit number for example 01>

export ADMIN_STORAGE_BUCKET=<ADMIN CLOUD STORAGE BUCKET>
 
  1. bootstrap_workshop.sh স্ক্রিপ্টটি চালান। এই স্ক্রিপ্টটি সম্পূর্ণ হতে কয়েক মিনিট সময় লাগতে পারে।
cd asm
./scripts/bootstrap_workshop.sh --org-name ${ORGANIZATION_NAME} --billing-id ${ADMIN_BILLING_ID} --workshop-num ${WORKSHOP_NUMBER} --admin-gcs-bucket ${ADMIN_STORAGE_BUCKET} --set-up-for-admin 
 

bootstrap_workshop.sh স্ক্রিপ্টটি সম্পন্ন হওয়ার পর, অর্গানাইজেশনের প্রতিটি ব্যবহারকারীর জন্য একটি GCP ফোল্ডার তৈরি করা হয়। ফোল্ডারটির ভেতরে একটি টেরাফর্ম অ্যাডমিন প্রজেক্ট তৈরি করা হয়। এই ওয়ার্কশপের জন্য প্রয়োজনীয় বাকি GCP রিসোর্সগুলো তৈরি করতে টেরাফর্ম অ্যাডমিন প্রজেক্টটি ব্যবহার করা হয়। আপনি টেরাফর্ম অ্যাডমিন প্রজেক্টে প্রয়োজনীয় API-গুলো সক্রিয় করেন। টেরাফর্ম প্ল্যানগুলো প্রয়োগ করার জন্য আপনি ক্লাউড বিল্ড ব্যবহার করেন। GCP-তে রিসোর্স তৈরি করতে পারার জন্য আপনি ক্লাউড বিল্ড সার্ভিস অ্যাকাউন্টকে যথাযথ IAM রোল প্রদান করেন। সবশেষে, সমস্ত GCP রিসোর্সের টেরাফর্ম স্টেটগুলো সংরক্ষণ করার জন্য আপনি একটি গুগল ক্লাউড স্টোরেজ (GCS) বাকেটে একটি রিমোট ব্যাকএন্ড কনফিগার করেন।

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

  1. এনভায়রনমেন্ট ভেরিয়েবল সেট করতে ভেরিয়েবল ফাইলটি সোর্স করুন।
echo "export WORKDIR=$WORKDIR" >> $WORKDIR/asm/vars/vars.sh
source $WORKDIR/asm/vars/vars.sh 
 

একাধিক ব্যবহারকারীর জন্য ওয়ার্কশপ সেট আপ করুন (মাল্টি ইউজার সেটআপ)

  1. ক্লাউড শেল খুলুন এবং এর ভেতরে নিচের সমস্ত কাজ সম্পাদন করুন। নিচের লিঙ্কে ক্লিক করুন।

মেঘের খোলস

  1. নিশ্চিত করুন যে আপনি উদ্দিষ্ট অ্যাডমিন ব্যবহারকারী হিসেবে gcloud-এ লগ ইন করেছেন।
gcloud config list
 
  1. একটি WORKDIR তৈরি করুন এবং ওয়ার্কশপ রিপোটি ক্লোন করুন।
mkdir asm-workshop
cd asm-workshop
export WORKDIR=`pwd`
git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-workshop.git asm
 
  1. আপনার প্রতিষ্ঠানের নাম, বিলিং আইডি, ওয়ার্কশপ নম্বর, শুরু ও শেষ ব্যবহারকারী নম্বর এবং ওয়ার্কশপের জন্য একটি অ্যাডমিন জিসিএস বাকেট নির্ধারণ করুন। উপরের বিভাগগুলিতে ওয়ার্কশপ সেট আপ করার জন্য প্রয়োজনীয় অনুমতিগুলি পর্যালোচনা করুন।
gcloud organizations list
export ORGANIZATION_NAME=<ORGANIZATION NAME>

gcloud beta billing accounts list
export ADMIN_BILLING_ID=<BILLING ID>

export WORKSHOP_NUMBER=<two digit number for example 01>

export START_USER_NUMBER=<number for example 1>

export END_USER_NUMBER=<number greater or equal to START_USER_NUM>

export ADMIN_STORAGE_BUCKET=<ADMIN CLOUD STORAGE BUCKET>
 
  1. bootstrap_workshop.sh স্ক্রিপ্টটি চালান। এই স্ক্রিপ্টটি সম্পূর্ণ হতে কয়েক মিনিট সময় লাগতে পারে।
cd asm
./scripts/bootstrap_workshop.sh --org-name ${ORGANIZATION_NAME} --billing-id ${ADMIN_BILLING_ID} --workshop-num ${WORKSHOP_NUMBER} --start-user-num ${START_USER_NUMBER} --end-user-num ${END_USER_NUMBER} --admin-gcs-bucket ${ADMIN_STORAGE_BUCKET}
 
  1. টেরাফর্ম প্রজেক্ট আইডিগুলো পুনরুদ্ধার করতে অ্যাডমিন GCS বাকেট থেকে workshop.txt ফাইলটি নিন।
export WORKSHOP_ID="$(date '+%y%m%d')-${WORKSHOP_NUMBER}"
gsutil cp gs://${ADMIN_STORAGE_BUCKET}/${ORGANIZATION_NAME}/${WORKSHOP_ID}/workshop.txt .
 

৪. ল্যাব স্থাপন ও প্রস্তুতি

আপনার ল্যাবের পথ বেছে নিন

এই কর্মশালার ল্যাবগুলো দুটি উপায়ের যেকোনো একটিতে সম্পন্ন করা যেতে পারে:

  • " সহজ দ্রুত ইন্টারেক্টিভ স্ক্রিপ্ট " পদ্ধতি
  • " প্রতিটি নির্দেশনা হাতে-কলমে কপি-পেস্ট করার " পদ্ধতি

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

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

কপি-পেস্ট পদ্ধতি হলো কমান্ডের ব্যাখ্যাসহ স্বতন্ত্র কমান্ড ব্লক কপি-পেস্ট করার একটি প্রচলিত উপায়। এই পদ্ধতিটি শুধুমাত্র একবার চালানোর জন্য তৈরি করা হয়েছে। এই পদ্ধতিতে কমান্ডগুলো পুনরায় চালালে যে একই ফলাফল পাওয়া যাবে, তার কোনো নিশ্চয়তা নেই।

ল্যাবগুলো করার সময়, অনুগ্রহ করে দুটি পদ্ধতির মধ্যে একটি বেছে নিন।

ফাস্ট ট্র্যাক স্ক্রিপ্ট সেটআপ

ব্যবহারকারীর তথ্য পান

এই ওয়ার্কশপটি ওয়ার্কশপের অ্যাডমিনিস্ট্রেটর দ্বারা তৈরি একটি অস্থায়ী ইউজার অ্যাকাউন্ট (বা একটি ল্যাব অ্যাকাউন্ট) ব্যবহার করে সম্পন্ন করা হয়। এই ল্যাব অ্যাকাউন্টটি ওয়ার্কশপের সমস্ত প্রজেক্টের মালিক। ওয়ার্কশপ অ্যাডমিনিস্ট্রেটর ওয়ার্কশপ পরিচালনাকারী ব্যবহারকারীকে ল্যাব অ্যাকাউন্টের ক্রেডেনশিয়াল (ইউজারনেম এবং পাসওয়ার্ড) প্রদান করেন। ব্যবহারকারীর সমস্ত প্রজেক্টের নামের শুরুতে ল্যাব অ্যাকাউন্টের ইউজারনেম যুক্ত থাকে, উদাহরণস্বরূপ, user001@yourcompany.com ল্যাব অ্যাকাউন্টের জন্য টেরাফর্ম অ্যাডমিন প্রজেক্ট আইডি হবে user001-200131-01-tf-abcde এবং বাকি প্রজেক্টগুলোর ক্ষেত্রেও একইভাবে প্রযোজ্য। প্রত্যেক ব্যবহারকারীকে অবশ্যই ওয়ার্কশপ অ্যাডমিনিস্ট্রেটর দ্বারা প্রদত্ত ল্যাব অ্যাকাউন্ট দিয়ে লগ ইন করতে হবে এবং সেই ল্যাব অ্যাকাউন্ট ব্যবহার করেই ওয়ার্কশপটি সম্পন্ন করতে হবে।

  1. নিচের লিঙ্কে ক্লিক করে ক্লাউড শেল খুলুন।

মেঘের খোলস

  1. ল্যাব অ্যাকাউন্টের ক্রেডেনশিয়াল দিয়ে লগ ইন করুন (আপনার কর্পোরেট বা ব্যক্তিগত অ্যাকাউন্ট দিয়ে লগ ইন করবেন না)। ল্যাব অ্যাকাউন্টটি userXYZ@<workshop_domain>.com এর মতো দেখতে হয়। 3101eca1fd3722bf.png
  2. যেহেতু এটি একটি নতুন অ্যাকাউন্ট, তাই আপনাকে গুগলের পরিষেবার শর্তাবলী গ্রহণ করতে বলা হবে। 'গ্রহণ করুন' (Accept) বোতামে ক্লিক করুন।

fb0219a89ece5168.png ৪. পরবর্তী স্ক্রিনে, গুগলের পরিষেবার শর্তাবলীতে সম্মত হতে চেকবক্সটি নির্বাচন করুন এবং Start Cloud Shell এ ক্লিক করুন।

7b198cf2e32cb457.png

এই ধাপে আপনার জন্য একটি ছোট লিনাক্স ডেবিয়ান ভিএম প্রস্তুত করা হয়, যা আপনি GCP রিসোর্স অ্যাক্সেস করতে ব্যবহার করতে পারবেন। প্রতিটি অ্যাকাউন্ট একটি ক্লাউড শেল ভিএম পায়। ল্যাব অ্যাকাউন্ট দিয়ে লগ ইন করলে, ল্যাব অ্যাকাউন্টের ক্রেডেনশিয়াল ব্যবহার করে আপনাকে লগ ইন করানো হয়। ক্লাউড শেল ছাড়াও, একটি কোড এডিটরও প্রস্তুত করা হয়, যা কনফিগারেশন ফাইল (টেরাফর্ম, YAML ইত্যাদি) সম্পাদনা করা সহজ করে তোলে। ডিফল্টরূপে, ক্লাউড শেল স্ক্রিনটি ক্লাউড শেল শেল এনভায়রনমেন্ট (নিচে) এবং ক্লাউড কোড এডিটর (উপরে) অংশে বিভক্ত থাকে। 5643bb4ebeafd00a.png পেন্সিল 8bca25ef1421c17e.png এবং শেল প্রম্পট eaeb4ac333783ba8.png উপরের ডান কোণার আইকনগুলো আপনাকে দুটির (শেল এবং কোড এডিটর) মধ্যে টগল করতে দেয়। এছাড়াও আপনি মাঝের বিভাজক বারটি (উপরে বা নিচে) টেনে প্রতিটি উইন্ডোর আকার ম্যানুয়ালি পরিবর্তন করতে পারেন। ৫. এই ওয়ার্কশপের জন্য একটি WORKDIR তৈরি করুন। WORKDIR হলো এমন একটি ফোল্ডার যেখান থেকে আপনি এই ওয়ার্কশপের সমস্ত ল্যাব সম্পন্ন করবেন। WORKDIR তৈরি করতে ক্লাউড শেলে নিম্নলিখিত কমান্ডগুলো চালান।

mkdir -p ${HOME}/asm-workshop
cd ${HOME}/asm-workshop
export WORKDIR=`pwd` 
 
  1. এই ওয়ার্কশপের জন্য ল্যাব অ্যাকাউন্টের ব্যবহারকারীকে একটি ভেরিয়েবল হিসেবে এক্সপোর্ট করুন। এই সেই অ্যাকাউন্ট যা দিয়ে আপনি ক্লাউড শেলে লগ ইন করেছেন।
export MY_USER=<LAB ACCOUNT EMAIL PROVIDED BY THE WORKSHOP ADMIN>
# For example export MY_USER=user001@gcpworkshops.com 
 
  1. নিম্নলিখিত কমান্ডগুলো চালিয়ে WORKDIR এবং MY_USER ভেরিয়েবল দুটি সঠিকভাবে সেট করা আছে কিনা তা নিশ্চিত করুন।
echo "WORKDIR set to ${WORKDIR}" && echo "MY_USER set to ${MY_USER}"
 
  1. ওয়ার্কশপ রিপোটি ক্লোন করুন।
git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-workshop.git ${WORKDIR}/asm
 

৫. পরিকাঠামো স্থাপন - ব্যবহারকারীর কর্মপ্রবাহ

উদ্দেশ্য: পরিকাঠামো এবং Istio ইনস্টলেশন যাচাই করা

  • ওয়ার্কশপ টুলস ইনস্টল করুন
  • ক্লোন ওয়ার্কশপ রিপো
  • Infrastructure ইনস্টলেশন যাচাই করুন
  • k8s-repo ইনস্টলেশন যাচাই করুন
  • Istio ইনস্টলেশন যাচাই করুন

কপি-পেস্ট পদ্ধতি ল্যাব নির্দেশাবলী

ব্যবহারকারীর তথ্য পান

ওয়ার্কশপটি সেট আপ করার জন্য অ্যাডমিনিস্ট্রেটরকে ব্যবহারকারীকে ইউজারনেম এবং পাসওয়ার্ডের তথ্য প্রদান করতে হবে। ব্যবহারকারীর সমস্ত প্রজেক্টের নামের শুরুতে ইউজারনেমটি যুক্ত থাকবে, উদাহরণস্বরূপ, user001@yourcompany.com ব্যবহারকারীর জন্য টেরাফর্ম অ্যাডমিন প্রজেক্ট আইডি হবে user001-200131-01-tf-abcde এবং বাকি প্রজেক্টগুলোর ক্ষেত্রেও একইভাবে প্রযোজ্য হবে। প্রত্যেক ব্যবহারকারী শুধুমাত্র তার নিজের ওয়ার্কশপ এনভায়রনমেন্টে প্রবেশাধিকার পাবে।

কর্মশালার জন্য প্রয়োজনীয় সরঞ্জাম

এই ওয়ার্কশপটি ক্লাউড শেল থেকে শুরু করার জন্য ডিজাইন করা হয়েছে। এই ওয়ার্কশপের জন্য নিম্নলিখিত টুলগুলো প্রয়োজন।

টেরাফর্ম অ্যাডমিন প্রজেক্ট অ্যাক্সেস করুন

bootstrap_workshop.sh স্ক্রিপ্টটি সম্পন্ন হওয়ার পর, অর্গানাইজেশনের প্রতিটি ব্যবহারকারীর জন্য একটি GCP ফোল্ডার তৈরি করা হয়। ফোল্ডারটির ভেতরে একটি টেরাফর্ম অ্যাডমিন প্রজেক্ট তৈরি করা হয়। এই ওয়ার্কশপের জন্য প্রয়োজনীয় বাকি GCP রিসোর্সগুলো তৈরি করতে টেরাফর্ম অ্যাডমিন প্রজেক্টটি ব্যবহার করা হয়। setup-terraform-admin-project.sh স্ক্রিপ্টটি টেরাফর্ম অ্যাডমিন প্রজেক্টে প্রয়োজনীয় API-গুলো সক্রিয় করে। টেরাফর্ম প্ল্যানগুলো প্রয়োগ করার জন্য ক্লাউড বিল্ড ব্যবহার করা হয়। স্ক্রিপ্টটির মাধ্যমে, আপনি ক্লাউড বিল্ড সার্ভিস অ্যাকাউন্টকে যথাযথ IAM রোল প্রদান করেন, যাতে এটি GCP-তে রিসোর্স তৈরি করতে পারে। সবশেষে, সমস্ত GCP রিসোর্সের টেরাফর্ম স্টেটগুলো সংরক্ষণ করার জন্য একটি গুগল ক্লাউড স্টোরেজ (GCS) বাকেটে একটি রিমোট ব্যাকএন্ড কনফিগার করা হয়।

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

  1. নিচের লিঙ্কে ক্লিক করে ক্লাউড শেল খুলুন (যদি এটি ল্যাব সেটআপ এবং প্রস্তুতি বিভাগ থেকে আগে থেকেই খোলা না থাকে)।

মেঘের খোলস

  1. $HOME/bin ফোল্ডারে kustomize ইনস্টল করুন (যদি আগে থেকে ইনস্টল করা না থাকে) এবং $HOME/bin ফোল্ডারটিকে $PATH-এ যুক্ত করুন।
mkdir -p $HOME/bin
cd $HOME/bin
curl -s "https://raw.githubusercontent.com/\
kubernetes-sigs/kustomize/master/hack/install_kustomize.sh"  | bash
cd $HOME
export PATH=$PATH:${HOME}/bin
echo "export PATH=$PATH:$HOME/bin" >> $HOME/.bashrc
 
  1. pv ইনস্টল করুন এবং এটিকে $HOME/bin/pv-তে স্থানান্তর করুন।
sudo apt-get update && sudo apt-get -y install pv
sudo mv /usr/bin/pv ${HOME}/bin/pv
 
  1. আপনার ব্যাশ প্রম্পট আপডেট করুন।
cp $WORKDIR/asm/scripts/krompt.bash $HOME/.krompt.bash
echo "export PATH=\$PATH:\$HOME/bin" >> $HOME/.asm-workshop.bash
echo "source $HOME/.krompt.bash" >> $HOME/.asm-workshop.bash

alias asm-init='source $HOME/.asm-workshop.bash' >> $HOME/.bashrc
echo "source $HOME/.asm-workshop.bash" >> $HOME/.bashrc
source $HOME/.bashrc
 
  1. নিশ্চিত করুন যে আপনি উদ্দিষ্ট ইউজার অ্যাকাউন্ট দিয়ে gcloud-এ লগ ইন করেছেন।
echo "Check logged in user output from the next command is $MY_USER"
gcloud config list account --format=json | jq -r .core.account
 
  1. নিম্নলিখিত কমান্ডটি চালিয়ে আপনার Terraform অ্যাডমিন প্রজেক্ট আইডি সংগ্রহ করুন:
export TF_ADMIN=$(gcloud projects list | grep tf- | awk '{ print $1 }')
echo $TF_ADMIN
 
  1. ওয়ার্কশপের সাথে সম্পর্কিত সমস্ত রিসোর্স টেরাফর্ম অ্যাডমিন প্রজেক্টের GCS বাকেটে থাকা vars.sh ফাইলে ভ্যারিয়েবল হিসেবে সংরক্ষিত থাকে। আপনার টেরাফর্ম অ্যাডমিন প্রজেক্টের জন্য vars.sh ফাইলটি সংগ্রহ করুন।
mkdir $WORKDIR/asm/vars
gsutil cp gs://$TF_ADMIN/vars/vars.sh $WORKDIR/asm/vars/vars.sh
echo "export WORKDIR=$WORKDIR" >> $WORKDIR/asm/vars/vars.sh
 
  1. টেরাফর্ম অ্যাডমিন প্রজেক্টের ক্লাউড বিল্ড পেজটি খুলতে প্রদর্শিত লিঙ্কে ক্লিক করুন এবং বিল্ডটি সফলভাবে সম্পন্ন হয়েছে কিনা তা যাচাই করুন।
source $WORKDIR/asm/vars/vars.sh
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_ADMIN}"
 

প্রথমবার ক্লাউড কনসোল ব্যবহার করলে, গুগলের পরিষেবার শর্তাবলীতে সম্মত হন।

  1. এখন যেহেতু আপনি ক্লাউড বিল্ড পেজটি দেখছেন, বাম দিকের নেভিগেশন থেকে History লিঙ্কে ক্লিক করুন এবং প্রাথমিক টেরাফর্ম অ্যাপ্লাইয়ের বিবরণ দেখতে সর্বশেষ বিল্ডটিতে ক্লিক করুন। টেরাফর্ম স্ক্রিপ্টের অংশ হিসেবে নিম্নলিখিত রিসোর্সগুলো তৈরি করা হয়। আপনি উপরের আর্কিটেকচার ডায়াগ্রামটিও দেখতে পারেন।
  • প্রতিষ্ঠানে ৪টি GCP প্রজেক্ট রয়েছে। প্রদত্ত বিলিং অ্যাকাউন্টটি প্রতিটি প্রজেক্টের সাথে যুক্ত।
  • একটি প্রজেক্ট হলো শেয়ার্ড ভিপিসি-র network host project । এই প্রজেক্টে অন্য কোনো রিসোর্স তৈরি করা হয় না।
  • একটি প্রকল্প হলো Istio কন্ট্রোল প্লেন GKE ক্লাস্টারের জন্য ব্যবহৃত ops project
  • দুটি প্রকল্প দুটি ভিন্ন উন্নয়ন দলের প্রতিনিধিত্ব করে, যারা তাদের নিজ নিজ পরিষেবা নিয়ে কাজ করছে।
  • ops , dev1 এবং dev2 প্রজেক্টগুলোর প্রতিটিতে দুটি করে GKE ক্লাস্টার তৈরি করা হয়েছে।
  • k8s-repo নামে একটি CSR রিপো তৈরি করা হয়, যাতে Kubernetes ম্যানিফেস্ট ফাইলগুলির জন্য ছয়টি ফোল্ডার থাকে। প্রতিটি GKE ক্লাস্টারের জন্য একটি করে ফোল্ডার। এই রিপোটি GitOps পদ্ধতিতে ক্লাস্টারগুলিতে Kubernetes ম্যানিফেস্টগুলি ডেপ্লয় করতে ব্যবহৃত হয়।
  • একটি ক্লাউড বিল্ড ট্রিগার তৈরি করা হয়েছে, যাতে k8s-repo এর মাস্টার ব্রাঞ্চে যখনই কোনো কমিট হয়, তখনই এটি কুবারনেটিস ম্যানিফেস্টগুলোকে তাদের নিজ নিজ ফোল্ডার থেকে GKE ক্লাস্টারগুলোতে ডেপ্লয় করে।
  1. terraform admin project বিল্ড সম্পন্ন হলে অপস প্রজেক্টে আরেকটি বিল্ড শুরু হবে। ops project ক্লাউড বিল্ড পেজটি খুলতে প্রদর্শিত লিঙ্কে ক্লিক করুন এবং k8s-repo ক্লাউড বিল্ড সফলভাবে সম্পন্ন হয়েছে কিনা তা যাচাই করুন।
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_VAR_ops_project_name}"
 

ইনস্টলেশন যাচাই করুন

  1. সকল ক্লাস্টারের জন্য কিউবকনফিগ ফাইল তৈরি করুন। নিম্নলিখিত স্ক্রিপ্টটি চালান।
$WORKDIR/asm/scripts/setup-gke-vars-kubeconfig.sh
 

এই স্ক্রিপ্টটি gke ফোল্ডারে kubemesh নামে একটি নতুন kubeconfig ফাইল তৈরি করে।

  1. KUBECONFIG ভেরিয়েবলটি পরিবর্তন করে নতুন kubeconfig ফাইলটিকে নির্দেশ করুন।
source $WORKDIR/asm/vars/vars.sh
export KUBECONFIG=$WORKDIR/asm/gke/kubemesh
 
  1. Cloud Shell-এর .bashrc ফাইলে vars.sh এবং KUBECONFIG ভ্যারিয়েবল দুটি যোগ করুন, যাতে প্রতিবার Cloud Shell রিস্টার্ট করার সময় এগুলো সোর্স হয়।
echo "source ${WORKDIR}/asm/vars/vars.sh" >> $HOME/.bashrc
echo "export KUBECONFIG=${WORKDIR}/asm/gke/kubemesh" >> $HOME/.bashrc
 
  1. আপনার ক্লাস্টার কনটেক্সটগুলো তালিকাভুক্ত করুন। আপনি ছয়টি ক্লাস্টার দেখতে পাবেন।
kubectl config view -ojson | jq -r '.clusters[].name'
 
    `Output (do not copy)`
gke_tf05-01-ops_us-central1_gke-asm-2-r2-prod
gke_tf05-01-ops_us-west1_gke-asm-1-r1-prod
gke_tf05-02-dev1_us-west1-a_gke-1-apps-r1a-prod
gke_tf05-02-dev1_us-west1-b_gke-2-apps-r1b-prod
gke_tf05-03-dev2_us-central1-a_gke-3-apps-r2a-prod
gke_tf05-03-dev2_us-central1-b_gke-4-apps-r2b-prod

Istio ইনস্টলেশন যাচাই করুন

  1. সমস্ত পড চলছে এবং কাজগুলো সম্পন্ন হয়েছে কিনা তা পরীক্ষা করে নিশ্চিত করুন যে উভয় ক্লাস্টারেই Istio ইনস্টল করা আছে।
kubectl --context ${OPS_GKE_1} get pods -n istio-system
kubectl --context ${OPS_GKE_2} get pods -n istio-system
 
    `Output (do not copy)`
NAME                                      READY   STATUS    RESTARTS   AGE
grafana-5f798469fd-z9f98                  1/1     Running   0          6m21s
istio-citadel-568747d88-qdw64             1/1     Running   0          6m26s
istio-egressgateway-8f454cf58-ckw7n       1/1     Running   0          6m25s
istio-galley-6b9495645d-m996v             2/2     Running   0          6m25s
istio-ingressgateway-5df799fdbd-8nqhj     1/1     Running   0          2m57s
istio-pilot-67fd786f65-nwmcb              2/2     Running   0          6m24s
istio-policy-74cf89cb66-4wrpl             2/2     Running   1          6m25s
istio-sidecar-injector-759bf6b4bc-mw4vf   1/1     Running   0          6m25s
istio-telemetry-77b6dfb4ff-zqxzz          2/2     Running   1          6m24s
istio-tracing-cd67ddf8-n4d7k              1/1     Running   0          6m25s
istiocoredns-5f7546c6f4-g7b5c             2/2     Running   0          6m39s
kiali-7964898d8c-5twln                    1/1     Running   0          6m23s
prometheus-586d4445c7-xhn8d               1/1     Running   0          6m25s
    `Output (do not copy)`
NAME                                      READY   STATUS    RESTARTS   AGE
grafana-5f798469fd-2s8k4                  1/1     Running   0          59m
istio-citadel-568747d88-87kdj             1/1     Running   0          59m
istio-egressgateway-8f454cf58-zj9fs       1/1     Running   0          60m
istio-galley-6b9495645d-qfdr6             2/2     Running   0          59m
istio-ingressgateway-5df799fdbd-2c9rc     1/1     Running   0          60m
istio-pilot-67fd786f65-nzhx4              2/2     Running   0          59m
istio-policy-74cf89cb66-4bc7f             2/2     Running   3          59m
istio-sidecar-injector-759bf6b4bc-grk24   1/1     Running   0          59m
istio-telemetry-77b6dfb4ff-6zr94          2/2     Running   4          60m
istio-tracing-cd67ddf8-grs9g              1/1     Running   0          60m
istiocoredns-5f7546c6f4-gxd66             2/2     Running   0          60m
kiali-7964898d8c-nhn52                    1/1     Running   0          59m
prometheus-586d4445c7-xr44v               1/1     Running   0          59m
  1. নিশ্চিত করুন যে উভয় dev1 ক্লাস্টারেই Istio ইনস্টল করা আছে। dev1 ক্লাস্টারগুলিতে শুধুমাত্র Citadel, sidecar-injector এবং coredns চলে। এগুলি ops-1 ক্লাস্টারে চলমান একটি Istio কন্ট্রোলপ্লেন শেয়ার করে।
kubectl --context ${DEV1_GKE_1} get pods -n istio-system
kubectl --context ${DEV1_GKE_2} get pods -n istio-system
 
  1. নিশ্চিত করুন যে উভয় dev2 ক্লাস্টারেই Istio ইনস্টল করা আছে। dev2 ক্লাস্টারগুলিতে শুধুমাত্র Citadel, sidecar-injector এবং coredns চলে। এগুলি ops-2 ক্লাস্টারে চলমান একটি Istio কন্ট্রোলপ্লেন শেয়ার করে।
kubectl --context ${DEV2_GKE_1} get pods -n istio-system
kubectl --context ${DEV2_GKE_2} get pods -n istio-system
 
    `Output (do not copy)`
NAME                                      READY   STATUS    RESTARTS   AGE
istio-citadel-568747d88-4lj9b             1/1     Running   0          66s
istio-sidecar-injector-759bf6b4bc-ks5br   1/1     Running   0          66s
istiocoredns-5f7546c6f4-qbsqm             2/2     Running   0          78s

শেয়ার্ড কন্ট্রোল প্লেনগুলির জন্য সার্ভিস ডিসকভারি যাচাই করুন

  1. ঐচ্ছিকভাবে, গোপনীয় তথ্যগুলো স্থাপন করা হয়েছে কিনা তা যাচাই করুন।
kubectl --context ${OPS_GKE_1} get secrets -l istio/multiCluster=true -n istio-system
kubectl --context ${OPS_GKE_2} get secrets -l istio/multiCluster=true -n istio-system
 
    `Output (do not copy)`
For OPS_GKE_1:
NAME                  TYPE     DATA   AGE
gke-1-apps-r1a-prod   Opaque   1      8m7s
gke-2-apps-r1b-prod   Opaque   1      8m7s
gke-3-apps-r2a-prod   Opaque   1      44s
gke-4-apps-r2b-prod   Opaque   1      43s

For OPS_GKE_2:
NAME                  TYPE     DATA   AGE
gke-1-apps-r1a-prod   Opaque   1      40s
gke-2-apps-r1b-prod   Opaque   1      40s
gke-3-apps-r2a-prod   Opaque   1      8m4s
gke-4-apps-r2b-prod   Opaque   1      8m4s

এই ওয়ার্কশপে, আপনি একটিমাত্র শেয়ার্ড VPC ব্যবহার করেন যেখানে সমস্ত GKE ক্লাস্টার তৈরি করা হয়। ক্লাস্টারগুলোর মধ্যে সার্ভিস খুঁজে বের করার জন্য, আপনি অপস ক্লাস্টারে সিক্রেট হিসেবে তৈরি করা কিউবকনফিগ ফাইলগুলো (প্রতিটি অ্যাপ্লিকেশন ক্লাস্টারের জন্য) ব্যবহার করেন। পাইলট এই সিক্রেটগুলো ব্যবহার করে অ্যাপ্লিকেশন ক্লাস্টারগুলোর কিউব এপিআই সার্ভারকে কোয়েরি করার মাধ্যমে সার্ভিস খুঁজে বের করে (যা উপরের সিক্রেটগুলোর মাধ্যমে অথেনটিকেটেড হয়)। আপনি দেখতে পাবেন যে, উভয় অপস ক্লাস্টারই কিউবকনফিগ-এ তৈরি করা সিক্রেট ব্যবহার করে সমস্ত অ্যাপ ক্লাস্টারে অথেনটিকেট করতে পারে। অপস ক্লাস্টারগুলো কিউবকনফিগ ফাইলগুলোকে একটি সিক্রেট মেথড হিসেবে ব্যবহার করে স্বয়ংক্রিয়ভাবে সার্ভিস খুঁজে বের করতে পারে। এর জন্য প্রয়োজন যে, অপস ক্লাস্টারের পাইলটের যেন অন্য সব ক্লাস্টারের কিউব এপিআই সার্ভারে অ্যাক্সেস থাকে। যদি পাইলট কিউব এপিআই সার্ভারগুলোতে পৌঁছাতে না পারে, তবে আপনাকে ম্যানুয়ালি রিমোট সার্ভিসগুলোকে সার্ভিসএন্ট্রি হিসেবে যোগ করতে হবে। আপনি সার্ভিসএন্ট্রিগুলোকে আপনার সার্ভিস রেজিস্ট্রির ডিএনএস এন্ট্রি হিসেবে ভাবতে পারেন। সার্ভিসএন্ট্রি একটি সম্পূর্ণ যোগ্য ডিএনএস নাম ( FQDN ) এবং একটি আইপি অ্যাড্রেস ব্যবহার করে একটি সার্ভিসকে সংজ্ঞায়িত করে, যেখান থেকে এটিতে পৌঁছানো যায়। আরও তথ্যের জন্য ইস্তিও মাল্টিক্লাস্টার ডক্স দেখুন।

৬. ইনফ্রাস্ট্রাকচার রিপো ব্যাখ্যা করা হলো

অবকাঠামো ক্লাউড নির্মাণ

ওয়ার্কশপের জন্য GCP রিসোর্সগুলো ক্লাউড বিল্ড এবং একটি infrastructure CSR রিপো ব্যবহার করে তৈরি করা হয়। আপনি এইমাত্র আপনার লোকাল টার্মিনাল থেকে একটি বুটস্ট্র্যাপ স্ক্রিপ্ট (যা scripts/bootstrap_workshop.sh এ অবস্থিত) রান করেছেন। বুটস্ট্র্যাপ স্ক্রিপ্টটি একটি GCP ফোল্ডার, একটি টেরাফর্ম অ্যাডমিন প্রজেক্ট এবং ক্লাউড বিল্ড সার্ভিস অ্যাকাউন্টের জন্য উপযুক্ত IAM পারমিশন তৈরি করে। টেরাফর্ম অ্যাডমিন প্রজেক্টটি টেরাফর্ম স্টেট, লগ এবং বিভিন্ন স্ক্রিপ্ট সংরক্ষণের জন্য ব্যবহৃত হয়। এতে infrastructure এবং k8s_repo CSR রিপোগুলো রয়েছে। এই রিপোগুলো পরবর্তী সেকশনে বিস্তারিতভাবে ব্যাখ্যা করা হয়েছে। টেরাফর্ম অ্যাডমিন প্রজেক্টে ওয়ার্কশপের অন্য কোনো রিসোর্স তৈরি করা হয় না। টেরাফর্ম অ্যাডমিন প্রজেক্টের ক্লাউড বিল্ড সার্ভিস অ্যাকাউন্টটি ওয়ার্কশপের জন্য রিসোর্স তৈরি করতে ব্যবহৃত হয়।

ওয়ার্কশপের জন্য GCP রিসোর্স বিল্ড করতে infrastructure ফোল্ডারে অবস্থিত cloudbuild.yaml ফাইলটি ব্যবহৃত হয়। এটি GCP রিসোর্স তৈরির জন্য প্রয়োজনীয় সমস্ত টুলসহ একটি কাস্টম বিল্ডার ইমেজ তৈরি করে। এই টুলগুলোর মধ্যে রয়েছে gcloud SDK, terraform এবং python, git, jq ইত্যাদির মতো অন্যান্য ইউটিলিটি। কাস্টম বিল্ডার ইমেজটি প্রতিটি রিসোর্সের জন্য terraform plan এবং apply রান করে। প্রতিটি রিসোর্সের terraform ফাইলগুলো আলাদা আলাদা ফোল্ডারে থাকে (বিস্তারিত পরবর্তী বিভাগে)। রিসোর্সগুলো একবারে একটি করে এবং সাধারণত যেভাবে বিল্ড করা হয় সেই ক্রমানুসারে বিল্ড করা হয় (উদাহরণস্বরূপ, একটি GCP প্রজেক্টে রিসোর্স তৈরি করার আগে প্রজেক্টটি বিল্ড করা হয়)। আরও বিস্তারিত জানতে অনুগ্রহ করে cloudbuild.yaml ফাইলটি পর্যালোচনা করুন।

infrastructure রিপোতে কোনো কমিট করা হলেই ক্লাউড বিল্ড চালু হয়। ইনফ্রাস্ট্রাকচারে করা যেকোনো পরিবর্তনকে ইনফ্রাস্ট্রাকচার অ্যাজ কোড (IaC) হিসেবে সংরক্ষণ করা হয় এবং রিপোতে কমিট করা হয়। আপনার ওয়ার্কশপের অবস্থা সর্বদা এই রিপোতে সংরক্ষিত থাকে।

ফোল্ডার কাঠামো - দল, পরিবেশ এবং সম্পদ

ইনফ্রাস্ট্রাকচার রিপো ওয়ার্কশপের জন্য GCP ইনফ্রাস্ট্রাকচার রিসোর্সগুলো সেট আপ করে। এটি ফোল্ডার এবং সাবফোল্ডারে বিভক্ত। রিপোর ভেতরের বেস ফোল্ডারগুলো সেই team প্রতিনিধিত্ব করে, যারা নির্দিষ্ট GCP রিসোর্সের মালিক। ফোল্ডারের পরবর্তী স্তরটি টিমের জন্য নির্দিষ্ট environment প্রতিনিধিত্ব করে (যেমন dev, stage, prod)। এনভায়রনমেন্টের ভেতরের ফোল্ডারের পরবর্তী স্তরটি নির্দিষ্ট resource প্রতিনিধিত্ব করে (যেমন host_project, gke_clusters ইত্যাদি)। প্রয়োজনীয় স্ক্রিপ্ট এবং টেরাফর্ম ফাইলগুলো রিসোর্স ফোল্ডারগুলোর ভেতরে থাকে।

434fc1769bb49b8c.png

এই কর্মশালায় নিম্নলিখিত চার ধরনের দল প্রতিনিধিত্ব করছে:

  1. ইনফ্রাস্ট্রাকচার - ক্লাউড ইনফ্রাস্ট্রাকচার টিমের প্রতিনিধিত্ব করে। অন্য সব টিমের জন্য GCP রিসোর্স তৈরির দায়িত্ব তাদের। তারা তাদের রিসোর্সের জন্য টেরাফর্ম অ্যাডমিন প্রজেক্ট ব্যবহার করে। ইনফ্রাস্ট্রাকচার রিপোটি স্বয়ং টেরাফর্ম অ্যাডমিন প্রজেক্টের মধ্যেই থাকে, সেইসাথে টেরাফর্ম স্টেট ফাইলগুলোও (যা নিচে ব্যাখ্যা করা হয়েছে)। এই রিসোর্সগুলো বুটস্ট্র্যাপ প্রক্রিয়ার সময় একটি ব্যাশ স্ক্রিপ্ট দ্বারা তৈরি করা হয় (বিস্তারিত জানতে মডিউল ০ - অ্যাডমিনিস্ট্রেটর ওয়ার্কফ্লো দেখুন)।
  2. নেটওয়ার্ক - নেটওয়ার্কিং টিমের প্রতিনিধিত্ব করে। তারা ভিপিসি (VPC) এবং নেটওয়ার্কিং রিসোর্সের জন্য দায়ী। তারা নিম্নলিখিত জিসিপি (GCP) রিসোর্সগুলোর মালিক।
  3. host project - এটি শেয়ার্ড ভিপিসি হোস্ট প্রজেক্টকে বোঝায়।
  4. shared VPC - এটি শেয়ার্ড ভিপিসি, সাবনেট, সেকেন্ডারি আইপি রেঞ্জ, রাউট এবং ফায়ারওয়াল নিয়মসমূহকে বোঝায়।
  5. ops - অপারেশনস/ডেভঅপস টিমের প্রতিনিধিত্ব করে। তারা নিম্নলিখিত রিসোর্সগুলোর মালিক।
  6. ops project - এটি সকল অপারেশনস রিসোর্সের জন্য একটি প্রকল্পকে বোঝায়।
  7. gke clusters – প্রতিটি অঞ্চলের জন্য একটি করে ওপিএস জিকেই ক্লাস্টার। প্রতিটি ওপিএস জিকেই ক্লাস্টারে ইস্তিও কন্ট্রোল প্লেন ইনস্টল করা থাকে।
  8. k8s-repo - একটি CSR রিপো যাতে সকল GKE ক্লাস্টারের GKE ম্যানিফেস্টগুলো রয়েছে।
  9. অ্যাপস - অ্যাপ্লিকেশন টিমগুলোকে বোঝায়। এই ওয়ার্কশপটি app1 এবং app2 নামে দুটি টিমকে সিমুলেট করে। তাদের নিম্নলিখিত রিসোর্সগুলো রয়েছে।
  10. app projects - প্রতিটি অ্যাপ টিম তাদের নিজস্ব কিছু প্রজেক্ট পায়। এর মাধ্যমে তারা তাদের নির্দিষ্ট প্রজেক্টের বিলিং এবং আইএএম (IAM) নিয়ন্ত্রণ করতে পারে।
  11. gke clusters - এগুলো হলো অ্যাপ্লিকেশন ক্লাস্টার যেখানে অ্যাপ্লিকেশন কন্টেইনার/পডগুলো চলে।
  12. gce instances - ঐচ্ছিকভাবে, যদি তাদের এমন অ্যাপ্লিকেশন থাকে যা জিসিই ইনস্ট্যান্সে চলে। এই ওয়ার্কশপে, অ্যাপ১-এর কয়েকটি জিসিই ইনস্ট্যান্স রয়েছে যেখানে অ্যাপ্লিকেশনটির একটি অংশ চলে।

এই কর্মশালায়, একই অ্যাপ (হিপস্টার শপ অ্যাপ) অ্যাপ১ এবং অ্যাপ২ উভয়কেই প্রতিনিধিত্ব করে।

প্রোভাইডার, স্টেট এবং আউটপুট - ব্যাকএন্ড এবং শেয়ার্ড স্টেট

google এবং google-beta প্রোভাইডারগুলো gcp/[environment]/gcp/provider.tf এ অবস্থিত। প্রতিটি রিসোর্স ফোল্ডারে provider.tf ফাইলটি সিমলিঙ্ক করা থাকে। এর ফলে, প্রতিটি রিসোর্সের জন্য আলাদাভাবে প্রোভাইডার পরিচালনা করার পরিবর্তে আপনি এক জায়গা থেকেই তা পরিবর্তন করতে পারেন।

প্রতিটি রিসোর্সে একটি backend.tf ফাইল থাকে, যা রিসোর্সটির tfstate ফাইলের অবস্থান নির্ধারণ করে। এই backend.tf ফাইলটি একটি টেমপ্লেট ( templates/backend.tf_tmpl এ অবস্থিত) থেকে একটি স্ক্রিপ্ট ( scripts/setup_terraform_admin_project এ অবস্থিত) ব্যবহার করে তৈরি করা হয় এবং তারপর সংশ্লিষ্ট রিসোর্স ফোল্ডারে রাখা হয়। ব্যাকএন্ডের জন্য গুগল ক্লাউড স্টোরেজ (GCS) বাকেট ব্যবহার করা হয়। GCS বাকেট ফোল্ডারের নামটি রিসোর্সের নামের সাথে মিলে যায়। সমস্ত রিসোর্স ব্যাকএন্ড টেরাফর্ম অ্যাডমিন প্রজেক্টের মধ্যে থাকে।

পরস্পর নির্ভরশীল মানযুক্ত রিসোর্সগুলিতে একটি output.tf ফাইল থাকে। প্রয়োজনীয় আউটপুট মানগুলি সেই নির্দিষ্ট রিসোর্সের জন্য ব্যাকএন্ডে সংজ্ঞায়িত tfstate ফাইলে সংরক্ষিত থাকে। উদাহরণস্বরূপ, একটি প্রজেক্টে GKE ক্লাস্টার তৈরি করার জন্য, আপনার প্রজেক্ট আইডি জানা প্রয়োজন। প্রজেক্ট আইডিটি আউটপুট.tf ফাইলের মাধ্যমে tfstate ফাইলে আউটপুট করা হয়, যা GKE ক্লাস্টার রিসোর্সে একটি terraform_remote_state ডেটা সোর্সের মাধ্যমে ব্যবহার করা যেতে পারে।

shared_state ফাইলটি হলো একটি terraform_remote_state ডেটা সোর্স যা কোনো রিসোর্সের tfstate ফাইলের দিকে নির্দেশ করে। যে রিসোর্স ফোল্ডারগুলোতে অন্যান্য রিসোর্সের আউটপুট প্রয়োজন হয়, সেখানে একটি shared_state_[resource_name].tf ফাইল (বা ফাইলগুলো) থাকে। উদাহরণস্বরূপ, ops_gke রিসোর্স ফোল্ডারে ops_project এবং shared_vpc রিসোর্সের shared_state ফাইল রয়েছে, কারণ ops প্রজেক্টে GKE ক্লাস্টার তৈরি করার জন্য আপনার প্রজেক্ট আইডি এবং VPC-এর বিবরণ প্রয়োজন। shared_state ফাইলগুলো একটি টেমপ্লেট ( templates/shared_state.tf_tmpl এ অবস্থিত) থেকে একটি স্ক্রিপ্ট ( scripts/setup_terraform_admin_project এ অবস্থিত) ব্যবহার করে তৈরি করা হয়। সমস্ত রিসোর্সের shared_state ফাইলগুলো gcp/[environment]/shared_states ফোল্ডারে রাখা হয়। প্রয়োজনীয় shared_state ফাইলগুলো নিজ নিজ রিসোর্স ফোল্ডারে সিমলিঙ্ক করা থাকে। সমস্ত shared_state ফাইল একটি ফোল্ডারে রেখে এবং সেগুলোকে উপযুক্ত রিসোর্স ফোল্ডারে সিমলিঙ্ক করার ফলে একটি একক স্থান থেকে সমস্ত স্টেট ফাইল পরিচালনা করা সহজ হয়।

ভেরিয়েবল

সমস্ত রিসোর্স ভ্যালু এনভায়রনমেন্ট ভেরিয়েবল হিসেবে সংরক্ষিত থাকে। এই ভেরিয়েবলগুলো টেরাফর্ম অ্যাডমিন প্রজেক্টের GCS বাকেটে অবস্থিত vars.sh নামক একটি ফাইলে (এক্সপোর্ট স্টেটমেন্ট হিসেবে) সংরক্ষিত থাকে। এতে অর্গানাইজেশন আইডি, বিলিং অ্যাকাউন্ট, প্রজেক্ট আইডি, GKE ক্লাস্টারের বিবরণ ইত্যাদি থাকে। আপনার সেটআপের জন্য ভ্যালুগুলো পেতে আপনি যেকোনো টার্মিনাল থেকে vars.sh ফাইলটি ডাউনলোড এবং সোর্স করতে পারেন।

টেরাফর্ম ভেরিয়েবলগুলো vars.sh ফাইলে TF_VAR_[variable name] হিসেবে সংরক্ষিত থাকে। এই ভেরিয়েবলগুলো সংশ্লিষ্ট রিসোর্স ফোল্ডারে একটি variables.tfvars ফাইল তৈরি করতে ব্যবহৃত হয়। variables.tfvars ফাইলে সমস্ত ভেরিয়েবল এবং তাদের মান থাকে। একই ফোল্ডারের একটি টেমপ্লেট ফাইল থেকে একটি স্ক্রিপ্ট (যা scripts/setup_terraform_admin_project এ অবস্থিত) ব্যবহার করে variables.tfvars ফাইলটি তৈরি করা হয়।

K8s রিপো ব্যাখ্যা করা হয়েছে

k8s_repo হলো একটি CSR রিপো (ইনফ্রাস্ট্রাকচার রিপো থেকে আলাদা) যা Terraform অ্যাডমিন প্রজেক্টে অবস্থিত। এটি সমস্ত GKE ক্লাস্টারে GKE ম্যানিফেস্ট সংরক্ষণ এবং প্রয়োগ করতে ব্যবহৃত হয়। k8s_repo ইনফ্রাস্ট্রাকচার ক্লাউড বিল্ড দ্বারা তৈরি করা হয় (বিস্তারিত জানার জন্য পূর্ববর্তী বিভাগ দেখুন)। প্রাথমিক ইনফ্রাস্ট্রাকচার ক্লাউড বিল্ড প্রক্রিয়ার সময়, মোট ছয়টি GKE ক্লাস্টার তৈরি করা হয়। k8s_repo তে ছয়টি ফোল্ডার তৈরি করা হয়। প্রতিটি ফোল্ডার (যার নাম GKE ক্লাস্টারের নামের সাথে মেলে) একটি GKE ক্লাস্টারের সাথে সম্পর্কিত, যেখানে তার নিজ নিজ রিসোর্স ম্যানিফেস্ট ফাইল থাকে। ইনফ্রাস্ট্রাকচার তৈরির মতোই, ক্লাউড বিল্ড k8s_repo ব্যবহার করে সমস্ত GKE ক্লাস্টারে Kubernetes ম্যানিফেস্ট প্রয়োগ করতে ব্যবহৃত হয়। যখনই k8s_repo রিপোতে কোনো কমিট করা হয়, তখনই ক্লাউড বিল্ড ট্রিগার হয়। ইনফ্রাস্ট্রাকচারের মতোই, সমস্ত Kubernetes ম্যানিফেস্ট k8s_repo রিপোজিটরিতে কোড হিসাবে সংরক্ষিত থাকে এবং প্রতিটি GKE ক্লাস্টারের স্টেট সর্বদা তার নিজ নিজ ফোল্ডারে সংরক্ষিত থাকে।

প্রাথমিক পরিকাঠামো নির্মাণের অংশ হিসেবে, k8s_repo তৈরি করা হয় এবং সমস্ত ক্লাস্টারে Istio ইনস্টল করা হয়।

প্রজেক্ট, GKE ক্লাস্টার এবং নেমস্পেস

এই ওয়ার্কশপের রিসোর্সগুলো বিভিন্ন GCP প্রজেক্টে বিভক্ত। প্রজেক্টগুলো আপনার কোম্পানির সাংগঠনিক (বা টিম) কাঠামোর সাথে সামঞ্জস্যপূর্ণ হওয়া উচিত। আপনার প্রতিষ্ঠানের বিভিন্ন প্রজেক্ট/প্রোডাক্ট/রিসোর্সের দায়িত্বে থাকা টিমগুলো আলাদা আলাদা GCP প্রজেক্ট ব্যবহার করে। আলাদা প্রজেক্ট থাকার ফলে আপনি IAM পারমিশনের পৃথক সেট তৈরি করতে এবং প্রজেক্ট পর্যায়ে বিলিং পরিচালনা করতে পারেন। এছাড়াও, কোটাও প্রজেক্ট পর্যায়েই পরিচালিত হয়।

এই কর্মশালায় পাঁচটি দল অংশগ্রহণ করেছে, প্রত্যেকের নিজস্ব প্রকল্প রয়েছে।

  1. যে ইনফ্রাস্ট্রাকচার টিম GCP রিসোর্স তৈরি করে, তারা Terraform admin project ব্যবহার করে। তারা একটি CSR রিপোতে (যার নাম infrastructure ) ইনফ্রাস্ট্রাকচারকে কোড হিসেবে পরিচালনা করে এবং GCP-তে তৈরি রিসোর্স সম্পর্কিত সমস্ত Terraform স্টেট তথ্য GCS বাকেটে সংরক্ষণ করে। তারা CSR রিপো এবং Terraform স্টেট GCS বাকেটগুলোতে অ্যাক্সেস নিয়ন্ত্রণ করে।
  2. যে নেটওয়ার্ক টিম শেয়ার্ড ভিপিসি তৈরি করে, তারা host project ব্যবহার করে। এই প্রজেক্টটিতে ভিপিসি, সাবনেট, রাউট এবং ফায়ারওয়াল রুলস থাকে। একটি শেয়ার্ড ভিপিসি থাকার ফলে তারা জিসিপি রিসোর্সগুলোর নেটওয়ার্কিং কেন্দ্রীয়ভাবে পরিচালনা করতে পারে। সমস্ত প্রজেক্ট নেটওয়ার্কিংয়ের জন্য এই একটিমাত্র শেয়ার্ড ভিপিসি ব্যবহার করেছে।
  3. যে অপস/প্ল্যাটফর্ম টিম GKE ক্লাস্টার এবং ASM/Istio কন্ট্রোল প্লেন তৈরি করে, তারা ops project ব্যবহার করে। তারা GKE ক্লাস্টার এবং সার্ভিস মেশের জীবনচক্র পরিচালনা করে। তারা ক্লাস্টারগুলোকে আরও সুরক্ষিত করা এবং কুবারনেটিস প্ল্যাটফর্মের স্থিতিস্থাপকতা ও স্কেল ব্যবস্থাপনার জন্য দায়ী। এই ওয়ার্কশপে, আপনি কুবারনেটিসে রিসোর্স ডেপ্লয় করার জন্য গিটঅপস পদ্ধতি ব্যবহার করবেন। অপস প্রজেক্টে একটি CSR রিপো (যার নাম k8s_repo ) রয়েছে।
  4. Lastly, dev1 and dev2 teams (represent two development teams) that build applications use their own dev1 and dev2 projects . These are the applications and services you provide to your customers. These are built on the platform that the ops team manages. The resources (Deployments, Services etc) are pushed to the k8s_repo and get deployed to the appropriate clusters. It is important to note that this workshop does not focus on CI/CD best practices and tooling. You use Cloud Build to automate deploying Kubernetes resources to the GKE clusters directly. In real world production scenarios, you would use a proper CI/CD solution to deploy applications to GKE clusters.

There are two types of GKE clusters in this workshop.

  1. Ops clusters - used by the ops team to run devops tools. In this workshop, they run the ASM/Istio control plane to manage the service mesh.
  2. Application (apps) clusters - used by the development teams to run applications. In this workshop, the Hipster shop app is used.

Separating the ops/admin tooling from the clusters running the application allows you to manage the life cycle of each resource independently. The two types of clusters also exist in different projects pertaining to the team/product that uses them which makes IAM permissions also easier to manage.

There are a total of six GKE clusters. Two regional ops clusters are created in the ops project. ASM/Istio control plane is installed on both ops clusters. Each ops cluster is in a different region. In addition, there are four zonal application clusters. These are created in their own projects. This workshop simulates two development teams each with their own projects. Each project contains two app clusters. App clusters are zonal clusters in different zones. The four app clusters are located in two regions and four zones. This way you get regional and zonal redundancy.

The application used in this workshop, the Hipster Shop app, is deployed on all four app clusters. Each microservice lives in its own namespace in every app cluster. Hipster shop app Deployments (Pods) are not deployed on the ops clusters. However, the namespaces and Service resources for all microservices are also created in the ops clusters. ASM/Istio control plane uses the Kubernetes service registries for service discovery. In the absence of Services (in the ops clusters), you would have to manually create ServiceEntries for each service running in the app cluster.

You deploy a 10-tier microservices application in this workshop. The application is a web-based e-commerce app called " Hipster Shop " where users can browse items, add them to the cart, and purchase them.

Kubernetes manifests and k8s_repo

You use the k8s_repo to add Kubernetes resources to all GKE clusters. You do this by copying Kubernetes manifests and committing to the k8s_repo . All commits to the k8s_repo trigger a Cloud Build job which deploys the Kubernetes manifests to the respective cluster. Each cluster's manifest is located in a separate folder named the same as the cluster name.

The six cluster names are:

  1. gke-asm-1-r1-prod - the regional ops cluster in region 1
  2. gke-asm-2-r2-prod - the regional ops cluster in region 2
  3. gke-1-apps-r1a-prod - the app cluster in region 1 zone a
  4. gke-2-apps-r1b-prod - the app cluster in region 1 zone b
  5. gke-3-apps-r2a-prod - the app cluster in region 2 zone a
  6. gke-4-apps-r2b-prod - the app cluster in region 2 zone b

The k8s_repo has folders corresponding to these clusters. Any manifest placed in these folders get applied to the corresponding GKE cluster. Manifests for each cluster are placed in sub-folders (within the cluster's main folder) for ease of management. In this workshop, you use Kustomize to keep track of resources that get deployed. Please refer to the Kustomize official documentation for more details.

7. Deploy the Sample App

Objective: Deploy Hipster shop app on apps clusters

  • Clone k8s-repo
  • Copy Hipster shop manifests to all apps clusters
  • Create Services for Hipster shop app in the ops clusters
  • Setup loadgenerators in the ops clusters to test global connectivity
  • Verify secure connectivity to the Hipster shop app

Copy-and-Paste Method Lab Instructions

Clone the ops project source repo

As part of the initial Terraform infrastructure build, the k8s-repo is already created in the ops project.

  1. Create an empty directory for git repo:
mkdir $WORKDIR/k8s-repo
 
  1. Init git repo, add remote and pull master from remote repo:
cd $WORKDIR/k8s-repo
git init && git remote add origin \
https://source.developers.google.com/p/$TF_VAR_ops_project_name/r/k8s-repo
 
  1. Set local git local configuration.
git config --local user.email $MY_USER
git config --local user.name "K8s repo user"
git config --local \
credential.'https://source.developers.google.com'.helper gcloud.sh
git pull origin master

Copy manifests, commit and push

  1. Copy the Hipster Shop namespaces and services to the source repo for all clusters.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/namespaces \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/namespaces \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/namespaces \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/namespaces \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/namespaces \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/namespaces \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app/.

cp -r $WORKDIR/asm/k8s_manifests/prod/app/services \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/services \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/services \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/services \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/services \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/services \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app/.
 
  1. Copy the app folder kustomization.yaml to all clusters.
cp $WORKDIR/asm/k8s_manifests/prod/app/kustomization.yaml \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app/
cp $WORKDIR/asm/k8s_manifests/prod/app/kustomization.yaml \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/
cp $WORKDIR/asm/k8s_manifests/prod/app/kustomization.yaml \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/
cp $WORKDIR/asm/k8s_manifests/prod/app/kustomization.yaml \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/
cp $WORKDIR/asm/k8s_manifests/prod/app/kustomization.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app/
cp $WORKDIR/asm/k8s_manifests/prod/app/kustomization.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app/
 
  1. Copy the Hipster Shop Deployments, RBAC and PodSecurityPolicy to the source repo for the apps clusters.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/deployments \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/deployments \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/deployments \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/deployments \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/

cp -r $WORKDIR/asm/k8s_manifests/prod/app/rbac \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/rbac \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/rbac \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/rbac \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/podsecuritypolicies \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/podsecuritypolicies \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/podsecuritypolicies \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/podsecuritypolicies \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/
  1. Remove the cartservice deployment, rbac and podsecuritypolicy from all but one dev cluster. Hipstershop was not built for multi-cluster deployment, so to avoid inconsistent results, we are using just one cartservice.
rm $WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/deployments/app-cart-service.yaml
rm $WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/podsecuritypolicies/cart-psp.yaml
rm $WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/rbac/cart-rbac.yaml

rm $WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/deployments/app-cart-service.yaml
rm $WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/podsecuritypolicies/cart-psp.yaml
rm $WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/rbac/cart-rbac.yaml

rm $WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/deployments/app-cart-service.yaml
rm $WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/podsecuritypolicies/cart-psp.yaml
rm $WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/rbac/cart-rbac.yaml
 
  1. Add cartservice deployment, rbac and podsecuritypolicy to kustomization.yaml in the first dev cluster only.
cd ${WORKDIR}/k8s-repo/${DEV1_GKE_1_CLUSTER}/app
cd deployments && kustomize edit add resource app-cart-service.yaml
cd ../podsecuritypolicies && kustomize edit add resource cart-psp.yaml
cd ../rbac && kustomize edit add resource cart-rbac.yaml
cd ${WORKDIR}/asm
 
  1. Remove podsecuritypolicies, deployments and rbac directories from ops clusters kustomization.yaml
sed -i -e '/- deployments\//d' -e '/- podsecuritypolicies\//d' \
  -e '/- rbac\//d' \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app/kustomization.yaml
sed -i -e '/- deployments\//d' -e '/- podsecuritypolicies\//d' \
  -e '/- rbac\//d' \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app/kustomization.yaml
  1. Replace the PROJECT_ID in the RBAC manifests.
sed -i 's/\${PROJECT_ID}/'${TF_VAR_dev1_project_name}'/g' \
${WORKDIR}/k8s-repo/${DEV1_GKE_1_CLUSTER}/app/rbac/*
sed -i 's/\${PROJECT_ID}/'${TF_VAR_dev1_project_name}'/g' \
${WORKDIR}/k8s-repo/${DEV1_GKE_2_CLUSTER}/app/rbac/*
sed -i 's/\${PROJECT_ID}/'${TF_VAR_dev2_project_name}'/g' \
${WORKDIR}/k8s-repo/${DEV2_GKE_1_CLUSTER}/app/rbac/*
sed -i 's/\${PROJECT_ID}/'${TF_VAR_dev2_project_name}'/g' \
${WORKDIR}/k8s-repo/${DEV2_GKE_2_CLUSTER}/app/rbac/*
  
  1. Copy the IngressGateway and VirtualService manifests to the source repo for the ops clusters.
cp -r $WORKDIR/asm/k8s_manifests/prod/app-ingress/* \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-ingress/
cp -r $WORKDIR/asm/k8s_manifests/prod/app-ingress/* \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-ingress/
 
  1. Copy the Config Connector resources to one of clusters in each project.
cp -r $WORKDIR/asm/k8s_manifests/prod/app-cnrm/* \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-cnrm/
cp -r $WORKDIR/asm/k8s_manifests/prod/app-cnrm/* \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app-cnrm/
cp -r $WORKDIR/asm/k8s_manifests/prod/app-cnrm/* \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app-cnrm/
 
  1. Replace the PROJECT_ID in the Config Connector manifests.
sed -i 's/${PROJECT_ID}/'$TF_VAR_ops_project_name'/g' \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-cnrm/*
sed -i 's/${PROJECT_ID}/'$TF_VAR_dev1_project_name'/g' \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app-cnrm/*
sed -i 's/${PROJECT_ID}/'$TF_VAR_dev2_project_name'/g' \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app-cnrm/*
 
  1. Copy loadgenerator manifests (Deployment, PodSecurityPolicy and RBAC) to the ops clusters. The Hipster shop app is exposed using a global Google Cloud Load Balancer (GCLB). GCLB receives client traffic (destined to frontend ) and sends it to the closest instance of the Service. Putting loadgenerator on both ops clusters will ensure traffic to being sent to both Istio Ingress gateways running in the ops clusters. Load balancing is explained in detail in the following section.
cp -r $WORKDIR/asm/k8s_manifests/prod/app-loadgenerator/. \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-loadgenerator/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app-loadgenerator/. \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-loadgenerator/. 
 
  1. Replace the ops project ID in the loadgenerator manifests for both ops clusters.
sed -i 's/OPS_PROJECT_ID/'$TF_VAR_ops_project_name'/g'  \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-loadgenerator/loadgenerator-deployment.yaml
sed -i 's/OPS_PROJECT_ID/'$TF_VAR_ops_project_name'/g' \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-loadgenerator/loadgenerator-rbac.yaml
sed -i 's/OPS_PROJECT_ID/'$TF_VAR_ops_project_name'/g' \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-loadgenerator/loadgenerator-deployment.yaml
sed -i 's/OPS_PROJECT_ID/'$TF_VAR_ops_project_name'/g' \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-loadgenerator/loadgenerator-rbac.yaml
 

  1. Add the loadgenerator resources to kustomization.yaml for both ops clusters.
cd $WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-loadgenerator/
kustomize edit add resource loadgenerator-psp.yaml
kustomize edit add resource loadgenerator-rbac.yaml
kustomize edit add resource loadgenerator-deployment.yaml

cd $WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-loadgenerator/
kustomize edit add resource loadgenerator-psp.yaml
kustomize edit add resource loadgenerator-rbac.yaml
kustomize edit add resource loadgenerator-deployment.yaml
 

  1. Commit to k8s-repo .
cd $WORKDIR/k8s-repo
git add . && git commit -am "create app namespaces and install hipster shop"
git push --set-upstream origin master 
 
  1. View the status of the Ops project Cloud Build in a previously opened tab or by clicking the following link:
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_VAR_ops_project_name}"
  

Verify Application deployment

  1. Verify pods in all application namespaces except cart are in Running state in all dev clusters.
for ns in ad checkout currency email frontend payment product-catalog recommendation shipping; do
  kubectl --context $DEV1_GKE_1 get pods -n $ns;
  kubectl --context $DEV1_GKE_2 get pods -n $ns;
  kubectl --context $DEV2_GKE_1 get pods -n $ns;
  kubectl --context $DEV2_GKE_2 get pods -n $ns;
done;
 

Output (do not copy)

NAME                               READY   STATUS    RESTARTS   AGE
currencyservice-5c5b8876db-pvc6s   2/2     Running   0          13m
NAME                               READY   STATUS    RESTARTS   AGE
currencyservice-5c5b8876db-xlkl9   2/2     Running   0          13m
NAME                               READY   STATUS    RESTARTS   AGE
currencyservice-5c5b8876db-zdjkg   2/2     Running   0          115s
NAME                               READY   STATUS    RESTARTS   AGE
currencyservice-5c5b8876db-l748q   2/2     Running   0          82s

NAME                            READY   STATUS    RESTARTS   AGE
emailservice-588467b8c8-gk92n   2/2     Running   0          13m
NAME                            READY   STATUS    RESTARTS   AGE
emailservice-588467b8c8-rvzk9   2/2     Running   0          13m
NAME                            READY   STATUS    RESTARTS   AGE
emailservice-588467b8c8-mt925   2/2     Running   0          117s
NAME                            READY   STATUS    RESTARTS   AGE
emailservice-588467b8c8-klqn7   2/2     Running   0          84s

NAME                        READY   STATUS    RESTARTS   AGE
frontend-64b94cf46f-kkq7d   2/2     Running   0          13m
NAME                        READY   STATUS    RESTARTS   AGE
frontend-64b94cf46f-lwskf   2/2     Running   0          13m
NAME                        READY   STATUS    RESTARTS   AGE
frontend-64b94cf46f-zz7xs   2/2     Running   0          118s
NAME                        READY   STATUS    RESTARTS   AGE
frontend-64b94cf46f-2vtw5   2/2     Running   0          85s

NAME                              READY   STATUS    RESTARTS   AGE
paymentservice-777f6c74f8-df8ml   2/2     Running   0          13m
NAME                              READY   STATUS    RESTARTS   AGE
paymentservice-777f6c74f8-bdcvg   2/2     Running   0          13m
NAME                              READY   STATUS    RESTARTS   AGE
paymentservice-777f6c74f8-jqf28   2/2     Running   0          117s
NAME                              READY   STATUS    RESTARTS   AGE
paymentservice-777f6c74f8-95x2m   2/2     Running   0          86s

NAME                                     READY   STATUS    RESTARTS   AGE
productcatalogservice-786dc84f84-q5g9p   2/2     Running   0          13m
NAME                                     READY   STATUS    RESTARTS   AGE
productcatalogservice-786dc84f84-n6lp8   2/2     Running   0          13m
NAME                                     READY   STATUS    RESTARTS   AGE
productcatalogservice-786dc84f84-gf9xl   2/2     Running   0          119s
NAME                                     READY   STATUS    RESTARTS   AGE
productcatalogservice-786dc84f84-v7cbr   2/2     Running   0          86s

NAME                                     READY   STATUS    RESTARTS   AGE
recommendationservice-5fdf959f6b-2ltrk   2/2     Running   0          13m
NAME                                     READY   STATUS    RESTARTS   AGE
recommendationservice-5fdf959f6b-dqd55   2/2     Running   0          13m
NAME                                     READY   STATUS    RESTARTS   AGE
recommendationservice-5fdf959f6b-jghcl   2/2     Running   0          119s
NAME                                     READY   STATUS    RESTARTS   AGE
recommendationservice-5fdf959f6b-kkspz   2/2     Running   0          87s

NAME                              READY   STATUS    RESTARTS   AGE
shippingservice-7bd5f569d-qqd9n   2/2     Running   0          13m
NAME                              READY   STATUS    RESTARTS   AGE
shippingservice-7bd5f569d-xczg5   2/2     Running   0          13m
NAME                              READY   STATUS    RESTARTS   AGE
shippingservice-7bd5f569d-wfgfr   2/2     Running   0          2m
NAME                              READY   STATUS    RESTARTS   AGE
shippingservice-7bd5f569d-r6t8v   2/2     Running   0          88s
  1. Verify pods in cart namespace are in Running state in first dev cluster only.
kubectl --context $DEV1_GKE_1 get pods -n cart;
 

Output (do not copy)

NAME                           READY   STATUS    RESTARTS   AGE
cartservice-659c9749b4-vqnrd   2/2     Running   0          17m

Access the Hipster Shop app

Global load balancing

You now have Hipster Shop app deployed to all four app clusters. These clusters are in two regions and four zones. Clients can access the Hipster shop app by accessing the frontend service. The frontend service runs on all four app clusters. A Google Cloud Load Balancer ( GCLB ) is used to get client traffic to all four instances of the frontend service.

Istio Ingress gateways only run in the ops clusters and act as a regional load balancer to the two zonal application clusters within the region. GCLB uses the two Istio ingress gateways (running in the two ops clusters) as backends to the global frontend service. The Istio Ingress gateways receive the client traffic from the GCLB and then send the client traffic onwards to the frontend Pods running in the application clusters.

4c618df35cb928ee.png

Alternatively, you can put Istio Ingress gateways on the application clusters directly and the GCLB can use those as backends.

GKE Autoneg controller

Istio Ingress gateway Kubernetes Service registers itself as a backend to the GCLB using Network Endpoint Groups (NEGs). NEGs allow for container-native load balancing using GCLBs. NEGs are created through a special annotation on a Kubernetes Service, so it can register itself to the NEG Controller. Autoneg controller is a special GKE controller that automates the creation of NEGs as well as assigning them as backends to a GCLB using Service annotations. Istio control planes including the Istio ingress gateways are deployed during the initial infrastructure Terraform Cloud Build. The GCLB and autoneg configuration is done as part of the initial Terraform infrastructure Cloud Build.

Secure Ingress using Cloud Endpoints and managed certs

GCP Managed certs are used to secure the client traffic to the frontend GCLB service. GCLB uses managed certs for the global frontend service and the certificate is terminated at the GCLB. In this workshop, you use Cloud Endpoints as the domain for the managed cert. Alternatively, you can use your domain and a DNS name for the frontend to create GCP managed certs.

  1. To access the Hipster shop, click on the link output of the following command.
echo "https://frontend.endpoints.$TF_VAR_ops_project_name.cloud.goog" 
 
  1. You can check that the certificate is valid by clicking the lock symbol in the URL bar of your Chrome tab.

6c403a63caa06c84.png

Verify global load balancing

As part of the application deployment, load generators were deployed in both ops clusters that generate test traffic to the GCLB Hipster shop Cloud Endpoints link. Verify that the GCLB is receiving traffic and sending to both Istio Ingress gateways.

  1. Get the GCLB > Monitoring link for the ops project where the Hipster shop GCLB is created.
echo "https://console.cloud.google.com/net-services/loadbalancing/details/http/istio-ingressgateway?project=$TF_VAR_ops_project_name&cloudshell=false&tab=monitoring&duration=PT1H" 
 
  1. Change from All backends to istio-ingressgateway from the Backend dropdown menu as shown below.

6697c9eb67998d27.png

  1. Note traffic going to both istio-ingressgateways .

ff8126e44cfd7f5e.png

There are three NEGs created per istio-ingressgateway . Since the ops clusters are regional clusters, one NEG is created for each zone in the region. The istio-ingressgateway Pods, however, run in a single zone per region. Traffic is shown going to the istio-ingressgateway Pods.

Load generators are running in both ops clusters simulating client traffic from the two regions they are in. The load generated in the ops cluster region 1 is being sent to istio-ingressgateway in region 2. Likewise, the load generated in ops cluster region 2 is being sent to istio-ingressgateway in region 2.

8. Observability with Stackdriver

Objective: Connect Istio telemetry to Stackdriver and validate.

  • Install istio-telemetry resources
  • Create/update Istio Services dashboards
  • View container logs
  • View distributed tracing in Stackdriver

Copy-and-Paste Method Lab Instructions

One of Istio's major features is built-in observability ("o11y"). This means that even with black-box, uninstrumented containers, operators can still observe the traffic going in and out of these containers, providing services to customers. This observation takes the shape of a few different methods: metrics, logs, and traces.

We will also utilize the built-in load generation system in Hipster Shop. Observability doesn't work very well in a static system with no traffic, so load generation helps us see how it works. This load is already running, now we'll just be able to see it.

  1. Install the istio to stackdriver config file.
cd $WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/istio-telemetry
kustomize edit add resource istio-telemetry.yaml

cd $WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/istio-telemetry
kustomize edit add resource istio-telemetry.yaml
 
  1. Commit to k8s-repo.
cd $WORKDIR/k8s-repo
git add . && git commit -am "Install istio to stackdriver configuration"
git push 
 
  1. View the status of the Ops project Cloud Build in a previously opened tab or by clicking the following link:
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_VAR_ops_project_name}"
 
  1. Verify the Istio → Stackdriver integration Get the Stackdriver Handler CRD.
kubectl --context $OPS_GKE_1 get handler -n istio-system
 

The output should show a handler named stackdriver:

NAME            AGE
kubernetesenv   12d
prometheus      12d
stackdriver     69s      # <== NEW!
  1. Verify that the Istio metrics export to Stackdriver is working. Click the link output from this command:
echo "https://console.cloud.google.com/monitoring/metrics-explorer?cloudshell=false&project=$TF_VAR_ops_project_name"
 

You will be prompted to create a new Workspace, named after the Ops project, just choose OK. If it prompts you about the new UI, just dismiss the dialog.

In the Metrics Explorer, under "Find resource type and metric" type " istio " to see there are options like "Server Request Count" on the "Kubernetes Container" resource type. This shows us that the metrics are flowing from the mesh into Stackdriver.

(You will have to Group By destination_service_name label if you want to see the lines below.)

b9b59432ee68e695.png

Visualizing metrics with Dashboards:

Now that our metrics are in the Stackdriver APM system, we want a way to visualize them. In this section, we will install a pre-built dashboard which shows us the three of the four " Golden Signals " of metrics: Traffic (Requests per second), Latency (in this case, 99th and 50th percentile), and Errors (we're excluding Saturation in this example).

Istio's Envoy proxy gives us several metrics , but these are a good set to start with. (exhaustive list is here ). Note that each metric has a set of labels that can be used for filtering, aggregating, such as: destination_service, source_workload_namespace, response_code, istio_tcp_received_bytes_total, etc).

  1. Now let's add our pre-canned metrics dashboard . We are going to be using the Dashboard API directly. This is something you wouldn't normally do by hand-generating API calls, it would be part of an automation system, or you would build the dashboard manually in the web UI. This will get us started quickly:
sed -i 's/OPS_PROJECT/'${TF_VAR_ops_project_name}'/g' \
$WORKDIR/asm/k8s_manifests/prod/app-telemetry/services-dashboard.json
OAUTH_TOKEN=$(gcloud auth application-default print-access-token)
curl -X POST -H "Authorization: Bearer $OAUTH_TOKEN" -H "Content-Type: application/json" \
https://monitoring.googleapis.com/v1/projects/$TF_VAR_ops_project_name/dashboards \
 -d @$WORKDIR/asm/k8s_manifests/prod/app-telemetry/services-dashboard.json
 
  1. Navigate to the output link below to view the newly added "Services dashboard".
echo "https://console.cloud.google.com/monitoring/dashboards/custom/servicesdash?cloudshell=false&project=$TF_VAR_ops_project_name"
 
 

We could edit the dashboard in-place using the UX, but in our case we are going to quickly add a new graph using the API. In order to do that, you should pull down the latest version of the dashboard, apply your edits, then push it back up using the HTTP PATCH method.

  1. You can get an existing dashboard by querying the monitoring API. Get the existing dashboard that was just added:
curl -X GET -H "Authorization: Bearer $OAUTH_TOKEN" -H "Content-Type: application/json" \
https://monitoring.googleapis.com/v1/projects/$TF_VAR_ops_project_name/dashboards/servicesdash > /tmp/services-dashboard.json
 
  1. Add a new graph: (50th %ile latency): [ API reference ] Now we can add a new graph widget to our dashboard in code. This change can be reviewed by peers and checked into version control. Here is a widget to add that shows 50%ile latency (median latency).

Try editing the dashboard you just got, adding a new stanza:

NEW_CHART=${WORKDIR}/asm/k8s_manifests/prod/app-telemetry/new-chart.json
jq --argjson newChart "$(<$NEW_CHART)" '.gridLayout.widgets += [$newChart]' /tmp/services-dashboard.json > /tmp/patched-services-dashboard.json
 
  1. Update the existing services dashboard:
curl -X PATCH -H "Authorization: Bearer $OAUTH_TOKEN" -H "Content-Type: application/json" \
https://monitoring.googleapis.com/v1/projects/$TF_VAR_ops_project_name/dashboards/servicesdash \
 -d @/tmp/patched-services-dashboard.json
 
  1. View the updated dashboard by navigating to the following output link:
echo "https://console.cloud.google.com/monitoring/dashboards/custom/servicesdash?cloudshell=false&project=$TF_VAR_ops_project_name"
 
  1. Do some simple Logs Analysis.

Istio provides a set of structured logs for all in-mesh network traffic and uploads them to Stackdriver Logging to allow cross-cluster analysis in one powerful tool. Logs are annotated with service-level metadata such as the cluster, container, app, connection_id, etc.

An example log entry (in this case, Envoy proxy's accesslog) might look like this (trimmed):

*** DO NOT PASTE *** 
 logName: "projects/PROJECTNAME-11932-01-ops/logs/server-tcp-accesslog-stackdriver.instance.istio-system" 
labels: {
  connection_id: "fbb46826-96fd-476c-ac98-68a9bd6e585d-1517191"   
  destination_app: "redis-cart"   
  destination_ip: "10.16.1.7"   
  destination_name: "redis-cart-6448dcbdcc-cj52v"   
  destination_namespace: "cart"   
  destination_owner: "kubernetes://apis/apps/v1/namespaces/cart/deployments/redis-cart"   
  destination_workload: "redis-cart"   
  source_ip: "10.16.2.8"   
  total_received_bytes: "539"   
  total_sent_bytes: "569" 
...  
 }

View your logs here:

echo "https://console.cloud.google.com/logs/viewer?cloudshell=false&project=$TF_VAR_ops_project_name"
 

You can view Istio's control plane logs by selecting Resource > Kubernetes Container, and searching on "pilot" —

6f93b2aec6c4f520.png

Here, we can see the Istio Control Plane pushing proxy config to the sidecar proxies for each sample app service. "CDS," "LDS," and "RDS" represent different Envoy APIs ( more information ).

Beyond Istio's logs, you can also find container logs as well as infrastructure or other GCP services logs all in the same interface. Here are some sample logs queries for GKE. The logs viewer also allows you to create metrics out of logs (eg: "count every error that matches some string") which can be used on a dashboard or as part of an alert. Logs can also be streamed to other analysis tools such as BigQuery.

Some sample filters for hipster shop:

resource.type="k8s_container" labels.destination_app="productcatalogservice"

resource.type="k8s_container" resource.labels.namespace_name="cart"

  1. Check out Distributed Traces.

Now that you're working with a distributed system, debugging needs a new tool: Distributed Tracing . This tool allows you to discover statistics about how your services are interacting (such as finding outlying slow events in the picture below), as well as dive into raw sample traces to investigate the details of what is really going on.

The Timeline View shows all requests over time, graphed by their latency, or time spent between initial request, through the Hipster stack, to finally respond to the end user. The higher up the dots, the slower (and less-happy!) the user's experience.

You can click on a dot to find the detailed Waterfall View of that particular request. This ability to find the raw details of a particular request (not just aggregate statistics) is vital to understanding the interplay between services, especially when hunting down rare, but bad, interactions between services.

The Waterfall View should be familiar to anyone who has used a debugger, but in this case instead of showing time spent in different processes of a single application, this is showing time spent traversing our mesh, between services, running in separate containers.

Here you can find your Traces:

echo "https://console.cloud.google.com/traces/overview?cloudshell=false&project=$TF_VAR_ops_project_name"
 

An example screenshot of the tool:

5ee238836dc9047f.png

9. Mutual TLS Authentication

Objective: Secure connectivity between microservices (AuthN).

  • Enable mesh wide mTLS
  • Verify mTLS by inspecting logs

Copy-and-Paste Method Lab Instructions

Now that our apps are installed and Observability is set up, we can start securing the connections between services and make sure it keeps working.

For example, we can see on the Kiali dashboard that our services are not using MTLS (no "lock" icon). But the traffic is flowing and the system is working fine. Our StackDriver Golden Metrics dashboard is giving us some peace of mind that things are working, overall.

  1. Check MeshPolicy in ops clusters. Note mTLS is PERMISSIVE allowing for both encrypted and non-mTLS traffic.
kubectl --context $OPS_GKE_1 get MeshPolicy -o json | jq '.items[].spec'
kubectl --context $OPS_GKE_2 get MeshPolicy -o json | jq '.items[].spec'
 
    `Output (do not copy)`
{
  "peers": [
    {
      "mtls": {
        "mode": "PERMISSIVE"
      }
    }
  ]
}

Istio is configured on all clusters using the Istio operator, which uses the IstioControlPlane custom resource (CR). We will configure mTLS in all clusters by updating the IstioControlPlane CR and updating the k8s-repo. Setting global > mTLS > enabled: true in the IstioControlPlane CR results in the following two changes to the Istio control plane:

  • MeshPolicy is set to turn on mTLS mesh wide for all Services running in all clusters.
  • A DestinationRule is created to allow ISTIO_MUTUAL traffic between Services running in all clusters.
  1. We will apply a kustomize patch to the istioControlPlane CR to enable mTLS cluster wide. Copy the patch to relevant dir for all clusters and add a kustomize patch.
cp -r $WORKDIR/asm/k8s_manifests/prod/app-mtls/mtls-kustomize-patch-replicated.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/istio-controlplane/mtls-kustomize-patch.yaml
cd $WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/istio-controlplane
kustomize edit add patch mtls-kustomize-patch.yaml

cp -r $WORKDIR/asm/k8s_manifests/prod/app-mtls/mtls-kustomize-patch-replicated.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/istio-controlplane/mtls-kustomize-patch.yaml
cd $WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/istio-controlplane
kustomize edit add patch mtls-kustomize-patch.yaml

cp -r $WORKDIR/asm/k8s_manifests/prod/app-mtls/mtls-kustomize-patch-shared.yaml \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/istio-controlplane/mtls-kustomize-patch.yaml
cd $WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/istio-controlplane
kustomize edit add patch mtls-kustomize-patch.yaml

cp -r $WORKDIR/asm/k8s_manifests/prod/app-mtls/mtls-kustomize-patch-shared.yaml \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/istio-controlplane/mtls-kustomize-patch.yaml
cd $WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/istio-controlplane
kustomize edit add patch mtls-kustomize-patch.yaml

cp -r $WORKDIR/asm/k8s_manifests/prod/app-mtls/mtls-kustomize-patch-shared.yaml \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/istio-controlplane/mtls-kustomize-patch.yaml
cd $WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/istio-controlplane
kustomize edit add patch mtls-kustomize-patch.yaml

cp -r $WORKDIR/asm/k8s_manifests/prod/app-mtls/mtls-kustomize-patch-shared.yaml \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/istio-controlplane/mtls-kustomize-patch.yaml
cd $WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/istio-controlplane
kustomize edit add patch mtls-kustomize-patch.yaml
 
  1. Commit to k8s-repo.
cd $WORKDIR/k8s-repo
git add . && git commit -am "turn mTLS on"
git push
 
  1. View the status of the Ops project Cloud Build in a previously opened tab or by clicking the following link:
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_VAR_ops_project_name}"

 

Verify mTLS

  1. Check MeshPolicy once more in ops clusters. Note mTLS is no longer PERMISSIVE and will only allow for mTLS traffic.
kubectl --context $OPS_GKE_1 get MeshPolicy -o json | jq .items[].spec
kubectl --context $OPS_GKE_2 get MeshPolicy -o json | jq .items[].spec
 

Output (do not copy):

{
  "peers": [
    {
      "mtls": {}
    }
  ]
}
  1. Describe the DestinationRule created by the Istio operator controller.
kubectl --context $OPS_GKE_1 get DestinationRule default -n istio-system -o json | jq '.spec'
kubectl --context $OPS_GKE_2 get DestinationRule default -n istio-system -o json | jq '.spec'

Output (do not copy):

{
    host: '*.local',
    trafficPolicy: {
      tls: {
        mode: ISTIO_MUTUAL
      }
   }
}

We can also see the move from HTTP to HTTPS in the logs.

We can expose this particular field from the logs in the UI by clicking one one log entry and then clicking on the value of the field you want to display, in our case, click on "http" next to "protocol:

d92e0c88cd5b2132.png

This results in a nice way to visualize the changeover.:

ea3d0240fa6fed81.png

10. Canary Deployments

Objective: Rollout a new version of the frontend Service.

  • Rollout frontend-v2 (next production version) Service in one region
  • Use DestinationRules and VirtualServices to slowly steer traffic to frontend-v2
  • Verify GitOps deployment pipeline by inspecting series of commits to the k8s-repo

Copy-and-Paste Method Lab Instructions

A canary deployment is a progressive rollout of a new service. In a canary deployment, you send an increasing amount of traffic to the new version, while still sending the remaining percentage to the current version. A common pattern is to perform a canary analysis at each stage of traffic splitting, and compare the "golden signals" of the new version (latency, error rate, saturation) against a baseline. This helps prevent outages, and ensure the stability of the new "v2" service at every stage of traffic splitting.

In this section, you will learn how to use Cloud Build and Istio traffic policies to create a basic canary deployment for a new version of the frontend service.

First, we'll run the Canary pipeline in the DEV1 region (us-west1), and roll out frontend v2 on both clusters in that region. Second, we'll run the Canary pipeline in the DEV2 region (us-central), and deploy v2 onto both clusters in that region. Running the pipeline on regions in order, versus in parallel across all regions, helps avoid global outages caused by bad configuration, or by bugs in the v2 app itself.

Note : we'll manually trigger the Canary pipeline in both regions, but in production, you would use an automated trigger, for instance based on a new Docker image tag pushed to a registry.

  1. From Cloud Shell, define some env variables to simplify running the rest of the commands.
CANARY_DIR="$WORKDIR/asm/k8s_manifests/prod/app-canary/"
K8S_REPO="$WORKDIR/k8s-repo"
 
  1. Run the repo_setup.sh script, to copy the baseline manifests into k8s-repo.
$CANARY_DIR/repo-setup.sh 
 

The following manifests are copied:

  • frontend-v2 deployment
  • frontend-v1 patch (to include the "v1" label, and an image with a "/version" endpoint)
  • respy , a small pod that will print HTTP response distribution, and help us visualize the canary deployment in real time.
  • frontend Istio DestinationRule - splits the frontend Kubernetes Service into two subsets, v1 and v2, based on the "version" deployment label
  • frontend Istio VirtualService - routes 100% of traffic to frontend v1. This overrides the Kubernetes Service default round-robin behavior, which would immediately send 50% of all Dev1 regional traffic to frontend v2.
  1. Commit changes to k8s_repo:
cd $K8S_REPO 
git add . && git commit -am "frontend canary setup"
git push
 
  1. View the status of the Ops project Cloud Build in a previously opened tab or by clicking the following link:
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_VAR_ops_project_name}" 
 
  1. Navigate to Cloud Build in the console for the OPS1 project. Wait for the Cloud Build pipeline to complete, then get pods in the frontend namespace in both DEV1 clusters. You should see the following:
watch -n 1 kubectl --context $DEV1_GKE_1 get pods -n frontend 
 

Output (do not copy)

NAME                           READY   STATUS    RESTARTS   AGE
frontend-578b5c5db6-h9567      2/2     Running   0          59m
frontend-v2-54b74fc75b-fbxhc   2/2     Running   0          2m26s
respy-5f4664b5f6-ff22r         2/2     Running   0          2m26s

We will use tmux to split our cloudshell window into 2 panes:

  • The bottom pane will be running the watch command to observe the HTTP response distribution for the frontend service.
  • The top pane will be running the actual canary pipeline script.
  1. Run the command to split the cloud shell window and execute the watch command in the bottom pane.
RESPY_POD=$(kubectl --context $DEV1_GKE_1 get pod \
-n frontend -l app=respy -o jsonpath='{..metadata.name}')
export TMUX_SESSION=$(tmux display-message -p '#S')
tmux split-window -d -t $TMUX_SESSION:0 -p33 \
-v "export KUBECONFIG=$WORKDIR/asm/gke/kubemesh; \
kubectl --context $DEV1_GKE_1 exec -n frontend -it \
$RESPY_POD -c respy /bin/sh -- -c 'watch -n 1 ./respy \
--u http://frontend:80/version --c 10 --n 500'; sleep 2"
 

Output (do not copy)

500 requests to http://frontend:80/version...
+----------+-------------------+
| RESPONSE | % OF 500 REQUESTS |
+----------+-------------------+
| v1       | 100.0%            |
|          |                   |
+----------+-------------------+
  1. Execute the canary pipeline on the Dev1 region. We provide a script that updates frontend-v2 traffic percentages in the VirtualService (updating weights to 20%, 50%, 80%, then 100%). Between updates, the script waits for the Cloud Build pipeline to complete. Run the canary deployment script for the Dev1 region. Note - this script takes about 10 minutes to complete.
K8S_REPO=$K8S_REPO CANARY_DIR=$CANARY_DIR \
OPS_DIR=$OPS_GKE_1_CLUSTER OPS_CONTEXT=$OPS_GKE_1 \
${CANARY_DIR}/auto-canary.sh
 

You can see traffic splitting in real time in the bottom window where you're running the respy command. For instance, at the 20% mark :

Output (do not copy)

500 requests to http://frontend:80/version...
+----------+-------------------+
| RESPONSE | % OF 500 REQUESTS |
+----------+-------------------+
| v1       | 79.4%             |
|          |                   |
| v2       | 20.6%             |
|          |                   |
+----------+-------------------+
  1. Once the Dev2 rollout completes for frontend-v2, you should see a success message at the end of the script:
     Output (do not copy) 
    
✅ 100% successfully deployed
🌈 frontend-v2 Canary Complete for gke-asm-1-r1-prod
  1. And all frontend traffic from a Dev2 pod should be going to frontend-v2:
     Output (do not copy) 
    
500 requests to http://frontend:80/version...
+----------+-------------------+
| RESPONSE | % OF 500 REQUESTS |
+----------+-------------------+
| v2       | 100.0%            |
|          |                   |
+----------+-------------------+
  1. Close the split pane.
tmux respawn-pane -t ${TMUX_SESSION}:0.1 -k 'exit'
 
  1. Navigate to Cloud Source Repos at the link generated.
echo https://source.developers.google.com/p/$TF_VAR_ops_project_name/r/k8s-repo

You should see a separate commit for each traffic percentage, with the most recent commit at the top of the list:

b87b85f52fd2ff0f.png

Now, you will repeat the same process for the Dev2 region. Note that the Dev2 region is still "locked" on v1. This is because in the baseline repo_setup script, we pushed a VirtualService to explicitly send all traffic to v1. This way, we were able to safely do a regional canary on Dev1, and make sure it ran successfully before rolling out the new version globally.

  1. Run the command to split the cloud shell window and execute the watch command in the bottom pane.
RESPY_POD=$(kubectl --context $DEV2_GKE_1 get pod \
-n frontend -l app=respy -o jsonpath='{..metadata.name}')
export TMUX_SESSION=$(tmux display-message -p '#S')
tmux split-window -d -t $TMUX_SESSION:0 -p33 \
-v "export KUBECONFIG=$WORKDIR/asm/gke/kubemesh; \
kubectl --context $DEV2_GKE_1 exec -n frontend -it \
$RESPY_POD -c respy /bin/sh -- -c 'watch -n 1 ./respy \
--u http://frontend:80/version --c 10 --n 500'; sleep 2"
 

Output (do not copy)

500 requests to http://frontend:80/version...
+----------+-------------------+
| RESPONSE | % OF 500 REQUESTS |
+----------+-------------------+
| v1       | 100.0%            |
|          |                   |
+----------+-------------------+
  1. Execute the canary pipeline on the Dev2 region. We provide a script that updates frontend-v2 traffic percentages in the VirtualService (updating weights to 20%, 50%, 80%, then 100%). Between updates, the script waits for the Cloud Build pipeline to complete. Run the canary deployment script for the Dev1 region. Note - this script takes about 10 minutes to complete.
K8S_REPO=$K8S_REPO CANARY_DIR=$CANARY_DIR \
OPS_DIR=$OPS_GKE_2_CLUSTER OPS_CONTEXT=$OPS_GKE_2 \
${CANARY_DIR}/auto-canary.sh
 

Output (do not copy)

500 requests to http://frontend:80/version...
+----------+-------------------+
| RESPONSE | % OF 500 REQUESTS |
+----------+-------------------+
| v1       | 100.0%            |
|          |                   |
+----------+-------------------+
  1. From the Respy pod in Dev2, watch traffic from Dev2 pods move progressively from frontend v1 to v2. Once the script completes, you should see:

Output (do not copy)

500 requests to http://frontend:80/version...
+----------+-------------------+
| RESPONSE | % OF 500 REQUESTS |
+----------+-------------------+
| v2       | 100.0%            |
|          |                   |
+----------+-------------------+
  1. Close the split pane.
tmux respawn-pane -t ${TMUX_SESSION}:0.1 -k 'exit'

This section introduced how to use Istio for regional canary deployments. In production, instead of a manual script, you might automatically trigger this canary script as a Cloud Build pipeline, using a trigger such as a new tagged image pushed to a container registry. You would also want to add canary analysis in between each step, analyzing v2's latency and error rate against a predefined safety threshold, before sending over more traffic.

11. Authorization Policies

Objective: Set up RBAC between microservices (AuthZ).

  • Create AuthorizationPolicy to DENY access to a microservice
  • Create AuthorizationPolicy to ALLOW specific access to a microservice

Copy-and-Paste Method Lab Instructions

Unlike a monolithic application that might be running in one place, globally-distributed microservices apps make calls across network boundaries. This means more points of entry into your applications, and more opportunities for malicious attacks. And because Kubernetes pods have transient IPs, traditional IP-based firewall rules are no longer adequate to secure access between workloads. In a microservices architecture, a new approach to security is needed. Building on Kubernetes security building blocks like service accounts , Istio provides a flexible set of security policies for your applications.

Istio policies cover both authentication and authorization. Authentication verifies identity (is this server who they say they are?), and authorization verifies permissions (is this client allowed to do that?). We covered Istio authentication in the mutual TLS section in Module 1 (MeshPolicy). In this section, we will learn how to use Istio authorization policies to control access to one of our application workloads, currencyservice .

First, we'll deploy an AuthorizationPolicy across all 4 Dev clusters, closing off all access to currencyservice, and triggering an error in the frontend. Then, we will allow only the frontend service to access currencyservice.

  1. Inspect the contents of currency-deny-all.yaml . This policy uses Deployment label selectors to restrict access to the currencyservice. Notice how there is no spec field - this means this policy will deny all access to the selected service.
cat $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-deny-all.yaml
 

Output (do not copy)

apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
  name: "currency-policy"
  namespace: currency
spec:
  selector:
    matchLabels:
      app: currencyservice
  1. Copy the currency policy into k8s-repo, for the ops clusters in both regions.
cp $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-deny-all.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-authorization/currency-policy.yaml
cd $WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-authorization
kustomize edit add resource currency-policy.yaml
cp $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-deny-all.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-authorization/currency-policy.yaml
cd $WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-authorization
kustomize edit add resource currency-policy.yaml
  1. Push changes.
cd $WORKDIR/k8s-repo 
git add . && git commit -am "AuthorizationPolicy - currency: deny all"
git push 
  1. Check the status of the Ops project Cloud Build in a previously opened tab or by clicking the following link:
echo https://console.cloud.google.com/cloud-build/builds?project=$TF_VAR_ops_project_name 
 
  1. After the build finishes successfully, try to reach the hipstershop frontend in a browser on the following link:
echo "https://frontend.endpoints.$TF_VAR_ops_project_name.cloud.goog" 
 

You should see an Authorization error from currencyservice:

f120f3d30d6ee9f.png

  1. Let's investigate how the currency service is enforcing this AuthorizationPolicy. First, enable trace-level logs on the Envoy proxy for one of the currency pods, since blocked authorization calls aren't logged by default.
CURRENCY_POD=$(kubectl --context $DEV1_GKE_2 get pod -n currency | grep currency| awk '{ print $1 }')
kubectl --context $DEV1_GKE_2 exec -it $CURRENCY_POD -n \
currency -c istio-proxy -- curl -X POST \
"http://localhost:15000/logging?level=trace"
 
  1. Get the RBAC (authorization) logs from the currency service's sidecar proxy. You should see an "enforced denied" message, indicating that the currencyservice is set to block all inbound requests.
kubectl --context $DEV1_GKE_2 logs -n currency $CURRENCY_POD \
-c istio-proxy | grep -m 3 rbac
 

Output (do not copy)

[Envoy (Epoch 0)] [2020-01-30 00:45:50.815][22][debug][rbac] [external/envoy/source/extensions/filters/http/rbac/rbac_filter.cc:67] checking request: remoteAddress: 10.16.5.15:37310, localAddress: 10.16.3.8:7000, ssl: uriSanPeerCertificate: spiffe://cluster.local/ns/frontend/sa/frontend, subjectPeerCertificate: , headers: ':method', 'POST'
[Envoy (Epoch 0)] [2020-01-30 00:45:50.815][22][debug][rbac] [external/envoy/source/extensions/filters/http/rbac/rbac_filter.cc:118] enforced denied
[Envoy (Epoch 0)] [2020-01-30 00:45:50.815][22][debug][http] [external/envoy/source/common/http/conn_manager_impl.cc:1354] [C115][S17310331589050212978] Sending local reply with details rbac_access_denied
  1. Now, let's allow the frontend – but not the other backend services – to access currencyservice. Open currency-allow-frontend.yaml and inspect its contents. Note that we've added the following rule:
cat ${WORKDIR}/asm/k8s_manifests/prod/app-authorization/currency-allow-frontend.yaml

Output (do not copy)

rules:
 - from:
   - source:
       principals: ["cluster.local/ns/frontend/sa/frontend"]

Here, we are whitelisting a specific source.principal (client) to access currency service. This source.principal is defined by is Kubernetes Service Account. In this case, the service account we are whitelisting is the frontend service account in the frontend namespace.

Note: when using Kubernetes Service Accounts in Istio AuthorizationPolicies, you must first enable cluster-wide mutual TLS, as we did in Module 1. This is to ensure that service account credentials are mounted into requests.

  1. Copy over the updated currency policy
cp $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-allow-frontend.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-authorization/currency-policy.yaml
cp $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-allow-frontend.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-authorization/currency-policy.yaml
 
  1. Push changes.
cd $WORKDIR/k8s-repo
git add . && git commit -am "AuthorizationPolicy - currency: allow frontend"
git push
 
  1. View the status of the Ops project Cloud Build in a previously opened tab or by clicking the following link:
echo https://console.cloud.google.com/cloud-build/builds?project=$TF_VAR_ops_project_name
  1. After the build finishes successfully, open the Hipstershop frontend again. This time you should see no errors in the homepage - this is because the frontend is explicitly allowed to access the current service.
  2. Now, try to execute a checkout, by adding items to your cart and clicking "place order." This time, you should see a price-conversion error from currency service - this is because we have only whitelisted the frontend, so the checkoutservice is still unable to access currencyservice.

7e30813d693675fe.png

  1. Finally, let's allow the checkout service access to currency, by adding another rule to our currencyservice AuthorizationPolicy. Note that we are only opening up currency access to the two services that need to access it - frontend and checkout. The other backends will still be blocked.
  2. Open currency-allow-frontend-checkout.yaml and inspect its contents. Notice that the list of rules functions as a logical OR - currency will accept only requests from workloads with either of these two service accounts.
cat ${WORKDIR}/asm/k8s_manifests/prod/app-authorization/currency-allow-frontend-checkout.yaml
 

Output (do not copy)

apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
  name: "currency-policy"
  namespace: currency
spec:
  selector:
    matchLabels:
      app: currencyservice
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/frontend/sa/frontend"]
  - from:
    - source:
        principals: ["cluster.local/ns/checkout/sa/checkout"]
  1. Copy the final authorization policy to k8s-repo.
cp $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-allow-frontend-checkout.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-authorization/currency-policy.yaml
cp $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-allow-frontend-checkout.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-authorization/currency-policy.yaml
 
  1. Push changes
cd $WORKDIR/k8s-repo 
git add . && git commit -am "AuthorizationPolicy - currency: allow frontend and checkout"
git push
 
  1. View the status of the Ops project Cloud Build in a previously opened tab or by clicking the following link:
echo https://console.cloud.google.com/cloud-build/builds?project=$TF_VAR_ops_project_name
 
  1. After the build finishes successfully, try to execute a checkout - it should work successfully.

This section walked through how to use Istio Authorization Policies to enforce granular access control at the per-service level. In production, you might create one AuthorizationPolicy per service, and (for instance) use an allow-all policy to let all workloads in the same namespace access each other.

12. Infrastructure Scaling

Objective: Scale infrastructure by adding new region, project, and clusters.

  • Clone the infrastructure repo
  • Update the terraform files to create new resources
  • 2 subnets in the new region (one for the ops project and one for the new project)
  • New ops cluster in new region (in the new subnet)
  • New Istio control plane for the new region
  • 2 apps clusters in the new project in the new region
  • Commit to infrastructure repo
  • Verify installation

Copy-and-Paste Method Lab Instructions

There are a number of ways to scale a platform. You can add more compute by adding nodes to existing clusters. You can add more clusters in a region. Or you can add more regions to the platform. The decision on what aspect of the platform to scale depends upon the requirements. For example, if you have clusters in all three zones in a region, perhaps adding more nodes (or node pools) to existing cluster may suffice. However, if you have clusters in two of three zones in a single region, then adding a new cluster in the third zone gives you scaling and an additional fault domain (ie a new zone). Another reason for adding a new cluster in a region might be the need to create a single tenant cluster - for regulatory or compliance reasons (for example PCI, or a database cluster that houses PII information). As your business and services expand, adding new regions become inevitable to provide services closer to the clients.

The current platform consists of two regions and clusters in two zones per region. You can think of scaling the platform in two ways:

  • Vertically - within each region by adding more compute. This is done either by adding more nodes (or node pools) to existing clusters or by adding new clusters within the region. This is done via the infrastructure repo. The simplest path is adding nodes to existing clusters. No additional configuration is required. Adding new clusters may require additional subnets (and secondary ranges), adding appropriate firewall rules, adding the new clusters to the regional ASM/Istio service mesh control plane and deploying application resources to the new clusters.
  • Horizontally - by adding more regions. The current platform gives you a regional template. It consists on a regional ops cluster where the ASM/Istio control please resides and two (or more) zonal application clusters where application resources are deployed.

In this workshop, you scale the platform "horizontally" as it encompasses the vertical use case steps as well. In order to horizontally, scale the platform by adding a new region (r3) to the platform, the following resources need to be added:

  1. Subnets in the host project shared VPC in region r3 for the new ops and application clusters.
  2. A regional ops cluster in region r3 where the ASM/Istio control plane resides.
  3. Two zonal application clusters in two zones on region r3.
  4. Update to the k8s-repo:
  5. Deploy ASM/Istio control plane resources to the ops cluster in region r3.
  6. Deploy ASM/Istio shared control plane resources to the app clusters in region r3.
  7. While you don't need to create a new project, the steps in the workshop demonstrate adding a new project dev3 to cover the use case of adding a new team to the platform.

Infrastructure repo is used to add new resources stated above.

  1. In Cloud Shell, navigate to WORKDIR and clone the infrastructure repo.
mkdir -p $WORKDIR/infra-repo
cd $WORKDIR/infra-repo
git init && git remote add origin https://source.developers.google.com/p/${TF_ADMIN}/r/infrastructure
git config --local user.email ${MY_USER}
git config --local user.name "infra repo user"
git config --local credential.'https://source.developers.google.com'.helper gcloud.sh
git pull origin master
  1. Clone the workshop source repo add-proj branch into the add-proj-repo directory.
cd $WORKDIR
git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-workshop.git add-proj-repo -b add-proj

 
  1. Copy files from the add-proj branch in the source workshop repo. The add-proj branch contains the changes for this section.
cp -r $WORKDIR/add-proj-repo/infrastructure/* $WORKDIR/infra-repo/
 
  1. Replace the infrastructure directory in the add-proj repo directory with a symlink to the infra-repo directory to allow the scripts on the branch to run.
rm -rf $WORKDIR/add-proj-repo/infrastructure
ln -s $WORKDIR/infra-repo $WORKDIR/add-proj-repo/infrastructure
 
  1. Run the add-project.sh script to copy the shared states and vars to the new project directory structure.
$WORKDIR/add-proj-repo/scripts/add-project.sh app3 $WORKDIR/asm $WORKDIR/infra-repo
  1. Commit and push changes to create new project
cd $WORKDIR/infra-repo
git add .
git status
git commit -m "add new project" && git push origin master
 

  1. The commit triggers the infrastructure repo to deploy the infrastructure with the new resources. View the Cloud Build progress by clicking on the output of the following link and navigating to the latest build at the top.
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_ADMIN}"
 

The last step of the infrastructure Cloud Build creates new Kubernetes resources in the k8s-repo . This triggers the Cloud Build in the k8s-repo (in the ops project). The new Kubernetes resources are for the three new clusters added in the previous step. ASM/Istio control plane and shared control plane resources are added to the new clusters with the k8s-repo Cloud Build.

  1. After the infrastructure Cloud Build successfully finishes, navigate to the k8s-repo latest Cloud Build run by clicking on the following output link.
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_VAR_ops_project_name}"
 
  1. Run the following script to add the new clusters to the vars and kubeconfig file.
$WORKDIR/add-proj-repo/scripts/setup-gke-vars-kubeconfig-add-proj.sh $WORKDIR/asm
 
  1. Change the KUBECONFIG variable to point to the new kubeconfig file.
source $WORKDIR/asm/vars/vars.sh
export KUBECONFIG=$WORKDIR/asm/gke/kubemesh
 
  1. List your cluster contexts. You should see eight clusters.
kubectl config view -ojson | jq -r '.clusters[].name'
 
    `Output (do not copy)`
gke_user001-200204-05-dev1-49tqc4_us-west1-a_gke-1-apps-r1a-prod
gke_user001-200204-05-dev1-49tqc4_us-west1-b_gke-2-apps-r1b-prod
gke_user001-200204-05-dev2-49tqc4_us-central1-a_gke-3-apps-r2a-prod
gke_user001-200204-05-dev2-49tqc4_us-central1-b_gke-4-apps-r2b-prod
gke_user001-200204-05-dev3-49tqc4_us-east1-b_gke-5-apps-r3b-prod
gke_user001-200204-05-dev3-49tqc4_us-east1-c_gke-6-apps-r3c-prod
gke_user001-200204-05-ops-49tqc4_us-central1_gke-asm-2-r2-prod
gke_user001-200204-05-ops-49tqc4_us-east1_gke-asm-3-r3-prod
gke_user001-200204-05-ops-49tqc4_us-west1_gke-asm-1-r1-prod

Verify Istio Installation

  1. Ensure Istio is installed on the new ops cluster by checking all pods are running and jobs have completed.
kubectl --context $OPS_GKE_3 get pods -n istio-system
 
    `Output (do not copy)`
NAME                                      READY   STATUS    RESTARTS   AGE
grafana-5f798469fd-72g6w                  1/1     Running   0          5h12m
istio-citadel-7d8595845-hmmvj             1/1     Running   0          5h12m
istio-egressgateway-779b87c464-rw8bg      1/1     Running   0          5h12m
istio-galley-844ddfc788-zzpkl             2/2     Running   0          5h12m
istio-ingressgateway-59ccd6574b-xfj98     1/1     Running   0          5h12m
istio-pilot-7c8989f5cf-5plsg              2/2     Running   0          5h12m
istio-policy-6674bc7678-2shrk             2/2     Running   3          5h12m
istio-sidecar-injector-7795bb5888-kbl5p   1/1     Running   0          5h12m
istio-telemetry-5fd7cbbb47-c4q7b          2/2     Running   2          5h12m
istio-tracing-cd67ddf8-2qwkd              1/1     Running   0          5h12m
istiocoredns-5f7546c6f4-qhj9k             2/2     Running   0          5h12m
kiali-7964898d8c-l74ww                    1/1     Running   0          5h12m
prometheus-586d4445c7-x9ln6               1/1     Running   0          5h12m
  1. Ensure Istio is installed on both dev3 clusters. Only Citadel, sidecar-injector and coredns run in the dev3 clusters. They share an Istio controlplane running in the ops-3 cluster.
kubectl --context $DEV3_GKE_1 get pods -n istio-system
kubectl --context $DEV3_GKE_2 get pods -n istio-system
 
    `Output (do not copy)`
NAME                                      READY   STATUS    RESTARTS   AGE
istio-citadel-568747d88-4lj9b             1/1     Running   0          66s
istio-sidecar-injector-759bf6b4bc-ks5br   1/1     Running   0          66s
istiocoredns-5f7546c6f4-qbsqm             2/2     Running   0          78s

Verify service discovery for shared control planes

  1. Verify the secrets are deployed in all ops clusters for all six application clusters.
kubectl --context $OPS_GKE_1 get secrets -l istio/multiCluster=true -n istio-system
kubectl --context $OPS_GKE_2 get secrets -l istio/multiCluster=true -n istio-system
kubectl --context $OPS_GKE_3 get secrets -l istio/multiCluster=true -n istio-system
 
    `Output (do not copy)`
NAME                  TYPE     DATA   AGE
gke-1-apps-r1a-prod   Opaque   1      14h
gke-2-apps-r1b-prod   Opaque   1      14h
gke-3-apps-r2a-prod   Opaque   1      14h
gke-4-apps-r2b-prod   Opaque   1      14h
gke-5-apps-r3b-prod   Opaque   1      5h12m
gke-6-apps-r3c-prod   Opaque   1      5h12m

13. Circuit Breaking

Objective: Implement a Circuit Breaker for the shipping Service.

  • Create a DestinationRule for the shipping Service to implement a circuit breaker
  • Use fortio (a load gen utility) to validate circuit breaker for the shipping Service by force tripping the circuit

Fast Track Script Lab Instructions

Fast Track Script Lab is coming soon!!

Copy-and-Paste Method Lab Instructions

Now that we've learned some basic monitoring and troubleshooting strategies for Istio-enabled services, let's look at how Istio helps you improve the resilience of your services, reducing the amount of troubleshooting you'll have to do in the first place.

A microservices architecture introduces the risk of cascading failures , where the failure of one service can propagate to its dependencies, and the dependencies of those dependencies, causing a "ripple effect" outage that can potentially affect end-users. Istio provides a Circuit Breaker traffic policy to help you isolate services, protecting downstream (client-side) services from waiting on failing services, and protecting upstream (server-side) services from a sudden flood of downstream traffic when they do come back online. Overall, using Circuit Breakers can help you avoid all your services failing their SLOs because of one backend service that is hanging.

The Circuit Breaker pattern is named for an electrical switch that can "trip" when too much electricity flows through, protecting devices from overload. In an Istio setup , this means that Envoy is the circuit breaker, keeping track of the number of pending requests for a service. In this default closed state, requests flow through Envoy uninterrupted.

But when the number of pending requests exceeds your defined threshold, the circuit breaker trips (opens), and Envoy immediately returns an error. This allows the server to fail fast for the client, and prevents the server application code from receiving the client's request when overloaded.

Then, after your defined timeout, Envoy moves to a half open state, where the server can start receiving requests again in a probationary way, and if it can successfully respond to requests, the circuit breaker closes again, and requests to the server begin to flow again.

This diagram summarizes the Istio circuit breaker pattern. The blue rectangles represent Envoy, the blue-filled circle represents the client, and the white-filled circles represent the server container:

2127a0a172ff4802.png

You can define Circuit Breaker policies using Istio DestinationRules. In this section, we'll apply the following policy to enforce a circuit breaker for the shipping service:

Output (do not copy)

apiVersion: "networking.istio.io/v1alpha3"
kind: "DestinationRule"
metadata:
  name: "shippingservice-shipping-destrule"
  namespace: "shipping"
spec:
  host: "shippingservice.shipping.svc.cluster.local"
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL
    connectionPool:
      tcp:
        maxConnections: 1
      http:
        http1MaxPendingRequests: 1
        maxRequestsPerConnection: 1
    outlierDetection:
      consecutiveErrors: 1
      interval: 1s
      baseEjectionTime: 10s
      maxEjectionPercent: 100

There are two DestinationRule fields to note here. connectionPool defines the number of connections this service will allow. The outlierDetection field is where we configure how Envoy will determine the threshold at which to open the circuit breaker. Here, every second (interval), Envoy will count the number of errors it received from the server container. If it exceeds the consecutiveErrors threshold, the Envoy circuit breaker will open, and 100% of productcatalog pods will be shielded from new client requests for 10 seconds. Once the Envoy circuit breaker is open (ie. active), clients will receive 503 (Service Unavailable) errors. Let's see this in action.

  1. Set environment variables for the k8s-repo and asm dir to simplify commands.
export K8S_REPO="${WORKDIR}/k8s-repo"
export ASM="${WORKDIR}/asm" 
 
  1. Update the k8s-repo
cd $WORKDIR/k8s-repo
git pull
cd $WORKDIR
  1. Update the shipping service DestinationRule on both Ops clusters.
cp $ASM/k8s_manifests/prod/istio-networking/app-shipping-circuit-breaker.yaml ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/app-shipping-circuit-breaker.yaml
cp $ASM/k8s_manifests/prod/istio-networking/app-shipping-circuit-breaker.yaml ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/app-shipping-circuit-breaker.yaml

cd ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/; kustomize edit add resource app-shipping-circuit-breaker.yaml
cd ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/; kustomize edit add resource app-shipping-circuit-breaker.yaml
 
  1. Copy a Fortio load generator pod into the GKE_1 cluster in the Dev1 region. This is the client pod we'll use to "trip" the circuit breaker for shippingservice.
cp $ASM/k8s_manifests/prod/app/deployments/app-fortio.yaml ${K8S_REPO}/${DEV1_GKE_1_CLUSTER}/app/deployments/
cd ${K8S_REPO}/${DEV1_GKE_1_CLUSTER}/app/deployments; kustomize edit add resource app-fortio.yaml
 
  1. Commit changes.
cd $K8S_REPO 
git add . && git commit -am "Circuit Breaker: shippingservice"
git push
cd $ASM
 
  1. Wait for Cloud Build to complete.
  2. Back in Cloud Shell, use the fortio pod to send gRPC traffic to shippingservice with 1 concurrent connection, 1000 requests total - this will not trip the circuit breaker, because we have not exceeded the connectionPool settings yet.
FORTIO_POD=$(kubectl --context ${DEV1_GKE_1} get pod -n shipping | grep fortio | awk '{ print $1 }')

kubectl --context ${DEV1_GKE_1} exec -it $FORTIO_POD -n shipping -c fortio /usr/bin/fortio -- load -grpc -c 1 -n 1000 -qps 0 shippingservice.shipping.svc.cluster.local:50051 
 

Output (do not copy)

Health SERVING : 1000
All done 1000 calls (plus 0 warmup) 4.968 ms avg, 201.2 qps
  1. Now run fortio again, increasing the number of concurrent connections to 2, but keeping the total number of requests constant. We should see up to two-thirds of the requests return an "overflow" error, because the circuit breaker has been tripped: in the policy we defined, only 1 concurrent connection is allowed in a 1-second interval.
kubectl --context ${DEV1_GKE_1} exec -it $FORTIO_POD -n shipping -c fortio /usr/bin/fortio -- load -grpc -c 2 -n 1000 -qps 0 shippingservice.shipping.svc.cluster.local:50051 
 

Output (do not copy)

18:46:16 W grpcrunner.go:107> Error making grpc call: rpc error: code = Unavailable desc = upstream connect error or disconnect/reset before headers. reset reason: overflow
...

Health ERROR : 625
Health SERVING : 375
All done 1000 calls (plus 0 warmup) 12.118 ms avg, 96.1 qps
  1. Envoy keeps track of the number of connections it dropped when the circuit breaker is active, with the upstream_rq_pending_overflow metric. Let's find this in the fortio pod:
kubectl --context ${DEV1_GKE_1} exec -it $FORTIO_POD -n shipping -c istio-proxy  -- sh -c 'curl localhost:15000/stats' | grep shipping | grep pending
 

Output (do not copy)

cluster.outbound|50051||shippingservice.shipping.svc.cluster.local.circuit_breakers.default.rq_pending_open: 0
cluster.outbound|50051||shippingservice.shipping.svc.cluster.local.circuit_breakers.high.rq_pending_open: 0
cluster.outbound|50051||shippingservice.shipping.svc.cluster.local.upstream_rq_pending_active: 0
cluster.outbound|50051||shippingservice.shipping.svc.cluster.local.upstream_rq_pending_failure_eject: 9
cluster.outbound|50051||shippingservice.shipping.svc.cluster.local.upstream_rq_pending_overflow: 565
cluster.outbound|50051||shippingservice.shipping.svc.cluster.local.upstream_rq_pending_total: 1433
  1. Clean up by removing the circuit breaker policy from both regions.
kubectl --context ${OPS_GKE_1} delete destinationrule shippingservice-circuit-breaker -n shipping 
rm ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/app-shipping-circuit-breaker.yaml
cd ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/; kustomize edit remove resource app-shipping-circuit-breaker.yaml
 

kubectl --context ${OPS_GKE_2} delete destinationrule shippingservice-circuit-breaker -n shipping 
rm ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/app-shipping-circuit-breaker.yaml
cd ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/; kustomize edit remove resource app-shipping-circuit-breaker.yaml
cd $K8S_REPO; git add .; git commit -m "Circuit Breaker: cleanup"; git push origin master
 

This section demonstrated how to set up a single circuit breaker policy for a service. A best practice is to set up a circuit breaker for any upstream (backend) service that has the potential to hang. By applying Istio circuit breaker policies, you help isolate your microservices, build fault tolerance into your architecture, and reduce the risk of cascading failures under high load.

14. Fault Injection

Objective: Test the resilience of the recommendation Service by introducing delays (before it is pushed to production).

  • Create a VirtualService for the recommendation Service to introduce a 5s delay
  • Test the delay using fortio load generator
  • Remove the delay in the VirtualService and validate

Fast Track Script Lab Instructions

Fast Track Script Lab is coming soon!!

Copy-and-Paste Method Lab Instructions

Adding circuit breaker policies to your services is one way to build resilience against services in production. But circuit breaking results in faults — potentially user-facing errors — which is not ideal. To get ahead of these error cases, and better predict how your downstream services might respond when backends do return errors, you can adopt chaos testing in a staging environment. Chaos testing is the practice of deliberately breaking your services, in order to analyze weak points in the system and improve fault tolerance. You can also use chaos testing to identify ways to mitigate user-facing errors when backends fail - for instance, by displaying a cached result in a frontend.

Using Istio for fault injection is helpful because you can use your production release images, and add the fault at the network layer, instead of modifying source code. In production, you might use a full-fledged chaos testing tool to test resilience at the Kubernetes/compute layer in addition to the network layer.

You can use Istio for chaos testing by applying a VirtualService with the "fault" field. Istio supports two kinds of faults: delay faults (inject a timeout) and abort faults (inject HTTP errors). In this example, we'll inject a 5-second delay fault into the recommendations service . But this time instead of using a circuit breaker to "fail fast" against this hanging service, we will force downstream services to endure the full timeout.

  1. Navigate into the fault injection directory.
export K8S_REPO="${WORKDIR}/k8s-repo"
export ASM="${WORKDIR}/asm/" 
cd $ASM
 
  1. Open k8s_manifests/prod/istio-networking/app-recommendation-vs-fault.yaml to inspect its contents. Notice that Istio has an option to inject the fault into a percentage of the requests - here, we'll introduce a timeout into all recommendationservice requests.

Output (do not copy)

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: recommendation-delay-fault
spec:
  hosts:
  - recommendationservice.recommendation.svc.cluster.local
  http:
  - route:
    - destination:
        host: recommendationservice.recommendation.svc.cluster.local
    fault:
      delay:
        percentage:
          value: 100
        fixedDelay: 5s
  1. Copy the VirtualService into k8s_repo. We'll inject the fault globally, across both regions.
cp $ASM/k8s_manifests/prod/istio-networking/app-recommendation-vs-fault.yaml ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/app-recommendation-vs-fault.yaml
cd ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/; kustomize edit add resource app-recommendation-vs-fault.yaml

cp $ASM/k8s_manifests/prod/istio-networking/app-recommendation-vs-fault.yaml ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/app-recommendation-vs-fault.yaml
cd ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/; kustomize edit add resource app-recommendation-vs-fault.yaml
 
  1. Push changes
cd $K8S_REPO 
git add . && git commit -am "Fault Injection: recommendationservice"
git push
cd $ASM
 
  1. Wait for Cloud Build to complete.
  2. Exec into the fortio pod deployed in the circuit breaker section, and send some traffic to recommendationservice.
FORTIO_POD=$(kubectl --context ${DEV1_GKE_1} get pod -n shipping | grep fortio | awk '{ print $1 }')

kubectl --context ${DEV1_GKE_1} exec -it $FORTIO_POD -n shipping -c fortio /usr/bin/fortio -- load -grpc -c 100 -n 100 -qps 0 recommendationservice.recommendation.svc.cluster.local:8080
 
    Once the fortio command is complete, you should see responses averaging 5s:

Output (do not copy)

Ended after 5.181367359s : 100 calls. qps=19.3
Aggregated Function Time : count 100 avg 5.0996506 +/- 0.03831 min 5.040237641 max 5.177559818 sum 509.965055
  1. Another way to see the fault we injected in action is open the frontend in a web browser, and click on any product. A product page should take 5 extra seconds to load, since it fetches the recommendations that are displayed at the bottom of the page.
  2. Clean up by removing the fault injection service from both Ops clusters.
kubectl --context ${OPS_GKE_1} delete virtualservice recommendation-delay-fault -n recommendation 
rm ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/app-recommendation-vs-fault.yaml
cd ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/; kustomize edit remove resource app-recommendation-vs-fault.yaml

kubectl --context ${OPS_GKE_2} delete virtualservice recommendation-delay-fault -n recommendation 
rm ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/app-recommendation-vs-fault.yaml
cd ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/; kustomize edit remove resource app-recommendation-vs-fault.yaml
 
  1. Push changes:
cd $K8S_REPO 
git add . && git commit -am "Fault Injection cleanup / restore"
git push
cd $ASM
 

15. Monitoring the Istio Control Plane

ASM installs four important control plane components: Pilot, Mixer, Galley and Citadel. Each sends its relevant monitoring metrics to Prometheus, and ASM ships with Grafana dashboards that let operators visualize this monitoring data and assess the health and performance of the control plane.

Viewing the Dashboards

  1. Port-forward your Grafana service installed with Istio
kubectl --context ${OPS_GKE_1} -n istio-system port-forward svc/grafana 3000:3000 >> /dev/null
 
  1. Open Grafana in your browser
  2. Click on the "Web Preview" icon on the top right corner of your Cloud Shell Window
  3. Click Preview on port 3000 (Note: if the port is not 3000, click on change port and select port 3000)
  4. This will open a tab in your browser with a URL similar to " BASE_URL/?orgId=1&authuser=0&environment_id=default "
  5. View available dashboards
  6. Modify the URL to " BASE_URL/dashboard "
  7. Click on "istio" folder to view available dashboards
  8. Click on any of those dashboards to view the performance of that component. We'll look at the important metrics for each component in the following sections.

Monitoring Pilot

Pilot is the control plane component that distributes networking and policy configuration to the data plane (the Envoy proxies). Pilot tends to scale with the number of workloads and deployments, although not necessarily with the amount of traffic to those workloads. An unhealthy Pilot can:

  • consume more resources than necessary (CPU and/or RAM)
  • result in delays in pushing updated configuration information to Envoys

Note: if Pilot is down, or if there are delays, your workloads still serve traffic.

  1. Navigate to " BASE_URL/dashboard/db/istio-pilot-dashboard " in your browser to view Pilot metrics.

Important monitored metrics

সম্পদ ব্যবহার

Use the Istio Performance and Scalability page as your guide for acceptable usage numbers. Contact GCP support if you see significantly more sustained resource usage than this.

5f1969f8e2c8b137.png

Pilot Push Information

This section monitors Pilots pushes of configuration to your Envoy proxies.

  • Pilot Pushes shows the type of configuration pushed at any given time.
  • ADS Monitoring shows the number of Virtual Services, Services and Connected Endpoints in the system.
  • Clusters with no known endpoints shows endpoints that have been configured but do not have any instances running (which may indicate external services, such as *.googleapis.com).
  • Pilot Errors show the number of errors encountered over time.
  • Conflicts show the number of conflicts which are ambiguous configuration on listeners.

If you have Errors or Conflicts, you have bad or inconsistent configuration for one or more of your services. See Troubleshooting the data plane for information.

Envoy Information

This section contains information about the Envoy proxies contacting the control plane. Contact GCP support if you see repeated XDS Connection Failures.

Monitoring Mixer

Mixer is the component that funnels telemetry from the Envoy proxies to telemetry backends (typically Prometheus, Stackdriver, etc). In this capacity, it is not in the data plane. It is deployed as two Kubernetes Jobs (called Mixer) deployed with two different service names (istio-telemetry and istio-policy).

Mixer can also be used to integrate with policy systems. In this capacity, Mixer does affect the data plane, as policy checks to Mixer that fail block access to your services.

Mixer tends to scale with volume of traffic.

  1. Navigate to " BASE_URL/dashboard/db/istio-mixer-dashboard " in your browser to view Mixer metrics.

Important monitored metrics

সম্পদ ব্যবহার

Use the Istio Performance and Scalability page as your guide for acceptable usage numbers. Contact GCP support if you see significantly more sustained resource usage than this.

87ed83238f9addd8.png

Mixer Overview

  • Response Duration is an important metric. While reports to Mixer telemetry are not in the datapath, if these latencies are high it will definitely slow down sidecar proxy performance. You should expect the 90th percentile to be in the single-digit milliseconds, and the 99th percentile to be under 100ms.

e07bdf5fde4bfe87.png

  • Adapter Dispatch Duration indicates the latency Mixer is experiencing in calling adapters (through which it sends information to telemetry and logging systems). High latencies here will absolutely affect performance on the mesh. Again, p90 latencies should be under 10ms.

1c2ee56202b32bd9.png

Monitoring Galley

Galley is Istio's configuration validation, ingestion, processing and distribution component. It conveys configuration from the Kubernetes API server to Pilot. Like Pilot, it tends to scale with the number of services and endpoints in the system.

  1. Navigate to " BASE_URL/dashboard/db/istio-galley-dashboard " in your browser to view Galley metrics.

Important monitored metrics

Resource Validation

The most important metric to follow which indicates the number of resources of various types like Destination rules, Gateways and Service entries that are passing or failing validation.

Connected clients

Indicates how many clients are connected to Galley; typically this will be 3 (pilot, istio-telemetry, istio-policy) and will scale as those components scale.

16. Troubleshooting Istio

Troubleshooting the data plane

If your Pilot dashboard indicates that you have configuration issues, you should examine PIlot logs or use istioctl to find configuration problems.

To examine Pilot logs, run kubectl -n istio-system logs istio-pilot-69db46c598-45m44 discovery, replacing istio-pilot-... with the pod identifier for the Pilot instance you want to troubleshoot.

In the resulting log, search for a Push Status message. For example:

2019-11-07T01:16:20.451967Z        info        ads        Push Status: {
    "ProxyStatus": {
        "pilot_conflict_outbound_listener_tcp_over_current_tcp": {
            "0.0.0.0:443": {
                "proxy": "cartservice-7555f749f-k44dg.hipster",
                "message": "Listener=0.0.0.0:443 AcceptedTCP=accounts.google.com,*.googleapis.com RejectedTCP=edition.cnn.com TCPServices=2"
            }
        },
        "pilot_duplicate_envoy_clusters": {
            "outbound|15443|httpbin|istio-egressgateway.istio-system.svc.cluster.local": {
                "proxy": "sleep-6c66c7765d-9r85f.default",
                "message": "Duplicate cluster outbound|15443|httpbin|istio-egressgateway.istio-system.svc.cluster.local found while pushing CDS"
            },
            "outbound|443|httpbin|istio-egressgateway.istio-system.svc.cluster.local": {
                "proxy": "sleep-6c66c7765d-9r85f.default",
                "message": "Duplicate cluster outbound|443|httpbin|istio-egressgateway.istio-system.svc.cluster.local found while pushing CDS"
            },
            "outbound|80|httpbin|istio-egressgateway.istio-system.svc.cluster.local": {
                "proxy": "sleep-6c66c7765d-9r85f.default",
                "message": "Duplicate cluster outbound|80|httpbin|istio-egressgateway.istio-system.svc.cluster.local found while pushing CDS"
            }
        },
        "pilot_eds_no_instances": {
            "outbound_.80_._.frontend-external.hipster.svc.cluster.local": {},
            "outbound|443||*.googleapis.com": {},
            "outbound|443||accounts.google.com": {},
            "outbound|443||metadata.google.internal": {},
            "outbound|80||*.googleapis.com": {},
            "outbound|80||accounts.google.com": {},
            "outbound|80||frontend-external.hipster.svc.cluster.local": {},
            "outbound|80||metadata.google.internal": {}
        },
        "pilot_no_ip": {
            "loadgenerator-778c8489d6-bc65d.hipster": {
                "proxy": "loadgenerator-778c8489d6-bc65d.hipster"
            }
        }
    },
    "Version": "o1HFhx32U4s="
}

The Push Status will indicate any issues that occurred when trying to push the configuration to Envoy proxies – in this case, we see several "Duplicate cluster" messages, which indicate duplicate upstream destinations.

For assistance in diagnosing problems, contact Google Cloud support with issues.

Finding configuration errors

In order to use istioctl to analyze your configuration, run istioctl experimental analyze -k --context $OPS_GKE_1 . This will perform an analysis of configuration in your system, indicate any problems along with any suggested changes. See documentation for a full list of configuration errors that this command can detect.

17. Cleanup

An administrator runs the cleanup_workshop.sh script to delete resources created by the bootstrap_workshop.sh script. You need the following pieces of information for the cleanup script to run.

  • Organization name - for example yourcompany.com
  • Workshop ID - in the form YYMMDD-NN for example 200131-01
  • Admin GCS bucket - defined in the bootstrap script.
  1. Open Cloud Shell, perform all actions below in Cloud Shell. Click on the link below.

CLOUD SHELL

  1. Verify you are logged into gcloud with the intended Admin user.
gcloud config list
 
  1. Navigate you the asm folder.
cd ${WORKDIR}/asm
 
  1. Define your Organization name and workshop ID to be deleted.
export ORGANIZATION_NAME=<ORGANIZATION NAME>
export ASM_WORKSHOP_ID=<WORKSHOP ID>
export ADMIN_STORAGE_BUCKET=<ADMIN CLOUD STORAGE BUCKET>
 
  1. Run the cleanup script as follows.
./scripts/cleanup_workshop.sh --workshop-id ${ASM_WORKSHOP_ID} --admin-gcs-bucket ${ADMIN_STORAGE_BUCKET} --org-name ${ORGANIZATION_NAME}