การใช้ Istio Multicluster เพื่อ "เพิ่ม" ปริมาณงานระหว่างคลัสเตอร์

1. ยินดีต้อนรับ

ขอขอบคุณที่เข้าร่วม Codelab Istio Multi Cloud Burst ของ Google นี้ Codelab นี้กำหนดให้ต้องมีประสบการณ์ระดับเริ่มต้นในการใช้งาน Kubernetes, Node และ Go

สิ่งที่ต้องมี

  • บัญชี Google Cloud Platform (ใช้บัญชีที่มีอยู่หรือเราจะให้บัญชีฟรี)
  • แล็ปท็อป (ติดตั้ง "kubectl", "gcloud" ฯลฯ) หรือจะใช้ Google Cloud Shell ก็ได้

สิ่งที่คุณจะได้เรียนรู้

  • วิธีสร้างคลัสเตอร์ Kubernetes ใน GKE
  • วิธีติดตั้ง Istio ในคลัสเตอร์ Kubernetes ด้วย Helm
  • วิธีติดตั้ง Istio Multicluster ด้วย Helm
  • การทำให้เว็บแอปพลิเคชันใช้งานได้จากแหล่งที่มาไปยัง Kubernetes
  • การเขียนและใช้กฎการกำหนดเส้นทางการเข้าชมกับ Istio
  • เมตริก Prometheus
  • สร้างและพุชอิมเมจคอนเทนเนอร์ภายในคลัสเตอร์ Kubernetes

2. การเริ่มตั้งค่า

คุณทำตาม Codelab นี้ได้จากอุปกรณ์ต่อไปนี้

  • Google Cloud Shell (แนะนำ): เชลล์ในเบราว์เซอร์ที่มาพร้อมกับเครื่องมือที่ติดตั้งไว้
  • แล็ปท็อป (ทำตามวิธีการด้านล่าง)

เริ่มต้นด้วย Google Cloud Platform

  1. รับการ์ดบัญชีผู้ใช้แบบไม่มีค่าใช้จ่ายจากผู้สอนหากคุณไม่มีบัญชี GCP
  2. ไปที่ Google Cloud Console แล้วคลิก "เลือกโปรเจ็กต์": 5c2d9bf74c78f7e4.png
  3. จด "รหัส" ของโปรเจ็กต์ไว้ จากนั้นคลิกโปรเจ็กต์เพื่อเลือก ecc5e8e97bfa6559.png

Cloud Shell มีเชลล์บรรทัดคำสั่งในเบราว์เซอร์พร้อมเครื่องมือที่คุณต้องติดตั้งและตรวจสอบสิทธิ์กับบัญชี Google Cloud Platform โดยอัตโนมัติ (หากไม่ต้องการฝึกฝนนี้ใน Cloud Shell ให้ข้ามไปยังส่วนถัดไป)

ไปที่ Cloud Console แล้วคลิก "เปิดใช้งาน Cloud Shell" ในแถบเครื่องมือด้านขวาบน

68a17b036ce24ccb.png

เพิ่มเครื่องมือลงใน Cloud Shell

  1. ติดตั้ง kubectx****: โดยดาวน์โหลดสคริปต์ Bash จากที่นี่ไปยังตำแหน่งใน $PATH
  2. ติดตั้ง helm****: ทำตามวิธีการเหล่านี้

หรือเรียกใช้คําสั่งเหล่านี้เพื่อติดตั้งทั้ง 2 รายการใน ~/.bin และเพิ่มลงใน $PATH

mkdir -p ~/.bin && \
cd ~/.bin && \
curl -LO https://raw.githubusercontent.com/ahmetb/kubectx/master/kubectx && \
chmod +x kubectx && \
curl -LO https://raw.githubusercontent.com/ahmetb/kubectx/master/kubens && \
chmod +x kubens && \
curl -LO  https://storage.googleapis.com/kubernetes-helm/helm-v2.12.0-linux-amd64.tar.gz && \
tar xzf helm-v2.12.0-linux-amd64.tar.gz && \
rm helm-v2.12.0-linux-amd64.tar.gz && \
mv linux-amd64/helm ./helm && \
rm -r linux-amd64 && \
export PATH=${HOME}/.bin:${PATH}

เคล็ดลับสั้นๆ ที่ช่วยให้คุณใช้ Cloud Shell ได้ง่ายขึ้น

1. แยกเชลล์ออกเป็นหน้าต่างใหม่

2. การใช้เครื่องมือแก้ไขไฟล์: คลิกไอคอนดินสอที่ด้านขวาบนเพื่อเปิดเครื่องมือแก้ไขไฟล์ในเบราว์เซอร์ ซึ่งจะมีประโยชน์เนื่องจากเราจะคัดลอกข้อมูลโค้ดลงในไฟล์

3. เริ่มแท็บใหม่: หากต้องการพรอมต์เทอร์มินัลมากกว่า 1 รายการ

4. ทำให้ข้อความใหญ่ขึ้น: ขนาดแบบอักษรเริ่มต้นใน Cloud Shell อาจเล็กเกินกว่าที่จะอ่านได้

Ctrl-+ ใน Linux/Windows⌘-+ ใน macOS

หากรู้สึกสะดวกกว่าที่จะใช้สภาพแวดล้อมเวิร์กสเตชันของคุณเองมากกว่า Cloud Shell ให้ตั้งค่าเครื่องมือต่อไปนี้

  1. ติดตั้ง gcloud: (ติดตั้งไว้ล่วงหน้าใน Cloud Shell) ทําตามวิธีการเพื่อติดตั้ง gcloud ในแพลตฟอร์ม เราจะใช้ข้อมูลนี้เพื่อสร้างคลัสเตอร์ Kubernetes
  2. ติดตั้ง kubectl:(ติดตั้งไว้ล่วงหน้าใน Cloud Shell) เรียกใช้คําสั่งต่อไปนี้เพื่อติดตั้ง
gcloud components install kubectl

เรียกใช้คำสั่งต่อไปนี้เพื่อตรวจสอบสิทธิ์ gcloud ระบบจะขอให้คุณเข้าสู่ระบบด้วยบัญชี Google จากนั้นเลือกโปรเจ็กต์ที่สร้างไว้ล่วงหน้า (ดูด้านบน) เป็นโปรเจ็กต์เริ่มต้น (คุณสามารถข้ามการกําหนดค่าโซนการประมวลผลได้)

gcloud init
  1. ติดตั้ง curl: ติดตั้งไว้ล่วงหน้าในระบบ Linux/macOS ส่วนใหญ่ คุณน่าจะมีอยู่แล้ว หรือค้นหาวิธีติดตั้งในอินเทอร์เน็ต
  2. ติดตั้ง kubectx****: โดยดาวน์โหลดสคริปต์ Bash จากที่นี่ ไปยังตำแหน่งใน $PATH
  3. ติดตั้ง helm****: ทำตามวิธีการเหล่านี้

3. ตั้งค่าโปรเจ็กต์ GCP

เปิดใช้ API ของ GKE (Google Kubernetes Engine), GCR (Google Container Registry) และ GCB (Google Cloud Build) ในโปรเจ็กต์ โดยทำดังนี้

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

ตั้งค่าตัวแปรสภาพแวดล้อม

เราจะทํางานกับโปรเจ็กต์ Google Cloud อย่างมากในระหว่างการตั้งค่า ดังนั้นมาตั้งค่าตัวแปรสภาพแวดล้อมเพื่อใช้อ้างอิงอย่างรวดเร็วกัน

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

เราจะสร้างโค้ดและไฟล์การกําหนดค่าบางส่วนในเวิร์กช็อปนี้ ดังนั้นมาสร้างไดเรกทอรีโปรเจ็กต์และเปลี่ยนเป็นไดเรกทอรีนั้นกัน

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

4. สร้างคลัสเตอร์ Kubernetes "หลัก"

คุณสร้างคลัสเตอร์ Kubernetes ที่มีการจัดการได้ง่ายๆ ด้วย Google Kubernetes Engine (GKE)

คำสั่งต่อไปนี้จะสร้างคลัสเตอร์ Kubernetes

  • ชื่อ "primary"
  • ในโซน us-west1-a
  • Kubernetes เวอร์ชันล่าสุดที่พร้อมใช้งาน
  • มีโหนดเริ่มต้น 4 โหนด
export cluster=primary
export zone=us-west1-a
gcloud container clusters create $cluster --zone $zone --username "admin" \
--cluster-version latest --machine-type "n1-standard-2" \
--image-type "COS" --disk-size "100" \
--scopes "https://www.googleapis.com/auth/compute",\
"https://www.googleapis.com/auth/devstorage.read_only",\
"https://www.googleapis.com/auth/logging.write",\
"https://www.googleapis.com/auth/monitoring",\
"https://www.googleapis.com/auth/servicecontrol",\
"https://www.googleapis.com/auth/service.management.readonly",\
"https://www.googleapis.com/auth/trace.append" \
--num-nodes "4" --network "default" \
--enable-cloud-logging --enable-cloud-monitoring --enable-ip-alias

(การดำเนินการนี้อาจใช้เวลาประมาณ 5 นาที คุณสามารถดูการสร้างคลัสเตอร์ได้ที่ Cloud Console)

หลังจากสร้างคลัสเตอร์ Kubernetes แล้ว gcloud จะกำหนดค่า kubectl ด้วยข้อมูลเข้าสู่ระบบที่ชี้ไปยังคลัสเตอร์

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

ตอนนี้คุณควรใช้ kubectl กับคลัสเตอร์ใหม่ได้แล้ว

