Menggunakan Multicluster Istio untuk "Meningkatkan" Beban Kerja Antar-Cluster

1. Selamat Datang

Terima kasih telah bergabung dengan kami di codelab Istio Multi Cloud Burst dari Google.Codelab ini memerlukan pengalaman langsung tingkat pemula dengan Kubernetes, Node, dan Go.

Yang Anda butuhkan

  • Akun Google Cloud Platform (gunakan yang sudah ada, atau kami akan memberikan akun gratis)
  • Laptop Anda (instal "kubectl", "gcloud", dll.) atau Anda dapat menggunakan Google Cloud Shell.

Yang akan Anda pelajari

  • Cara membuat cluster Kubernetes di GKE
  • Cara menginstal Istio di cluster Kubernetes dengan Helm
  • Cara menginstal Multicluster Istio dengan Helm
  • Men-deploy aplikasi web dari sumber ke Kubernetes
  • Menulis dan Menerapkan aturan Pemilihan Rute Traffic ke Istio
  • Metrik Prometheus
  • Mem-build dan mengirim image container di dalam cluster Kubernetes

2. Mempersiapkan

Anda dapat mengikuti codelab ini di:

  • Google Cloud Shell (direkomendasikan): shell dalam browser, dilengkapi dengan alat yang diinstal
  • laptop Anda (ikuti petunjuk di bawah)

Memulai dengan Google Cloud Platform

  1. Ambil kartu akun pengguna gratis dari instruktur jika Anda tidak memiliki akun GCP.
  2. Buka Google Cloud Console dan klik "Select a project": 5c2d9bf74c78f7e4.png
  3. Catat "ID" project di suatu tempat, lalu klik project untuk memilihnya: ecc5e8e97bfa6559.png

Cloud Shell menyediakan shell command line di dalam browser dengan alat yang perlu diinstal dan diautentikasi secara otomatis ke akun Google Cloud Platform Anda. (Jika Anda tidak ingin menjalankan latihan ini di Cloud Shell, lanjutkan ke bagian berikutnya.)

Buka Cloud Console, lalu klik "Activate Cloud Shell" di toolbar kanan atas:

68a17b036ce24ccb.png

Menambahkan alat ke Cloud Shell

  1. Instal kubectx****: dengan mendownload skrip bash dari sini ke lokasi di $PATH.
  2. Instal helm****: dengan mengikuti petunjuk ini.

Atau, jalankan perintah ini untuk menginstal keduanya ke ~/.bin dan menambahkannya ke $PATH Anda:

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}

Beberapa tips cepat yang dapat mempermudah penggunaan Cloud Shell:

1. Lepaskan shell ke jendela baru:

2. Menggunakan editor file: Klik ikon pensil di kanan atas untuk meluncurkan editor file dalam browser. Anda akan merasa ini berguna karena kita akan menyalin cuplikan kode ke dalam file.

3. Memulai tab baru: Jika Anda memerlukan lebih dari satu perintah terminal.

4. Memperbesar teks: Ukuran font default di Cloud Shell mungkin terlalu kecil untuk dibaca.

Ctrl-+ di Linux/Windows⌘-+ di macOS.

Jika Anda merasa lebih nyaman menggunakan lingkungan workstation Anda sendiri daripada Cloud Shell, siapkan alat berikut:

  1. Instal gcloud: (Sudah diinstal sebelumnya di Cloud Shell.) Ikuti petunjuk untuk menginstal gcloud di platform Anda. Kita akan menggunakannya untuk membuat cluster Kubernetes.
  2. Instal kubectl:(Sudah diinstal sebelumnya di Cloud Shell.) Jalankan perintah berikut untuk menginstal:
gcloud components install kubectl

Jalankan perintah berikut untuk mengautentikasi gcloud. Anda akan diminta untuk login dengan Akun Google Anda. Kemudian, pilih project yang telah dibuat sebelumnya (lihat di atas) sebagai project default. (Anda dapat melewati konfigurasi zona komputasi):

gcloud init
  1. Instal curl: Diinstal sebelumnya di sebagian besar sistem Linux/macOS. Anda mungkin sudah memilikinya. Jika tidak, telusuri internet untuk mengetahui cara menginstalnya.
  2. Instal kubectx****: dengan mendownload skrip bash dari sini ke lokasi di $PATH
  3. Instal helm****: dengan mengikuti petunjuk ini.

3. Menyiapkan Project GCP

Aktifkan GKE (Google Kubernetes Engine), GCR (Google Container Registry), dan GCB (Google Cloud Build) API di project Anda:

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

Menyiapkan Variabel Lingkungan

Kita akan menggunakan project Google Cloud secara ekstensif selama penyiapan. Mari kita tetapkan variabel lingkungan untuk referensi cepat

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

Kita akan membuat beberapa kode dan file konfigurasi selama workshop ini, jadi mari kita buat direktori project dan beralih ke direktori tersebut

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

4. Membuat cluster Kubernetes "utama"

