Micro-service mimarisi kullanan servisler ile birlikte dünyamıza giren bir diğer kavram da Service Discovery oldu. Servislerin Dinamik olarak ölçeklendirilmesi, sisteme sürekli olarak yeni servislerin eklenip çıkarılması micro-service tabanlı mimarinin operasyonel anlamda zorlaşmasına sebep oldu. Service discovery nedir diyecek olursak micro-servislerin en büyük sorunu olan monitoring ve management süreçlerine aranan çözümlerdir. Consul ise bunu en sade ve etkili bir şekilde yapan açık kaynak araçlardan biridir.
Consul Kurulumu
Consul tek bir binary dosyasından oluşuyor. Server için de Client sistemler için de aynı dosyayı kullanıyoruz. Sunucuyu normal başlattıktan sonra diğer node’ları join komutu ile bağlıyoruz.
consul agent -server -bootstrap -data-dir /tmp/consul -ui -client 0.0.0.0 -retry-join 192.168.1.102 -retry-join 192.168.1.104 -retry-join 192.168.1.105 -bind 192.168.1.109
Buradaki -bootstrap parameteresi consul’u tek sunucu ile çalıştırmak için gerekli. Normal koşullar altında sistemin sürekli olarak çalışabilmesi için (high availability) en az 3 sunucu üzerine server olarak kurulum yapmamız gerekiyor. 3 sunucu birbirine bağlandığında raft protokolü ile aralarında birini lider olarak seçiyorlar ve artık tüm kritik işlemler bu sunucu üzerinden yapılıyor. -bootstrap
parametresi ile test amaçlı kurulumlarda bu süreci iptal edip doğrudan tek sunucu ile işlemlere başlayabiliyoruz.
İlk sunucuyu bu şekilde kurduktan sonra diğer server sistemler üzerinde aşağıdaki komutları çalıştırarak bu sunucuya bağlanabiliyoruz:
consul agent -server -data-dir /tmp/consul -ui -client 0.0.0.0 -retry-join 192.168.1.102 -retry-join 192.168.1.104 -retry-join 192.168.1.105 -bind 192.168.1.107
Bu komutla yine sunucu olarak bağlandığımızı unutmayalım. Tavsiye edilen sunucu sayısı 3 ya da 5. Tek sayı olması raft ile concensus yapılmasını kolaylaştırıyor. 5 ten fazla node ise gereksiz bir trafik oluşturuyor. 3 node ile kurulan server clusterlarında 1 node, 5 node ile kurulanlarda ise 2 node’luk tolerans seviyemiz oluyor. Yani anlık olarak 1-2 sunucunun offline olması sistemin çalışmasını engellemiyor. Bunların yerine yeni sunucu ekleyip otomatik olarak sync edilmesini sağlayabiliyoruz.
Consul ne işe yarar
Consul ile uygulama seviyesinde service discovery yapabiliyoruz. Kendi yazdığımız scriptler ile uygulamamızın çalışıp çalışmadığını kontrol edip Consul sistemine bildirebiliyoruz. Bu sayede sisteme bağlı tüm client ve server sistemler aktif uygulamaların endpointlerini bulabiliyorlar.
Consul örnek parametreler
Öncelikle members komutu ile sistemdeki aktif nodeları sorgulayabiliyoruz. Örnek vermek gerekirse:
Consul’u -client parametresi ile yalnızca istemci olarak çalıştırabiliriz. Bu durumda KV Store ve servis discovery ile ilgili bilgiler sunucuda tutulacak ve consul agent bu sistemde yalnızca raporlama amaçlı çalıştırılacaktır.
consul agent -server -data-dir /tmp/consul -ui -client 0.0.0.0 -bind 192.168.1.107
Consul arkaplanda server sistemler arasındaki uzlaşı için paxos temelli raft protokolünü kullanıyor. Bu alt sisteme operator raft parametresi ile erişebiliyoruz. Bu aşamada artık sunucu seviyesinde discovery yapabiliyoruz. Raft protokolü Consul’un üzerine kurulu olduğu Serf için de kullanıyor. Bir yerde sistemin koordine çalışması için gerekli olan alt yapı gibi düşünebiliriz.
consul operator raft
Bootstrap except parametresi ile sistemi kaç sunucu ile çalışacağını belirtebiliriz. Böylece belirtilen sayıya kadar ulaşmadan sistem başlatılmayacaktır. Kurulum aşamasındaki zorlukları aşmamızda alternatif bir çözüm olarak kullanılabilir.
consul agent -server -bootstrap-expect 1 -data-dir /var/lib/consul -config-dir /etc/consul.d
Config dir parametresi ile birden fazla dosyaya bölünmüş halde ayarları consul sistemine tanıtabiliriz.
consul agent -data-dir /var/lib/consul -config-dir /etc/consul.d
curl ile RPC ve REST apisini kullanarak sistem hakkında ek bilgi edinebiliriz. Alttaki örnekte hangi sunucunun raft protokolü ile leader olarak seçildiğini kontrol edebiliyoruz.
curl http://127.0.0.1:8500/v1/status/leader
Retry join kullanarak client olarak çalışan sistemlerin servera sürekli olarak bağlanmaya çalışacak şekilde yapılandırılmasını sağlayabiliyoruz. Bu seçeneği kullanmadığımızda eğer ilk denemede başarısız olursa sistem kendisini kapatıyor.
-retry-join "consul.domain.internal"
Consul keygen komutu ile sunucu ve client sistemlerin birbiri ile haberleşmek için kullandıkları gossip protokolünü şifrelemek üzere anahtar oluşturabiliyoruz. Tabi bunu config dosyamıza yazmamız gerekiyor. Ya da sistemi çalıştırken -encrypt
parametresini de kullanabiliriz.
consul keygen
Consul örnek configler
/etc/consul.d/config.json
{ "datacenter": "dc1", "data_dir": "/var/consul", "log_level": "INFO", "node_name": "mysql1", "server": true, "bootstrap_expect": 3, "bind_addr": "111.111.111.111", "start_join": ["111.111.111.111"], "encrypt": "iBD2pgX6F1plIff72cyi0A==" }
Consul Güvenlik Ayarları
Consul için belki de en çok kafa karıştıran noktalardan biri güvenlik meselesi. Sistem bir çok alt sistemden oluşuyor ve tüm bunların güvenliğini ayrı ayrı düşünmemiz gerekiyor. Öncelikle sistemdeki tüm client ve server nodelar kendi aralarında iletişim için Hashicorp’un ayrı bir ürünü olan Serf’in alt yapısını kullanıyor. Bu mesajları doğrudan encrypt
parametresine vereceğimiz key ile şifreleyebiliyoruz. Bunun için gerekli key’i de consul keygen
ile oluşturabiliriz.
Sistemler arasındaki en temel mesajlaşmayı şifreledik fakat bu kesinlikle yeterli değil. Yukarıdaki örneklerde curl ile sorgulama yapabildiğimizi gördük. Bu sistem RPC, REST tabanlı olarak çalışıyor ve bunun da şifrelenmesi gerekiyor. Bunun için ACL (
Access Control List) ayrı bir güvenlik sistemi var. Temel olarak ana bir api key üzerinden bir çok api anahtarı oluşturarak http api’de kullanacağımız her isteğe bu keyi ekleme tabanlı bir güvenlik sistemi diyebiliriz. Yapılandırması gossip protokolünden daha zor ama imkansız değil. Gerekli adımları resmi sitedeki https://www.consul.io/docs/guides/acl.html
adresinden inceleyebilirsiniz.
Son önemli adım ise TLS yani sunucular arasındaki HTTP trafiğinin şifrelenmesi. ACL ile apikey ekleyerek izinsiz istek yapılmasını engellesek de Consul gibi dağıtık bir sistemdeki veri dolaşımının güvenliğini sağlayamıyoruz. Yani hattı dinleyen herkes doğrudan apikeyi ele geçirip sisteme sızabilir. Bunu engellemek için TLS bazlı bir güvenlik gerekiyor yani tüm hattı şifrelemek gerekiyor. Consul burada işleri zorlaştırıyor. Sisteme ait her sertifikayı ortak bir CA’dan oluşturmamız ve clientlere bu ayrı sertifikaları yüklememiz gerekiyor. Açıkçası ben burada koptum bence bu pratik bir işlem değil. Bu işlemi kolaşlaştıran Vault adlı yine ücretsiz bir Hashicorp ürünü var. Güvenlik için şu adrese bakabilirsiniz. https://www.consul.io/docs/agent/encryption.html
Consul ile dinamik DNS
Consul’un en büyük özelliklerinden biri de servislerimiz için dinamik DNS kullanabilmektir. dnsmasq ile gerekli ayarları yaptıktan sonra servislerin aktif olup olmama durumuna göre dinamik olarak yanıt veren bir DNS sunucusu elde edebiliyoruz. Dig ile yapılmış örnek bir internal DNS çıktısı şöyle oluyor:
Nomad ile container ve native deployment
Servislerinizi monitor etmek ve discovery ile takip etmek sizin için yeterli değilse ve alternatif bir deployment aracı arıyorsanız Consul’un yapımcısı olan Hashicorp’un nomad aracına göz atabilirsiniz. Kubernetes kadar kapsamlı olmasa da ufak takımların her türlü ihtiyacını görebilecek bir araç ve tüm Hashicorp ekosistemi ile uyumlu çalışıyor.
Tüm bu süreci otomasyona döken otto isimli bir araç daha vardı fakat Hashicorp bu aracı geliştirmekten vazgeçti ve tüm desteği kaldırdı.