💻
Cheet Sheets
  • 🦁Başlarken
  • 🟧DevOps Pre-Requisite
    • ❤️Why Linux? | Linux Basics #1
    • 💛Vi Editor | Linux Basics #2
    • 💙Basics Commands | Linux Basics #3
    • 🧡Package Managers | Linux Basics #4
    • 💚Services | Linux Basics #5
    • 💛Networking Basics
    • 🤎DNS Basics
    • 🩶Applications Basics
    • 🟨Java introduction
    • 🟩NodeJS Introduction
    • 🟦Python Introduction
    • 🟪GIT Introduction
    • 🟧Apache Web Server Introduction
    • ⬛Apache Tomcat
    • 🟫Python Flask
    • 🟥Node.js Express App
    • 🟨Databases
    • 🟩MySQL
    • 🟪MongoDB
    • 🟨SSL & TLS
    • 🟦YAML & JSON - JSON Path
    • ⬛Labs Resources
  • 🍎Kubernetes
    • 🍏Kubernetes: Nedir ?
    • 🍒Bileşenler
    • 🍵Kubectl ve Versiyon
    • ❤️Pod
    • 🏷️Label ve Selector
    • 🔎Annotation
    • 📲Namespaces
    • 📦Deployments
    • 🔁ReplicaSet
    • 🔙Rollout & Rollback
    • 🌐Networking - 1
    • 🌏Service
    • 🛠️Liveness Probe & Readiness Probe
    • 🥐Resource Limits
    • 💰Environment Variables
    • 📃Ephemeral Volumes
    • 🔑Secrets
    • 🌂ConfigMap
    • 🖥️Node Affinity
    • 🔌Pod Affinity
    • ✍️Taint and Toleration
    • 🔦DaemonSet
    • 🧀PV/PVC
    • 🌜Storage Class
    • 🗿StatefulSet
    • 🕹️Job & Cronjob
    • 🔐Authentication
    • 📏Role-based access control (RBAC)
    • 🈷️Service Account
    • 📈Ingress
    • 📂ImagePullPolicy & ImageSecret
    • 📖Static Pods
    • 🌐Network Policy
    • 🫐Helm Nedir?
    • 📽️Prometheus Stack - Monitoring
    • 💼EFK Stack - Monitoring
    • 🥳CRD & Operator
  • 🧑‍⚕️GIT & GITHUB
    • 👉Girizgah
    • 🌴Branch
    • 🤝Merge
    • 🤔Conflict - Rebase
    • 🇸🇴Alias
    • 🛑Gitignore
    • 🥢Diff
    • ◀️Checkout
    • 🔦Stash
    • 👉Other
  • ☁️AWS
    • 🪣S3
    • 🚙EC2
    • ⚖️ELB
    • 🤝Auto Scaling
    • 🗄️EFS
    • 🔐VPC
    • 🎆CloudFront
    • ❤️Route53
    • 🦈RDS
    • 🏢ElastiCache
    • 🔭CloudWatch
    • 👀CloudTrail
    • 📃CloudFormation
    • 🔕SNS
    • 📬SQS
    • 🎇SWF
    • 📧SES
    • 📦Kinesis
    • 📐AWSConfig
    • 👩‍🏭OpsWork
    • 🚀Lambda - Api Gateway
    • 📌ECS - EKS
    • 🔑KMS
    • 📂Directory Service
    • 🏐Snowball
    • 💾Storage Gateway
    • 💽Volume Gateway
    • 📼Tape Gateway
    • 🏠Organizations
    • 🔙Backup-Transfer-CloudShell
    • 🆔IAM
    • 📀DataSync
    • 🗃️FSx
    • 🎒Aurora Serverless
    • 🌐Global Accelerator
    • 💪HPC
    • 🎰Outposts
    • 🗼Others
  • 👨‍🔬Ansible
    • 👉Girizhah
    • 📔YAML
    • ⚙️Komponentler
    • 🎒Inventory
    • 🏑ad-hoc
    • ▶️Playbook
  • 👨‍⚕️PROMETHEUS
    • 📈Terminoloji
    • 🦯Ubuntu 20.04 Prometheus Kurulum
    • 🗒️prometheus.yml dosyasına ilk bakış:
    • 🧭promQL up query
    • 📇Exporters
    • 🔦promQL Data Types
    • 🦯Selectors & Matchers
    • 🔢Binary Operators
    • 💀ignoring and on
    • ✍️Aggregation Operators
    • 🧠Functions
    • 🖊️Alıştırma
    • 💻Client Libraries
    • 🐍Examining the data of our Python application
    • 🐐Examining the data of our GO application
    • ⏺️Recording Rules
    • 💡rate functions
    • ⏰Alerting
    • ⌚Alert Routing
    • ⏰Slack integration with Prometheus
    • 🤯PagerDuty integration with Prometheus
    • ◼️BlackBox exporter
    • 📍Push Gateway
    • 🪒Service Discovery
    • 🧊kube cadvisor with external prometheus
    • 👉aws with prometheus
    • ☁️CloudWatch Exporter
    • 👨‍🚒mysql exporter
    • 🛃Custom exporter with Python
    • ⚙️Prometheus with HTTP API
    • 🤖Prometheus Federation For Kubernetes
    • 📺Grafana
    • ⁉️Prometheus: Ne zaman kullanılmalı? Ne zaman kullanılmamalıdır?
  • 🍪Sheets
    • 🛳️Docker Sheets
    • 🐐Kube Sheets
  • 🔢12 Factor APP
    • 🏗️Introduction
    • 1️⃣Codebase
    • 2️⃣Dependencies
    • 3️⃣Concurrency
    • 4️⃣Processes
    • 5️⃣Backing Services
    • 6️⃣Config
    • 7️⃣Build, release, run
    • 8️⃣Port binding
    • 9️⃣Disposability
    • 🔟Dev/prod parity
    • 🕚Logs
    • 🕛Admin processes
  • ☁️Azure 104
    • 👨‍👨‍👧‍👧Azure Active Directory ( Entra ID )
    • 💰Subscriptions
    • 🌎Virtual Network (VNET)
    • 💻Virtual Machines
    • 🧑‍🌾Load Balancing
    • 🥍Network Advanced
    • 🪡Automating Deployment and Configuration
    • 💂Securing Storage
    • 📓Administering Azure Blobs and Azure Files
    • 🔧Managing Storage
    • 🎁App Service
    • 🛳️Azure Container
    • 🥇Backup And Recovery
    • 🪐Network Watcher
    • ⏰Resource Monitoring And Alerts
  • ⛅AZURE 305
    • 🆔identity and access management
    • 💼Desing Azure AD (Entra ID)
    • 👨‍💼Desing for Azure B2B
    • 🛃Desing for Azure B2C
    • 💳Design for MFA and Conditional Access
    • ⛑️Design for Identity Protection
    • 🚶Access Reviews
    • 🚦Managed identity Demostration
    • 🔐Key Vault Demostration
    • 👑Governance hierarchy
    • 💠Design for Management Groups
    • 🔑Desing for Subscriptions
    • 🍇Desing for resource groups
    • 📟Design for resource tags
    • 🚷Azure Policy & RBAC
    • 🫐Desing For Blueprints
    • 🪡Desing for Virtual Networks
    • 🛫Design for on-premises connectivity to Azure
    • 🔽Design for network connectivity
    • 📦Design for application delivery
    • 🥞Design for network security and application protection
    • 📕Choose a compute solution
    • 🌊Design for virtual machines
    • 🔋Azure Batch Demostration
    • 🛰️Design for Azure App Service
    • ⛲Design for Azure Container Instances
    • 🎢Design for Azure Kubernetes Service
    • 📠Azure Functions Demostration
    • 💪Azure Logic Apps Demostration
    • 🧑‍💼Design for data storage
    • 🎞️Design for Azure storage accounts
    • 🌟Choose the storage replication
    • 📹Azure blob storage - Lifecycle & immutable demo
    • 🥌Azure Files Demostration
    • 🕸️Design Azure disks
    • 🦼Design for storage security
    • 🔮Azure Table Storage And Cosmos DB Demostration
    • 🟧Azure SQL Solutions
    • 🎡Azure SQL Database - Purchasing models
    • 🕯️Database availability
    • 📜Data security strategy
    • 🧮Azure SQL Edge
    • 🚲Azure Data Factory
    • 🔅Azure Data Lake Storage
    • 🧘‍♂️Azure Databricks
    • 🎒Azure Synapse Analytics
    • 🅰️Azure Stream Analytics
    • 📼Data flow strategy
    • 🍥Cloud Adoption Framework
    • ☣️Azure Migration Framework
    • 🦿Assessing workloads
    • 🪡Migration tools
    • 🤖Azure Database migration
    • 👥Storage migration
    • 👜Azure Backup
    • ⏲️Azure Blob Backup and Recovery
    • 💈Azure files backup and recovery
    • 🎞️Azure VM backup and recovery
    • 🧺Azure SQL backup and recovery
    • ⏰Azure Site Recovery
    • 📩Differentiate event and message
    • ✈️Azure messaging solutions
    • 🚜Event Hub
    • 🥍Application optimization solution
    • 🎁Application lifecycle
    • 📺Azure Monitor
    • 🅱️Log Analytics
    • 👥Azure workbooks and Insights
    • 🚌Azure Data Explorer
  • Github Actions
    • Github Actions Nedir?
    • Workflow & Schedule Triggers
    • Single and Multiple Events
    • Manuel Events
    • Webhook Events
    • Conditional Keywords For Steps
    • Expressions - 1
    • Expressions - 2
    • Runners
    • Workflow Commands
    • Workflow Context
    • Dependent Jobs
    • Encrypted Secrets
    • Configuration Variables
    • Default & Custom Env Varb
    • Set Env Varb with Workflow Commands
    • Github Token Secret
    • Add Script to workflow
    • Push Package #1
    • Push Package #2 Docker
    • Service Containers
    • Routing workflow to runner
    • CodeQL Step
    • Caching Package and Dependency Files
    • Remove workflow Artifact
    • Workflow Status Badge
    • Env Protection
    • Job Matrix Configuration
    • Disable & Delete Workflows
    • Actions type for Action
    • Inputs and Outputs for actions
    • Action Versions
    • Files and Directories for Actions
    • Exit Codes
    • Reusable Workflow & Reuse Templates for Actions and Workflows
    • Configure Self Hosted Runners for Enterprise
  • Loki
    • What is Loki?
    • Architecture of Loki
    • Install Loki For Ubuntu
    • Install Promtail For Ubuntu
    • Querying Logs
    • Loki in Kubernetes
    • Deploying Loki in Kubernetes
    • Connecting to Grafana
    • Viewing Kubernetes logs
    • Promtail Customize & Pipeline
  • Ansible
    • Ansible Introduction
    • Introduction to Ansible Configuration Files
    • Ansible Inventory
    • Inventory Formats
    • Ansible Variables
    • Variable Types
    • Registering Variables and Variable Precedence
    • Variable Scoping
    • Magic Variables
    • Ansible Facts
    • Ansible Playbooks
    • Verifying Playbooks
    • Ansible lint
    • Ansible Conditionals
    • Ansible Conditionals based on facts, variables, re-use
    • Ansible Loops
    • Ansible Modules
    • Introduction to Ansible Plugins
    • Modules and Plugins Index
    • Introduction to Handlers
    • Ansible Roles
    • Ansible Collections
    • Introduction to Templating
    • Jinja2 Templates for Dynamic Configs
  • 🅰️Ansible Advanced
    • Playbook run options
    • Facts
    • Configuration files