Anda dapat dengan mudah membuat cluster Kubernetes terkelola dengan Google Kubernetes Engine (GKE).

Perintah berikut akan membuat cluster Kubernetes:

  • bernama "primary",
  • di zona us-west1-a,
  • Versi Kubernetes terbaru yang tersedia,
  • dengan 4 node awal
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

(Proses ini mungkin memerlukan waktu sekitar 5 menit. Anda dapat melihat cluster yang dibuat di Cloud Console.)

Setelah cluster Kubernetes dibuat, gcloud akan mengonfigurasi kubectl dengan kredensial yang mengarah ke cluster.

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

Anda kini dapat menggunakan kubectl dengan cluster baru.

Jalankan perintah berikut untuk menampilkan daftar node Kubernetes cluster Anda (node akan menampilkan status "Siap"):

kubectl get nodes

Mengubah nama Kubeconfig untuk memudahkan penggunaan

Kita akan sering beralih antarkonteks sehingga memiliki alias singkat untuk cluster akan sangat berguna.

Perintah ini akan mengganti nama entri kubeconfig yang baru saja Anda buat menjadi primary

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

Tetapkan izin:

Untuk men-deploy Istio, Anda harus menjadi admin cluster. Perintah ini akan menetapkan email yang terkait dengan akun Google Cloud Anda sebagai admin cluster

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

5. Membuat cluster "burst"

Perintah berikut akan membuat cluster Kubernetes:

  • bernama "burst",
  • di zona us-west1-a,
  • Versi Kubernetes terbaru yang tersedia,
  • Dengan 1 node awal
  • Penskalaan otomatis diaktifkan hingga 5 node
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

(Proses ini mungkin memerlukan waktu sekitar 5 menit. Anda dapat melihat cluster yang dibuat di Cloud Console.)

Setelah cluster Kubernetes dibuat, gcloud akan mengonfigurasi kubectl dengan kredensial yang mengarah ke cluster.

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

Anda kini dapat menggunakan kubectl dengan cluster baru.

Jalankan perintah berikut untuk menampilkan daftar node Kubernetes cluster Anda (node akan menampilkan status "Siap"):

kubectl get nodes

Mengubah nama Kubeconfig untuk memudahkan penggunaan

Perintah ini akan mengubah entri kubeconfig yang baru saja Anda buat menjadi burst

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

Tetapkan izin:

Untuk men-deploy Istio Remote, Anda harus menjadi admin cluster. Perintah ini akan menetapkan email yang terkait dengan akun Google Cloud Anda sebagai admin cluster

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

6. Menerapkan Aturan Firewall

Agar kedua cluster dapat berkomunikasi satu sama lain, kita harus membuat aturan Firewall.

Jalankan perintah berikut untuk membuat aturan Firewall di Google Cloud Platform yang akan memungkinkan cluster kita berkomunikasi

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

Kita telah menyiapkan kedua cluster dan siap untuk men-deploy aplikasi dan Istio di cluster tersebut.

7. Pengantar Istio

Apa Itu Istio?

Istio adalah bidang kontrol mesh layanan yang bertujuan untuk "menghubungkan, mengamankan, mengontrol, dan mengamati layanan". Hal ini dilakukan dengan berbagai cara, tetapi terutama dengan menambahkan penampung proxy ( Envoy) ke setiap Pod Kubernetes yang di-deploy. Penampung proxy mengontrol semua komunikasi jaringan antar-microservice bersama dengan kebijakan tujuan umum dan hub telemetri ( Mixer).

a25613cd581825da.png

Kebijakan ini dapat diterapkan secara independen dari Deployment dan Layanan Kubernetes Anda, yang berarti Operator Jaringan dapat mengamati aktivitas jaringan, membatasi, mengalihkan, atau menulis ulang kebijakan jaringan tanpa men-deploy ulang aplikasi terkait.

Beberapa fitur Pengelolaan Traffic yang Didukung Istio adalah:

  • Pemutus rangkaian
  • Pemisahan traffic berbasis persentase
  • Penulisan ulang URL
  • TLS termination
  • Health check
  • Load balancing

Untuk tujuan workshop ini, kita akan berfokus pada pemisahan traffic berbasis persentase.

Istilah Istio yang Akan Kita Gunakan

Layanan Virtual

VirtualService menentukan serangkaian aturan pemilihan rute traffic yang akan diterapkan saat host ditangani.

Gateway

Gateway adalah load balancer yang beroperasi di tepi mesh yang menerima koneksi HTTP/TCP masuk atau keluar. Gateway dapat menentukan Port, konfigurasi SNI, dll.

Aturan Tujuan

DestinationRule menentukan kebijakan yang berlaku untuk traffic yang ditujukan untuk layanan setelah perutean terjadi. File ini menentukan konfigurasi untuk load balancing, ukuran kumpulan koneksi dari sidecar, dan setelan deteksi pencilan.

Multicluster Istio

Anda mungkin telah memperhatikan saat membuat dua cluster, bahwa cluster primary memiliki 4 node tanpa penskalaan otomatis, dan cluster burst memiliki 1 node dengan penskalaan otomatis hingga 5 node.

