8 Temmuz 2020 Çarşamba

DOCKER SWARM ÜZERİNDE TRAEFIK CLOUD LOAD-BALANCER İLE WORDPRESS UYGULAMASI DEPLOY ETME (2)

Bir önceki yazıda wordpress uygulamasının docker-swarm cluster üzerinde nasıl deploy edileceğine değinilmişti. Yapılan örnek ile wordpress uygulaması 3 düğümlü clusterda çalışır hale getirilmiş ve tarayıcı üzerinden herhangi bir swarm nodunun ip adresi ve tcp 80 portuyla erişim sağlanmıştır. Fakat kurulan mimarinin birçok eksiği bulunmaktadır. Bunları sıralayacak olur isek;

- Uygulamaya overlay üzerinden erişim sağlanmaktadır fakat herhangi bir "persistence session" olmadığından, her seferinde uygulama gönderilen http istekleri farklı bir konteynere düşecektir. 
- Uygulama 80 portundan yani http olarak hizmet vermekte olup, tüm trafik şifresiz gerçekleşmektedir. 
-  Docker swarm cluster gelen istekleri konteynere dağıtmaktadır fakat herhangi bir sağlık kontrolü yapmadığından, "down" duruma düşen konteynere http istekleri gitmeye devam edecektir. 

Yukarıda bahsedilen sebeplerden ötürü uygulamanın önüne "reverse-proxy" veya "load balancer" koyma ihtiyacı ortaya çıkmaktadır. Bu açıdan bakıldığında en bilinir load-balancerlar olan nginx veya haproxy çözümü akıllara gelecektir. Fakat bu yazılımlar konteyner ekosistemi için tasarlanmamıştır. Service-discovery, dinamik konfigürasyon gibi özellikleri barındırmadıklarından bunları kullanmak efektif olmayacaktır. Bu sebeple cloud-native load-balancera ihtiyaç duyulmaktadır. Yapılan araştırma ve inceleme neticesinde "traefik" adlı yazılımın konteyner dünyası için tasarlandığı ve bu iş için kullanılabileceği değerlendirilmiştir. Traefik load-balancerını kullanmadan önce traefik load-balancerdan ve temel konseptlerin bahsedelim.

Traefik "open-source" bir edge router  olup kubernetes, docker, AWS, Mesos vb. cluster yapılarıyla doğrudan uyumlu olarak çalışabilmektedir. En faydalı özelliklerinden biri,  servisleri otomatik algılayıp konfigürasyonu ona göre uyarlayabilmesidir. Traefik edge-routerı anlamak için temel kavramlarından bahsedelim:

1- Entrypoint kavramı:  Dış dünyadan gelen istekleri karşılama biriminin adıdır. Örneğin http hizmeti veriyor iseniz, tcp 80'e bind ettiğiniz bir entrypoint gelen istekleri bu porttan  karşılar. Aşağıdaki şekil bunu simule etmektedir.


2- Routers kavramı: Router entrypointten gelen isteği dinler (isteğe bağlı olarak bir veya birden çok entryointten gelen isteği dinleyebilir.) ve gelen isteğe kendi üzerinde daha önce oluşturulan kuralı uygulayarak arka tarafta yer alan servise yönlendirir. Şayet gelen isteğin üzerinde bir oynama yapılacak ise bu isteği middleware birimine yönlendirir. Aşağıdaki şekil bunu simule etmektedir.

3- Middleware kavramı: Middlewareler routerlara bağlı olarak çalışırlar. Routerlardan gelen istekler üzerinde değişiklik yapabilmektedirler. Örneğin gelen isteği (request) ve başlığı (header) değiştirebilir, yeniden yönlendirebilir (redirect), authentication ekleyebilir vb. Kullanımı isteğe bağlıdır.  Aşağıdaki şekil bunu simule etmektedir.
4- Service kavramı: Servisler gelen isteği routerlardan alırlar ve isteklerin hedeflerine nasıl ulaştırılacağını belirlerler. Örneğin isteğin ulaşacağı hizmet sağlayıcılar (provider veya backend), load balance algoritması, sticky session, healt check, cookie ekleme vb. burada belirlenir. Aşağıdaki şekil bunu simule etmektedir.
5- Provider kavramı: Hizmet isteğinin ulaşacağı ve işleneceği son adres olarak tanımlanabilir. Traefik çeşitli providerları desteklemektedir. Örneğin docker, kubernetes, kv, rancher vb. Klasik load-balance yöntemlerinde backend olarak ifade edilen birime de karşılık gelebilir.