Powered by GitBook
On this page

Was this helpful?

  1. Kubernetes

StatefulSet

PreviousStorage ClassNextJob & Cronjob

Last updated 2 years ago

Was this helpful?

Kubernetes'in stateless iş yükleri için, uygun bir platform olduğundan, state tutan iş yükleri için ise bir çok problem ile karşılaştığımızdan önceki bölümlerde söz etmiştik.

Ephemeral ve Persistent volume konularında ise, bu sorunları ortadan kaldırmak adına, kullanabileceğimiz objeleri gördük ve işin depolama kısmını çözdük. Ancak stateful uygulamalarda, tek sıkıntımız depolama değil. Bunu çözmüş olsak da, şu ana kadar işlediğimiz obje tipleri diğer sorunlarımızı çözmüyor.

İşte bu durum ile başa çıkmamıza yardımcı olacak obje tipi olan, statefulSet objesinden bahsedeceğiz.

Sorun nedir?

İlk olarak kendimize sorun oluşturalım; 3 pod oluşturacak, bir deployment objesi oluşturduğumuzu düşünelim. Bu deployment objesi, bildiğiniz üzere bir replicaset oluşturuyor ve bu replicaset 'de, bizim belirlediğimiz tanıma göre random isimler verilen, birbirinin aynısı podlar oluşturuyor.