เรียกใช้คําสั่งต่อไปนี้เพื่อแสดงรายการโหนด Kubernetes ของคลัสเตอร์ (ควรแสดงสถานะ "พร้อม")

kubectl get nodes

แก้ไขชื่อ Kubeconfig เพื่อให้ใช้งานได้ง่าย

เราจะสลับระหว่างบริบทต่างๆ บ่อยครั้ง ดังนั้นการมีชื่อแทนสั้นๆ สําหรับคลัสเตอร์จึงมีประโยชน์

คำสั่งนี้จะเปลี่ยนชื่อรายการ kubeconfig ที่คุณเพิ่งสร้างขึ้นเป็น primary

kubectx ${cluster}=gke_${GCLOUD_PROJECT}_${zone}_${cluster}

ตั้งค่าสิทธิ์

คุณต้องเป็นผู้ดูแลระบบคลัสเตอร์จึงจะติดตั้งใช้งาน Istio ได้ คำสั่งนี้จะตั้งค่าอีเมลที่เชื่อมโยงกับบัญชี Google Cloud ของคุณเป็นผู้ดูแลระบบคลัสเตอร์

kubectl create clusterrolebinding cluster-admin-binding \
    --clusterrole=cluster-admin \
    --user=$(gcloud config get-value core/account)

5. สร้างคลัสเตอร์ "การเพิ่มจำนวน"

คำสั่งต่อไปนี้จะสร้างคลัสเตอร์ Kubernetes

  • ชื่อ "burst"
  • ในโซน us-west1-a
  • Kubernetes เวอร์ชันล่าสุดที่พร้อมใช้งาน
  • มีโหนดเริ่มต้น 1 โหนด
  • เปิดใช้การปรับขนาดอัตโนมัติได้สูงสุด 5 โหนด
export cluster=burst
export zone=us-west1-a
gcloud container clusters create $cluster --zone $zone --username "admin" \
--cluster-version latest --machine-type "n1-standard-2" \
--image-type "COS" --disk-size "100" \
--scopes "https://www.googleapis.com/auth/compute",\
"https://www.googleapis.com/auth/devstorage.read_only",\
"https://www.googleapis.com/auth/logging.write",\
"https://www.googleapis.com/auth/monitoring",\
"https://www.googleapis.com/auth/servicecontrol",\
"https://www.googleapis.com/auth/service.management.readonly",\
"https://www.googleapis.com/auth/trace.append" \
--num-nodes "1" --enable-autoscaling --min-nodes=1 --max-nodes=5 \
--network "default" \
--enable-cloud-logging --enable-cloud-monitoring --enable-ip-alias

(การดำเนินการนี้อาจใช้เวลาประมาณ 5 นาที คุณสามารถดูการสร้างคลัสเตอร์ได้ที่ Cloud Console)

หลังจากสร้างคลัสเตอร์ Kubernetes แล้ว gcloud จะกำหนดค่า kubectl ด้วยข้อมูลเข้าสู่ระบบที่ชี้ไปยังคลัสเตอร์

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

ตอนนี้คุณควรใช้ kubectl กับคลัสเตอร์ใหม่ได้แล้ว

เรียกใช้คําสั่งต่อไปนี้เพื่อแสดงรายการโหนด Kubernetes ของคลัสเตอร์ (ควรแสดงสถานะ "พร้อม")

kubectl get nodes

แก้ไขชื่อ Kubeconfig เพื่อให้ใช้งานได้ง่าย

คำสั่งนี้จะแก้ไขรายการ kubeconfig ที่คุณเพิ่งสร้างขึ้นเป็น burst

kubectx ${cluster}=gke_${GCLOUD_PROJECT}_${zone}_${cluster}

ตั้งค่าสิทธิ์

คุณต้องเป็นผู้ดูแลระบบคลัสเตอร์จึงจะติดตั้งใช้งาน Istio Remote ได้ คำสั่งนี้จะตั้งค่าอีเมลที่เชื่อมโยงกับบัญชี Google Cloud ของคุณเป็นผู้ดูแลระบบคลัสเตอร์

kubectl create clusterrolebinding cluster-admin-binding \
    --clusterrole=cluster-admin \
    --user=$(gcloud config get-value core/account)

6. ใช้กฎไฟร์วอลล์

เราจะต้องสร้างกฎไฟร์วอลล์เพื่อให้คลัสเตอร์ 2 กลุ่มสื่อสารกันได้

เรียกใช้คําสั่งต่อไปนี้เพื่อสร้างกฎไฟร์วอลล์ใน Google Cloud Platform ซึ่งจะช่วยให้คลัสเตอร์ของเราสื่อสารกันได้

function join_by { local IFS="$1"; shift; echo "$*"; }
ALL_CLUSTER_CIDRS=$(gcloud container clusters list \
--filter="(name=burst OR name=primary) AND zone=$zone" \
--format='value(clusterIpv4Cidr)' | sort | uniq)
ALL_CLUSTER_CIDRS=$(join_by , $(echo "${ALL_CLUSTER_CIDRS}"))
ALL_CLUSTER_NETTAGS=$(gcloud compute instances list \
--filter="(metadata.cluster-name=burst OR metadata.cluster-name=primary) AND metadata.cluster-location=us-west1-a" \
--format='value(tags.items.[0])' | sort | uniq)
ALL_CLUSTER_NETTAGS=$(join_by , $(echo "${ALL_CLUSTER_NETTAGS}"))
gcloud compute firewall-rules create istio-multicluster-test-pods \
  --allow=tcp,udp,icmp,esp,ah,sctp \
  --direction=INGRESS \
  --priority=900 \
  --source-ranges="${ALL_CLUSTER_CIDRS}" \
  --target-tags="${ALL_CLUSTER_NETTAGS}" --quiet

เราได้ตั้งค่าคลัสเตอร์ทั้ง 2 รายการแล้วและพร้อมให้เราติดตั้งใช้งานแอปพลิเคชันและ Istio ในคลัสเตอร์

7. ข้อมูลเบื้องต้นเกี่ยวกับ Istio

Istio คืออะไร

Istio เป็นแพลตฟอร์มควบคุมของ Service Mesh ซึ่งมีวัตถุประสงค์เพื่อ "เชื่อมต่อ รักษาความปลอดภัย ควบคุม และตรวจสอบบริการ" ซึ่งทำได้หลายวิธี แต่หลักๆ คือการใส่คอนเทนเนอร์พร็อกซี ( Envoy) ไว้ในพ็อด Kubernetes ที่ติดตั้งใช้งานแต่ละรายการ คอนเทนเนอร์พร็อกซีจะควบคุมการสื่อสารทางเครือข่ายทั้งหมดระหว่างไมโครเซอร์วิสควบคู่ไปกับนโยบายวัตถุประสงค์ทั่วไปและฮับการส่งข้อมูลทางไกล ( Mixer)

a25613cd581825da.png

นโยบายเหล่านี้ใช้ได้กับการติดตั้งใช้งานและบริการ Kubernetes ของคุณโดยอิสระ ซึ่งหมายความว่าผู้ให้บริการเครือข่ายสามารถสังเกตการณ์กิจกรรมในเครือข่าย จำกัด เปลี่ยนเส้นทาง หรือเขียนนโยบายเครือข่ายใหม่ได้โดยไม่ต้องติดตั้งใช้งานแอปพลิเคชันที่เกี่ยวข้องอีกครั้ง

ฟีเจอร์การจัดการการรับส่งข้อมูลบางส่วนที่ Istio รองรับ ได้แก่

  • Circuit Breaker
  • การแยกการเข้าชมตามเปอร์เซ็นต์
  • การเขียน URL ใหม่
  • การสิ้นสุด TLS
  • การตรวจสอบประสิทธิภาพการทำงาน
  • การจัดสรรภาระงาน

วัตถุประสงค์ของเวิร์กช็อปนี้จะมุ่งเน้นที่การแยกการเข้าชมตามเปอร์เซ็นต์

ข้อกำหนดของ Istio ที่เราจะใช้

VirtualService

VirtualService จะกำหนดชุดกฎการกำหนดเส้นทางการรับส่งข้อมูลที่จะใช้เมื่อมีการระบุโฮสต์

เกตเวย์

เกตเวย์คือตัวจัดสรรภาระงานที่ทำงานที่ขอบของเมชซึ่งรับการเชื่อมต่อ HTTP/TCP ขาเข้าหรือขาออก เกตเวย์สามารถระบุพอร์ต การกําหนดค่า SNI ฯลฯ

DestinationRule

DestinationRule จะกำหนดนโยบายที่มีผลกับการเข้าชมที่มีไว้สำหรับบริการหลังจากการกำหนดเส้นทาง โดยระบุการกําหนดค่าสําหรับการจัดสรรภาระงาน ขนาดพูลการเชื่อมต่อจากไซด์คาร์ และการตั้งค่าการตรวจหา Outlier

Istio Multicluster

คุณอาจสังเกตเห็นเมื่อเราสร้างคลัสเตอร์ 2 คลัสเตอร์ว่าคลัสเตอร์ primary มี 4 โหนดโดยไม่มีการปรับขนาดอัตโนมัติ และคลัสเตอร์ burst มี 1 โหนดที่มีการปรับขนาดอัตโนมัติสูงสุด 5 โหนด

การกำหนดค่านี้มี 2 เหตุผล

