1. Hoş geldiniz
Google tarafından sunulan Istio Multi Cloud Burst codelab'e katıldığınız için teşekkürler.Bu codelab'i tamamlamak için Kubernetes, Node ve Go ile ilgili başlangıç düzeyinde uygulamalı deneyime sahip olmanız gerekir. İhtiyacınız olanlar
|
|
Öğrenecekleriniz
- GKE'de Kubernetes kümesi oluşturma
- Helm ile Kubernetes kümesine Istio yükleme
- Istio Multicluster'ı Helm ile yükleme
- Bir web uygulamasını kaynaktan Kubernetes'e 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 yayınlama
2. Hazırlanma
Bu codelab'i şu platformlarda takip edebilirsiniz:
- Google Cloud Shell (önerilen): Tarayıcı içi kabuk, yüklü araçlarla birlikte gelir
- dizüstü bilgisayarınız (aşağıdaki talimatları uygulayın)
Google Cloud Platform ile Başlayın
- GCP hesabınız yoksa eğitmenizden ücretsiz kullanıcı hesabı kartınızı alın.
- Google Cloud Console'a gidip "Proje seçin"i tıklayın:

- Projenin "kimliğini" bir yere not edin, ardından projeyi tıklayarak seçin:

1. Seçenek: Google Cloud Shell'i kullanma (önerilir)
Cloud Shell, tarayıcınızda ihtiyacınız olan araçların yüklü olduğu ve Google Cloud Platform hesabınızla otomatik olarak kimlik doğrulaması yapılan bir komut satırı kabuğu sağlar. (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
- Yükleyin
kubectx****: Buradaki bash komut dosyalarını $PATH içindeki bir konuma indirin. - Yükleme
helm****: Bu talimatları uygulayın.
Alternatif olarak, her ikisini de ~/.bin'e yüklemek ve $PATH değişkeninize 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ğunu yeni bir pencerede ayırın: |
|
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 özelliği faydalı bulacaksınız. |
|
3. Yeni sekmeler başlatın: Birden fazla terminal istemi gerekiyorsa. |
|
4. Metni büyütme: Cloud Shell'daki varsayılan yazı tipi boyutu okunamayacak kadar küçük olabilir. | Linux/Windows'da Ctrl-+, macOS'te ⌘-+ |
2. Seçenek: Dizüstü bilgisayarınızı kurma (önerilmez)
Kendi iş istasyonu ortamınızı Cloud Shell'den daha rahat kullanıyorsanız aşağıdaki araçları ayarlayın:
gcloud:'yi yükleyin (Cloud Shell'e önceden yüklenmiştir.)gcloud'yi platformunuza yüklemek için talimatları uygulayın. Bu dosyayı, Kubernetes kümesi oluşturmak için kullanacağız.kubectl:'yi yükleyin(Cloud Shell'e ö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, varsayılan proje olarak önceden oluşturulmuş projeyi (yukarıda gösterilmiştir) seçin. (İşlem alt bölgesini yapılandırmayı atlayabilirsiniz):
gcloud init
- Yükleme
curl:Çoğu Linux/macOS sistemine önceden yüklenmiştir. Muhtemelen zaten sahipsinizdir. Aksi takdirde, nasıl yükleyeceğinizi internette arayın. kubectx****'yi yükleyin: Buradaki bash komut dosyalarını $PATH içindeki bir konuma indirin.- Yükleme
helm****: Bu talimatları uygulayın.
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 şekilde çalışacağız. Hızlı referans için bir ortam değişkeni ayarlayalım.
export GCLOUD_PROJECT=$(gcloud config get-value project)
Bu atölyede bazı kod ve yapılandırma dosyaları oluşturacağız. Öncelikle bir proje dizini oluşturup oraya 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 yönetilen Kubernetes kümesi oluşturabilirsiniz.
Aşağıdaki komut, bir Kubernetes kümesi oluşturur:
- "primary" adlı,
- us-west1-a bölgesinde,
- Mevcut Kubernetes'in en son sürümü,
- 4 başlangıç düğümü ile
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ümeye işaret eden kimlik bilgileriyle yapılandırır.
gcloud container clusters get-credentials $cluster --zone=$zone
Artık kubectl'yi yeni kümenizle kullanabilirsiniz.
Kümenizin Kubernetes düğümlerini listelemek için aşağıdaki komutu çalıştırın ("Hazır" durumunu göstermelidirler):
kubectl get nodes
Kullanımı kolaylaştırmak için Kubeconfig adlarını değiştirme
Bağlamlar arasında sık sık geçiş yapacağımızdan kümelerimiz için kısa bir takma ad kullanmak kullanışlıdır.
Bu komut, az önce oluşturduğunuz kubeconfig girişini primary olarak yeniden adlandırır.
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. "Burst" kümesi oluşturma
Aşağıdaki komut bir Kubernetes kümesi oluşturur:
- "burst" adlı bir dosya
- us-west1-a bölgesinde,
- Mevcut Kubernetes'in en son sürümü,
- 1 başlangıç düğümü ile
- 5 adede kadar düğüm için 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ümeye işaret eden kimlik bilgileriyle yapılandırır.
gcloud container clusters get-credentials $cluster --zone=$zone
Artık kubectl'yi yeni kümenizle kullanabilirsiniz.
Kümenizin Kubernetes düğümlerini listelemek için aşağıdaki komutu çalıştırın ("Hazır" durumunu göstermelidirler):
kubectl get nodes
Kullanımı kolaylaştırmak 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 birbiriyle 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
Her iki kümemiz de kuruldu ve uygulamamızı ve Istio'yu dağıtmaya hazır.
7. Istio'ya Giriş
Istio nedir?
Istio, "hizmetleri bağlamayı, güvenli hale getirmeyi, kontrol etmeyi ve gözlemlemeyi" amaçlayan bir hizmet ağı kontrol düzlemidir. Bunu çeşitli yöntemlerle yapar ancak temel olarak dağıtılan Kubernetes kapsayıcılarınızın her birine bir proxy kapsayıcısı ( Envoy) ekleyerek yapar. Proxy kapsayıcısı, 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ü, ilişkili uygulamaları yeniden dağıtmadan ağ etkinliğini gözlemleyebilir, ağ politikalarını kısıtlayabilir, yönlendirebilir veya yeniden yazabilir.
Istio'nun desteklediği Trafik Yönetimi özelliklerinden bazıları şunlardır:
- Devre kesiciler
- Yüzdeye dayalı trafik bölme
- Yeniden URL yazma
- TLS sonlandırma
- Durum denetimleri
- Yük dengeleme
Bu atölye çalışmasında, yüzdeye dayalı trafik bölme işlemine odaklanacağız.
Çalışacağımız Istio Şartları
VirtualService
VirtualService, bir ana makine adreslendiğinde uygulanacak bir dizi trafik yönlendirme kuralı tanımlar.
Ağ geçidi
Geçiş noktası, 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ı, SNI yapılandırmaları vb. belirtebilir.
DestinationRule
DestinationRule, yönlendirme yapıldıktan sonra bir hizmete yönelik trafik için geçerli olan politikaları tanımlar. Bunlar; yük dengeleme yapılandırması, yardımcı araçtaki bağlantı havuzu boyutu ve aykırı değer algılama ayarlarını belirtir.
Istio Çoklu Küme
İ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ırma için iki neden vardır.
Öncelikle, "yerinde"den Cloud'a geçiş senaryosunu simüle etmek istiyoruz. Yerleşik bir ortamda, sabit altyapınız olduğu için otomatik ölçeklendirme kümelerine erişiminiz yoktur.
İkinci olarak, Istio'yu çalıştırmak için minimum gereksinim 4 düğümlü bir kurulumdur (yukarıda belirtildiği gibi). Bu da şu soruyu akla getiriyor: Istio en az 4 düğüm gerektiriyorsa burst kümemiz Istio'yu 1 düğümle nasıl çalıştırabilir? Bunun nedeni, Istio Çoklu Küme'nin çok daha küçük bir Istio hizmeti grubunu kurmasıdır. Ayrıca, politika kurallarını almak ve telemetri bilgilerini yayınlamak için birincil kümedeki Istio kurulumuyla iletişim kurar.
8. Uygulama mimarisine genel bakış
Bileşenlere Genel Bakış
NodeJS ve Redis kullanarak üç katmanlı bir uygulama dağıtacağız.
İşçi
İşleyici uygulaması NodeJS'de yazılmıştır ve gelen POST HTTP isteklerini dinler, bunlar üzerinde karma oluşturma işlemi gerçekleştirir ve PREFIX adlı bir ortam değişkeni tanımlanmışsa karma oluşturma işleminin başına bu değeri ekler. Karma oluşturma işlemi tamamlandıktan sonra uygulama, sonucu belirtilen Redis sunucusunda "calculation" kanalına gönderir.
Çok kümeli işlevi göstermek için daha sonra PREFIX ortam değişkenini kullanacağız.
Referans olması amacıyla: Bunlar, uygulamanın kullandığı paketlerdir.
body-parser:http isteklerimizi ayrıştırmamıza olanak tanırcors:Merkezler arası kaynak paylaşımının kullanılmasına izin verirdotenv: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
Kullanıcı arayüzü
Ön uçumuz da express kullanarak bir web sayfası barındıran bir NodeJS uygulamasıdır. Kullanıcı tarafından girilen bir sıklığı alır ve worker uygulamamıza bu hızda 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ırdotenv: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 isteği göndermeye izin verirsocket.io:Web sayfasından sunucuya iki yönlü iletişime olanak tanır
Bu web sayfasında stil için Bootstrap kullanılmıştır ve sayfa çalıştırıldığında aşağıdaki gibi görünür.

Mimari Diyagramı

Dağıtım Diyagramı
Son uygulamamızı, oluşturduğumuz iki kümeye dağıtacağız. primary kümesinde tüm bileşenler (frontend, worker ve Redis) dağıtılır ancak burst kümesinde yalnızca worker uygulaması dağıtılır.
Aşağıda, iki kümeyi açıklayan bir şema verilmiştir. Kırmızıyla belirtilen kutular Kubernetes Hizmetleri, mavi olanlar ise Kubernetes Dağıtımları'dır. Sarı kutular, Istio'yu yüklediğimizi gösterir.
burst grubunda Redis dağıtımı olmamasına rağmen Redis hizmetinin dağıtıldığına dikkat edin. Kubernetes DNS'nin isteği çözebilmesi için bu hizmetin kümede bulunması gerekir. Ancak istek gerçekten yapıldığında Istio Proxy, isteği primary kümesindeki Redis dağıtımına yeniden yönlendirir.
Nihai uygulamada, primary kümesinde istiowatcher. adlı ek bir dağıtım bulunur. Bu dağıtım, trafiğimiz belirli bir eşiği aştığında trafiği burst'ye otomatik olarak dinamik olarak yeniden yönlendirmemize olanak tanır.

9. Uygulama dağıtım dosyaları oluşturma
Uygulamamızı dağıtmak için bir dizi Kubernetes manifest'i 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ı yazma
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'te dikkat edilmesi gereken önemli noktalar
- Uygulamanın çalışacağı bağlantı noktasını
8080olarak belirttik - İşleyicinin adresini "
http://worker-service" olarak ayarladık ve ortaya çıkan hizmeti çözmek için Kubernetes'in yerleşik DNS özelliğini kullanacağız. REDIS_URLadresimizi "redis-cache-service:6379" olarak ayarladık ve elde edilen IP adreslerini çözümlemek için Kubernetes'in yerleşik DNS özelliğini kullanacağız.- Ayrıca, Kubernetes'in kapsayıcı çalışır durumda olduğunda bilgilendirilmesine yardımcı olmak için kapsayıcıya
livenessvereadinessprobları da ayarladık.
worker-service.yaml dosyasını yazma
Bu hizmeti birden fazla kümede yeniden kullanacağımız ancak her küme için farklı bir dağıtım yazacağımız için Kubernetes hizmet tanımını, dağıtım tanımından ayrı bir dosyaya yazıyoruz.
Aşağıdakileri worker-service.yaml alanına ekleyin
apiVersion: v1
kind: Service
metadata:
name: worker-service
spec:
type: ClusterIP
selector:
app: worker
ports:
- name: http
port: 80
targetPort: 8081
worker-primary.yaml dosyasını yazma
Bu, birincil kümeye göndereceğimiz worker dağıtımı olacaktır.
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, liveness ve readiness probları sağlamanın yanı sıra uygulamamızın kullanacağı PORT ve REDIS_URL ortam değişkenlerini belirtme konusunda aynı kalıbı izlediğimizi görebilirsiniz.
Bu dağıtımda dikkat edilmesi gereken bir diğer nokta da PREFIX ortam değişkeninin olmamasıdır. Bu, hesaplama sonuçlarımızın ham karma oluşturma işlemleri olacağı anlamına gelir (önlerine hiçbir şey eklenmez).
Bu dağıtımın son önemli noktası cluster-type: primary-cluster etiketidir. Bunu daha sonra Istio Çoklu Küme'de Trafik Yönlendirme yaparken kullanacağız.
redis.yaml dosyasını yazma
Çalışanımızdan ön uca olan iletişim bir Redis kanalı üzerinden gerçekleşir. Bu nedenle, kümemize bir Redis uygulaması dağıtmamız gerekir.
Aşağıdakileri redis.yaml alanına 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, Redis uygulamasının yarı standart bir dağıtımıdır. redis:alpine görüntüsüne dayalı bir kapsayıcı oluşturur, uygun bağlantı noktalarını gösterir ve makul kaynak sınırlamaları belirler.
redis-service.yaml dosyasını yazma
Redis uygulamamızla iletişim kurmak için bir Kubernetes Hizmeti'ne ihtiyacımız var
Aşağıdakileri redis-service.yaml alanına 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ı hizmeti sağlar.
10. Uygulamayı dağıtma
Görüntülerimiz GCR'ye gönderilmiş ve Kubernetes manifest'lerimiz yazılmış durumda. Bu noktada uygulamamızı dağıtıp nasıl çalıştığını görebiliriz.
Uygulamayı dağıtmak için aşağıdaki komutları çalıştırın
- Doğru kümede olduğumuzdan emin olma
kubectx primary
- Redis önbelleğini dağıtma
kubectl apply -f redis.yaml
- Redis Hizmeti'ni dağıtma
kubectl apply -f redis-service.yaml
- Ön ucu dağıtma
kubectl apply -f frontend.yaml
- Çalışanı dağıtma
kubectl apply -f worker-primary.yaml
- Çalışan Hizmeti'ni dağıtma
kubectl apply -f worker-service.yaml
Uygulamamızı GKE'ye dağıttık. Tebrikler!
Test
Kapsüllerin internete bağlanmasını bekleyin
kubectl get pods -w
Tüm kapsüller "Ç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ç hizmetimizi bir LoadBalancer üzerinden göstermediğimizi fark edeceksiniz. Bunun nedeni, daha sonra uygulamaya Istio üzerinden erişeceğimizdir. Her şeyin çalışır durumda olduğunu test etmek için kubectl port-forward. kullanacağız. Yerel (veya Cloud Shell) makinenizdeki 8080 numaralı bağlantı noktasını, frontend dağıtımını çalıştıran 8080 numaralı bağlantı noktasına yönlendirmek için aşağıdaki komutu çalıştırın.
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ıştırıyorsanız: "Web Önizlemesi" düğmesini tıklayın ve "8080 bağlantı noktasında önizle"yi seçin.

Ön uçu göreceksiniz. "Sıklık" kutusuna bir sayı girerseniz karma oluşturma işlemlerinin görünmeye başladığını görürsünüz.

Tebrikler, tüm işlemler tamamlandı.
Bağlantı noktasını yönlendirmeyi durdurmak için Ctrl+C simgesine basın.
11. Dağıtılmış Uygulamayı Temizleme
Istio'yu kümemize uygulayacak ve ardından uygulamamızı yeniden dağıtacağız. Bu nedenle, önce mevcut uygulamamızı temizleyelim.
Az önce 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. Istio'yu birincil kümeye 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 paketini açar.
- Projenizin köküne geçme
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 ayıklama 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ırarak Istio'yu kümenize yüklemek için şablonu oluşturun.
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 spesifikasyonları içeren istio-primary.yaml adlı bir dosya oluşturur.
İki --set parametresine dikkat edin. Bu sürümler, 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
Etiketin varsayılan ad alanı
Istio, dağıtımlarınızın her birine yardımcı dosya proxy hizmeti ekleyerek çalışır. Bu işlem etkinleştirme esasına göre yapılır. Bu nedenle, Istio'nun bizim için otomatik olarak yan aracı ekleyebilmesi 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 ile çalışan 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ı kullandığından Kubernetes'e benzer şekilde çalışır. Bu bağlamda, Istio'ya trafiğimizi nasıl göstereceğini ve yönlendireceğini söyleyen 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ı yazma
Bu dosya, Kubernetes kümemizi GKE LoadBalancer'a benzer bir şekilde kullanıma sunar ve gelen tüm 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ı yazma
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ı yazma
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 uygulayın
kubectl apply -f worker-virtualservice.yaml
Uygulamayı dağıtma
kubernetesdizine geri dönme
cd ${proj}/kubernetes
- Redis önbelleğini dağıtma
kubectl apply -f redis.yaml
- Redis Hizmeti'ni dağıtma
kubectl apply -f redis-service.yaml
- Ön ucu dağıtma
kubectl apply -f frontend.yaml
- Çalışanı dağıtma
kubectl apply -f worker-primary.yaml
- Çalışan Hizmeti'ni 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 online olmasını bekleyelim
Tüm düğümler çevrimiçi olduktan sonra frontend-ingressgateway.yaml
$ kubectl -n istio-system get svc istio-ingressgateway NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE istio-ingressgateway LoadBalancer 10.36.3.112 35.199.158.10 80:31380/TCP,
<EXTERNAL-IP> adresine gidin veya bu adresi curl ile işleyin. Ön ucu göreceksiniz.
$ curl 35.199.158.10
<!doctype html>
<html>
<head>
<title>String Hashr</title>
<!-- Bootstrap -->
...
14. Istio'yu "burst" kümesine yükleme
primary kümemizi ayarlamak ve dağıtmak için çok zaman harcadık ancak dağıtacağı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 gerekir. Bu nedenle, her komut için hangi kümeye yönlendirildiğimize dikkat edin.
Istio uzak manifestini oluşturma
Istio'yu primary kümesine dağıttığımızda olduğu gibi, Istio uzaktan dağıtımını burst kümesine şablonlamak için Helm'i kullanacağız. Ancak bunu yapabilmemiz için primary kümemiz hakkında bazı bilgiler edinmemiz gerekiyor.
Birincil küme bilgilerini toplama
primary kümesine geçme
kubectx primary
Aşağıdaki komutlar, birincil kümedeki çeşitli kapsüllerin IP adreslerini alır. Bunlar, Istio Remote tarafından birincil kümeyle geri 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 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
Burst kümesine Istio Remote'ı yükleme
Istio'yu burst kümemize yüklemek için primary kümesine yüklerken uyguladığımız adımları uygulamamız gerekir. Ancak bunun yerine istio-remote-burst.yaml dosyasını kullanmamız gerekir.
kubecontext değerini burst olarak değiştirme
kubectx burst
istio-system ad alanını oluşturma
kubectl create ns istio-system
istio-burst.yaml dosyasını uygulama
kubectl apply -f istio-remote-burst.yaml
Etiketin varsayılan ad alanı
Proxy'nin otomatik olarak eklenebilmesi için default ad alanını tekrar etiketlememiz gerekir.
kubectl label namespace default istio-injection=enabled
Tebrikler! Bu noktada burst kümesinde Istio Remote'u kurduk. Ancak bu noktada kümeler hâlâ iletişim kuramıyor. burst kümesi için, bunları birbirine bağlamak üzere primary kümesine dağıtabileceğimiz bir kubeconfig dosyası oluşturmamız gerekir.
"burst" kümesi için kubeconfig oluşturma
Burst kümesine geçme
kubectx burst
Ortam oluşturma
Küme için bir 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 sunucusu adını alma
SERVER=$(kubectl config view --minify=true -o "jsonpath={.clusters[].cluster.server}")
istio-multihizmet hesabı sertifika yetkilisinin gizlisinin adını alın
SECRET_NAME=$(kubectl get sa istio-multi -n istio-system -o jsonpath='{.secrets[].name}')
- Önceki gizlilikte depolanan sertifika yetkilisi verilerini alma
CA_DATA=$(kubectl get secret ${SECRET_NAME} -n istio-system -o "jsonpath={.data['ca\.crt']}")
- Önceki gizli anahtarda 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, mevcut dizininizde burst-kubeconfig adlı yeni bir dosya oluşturur. Bu dosya, primary kümesi tarafından burst kümesinin kimliğini doğrulamak ve yönetmek için kullanılabilir.
Birincil kümeye geri dönme
kubectx primary
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ğrulaması için kullanacağını bilmesi amacıyla gizliyi etiketleyin
kubectl label secret burst-kubeconfig istio/multiCluster=true -n istio-system
Tebrikler! Her iki kümenin de kimliği doğrulandı ve Istio Multicluster üzerinden birbirleriyle iletişim kuruyor. Uygulamamızı kümeler arası dağıtalım
15. Kümeler Arası Uygulama Dağıtma
Dağıtım oluşturma
kubernetes dizinine geçin
cd ${proj}/kubernetes
"burst" kümesi için çalışan dağıtımı oluşturun: 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-"
Bunun daha önce oluşturduğumuz worker-primary.yaml ile neredeyse aynı olduğunu fark edin. İki temel fark vardır.
İlk önemli fark, PREFIX ortam değişkenini "bursty-" değeriyle eklememizdir.
env:
- name: PORT
value: "8081"
- name: REDIS_URL
value: "redis-cache-service:6379"
- name: PREFIX
value: "bursty-"
Bu, burst kümesindeki işleyicimizin gönderdiği tüm karma oluşturma işlemlerinin başına "bursty-" ön ekini ekleyeceği anlamına gelir. Bu, uygulamamızın gerçekten kümeler arası olduğunu öğrenmek için kullanabileceğimiz bir özelliktir.
İkinci önemli fark, 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 her iki dağıtımdan da yararlanmıyor. Trafiğimizin% 100'ü "birincil" kümeye yönlendiriliyor. Bunu değiştirelim.
istio-manifests dizinimize geçin
cd ${proj}/istio-manifests
worker-virtualservice.yaml dosyasını DestinationRules'ı içerecek şekilde düzenleme
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 eder ancak trafiğin% 50'si primary alt kümesine, diğer% 50'si ise burst alt kümesine yönlendirilir.
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 eşit olarak bölünür.
Kümeye dağıtma
redis-service.yaml dosyasını patlama kümesine dağıtma
burst kubeconfig olarak değiştirin
kubectx burst
Proje kökümüzü değiştirme
cd ${proj}
Ardından dağıtın
redis-service.yaml dosyasını patlama kümesine dağıtma
kubectl apply -f kubernetes/redis-service.yaml
worker-burst.yaml dosyasını burst kümesine dağıtma
kubectl apply -f kubernetes/worker-burst.yaml
worker-service.yaml dosyasını ani artış kümesine dağıtma
kubectl apply -f kubernetes/worker-service.yaml
Istio VirtualServices'i uygulama
primary kubeconfig olarak değiştirin
kubectx primary
Ardından dağıtın
kubectl apply -f istio-manifests/worker-virtualservice.yaml
İşleyip İşlemediğini Doğrulama
Bu işlemin çalıştığını doğrulamak için Istio giriş noktanıza göz atın ve karmaların yaklaşık% 50'sinin önüne "burst-" eklendiğini fark edin.

Bu, kümeler arası başarıyla konuştuğumuz anlamına geliyor. Farklı hizmetlerdeki ağırlıkları değiştirmeyi ve worker-virtualservice.yaml dosyasını uygulamayı deneyin. Bu, kümeler arasındaki trafiği dengelemek için mükemmel bir yöntemdir. Peki bunu otomatik olarak yapabilseydik ne olurdu?
16. Prometheus metriklerinden yararlanma
Prometheus'a Giriş
Prometheus, başlangıçta SoundCloud'da geliştirilmiş açık kaynak bir sistem izleme ve uyarı aracıdır. Metrik adı ve anahtar/değer çiftleriyle tanımlanan zaman serisi verilerini içeren çok boyutlu bir veri modeli kullanır.
Referans olarak kullanabileceğiniz Prometheus mimari şeması aşağıda verilmiştir:

Prometheus ile dağıtılan Istio, çeşitli metrikleri otomatik olarak Prometheus sunucusuna bildirir. Bu metrikleri kullanarak kümelerimizi anında yönetebiliriz.
Prometheus metriklerimizi keşfetme
Başlamak için Prometheus dağıtımını göstermemiz gerekir.
GKE'deki İş Yükleri sekmesine gidin, "prometheus" iş yüküne gidin.

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

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

Ardından "Expose"i (Belirleme) seçin.
Bu işlem, Prometheus metriklerimizi keşfetmek için kullanabileceğimiz, herkese açık bir IP adresinde bir Hizmet oluşturur.
Uç noktasının çalışmaya başlamasını bekleyin ve çalışmaya başladıktan sonra "Harici uç noktalar"ın yanındaki IP adresini tıklayın 
Şimdi Prometheus kullanıcı arayüzüne bakıyor olmalısınız.

Prometheus, kendi atölyesi olacak kadar yeterli metrik sağlar. Şimdilik istio_requests_total metriğini keşfetmeye başlayacağız.
Bu sorgunun yürütülmesi bir dizi veri döndürür. Istio hizmet ağı üzerinden geçen tüm isteklerle ilgili metriklerdir ve bu çok fazladır. Gerçekten ilgilendiğimiz verilere ulaşabilmek için ifademizi değiştireceğiz:
Hedef hizmeti worker-service.default.svc.cluster.local olan ve kaynağı son 15 saniyeyle sınırlı olan frontend-deployment istekleri
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]
Bu sayede, daha kolay yönetilebilir bir veri kümesiyle çalışabiliriz.