Bu replicaset altında oluşturulan podların, birbirinden farkı yok. Ve bu nedenle kubernetes bunlara eşit davranıyor. Biz bu deployment objesini, yukarı doğru scale ettiğimiz zaman, istediğimiz sayıda yeni pod ekleniyor ve aşağı doğru scale edersek de, bu sefer bu podlardan istediğimiz sayıda pod rastgele olarak siliniyor.

Yani 5 podlu deployment objesini, 3 pod'a indirmek istersek, kubernetes ilk hangisi yaratılmış, hangisi diğerinden önce yaratılmış vb şeylere bakmıyor ve rastgele olarak 2 podu siliyor. Podlar üzerinde herhangi bir state tutulmadığı için bu durum sıkıntı yaratmıyor.

Fakat şöyle bir senaryo da,

Misal, yeni nesil noSQL veritabanlarından birini kubernetes üzerinde deploy etmek istiyoruz. Bu veritabanları hemen, hemen hepsi şu şekilde çalışır. Bir adet master instance bulunur ve bunun üzerinden bir cluster oluşturulur. Ardından bu cluster'a yeni instance'lar ekleriz. Yazma işlemlerini master üzerinden yaparken, sorguları herhangi bir instance'a gönderebilirsiniz.

Tüm veri bu istancelar üstünde dağıtık şekilde durur.