ก่อนอื่น เราต้องการจำลองสถานการณ์ "ในองค์กร" ไปยังระบบคลาวด์ ในสภาพแวดล้อมในองค์กร คุณจะไม่มีสิทธิ์เข้าถึงคลัสเตอร์การปรับขนาดอัตโนมัติเนื่องจากมีโครงสร้างพื้นฐานแบบคงที่

ข้อที่ 2 คือการตั้งค่าโหนด 4 ตัว (ตามที่ระบุไว้ข้างต้น) เป็นข้อกำหนดขั้นต่ำในการใช้งาน Istio คำถามนี้จึงเกิดขึ้นว่า หาก Istio ต้องใช้โหนดอย่างน้อย 4 โหนด คลัสเตอร์ burst ของเราจะใช้ Istio ด้วยโหนด 1 โหนดได้อย่างไร คำตอบคือ Istio Multicluster จะติดตั้งชุดบริการ Istio ขนาดเล็กกว่ามาก และสื่อสารกับการติดตั้ง Istio ในคลัสเตอร์หลักเพื่อดึงข้อมูลกฎนโยบายและเผยแพร่ข้อมูลการวัดผล

8. ภาพรวมสถาปัตยกรรมแอปพลิเคชัน

ภาพรวมคอมโพเนนต์

เราจะติดตั้งใช้งานแอปพลิเคชัน 3 ชั้นโดยใช้ NodeJS และ Redis

Worker

แอปพลิเคชันสำหรับงานเขียนด้วย NodeJS และจะคอยรับคำขอ POST HTTP ขาเข้า ดำเนินการแฮชกับคำขอเหล่านั้น และหากมีการกําหนดตัวแปรสภาพแวดล้อมชื่อ PREFIX ระบบจะใส่ค่านั้นไว้หน้าแฮช เมื่อคำนวณแฮชแล้ว แอปพลิเคชันจะส่งผลลัพธ์ในช่อง "calculation" บนเซิร์ฟเวอร์ Redis ที่ระบุ

เราจะใช้ตัวแปรสภาพแวดล้อม PREFIX ในภายหลังเพื่อสาธิตฟังก์ชันการทำงานแบบคลัสเตอร์หลายกลุ่ม

ข้อมูลอ้างอิง: แพ็กเกจที่แอปพลิเคชันใช้

  • body-parser: อนุญาตให้เราแยกวิเคราะห์คําขอ HTTP
  • cors: อนุญาตให้ใช้กลไกการแชร์ทรัพยากรข้ามโดเมน
  • dotenv: แยกวิเคราะห์ตัวแปรสภาพแวดล้อมได้ง่าย
  • express: โฮสติ้งเว็บไซต์ที่ง่ายดาย
  • ioredis: ไลบรารีของไคลเอ็นต์เพื่อสื่อสารกับฐานข้อมูล Redis
  • morgan: มีบันทึกที่มีโครงสร้างดี

ฟรอนต์เอนด์

ฟรอนต์เอนด์ของเรายังเป็นแอปพลิเคชัน NodeJS ที่โฮสต์หน้าเว็บโดยใช้ express ด้วย โดยระบบจะใช้ความถี่ที่ผู้ใช้ป้อนและส่งคำขอไปยังแอปพลิเคชัน worker ในอัตราดังกล่าว แอปพลิเคชันนี้จะสมัครรับข้อความในช่อง Redis ชื่อ "calculation" และแสดงผลลัพธ์ในหน้าเว็บด้วย

แอปพลิเคชันใช้ทรัพยากรต่อไปนี้

  • body-parser: อนุญาตให้เราแยกวิเคราะห์คําขอ HTTP
  • dotenv: แยกวิเคราะห์ตัวแปรสภาพแวดล้อมได้ง่าย
  • express: โฮสติ้งเว็บไซต์ที่ง่ายดาย
  • ioredis: ไลบรารีของไคลเอ็นต์เพื่อสื่อสารกับฐานข้อมูล Redis
  • morgan: มีบันทึกที่มีโครงสร้างดี
  • request: อนุญาตให้ส่งคําขอ HTTP
  • socket.io: อนุญาตการสื่อสารแบบ 2 ทิศทางจากหน้าเว็บไปยังเซิร์ฟเวอร์

หน้าเว็บนี้ใช้ Bootstrap ในการจัดสไตล์ และเมื่อเรียกใช้จะมีลักษณะดังต่อไปนี้

e5e3b9cbede4cac4.png

แผนภาพสถาปัตยกรรม

7ae4bc22a58f80a6.png

ผังการนําไปใช้งาน

เราจะติดตั้งใช้งานแอปพลิเคชันเวอร์ชันสุดท้ายในคลัสเตอร์ 2 ชุดที่เราสร้างขึ้น คลัสเตอร์ primary จะมีการติดตั้งใช้งานคอมโพเนนต์ทั้งหมด (frontend, worker และ Redis) แต่คลัสเตอร์ burst จะมีการติดตั้งใช้งานเฉพาะแอปพลิเคชัน worker เท่านั้น

แผนภาพต่อไปนี้อธิบายคลัสเตอร์ 2 กลุ่ม กล่องที่ขอบเป็นสีแดงคือบริการ Kubernetes ส่วนกล่องสีน้ำเงินคือการทำให้ Kubernetes ใช้งานได้ กล่องสีเหลืองแสดงการติดตั้ง Istio

561db37c510944bd.png

โปรดสังเกตว่าคลัสเตอร์ burst ยังมีบริการสําหรับ Redis ที่ติดตั้งใช้งานอยู่ แม้ว่าจะไม่มีการติดตั้งใช้งาน Redis ในคลัสเตอร์ก็ตาม เราต้องให้บริการนี้ในคลัสเตอร์เพื่อให้ Kubernetes DNS แก้ปัญหาคำขอได้ แต่เมื่อมีการส่งคำขอจริง Istio Proxy จะเปลี่ยนเส้นทางคำขอไปยังการติดตั้งใช้งาน Redis ในคลัสเตอร์ primary อีกครั้ง

แอปพลิเคชันสุดท้ายจะมีการทําให้การนําส่งข้อมูลเพิ่มเติมทํางานในคลัสเตอร์ primary ที่มีชื่อว่า istiowatcher. ซึ่งจะช่วยให้เราเปลี่ยนเส้นทางการเข้าชมไปยัง burst โดยอัตโนมัติได้แบบไดนามิกเมื่อการเข้าชมเกินเกณฑ์ที่กำหนด

8f6183bdfc3f813c.png

9. สร้างไฟล์การทำให้ใช้งานได้ของแอปพลิเคชัน

เราต้องสร้างชุดไฟล์ Manifest ของ Kubernetes เพื่อทำให้แอปพลิเคชันใช้งานได้

เปลี่ยนเป็นไดเรกทอรีรูทของโปรเจ็กต์ แล้วสร้างโฟลเดอร์ใหม่ชื่อ kubernetes

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

เขียน frontend.yaml

ซึ่งจะสร้างทั้งการทำให้ใช้งานได้และบริการ Kubernetes เพื่อเข้าถึงรูปภาพในฟรอนต์เอนด์

แทรกข้อมูลต่อไปนี้ลงใน frontend.yaml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: frontend-deployment
  labels:
    app: frontend
spec:
  replicas: 1
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
    spec:
      containers:
      - name: frontend
        image: gcr.io/istio-burst-workshop/frontend
        ports:
        - containerPort: 8080
        readinessProbe:
            initialDelaySeconds: 10
            httpGet:
              path: "/_healthz"
              port: 8080
              httpHeaders:
              - name: "Cookie"
                value: "istio_session-id=x-readiness-probe"
        livenessProbe:
          initialDelaySeconds: 10
          httpGet:
            path: "/"
            port: 8080
            httpHeaders:
            - name: "Cookie"
              value: "istio_session-id=x-liveness-probe"
        env:
        - name: PORT
          value: "8080"
        - name: PROCESSOR_URL
          value: "http://worker-service"
        - name: REDIS_URL
          value: "redis-cache-service:6379"
---
apiVersion: v1
kind: Service
metadata:
  name: frontend-service
spec:
  type: ClusterIP
  selector:
    app: frontend
  ports:
  - name: http
    port: 80
    targetPort: 8080

สิ่งสำคัญที่ควรสังเกตใน Deployment

  • เราได้ระบุพอร์ตที่แอปพลิเคชันจะทํางานเป็น 8080
  • เราได้ตั้งค่าที่อยู่สำหรับโหนดที่ทำงานเป็น "http://worker-service" และใช้ฟีเจอร์ DNS ในตัวของ Kubernetes เพื่อแก้ไขบริการที่แสดงผล
  • เราได้ตั้งค่าที่อยู่สำหรับ REDIS_URL เป็น "redis-cache-service:6379" และใช้ฟีเจอร์ DNS ในตัวของ Kubernetes เพื่อแก้ไขที่อยู่ IP ที่แสดงผล
  • นอกจากนี้ เรายังได้ตั้งค่าการสำรวจ liveness และ readiness ในคอนเทนเนอร์เพื่อช่วยแจ้งให้ Kubernetes ทราบเมื่อคอนเทนเนอร์พร้อมใช้งาน

เขียนไฟล์ worker-service.yaml

เรากําลังเขียนคําจํากัดความบริการ Kubernetes ในไฟล์แยกต่างหากจากคําจํากัดความของการปรับใช้ เนื่องจากเราจะนําบริการนี้ไปใช้ซ้ำในคลัสเตอร์หลายแห่ง แต่จะเขียนการปรับใช้ที่แตกต่างกันสําหรับแต่ละคลัสเตอร์