Ancak yine de biraz yoğun. Tüm isteklerin değil, saniye başına 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 biraz daha yaklaştırıyor ancak bu metrikleri mantıklı bir grupta biraz daha azaltmamız gerekiyor.
Bunu yapmak için sum ve by anahtar kelimelerini kullanarak sonuçlarımızı gruplandırıp toplayabiliriz.
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 ihtiyaç duyduğumuz metrikleri alabiliriz.
Son Prometheus Sorgumuz
Tüm öğrendiklerimizle birlikte, 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 API'lerini sorgumuzla sorgulayabiliriz. <prometheus-ip-here> yerine
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"
]
}
]
}
}
Artık metrik değerimizi JSON'dan ayıklayabiliriz.
Temizleme
Prometheus'u göstermek için kullandığımız hizmeti silmemiz gerekiyor. Google Cloud Console'da, yeni oluşturduğumuz hizmetin üst kısmına gidin ve "Sil"i tıklayın.

Sonraki Adımlar:
Trafiğin kümede nasıl ve hangi hızda hareket ettiğini keşfetmenin bir yolunu bulduktan sonra, bir sonraki adımımız prometheus'i düzenli olarak sorgulayan küçük bir ikili dosya yazmak ve worker'e saniye başına gelen istek sayısı belirli bir eşiğin üzerine çıkarsa tüm trafiği burst kümesine göndermek için çalışan sanal hizmetimize farklı hedef ağırlıkları uygulamaktır. Saniye başına istek sayısı daha düşük bir eşiğin altına düştüğünde tüm trafiği primary adresine geri gönderin.
17. Kümeler Arası Patlama Oluşturma
Ayarlar
İşçi hizmetinin tüm trafiğini birincil kümeye ayarlama
worker-service adresine giden ve primary kümesine yönlendirilen tüm trafiği, uygulamamızın "varsayılan" durumu olarak kabul ederiz.
$proj/istio-manifests/worker-virtualservice.yaml öğesini aşağıdaki gibi 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
istiowatcher daemon'ı yazma
Bu hizmeti yazmak için hız ve taşınabilirlik avantajlarından yararlanmak üzere Go'yu kullanacağız. Uygulamanın genel akışı, başlatıldıktan sonra her saniye prometheus'i sorgulamak olacaktır.
src içinde istiowatcher adlı yeni bir dizin oluşturun
mkdir -p ${proj}/src/istiowatcher && cd ${proj}/src/istiowatcher
Istio kontrol düzleminde küme içinden değişiklik yapmak için kapsayıcımızdan istioctl'i çağıracağız.
istiowatcher.go dosyasını yazma
Söz konusu dizinde istiowatcher.go adlı bir dosya oluşturun ve içine aşağıdakileri 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 aşağıdakileri bu dosyaya 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 aşamalı Dockerfile, ilk aşamada Istio'nun 1.0.0 sürümünü indirip açar. İkinci aşamada, dizinimizdeki her şey görüntüye kopyalanır, ardından istioctl derleme aşamasından /usr/local/bin'a 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ı yazma
Bu, frontend'den worker'a saniye başına gelen istek sayısı 15'i aştığında istiowatcher'nin uygulanacağı dosyadır.
burst.yaml adlı yeni bir dosya oluşturun ve aşağıdakileri bu dosyaya 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ı yazma
Bu, frontend ile worker arasındaki saniye başına istek sayısı 10'un altına düştüğünde geri döndüğümüz "doğal" durum olarak kabul edilir. Bu durumda trafiğin% 100'ü primary kümesine yönlendirilir.
natural.yaml adlı yeni bir dosya oluşturun ve aşağıdakileri bu dosyaya 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
istiowatcher'ı derleme ve yayınlama
Mevcut dizini Google Cloud Build'e (GCB) göndermek için aşağıdaki komutu çalıştırın. Bu komut, 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ğıdakileri ekleyin (<proje-kimliğiniz> yerine kendi 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ım
Birincil kümede çalıştığımızdan emin olun
kubectx primary
istiowatcher.yaml'ü istio-system ad alanında dağıtma
kubectl apply -n istio-system -f istiowatcher.yaml
yaml dosyasında serviceAccountName ve automountServiceAccountToken yönergelerinin yer aldığını unutmayın. Bu sayede, istioctl'ü küme içinde çalıştırmak için gereken kimlik bilgilerini elde ederiz.
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 gerekir. (default ad alanında mevcut değildir).
Trafiği otomatik olarak geçişini izleyin.
Şimdi büyülü anı yaşamaya hazır olun. Ön uçumuza gidip saniye başına istek sayısını 20'ye çıkaralım.
Bu işlemin birkaç saniye sürdüğünü fark edeceksiniz. Ancak hızlanır ve tüm karma oluşturma işlemlerinin önüne "bursty-" ön eki eklenir.
Bunun nedeni, prometheus'i 15s aralığında örneklememizdir. Bu da yanıt süremizin biraz gecikmesine neden olur. Daha dar bir bant aralığı isterseniz sorgumuzu prometheus olarak değiştirerek 5s.
18. Sırada ne var?
Temizleme
Bu atölye için sağlanan geçici bir hesap kullanıyorsanız temizleme 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
Sonraki adımlar
- Istio Talks oturumlarına katılın.
- Sertifika Alın: Sonraki Uygulamanızı Kubernetes ve Istio ile Geliştirin
- Açılış Konuşması: Kubernetes, Istio, Knative: Yeni Açık Bulut Grubu - Aparna Sinha, Google'ın Kubernetes Grup Ürün Müdürü
- Eğitim: Istio'yu kullanma - Lee Calcote ve Girish Ranganathan, SolarWinds
- Istio - The Packet's-Eye View - Matt Turner, Tetrate
- Istio, Şimdiye Kadarki En Yeni Nesil Güvenlik Duvarı mı? - John Morello, Twistlock
- Istio belgelerini okuyun.
- Istio Çalışma Gruplarına katılma
- Twitter'da @IstioMesh hesabını takip edin