Böyle bir veritabanı alanı olan, apache cassandra 'yı 3 instance'dan oluşacak, bir cluster olacak şekilde şu ana kadar öğrendiğimiz obje tipleri ile kubernetes'e deploy ettiğimizi düşünün,

Bunun için nasıl bir yol izleyeceğiz?

Cassandra master olacak instance'ı deploy edeceğiz, ardından buna bağlanarak yada başlangıç komutları ile cassandra uygulamasını master hale getirecek şekilde, bir cluster oluşturacağız. Sonrasında 2. instance oluşturacağız ve bu 2. instance bağlanıp, 1.instance'daki cassandra cluster'a 2.instance'ı dahil edeceğiz. Ardından 3.instance oluşturup, aynı işlemleri yapacağız. Böylelikle 3. instance ile bir cassandra cluster'mız olacak.

Kubernetes'de nasıl ayağa kaldıracağız?

Bu adımları takip ederek, Kubernetes de nasıl bu uygulamayı ayağa kaldıracağımıza bakalım,

İlk olarak singleton podlar şeklinde deploy etmeyi deneyelim, Master olacak instance oluşturacak pod tanımını yaptık içine PVC tanımı ekledik ki, cassandra verileri tutabilecek, bir PV'ye sahip olabilsin. Pod ayağa kalktı, bunu master hale getirecek komutları, ya başlangıç komutu olarak yada sonrasında bağlanıp hallettik. Ardından 2. pod tanımı daha yaptık, bunu da, 2.instance olarak ayağa kaldırdık. Ardıdan 3.pod tanımını yapıp, ayağa kaldırdık. Ve böylelikle gerekli ayarları yaptıktan sonra, cluster ayağa kalktı.

Ancak burada bir çok sorun var,

-İşlemler manuel ve zahmetli -Singleton podların fail durumunu kontrol eden bir mekanizma yok. -Yeni bir pod eklemek veya çıkarmak istersem, tüm süreci yönetiyorum.

SingletonPod işimize yaramadı, Peki deployment kullansak?

3 adet cassandra podu oluşturacak, deployment objesi oluşturduk ve deploy ettik. Bu deployment objesi 3 adet birbirinin aynısı pod oluşturdu ve hepsine rastgele bir isim verdi. Problem şu ki, hepsi aynı anda oluşturuldu. Ben ilk oluşanı master olarak ayarlamak istesem de, ayarlayamam. Çünkü hepsi, bu sorun dersek, bu işlemleri manuel olarak yapalım. Bağlanıp, birini master'a çevirelim, Diğerlerine de tek, tek bağlanıp cluster'a kattık. Aradan zaman geçti, worker nodelardan birinde sıkıntı oldu ve cassandra podlarından birine erişilemiyor.