Ada dua alasan untuk konfigurasi ini.

Pertama, kita ingin menyimulasikan skenario "on-prem" ke Cloud. Di lingkungan on-premise, Anda tidak memiliki akses ke cluster penskalaan otomatis karena Anda memiliki infrastruktur tetap.

Kedua, penyiapan 4 node (seperti yang ditentukan di atas) adalah persyaratan minimum untuk menjalankan Istio. Hal ini menimbulkan pertanyaan: jika Istio memerlukan minimal 4 node, bagaimana cluster burst kami dapat menjalankan Istio dengan 1 node? Jawabannya adalah Istio Multicluster menginstal kumpulan layanan Istio yang jauh lebih kecil, dan berkomunikasi dengan penginstalan Istio di cluster utama untuk mengambil aturan kebijakan dan memublikasikan informasi telemetri.

8. Ringkasan Arsitektur Aplikasi

Ringkasan Komponen

Kita akan men-deploy aplikasi tiga tingkat menggunakan NodeJS dan Redis.

Pekerja

Aplikasi pekerja ditulis dalam NodeJS dan akan memproses permintaan HTTP POST yang masuk, melakukan operasi hashing pada permintaan tersebut, dan jika variabel lingkungan bernama PREFIX ditentukan, aplikasi akan menambahkan hash dengan nilai tersebut. Setelah hash dihitung, aplikasi akan mengirimkan hasilnya di channel "calculation" di server Redis yang ditentukan.

Kita akan menggunakan variabel lingkungan PREFIX nanti untuk mendemonstrasikan fungsi multi-cluster.

Sebagai referensi: ini adalah paket yang digunakan aplikasi.

  • body-parser: Memungkinkan kita mengurai permintaan http
  • cors: Mengizinkan penggunaan Cross-Origin Resource Sharing
  • dotenv: Pemisahan variabel lingkungan yang mudah
  • express: Hosting situs yang mudah
  • ioredis: Library klien untuk berkomunikasi dengan database Redis
  • morgan: Memberikan log terstruktur yang bagus

Frontend

Frontend kami juga merupakan aplikasi NodeJS yang menghosting halaman web menggunakan express. Fungsi ini menggunakan frekuensi yang dimasukkan pengguna dan mengirim permintaan ke aplikasi worker kami dengan kecepatan tersebut. Aplikasi ini juga berlangganan pesan di saluran Redis bernama "calculation" dan menampilkan hasilnya di halaman web.

Aplikasi menggunakan dependensi berikut.

  • body-parser: Memungkinkan kita mengurai permintaan http
  • dotenv: Pemisahan variabel lingkungan yang mudah
  • express: Hosting situs yang mudah
  • ioredis: Library klien untuk berkomunikasi dengan database Redis
  • morgan: Memberikan log terstruktur yang bagus
  • request: Memungkinkan pembuatan permintaan HTTP
  • socket.io: Memungkinkan komunikasi dua arah dari Halaman Web ke server

Halaman web ini menggunakan Bootstrap untuk gaya visual dan, saat dijalankan, akan terlihat seperti berikut

e5e3b9cbede4cac4.png

Diagram Arsitektur

7ae4bc22a58f80a6.png

Diagram Deployment

Kita akan men-deploy aplikasi akhir di kedua cluster yang kita buat. Cluster primary akan memiliki semua komponen (frontend, worker, dan Redis) yang di-deploy ke cluster tersebut, tetapi cluster burst hanya akan memiliki aplikasi worker yang di-deploy.

Berikut adalah diagram yang menjelaskan kedua cluster tersebut. Kotak yang digarisbawahi dengan warna merah adalah Layanan Kubernetes, sedangkan yang berwarna biru adalah Deployment Kubernetes. Kotak kuning menunjukkan penginstalan Istio.

561db37c510944bd.png

Perhatikan bagaimana cluster burst masih memiliki layanan untuk Redis yang di-deploy ke cluster meskipun tidak ada Deployment untuk Redis di cluster. Kita harus memiliki layanan ini di cluster agar DNS Kubernetes dapat me-resolve permintaan, tetapi saat permintaan benar-benar dibuat, Proxy Istio akan merutekan ulang permintaan ke deployment Redis di cluster primary.

Aplikasi akhir akan memiliki Deployment tambahan yang berjalan di cluster primary bernama istiowatcher.. Hal ini memungkinkan kita untuk secara dinamis mengalihkan traffic ke burst secara otomatis saat traffic melampaui nilai minimum tertentu.

8f6183bdfc3f813c.png

9. Membuat File Deployment Aplikasi

Kita perlu membuat serangkaian manifes Kubernetes untuk men-deploy aplikasi

Beralih ke direktori utama project dan buat folder baru bernama kubernetes

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

Menulis frontend.yaml

Tindakan ini akan membuat Deployment dan Layanan Kubernetes untuk mengakses image frontend kita.