Şimdi traefik edge-routerı docker-swarm üzerinde oluşturduğumuz sisteme nasıl adapte edeceğimizi anlatalım:
- Traefik yazılımını da konteyner üzerinde ayağa kaldıracağız ve service discovery özelliğini çalıştırabilmek için docker soketini dinlettireceğiz. Bu sebeple swarm clusterda manager node'da konumlandıracağız. 
- Wordpress uygulama konteynerlerının kontrolünü traefik'e verebilmek için wordpress servisinde labelları kullanacağız. 
- Traefik için iki ayrı konfigürasyon dosyası oluşturulacaktır. Traefik dinamik ve statik olarak iki farklı konfigürasyon seçeneği ile yapılandırılmaktadır . Bazı özellikleri her iki dosyada da yapılandırabiliyor iken bazı özellikleri yalnızca tek bir dosyada tanımlayabilmektesiniz. Bu sebeple iki adet konfigürsayon dosyası kullanılacaktır. Ayrıca dinamik ve statik konfigürasyonu aynı dosya içerisinde tanımlamak mümkün değildir.
    a- Static dosyada provider, entrypoint, log ayarları ve traefik'i gözlemleyeceğiniz web arayüzü yapılandırılacak; dinamik konfigürsayon dosyasının yolu belirtilecek,
    b- Dinamik dosyada ise web sayfası için kullanılacak olan tls sertifika ayarları yapılandırılacaktır. 

Statik yapılandırma dosyası aşağıdaki gibidir:

config-static.yml
--------------------------------------------------------------------------------------------------------------------------
providers:
  docker:
    swarmMode: true
    watch: true
    exposedByDefault: false
    swarmModeRefreshSeconds: 5
    network: "base-network"
  file:
    filename: "/etc/traefik/config-dynamic.yml"
api:
  insecure: true
log:
  level: FATAL
  #  filePath: "/var/log/traefik.log" #traefik loglarını dosyaya yönlendirmek isterseniz bu satırı açabilrisiniz
#
#ENTRYPOINTS#
entryPoints:     # wordpress uygulaması için iki adet entrypoint tanımlanmıştır.
  web:
    address: ':80'
  websecure:
    address: ':443'
--------------------------------------------------------------------------------------------------------------------------
config-dynamic.yml
--------------------------------------------------------------------------------------------------------------------------
#TLS CERTIFICATES#
tls:
  certificates:
    - certFile: /etc/ca-certificates/omer.cer
      keyFile: /etc/ca-certificates/omer.key

Hazırladığımız config dosyalarını traefik konteynerine bind ederek traefiği ayağı kaldırıyoruz.

load-balancer.yml
--------------------------------------------------------------------------------------------------------------------------
#wordpress application
version: "3.8"
services:
  traefik
    image: traefik
    ports:
      - 80:80
      - 443:443
      - 8080:8080 #traefik yönetim paneli erişimi için kullanılacaktır.
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /home/centos/swarm-file/config-static.yml:/etc/traefik/traefik.yml
      - /home/centos/swarm-file/config-dynamic.yml:/etc/traefik/config-dynamic.yml
     - /mnt/docker-swarm/cert:/etc/ca-certificates  #websitesi için kullanılacak olan serfitikaları bind ediyoruz.
    deploy:
      restart_policy:
        condition: any
      mode: replicated
      replicas: 1
      update_config:
        delay: 2s               # 2sn aralıklarla konfigürasyon yenilenecektir.
      placement:
        constraints:
          - "node.role == manager"    #traefik konteynerini manager node'da çalıştırıyoruz. "Best practice" olarak HA (High Availability) traefik için birden çok swarm manager node'unuz olmalı ve traefik konteynerlerini manager nodelarda çalıştırmalısınız.
    networks:
      base-network:

networks:
  base-network:
    external: True

Uygulamanın ssl üzerinden hizmet vermesi için wordpress konteynırları üzerinde ayar yapmak iş yükü ve karmaşık konfigürsayon gerektirir iken, traefik üzerinde kolayca bu işi halledebilirsiniz. Ayrıca konteyner tarafını düşünmeksizin yalnızca traefik üzerinden tüm sertifikalarınızı yönetebilirsiniz. Burada örnek olarak "omer.com" sitesi için openssl ile self-signed sertifika üretip, bu sertifikayı "/mnt/docker-swarm/cert" dizini altına taşıyor ve daha sonra bu alanı traefik konteynerine bind ederek dinamik konfigürsayon dosyasında sertifikaları gösterip trafiğin https olarak akmasını sağlıyoruz. Tüm bunlar için hazırladığımız load-balancer.yml'ı deploy ediyoruz.