แทรกข้อมูลต่อไปนี้ใน worker-service.yaml

apiVersion: v1
kind: Service
metadata:
 name: worker-service
spec:
 type: ClusterIP
 selector:
   app: worker
 ports:
 - name: http
   port: 80
   targetPort: 8081

เขียน worker-primary.yaml

การดำเนินการนี้จะเป็นการทำให้ worker ใช้งานได้ ซึ่งเราจะพุชไปยังคลัสเตอร์หลัก

แทรกข้อมูลต่อไปนี้ลงใน worker-primary.yaml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
 name: worker-deployment
 labels:
   app: worker
spec:
 replicas: 1
 selector:
   matchLabels:
     app: worker
 template:
   metadata:
     labels:
       app: worker
       cluster-type: primary-cluster
   spec:
     containers:
     - name: worker
       image: gcr.io/istio-burst-workshop/worker
       imagePullPolicy: Always
       ports:
       - containerPort: 8081
       readinessProbe:
           initialDelaySeconds: 10
           httpGet:
             path: "/_healthz"
             port: 8081
             httpHeaders:
             - name: "Cookie"
               value: "istio_session-id=x-readiness-probe"
       livenessProbe:
         initialDelaySeconds: 10
         httpGet:
           path: "/"
           port: 8081
           httpHeaders:
           - name: "Cookie"
             value: "istio_session-id=x-liveness-probe"
       env:
       - name: PORT
         value: "8081"
       - name: REDIS_URL
         value: "redis-cache-service:6379"

โปรดสังเกตว่าเราใช้รูปแบบเดียวกันในการระบุพร็อบ liveness และ readiness รวมถึงระบุตัวแปรสภาพแวดล้อม PORT และ REDIS_URL เพื่อให้แอปพลิเคชันของเราใช้

อีกสิ่งหนึ่งที่ควรทราบในการทำให้ใช้งานได้จริงครั้งนี้คือไม่มีตัวแปรสภาพแวดล้อม PREFIX ซึ่งหมายความว่าผลลัพธ์การคำนวณจะเป็นแฮชดิบ (ไม่มีคำนำหน้า)

ประเด็นสําคัญสุดท้ายของการติดตั้งใช้งานนี้คือป้ายกํากับ cluster-type: primary-cluster เราจะใช้ข้อมูลนี้ในภายหลังเมื่อทำการกำหนดเส้นทางการรับส่งข้อมูลใน Istio Multicluster

เขียน redis.yaml

การสื่อสารจากผู้ปฏิบัติงานกลับไปที่ส่วนหน้าเว็บนั้นทำผ่านช่องทาง Redis เราจึงต้องทำให้แอปพลิเคชัน Redis ใช้งานได้ในคลัสเตอร์

แทรกข้อมูลต่อไปนี้ลงใน redis.yaml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
 name: redis-cache
spec:
 template:
   metadata:
     labels:
       app: redis-cache
   spec:
     containers:
     - name: redis
       image: redis:alpine
       ports:
       - containerPort: 6379
       readinessProbe:
         periodSeconds: 5
         tcpSocket:
           port: 6379
       livenessProbe:
         periodSeconds: 5
         tcpSocket:
           port: 6379
       volumeMounts:
       - mountPath: /data
         name: redis-data
       resources:
         limits:
           memory: 256Mi
           cpu: 125m
         requests:
           cpu: 70m
           memory: 200Mi
     volumes:
     - name: redis-data
       emptyDir: {}

นี่เป็นการใช้งานแอปพลิเคชัน Redis แบบกึ่งมาตรฐาน โดยจะสร้างคอนเทนเนอร์ตามอิมเมจ redis:alpine แสดงพอร์ตที่เหมาะสม และกำหนดขีดจำกัดทรัพยากรที่เหมาะสม

เขียน redis-service.yaml

เราต้องใช้บริการ Kubernetes เพื่อสื่อสารกับแอปพลิเคชัน Redis

แทรกข้อมูลต่อไปนี้ลงใน redis-service.yaml

apiVersion: v1
kind: Service
metadata:
 name: redis-cache-service
spec:
 type: ClusterIP
 selector:
   app: redis-cache
 ports:
 - port: 6379
   targetPort: 6379

ซึ่งให้บริการชื่อ redis-cache-service เพื่อเข้าถึงการติดตั้งใช้งาน Redis

10. ติดตั้งใช้งานแอปพลิเคชัน

เมื่อพุชอิมเมจไปยัง GCR และเขียนไฟล์ Manifest ของ Kubernetes แล้ว เราจึงพร้อมที่จะทำให้แอปพลิเคชันใช้งานได้และดูว่าทำงานอย่างไร

เรียกใช้คําสั่งต่อไปนี้เพื่อทําให้แอปพลิเคชันใช้งานได้

  1. ตรวจสอบว่าเราอยู่ในคลัสเตอร์ที่ถูกต้อง
kubectx primary
  1. ทำให้แคช Redis ใช้งานได้
kubectl apply -f redis.yaml
  1. ติดตั้งใช้งานบริการ Redis
kubectl apply -f redis-service.yaml
  1. ติดตั้งใช้งานฟรอนต์เอนด์
kubectl apply -f frontend.yaml
  1. ทำให้ผู้ปฏิบัติงานใช้งานได้
kubectl apply -f worker-primary.yaml
  1. ทำให้บริการแรงงานใช้งานได้
kubectl apply -f worker-service.yaml

เราได้ทำให้แอปพลิเคชันใช้งานได้ใน GKE แล้ว ยินดีด้วย

ทดสอบ

รอให้พ็อดออนไลน์

kubectl get pods -w

เมื่อพ็อดทั้งหมด "ทํางาน" ให้กด Ctrl + C

NAME                                   READY     STATUS    RESTARTS   AGE
frontend-deployment-695d95fbf7-76sd8   1/1       Running   0          2m
redis-cache-7475999bf5-nxj8x           1/1       Running   0          2m
worker-deployment-5b9cf9956d-g975p     1/1       Running   0          2m

คุณจะเห็นว่าเราไม่ได้แสดง Frontend ผ่าน LoadBalancer เนื่องจากเราจะเข้าถึงแอปพลิเคชันผ่าน Istio ในภายหลัง เราจะใช้ kubectl port-forward. เรียกใช้คําสั่งต่อไปนี้เพื่อส่งต่อพอร์ต 8080 ในเครื่อง (หรือ Cloud Shell) ไปยังพอร์ต 8080 ที่ใช้งานการนําส่ง frontend เพื่อทดสอบว่าทุกอย่างพร้อมใช้งาน

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

หากใช้งานในเครื่อง ให้เปิดเว็บเบราว์เซอร์และไปที่ http://localhost:8080

หากเรียกใช้ใน Cloud Shell: ให้คลิกปุ่ม "ตัวอย่างเว็บ" แล้วเลือก "แสดงตัวอย่างบนพอร์ต 8080"

bdb5dc75f415be11.png

คุณควรเห็นหน้าเว็บ และหากคุณป้อนตัวเลขในช่อง "ความถี่" คุณควรเห็นแฮชเริ่มปรากฏขึ้น

1caafaffab26897a.png

ยินดีด้วย ทุกอย่างพร้อมใช้งานแล้ว

กด Ctrl+C เพื่อหยุดการส่งต่อพอร์ต

11. ล้างข้อมูลแอปพลิเคชันที่ติดตั้งใช้งาน

เราจะใช้ Istio ในคลัสเตอร์ จากนั้นจึงทำให้แอปพลิเคชันใช้งานได้อีกครั้ง ดังนั้นมาล้างข้อมูลแอปพลิเคชันปัจจุบันกันก่อน

เรียกใช้คําสั่งต่อไปนี้เพื่อลบการทําให้ใช้งานได้และบริการทั้งหมดที่คุณเพิ่งสร้างขึ้น

  1. ลบ redis-cache-service
kubectl delete -f redis-service.yaml
  1. ลบ redis
kubectl delete -f redis.yaml
  1. ลบ frontend
kubectl delete -f frontend.yaml
  1. ลบ worker
kubectl delete -f worker-primary.yaml
  1. ลบ worker-service
kubectl delete -f worker-service.yaml

12. ติดตั้ง Istio ในคลัสเตอร์หลัก

รับ Istio

เรามีรุ่นของ Istio ฝากไว้บน GitHub คำสั่งต่อไปนี้จะดาวน์โหลด istio เวอร์ชัน 1.0.0 และแตกไฟล์

  1. เปลี่ยนเป็นรูทของโปรเจ็กต์
cd ${proj}
  1. ดาวน์โหลดไฟล์เก็บถาวร
curl -LO https://github.com/istio/istio/releases/download/1.0.0/istio-1.0.0-linux.tar.gz
  1. แตกไฟล์และนำไฟล์ที่เก็บออก
tar xzf istio-1.0.0-linux.tar.gz && rm istio-1.0.0-linux.tar.gz

สร้างเทมเพลต Istio

การใช้คำสั่ง Helm ต่อไปนี้จะสร้างเทมเพลตเพื่อติดตั้ง Istio ในคลัสเตอร์

helm template istio-1.0.0/install/kubernetes/helm/istio \
--name istio --namespace istio-system \
--set prometheus.enabled=true \
--set servicegraph.enabled=true  > istio-primary.yaml

ซึ่งจะสร้างไฟล์ชื่อ istio-primary.yaml ในไดเรกทอรีปัจจุบันของคุณที่มีคำจำกัดความและข้อกำหนดทั้งหมดที่จำเป็นในการติดตั้งใช้งานและเรียกใช้ Istio