Masukkan kode berikut ke 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

Hal-hal penting yang perlu diperhatikan di Deployment

  • Kami telah menentukan port tempat aplikasi akan berjalan menjadi 8080
  • Kami telah menetapkan alamat untuk pekerja menjadi "http://worker-service" dan akan menggunakan fitur DNS bawaan Kubernetes untuk me-resolve layanan yang dihasilkan
  • Kita telah menetapkan alamat untuk REDIS_URL menjadi "redis-cache-service:6379" dan akan menggunakan fitur DNS bawaan Kubernetes untuk me-resolve alamat IP yang dihasilkan.
  • Kita juga telah menetapkan probe liveness dan readiness ke penampung untuk membantu memberi tahu Kubernetes saat penampung sudah aktif dan berjalan.

Menulis worker-service.yaml

Kita menulis definisi layanan Kubernetes dalam file terpisah dari definisi Deployment karena kita akan menggunakan kembali layanan ini di beberapa cluster, tetapi akan menulis Deployment yang berbeda untuk setiap cluster.

Masukkan kode berikut di worker-service.yaml

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

Menulis worker-primary.yaml

Ini akan menjadi deployment worker yang akan kita kirim ke cluster utama.

Masukkan kode berikut ke 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"

Perhatikan bahwa dalam hal ini, kita mengikuti pola yang sama dalam menyediakan probe liveness dan readiness serta menentukan variabel lingkungan PORT dan REDIS_URL untuk digunakan aplikasi kita.

Hal lain yang perlu diperhatikan dalam deployment ini adalah tidak adanya variabel lingkungan PREFIX. Artinya, hasil penghitungan kita akan berupa hash mentah (tidak ada awalan).

Poin utama akhir deployment ini adalah label cluster-type: primary-cluster. Kita akan menggunakannya nanti saat melakukan Pemilihan Rute Traffic di Multicluster Istio

Menulis redis.yaml

Komunikasi dari pekerja kembali ke frontend dilakukan melalui saluran Redis, sehingga kita perlu men-deploy aplikasi Redis ke cluster.

Masukkan kode berikut ke 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: {}

Ini adalah deployment semi standar aplikasi Redis. Fungsi ini menyiapkan penampung berdasarkan image redis:alpine, mengekspos port yang sesuai, dan menetapkan batas resource yang wajar.

Menulis redis-service.yaml

Kita memerlukan Layanan Kubernetes untuk berkomunikasi dengan aplikasi Redis

Masukkan kode berikut ke redis-service.yaml

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

Tindakan ini akan menyediakan layanan bernama redis-cache-service untuk mengakses Deployment Redis.

10. Men-deploy Aplikasi

Setelah image di-push ke GCR dan manifes Kubernetes ditulis, ini adalah waktu yang tepat untuk men-deploy aplikasi dan melihat cara kerjanya.

Jalankan perintah berikut untuk men-deploy aplikasi

  1. Pastikan kita berada di cluster yang tepat
kubectx primary
  1. Men-deploy Cache Redis
kubectl apply -f redis.yaml
  1. Men-deploy Layanan Redis
kubectl apply -f redis-service.yaml
  1. Men-deploy frontend
kubectl apply -f frontend.yaml
  1. Men-deploy Pekerja
kubectl apply -f worker-primary.yaml
  1. Men-deploy Layanan Pekerja
kubectl apply -f worker-service.yaml

Kita telah men-deploy aplikasi ke GKE. Selamat!

Menguji

Tunggu hingga pod muncul secara online

kubectl get pods -w

Setelah semua pod "Berjalan", tekan 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

Anda akan melihat bahwa kita tidak mengekspos frontend melalui LoadBalancer. Hal ini karena nanti kita akan mengakses aplikasi melalui Istio. Untuk menguji apakah semuanya sudah aktif dan berjalan, kita akan menggunakan kubectl port-forward. Jalankan perintah berikut untuk meneruskan port 8080 di komputer lokal (atau Cloud Shell) Anda ke port 8080 yang menjalankan deployment frontend.

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

Jika Anda menjalankannya secara lokal: buka browser web dan buka http://localhost:8080

Jika Anda menjalankannya di Cloud Shell: klik tombol "Web Preview" dan pilih "Preview on port 8080"

bdb5dc75f415be11.png

Anda akan melihat frontend. Dan jika Anda memasukkan angka di kotak "frekuensi", Anda akan melihat hash mulai muncul

1caafaffab26897a.png

Selamat, semuanya sudah siap dan berjalan.

Tekan Ctrl+C untuk berhenti meneruskan port.

11. Membersihkan Aplikasi yang Di-deploy

Kita akan menerapkan Istio ke cluster, lalu men-deploy ulang aplikasi. Jadi, mari kita hapus aplikasi saat ini terlebih dahulu.

Jalankan perintah berikut untuk menghapus semua Deployment dan layanan yang baru saja Anda buat

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

12. Menginstal Istio di Cluster utama

Mendapatkan Istio

