2. Deployment ve Istio

Ömer Burak Demirpolat
4 min readAug 31, 2023

--

← Önceki: 1. Istio Service Mesh

Yazının 2. kısmında öncelikle local ortamdaki Kubernetes cluster’ımıza Istio kurulumu yapacağız, seçtiğimiz bir cluster üzerinde istio-injection enable olarak label ekleyeceğiz ve ardından Go ile bir client ve bir server yazacağız. Client belli aralıklar ile server tarafına http istekleri gönderecek ve yanıt alacak daha sonrasında client ve server için Kubernetes deployment ve service objelerini yazacağız.

Bu aşamaların ardından client ve server uygulamalarını Kubernetes objeleri sayesinde cluster’ımız üzerinde deploy edeceğiz.

Burada sonuç olarak beklentimiz Istio’nun bizim eklediğimiz deployment yaml’a istinaden oluşacak pod’ları yakalaması ve bu podların yanına side-car container’ını inject etmesi.

Özetle bu yazı şu aşamalalardan oluşacak.

  • Istio kurulum ve istio-injection
  • Client ve server uygulamalarını yazmak
  • Client ve server için Kubernetes manifestlerini yazmak
  • Istio injection için pod inceleme

Istio kurulumu ve istio-injection

Bu işlem için cihazda kurulu bir cluster olması gerektiğini hatırlatarak devam ediyorum. Local k8s cluster için: https://kind.sigs.k8s.io

Mevcut clusterımıza istio yükleyerek başlayalım.

istioctl install

Şimdi her şey yolunda ise namespace’leri kontrol ederek devam edelim. Istio kendi kubernetes nesnelerini “istio-system” namespace’i altına kuruyor. Bu doğrultuda namespace’leri listeleyerek kontrol edebiliriz.

kubectl get ns

NAME STATUS AGE
default Active 3h54m
istio-system Active 3h49m

Bu komut sonucunda istio-system çıktısını görüyorsak her şey yolunda gidiyor.

Son olarak tüm işlemlerin başarılı olup olmadığını görmek için verify komutunu çalıştırabiliriz.

istioctl verify-install

Her şey yolunda ise sırada istio-injection bulunuyor.

Istio-injection’dan bir önceki yazıda da bahsetmiştim. Istio-injection aslında belirlediğimiz bir namespace için label tanımlama işinden ibaret. Biz bu label’ı tanımladığımızda Istio bu namespace’de yayınlanan uygulamalara side-car ekliyor ve yayınlanan servisleri tespit edip service discovery yapıyor.

Evet ilgili label’ı ekleyelim.

kubectl label namespace default istio-injection=enabled --overwrite

Ben default namespace için istio-injection’u aktif ettim.

Şimdi label eklenmiş mi kontrol edelim.

kubectl get ns --show-labels

NAME STATUS AGE LABELS
default Active 3h53m istio-injection=enabled

Şimdi server uygulamamızı yazarak devam edebiliriz. Basit bir server yazacağız, bir adet endpoint hizmet verecek ve 200 dönecek.

server/main.go

package main

import "net/http"

func main() {
http.HandleFunc("/test", test)
http.ListenAndServe(":8080", nil)
}

func test(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(200)
w.Write([]byte("hi"))
}

Hızlıca bu uygulamayı Dockerize edelim.

server/Dockerfile

FROM golang:1.20
WORKDIR /app
COPY . .
RUN go build -o main main.go
CMD ["./main"]
EXPOSE 8080

Artık bu uygulamadan bir Docker image yaratıp imajı local cluster’ımızın registry’sine atabiliriz.

Dockerfile’ın bulunduğu klasörde:

docker build . -t server:v1

Image yaratıldıktan sonra Kind registry’sine yükleyelim:

kind load docker-image server:v1

Artık Kubernetes objelerini hazırlayabiliriz.

Basit bir yaml hazırlayalım, bu yaml dosyası deployment ve service objesi içerecek.

server/manifest.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
name: server-deployment
labels:
name: server
app: server
version: v1
spec:
replicas: 1
selector:
matchLabels:
name: server
template:
metadata:
labels:
name: server
app: server
version: v1
spec:
containers:
- name: server
image: server:v1
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: server-service
spec:
selector:
name: server
ports:
- protocol: TCP
port: 8080
targetPort: 8080

Deployment dosyası Kubernetes web sitesindeki basit örnek ile nerede ise aynı sadece alışılmışın dışında 2 adet label var, app ve version bunları daha sonra Kiali bölümünde inceleyeceğiz.

