1. Hoş geldiniz
Google'ın Istio Multi Cloud Burst codelab'ine katıldığınız için teşekkür ederiz.Bu codelab için Kubernetes, Node ve Go ile ilgili başlangıç düzeyinde uygulamalı deneyim gerekir. İhtiyacınız olanlar
|
|
Öğrenecekleriniz
- GKE'de Kubernetes kümesi oluşturma
- Helm ile Kubernetes kümesine Istio'yu yükleme
- Helm ile Istio Multicluster'ı yükleme
- Kaynak koddan Kubernetes'e web uygulaması dağıtma
- Istio'ya trafik yönlendirme kuralları yazma ve uygulama
- Prometheus Metrikleri
- Kubernetes kümesinde kapsayıcı görüntüleri oluşturma ve aktarma
2. Hazırlanma
Bu codelab'i aşağıdaki platformlardan birinde uygulayabilirsiniz:
- Google Cloud Shell (önerilir): Tarayıcı içi kabuk, araçlar yüklü olarak gelir.
- dizüstü bilgisayarınız (aşağıdaki talimatları uygulayın)
Google Cloud Platform'u kullanmaya başlama
- GCP hesabınız yoksa ücretsiz kullanıcı hesabı kartınızı eğitmeninizden alın.
- Google Cloud Console'a gidip "Proje seçin"i tıklayın:

- Projenin "Kimlik" bilgisini bir yere not edin, ardından projeyi seçmek için tıklayın:

1. seçenek: Google Cloud Shell'i kullanma (önerilir)
Cloud Shell, tarayıcınızda komut satırı kabuğu sağlar. Bu kabukta, ihtiyacınız olan araçlar yüklü ve Google Cloud Platform hesabınızda otomatik olarak kimliği doğrulanmış şekilde bulunur. (Bu alıştırmayı Cloud Shell'de çalıştırmak istemiyorsanız bir sonraki bölüme geçin.)
Cloud Console'a gidin ve sağ üstteki araç çubuğunda "Cloud Shell'i Etkinleştir"i tıklayın:

Cloud Shell'e araç ekleme
- Install
kubectx****: Bash komut dosyalarını buradan indirip $PATH'teki bir konuma yükleyin. helm****: Bu talimatları uygulayarak yükleyin.
Alternatif olarak, her ikisini de ~/.bin konumuna yüklemek ve $PATH'inize eklemek için şu komutları çalıştırın:
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'i kullanmayı kolaylaştırabilecek bazı hızlı ipuçları:
1. Kabuğu yeni bir pencereye ayırma: |
|
2. Dosya düzenleyiciyi kullanma: Tarayıcı içi dosya düzenleyiciyi başlatmak için sağ üstteki kalem simgesini tıklayın. Kod snippet'lerini dosyalara kopyalayacağımız için bu özellikten yararlanabilirsiniz. |
|
3. Yeni sekmeler başlatma: Birden fazla terminal istemine ihtiyacınız varsa. |
|
4. Metni büyütme: Cloud Shell'deki varsayılan yazı tipi boyutu okumak için çok küçük olabilir. | Linux/Windows'da Ctrl-+, macOS'te ⌘-+. |
2. seçenek: Dizüstü bilgisayarınızı kurma (önerilmez)
Cloud Shell yerine kendi iş istasyonu ortamınızı kullanmayı tercih ediyorsanız aşağıdaki araçları kurun:
gcloud:'ı yükleyin (Cloud Shell'de önceden yüklenmiştir.) Platformunuzagcloudyüklemek için talimatları uygulayın. Bu bilgiyi Kubernetes kümesi oluşturmak için kullanacağız.- Yükleyin
kubectl:(Cloud Shell'de önceden yüklenmiştir.) Yüklemek için aşağıdaki komutu çalıştırın:
gcloud components install kubectl
gcloud'un kimliğini doğrulamak için aşağıdaki komutu çalıştırın. Google Hesabınızla giriş yapmanız istenir. Ardından, önceden oluşturulmuş projeyi (yukarıda gösterilmiştir) varsayılan proje olarak seçin. (İşlem alt bölgesi yapılandırmayı atlayabilirsiniz):
gcloud init
- Yükleme
curl:Çoğu Linux/macOS sisteminde önceden yüklenmiştir. Büyük olasılıkla bu özelliği zaten kullanıyorsunuzdur. Aksi takdirde, internette nasıl yükleneceğini arayın. - Yükleme
kubectx****: Bash komut dosyalarını buradan $PATH'deki bir konuma indirerek yükleyin. helm****: Bu talimatları uygulayarak yükleyin.
3. GCP projesi oluşturma
Projenizde GKE (Google Kubernetes Engine), GCR (Google Container Registry) ve GCB (Google Cloud Build) API'lerini etkinleştirin:
gcloud services enable \ cloudapis.googleapis.com \ container.googleapis.com \ containerregistry.googleapis.com \ cloudbuild.googleapis.com
Ortam değişkenlerini ayarlama
Kurulum sırasında Google Cloud projemizle yoğun bir şekilde çalışacağız. Bu nedenle, hızlıca başvurmak için bir ortam değişkeni ayarlayalım.
export GCLOUD_PROJECT=$(gcloud config get-value project)
Bu atölye çalışması sırasında bazı kod ve yapılandırma dosyaları oluşturacağız. Bu nedenle, bir proje dizini oluşturalım ve bu dizine geçelim.
mkdir -p src/istio-burst && \ cd src/istio-burst && \ export proj=$(pwd)
4. "Birincil" Kubernetes kümesi oluşturma
Google Kubernetes Engine (GKE) ile kolayca yönetilen Kubernetes kümesi oluşturabilirsiniz.
Aşağıdaki komut bir Kubernetes kümesi oluşturur:
- "primary" adlı,
- us-west1-a bölgesinde,
- Kullanılabilir en yeni Kubernetes sürümü,
- 4 başlangıç düğümüyle
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
(Bu işlem yaklaşık 5 dakika sürebilir. Kümenin oluşturulmasını Cloud Console'da izleyebilirsiniz.
Kubernetes kümesi oluşturulduktan sonra gcloud, kubectl'yi kümeyi işaret eden kimlik bilgileriyle yapılandırır.
gcloud container clusters get-credentials $cluster --zone=$zone
Artık yeni kümenizle kubectl kullanabilirsiniz.
Kümenizin Kubernetes düğümlerini listelemek için aşağıdaki komutu çalıştırın (durum "Hazır" olarak gösterilmelidir):
kubectl get nodes
Kullanım kolaylığı için Kubeconfig adlarını değiştirme
Bağlamlar arasında sık sık geçiş yapacağımız için kümelerimiz için kısa bir takma ad kullanmak işimize yarayacak.
Bu komut, yeni oluşturduğunuz kubeconfig girişinin adını primary olarak değiştirir.
kubectx ${cluster}=gke_${GCLOUD_PROJECT}_${zone}_${cluster}
İzinleri ayarlama:
Istio'yu dağıtmak için küme yöneticisi olmanız gerekir. Bu komut, Google Cloud hesabınızla ilişkili e-postayı küme yöneticisi olarak ayarlar.
kubectl create clusterrolebinding cluster-admin-binding \
--clusterrole=cluster-admin \
--user=$(gcloud config get-value core/account)
5. "Patlama" kümesi oluşturma
Aşağıdaki komut bir Kubernetes kümesi oluşturur:
- "burst" adlı,
- us-west1-a bölgesinde,
- Kullanılabilir en yeni Kubernetes sürümü,
- 1 başlangıç düğümüyle
- 5 düğüme kadar otomatik ölçeklendirme etkinleştirildi
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
(Bu işlem yaklaşık 5 dakika sürebilir. Kümenin oluşturulmasını Cloud Console'da izleyebilirsiniz.
Kubernetes kümesi oluşturulduktan sonra gcloud, kubectl'yi kümeyi işaret eden kimlik bilgileriyle yapılandırır.
gcloud container clusters get-credentials $cluster --zone=$zone
Artık yeni kümenizle kubectl kullanabilirsiniz.
Kümenizin Kubernetes düğümlerini listelemek için aşağıdaki komutu çalıştırın (durum "Hazır" olarak gösterilmelidir):
kubectl get nodes
Kullanım kolaylığı için Kubeconfig adlarını değiştirme
Bu komut, az önce oluşturduğunuz kubeconfig girişini burst olarak değiştirir.
kubectx ${cluster}=gke_${GCLOUD_PROJECT}_${zone}_${cluster}
İzinleri ayarlama:
Istio Remote'u dağıtmak için küme yöneticisi olmanız gerekir. Bu komut, Google Cloud hesabınızla ilişkili e-postayı küme yöneticisi olarak ayarlar.
kubectl create clusterrolebinding cluster-admin-binding \
--clusterrole=cluster-admin \
--user=$(gcloud config get-value core/account)
6. Güvenlik Duvarı Kurallarını Uygulama
İki kümemizin birbirleriyle iletişim kurabilmesi için bir güvenlik duvarı kuralı oluşturmamız gerekir.
Google Cloud Platform'da kümelerimizin iletişim kurmasına izin verecek bir güvenlik duvarı kuralı oluşturmak için aşağıdaki komutları çalıştırın.
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
İki kümemiz de kuruldu ve uygulamamızı ve Istio'yu dağıtmaya hazır.
7. Istio'ya giriş
Istio nedir?
Istio, "hizmetleri bağlamak, güvenli hale getirmek, kontrol etmek ve gözlemlemek" amacıyla kullanılan bir hizmet ağı kontrol düzlemidir. Bunu çeşitli şekillerde yapar ancak öncelikle, dağıtılan Kubernetes Pod'larınızın her birine bir proxy container ( Envoy) ekleyerek yapar. Proxy kapsayıcı, genel amaçlı bir politika ve telemetri merkezi ( Mixer) ile birlikte mikro hizmetler arasındaki tüm ağ iletişimini kontrol eder.

Bu politikalar, Kubernetes dağıtımlarınızdan ve hizmetlerinizden bağımsız olarak uygulanabilir. Bu sayede, Ağ Operatörü ağ etkinliğini gözlemleyebilir, ağ politikalarını kısıtlayabilir, yönlendirebilir veya yeniden yazabilir. Bunun için ilişkili uygulamaların yeniden dağıtılması gerekmez.
Istio'nun desteklediği trafik yönetimi özelliklerinden bazıları şunlardır:
- Devre kesiciler
- Yüzdeye dayalı trafik bölme
- URL yeniden yazma
- TLS sonlandırma
- Durum denetimleri
- Yük dengeleme
Bu atölye çalışmasının amaçları doğrultusunda, yüzdeye dayalı trafik bölme yöntemine odaklanacağız.
Çalışacağımız Istio Terimleri
VirtualService
VirtualService, bir ana makineye erişildiğinde uygulanacak bir dizi trafik yönlendirme kuralını tanımlar.
Ağ geçidi
Ağ Geçidi, gelen veya giden HTTP/TCP bağlantılarını alan, ağın kenarında çalışan bir yük dengeleyicidir. Ağ geçitleri bağlantı noktalarını, SNI yapılandırmalarını vb. belirtebilir.
DestinationRule
DestinationRule, yönlendirme gerçekleştikten sonra bir hizmete yönelik trafik için geçerli olan politikaları tanımlar. Yük dengeleme, sidecar'dan bağlantı havuzu boyutu ve aykırı değer algılama ayarları için yapılandırmayı belirtirler.
Istio Multicluster
İki kümemizi oluştururken primary kümemizin otomatik ölçeklendirme olmadan 4 düğüm, burst kümemizin ise 5 düğüme kadar otomatik ölçeklendirme ile 1 düğüm olduğunu fark etmiş olabilirsiniz.
Bu yapılandırmanın iki nedeni vardır.
İlk olarak, "şirket içi" ortamdan buluta geçiş senaryosunu simüle etmek istiyoruz. Şirket içi bir ortamda, sabit bir altyapınız olduğundan otomatik ölçeklendirme kümelerine erişemezsiniz.
İkincisi, Istio'yu çalıştırmak için minimum gereksinimler 4 düğümlü bir kurulumdur (yukarıda tanımlandığı gibi). Bu durum şu soruyu akla getiriyor: Istio için en az 4 düğüm gerekiyorsa burst kümemiz Istio'yu 1 düğümle nasıl çalıştırabilir? Istio Multicluster, çok daha küçük bir Istio hizmetleri grubu yükler ve politika kurallarını almak ve telemetri bilgilerini yayınlamak için birincil kümedeki Istio yüklemesiyle iletişim kurar.
8. Uygulama Mimarisine Genel Bakış
Bileşenlere Genel Bakış
NodeJS ve Redis kullanarak üç katmanlı bir uygulama dağıtacağız.
Worker
Worker uygulaması NodeJS'de yazılmıştır ve gelen POST HTTP isteklerini dinler, bu isteklerde karma oluşturma işlemi gerçekleştirir ve PREFIX adlı bir ortam değişkeni tanımlanmışsa karma değerinin önüne bu değeri ekler. Karma hesaplandıktan sonra uygulama, sonucu belirtilen Redis sunucusundaki "calculation" kanalında gönderir.
Çok kümeli işlevselliği göstermek için daha sonra PREFIX ortam değişkenini kullanacağız.
Referans için: Bunlar, uygulamanın kullandığı paketlerdir.
body-parser:HTTP isteklerimizi ayrıştırmamıza olanak tanır.cors:Merkezler arası kaynak paylaşımının kullanılmasına izin verir.dotenv:Ortam değişkenlerinin kolayca ayrıştırılmasıexpress:Kolay web sitesi barındırmaioredis:Redis veritabanlarıyla iletişim kurmak için istemci kitaplığımorgan:Güzel bir yapılandırılmış günlük sağlar
Frontend
Ön ucumuz da express kullanarak bir web sayfası barındıran bir NodeJS uygulamasıdır. Kullanıcı tarafından girilen sıklığı alır ve bu sıklıkta worker uygulamamıza istek gönderir. Bu uygulama, "calculation" adlı bir Redis kanalındaki mesajlara da abone olur ve sonuçları bir web sayfasında gösterir.
Uygulama aşağıdaki bağımlılıkları kullanır.
body-parser:HTTP isteklerimizi ayrıştırmamıza olanak tanır.dotenv:Ortam değişkenlerinin kolayca ayrıştırılmasıexpress:Kolay web sitesi barındırmaioredis:Redis veritabanlarıyla iletişim kurmak için istemci kitaplığımorgan:Güzel yapılandırılmış günlükler sağlarrequest:HTTP isteklerinin gönderilmesine izin verir.socket.io:Web sayfasından sunucuya çift yönlü iletişime izin verir.
Bu web sayfası, stil oluşturmak için Bootstrap'i kullanır ve çalıştırıldığında aşağıdaki gibi görünür.

Mimari Diyagramı

Dağıtım Şeması
Son uygulamamızı, oluşturduğumuz iki kümede dağıtacağız. primary kümesinde tüm bileşenler (frontend, worker ve Redis) dağıtılırken burst kümesinde yalnızca worker uygulaması dağıtılır.
İki kümeyi açıklayan bir diyagram aşağıda verilmiştir. Kırmızıyla belirtilen kutular Kubernetes Hizmetleri, maviyle belirtilenler ise Kubernetes Dağıtımlarıdır. Sarı kutular, Istio'nun yüklenmesini gösterir.
burst kümesinde Redis için dağıtım olmamasına rağmen kümede Redis için bir hizmet dağıtıldığını fark edin. Kubernetes DNS'nin isteği çözümleyebilmesi için bu hizmetin kümede olması gerekir. Ancak istek gerçekten yapıldığında Istio Proxy, isteği primary kümesindeki Redis dağıtımına yeniden yönlendirir.
Son uygulamada, primary kümesinde çalışan ek bir Dağıtım olacak ve bu Dağıtım istiowatcher. olarak adlandırılacak. Bu Dağıtım, trafiğimiz belirli bir eşiği aştığında trafiği otomatik olarak burst'ye dinamik olarak yönlendirmemize olanak tanıyacak.

9. Uygulama dağıtım dosyaları oluşturma
Uygulamamızı dağıtmak için bir dizi Kubernetes manifesti oluşturmamız gerekiyor.
Projenin kök dizinine geçin ve kubernetes adlı yeni bir klasör oluşturun.
mkdir ${proj}/kubernetes && cd ${proj}/kubernetes
frontend.yaml dosyasını yazın
Bu işlem, ön uç görüntümüze erişmek için hem Kubernetes dağıtımı hem de hizmeti oluşturur.
Aşağıdakileri frontend.yaml içine ekleyin.
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 içinde dikkat edilmesi gereken önemli noktalar
- Uygulamanın çalışacağı bağlantı noktası
8080olarak belirtildi. - Çalışanın adresini "
http://worker-service" olarak ayarladık ve ortaya çıkan hizmeti çözümlemek için Kubernetes'in yerleşik DNS özelliğini kullanacağız. REDIS_URLadresini "redis-cache-service:6379" olarak ayarladık ve ortaya çıkan IP adreslerini çözümlemek için Kubernetes'in yerleşik DNS özelliğini kullanacağız.- Ayrıca, Kubernetes'i container'ın ne zaman çalışır durumda olduğu konusunda bilgilendirmek için container'a
livenessvereadinessprobları ayarladık.
worker-service.yaml dosyasını yazma
Bu hizmeti birden fazla kümede yeniden kullanacağımız için Kubernetes hizmet tanımını dağıtım tanımından ayrı bir dosyada yazıyoruz ancak her küme için farklı bir dağıtım yazacağız.
worker-service.yaml içine aşağıdakileri ekleyin.
apiVersion: v1
kind: Service
metadata:
name: worker-service
spec:
type: ClusterIP
selector:
app: worker
ports:
- name: http
port: 80
targetPort: 8081
Write worker-primary.yaml
Bu, birincil kümeye göndereceğimiz worker dağıtımı olacak.
Aşağıdakileri worker-primary.yaml içine ekleyin.
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"
Burada, uygulamamızın kullanması için liveness ve readiness yoklamaları sağlamanın yanı sıra PORT ve REDIS_URL ortam değişkenlerini belirtme konusunda aynı kalıbı izlediğimizi görüyoruz.
Bu dağıtımda dikkat edilmesi gereken bir diğer nokta ise PREFIX ortam değişkeninin olmamasıdır. Bu nedenle, hesaplama sonuçlarımız ham karma değerler (ön ek içermeyen) olacaktır.
Bu dağıtımın son önemli noktası cluster-type: primary-cluster etiketidir. Bunu daha sonra Istio çok kümeli ortamında trafik yönlendirme yaparken kullanacağız.
redis.yaml dosyasını yazın
Çalışanımızdan ön uca iletişim bir Redis kanalı üzerinden gerçekleşir. Bu nedenle, kümemize bir Redis uygulaması dağıtmamız gerekir.
redis.yaml içine aşağıdakileri ekleyin.
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: {}
Bu, bir Redis uygulamasının yarı standart dağıtımıdır. redis:alpine görüntüsüne dayalı bir kapsayıcı oluşturur, uygun bağlantı noktalarını kullanıma sunar ve makul kaynak sınırları belirler.
redis-service.yaml dosyasını yazın
Redis uygulamamızla iletişim kurmak için bir Kubernetes hizmetine ihtiyacımız var.
redis-service.yaml içine aşağıdakileri ekleyin.
apiVersion: v1
kind: Service
metadata:
name: redis-cache-service
spec:
type: ClusterIP
selector:
app: redis-cache
ports:
- port: 6379
targetPort: 6379
Bu, Redis dağıtımımıza erişmek için redis-cache-service adlı bir hizmet sağlar.
10. Uygulamayı dağıtma
Görüntülerimiz GCR'ye gönderildi ve Kubernetes manifestlerimiz yazıldı. Bu aşamada uygulamamızı dağıtıp nasıl çalıştığını görmemiz iyi olacaktır.
Uygulamayı dağıtmak için aşağıdaki komutları çalıştırın
- Doğru kümede olduğumuzdan emin olun.
kubectx primary
- Redis önbelleğini dağıtma
kubectl apply -f redis.yaml
- Redis hizmetini dağıtma
kubectl apply -f redis-service.yaml
- Ön ucu dağıtma
kubectl apply -f frontend.yaml
- Çalışanı Dağıt
kubectl apply -f worker-primary.yaml
- Worker Service'i dağıtma
kubectl apply -f worker-service.yaml
Uygulamamızı GKE'ye dağıttık. Tebrikler!
Test etme
Kapsüllerin internete bağlanmasını bekleyin.
kubectl get pods -w
Tüm pod'lar "Running" (Çalışıyor) durumuna geldiğinde Ctrl + C tuşlarına basın.
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
Ön uç uygulamamızı LoadBalancer aracılığıyla kullanıma sunmadığımızı fark edeceksiniz. Bunun nedeni, daha sonra uygulamaya Istio üzerinden erişeceğiz. Her şeyin çalışır durumda olduğunu test etmek için kubectl port-forward. dağıtımının çalıştığı bağlantı noktası 8080'e yerel (veya Cloud Shell) makinenizdeki bağlantı noktası 8080'i yönlendirmek üzere aşağıdaki komutu çalıştıracağız.frontend
kubectl port-forward \
$(kubectl get pods -l app=frontend -o jsonpath='{.items[0].metadata.name}') \
8080:8080
Yerel olarak çalıştırıyorsanız: Bir web tarayıcısı açın ve http://localhost:8080 adresine gidin.
Cloud Shell'de çalışıyorsanız: "Web Önizlemesi" düğmesini tıklayın ve "8080 numaralı bağlantı noktasında önizle"yi seçin.

Ön ucu görmeniz gerekir. "Sıklık" kutusuna bir sayı girerseniz karma işaretlerinin görünmeye başladığını görürsünüz.

Tebrikler, her şey hazır!
Bağlantı noktasının yönlendirilmesini durdurmak için Ctrl+C tuşuna basın.
11. Dağıtılan Uygulamayı Temizleme
Kümemize Istio'yu uygulayacak ve ardından uygulamamızı yeniden dağıtacağız. Bu nedenle, önce mevcut uygulamamızı temizleyelim.
Oluşturduğunuz tüm dağıtımları ve hizmetleri silmek için aşağıdaki komutları çalıştırın.
redis-cache-serviceöğesini sil
kubectl delete -f redis-service.yaml
redisöğesini sil
kubectl delete -f redis.yaml
frontendöğesini sil
kubectl delete -f frontend.yaml
workeröğesini sil
kubectl delete -f worker-primary.yaml
worker-serviceöğesini sil
kubectl delete -f worker-service.yaml
12. Birincil kümeye Istio'yu yükleme
Istio'yu edinme
Istio'nun sürümleri GitHub'da barındırılır. Aşağıdaki komutlar, istio'nun 1.0.0 sürümünü indirip paketi açar.
- Projenizin kökünü değiştirme
cd ${proj}
- Arşivi indirme
curl -LO https://github.com/istio/istio/releases/download/1.0.0/istio-1.0.0-linux.tar.gz
- Arşivi çıkarma ve kaldırma
tar xzf istio-1.0.0-linux.tar.gz && rm istio-1.0.0-linux.tar.gz
Istio şablonu oluşturma
Aşağıdaki Helm komutunu çalıştırdığınızda, Istio'yu kümenize yüklemek için şablon oluşturulur.
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
Bu işlem, geçerli dizininizde Istio'yu dağıtmak ve çalıştırmak için gereken tüm tanımları ve özellikleri içeren istio-primary.yaml adlı bir dosya oluşturur.
İki --set parametresine dikkat edin. Bu hizmetler, Istio sistemine Prometheus ve ServiceGraph desteği ekler. Prometheus hizmetini laboratuvarın ilerleyen bölümlerinde kullanacağız.
Istio'yu dağıtma
Istio'yu dağıtmak için öncelikle Istio dağıtımlarının ve hizmetlerinin çalışabileceği istio-system adlı bir ad alanı oluşturmamız gerekir.
kubectl create namespace istio-system
Son olarak, Helm ile oluşturduğumuz istio-primary.yaml dosyasını uygulayın.
kubectl apply -f istio-primary.yaml
Varsayılan etiket ad alanı
Istio, dağıtımlarınızın her birine yardımcı proxy hizmeti yerleştirerek çalışır. Bu işlem, katılım esasına göre yapılır. Bu nedenle, Istio'nun yardımcı dosyayı otomatik olarak yerleştirebilmesi için default ad alanımızı istio-injection=enabled ile etiketlememiz gerekir.
kubectl label namespace default istio-injection=enabled
Tebrikler! Uygulamamızı dağıtmaya hazır, Istio'nun etkin olduğu bir kümemiz var.
13. Uygulamamızı Istio Trafik Yönetimi ile Dağıtma
Istio Trafik Yönetimi Yapılandırma Dosyaları Oluşturma
Istio, yapılandırma için YAML dosyalarını kullandığından Kubernetes'e benzer şekilde çalışır. Bu bağlamda, trafiğimizi nasıl kullanıma sunacağımızı ve yönlendireceğimizi Istio'ya bildiren bir dizi dosya oluşturmamız gerekir.
istio-manifests adlı bir dizin oluşturun ve bu dizine geçin.
mkdir ${proj}/istio-manifests && cd ${proj}/istio-manifests
frontend-gateway.yaml dosyasını yazın
Bu dosya, Kubernetes kümemizi GKE LoadBalancer'a benzer şekilde kullanıma sunar ve tüm gelen trafiği ön uç hizmetimize yönlendirir.
frontend-gateway.yaml adlı bir dosya oluşturun ve aşağıdakileri ekleyin.
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 dosyasını yazın
redis-virtualservice.yaml adlı bir dosya oluşturun ve aşağıdakileri ekleyin.
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 dosyasını yazın
worker-virtualservice.yaml adlı bir dosya oluşturun ve aşağıdakileri ekleyin.
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 trafik yönetimi politikalarını dağıtma
Istio politikalarının dağıtımı, diğer Kubernetes kaynaklarıyla aynı şekilde yapılır. kubectl apply
- Ağ geçidimizi uygulama
kubectl apply -f frontend-gateway.yaml
- Redis VirtualService'imizi uygulama
kubectl apply -f redis-virtualservice.yaml
- Worker VirtualService'imizi uygulama
kubectl apply -f worker-virtualservice.yaml
Uygulamayı Dağıt
kubernetesdizinimize geri dönme
cd ${proj}/kubernetes
- Redis önbelleğini dağıtma
kubectl apply -f redis.yaml
- Redis hizmetini dağıtma
kubectl apply -f redis-service.yaml
- Ön ucu dağıtma
kubectl apply -f frontend.yaml
- Çalışanı Dağıt
kubectl apply -f worker-primary.yaml
- Worker Service'i dağıtma
kubectl apply -f worker-service.yaml
Doğrula
Bu noktada uygulamamızı Istio ve trafik yönetimi politikaları içeren bir kümeye yeniden dağıttık.
Tüm iş yüklerimizin çevrimiçi olmasını bekleyelim
Tümü internete bağlandıktan sonra frontend-ingressgateway.yaml içinde yapılandırdığımız IngressGateway'i alın.
$ 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> adresine göz atın veya curl komutunu çalıştırın. Ardından ön ucu görmeniz gerekir.
$ curl 35.199.158.10
<!doctype html>
<html>
<head>
<title>String Hashr</title>
<!-- Bootstrap -->
...
14. "Burst" kümesine Istio'yu yükleme
primary kümemizde kurulum ve dağıtım yapmak için çok zaman harcadık ancak dağıtım yapacağımız başka bir kümemiz daha var.
Bu bölümde, her iki kümemizdeki yapılandırma değişkenlerini almamız gerekecek. Bu nedenle, her komut için hangi kümeye yönlendirildiğimize dikkat edin.
Istio Remote Manifest'i oluşturma
Istio'yu primary kümesine dağıtırken yaptığımız gibi, istio remote'u burst kümesine dağıtmak için Helm'i kullanacağız. Ancak bunu yapabilmemiz için primary kümemiz hakkında bazı bilgiler almamız gerekiyor.
Birincil küme bilgilerini toplama
primary kümesine geçiş
kubectx primary
Aşağıdaki komutlar, birincil kümedeki çeşitli pod'lerin IP adreslerini alır. Bunlar, Istio Remote tarafından birincil kümeyle iletişim kurmak için kullanılır.
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}')
Uzak Şablon Oluşturma
Şimdi helm komutunu kullanarak istio-remote-burst.yaml adlı bir dosya oluşturacağız. Bu dosyayı daha sonra burst kümesine dağıtabiliriz.
Proje köküne geçme
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'u genişleme kümesine yükleme
Istio'yu burst kümemize yüklemek için primary kümesine yüklerken uyguladığımız adımları izlememiz gerekir ancak bunun yerine istio-remote-burst.yaml dosyasını kullanmamız gerekir.
kubecontext'i burst olarak değiştirme
kubectx burst
istio-system ad alanını oluşturun
kubectl create ns istio-system
Apply istio-burst.yaml (istio-burst.yaml dosyasını uygula)
kubectl apply -f istio-remote-burst.yaml
Etiket varsayılan ad alanı
Bir kez daha, proxy'nin otomatik olarak yerleştirilebilmesi için default ad alanını etiketlememiz gerekiyor.
kubectl label namespace default istio-injection=enabled
Tebrikler! Bu noktada burst kümesinde Istio Remote'u kurmuş oluyoruz. Ancak bu noktada kümeler hâlâ iletişim kuramaz. İkisi arasında bağlantı oluşturmak için burst kümesi için bir kubeconfig dosyası oluşturmamız ve bu dosyayı primary kümesine dağıtmamız gerekir.
"Burst" kümesi için kubeconfig oluşturma
Patlama kümesine geçiş
kubectx burst
Ortamı ayarlama
Küme için kubeconfig dosyası oluşturmak üzere küme hakkında bazı bilgiler toplamamız gerekiyor.
- Kümenin adını alma
CLUSTER_NAME=$(kubectl config view --minify=true -o "jsonpath={.clusters[].name}")
- Küme sunucusunun adını alma
SERVER=$(kubectl config view --minify=true -o "jsonpath={.clusters[].cluster.server}")
istio-multihizmet hesabı sertifika yetkilisi için gizli dizinin adını alma
SECRET_NAME=$(kubectl get sa istio-multi -n istio-system -o jsonpath='{.secrets[].name}')
- Önceki gizli dizide depolanan sertifika yetkilisi verilerini alma
CA_DATA=$(kubectl get secret ${SECRET_NAME} -n istio-system -o "jsonpath={.data['ca\.crt']}")
- Önceki gizli dizide depolanan jetonu alma
TOKEN=$(kubectl get secret ${SECRET_NAME} -n istio-system -o "jsonpath={.data['token']}" | base64 --decode)
Kubeconfig dosyası oluşturma
Tüm bu ortam değişkenleri ayarlandıktan sonra kubeconfig dosyamızı oluşturmamız gerekir.
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
Bu işlem, geçerli dizininizde burst-kubeconfig adlı yeni bir dosya oluşturur. Bu dosya, primary kümesi tarafından burst kümesinin kimliğini doğrulamak ve kümeyi yönetmek için kullanılabilir.
Birincil kümeye geri dönme
kubectx primary
Bir gizli anahtar oluşturup etiketleyerek "burst" için kubeconfig'i uygulama
kubectl create secret generic burst-kubeconfig --from-file burst-kubeconfig -n istio-system
Istio'nun çok kümeli kimlik doğrulama için kullanacağını bilmesi için gizli anahtarı etiketleyin.
kubectl label secret burst-kubeconfig istio/multiCluster=true -n istio-system
Tebrikler! Her iki kümenin de kimliği doğrulanmış ve Istio Multicluster aracılığıyla birbirleriyle iletişim kuruyor olması gerekir. Uygulamamızı kümeler arası dağıtalım
15. Kümeler Arası Uygulama Dağıtma
Dağıtımlar Oluşturma
kubernetes dizinine geçin.
cd ${proj}/kubernetes
"Burst" kümesi için çalışan dağıtımı oluşturma: worker-burst.yaml
worker-burst.yaml adlı bir dosya oluşturun ve içine aşağıdakileri ekleyin:
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-"
Bu dosyanın, daha önce oluşturduğumuz worker-primary.yaml dosyasıyla neredeyse aynı olduğuna dikkat edin. İki temel fark vardır.
İlk önemli fark, "bursty-" değerine sahip PREFIX ortam değişkenini eklemiş olmamızdır.
env:
- name: PORT
value: "8081"
- name: REDIS_URL
value: "redis-cache-service:6379"
- name: PREFIX
value: "bursty-"
Bu, burst kümesindeki çalışanımızın gönderdiği tüm karma değerlerin başına "bursty-" ön ekini ekleyeceği anlamına gelir. Bu ön eki, uygulamamızın gerçekten kümeler arası olduğunu anlamak için kullanabiliriz.
İkinci önemli fark ise bu dağıtımdaki cluster-type etiketini primary-cluster yerine burst-cluster olarak değiştirmiş olmamızdır.
labels:
app: worker
cluster-type: burst-cluster
Bu etiketi daha sonra VirtualService'imizi güncellerken kullanacağız.
Istio Hizmetlerini Değiştirme
Şu anda Istio hizmetlerimiz dağıtımlarımızın ikisinden de yararlanmıyor. Trafiğimizin% 100'ü "birincil" kümeye yönlendiriliyor. Bu durumu değiştirelim.
istio-manifests dizinimize geçin.
cd ${proj}/istio-manifests
worker-virtualservice.yaml dosyasını DestinationRules'u içerecek şekilde düzenleyin
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: worker-virtual-service
spec:
hosts:
- worker-service
gateways:
- mesh
http:
- route:
- destination:
host: worker-service.default.svc.cluster.local
subset: primary
port:
number: 80
weight: 50
- destination:
host: worker-service.default.svc.cluster.local
subset: burst
port:
number: 80
weight: 50
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: worker-destination-rule
spec:
host: worker-service
trafficPolicy:
loadBalancer:
simple: RANDOM
subsets:
- name: primary
labels:
cluster-type: primary-cluster
- name: burst
labels:
cluster-type: burst-cluster
VirtualService'imize ikinci bir hedef eklediğimizi görebilirsiniz. Aynı ana makineye (worker-service.default.svc.cluster.local)) referans vermeye devam ediyor ancak trafiğin% 50'si primary alt kümesine, diğer% 50'si ise burst alt kümesine yönlendiriliyor.
primary alt kümesini, cluster-type: primary-cluster etiketine sahip dağıtımlar, burst alt kümesini ise cluster-type: burst-cluster etiketine sahip dağıtımlar olarak tanımladık.
Bu sayede trafiğimiz iki küme arasında 50/50 oranında etkili bir şekilde bölünür.
Kümeye Dağıt
redis-service.yaml dosyasını patlama kümesine dağıtın.
burst kubeconfig olarak değiştirme
kubectx burst
Projemizin kök dizinine geçin.
cd ${proj}
Ardından dağıtın.
redis-service.yaml dosyasını burst kümesine dağıtın
kubectl apply -f kubernetes/redis-service.yaml
worker-burst.yaml dosyasını seri işlem kümesine dağıtın
kubectl apply -f kubernetes/worker-burst.yaml
worker-service.yaml dosyasını burst kümesine dağıtın
kubectl apply -f kubernetes/worker-service.yaml
Istio VirtualService'leri uygulama
primary kubeconfig olarak değiştirme
kubectx primary
Ardından Dağıt'ı tıklayın.
kubectl apply -f istio-manifests/worker-virtualservice.yaml
Çalıştığını Doğrulama
Çalıştığını doğrulamak için Istio Ingress noktanıza göz atın ve karma değerlerin yaklaşık% 50'sinin "burst-" ile başladığını fark edin.

Bu, kümeler arası iletişimin başarıyla sağlandığı anlamına gelir. Farklı hizmetlerdeki ağırlıkları değiştirmeyi ve worker-virtualservice.yaml dosyasını uygulamayı deneyin. Bu, kümeler arasındaki trafiği dengelemenin harika bir yoludur ancak bunu otomatik olarak yapabilirsek ne olur?
16. Prometheus metriklerinden yararlanma
Prometheus'a Giriş
Prometheus, başlangıçta SoundCloud'da oluşturulan açık kaynaklı bir sistem izleme ve uyarı araç setidir. Metrik adı ve anahtar/değer çiftleriyle tanımlanan zaman serisi verileri içeren çok boyutlu bir veri modeli kullanır.
Referans olarak Prometheus mimari şemasını aşağıda bulabilirsiniz:

Prometheus ile dağıtılan Istio, çeşitli metrikleri Prometheus sunucusuna otomatik olarak bildirir. Bu metrikleri kullanarak kümelerimizi anında yönetebiliriz.
Prometheus metriklerimizi keşfetme
Başlamak için Prometheus dağıtımını kullanıma sunmamız gerekir.
GKE'de İş Yükleri sekmesine gidin ve "prometheus" iş yüküne ayrıntılı olarak bakın.

Dağıtımın ayrıntılarını görüntülerken İşlemler -> Göster'e gidin.

9090 bağlantı noktasına yönlendirmeyi seçin ve "Yük dengeleyici" yazın.

"Expose"u (Göster) seçin.
Bu işlem, Prometheus metriklerimizi keşfetmek için kullanabileceğimiz, herkese açık bir IP adresinde bir hizmet oluşturur.
Uç noktanın çalışır duruma gelmesini bekleyin ve çalışır duruma geldiğinde "Harici uç noktalar"ın yanındaki IP adresini tıklayın. 
Artık Prometheus kullanıcı arayüzünü görüyor olmalısınız.

Prometheus, kendi atölyesi olacak kadar çok metrik sağlar. Şimdilik istio_requests_total metriğini inceleyerek başlayacağız.
Bu sorguyu yürütmek bir dizi veri döndürür. Bu metrikler, Istio hizmet ağından geçen tüm isteklerle ilgilidir ve bu isteklerin sayısı çok fazladır. İlgilendiğimiz öğeleri filtrelemek için ifademizi şu şekilde değiştiririz:
Hedef hizmetin worker-service.default.svc.cluster.local, kaynağın ise frontend-deployment olduğu istekler son 15 saniyeyle sınırlıdır.
Bu sorgu şu şekilde görünür:
istio_requests_total{reporter="destination",
destination_service="worker-service.default.svc.cluster.local",
source_workload="frontend-deployment"}[15s]
Ayrıca, üzerinde çalışabileceğimiz çok daha yönetilebilir bir veri kümesi sunar.

Ancak yine de biraz yoğun. Tüm istekleri değil, saniye başına düşen istek sayısını öğrenmek istiyoruz.
Bunu elde etmek için yerleşik rate işlevini kullanabiliriz.
rate(istio_requests_total{reporter="destination",
destination_service="worker-service.default.svc.cluster.local",
source_workload="frontend-deployment"}[15s])

Bu, bizi hedefe yaklaştırıyor ancak bu metrikleri biraz daha azaltarak mantıksal bir grupta toplamamız gerekiyor.
Bunu yapmak için sonuçlarımızı gruplandırmak ve toplamak üzere sum ve by anahtar kelimelerini kullanabiliriz.
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)

Mükemmel! Prometheus'tan tam olarak ihtiyacımız olan metrikleri alabiliriz.
Son Prometheus sorgumuz
Öğrendiklerimiz ışığında Prometheus'a sormamız gereken son sorgu şudur:
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)
Artık metriği almak için HTTP API'lerini kullanabiliriz.
Aşağıdaki gibi bir HTTP GET isteği göndererek sorgumuzu kullanarak API'lerini sorgulayabiliriz. <prometheus-ip-here> yerine kendi IP'nizi girin.
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\)
Örnek yanıt:
{
"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"
]
}
]
}
}
Şimdi metrik değerimizi JSON'dan çıkarabiliriz.
Temizleme
Prometheus'u kullanıma sunmak için kullandığımız hizmeti silmemiz gerekiyor. Google Cloud Console'da, yeni oluşturduğumuz hizmetin en üstüne gidin ve "Sil"i tıklayın.