Rilis Istio dihosting di GitHub. Perintah berikut akan mendownload istio versi 1.0.0 dan mengekstraknya.

  1. Beralih ke root project Anda
cd ${proj}
  1. Mendownload arsip
curl -LO https://github.com/istio/istio/releases/download/1.0.0/istio-1.0.0-linux.tar.gz
  1. Mengekstrak dan menghapus arsip
tar xzf istio-1.0.0-linux.tar.gz && rm istio-1.0.0-linux.tar.gz

Membuat Template Istio

Dengan menjalankan perintah Helm berikut, Anda akan membuat template untuk menginstal Istio ke cluster.

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

Tindakan ini akan membuat file bernama istio-primary.yaml di direktori saat ini yang berisi semua definisi dan spesifikasi yang diperlukan untuk men-deploy dan menjalankan Istio.

Perhatikan dua parameter --set. Hal ini menambahkan dukungan Prometheus dan ServiceGraph ke sistem Istio. Kita akan menggunakan layanan Prometheus nanti di lab.

Men-deploy Istio

Untuk men-deploy istio, pertama-tama kita harus membuat namespace bernama istio-system tempat Deployment dan Layanan Istio dapat berjalan.

kubectl create namespace istio-system

Terakhir, terapkan file istio-primary.yaml yang kita buat dengan Helm

kubectl apply -f istio-primary.yaml

Namespace default Label

Istio berfungsi dengan memasukkan layanan proxy file bantuan ke setiap Deployment Anda. Hal ini dilakukan berdasarkan keikutsertaan sehingga kita perlu memberi label pada namespace default dengan istio-injection=enabled agar Istio dapat otomatis memasukkan sidecar untuk kita.

kubectl label namespace default istio-injection=enabled

Selamat! Kita sudah menyiapkan cluster dan menjalankan Istio untuk men-deploy aplikasi.

13. Men-deploy Aplikasi dengan Pengelolaan Traffic Istio

Membuat File Konfigurasi Pengelolaan Traffic Istio

Istio berfungsi mirip dengan Kubernetes karena menggunakan file yaml untuk konfigurasi. Dalam hal ini, kita perlu membuat serangkaian file yang memberi tahu Istio cara mengekspos dan merutekan traffic.

Buat direktori bernama istio-manifests dan ubah ke direktori tersebut

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

Menulis frontend-gateway.yaml

File ini akan mengekspos cluster Kubernetes dengan cara yang mirip dengan LoadBalancer GKE dan akan merutekan semua traffic masuk ke layanan frontend.

Buat file bernama frontend-gateway.yaml dan masukkan kode berikut.

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

Menulis redis-virtualservice.yaml

Buat file bernama redis-virtualservice.yaml dan masukkan kode berikut

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

Menulis worker-virtualservice.yaml

Buat file bernama worker-virtualservice.yaml dan masukkan kode berikut

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

Men-deploy Kebijakan Pengelolaan Traffic Istio

Men-deploy kebijakan Istio dilakukan dengan cara yang sama seperti resource Kubernetes lainnya, dengan kubectl apply

  1. Menerapkan Gateway kami
kubectl apply -f frontend-gateway.yaml
  1. Menerapkan VirtualService Redis
kubectl apply -f redis-virtualservice.yaml
  1. Menerapkan VirtualService Pekerja kami
kubectl apply -f worker-virtualservice.yaml

Men-deploy Aplikasi

  1. Kembali ke direktori kubernetes
cd ${proj}/kubernetes
  1. Men-deploy Cache Redis
kubectl apply -f redis.yaml
  1. Men-deploy Layanan Redis
kubectl apply -f redis-service.yaml
  1. Men-deploy frontend
kubectl apply -f frontend.yaml
  1. Men-deploy Pekerja
kubectl apply -f worker-primary.yaml
  1. Men-deploy Layanan Pekerja
kubectl apply -f worker-service.yaml

Verifikasi

Pada tahap ini, kita telah men-deploy ulang aplikasi di cluster dengan Istio dan kebijakan pengelolaan traffic.

Mari kita tunggu hingga semua beban kerja online

Setelah semuanya online, dapatkan IngressGateway yang kita konfigurasi di 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,

Buka alamat <EXTERNAL-IP>, atau gunakan curl dan Anda akan melihat frontend.

$ curl 35.199.158.10
<!doctype html>
<html>

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

14. Menginstal Istio di Cluster "burst"

Kita telah menghabiskan banyak waktu untuk menyiapkan dan men-deploy di cluster primary, tetapi kita memiliki cluster lain yang akan di-deploy.

Di bagian ini, kita perlu mengambil variabel konfigurasi di kedua cluster, jadi perhatikan dengan cermat cluster mana yang dituju untuk setiap perintah.

Membuat Manifes Jarak Jauh Istio

Sama seperti saat men-deploy Istio ke cluster primary, kita akan menggunakan Helm untuk membuat template deployment istio jarak jauh ke cluster burst. Namun, sebelum dapat melakukannya, kita perlu mendapatkan beberapa informasi tentang cluster primary