สังเกตพารามิเตอร์ --set 2 รายการ ซึ่งจะเพิ่มการรองรับ Prometheus และ ServiceGraph ลงในระบบ Istio เราจะใช้บริการ Prometheus ในภายหลังในห้องทดลอง

ทำให้ Istio ใช้งานได้

หากต้องการทําให้การนํา Istio ไปใช้ เราต้องสร้างเนมสเปซชื่อ istio-system ก่อนเพื่อให้การนํา Istio ไปใช้และบริการทํางานได้

kubectl create namespace istio-system

และสุดท้าย ให้ใช้ไฟล์ istio-primary.yaml ที่เราสร้างด้วย Helm

kubectl apply -f istio-primary.yaml

เนมสเปซเริ่มต้นของป้ายกำกับ

Istio ทํางานโดยการแทรกบริการพร็อกซีไฟล์ช่วยเหลือลงในแต่ละการนําไปใช้งาน การดำเนินการนี้เป็นแบบเลือกใช้ เราจึงต้องติดป้ายกำกับเนมสเปซ default ด้วย istio-injection=enabled เพื่อให้ Istio แทรก Sidecar ให้เราโดยอัตโนมัติ

kubectl label namespace default istio-injection=enabled

ยินดีด้วย เรามีคลัสเตอร์ที่พร้อมใช้งานด้วย Istio แล้วเพื่อให้เราติดตั้งใช้งานแอปพลิเคชันได้

13. ติดตั้งใช้งานแอปพลิเคชันด้วยการจัดการการรับส่งข้อมูล Istio

สร้างไฟล์การกําหนดค่าการจัดการการเข้าชม Istio

Istio ทำงานคล้ายกับ Kubernetes เนื่องจากใช้ไฟล์ YAML ในการกําหนดค่า ด้วยเหตุนี้ เราจึงต้องสร้างชุดไฟล์เพื่อบอก Istio ว่าจะแสดงและกำหนดเส้นทางการรับส่งข้อมูลอย่างไร

สร้างไดเรกทอรีชื่อ istio-manifests แล้วเปลี่ยนเป็นไดเรกทอรีนั้น

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

เขียน frontend-gateway.yaml

ไฟล์นี้จะแสดงคลัสเตอร์ Kubernetes ในลักษณะที่คล้ายกับ GKE LoadBalancer และจะกำหนดเส้นทางการรับส่งข้อมูลขาเข้าทั้งหมดไปยังบริการส่วนหน้า

สร้างไฟล์ชื่อ frontend-gateway.yaml แล้วแทรกข้อมูลต่อไปนี้

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
 name: frontend-gateway
spec:
 selector:
   istio: ingressgateway # use Istio default gateway implementation
 servers:
 - port:
     number: 80
     name: http
     protocol: HTTP
   hosts:
   - "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: frontend-ingress-virtual-service
spec:
 hosts:
 - "*"
 gateways:
 - frontend-gateway
 http:
 - route:
   - destination:
       host: frontend-service
       port:
         number: 80

เขียน redis-virtualservice.yaml

สร้างไฟล์ชื่อ redis-virtualservice.yaml แล้วแทรกข้อมูลต่อไปนี้

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: redis-virtual-service
spec:
 hosts:
 - redis-cache-service
 gateways:
 - mesh
 tcp:
 - route:
   - destination:
       host: redis-cache-service.default.svc.cluster.local

เขียนไฟล์ worker-virtualservice.yaml

สร้างไฟล์ชื่อ worker-virtualservice.yaml แล้วแทรกข้อมูลต่อไปนี้

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: worker-virtual-service
spec:
 hosts:
 - worker-service
 gateways:
 - mesh
 http:
 - route:
   - destination:
       host: worker-service.default.svc.cluster.local   
       port:
         number: 80

ทำให้นโยบายการจัดการการเข้าชมของ Istio ใช้งานได้

การติดตั้งใช้งานนโยบาย Istio ทำได้ในลักษณะเดียวกับทรัพยากร Kubernetes อื่นๆ ด้วย kubectl apply

  1. ใช้เกตเวย์ของเรา
kubectl apply -f frontend-gateway.yaml
  1. ใช้ VirtualService ของ Redis
kubectl apply -f redis-virtualservice.yaml
  1. ใช้ VirtualService ของ Worker
kubectl apply -f worker-virtualservice.yaml

ทำให้แอปพลิเคชันใช้งานได้

  1. เปลี่ยนกลับไปใช้ไดเรกทอรี kubernetes
cd ${proj}/kubernetes
  1. ทำให้แคช Redis ใช้งานได้
kubectl apply -f redis.yaml
  1. ติดตั้งใช้งานบริการ Redis
kubectl apply -f redis-service.yaml
  1. ติดตั้งใช้งานฟรอนต์เอนด์
kubectl apply -f frontend.yaml
  1. ทำให้ผู้ปฏิบัติงานใช้งานได้
kubectl apply -f worker-primary.yaml
  1. ทำให้บริการแรงงานใช้งานได้
kubectl apply -f worker-service.yaml

ยืนยัน

ในตอนนี้ เราได้ทำให้แอปพลิเคชันใช้งานได้อีกครั้งในคลัสเตอร์ที่มี Istio และนโยบายการจัดการการเข้าชม

โปรดรอให้ภาระงานทั้งหมดออนไลน์

เมื่อออนไลน์ทั้งหมดแล้ว ให้รับ IngressGateway ที่เรากําหนดค่าไว้ใน frontend-ingressgateway.yaml

$ kubectl -n istio-system get svc istio-ingressgateway
NAME                   TYPE           CLUSTER-IP    EXTERNAL-IP     PORT(S)                                                                                                     AGE
istio-ingressgateway   LoadBalancer   10.36.3.112   35.199.158.10   80:31380/TCP,

เรียกดูที่อยู่ <EXTERNAL-IP> หรือใช้ Curl แล้วคุณจะเห็นฟรอนต์เอนด์

$ curl 35.199.158.10
<!doctype html>
<html>

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

14. ติดตั้ง Istio ในคลัสเตอร์ "Burst"

เราใช้เวลาตั้งค่าและทำให้ใช้งานได้ในคลัสเตอร์ primary นานมากแล้ว แต่ยังมีคลัสเตอร์อีกคลัสเตอร์ที่ต้องทำให้ใช้งานได้

ในส่วนนี้ เราจะต้องดึงตัวแปรการกําหนดค่าในคลัสเตอร์ทั้ง 2 รายการ ดังนั้นโปรดดูให้แน่ใจว่าเรากําลังชี้ไปที่คลัสเตอร์ใดสําหรับคําสั่งแต่ละรายการ

สร้างไฟล์ Manifest ระยะไกลของ Istio

เราจะใช้ Helm เพื่อสร้างเทมเพลตสำหรับทำให้ Istio ระยะไกลใช้งานได้ในคลัสเตอร์ burst เช่นเดียวกับเมื่อเราทำให้ Istio ใช้งานได้ในคลัสเตอร์ primary อย่างไรก็ตาม เราต้องขอข้อมูลบางอย่างเกี่ยวกับคลัสเตอร์ primary ก่อน

รวบรวมข้อมูลคลัสเตอร์หลัก

เปลี่ยนเป็นคลัสเตอร์ primary

kubectx primary

คำสั่งต่อไปนี้จะดึงข้อมูลที่อยู่ IP ของพ็อดต่างๆ ในคลัสเตอร์หลัก โดย Istio Remote จะใช้เพื่อสื่อสารกลับไปยังคลัสเตอร์หลัก

export PILOT_POD_IP=$(kubectl -n istio-system get pod -l istio=pilot -o jsonpath='{.items[0].status.podIP}')
export POLICY_POD_IP=$(kubectl -n istio-system get pod -l istio-mixer-type=policy -o jsonpath='{.items[0].status.podIP}')
export STATSD_POD_IP=$(kubectl -n istio-system get pod -l istio=statsd-prom-bridge -o jsonpath='{.items[0].status.podIP}')
export TELEMETRY_POD_IP=$(kubectl -n istio-system get pod -l istio-mixer-type=telemetry -o jsonpath='{.items[0].status.podIP}')
export ZIPKIN_POD_IP=$(kubectl -n istio-system get pod -l app=jaeger -o jsonpath='{range .items[*]}{.status.podIP}{end}')

สร้างเทมเพลตระยะไกล

ตอนนี้เราจะใช้ helm เพื่อสร้างไฟล์ชื่อ istio-remote-burst.yaml ซึ่งจะนำไปติดตั้งใช้งานในคลัสเตอร์ burst ได้

เปลี่ยนเป็นรูทโปรเจ็กต์

cd $proj
helm template istio-1.0.0/install/kubernetes/helm/istio-remote --namespace istio-system \
--name istio-remote \
--set global.remotePilotAddress=${PILOT_POD_IP} \
--set global.remotePolicyAddress=${POLICY_POD_IP} \
--set global.remoteTelemetryAddress=${TELEMETRY_POD_IP} \
--set global.proxy.envoyStatsd.enabled=true \
--set global.proxy.envoyStatsd.host=${STATSD_POD_IP} \
--set global.remoteZipkinAddress=${ZIPKIN_POD_IP} > istio-remote-burst.yaml

ติดตั้ง Istio Remote ในคลัสเตอร์แบบ Burst