~# docker stack deploy -c load-balancer.yml WORDPRESS_LOADBALANCER

Traefik konteynerini  çalıştırdık fakat henüz wordpress konteynerlerini nasıl kontrol altına alacağını kararlaştırmadık. Burada docker swarm providerı kullandığımız için servis "label"larını kullanarak daha önce deploy edilmiş olan wordpress.yml'ı labellarla güncelleyerek traefik2in kontrolü altına alıyoruz. wodpress.yml dosyasına eklenen alanlar kırmızı ile gösterilmiştir.

wordpress.yml
--------------------------------------------------------------------------------------------------------------------------
#wordpress application
version: "3.8"
services:
  wordpress:
    image: wordpress:latest
    depends_on:
      - db
    volumes:
      - /mnt/docker-swarm/wordpress/:/var/www/html/wp-content
    deploy:
      mode: global
     ports: 80:80         #traefik tarafından dış dünyaya portlar expose edileceğinden wordpress expose satırı silinir.
      labels:
        - "traefik.enable=true"   #traefik bu servis için aktif edilir.
        - "traefik.docker.network=base-network" #traefik'in base-network' için çalışması sağlanır.
        - "traefik.http.routers.router-web.entrypoints=web" #router-web adında router' tanımlar ve web entrypointe bağlandığı kararlaştırılır.
        - "traefik.http.routers.router-web.middlewares=redirect-to-https"  #router-web için  redirect-to-https adında middleware tanımlanır.
        - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https" #redirect-to-https middleware'ını kullarak http isteklerini https'e yönlendiriyoruz.
        - "traefik.http.routers.router-websecure.tls=true"  #router-websecure adında  router'ı tanımlanır ve tls enable edilir.
        - "traefik.http.routers.router-websecure.entrypoints=websecure" #https için websecure entrypoint seçilir
        - "traefik.http.routers.router-websecure.rule=Host(`omer.com`)" #router-websecure için kural belirliyoruz.
        - "traefik.http.routers.router-web.rule=Host(`omer.com`)" #router-web için kural belirliyoruz.
        - "traefik.http.services.wordpress.loadbalancer.server.port=80" #wordpress adında servis tanımlıyor ve gelen isteklerin bu servisin arkasında çalışan backend serverların  80.portuna yani wordpress konteynerlerine gönderilmesini sağlıyoruz..
        - "traefik.http.services.wordpress.loadbalancer.sticky=true" 
        - "traefik.http.services.wordpress.loadbalancer.sticky.cookie.name=wp-elif" #sticky sessin için cookie eklenir.
        - "traefik.http.services.wordpress.loadbalancer.healthcheck.port=80" #load-balance yapılan konteynerler için healt-check tanımlanır.
    environment:
      - WORDPRESS_DB_NAME=wordpress
      - WORDPRESS_DB_USER=elif
      - WORDPRESS_DB_PASSWORD=elif
      - WORDPRESS_DB_HOST=db:3306
      - WORDPRESS_TABLE_PREFIX=elif
    networks:
      base-network:

  db:
    .
    .
    .
--------------------------------------------------------------------------------------------------------------------------
wodpress.yml güncellendikten sonra wordpress servisinin bu tanımlar ile çalıması için wordpress servisi güncellenir.

~# docker stack deploy -c wordpress.yml WORDPRESS

Tüm bu işlem  adımları uygulandıktan sonra mimari aşağıdaki gibi düzenlenmiş olacaktır.

Sonuç olarak uygulama artık https üzerinden çalışmaya başlamış, cookie kullanımı ile persistence session özellğine kazanmış, healtcheck ile load-balancing sağlıklı olarak yapılımış ve servis üzerinden yapılacak güncelleme ile konteyner sayısı artırıldığında otomatik olarak traefik yeni oluşan konteynerlere trafiği yönlendirmeye başlayacaktır. Bu yazıda yalnızca traefik edge-routerın docker-swarm üzerinde bir takım özellekleri kullanılmıl olup daha ayrıntılı bilgiye yararlanılan kaynaklar bölümünden ulaşabilirsiniz. İyi çalışmalar.

Yararlanılan Kaynaklar,
[1] https://docs.docker.com/compose/compose-file/
[2] https://docs.traefik.io/







Hiç yorum yok:

Yorum Gönder