Mengumpulkan informasi cluster utama

Mengubah ke cluster primary

kubectx primary

Perintah berikut mengambil alamat IP berbagai pod di cluster utama. Ini digunakan oleh Istio Remote untuk berkomunikasi kembali dengan cluster utama.

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}')

Membuat Template Jarak Jauh

Sekarang kita akan menggunakan helm untuk membuat file bernama istio-remote-burst.yaml yang kemudian dapat kita deploy ke cluster burst.

Mengubah ke root project

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

Menginstal Istio Remote di Cluster burst

Untuk menginstal Istio di cluster burst, kita harus mengikuti langkah-langkah yang sama seperti saat menginstal di cluster primary, tetapi kita harus menggunakan file istio-remote-burst.yaml.

Mengubah kubecontext menjadi burst

kubectx burst

Membuat namespace istio-system

kubectl create ns istio-system

Menerapkan istio-burst.yaml

kubectl apply -f istio-remote-burst.yaml

Namespace default label

Sekali lagi, kita perlu memberi label pada namespace default agar proxy dapat dimasukkan secara otomatis.

kubectl label namespace default istio-injection=enabled

Selamat! Pada tahap ini, kita telah menyiapkan Istio Remote di cluster burst. Namun, pada tahap ini, cluster masih tidak dapat berkomunikasi. Kita perlu membuat file kubeconfig untuk cluster burst yang dapat di-deploy ke cluster primary untuk menautkan keduanya.

Membuat kubeconfig untuk cluster "burst"

Mengubah ke cluster burst

kubectx burst

Menyiapkan lingkungan

Kita perlu mengumpulkan beberapa informasi tentang cluster untuk membuat file kubeconfig.

  1. Mendapatkan nama cluster
CLUSTER_NAME=$(kubectl config view --minify=true -o "jsonpath={.clusters[].name}")
  1. Mendapatkan nama server cluster
SERVER=$(kubectl config view --minify=true -o "jsonpath={.clusters[].cluster.server}")
  1. Mendapatkan nama secret untuk Otoritas Sertifikasi akun layanan istio-multi
SECRET_NAME=$(kubectl get sa istio-multi -n istio-system -o jsonpath='{.secrets[].name}')
  1. Mendapatkan data Certificate Authority yang disimpan dalam secret sebelumnya
CA_DATA=$(kubectl get secret ${SECRET_NAME} -n istio-system -o "jsonpath={.data['ca\.crt']}")
  1. Mendapatkan token yang disimpan dalam secret sebelumnya
TOKEN=$(kubectl get secret ${SECRET_NAME} -n istio-system -o "jsonpath={.data['token']}" | base64 --decode)

Membuat file kubeconfig

Dengan semua variabel lingkungan yang ditetapkan, kita perlu membuat file 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

Tindakan ini akan membuat file baru bernama burst-kubeconfig di direktori Anda saat ini yang dapat digunakan oleh cluster primary untuk mengautentikasi dan mengelola cluster burst.

Beralih kembali ke cluster utama

kubectx primary

Menerapkan kubeconfig untuk "burst", dengan membuat secret dan memberinya label

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

Beri label pada secret agar Istio tahu untuk menggunakannya untuk autentikasi multi-cluster

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

Selamat! Kita memiliki kedua cluster yang diautentikasi dan berkomunikasi satu sama lain melalui Multicluster Istio. Mari kita deploy aplikasi secara Lintas Cluster

15. Men-deploy Aplikasi Lintas Cluster

Membuat Deployment

Ubah ke direktori kubernetes

cd ${proj}/kubernetes

Membuat deployment pekerja untuk cluster "burst": worker-burst.yaml

Buat file bernama worker-burst.yaml dan masukkan kode berikut ke dalamnya:

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

Perhatikan bahwa file ini hampir sama dengan worker-primary.yaml yang kita buat sebelumnya. Ada dua perbedaan utama.

Perbedaan utama pertama adalah kita telah menambahkan variabel lingkungan PREFIX dengan nilai "bursty-"

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

Ini berarti bahwa pekerja kita di cluster burst akan menambahkan awalan "bursty-" ke semua hash yang dikirimnya. Kita dapat menggunakan ini untuk mengetahui bahwa aplikasi kita benar-benar lintas cluster.

Perbedaan utama kedua adalah kami telah mengubah label cluster-type pada deployment ini dari primary-cluster menjadi burst-cluster

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

Kita akan menggunakan label ini nanti saat memperbarui VirtualService.

Mengubah Layanan Istio

Saat ini, layanan Istio kami tidak memanfaatkan kedua deployment kami. 100% traffic kami dirutekan ke cluster "utama". Mari kita ubah.

Beralih ke direktori istio-manifests

cd ${proj}/istio-manifests

Mengedit worker-virtualservice.yaml untuk menyertakan 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