หากต้องการติดตั้ง Istio ในคลัสเตอร์ burst เราต้องทําตามขั้นตอนเดียวกับการติดตั้งในคลัสเตอร์ primary แต่ต้องใช้ไฟล์ istio-remote-burst.yaml แทน

เปลี่ยน kubecontext เป็น burst

kubectx burst

สร้างเนมสเปซ istio-system

kubectl create ns istio-system

ใช้ istio-burst.yaml

kubectl apply -f istio-remote-burst.yaml

เนมสเปซเริ่มต้นของป้ายกำกับ

อีกครั้ง เราต้องติดป้ายกำกับเนมสเปซ default เพื่อให้ระบบแทรกพร็อกซีโดยอัตโนมัติ

kubectl label namespace default istio-injection=enabled

ยินดีด้วย ตอนนี้เราได้ตั้งค่า Istio Remote ในคลัสเตอร์ burst แล้ว อย่างไรก็ตาม คลัสเตอร์ยังคงสื่อสารกันไม่ได้ในตอนนี้ เราต้องสร้างไฟล์ kubeconfig สําหรับคลัสเตอร์ burst ที่เราสามารถติดตั้งใช้งานในคลัสเตอร์ primary เพื่อลิงก์เข้าด้วยกัน

สร้าง kubeconfig สําหรับคลัสเตอร์ "burst"

เปลี่ยนเป็นคลัสเตอร์การระเบิด

kubectx burst

ตั้งค่าสภาพแวดล้อม

เราจําเป็นต้องรวบรวมข้อมูลบางอย่างเกี่ยวกับคลัสเตอร์เพื่อสร้างไฟล์ kubeconfig

  1. รับชื่อคลัสเตอร์
CLUSTER_NAME=$(kubectl config view --minify=true -o "jsonpath={.clusters[].name}")
  1. รับชื่อเซิร์ฟเวอร์คลัสเตอร์
SERVER=$(kubectl config view --minify=true -o "jsonpath={.clusters[].cluster.server}")
  1. รับชื่อของข้อมูลลับสําหรับหน่วยงานที่รับรองของบัญชีบริการ istio-multi
SECRET_NAME=$(kubectl get sa istio-multi -n istio-system -o jsonpath='{.secrets[].name}')
  1. รับข้อมูลผู้ออกใบรับรองที่จัดเก็บไว้ในข้อมูลลับก่อนหน้า
CA_DATA=$(kubectl get secret ${SECRET_NAME} -n istio-system -o "jsonpath={.data['ca\.crt']}")
  1. รับโทเค็นที่เก็บไว้ในข้อมูลลับก่อนหน้า
TOKEN=$(kubectl get secret ${SECRET_NAME} -n istio-system -o "jsonpath={.data['token']}" | base64 --decode)

สร้างไฟล์ kubeconfig

เมื่อตั้งค่าตัวแปรสภาพแวดล้อมทั้งหมดแล้ว เราจะต้องสร้างไฟล์ kubeconfig

cat <<EOF > burst-kubeconfig
apiVersion: v1
clusters:
   - cluster:
       certificate-authority-data: ${CA_DATA}
       server: ${SERVER}
     name: ${CLUSTER_NAME}
contexts:
   - context:
       cluster: ${CLUSTER_NAME}
       user: ${CLUSTER_NAME}
     name: ${CLUSTER_NAME}
current-context: ${CLUSTER_NAME}
kind: Config
preferences: {}
users:
   - name: ${CLUSTER_NAME}
     user:
       token: ${TOKEN}
EOF

ซึ่งจะสร้างไฟล์ใหม่ชื่อ burst-kubeconfig ในไดเรกทอรีปัจจุบัน ซึ่งคลัสเตอร์ primary สามารถใช้เพื่อตรวจสอบสิทธิ์และจัดการคลัสเตอร์ burst

เปลี่ยนกลับไปใช้คลัสเตอร์หลัก

kubectx primary

ใช้ kubeconfig สำหรับ "burst" โดยสร้างข้อมูลลับและติดป้ายกำกับ

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

ติดป้ายกำกับข้อมูลลับเพื่อให้ Istio ทราบว่าจะใช้ข้อมูลลับดังกล่าวเพื่อการตรวจสอบสิทธิ์หลายคลัสเตอร์

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

ยินดีด้วย เราได้ตรวจสอบสิทธิ์คลัสเตอร์ทั้ง 2 รายการและสื่อสารกันผ่าน Istio Multicluster แล้ว มาทำให้แอปพลิเคชันใช้งานได้ในหลายคลัสเตอร์กัน

15. ทำให้แอปพลิเคชันข้ามคลัสเตอร์ใช้งานได้

สร้างการติดตั้งใช้งาน

เปลี่ยนเป็นไดเรกทอรี kubernetes

cd ${proj}/kubernetes

สร้างการทํางานของผู้ปฏิบัติงานสําหรับคลัสเตอร์ "burst": worker-burst.yaml

สร้างไฟล์ชื่อ worker-burst.yaml แล้วแทรกข้อมูลต่อไปนี้ลงในไฟล์

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: worker-deployment
  labels:
    app: worker
spec:
  replicas: 1
  selector:
    matchLabels:
      app: worker
  template:
    metadata:
      labels:
        app: worker
        cluster-type: burst-cluster
    spec:
      containers:
      - name: worker
        image: gcr.io/istio-burst-workshop/worker
        imagePullPolicy: Always
        ports:
        - containerPort: 8081
        readinessProbe:
            initialDelaySeconds: 10
            httpGet:
              path: "/_healthz"
              port: 8081
              httpHeaders:
              - name: "Cookie"
                value: "istio_session-id=x-readiness-probe"
        livenessProbe:
          initialDelaySeconds: 10
          httpGet:
            path: "/"
            port: 8081
            httpHeaders:
            - name: "Cookie"
              value: "istio_session-id=x-liveness-probe"
        env:
        - name: PORT
          value: "8081"
        - name: REDIS_URL
          value: "redis-cache-service:6379"
        - name: PREFIX
          value: "bursty-"

โปรดสังเกตว่าไฟล์นี้เกือบเหมือนกับ worker-primary.yaml ที่เราสร้างขึ้นก่อนหน้านี้ ความแตกต่างที่สำคัญมี 2 ประการ

ความแตกต่างที่สําคัญประการแรกคือเราได้เพิ่มตัวแปรสภาพแวดล้อม PREFIX ที่มีค่า "bursty-"

env:
- name: PORT
  value: "8081"
- name: REDIS_URL
  value: "redis-cache-service:6379"
- name: PREFIX
  value: "bursty-"

ซึ่งหมายความว่าเวิร์กเกอร์ในคลัสเตอร์ burst จะใส่ "bursty-" ต่อหน้าแฮชทั้งหมดที่ส่ง เราสามารถใช้ข้อมูลนี้เพื่อระบุว่าแอปพลิเคชันของเราเป็นแบบข้ามคลัสเตอร์อย่างแท้จริง

ความแตกต่างที่สําคัญประการที่ 2 คือเราได้เปลี่ยนป้ายกํากับ cluster-type ในการติดตั้งใช้งานนี้จาก primary-cluster เป็น burst-cluster

labels:
  app: worker
  cluster-type: burst-cluster

เราจะใช้ป้ายกำกับนี้ในภายหลังเมื่ออัปเดต VirtualService

แก้ไขบริการ Istio

ขณะนี้บริการ Istio ไม่ได้ใช้ประโยชน์จากทั้ง 2 การติดตั้งใช้งาน การเข้าชม 100% ของเราได้รับการกําหนดเส้นทางไปยังคลัสเตอร์ "หลัก" มาเปลี่ยนเรื่องนี้กัน

การเปลี่ยนแปลงในไดเรกทอรี istio-manifests

cd ${proj}/istio-manifests

แก้ไข worker-virtualservice.yaml ให้รวม DestinationRules

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: worker-virtual-service
spec:
  hosts:
  - worker-service
  gateways:
  - mesh
  http:
  - route:
    - destination:
        host: worker-service.default.svc.cluster.local    
        subset: primary
        port:
          number: 80        
      weight: 50
    - destination:
        host: worker-service.default.svc.cluster.local     
        subset: burst  
        port:
          number: 80        
      weight: 50
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: worker-destination-rule
spec:
  host: worker-service
  trafficPolicy:
    loadBalancer:
      simple: RANDOM
  subsets:
  - name: primary
    labels:
      cluster-type: primary-cluster
  - name: burst
    labels:
     cluster-type: burst-cluster

คุณจะเห็นว่าเราได้เพิ่มปลายทางที่ 2 ไปยัง VirtualService แล้ว ยังคงอ้างอิงโฮสต์เดียวกัน (worker-service.default.svc.cluster.local) แต่มีการกําหนดเส้นทางการเข้าชม 50% ไปยังชุดย่อย primary และอีก 50% ไปยังชุดย่อย burst

เราได้กําหนดชุดย่อย primary เป็นการนําไปใช้ที่มีป้ายกํากับ cluster-type: primary-cluster และชุดย่อย burst เป็นการนําไปใช้ที่มีป้ายกํากับ cluster-type: burst-cluster

ซึ่งจะแบ่งการเข้าชมระหว่างคลัสเตอร์ 2 กลุ่มนี้อย่างมีประสิทธิภาพ 50/50

ทำให้ใช้งานได้ในคลัสเตอร์

ติดตั้งใช้งาน redis-service.yaml เพื่อเพิ่มจำนวนคลัสเตอร์

เปลี่ยนเป็น burst kubeconfig

kubectx burst

