Orta 90 dakika 05.02.2024

Docker ve Kubernetes: Temel Eğitim

Container teknolojileri ve orchestration araçları hakkında kapsamlı eğitim. Docker kullanımı, image oluşturma ve Kubernetes temelleri.

docker kubernetes container devops orchestration

Docker ve Kubernetes

Docker Temelleri

Docker Kurulumu

# Ubuntu
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

# Kullanıcıyı docker grubuna ekle
sudo usermod -aG docker $USER

Temel Docker Komutları

# Image çek
docker pull nginx:latest

# Container çalıştır
docker run -d -p 80:80 --name webserver nginx

# Çalışan containerları listele
docker ps

# Tüm containerları listele
docker ps -a

# Container'ı durdur
docker stop webserver

# Container'ı sil
docker rm webserver

# Image'ları listele
docker images

# Image sil
docker rmi nginx:latest

Dockerfile Oluşturma

# Dockerfile
FROM ubuntu:20.04

RUN apt-get update && apt-get install -y \
    nginx \
    curl \
    && rm -rf /var/lib/apt/lists/*

COPY index.html /var/www/html/

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]

Image Build Etme

# Image oluştur
docker build -t myapp:1.0 .

# Image'ı çalıştır
docker run -d -p 8080:80 myapp:1.0

Docker Compose

# docker-compose.yml
version: "3.8"

services:
  web:
    image: nginx:latest
    ports:
      - "80:80"
    volumes:
      - ./html:/usr/share/nginx/html
  
  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: myapp
    volumes:
      - db_data:/var/lib/mysql

volumes:
  db_data:

# Başlat
docker-compose up -d

# Durdur
docker-compose down

Kubernetes Temelleri

Minikube Kurulumu

# Minikube kur
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube

# Başlat
minikube start

# Kubectl kur
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo install kubectl /usr/local/bin/

Deployment Oluşturma

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80

# Deploy et
kubectl apply -f deployment.yaml

# Durumu kontrol et
kubectl get deployments
kubectl get pods

Service Oluşturma

# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: LoadBalancer

# Uygula
kubectl apply -f service.yaml
kubectl get services

Docker Gelişmiş Konular

Docker Volume Yönetimi

# Volume oluştur
docker volume create myvolume

# Volume listele
docker volume ls

# Volume bilgisi
docker volume inspect myvolume

# Volume ile container çalıştır
docker run -d -v myvolume:/data nginx

# Bind mount kullanımı
docker run -d -v /host/path:/container/path nginx

# Named volume kullanımı
docker run -d -v volume_name:/data nginx

Docker Network Yönetimi

# Network oluştur
docker network create mynetwork

# Network listele
docker network ls

# Network'e container ekle
docker run -d --network=mynetwork nginx

# Container'ı network'e bağla
docker network connect mynetwork container_name

# Network'ten ayır
docker network disconnect mynetwork container_name

# Network bilgisi
docker network inspect mynetwork

Docker Multi-Stage Build

# Dockerfile (Multi-stage)
FROM node:16 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

Docker Health Check

# Dockerfile
FROM nginx:alpine
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost/ || exit 1
EXPOSE 80

Docker Best Practices

  • Küçük Base Image: Alpine Linux gibi küçük image'lar kullanın
  • Layer Caching: Sık değişmeyen dosyaları önce kopyalayın
  • .dockerignore: Gereksiz dosyaları exclude edin
  • Multi-stage Build: Production image'ı küçük tutun
  • Non-root User: Container'ı root olmayan kullanıcı ile çalıştırın
  • Health Checks: Container sağlığını izleyin

Docker Compose Gelişmiş Kullanım

Environment Variables

# docker-compose.yml
version: "3.8"

services:
  web:
    image: nginx
    environment:
      - ENV_VAR=value
    env_file:
      - .env
    ports:
      - "${PORT:-80}:80"

Dependencies ve Health Checks

# docker-compose.yml
version: "3.8"

services:
  db:
    image: postgres:13
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5

  web:
    image: nginx
    depends_on:
      db:
        condition: service_healthy
    ports:
      - "80:80"

Docker Compose Override

# docker-compose.yml (production)
version: "3.8"
services:
  web:
    image: nginx:latest

# docker-compose.override.yml (development)
version: "3.8"
services:
  web:
    volumes:
      - ./src:/app
    command: npm run dev

Kubernetes Gelişmiş Konular

ConfigMap ve Secrets

# ConfigMap oluştur
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  database_url: "postgresql://localhost:5432/mydb"
  log_level: "info"

# Secret oluştur
apiVersion: v1
kind: Secret
metadata:
  name: app-secret
type: Opaque
data:
  username: YWRtaW4=  # base64 encoded
  password: cGFzc3dvcmQ=

# Deployment'ta kullan
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  template:
    spec:
      containers:
      - name: app
        image: myapp:latest
        env:
        - name: DB_URL
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: database_url
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: app-secret
              key: password

Persistent Volumes

# PersistentVolume oluştur
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-data
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /data

# PersistentVolumeClaim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-data
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi

# Deployment'ta kullan
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  template:
    spec:
      containers:
      - name: app
        image: myapp:latest
        volumeMounts:
        - name: data
          mountPath: /data
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: pvc-data

Horizontal Pod Autoscaler

# HPA oluştur
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: myapp-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: myapp
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70

Ingress Controller

# Ingress oluştur
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: myapp-service
            port:
              number: 80

Pratik Projeler

Proje 1: Web Uygulaması Dockerfile

# Multi-stage Dockerfile
FROM node:16-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build

FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
HEALTHCHECK --interval=30s --timeout=3s \
  CMD wget --quiet --tries=1 --spider http://localhost/ || exit 1
CMD ["nginx", "-g", "daemon off;"]

Proje 2: Full Stack Docker Compose

# docker-compose.yml
version: "3.8"

services:
  frontend:
    build: ./frontend
    ports:
      - "3000:3000"
    depends_on:
      - backend
    environment:
      - REACT_APP_API_URL=http://backend:5000

  backend:
    build: ./backend
    ports:
      - "5000:5000"
    depends_on:
      - db
    environment:
      - DATABASE_URL=postgresql://user:pass@db:5432/mydb

  db:
    image: postgres:13
    environment:
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=pass
      - POSTGRES_DB=mydb
    volumes:
      - db_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U user"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  db_data:

Proje 3: Kubernetes Production Deployment

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: app
        image: myapp:latest
        ports:
        - containerPort: 80
        resources:
          requests:
            memory: "128Mi"
            cpu: "100m"
          limits:
            memory: "256Mi"
            cpu: "200m"
        livenessProbe:
          httpGet:
            path: /health
            port: 80
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /ready
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
  name: myapp-service
spec:
  selector:
    app: myapp
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: LoadBalancer

Alıştırmalar ve Ödevler

  1. Dockerfile Optimizasyonu: Mevcut bir Dockerfile'ı optimize edin (multi-stage build, layer caching)
  2. Docker Compose Stack: WordPress, MySQL ve phpMyAdmin içeren bir stack oluşturun
  3. Kubernetes Deployment: 3 replica'lı bir web uygulaması deploy edin
  4. ConfigMap ve Secret: Uygulama yapılandırmasını ConfigMap ve Secret ile yönetin
  5. Persistent Storage: Veritabanı için persistent volume oluşturun
  6. Auto-scaling: HPA ile otomatik ölçeklendirme yapılandırın
  7. Ingress: Birden fazla servisi tek bir domain altında yayınlayın
  8. Health Checks: Liveness ve readiness probe'larını yapılandırın

Best Practices

  • Image Tagging: Production'da spesifik tag kullanın (latest yerine)
  • Resource Limits: Container'lara memory ve CPU limitleri koyun
  • Security Scanning: Image'ları güvenlik açıkları için tarayın
  • Logging: Centralized logging kullanın (ELK stack, Loki)
  • Monitoring: Prometheus ve Grafana ile izleme yapın
  • Backup: Persistent volume'leri düzenli yedekleyin
  • Disaster Recovery: Multi-region deployment planlayın