Anda dapat melihat bahwa kita telah menambahkan tujuan kedua ke VirtualService. Sub-domain ini masih mereferensikan host yang sama (worker-service.default.svc.cluster.local), tetapi 50% traffic dirutekan ke subset primary dan 50% lainnya dirutekan ke subset burst.

Kita telah menentukan subset primary sebagai deployment yang memiliki label cluster-type: primary-cluster dan subset burst sebagai deployment yang memiliki label cluster-type: burst-cluster.

Hal ini secara efektif membagi traffic kita 50/50 di antara kedua cluster.

Deploy ke Cluster

Men-deploy redis-service.yaml ke cluster burst

Mengubah ke kubeconfig burst

kubectx burst

Beralih ke root project

cd ${proj}

Kemudian deploy

Men-deploy redis-service.yaml ke cluster burst

kubectl apply -f kubernetes/redis-service.yaml

Men-deploy worker-burst.yaml ke cluster burst

kubectl apply -f kubernetes/worker-burst.yaml

Men-deploy worker-service.yaml ke cluster burst

kubectl apply -f kubernetes/worker-service.yaml

Menerapkan VirtualServices Istio

Mengubah ke kubeconfig primary

kubectx primary

Kemudian Deploy

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

Memverifikasi Fungsinya

Untuk memverifikasi bahwa konfigurasi ini berfungsi, buka titik Ingress Istio Anda, dan perhatikan bahwa sekitar 50% hash diawali dengan "burst-".

78fb6e235e9f4a07.png

Ini berarti kita berhasil berkomunikasi lintas cluster. Coba ubah bobot pada berbagai layanan dan terapkan file worker-virtualservice.yaml. Ini adalah cara yang bagus untuk menyeimbangkan traffic antar-cluster, tetapi bagaimana jika kita dapat melakukannya secara otomatis?

16. Memanfaatkan Metrik Prometheus

Pengantar Prometheus

Prometheus adalah toolkit pemantauan dan pemberitahuan sistem open source yang awalnya dibuat di SoundCloud. Bigtable mempertahankan model data multidimensi dengan data deret waktu yang diidentifikasi berdasarkan nama metrik dan key-value pair.

Sebagai referensi, berikut adalah diagram Arsitektur Prometheus:

601e1155a825e0c2.png

Istio, saat di-deploy dengan Prometheus, akan otomatis melaporkan berbagai metrik ke server Prometheus. Kita dapat menggunakan metrik ini untuk mengelola cluster secara langsung.

Menjelajahi Metrik Prometheus

Untuk memulai, kita perlu mengekspos Deployment Prometheus.

Buka tab Workloads di GKE, lalu buka workload "prometheus".

b4a7a3cd67db05b3.png

Setelah Anda melihat detail deployment, buka Actions -> Expose.

c04a482e55bdfd41.png

Pilih untuk meneruskan ke port 9090, lalu ketik "Load balancer"

d5af3ba22a7a6ebb.png

Lalu pilih "Expose"

Tindakan ini akan membuat Layanan di alamat IP yang dapat diakses secara publik yang dapat kita gunakan untuk menjelajahi Metrik Prometheus

Tunggu endpoint beroperasi, lalu klik alamat IP di samping "Endpoint eksternal" b1e40ad90851da29.png

Sekarang Anda akan melihat UI Prometheus.

ed273552270337ec.png

Prometheus menyediakan cukup metrik untuk menjadi workshop-nya sendiri. Namun, untuk saat ini, kita akan mulai dengan mempelajari metrik istio_requests_total.

Mengeksekusi kueri tersebut akan menampilkan banyak data. Ini adalah metrik pada semua permintaan yang melewati mesh layanan Istio, dan jumlahnya sangat banyak. Kita akan mengubah ekspresi untuk memfilter hal yang benar-benar kita minati:

Permintaan dengan layanan tujuan worker-service.default.svc.cluster.local, dan sumbernya frontend-deployment dibatasi hingga 15 detik terakhir

Kueri tersebut terlihat seperti:

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

Dan memberi kita kumpulan data yang jauh lebih mudah dikelola

19d551fd5eac3785.png

Namun, masih sedikit padat. Kita ingin mengetahui permintaan per detik, bukan semua permintaan.

Untuk mendapatkannya, kita dapat menggunakan fungsi rate bawaan

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

dbb9dc063a18da9b.png

Hal ini semakin mendekatkan kita, tetapi kita perlu mengurangi metrik tersebut sedikit lebih jauh ke dalam grup yang logis.

Untuk melakukannya, kita dapat menggunakan kata kunci sum dan by untuk mengelompokkan dan menjumlahkan hasil

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

Sempurna! Kita bisa mendapatkan metrik yang tepat yang kita butuhkan dari Prometheus.

Kueri Prometheus akhir kami

Dengan semua yang telah kita pelajari, kueri terakhir yang perlu kita tanyakan kepada Prometheus adalah

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)

Sekarang kita dapat menggunakan HTTP API untuk mendapatkan metrik.

Kita dapat mengkueri API mereka dengan kueri kita dengan membuat permintaan GET http seperti ini. Ganti <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\)

