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

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

ขอขอบคุณที่เข้าร่วม Codelab การขยายหลายระบบคลาวด์ของ Istio โดย 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 (แนะนำ): 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. สร้างคลัสเตอร์ "Burst"

คำสั่งต่อไปนี้จะสร้างคลัสเตอร์ 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 เป็นระนาบควบคุมของโครงข่ายบริการที่มีเป้าหมายเพื่อ "เชื่อมต่อ รักษาความปลอดภัย ควบคุม และสังเกตการณ์บริการ" โดยจะดำเนินการในหลายวิธี แต่หลักๆ คือการใส่คอนเทนเนอร์พร็อกซี ( Envoy) ลงในพ็อด Kubernetes ที่คุณติดตั้งใช้งานแต่ละรายการ คอนเทนเนอร์พร็อกซีจะควบคุมการสื่อสารผ่านเครือข่ายทั้งหมดระหว่างไมโครเซอร์วิสควบคู่ไปกับนโยบายและฮับการวัดและส่งข้อมูลทางไกลแบบอเนกประสงค์ ( Mixer)

a25613cd581825da.png

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

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

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

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

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

VirtualService

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

เกตเวย์

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

DestinationRule

DestinationRule จะกำหนดนโยบายที่ใช้กับการรับส่งข้อมูลที่มุ่งไปยังบริการหลังจากที่มีการกำหนดเส้นทาง โดยจะระบุการกำหนดค่าสำหรับการจัดสรรภาระงาน ขนาด Connection Pool จาก Sidecar และการตั้งค่าการตรวจหา Outlier

Istio Multicluster

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

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

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

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

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

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

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

คนงาน

แอปพลิเคชัน Worker เขียนด้วย NodeJS และจะรอรับคำขอ HTTP แบบ POST ขาเข้า ดำเนินการแฮชกับคำขอเหล่านั้น และหากมีการกำหนดตัวแปรสภาพแวดล้อมชื่อ 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

แอปพลิเคชันสุดท้ายจะมี Deployment เพิ่มเติมที่ทำงานในคลัสเตอร์ 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
  • เราได้ตั้งค่าที่อยู่สำหรับ Worker เป็น "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 Cache
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. ติดตั้งใช้งานบริการ Worker
kubectl apply -f worker-service.yaml

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

ทดสอบ

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

kubectl get pods -w

เมื่อพ็อดทั้งหมดมีสถานะเป็น "กำลังทำงาน" ให้กด Ctrl + C

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

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

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

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

หากคุณเรียกใช้ใน Cloud Shell: คลิกปุ่ม "ตัวอย่างเว็บ" แล้วเลือก "แสดงตัวอย่างบนพอร์ต 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 ในลักษณะเดียวกับ LoadBalancer ของ GKE และจะกำหนดเส้นทางการรับส่งข้อมูลขาเข้าทั้งหมดไปยังบริการส่วนหน้า

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

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

เขียน redis-virtualservice.yaml

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

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

เขียน worker-virtualservice.yaml

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

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

ใช้งานนโยบายการจัดการการรับส่งข้อมูลของ Istio

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

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

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

  1. เปลี่ยนกลับไปที่ไดเรกทอรี kubernetes ของเรา
cd ${proj}/kubernetes
  1. ติดตั้งใช้งาน Redis Cache
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. ติดตั้งใช้งานบริการ Worker
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 Remote

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

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

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

kubectx primary

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

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

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

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

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

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

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

หากต้องการติดตั้ง 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" โดยการสร้าง Secret และติดป้ายกำกับ

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

สร้างการติดตั้งใช้งาน Worker สำหรับคลัสเตอร์ "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-"

ซึ่งหมายความว่า Worker ในคลัสเตอร์ 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

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

นำไปใช้กับคลัสเตอร์

ทำให้ redis-service.yaml ใช้งานได้กับคลัสเตอร์ที่เพิ่มประสิทธิภาพ

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

kubectx burst

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

cd ${proj}

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

ติดตั้งใช้งาน redis-service.yaml กับคลัสเตอร์ที่ใช้การระเบิด

kubectl apply -f kubernetes/redis-service.yaml

Deploy worker-burst.yaml ไปยังคลัสเตอร์ที่เพิ่มขึ้น

kubectl apply -f kubernetes/worker-burst.yaml

ทำให้ worker-service.yaml ใช้งานได้กับคลัสเตอร์ที่รองรับการเพิ่มประสิทธิภาพ

kubectl apply -f kubernetes/worker-service.yaml

ใช้ Istio VirtualServices

เปลี่ยนเป็น 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

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

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

เราต้องเปิดเผยการติดตั้งใช้งาน Prometheus เพื่อเริ่มต้นใช้งาน

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

b4a7a3cd67db05b3.png

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

c04a482e55bdfd41.png

เลือกส่งต่อไปยังพอร์ต 9090 แล้วพิมพ์ "Load Balancer"

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 ของพวกเขาเพื่อรับเมตริกได้แล้ว

เราสามารถค้นหา API ของ Prometheus ด้วยการค้นหาของเราได้โดยส่งคำขอ 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 Console ให้ไปที่ด้านบนของบริการที่เราเพิ่งสร้าง แล้วคลิก "ลบ"

d58cb51b4c922751.png

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

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

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

ตั้งค่า

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

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

แก้ไข $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

เขียน daemon ของ Istiowatcher

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

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

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

เราจะโทรหา istioctl จากภายในคอนเทนเนอร์เพื่อจัดการระนาบควบคุม Istio จากภายในคลัสเตอร์

เขียน istiowatcher.go

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

package main

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

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

        isBurst := false

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

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

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

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

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

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

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

เขียน Dockerfile

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

FROM golang:1.11.2-stretch as base

FROM base as builder

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

FROM base 

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

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

CMD ["istiowatcher"]

Dockerfile แบบหลายขั้นตอนนี้จะดาวน์โหลดและแตกไฟล์ Istio เวอร์ชัน 1.0.0 ในขั้นตอนแรก ในขั้นที่ 2 ระบบจะคัดลอกทุกอย่างจากไดเรกทอรีของเราลงในอิมเมจ จากนั้นจะคัดลอก istioctl จากขั้นตอนการสร้างไปยัง /usr/local/bin (เพื่อให้แอปพลิเคชันของเราเรียกใช้ได้) รับทรัพยากร Dependency คอมไพล์โค้ด และตั้งค่า 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 Cloud 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

โปรดสังเกตว่าการดำเนินการนี้ใช้เวลาไม่กี่วินาที แต่เราจะเพิ่มความเร็วและแฮชทั้งหมดจะมีคำนำหน้า "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

ก้าวต่อไป