Service objesi zaten oldukça açık hedef container’lardaki 8080 portuna isteklerin yönlendirilmesini sağlayacak.

Aynı aşamaları client tarafı için de uygulayacağız.

Şimdi client tarafı için gerekenleri yapalım.

Client uygulamamızın amacı belirli aralıklarla server uygulamasına http istekleri göndermek olacak. Epey basit bir kod:

client/main.go

package main

import (
"fmt"
"io"
"net/http"
"time"
)

func main() {
t := time.NewTicker(time.Second)

for range t.C {
client := &http.Client{}
addr := "http://server-service.default.svc.cluster.local:8080/test"
res, err := client.Get(addr)
if err != nil {
fmt.Printf("error occured while getting %s :%v\n", addr, err)
continue
}
body, _ := io.ReadAll(res.Body)
res.Body.Close()
fmt.Printf("Date: %s Status Code: %d Response Body: %s\n", time.Now().String(), res.StatusCode, string(body))
}
}

Burada dikkat etmemiz gereken tek şey addr değişkeni olacaktır. Istio service adresleri için FQDN kullanıyor. Yani bir service objesine ulaşmak için host şu formatta olmalı:

<svc-name>.<namespace>.svc.cluster.local

Şimdi benzer bir Dockerfile ile client uygulamamızı Dockerize edelim.

client/Dockerfile

FROM golang:1.20
WORKDIR /app
COPY . .
RUN go build -o main main.go
CMD ["./main"]

Client Dockerfile dosyasının bulunduğu dizinde:

docker build . -t client:v1

Client image’ını da kind registry’sine yükleyelim.

kind load docker-image client:v1

Son olarak Client uygulamamızın Kubernetes objesini içeren yaml dosyasını hazırlayalım. Client için sadece Pod objesi yeterli olacaktır.

client/manifest.yaml

apiVersion: v1
kind: Pod
metadata:
name: client
labels:
app: client
version: v1
spec:
containers:
- name: client
image: client:v1

Evet artık client ve server uygulamalarını deploy etmek için hazırız.

kubectl apply -f server/manifest.yaml

Şimdi deploy ettiğimiz server uygulamasını kontrol edelim.

Bu yaptıklarımızın sonucunda beklentimiz istio’nun bu objeleri yakalaması ve hem service discovery gerçekleştirmesi hem de uygulama podlarımızın içerisine side-car container eklemesi olacaktır.

Öncelikli server podlarını kontrol ederek başlayalım.

kubectl get pods

NAME READY STATUS RESTARTS AGE
server-deployment-98df8b777-rgtmm 2/2 Running 0 119s

Burada 2 container gözüküyor, inceleyelim.

kubectl describe pod server-deployment-98df8b777-rgtmm

Çıktıyı incelediğiniz incelediğinizde uygulama container’ı haricinde “istio-proxy” adında bir container daha olduğunu göreceksiniz. Istio-injection’da bir sorun yok gibi duruyor.

Şimdi client uygulamasını oluşturalım ve http isteklerini loglardan inceleyelim.

kubectl apply -f manifest.yml

Podları tekrar listeleyelim.

kubectl get pods


NAME READY STATUS RESTARTS AGE
client 2/2 Running 0 37s
server-deployment-98df8b777-rgtmm 2/2 Running 0 6m50s

Client uygulamamızın da side-car’ı eklenmiş duruyor.

Şimdi client loglarına göz atalım.

kubectl logs client
Date: 2023-08-28 18:17:45.687685297 Status Code: 200 Response Body: hi
Date: 2023-08-28 18:17:46.673205297 Status Code: 200 Response Body: hi
Date: 2023-08-28 18:17:47.676762256 Status Code: 200 Response Body: hi
Date: 2023-08-28 18:17:48.677489798 Status Code: 200 Response Body: hi
Date: 2023-08-28 18:17:49.673319299 Status Code: 200 Response Body: hi

Client uygulamamız server’a başarılı şekilde ulaşabiliyor.

Şimdiye kadar başarılı şekilde Istio kurulumu yaptık, uygulamalarımızı Istio’nun side-car inject edebileceği şekilde yaratabildik.

Uygulamaların ikisi de sağlıklı şekilde çalışıyor, client server uygulamasına Istio üzerinden erişebiliyor.

Bir sonraki yazıda Kiali adlı araç ile Istio objelerini ve Istio üzerindeki ağ trafiğini inceleyceğiz .

→ Sonraki: 3. Kiali ile Istio Ağ Trafiği

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

No responses yet

Write a response