Berikut adalah contoh respons:

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

Sekarang, kita dapat mengekstrak nilai metrik dari JSON

Pembersihan

Kita perlu menghapus Layanan yang baru saja digunakan untuk mengekspos Prometheus. Di Konsol Google Cloud, buka bagian atas layanan yang baru saja kita buat, lalu klik "Hapus"

d58cb51b4c922751.png

Langkah Berikutnya:

Setelah menemukan cara untuk mengetahui cara traffic bergerak melalui cluster, dan pada kecepatan berapa, langkah berikutnya adalah menulis biner kecil yang secara berkala mengkueri prometheus, dan jika permintaan per detik ke worker melebihi nilai minimum tertentu, terapkan bobot tujuan yang berbeda pada layanan virtual pekerja untuk mengirim semua traffic ke cluster burst. Setelah permintaan per detik berada di bawah nilai minimum yang lebih rendah, kirim semua traffic kembali ke primary.

17. Membuat Burst Lintas Cluster

Penyiapan

Menetapkan semua traffic untuk layanan pekerja ke cluster utama

Kami akan menganggap semua traffic yang ditujukan untuk worker-service yang dirutekan ke cluster primary sebagai status "default" aplikasi kami

Edit $proj/istio-manifests/worker-virtualservice.yaml agar terlihat seperti berikut

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

Pastikan Anda terhubung ke cluster primary

kubectx primary

Terapkan istio-manifests/worker-virtualservice.yaml

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

Menulis daemon istiowatcher

Kita akan menggunakan Go untuk menulis layanan ini karena kecepatan dan portabilitasnya. Alur keseluruhan aplikasi akan dimulai dan setiap detik, membuat kueri prometheus,

Buat direktori baru di src bernama istiowatcher

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

Kita akan memanggil istioctl dari dalam penampung untuk memanipulasi bidang kontrol Istio dari dalam cluster.

Menulis istiowatcher.go

Buat file di direktori tersebut bernama istiowatcher.go dan masukkan kode berikut ke dalamnya

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)
        }
}

Menulis Dockerfile

Buat file baru bernama Dockerfile dan masukkan kode berikut ke dalamnya.

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 multi-tahap ini mendownload dan mengekstrak rilis Istio 1.0.0 di tahap pertama. Tahap kedua menyalin semua dari direktori kita ke dalam image, lalu menyalin istioctl dari tahap build ke /usr/local/bin (sehingga dapat dipanggil oleh aplikasi kita), mendapatkan dependensi, mengompilasi kode, dan menetapkan CMD menjadi "istiowatcher"

Menulis burst.yaml

Ini adalah file yang akan diterapkan istiowatcher saat permintaan/detik ke worker dari frontend melebihi 15.

Buat file baru bernama burst.yaml dan masukkan kode berikut ke dalamnya.

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

Menulis natural.yaml

Kami akan menganggapnya sebagai status "alami" yang akan kami kembalikan saat permintaan/detik dari frontend ke worker turun di bawah 10. Dalam status ini, 100% traffic dialihkan ke cluster primary.

Buat file baru bernama natural.yaml dan masukkan kode berikut ke dalamnya

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

Mem-build dan Mendorong istiowatcher

Jalankan perintah berikut untuk mengirim direktori saat ini ke Google Cloud Build (GCB), yang akan mem-build dan memberi tag pada image di GCR.

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

Men-deploy istiowatcher

Beralih ke direktori kubernetes

cd ${proj}/kubernetes/

Menulis file deployment: istiowatcher.yaml

Buat file bernama istiowatcher.yaml dan masukkan kode berikut (Ganti <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

Deploy

Pastikan kita berjalan di cluster utama

kubectx primary

Men-deploy istiowatcher.yaml di namespace istio-system

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

Hal yang penting untuk diperhatikan adalah perintah serviceAccountName dan automountServiceAccountToken dalam yaml. Tindakan ini memberi kita kredensial yang diperlukan untuk menjalankan istioctl dari dalam cluster.

Kita juga perlu men-deploynya dalam namespace istio-system untuk memastikan kita memiliki kredensial untuk istio-pilot-service-account. (tidak ada di namespace default).

Lihat traffic beralih secara otomatis.

Sekarang saatnya momen ajaib! Mari kita buka frontend dan tingkatkan permintaan/detik menjadi 20

Perhatikan bahwa perlu waktu beberapa detik, tetapi kami meningkatkannya dan semua hash kami memiliki awalan "bursty-".

Hal ini karena kita mengambil sampel prometheus di rentang 15s yang membuat waktu respons sedikit tertinggal. Jika menginginkan band yang lebih ketat, kita dapat mengubah kueri ke prometheus menjadi 5s.

18. Apa langkah selanjutnya?

Pembersihan

Anda tidak perlu melakukan pembersihan jika menggunakan akun sementara yang disediakan untuk workshop ini.

Anda dapat menghapus cluster Kubernetes, aturan firewall, dan image di 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

Rencana ke Depan