Sonraki Adımlar:
Trafiğin küme içinde nasıl ve hangi hızda hareket ettiğini keşfetmenin bir yolunu bulduktan sonraki adımımız, periyodik olarak Prometheus'u sorgulayan küçük bir ikili program yazmaktır. worker için saniye başına istek sayısı belirli bir eşiğin üzerine çıkarsa tüm trafiği burst kümesine göndermek için çalışan sanal hizmetimizde farklı hedef ağırlıkları uygularız. Saniyedeki istek sayısı daha düşük bir eşiğin altına düştüğünde tüm trafiği primary'ya geri gönderin.
17. Küme Arası Patlama Oluşturma
Ayarlar
Çalışan hizmeti için tüm trafiği birincil kümeye ayarlama
worker-service için hedeflenen ve primary kümesine yönlendirilen tüm trafiği uygulamamızın "varsayılan" durumu olarak kabul edeceğiz.
$proj/istio-manifests/worker-virtualservice.yaml öğesini aşağıdaki gibi görünecek şekilde düzenleyin.
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 kümesine bağlı olduğunuzdan emin olun.
kubectx primary
istio-manifests/worker-virtualservice.yaml dosyasını uygulayın
kubectl apply -f istio-manifests/worker-virtualservice.yaml
Write istiowatcher daemon (İstiowatcher daemon'ı yaz)
Bu hizmeti yazarken hız ve taşınabilirlik özellikleri nedeniyle Go programlama dilini kullanacağız. Uygulamanın genel akışı, başlatma ve her saniyede Prometheus'a sorgu gönderme şeklinde olacaktır.
src içinde istiowatcher adlı yeni bir dizin oluşturun.
mkdir -p ${proj}/src/istiowatcher && cd ${proj}/src/istiowatcher
Küme içinden Istio kontrol düzlemini değiştirmek için istioctl numaralı telefonu container'ımızdan arayacağız.
istiowatcher.go yazın
Bu dizinde istiowatcher.go adlı bir dosya oluşturun ve aşağıdaki kodu bu dosyaya ekleyin.
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 yazma
Dockerfile adlı yeni bir dosya oluşturun ve içine aşağıdakileri ekleyin.
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"]
Bu çok kademeli Dockerfile, ilk aşamada Istio'nun 1.0.0 sürümünü indirip ayıklar. İkinci aşamada, dizinimizdeki her şey görüntüye kopyalanır, ardından derleme aşamasındaki istioctl, /usr/local/bin'ye kopyalanır (böylece uygulamamız tarafından çağrılabilir), bağımlılıklar alınır, kod derlenir ve CMD, "istiowatcher" olarak ayarlanır.
burst.yaml dosyasını yazın
Bu, frontend tarafından worker adresine gönderilen saniyedeki istek sayısı 15'i aştığında istiowatcher dosyasının uygulanacağı anlamına gelir.
burst.yaml adlı yeni bir dosya oluşturun ve içine aşağıdakileri ekleyin.
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 dosyasını yazın
Bu durumu, frontend ile worker arasındaki saniyedeki istek sayısı 10'un altına düştüğünde döndüğümüz "doğal" durum olarak kabul ederiz. Bu durumda trafiğin% 100'ü primary kümesine yönlendirilir.
natural.yaml adlı yeni bir dosya oluşturun ve içine aşağıdakileri ekleyin
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
Build and Push istiowatcher
Mevcut dizini Google Cloud Build'e (GCB) göndermek için aşağıdaki komutu çalıştırın. GCB, görüntüyü GCR'de oluşturup etiketler.
gcloud builds submit -t gcr.io/${GCLOUD_PROJECT}/istiowatcher
istiowatcher'ı dağıtma
kubernetes dizinimize geçin.
cd ${proj}/kubernetes/
Dağıtım dosyası yazma: istiowatcher.yaml
istiowatcher.yaml adlı bir dosya oluşturun ve aşağıdaki kodu ekleyin (<your-project-id> yerine proje kimliğinizi girin).
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
Dağıt
Birincil kümede çalıştığımızdan emin olun
kubectx primary
istiowatcher.yaml öğesini istio-system ad alanında dağıtın
kubectl apply -n istio-system -f istiowatcher.yaml
Yaml dosyasındaki serviceAccountName ve automountServiceAccountToken yönergelerinin önemli olduğunu unutmayın. Bu, küme içinden istioctl çalıştırmak için gereken kimlik bilgilerini bize verir.
Ayrıca, istio-pilot-service-account için kimlik bilgilerine sahip olduğumuzdan emin olmak amacıyla bunu istio-system ad alanında dağıtmamız gerekiyor. (default ad alanında mevcut değil).
Trafiğin otomatik olarak değişmesini izleyin.
Şimdi büyülü anı yaşayalım. Ön uca gidip saniyedeki istek sayısını 20'ye çıkaralım.
Bu işlemin birkaç saniye sürdüğünü ancak tüm karma işlemlerimizin "bursty-" ön ekiyle başladığını fark edebilirsiniz.
Bunun nedeni, 15s aralığında Prometheus örneklemesi yapmamızdır. Bu durum, yanıt süremizin biraz gecikmesine neden olur. Çok daha dar bir bant istiyorsak sorgumuzu prometheus olarak değiştirebiliriz. 5s.
18. Sırada ne var?
Temizleme
Bu atölye çalışması için sağlanan geçici bir hesap kullanıyorsanız temizlik yapmanız gerekmez.
Kubernetes kümelerinizi, güvenlik duvarı kuralını ve GCR'deki görüntüleri silebilirsiniz.
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
Geleceğe Yönelik
- Istio Talks'a katılın.
- Sertifikayı alın: Kubernetes ve Istio ile bir sonraki uygulamanızı oluşturun
- Keynote: Kubernetes, Istio, Knative: The New Open Cloud Stack - Aparna Sinha, Group Product Manager for Kubernetes, Google
- Eğitim: Istio'yu kullanma - Lee Calcote ve Girish Ranganathan, SolarWinds
- Istio - The Packet's-Eye View - Matt Turner, Tetrate
- Is Istio the Most Next Gen Next Gen Firewall Ever Created? - John Morello, Twistlock
- Istio belgelerini okuyun.
- Istio Çalışma Grupları'na katılın.
- Twitter'da @IstioMesh hesabını takip edin.