การเปลี่ยนแปลงรูทโปรเจ็กต์

cd ${proj}

จากนั้นทําให้ใช้งานได้

ทำให้ redis-service.yaml ใช้งานได้ในคลัสเตอร์แบบ Burst

kubectl apply -f kubernetes/redis-service.yaml

ทำให้ worker-burst.yaml ใช้งานได้ในคลัสเตอร์ Burst

kubectl apply -f kubernetes/worker-burst.yaml

ทำให้ worker-service.yaml ใช้งานได้ในคลัสเตอร์แบบ Burst

kubectl apply -f kubernetes/worker-service.yaml

ใช้ VirtualServices ของ Istio

เปลี่ยนเป็น primary kubeconfig

kubectx primary

จากนั้นทําให้ใช้งานได้

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

ตรวจสอบว่าใช้งานได้

หากต้องการตรวจสอบว่าทํางาน ให้ไปที่จุดเข้าใช้งาน Istio และสังเกตว่าแฮชประมาณ 50% มี "burst-" เป็นคำนำหน้า

78fb6e235e9f4a07.png

ซึ่งหมายความว่าเราคุยกันข้ามคลัสเตอร์ได้สําเร็จ ลองเปลี่ยนน้ำหนักของบริการต่างๆ และใช้ไฟล์ worker-virtualservice.yaml วิธีนี้เป็นวิธีที่ยอดเยี่ยมในการปรับสมดุลการรับส่งข้อมูลระหว่างคลัสเตอร์ แต่จะเกิดอะไรขึ้นหากเราทําได้โดยอัตโนมัติ

16. ใช้ประโยชน์จากเมตริก Prometheus

ข้อมูลเบื้องต้นเกี่ยวกับ Prometheus

Prometheus เป็นเครื่องมือตรวจสอบและแจ้งเตือนระบบแบบโอเพนซอร์สที่สร้างขึ้นที่ SoundCloud เดิม โดยจะดูแลรักษาโมเดลข้อมูลมัลติไดเมนชันที่มีข้อมูลอนุกรมเวลาซึ่งระบุด้วยชื่อเมตริกและคู่คีย์/ค่า

แผนภาพสถาปัตยกรรม Prometheus มีไว้สำหรับใช้อ้างอิง

601e1155a825e0c2.png

เมื่อติดตั้งใช้งานกับ Prometheus แล้ว Istio จะรายงานเมตริกต่างๆ ไปยังเซิร์ฟเวอร์ Prometheus โดยอัตโนมัติ เราสามารถใช้เมตริกเหล่านี้เพื่อจัดการคลัสเตอร์ได้ทันที

การสํารวจเมตริก Prometheus

ในการเริ่มต้นใช้งาน เราจะต้องแสดงข้อมูลการทําให้ใช้งานได้ของ Prometheus

ไปที่แท็บ "ภาระงาน" ใน GKE แล้วเจาะลึกไปยังภาระงาน "prometheus"

b4a7a3cd67db05b3.png

เมื่อดูรายละเอียดของการติดตั้งใช้งานแล้ว ให้ไปที่การดําเนินการ -> แสดง

c04a482e55bdfd41.png

เลือกส่งต่อไปยังพอร์ต 9090 แล้วพิมพ์ "ตัวจัดโหลด"

d5af3ba22a7a6ebb.png

แล้วเลือก "แสดง"

ซึ่งจะสร้างบริการในที่อยู่ IP ที่เข้าถึงได้แบบสาธารณะที่เราสามารถใช้เพื่อสำรวจเมตริก Prometheus

รอให้อุปกรณ์ปลายทางทํางานได้ เมื่อทํางานได้แล้ว ให้คลิกที่อยู่ IP ข้าง "อุปกรณ์ปลายทางภายนอก" b1e40ad90851da29.png

ตอนนี้คุณควรเห็น UI ของ Prometheus

ed273552270337ec.png

Prometheus มีเมตริกเพียงพอที่จะใช้เป็นเวิร์กช็อปของตัวเอง แต่ตอนนี้เราจะเริ่มต้นด้วยการศึกษาเมตริก istio_requests_total

การดำเนินการค้นหาดังกล่าวจะแสดงผลข้อมูลจำนวนมาก ซึ่งเป็นเมตริกเกี่ยวกับคําขอทั้งหมดที่ส่งผ่าน Service Mesh ของ Istio ซึ่งก็มีจํานวนมาก เราจะเปลี่ยนการแสดงออกเพื่อกรองสิ่งที่เราสนใจจริงๆ ดังนี้

คำขอที่บริการปลายทางคือ worker-service.default.svc.cluster.local และแหล่งที่มาคือ frontend-deployment ซึ่งจำกัดไว้ที่ 15 วินาทีที่ผ่านมา

คําค้นหาดังกล่าวมีลักษณะดังนี้

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

และช่วยให้เราจัดการชุดข้อมูลได้ง่ายขึ้นมาก

19d551fd5eac3785.png

แต่ยังคงมีความหนาแน่นอยู่บ้าง เราต้องการทราบคําขอต่อวินาที ไม่ใช่คําขอทั้งหมด

หากต้องการดูข้อมูลดังกล่าว เราสามารถใช้ฟังก์ชัน rate ในตัว

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

dbb9dc063a18da9b.png

ข้อมูลนี้ทำให้เราเข้าใกล้คำตอบมากขึ้น แต่เราต้องลดเมตริกเหล่านั้นลงอีกเล็กน้อยให้เป็นกลุ่มที่สมเหตุสมผล

ซึ่งทำได้โดยใช้คีย์เวิร์ด sum และ by เพื่อจัดกลุ่มและรวมผลลัพธ์

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

898519966930ec56.png

งั้นก็แจ๋วเลย เราดึงเมตริกที่แน่นอนที่ต้องการจาก Prometheus ได้

การค้นหา Prometheus สุดท้ายของเรา

จากข้อมูลทั้งหมดที่เราได้เรียนรู้ คําค้นหาสุดท้ายที่เราต้องถาม Prometheus คือ

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

ตอนนี้เราใช้ HTTP API ของ Google เพื่อรับเมตริกได้แล้ว

เราค้นหา API โดยใช้การค้นหาของเราได้โดยส่งคําขอ HTTP GET ดังนี้ แทนที่ <prometheus-ip-here>

curl http://<prometheus-ip-here>/api/v1/query?query=sum\(rate\(istio_requests_total%7Breporter%3D%22destination%22%2C%0Adestination_service%3D%22worker-service.default.svc.cluster.local%22%2C%0Asource_workload%3D%22frontend-deployment%22%7D%5B15s%5D\)\)%20by%20\(source_workload%2C%0Asource_app%2C%20destination_service\)

ตัวอย่างการตอบกลับมีดังนี้

{
    "status": "success",
    "data": {
        "resultType": "vector",
        "result": [
            {
                "metric": {
                    "destination_service": "worker-service.default.svc.cluster.local",
                    "source_app": "frontend",
                    "source_workload": "frontend-deployment"
                },
                "value": [
                    1544404907.503,
                    "18.892886390062788"
                ]
            }
        ]
    }
}

ตอนนี้เราสามารถดึงค่าเมตริกจาก JSON ได้แล้ว

ล้างข้อมูล

เราต้องลบบริการที่เราเพิ่งใช้เพื่อแสดง Prometheus ในคอนโซล Google Cloud ให้ไปที่ด้านบนของบริการที่เราเพิ่งสร้างขึ้น แล้วคลิก "ลบ"

d58cb51b4c922751.png

ขั้นตอนถัดไป:

เมื่อค้นพบวิธีตรวจหาว่ามีการย้ายข้อมูลผ่านคลัสเตอร์อย่างไรและที่อัตราใด ขั้นตอนถัดไปคือการเขียนไบนารีขนาดเล็กที่จะค้นหา prometheus เป็นระยะๆ และหากคำขอต่อวินาทีไปยัง worker สูงกว่าเกณฑ์ที่กำหนด ให้ใช้น้ำหนักปลายทางที่แตกต่างกันในบริการเสมือนของเวิร์กเกอร์เพื่อส่งข้อมูลทั้งหมดไปยังคลัสเตอร์ burst เมื่อคำขอต่อวินาทีลดลงต่ำกว่าเกณฑ์ที่ต่ำลง ให้ส่งการเข้าชมทั้งหมดกลับไปยัง primary

17. สร้างการระเบิดข้ามคลัสเตอร์

ตั้งค่า

กำหนดการรับส่งข้อมูลทั้งหมดสำหรับบริการสำหรับงานไปยังคลัสเตอร์หลัก

เราจะถือว่าการรับส่งข้อมูลทั้งหมดที่มีปลายทางเป็น worker-service ซึ่งกำหนดเส้นทางไปยังคลัสเตอร์ primary เป็นสถานะ "เริ่มต้น" ของแอปพลิเคชัน

แก้ไข $proj/istio-manifests/worker-virtualservice.yaml ให้มีลักษณะดังต่อไปนี้

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: worker-virtual-service
spec:
  hosts:
  - worker-service
  gateways:
  - mesh
  http:
  - route:
    - destination:
        host: worker-service.default.svc.cluster.local    
        subset: primary
        port:
          number: 80        
      weight: 100
    - destination:
        host: worker-service.default.svc.cluster.local     
        subset: burst  
        port:
          number: 80        
      weight: 0
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: worker-destination-rule
spec:
  host: worker-service
  trafficPolicy:
    loadBalancer:
      simple: RANDOM
  subsets:
  - name: primary
    labels:
      cluster-type: primary-cluster
  - name: burst
    labels:
     cluster-type: burst-cluster