Deployment objemiz tarafından yönetildiği için, sıkıntı değil, hemen yeni bir pod oluşturulur. Ama bu yeni pod tamamen rastgele bir isim alacak ve sıfırdan oluşacak. Misal bu bahsettiğimiz pod Master instance olarak ayarladığımız Pod ise ne yapacağız? Cluster bu durumda çökmüş olacak.

Yada şunu düşünün, scale down veya up işlemi yaptığımızda, kubernetes buraya rastgele bir pod ekleyecek veya rastgele olarak içlerinden birini silecek. Bunların hepsi stateless uygulamalar için problem değil, fakat gördüğünüz üzere cluster uygulamaları vb stateful uygulamalardan oluşan clusterlar kurmak istersek, mevcut kubernetes objeleri sıkıntımızı çözmüyor.

Tüm bu sıkıntıları çözmek adına, statefulset adında bir obje mevcuttur.

  • Statefulset tarafından oluşturulan her pod, statefulset tanımında belirlediğimiz PVC'ye göre bir PV'ye sahip olur. Yani her podun kendine ait bir PV'si olur.

  • Statefulset altında, podlar sırayla oluşturulup, sırayla silinir. Misal 3 podlu bir stateful oluşturduğumuz zaman, öncelikle pod0 oluşturulur. Ve bu pod ayağa kalkıp, readiness ve liveness checklerinden geçip, işlemlerini tamamlamadan bir sonraki pod oluşturulmaz. Ne zaman pod hazır ve running duruma geçer, o zaman bir sonraki pod oluşturulur. Aynı şekilde 3.podda 2.pod tamamlanmadan oluşturulmaz. Tam tersi durumda da bu geçerlidir. Biz 3 podlu bir statefulseti 2 poda indirirseniz, kubernetes random bir pod seçip, onu silme yoluna gitmez. En son yaratılan pod hangisi ise, ilk olarak o silinir.

  • Statefulset tarafından oluşturulan her pod'a statefulsetismi-0 1 2 3 şeklinde devam eden, sabit bir isim verilir. İsimler random seçilmez ve bu isimler aynı zamanda containerların hostname olarak da ayarlandığı için, her uygulama bu isimle ulaşabilir.

Statefulset objesi, deployment objesine oldukça benzerdir. Yukarıda bahsettiğim özellikler haricinde aynıdır. Bu özellikler sayesinde, bizlerin stateful uygulamaları deploy etmemiz oldukça kolaylaşır.

Az önceki cassandra örneğini statefulset ile ayağa kaldıracak olursak, 3 pod oluşturacak bir statefulset objesi yaratıp, deploy ettik. Kubernetes hemen ilk podu ayağa kaldırdı. Biz bu poda başlangıç scripti eklemiştik. Bu script ortamda bizim belirlediğimiz isimde cluster var mı? yok mu? bunu kontrol ediyor. Ve yoksa bu isimle bir cluster oluşturuyor. Script çalıştı, ortamda bu isimle cluster olmadığı için, cassandra cluster'ı oluşturuldu. Liveness ve readiness probe tamamlandı ve artık hem cluster, hem de podumuz hazır.

Birinci pod sağlıklı şekilde çalışmaya başladığı anda Kubernetes 2.podu da oluşturmaya başladı, Bu podda da, aynı script var, ama bu sefer ortamda böyle bir cluster mevcut, dolayısıyla yeni bir cluster oluşturmak yerine, bu mevcut cluster'a dahil oldu. Liveness ve readiness probe tamamlandı ve bu pod hazır.

Bu pod'da hazır olduğu için 3.pod da oluşturulmaya başlandı, onda da aynı işlemler uygulandı ve cluster ayağa kalktı.

Şimdi bu podlardan, cassandra-1 podu silinirse, statefulset objesi, aynı podu, aynı isimle tekrar ayağa kaldırıp, aynı PV bu poda atanacak. ve sorun olmayacak.

Yada yeni pod eklersek, yeni identy olacak ve aynı şekilde cluster'a katılacak. Scale down olursa da, herhangi birini seçip, silmek yerine en son oluşturulan silinecek. Gördüğünüz gibi, cassandra cluster oluşturma problemini bu özellikleri sayesinde "statefulset" ile çözebildik.

Örnek statefulset objesi yaml içeriği,

apiVersion: v1
kind: Service
metadata:
  labels:
    app: cassandra
  name: cassandra
spec:
  clusterIP: None
  ports:
  - port: 9042
  selector:
    app: cassandra
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: cassandra
  labels:
    app: cassandra
spec:
  serviceName: cassandra
  replicas: 3
  selector:
    matchLabels:
      app: cassandra
  template:
    metadata:
      labels:
        app: cassandra
    spec:
      terminationGracePeriodSeconds: 1800
      containers:
      - name: cassandra
        image: gcr.io/google-samples/cassandra:v13
        imagePullPolicy: Always
        ports:
        - containerPort: 7000
          name: intra-node
        - containerPort: 7001
          name: tls-intra-node
        - containerPort: 7199
          name: jmx
        - containerPort: 9042
          name: cql
        resources:
          limits:
            cpu: "500m"
            memory: 1Gi
          requests:
            cpu: "500m"
            memory: 1Gi
        securityContext:
          capabilities:
            add:
              - IPC_LOCK
        lifecycle:
          preStop:
            exec:
              command: 
              - /bin/sh
              - -c
              - nodetool drain
        env:
          - name: MAX_HEAP_SIZE
            value: 512M
          - name: HEAP_NEWSIZE
            value: 100M
          - name: CASSANDRA_SEEDS
            value: "cassandra-0.cassandra.default.svc.cluster.local"
          - name: CASSANDRA_CLUSTER_NAME
            value: "K8Demo"
          - name: CASSANDRA_DC
            value: "DC1-K8Demo"
          - name: CASSANDRA_RACK
            value: "Rack1-K8Demo"
          - name: POD_IP
            valueFrom:
              fieldRef:
                fieldPath: status.podIP
        readinessProbe:
          exec:
            command:
            - /bin/bash
            - -c
            - /ready-probe.sh
          initialDelaySeconds: 15
          timeoutSeconds: 5
        volumeMounts:
        - name: cassandra-data
          mountPath: /cassandra_data
  volumeClaimTemplates:
  - metadata:
      name: cassandra-data
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: standard
      resources:
        requests:
          storage: 1Gi

Replicas sayımızı belirtiyor ve label selector'a dikkat ediyoruz. Ardından template kısmında ise, oluşturulmasını istediğimiz pod tanımını giriyoruz. template içeriği kullandığımız image'a göre değişir.

Template kısmı haricinde, en altta "VolumeClaimTemplates" kısmı mevcut. Burada her bir pod için, bu özelliklerde bir PVC oluşturulmasını söylüyoruz. Bu PVClerde standart isimli storage class'ı kullanarak, her bir pod için birer PV oluşturacak.

Yani her podun, aynı PV'ye bağlanması yerine, her pod'a ayrı bir PV oluşturulacak. PVCleri VolumeClaimTemplates ile yaratıyoruz. PVCleri dahi kendimiz manuel olarak oluşturmuyoruz. statefulset objesini oluşturduğumuz zaman, PVC oluşturulacak, PVClerde gidecek PVleri oluşturup, podlara tek, tek bağlayacak.

En üst kısımda "service" tanımı mevcut, gördüğünüz gibi şu ana kadar oluşturduğumuz service tanımına oldukça benzer. Fakat tek fark mevcut, clusterIP=none olarak set edilmiş. Buna headless services diyoruz. Bunu oluşturduğumuz anda, ClusterIP tipinde, bir servis oluşturulacak, Fakat ana bir IP adresi atanmayacak. Bu bize şu konuda yardımcı oluyor; Ben ne zaman, bu servis ismine gitmek istersem, o bana bu servis altındaki podlardan bir tanesinin IP adresini dönecek. Bunun yanında her bir podda da, podismi.serviceismi şeklinde erişme imkanı sağlamış olacak.

🍎
🗿