ตรวจสอบว่าคุณเชื่อมต่อกับคลัสเตอร์ primary

kubectx primary

ใช้ istio-manifests/worker-virtualservice.yaml

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

เขียนเดรัมน์ istiowatcher

เราจะใช้ Go เพื่อเขียนบริการนี้เนื่องจากความรวดเร็วและความสามารถในการพกพา ขั้นตอนโดยรวมของแอปพลิเคชันจะเริ่มต้นขึ้นและค้นหา prometheus ทุกๆ วินาที

สร้างไดเรกทอรีใหม่ใน src ชื่อ istiowatcher

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

เราจะเรียกใช้ istioctl จากภายในคอนเทนเนอร์เพื่อดัดแปลง Control Plane ของ Istio จากภายในคลัสเตอร์

เขียน istiowatcher.go

สร้างไฟล์ในไดเรกทอรีนั้นชื่อ istiowatcher.go แล้วแทรกข้อมูลต่อไปนี้ลงในไฟล์

package main

import (
        "github.com/tidwall/gjson"
        "io/ioutil"
        "log"
        "net/http"
        "os/exec"
        "time"
)

func main() {
        //These are in requests per second
        var targetLow float64 = 10
        var targetHigh float64 = 15
        // This is for the ticker in milliseconds
        ticker := time.NewTicker(1000 * time.Millisecond)

        isBurst := false

        // Our prometheus query
        reqQuery := `/api/v1/query?query=sum(rate(istio_requests_total{reporter="destination",destination_service="worker-service.default.svc.cluster.local",source_workload="frontend-deployment"}[15s]))by(source_workload,source_app,destination_service)`

        for t := range ticker.C {
                log.Printf("Checking Prometheus at %v", t)

                // Check prometheus
                // Note that b/c we are querying over the past 5 minutes, we are getting a very SLOW ramp of our reqs/second
                // If we wanted this to be a little "snappier" we can scale it down to say 30s
                resp, err := http.Get("http://prometheus.istio-system.svc.cluster.local:9090" + reqQuery)
                if err != nil {
                        log.Printf("Error: %v", err)
                        continue
                }
                defer resp.Body.Close()
                body, _ := ioutil.ReadAll(resp.Body)

                val := gjson.Get(string(body), "data.result.0.value.1")
                log.Printf("Value: %v", val)

                currentReqPerSecond := val.Float()
                log.Printf("Reqs per second %f", currentReqPerSecond)

                if currentReqPerSecond > targetHigh && !isBurst {
                        applyIstio("burst.yaml")
                        log.Println("Entering burst mode")
                        isBurst = true
                } else if currentReqPerSecond < targetLow && isBurst {
                        applyIstio("natural.yaml")
                        log.Println("Returning to natural state.")
                        isBurst = false
                }
        }
}

func applyIstio(filename string) {
        cmd := exec.Command("istioctl", "replace", "-f", filename)
        if err := cmd.Run(); err != nil {
                log.Printf("Error hit applying istio manifests: %v", err)
        }
}

เขียน Dockerfile

สร้างไฟล์ใหม่ชื่อ Dockerfile แล้วแทรกข้อมูลต่อไปนี้ลงในไฟล์

FROM golang:1.11.2-stretch as base

FROM base as builder

WORKDIR /workdir
RUN curl -LO https://github.com/istio/istio/releases/download/1.0.0/istio-1.0.0-linux.tar.gz
RUN tar xzf istio-1.0.0-linux.tar.gz
RUN cp istio-1.0.0/bin/istioctl ./istioctl

FROM base 

WORKDIR /go/src/istiowatcher
COPY . .
COPY --from=builder /workdir/istioctl /usr/local/bin/istioctl

RUN go get -d -v ./...
RUN go install -v ./...

CMD ["istiowatcher"]

Dockerfile แบบหลายระยะนี้จะดาวน์โหลดและแตกไฟล์ Istio เวอร์ชัน 1.0.0 ในระยะแรก ระยะที่ 2 จะคัดลอกทุกอย่างจากไดเรกทอรีของเราลงในอิมเมจ จากนั้นคัดลอก istioctl จากระยะการสร้างไปยัง /usr/local/bin (เพื่อให้แอปพลิเคชันเรียกใช้ได้) รับข้อมูลที่ต้องพึ่งพา คอมไพล์โค้ด และตั้งค่า CMD เป็น "istiowatcher"

เขียน burst.yaml

ไฟล์นี้คือไฟล์ที่ istiowatcher จะใช้เมื่อคำขอ/วินาทีไปยัง worker จาก frontend มากกว่า 15

สร้างไฟล์ใหม่ชื่อ burst.yaml แล้วแทรกข้อมูลต่อไปนี้ลงในไฟล์

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: worker-virtual-service
spec:
 hosts:
 - worker-service
 gateways:
 - mesh
 http:
 - route:
   - destination:
       host: worker-service.default.svc.cluster.local   
       subset: primary
       port:
         number: 80       
     weight: 0
   - destination:
       host: worker-service.default.svc.cluster.local    
       subset: burst 
       port:
         number: 80       
     weight:  100

เขียน natural.yaml

เราจะถือว่านี่คือสถานะ "ปกติ" ที่เรากลับคืนสู่เมื่อคำขอ/วินาทีจาก frontend ถึง worker ลดลงต่ำกว่า 10 ในสถานะนี้ ระบบจะกําหนดเส้นทางการเข้าชม 100% ไปยังคลัสเตอร์ primary

สร้างไฟล์ใหม่ชื่อ natural.yaml แล้วแทรกข้อมูลต่อไปนี้ลงในไฟล์

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: worker-virtual-service
spec:
 hosts:
 - worker-service
 gateways:
 - mesh
 http:
 - route:
   - destination:
       host: worker-service.default.svc.cluster.local   
       subset: primary
       port:
         number: 80       
     weight: 100
   - destination:
       host: worker-service.default.svc.cluster.local    
       subset: burst 
       port:
         number: 80       
     weight: 0

สร้างและพุช istiowatcher

เรียกใช้คำสั่งต่อไปนี้เพื่อส่งไดเรกทอรีปัจจุบันไปยัง Google Could Build (GCB) ซึ่งจะสร้างและติดแท็กรูปภาพใน GCR

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

ทำให้ istiowatcher ใช้งานได้

การเปลี่ยนแปลงในไดเรกทอรี kubernetes

cd ${proj}/kubernetes/

เขียนไฟล์การนําส่ง: istiowatcher.yaml

สร้างไฟล์ชื่อ istiowatcher.yaml แล้วแทรกข้อมูลต่อไปนี้ (แทนที่ <your-project-id>)

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: istiowatcher-deployment
  labels:
    app: istiowatcher
spec:
  replicas: 1
  selector:
    matchLabels:
      app: istiowatcher
  template:
    metadata:
      labels:
        app: istiowatcher
    spec:
      serviceAccountName: istio-pilot-service-account
      automountServiceAccountToken: true
      containers:
      - name: istiowatcher
        image: gcr.io/<your-project-id>/istiowatcher
        imagePullPolicy: Always

ทำให้ใช้งานได้

ตรวจสอบว่าเรากําลังทํางานในคลัสเตอร์หลัก

kubectx primary

ติดตั้งใช้งาน istiowatcher.yaml ในเนมสเปซ istio-system

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

สิ่งสำคัญที่ควรทราบคือคำสั่ง serviceAccountName และ automountServiceAccountToken ใน yaml ซึ่งจะช่วยให้เรามีข้อมูลเข้าสู่ระบบที่จําเป็นในการเรียกใช้ istioctl จากภายในคลัสเตอร์

นอกจากนี้ เรายังต้องติดตั้งใช้งานภายในเนมสเปซ istio-system เพื่อให้แน่ใจว่าเรามีข้อมูลเข้าสู่ระบบสำหรับ istio-pilot-service-account (ไม่มีอยู่ในเนมสเปซ default)

ดูการจราจรเปลี่ยนเส้นทางโดยอัตโนมัติ

มาดูช่วงเวลาที่น่าอัศจรรย์กัน ไปที่ส่วนหน้าเว็บและเพิ่มคำขอ/วินาทีเป็น 20

โปรดทราบว่าการดำเนินการนี้อาจใช้เวลา 2-3 วินาที แต่เราจะเพิ่มความเร็วขึ้นและแฮชทั้งหมดจะมี "bursty-" นำหน้า

เนื่องจากเรากำลังสุ่มตัวอย่าง prometheus ในช่วง 15s ซึ่งทำให้เวลาในการตอบสนองของเราล่าช้าเล็กน้อย หากต้องการแถบความถี่ที่แคบลงมาก เราอาจเปลี่ยนการค้นหาเป็น prometheus เป็น 5s.

18. ขั้นตอนถัดไปคือ

ล้างข้อมูล

คุณไม่จำเป็นต้องล้างข้อมูลหากใช้บัญชีชั่วคราวที่จัดเตรียมไว้สำหรับเวิร์กช็อปนี้

คุณลบคลัสเตอร์ Kubernetes, กฎไฟร์วอลล์ และอิมเมจใน GCR ได้

gcloud container clusters delete primary --zone=us-west1-a
gcloud container clusters delete burst --zone=us-west1-a
gcloud compute firewall-rules delete istio-multicluster-test-pods 
gcloud container images delete gcr.io/$GCLOUD_PROJECT/istiowatcher

การดำเนินการต่อจากนี้