Consul 101

developer-guy
Trendyol Tech
Published in
14 min readMar 29, 2020

--

Merhaba, bu yazımda da bize yol gösterici olacak başlangıç seviyesinde Consul teknolojisinden bahsedeceğim. Terraform yazısında da bahsettiğim gibi bu tip teknolojileri öğrenme sürecine giriştiğimiz bu bilgiyi ekip arkadaşlarımıza nasıl yayabileceğimizi de düşünmek zorundayız aslında bu tip yazıları hazırlanmamızın bir diğer nedeni de bu . Yine bu makale de Hashicorp’ un bize sunduğu Learn Consul serisinin türkçeleştirdiğim bir versiyonu. Bu tip teknolojileri Trendyol bünyesinde nasıl kullandığımız ile ilgili yazıları yavaş yavaş paylaşmaya başladık aslında Trendyol Medium sayfasını takip etmenizi bu konuda öneririm . Ayrıca bu süreçte Config&Secret Management konusunda beraber görev aldığım Onur Yilmaz’ın yazısında da Consul’u bu amaçta nasıl kullandığımızdan bahsetmekte ayrıca Öner Çiller ‘ in bu yazısı da Consul’un kendi ekiplerindeki diğer bir kullanım örneğini göstermekte okumanızı tavsiye ederim.

Consul Nedir ?

• Consul service discovery , konfigürasyon yönetimi ve network segmentetion işlevleri ile tam özellikli bir kontrol paneli sağlayan service mesh çözümüdür.Tüm bu bahsedilen özellikler ihtiyaca göre bireysel(tekil) olarak da kullanılabilir veya tam bir service mesh inşa etmek için beraber de kullanılabilir.

Consul’un anahtar özellikleri şunlardır:

» Service Discovery

• Consul’un clientları api veya mysql gibi servisleri register edebilir ve diğer clientlar da Consul’u verilen servisin sağlayıcılarını discover(keşfetmek) için kullanabilir.DNS veya HTTP kullanarak, uygulamalar bağlı oldukları servisleri kolayca bulabilirler.

» Health Checking

• Consul clientları ya verilen servisle(webserver 200 dönüyor mu?) ya da local node(memory kullanımı %90'ın altında mı?) ile bağlantılı herhangi bir sayıda health checkler sağlayabilir.Bu bilgi operator tarafından clusterın sağlığını monitor(gözlem) etmek için kullanılabilir ve servis discovery componentleri tarafından sağlıksız hostlara trafiğin yönlendirilmemesi için de kullanılır.

» KV Store

• Uygulamalar Consul’un key/value store’undan dynamic configuration, feature flagging , coordination ve leader election gibi pek çok amaç için faydalanabilir.

» Secure Service Communication

• Consul Servislerin mutual TLS connection’ı kurabilmeleri için TLS sertifikaları oluşturup servislere dağıtabilir.”Intensions” hangi servislerin iletişim kurmasına izin verildiğini tanımlamak için kullanılabilir.Complex network topologyleri ve statik firewall ruleları yerine gerçek zamanlı değişebilen “intentions” sayesinde “Service Segmentation” kolayca yönetilebilir.

» Multi Datacenter

• Consul multiple datacenterları destekler.Bu, Consul kullanıcılarının birden fazla bölgede(region) büyümek için ek soyutlama katmanları oluşturma konusunda endişelenmemeleri gerektiği anlamına gelir

How to install Consul ?

Bu linkte de bahsettiği gibi Consul’u kurmak oldukça basit.Ben MacOS üzerinde çalıştığım için brew paket yöneticisi ile basitçe Consul’ un kurulumunu gerçekleştirdim.

$ brew install consul --> install consul$ consul --> verify installation
usage: consul [--version] [--help] <command> [<args>]
Available commands are:
agent Runs a Consul agent
event Fire a new event
...

Basic Architecture of Consul

• Consul dağıtık ve high available(yüksek kullanılabilir,erişilebilir) bir sistemdir.

• Consul’a servis sağlayan her bir node “Consul Agent” çalıştırır.Bu agentın sorumluluğu nodeun kendisi ve node üzerindeki servisler için health check yapmaktır.

• Agentlar bir ya da daha fazla Consul serveri ile konuşabilir.Consul serverlar datanın depolanıp replika edildiği yerdir.Bu sunucuların kendisi bir leader seçer.Consul data kaybına sebep olabilecek fail senaryolarını engelleyebilmek için 1,3 veya 5 sunucu ile çalışmayı önerir.Her datacenter için de Consul serverlarının clusterı önerilir.

• Diğer servisleri veya nodeları discover(keşif) etme ihtiyacı olan infrandaki componentler herhangi bir Consul serverlerini veya Consul agentlarıını sorgulayabilir.Agentlar otomatik olarak sorguları serverlara yönlendirecektir.

• Her datacenter Consul serverlarının clusterını çalıştırır.Cross-datacenter service discovery veya configuration isteği yapıldığında , Consul sunucuları bu isteği remote datacenterlara iletir ve sonucu döner.

Server and Client Agents

• Production sistemlerde çalışırken her bir Consul Agent’ını “server” veya “client” mode çalıştırabiliriz.Her “Consul Datacenter”’ı Consul’un state’ini yönetmekten sorumlu olan bir servera sahip olmalıdır.Ayrıca bu server diğer Consul serverları ve clientları , hangi servislerin(hizmetler) discovery(keşfedilmek) için mevcut olduğunu ve hangi servislerin hangi servislerle konuşmaya izni olduğu gibi bilgileri içerir.

• Production ortamlarda Server’ın fail etmesi gibi durumlarda Consul’un state’ini koruyabilmesi için her zaman 3 veya 5 adet server(5'ten fazlası önerilmez) ile çalışmak önerilir.Tekil sayıda sunucularla çalışmak performans ve hata toleransı arasında bir denge kurmaya yardımcı olur.

• Non-server çalışan agentlar client modeda çalışır.Aslında bu client hafif bir işlem (lightweight process) olarak düşünülebilir.Temel görevleri servisleri register(kayıt) etmek, health-check’leri(sağlık kontrolleri) çalıştırmak ve queryleri(sorguları) serverlara iletmektir.Consul, servisleri çalıştıran Consul Datacenter’ındaki her bir node üzerinde client’ın çalıştırılmasını önerir çünkü bu clientlar servisin healthi(sağlığı) ile ilgili gerçeğin kaynağıdır.(source of the truth)

Şimdi örnek olması amacıyla development modunda(in-memory server mode) bir lokal agent başlatalım.

$ consul agent -dev -node <node_name>

• Komutun çıktısında agentımızın server olarak çalıştığını ve leader’lik iddiasında bulunduğunu ve leader olarak seçildiğini buna ek olarak datacenterın sağlıklı bir üyesi olarak işaretlendiğini de görebiliriz.

Burada OSX kullanıcıları için küçük bir not eklemek gerekirse, Consul default olarak node adını hostname olarak ayarlar eğer hostname’imiz periodlar içeriyorsa(yani noktalar) bu node yapılan DNS queryler(sorgular) çalışmayacaktır.Bunu engellemek amacıyla “-node flag”’i ile nodemuza bir isim vermeliyiz.

Datacenter Members


$ consul members

komutuyla Consul datacenterımızın üyelik bilgilerini kontrol edebiliriz. Çıktı olarak bize datacenterımızdaki agentlarımızı listeleyecektir.Şuan için sadece tek bir üyeyi(member) listeleyecektir.Çıktı olarak agentımızın IP adres bilgisi , sağlık durumu(health state), datacenterdaki rolü ve bazı version bilgilerini gösterilecektir.Bu bilgilere ek olarak bazı metadata bilgilerini “-detailed flag”’i ile gösterebiliriz.

$ consul members -detailed

• “members” komutu, bilgilerini “gossip protocol” aracılığıyla alan Consul clientına karşı çalışır.Clientın sahip olduğu bilgiler sonunda tutarlıdır fakat herhangi bir noktada kendisinin dünya görüşüyle sunucuların state’i tamamiyle eşleşmeyebilir.Dolayısıyla kesinlikle tutarlı bir dünya görüşü için requesti Consul serverlarına ileten HTTP API ‘sini sorgulayabiliriz.

$ curl localhost:8500/v1/catalog/nodes

• HTTP API’ye ek olarak nodeları keşfetmek için “DNS Interface” kullanabiliriz.go Interface’i caching enable edilmediği durumlarda sorguları Consul servera gönderir.DNS lookup sorgularını gerçekleştirmek için Consul agentının ki default olarak 8600 portunda çalışmakta olan DNS serverına işaret etmek zorundayız.DNS entry’lerinin formatı örnek olarak “Judiths-MBP.node.consul” şeklindedir.

$ dig @127.0.0.1 -p 8600 machine.node.consul

Stopping the Agent

 $ consul leave

komutuyla beraber Consul agentımızı durdurabiliriz.Bu Consul agentımızı düzgün bir şekilde (gracefully) durdurur ve bu da agentımızın Consul datacenterdan ayrılmasına ve kapatılmasına neden olacaktır.

• “leave” komutunu verdiğimizde Consul diğer üyelerimize(members) bu agentın datacenterı terk ettiğini bildirir.Bir agent ayrıldığında(leaves) ona ait olan lokal servisler ve kontroller(health checks) de catalogdan silinir ve Consul bu node ile tekrar iletişim kurmayı denemez.

• Fakat node graceful olarak değil de durdurulmaya zorlanmışsa(force kill) Consul’un bu node’u ayrılmış olarak değil de fail etmiş olarak diğer nodelara bildirir.Bir node fail ettiğinde health’i “critical” olarak işaretlenir ve catalogdan silinmez.Dolayısıyla Consul otomatik olarak bu fail etmiş olan node’a network problemlemleri yüzünden erişilemediğini ve tekrar geri gelebileceğini düşünerek tekrardan connection kurmaya çalışacaktır.

• Eğer agent, server olarak çalışıyorsa graceful olarak ayrılmak(leave) konsensüs protokolünü etkileyen potansiyel bir kullanılabilirlik kesintisine neden olmamak için önemlidir.

Register a Service and Health Check — Service Discovery

• Consul’un en önemli kullanım alanlarından birisi “service discovery”’dir.Consul downtstream servislerin upstream bağımlılıklarının IP adreslerini bulabilmek için kullanabileceği bir DNS Interface sağlar.

• Consul bu servislerin nerede konumlandırdıklarını bilir çünkü her servis kendi lokal Consul clientına register olur. Operatörler servisleri manuel olarak register(kayıt) edebilir , configuration management(konfigürasyon yönetim) toolları(araçları) servisleri deploy olduklarında register edebilir veya container orchestration toolları entegrasyonlar aracılığıyla servisleri otomatik register edebilir.

• Biz bu bölümde Consul’a bir konfigürasyon dosyası sağlayarak bir service register edeceğiz ve manuel olarak health check’i yapacağız.Daha sonra DNS Interface ve HTTP API faydalanarak Consul’u bu servisi discover etmek için kullanacağız.

Defining Service

• Consul’da servisleri register etmenin iyi yolu var, ilki “service definition” dosyası ile ki bu genelde en yaygın yol olarak kullanılır diğeri ise HTTP API’ye call(çağrı) yaparak.

• Şimdi örneğimize geçelim, önce Consul konfigürasyonumuz için bir klasör oluşturacağız.Consul bu konfigürasyon klasöründeki tüm konfigürasyon dosyalarını yükleyecek dolayısıyla bu klasörün adını bu tip klasörler için Unix sistemlerinde yaygın olan ortak sözleşme “/etc/consul.d” gibi isimlendirmek olacaktır(buradaki “.d” son eki bu klasörün konfigürasyon dosyalarını içerdiğini ima etmektedir.)

$ mkdir ./consul.d

Daha sonra “service definition configuration”(servis tanım konfigürasyonu) dosyamızı yazalım.Örneğimizde “web” adında 80 portunda bir servis çalışıyormuş gibi davranacağız.

$ echo ‘{“service”: {
“name”: “web”,
“tags”: [“rails”],
“port”: 80
}
}’ > ./consul.d/web.json

bu komutumuzda aslında servis tanımımızı içeren “web.json” adlı dosyamızı oluşturuyor, bu dosya servisimizin adını , portunu ve daha sonradan servisimizi bulmamız için kullanabileceğimiz taglarını içeriyor.

Şimdi agentımızı bu konfigürasyon dosyalarımızı içeren klasörü flag’ler kullanarak belirterek ve script kontrollerini enable ederek restart edelim.

$ consul agent -dev -enable-script-checks -config-dir=./consul.d 
2019/07/16 14:09:25 [INFO] agent: Synced service “web”
2019/07/16 14:09:25 [DEBUG] agent: Node info in sync
2019/07/16 14:09:25 [DEBUG] agent: Service “web” in sync
2019/07/16 14:09:25 [DEBUG] agent: Node info in sync

Çıktımızdan hemen fark edeceksiniz ki Consul “web” adlı servisimizi senkronize etti.Bunun manası agent konfigürasyon dosyamızdan service tanımımızı yükledi ve başarılı bir şekilde servis kataloğumuza ekledi.

Querying Services

• Agent servisi Consul’un servis kataloğuna eklediğinde DNS Interface’i veya HTTP API kullanarak onu sorgulayabiliriz.

DNS Interface

• Öncelikle Consul’un DNS Interface’ini kullanarak web servisimizi sorgulayalım.Consul’a register olan servisimizin DNS adının formatı “NAME.service.consul” şeklinde olacaktır ki “NAME” burada register ettiğimiz servisimizin adı olacaktır yani web.Varsayılan olarak tüm DNS adları “consul” namespace’i altındadır gerçi bu konfigüre edilebilir.
Yani bu örnekteki web servisimiz için DNS adımız “web.service.consul” olacaktır.Şimdi DNS Interface’imizi bu register edilmiş servisimiz için sorgulayalım.(Consul default olarak DNS Interface’ini 8600 portunda çalıştırır)

» dig @127.0.0.1 -p 8600 web.service.consul
;; ANSWER SECTION:
web.service.consul. 0 IN A 127.0.0.1

çıktıda görüldüğü gibi servisimizin register edildiği IP adressi içeren bir A recordu döndü, A recordları sadece IP adreslerini tutabilen recordlardır.
Fakat biz DNS Interface’imizi SRV recordlar için de sorgulayabiliriz, SRV recordları tüm adres/port ikilisi değerlerini dönecektir.

$ dig @127.0.0.1 -p 8600 web.service.consul SRV
;; ANSWER SECTION:
web.service.consul. 0 IN SRV 1 1 80 Judiths-MBP.lan.node.dc1.consul.

çıktıda görüldüğü üzere SRV record bize servisimizin 80 portunda “Judiths-MBP.lan.node.dc1.consul” node’u üzerinde çalıştığını söylüyor, eğer bu denemelerinizi lokal makineniz üzerinde yapıyorsanız o zaman bu değer “machine.node.dc1.consul” olacak çünkü hatırlayın lokal nodemuzda(makinemizde) agentımızı development modeda çalıştırırken -node flagine machine değeri vererek çalıştırmıştık.

Son olarak DNS Interface’i taglar aracılığıyla servisleri filtrelemek için de kullanabiliriz. “tag-based” service sorgularının genel formatı “TAG.NAME.service.consul” şeklindedir.

Şimdiki örneğimizde Consul’a “rails” tagına sahip tüm web servislerimizi soracağız.

$ dig @127.0.0.1 -p 8600 rails.web.service.consul
;; ANSWER SECTION:
rails.web.service.consul. 0 IN A 127.0.0.1

yine görüldüğü üzere bize cevap olarak bir A record döndü.

HTTP API

• DNS Interface’e ek olarak servisi HTTP API kullanarak da sorgulayabiliriz.

» curl http://localhost:8500/v1/catalog/service/web
[
{
“Address”: “127.0.0.1”,
“CreateIndex”: 10,
“Datacenter”: “dc1”,
“ID”: “77bac878–4e1d-7555–8592-cb9622c7566a”,
“ModifyIndex”: 10,
“Node”: “machine”,
“NodeMeta”: {
“consul-network-segment”: “”
},
“ServiceAddress”: “”,
“ServiceConnect”: {},
“ServiceEnableTagOverride”: false,
“ServiceID”: “web”,
“ServiceKind”: “”,
“ServiceMeta”: {},
“ServiceName”: “web”,
“ServicePort”: 80,
“ServiceProxy”: {
“Expose”: {},
“MeshGateway”: {}
},
“ServiceTags”: [
“rails”
],
“ServiceWeights”: {
“Passing”: 1,
“Warning”: 1
},
“TaggedAddresses”: {
“lan”: “127.0.0.1”,
“wan”: “127.0.0.1”
}
}
]

HTTP API verilen servisi barındıran tüm nodeları listeledi.HTTP API’yi kullanarak sadece sağlıklı olan servis örneklerimizi(healthy service instances) liseleyebiliriz yani filtreleme yapabiliriz ki DNS bunu arka tarafta otomatik olarak yönetir.

$ curl http://localhost:8500/v1/catalog/service/web?passing

Updating Services

• Şimdi sırada bu web servisimize health check register edecek şekilde güncelleme yapacağız neden? Çünkü bizim 80 portunda çalışan herhangi bir servisimiz yok dolayısıyla bu web servisimiz için bir health check register ettiğimizde fail edecektir.

• Biz “servis tanım dosyamızı değiştirerek” ve agenta “SIGHUP” signal yollayarak veya “consul reload” komutunu çalıştırarak herhangi bir downtime yaşamadan servislerimizi güncelleyebiliriz.Alternatif olarak HTTP API kullanarak da servislerimizi dinamik olarak ekleyebiliriz,silebiliriz ve modifiye edebiliriz.Biz bu örneğimizde registration file(kayıt dosyamızı) değiştirerek servisimizi güncelleyeceğiz.

 $ echo ‘{“service”: {
“name”: “web”,
“tags”: [“rails”],
“port”: 8085,
“check”: {
“args”: [“curl”, “localhost:8085”],
“interval”: “10s”
}
}
}’ > ./consul.d/web.json

bir önceki servis tanımımızdan farklı olarak “check” keywordünü görmekteyiz.Bu curl’den faydalanarak her 10saniyede bir web servise connect olmaya çalışacak olan script-based(script tabanlı) bir health check ekler.Burada bir not, script-based health checkler Consul işlemini başlatan aynı kullanıcı tarafından çalıştırılır.
Eğer bu komut exit-code (çıkış kodu) >=2 ‘u olursa,kontrol(check) fail edecektir ve Consul servisi sağlıksız olarak düşünecektir.Exit-code eğer 1 ise “warning state” olarak düşünülecektir.

$ consul reload
Configuration reload triggered
Daha sonra agent loglarına baktığımızda göreceğimiz çıktı:

2019/08/06 16:35:03 [INFO] agent: Synced service “web”
2019/08/06 16:35:03 [DEBUG] agent: Check “service:web” in sync
2019/08/06 16:35:03 [DEBUG] agent: Node info in sync

2019/08/06 16:35:06 [WARN] agent: Check “service:web” is now critical
2019/08/06 16:35:16 [WARN] agent: Check “service:web” is now critical

şeklinde olacaktır.

• Consul’un DNS server’inin sadece sağlıklı(healthy) sonuçları döneceğini söylemiştik bunu teyit etmemiz gerekirse :

$ dig @127.0.0.1 -p 600 web.service.consul

bu komutun çıktısında “ANSWER SECTION” bölümünün gelmediğini görmeliyiz.

Output:
; <<>> DiG 9.10.6 <<>> @127.0.0.1 -p 8600 web.service.consul
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 7687
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;web.service.consul. IN A
;; AUTHORITY SECTION:
consul. 0 IN SOA ns.consul. hostmaster.consul. 1580297064 3600 600 86400 0
;; Query time: 0 msec
;; SERVER: 127.0.0.1#8600(127.0.0.1)
;; WHEN: Wed Jan 29 14:24:24 +03 2020
;; MSG SIZE rcvd: 97

Connect Services — Service Mesh

• DNS Interface’i veya HTTP API’sı olan servislere doğrudan IP adresleri sağlamanın yanı sıra, Consul her bir servis örneğiyle deploy ettiğimiz sidecar proxyleri aracılığıyla, servisleri birbirine bağlayabilir.Bu tip dağıtım (yani servis örnekleri arasındaki network trafiğinin lokal proxyler ile kontrol edilmesi) service meshtir.Çünkü sidecar proxyleri senin register olan servislerini bağlar, Consul’un bu service mesh özelliğniin adı “Consul Connect”’tir.

• Connect,servislerimizin kodunu güncellemeye ihtiyaç duymadan servisler arasındaki iletişimi güvence altına almamıza ve gözlemlememizi sağlar.Bunun yerine Connect servisler arasında mutual TLS kurmak ve register olan servislerin adlarına dayanarak aralarındaki iletişime izin vermek veya vermemek için “sidecar proxy”’leri konfigüre eder.Çünkü sidecar proxyleri tüm service-to-service trafiği kontrol eder , metrikleri toplar ve onları 3rd Prometheus gibi aggregatorlara aktarır.

Start a Connect-unaware Service

• Öncelikle Connect’in farkında olmayan bir servis başlatıyoruz.Bu örneğimiz için “socat” komutu kullanarak “upstream” servis gibi davranacak basit bir echo servis başlatacağız.Production’da bu servis bir başka servisin dayandığı(relies) database , backend veya herhangi bir servis olabilir.

• Socat, şifreleme kavramına veya TLS protokolüne sahip olmayan onlarca yıllık bir Unix yardımcı programıdır.

• Şimdi 8181 portundan tcp connectionları dinleyip cat komutunu çalıştıran bir servis başlatacağız.

$ socat -v tcp-l:8181,fork exec:”/bin/cat”

bu komutumuzun çalıştırdığı servisi “nc(netcat)” aracı ile test edebiliriz.Bu komut aracılığıyla 8181 portunda çalışan servisimize bağlanıyor , bağlandıktan sonra hello veya herhangi bir şey yazıp aynı şekilde cevap aldığımızı görmeliyiz.

$ nc 127.0.0.1 8181
hello
hello

Register the Service and Proxy with Consul
— — — — — — — — — — — — — — — — — — — — —
• Şimdi önceki örneklerimizde yaptığımız gibi yeni bir servis tanımı yazarak Consul’a bir servis register edeceğiz fakat bunu yaparken bu sefer “connect” keyword ü kullanacağız bu sayede Consul,backend servis örneğimizin trafiğini yönetmesi için bir sidecar proxy register edecek.

$ echo ‘{
“service”: {
“name”: “socat”,
“port”: 8181,
“connect”: {
“sidecar_service”: {}
}
}
}’ > ./consul.d/socat.json

ardından “consul reload” komutunu çalıştırarak Consul’un yeni konfigürasyonu okumasını sağlamalıyız.

• Şimdi buradaki “connect” keyword e bakalım.Buradaki “{}” boş konfigürasyon Consul’a dynamic port ile bir sidecar proxy register etmesini bildiriyor.
Consul sizin için proxy işlemini otomatik olarak başlatmaz. Bunun nedeni Consul Connect’in kullanmak istediğiniz proxy’yi seçmenize izin vermesidir.

• Consul test amaçlı kullanılabilecek L4 proxy ve production deploymentlarında ve L7 trafik yönetiminde kullanılabilecek birinci sınıf Envoy desteği ile gelir.

• Şimdi diğer terminalde “consul connect proxy” komutunu kullanarak hangi servis örneğimize ve proxy kaydına karşılık geldiğini belirterek proxy işlemimizi başlatalım.

» consul connect proxy -sidecar-for socat

Register a Dependent Service and Proxy
— — — — — — — — — — — — — — — — — — —
• Şimdi downstream olarak web’i Consul’a register edelim.Bu seferki “connect” keywordümüzde yukarıdaki örnekten farklı olarak socat servisine upstream servis olarak bağlı olduğunu ve proxyinin dinleyeceği portu belirteceğiz.

$ echo ‘{ “service”: {
“name”: “web”,
“port”: 8080,
“connect”: {
“sidecar_service”: {
“proxy”: {
“upstreams”: [{
“destination_name”: “socat”,
“local_bind_port”: 9191
}]
}
}
}
}
}’ > ./consul.d/web.json

bu komutla beraber Consul “web” servisi için socat ile mTLS connectionı kurabilmek için 9191 portunu dinleyen bir sidecar proxy register edecektir.

Biraz daha açıklamak gerekirse, eğer gerçek bir web servis çalıştırıyor olsaydık loopback adresindeki kendi proxy’si ile konuşurdu.Proxy, trafiğini şifreleyecek ve ağ üzerinden socat hizmeti için sidecar proxy’sine gönderecektir.Socat servisinin proxysi trafiği decrypt edip loopback adresindeki 8181 portundaki socat servisine gönderecektir.

$ consul connect proxy -sidecar-for web

komutu çalıştırdıktan sonra register olan proxynin socat servisini proxylediğini görebiliriz.

• web ve socat proxleri arasındaki iletişim mTLS üzerinden encrypt ve authorize edildi fakat servis ile proxy arasındaki iletişim unencrypted durumda.Productionda servisler sadece loopback connectionları(bağlantılarını) kabul etmeli,makinenin içindeki ve dışındaki tüm trafik proxy üzerinden geçmelidir ve bu nedenle her zaman şifrelidir.

Control Communication with Intentions

• “Intensions”(niyetler) hangi servislerin hangi servislerle iletişimine izin verildiğini tanımlar.

Şimdi örnek olarak bir “intention” oluşturup web servisinden socat servisine olan erişimi reddedelim.

$ consul intention create -deny web socat

• “Intentions” geleneksel firewall ruleları gibi networkü parçalara ayırmaya izin verir fakat her bireysel servisin IP adresleri yerine mantıksal servis adlarına dayanarak bu
işi yapar.

Add to Consul KV — Service Configuration

• Consul uygulamaları dinamik olarak konfigüre ettiğin , servisleri koordine edebildiğin , leader seçimini yönettiğin veya Vault için data backend olarak hizmet verebildiğin key/value store’u dahil eder.

• Consul KV otomatik olarak agentlar üzerinde enabled durumdadır.

• Consul KV ile iletişime geçmenin iki yolu vardır HTTP API ve CLI.

Add Data

• İlk olarak “consul kv put” komutuyla KV store’a bazı değerler ekleyelim veya koyalım.(insert or put)

$ consul kv put redis/config/minconns 1
$ consul kv put -flags=42 redis/config/users/admin abcd1234

son örnekte flag değeri set ettik, bu Consul tarafından kullanılmayan 0–64 integer flag değeri set etmek için kullanılır fakat clientlar tarafından herhangi bir KV pair’ına metadata eklemek için kullanılabilir.

Query Data

• Şimdi bu key’lerden bazılarını sorgulayalım.

$ consul kv get redis/config/minconns

• Consul key-value çiftleri için bazı metadata bilgilerini ek olarak tutar.Bu metadata bilgilerini de yazdırmak için “-detailed” CLI flagden faydalanabiliriz.

• Eğer storedaki tüm keyleri listelemek istersek “recurse” seçeneğinden faydalanırız.

Delete Data

• Consul KV storedan bir key silmek için “delete” komutunu vermeliyiz.

$ consul kv delete redis/config/minconns

• Consul, anahtarlarla klasör benzeri bir şekilde etkileşime girmenizi sağlar.KV deposundaki tüm anahtarlar aslında düz olarak saklansa da, Consul belirli bir öneki grup olarak paylaşan anahtarları, sanki klasörler veya alt klasörlerdeymiş gibi değiştirmenize izin verir

• Dolayısıyla redis önekine sahip tüm keyleri silebilmek için “recurse” seçeneğinden faydalanabiliriz.

$ consul kv delete redis -recurse

Modify Existing Data

• Mevcut bir anahtarın değerini güncelleyin, mevcut bir ‘path’(yol) yeni bir değer koyun.

$ consul kv put foo bar$ consul kv get foo
bar
$ consul kv put foo zip$ consul kv get foo
zip

Create a Local Consul Datacenter
— — — — — — — — — — — — — — — —
• Consul agentı başladığında diğer agentların varlığından haberdar değildir.Agentlar birbirlerini öğrenmelerinin 2 yolu vardır.

• 1 — Varolan bir datacentera yeni bir agent eklemek için, ona datacenterda bulunan herhangi bir agentın (istemci veya sunucu) IP adresini verirsiniz, bu da yeni agent datacentera katılmasına neden olur.

• 2 — Agent datacenterın yeni bir üyesi olduğunda , gossip aracılığıyla otomatik olarak diğer agentları öğrenebilir.

Start the Agents

• Daha önceki örneklerimizde Consul’un işlevselliğini test amacıyla development modeda tek bir agent kullanmıştık.Fakat Production ortamlarında asla development modeda agentlar çalıştırmamalıyız.Bu seferki örneğimizde ilk server mode çalışacak agentımızı konfigüre edeceğiz.Şimdi agentı server modeda kaldırırken yapacağımız konfigürasyonları açıklayalım.

• server » Agentımızın server modeda başlamasını istediğimizi belirtiyoruz.

• -bootstrap-expect flag » Consul servera datacenter içerisinde toplamda kaç tane server olması gerektiğini
belirtiyoruz.Tüm sunucular, “replicated log”u yeniden başlatmadan önce bu numaranın katılmasını bekleyecek ve bu da verilerin tüm sunucularda tutarlı olmasını sağlayacaktır.

• -node <name> » Datacenterdaki her bir nodeun unique bir adı olmalı , varsayılan olarak Consul makinenin hostnameini kullanır.

• -bind <address> » bu adres,agentın diğer cluster üyelerinden gelen iletişimi dinleyeceği adrestir.

• -data-dir flag » Bu flag Consula server ve clientlar için örneğin ACL tokenları gibi sensitive dataları içeren stateini nerede depolaması gerektiğini söyler.Genelde standart lokasyon olan “/tmp/consul” olarak setlenir.

• config-dir flag » konfigürasyonları için nereye bakılması gerektiğini söyler yine bunun için de standart
lokasyon “/etc/consul.d” dir.

• Şimdi buradaki örneğimizde bir Vagrant aracından faydalanacağız.(https://www.vagrantup.com/intro/index.html)
Örneğimiz için kullanacağımız Vagrantfile’ımız.
https://github.com/hashicorp/consul/blob/master/demo/vagrant-cluster/Vagrantfile

• Bu örnekte içerisinde consul yüklü 2 makineye sahip olacağız ve bunlardan birini server birini de agent modda çalıştıracağız.

• Vagrantfile içerisinede Makine adlarımızı n1 ve n2 olarak ayarlanmış bu dolayısıyla makinelere ssh connectionı kurarken n1 ve n2 isimlerini kullanacağız.Örneğimizde n1 server mode da n2 ise client mode çalışacak agent olarak ayarlayacağız.
Vagrantfile’ımızı içeren klasörde:

 $ vagrant up

komutunu verdiğimizde makinelerimizin ayağa kalkmaya başladığını görüyoruz bu işlem tamamlandıktan sonra n1 adlı makinemize ssh connectionı ile bağlanıp server mode da agentımızı çalıştıralım.

$ vagrant ssh n1
$ consul agent \
-server \
-bootstrap-expect=1 \
-data-dir=/tmp/consul \
-node=agent-one \
-bind=172.20.20.10 \
-data-dir=/tmp/consul \
-config-dir=/etc/consul.d

• Şimdi diger n2 adlı makinemizi ssh connectionı ile bağlanıp agent modda çalıştıralım.

$ vagrant ssh n2
$ consul agent \
-node=agent-two \
-bind=172.20.20.11 \
-enable-script-checks=true \
-data-dir=/tmp/consul \
-config-dir=/etc/consul.d

• Şimdi burada açıklamamız gereken bir konu var, buradaki bind flagi,yukarıda da belirttiğimiz gibi agentların birbirlerinden gelecek iletişimi dinleyecekleri adres peki buradaki değerler nereden geldi , eğer Vagrantfile içerisine bakacak olursak başlatılan bu iki makinenin içerisindeki private_network IP adresinin burada belirtilen adresler olduğunu göreceğiz ve yine private network Vagrant için ne manaya geliyor bakmak istersek
https://www.vagrantup.com/docs/networking/private_network.html adresinden faydalanabiliriz.

• Şimdi ise bu 2 agentın birbirinden haberdar olmadığı loglara bakarak anlayabileceğimiz gibi , her iki makinede de “consul members” komutunu çalıştırarak bunu anlayabiliriz, çıktı olarak sadece kendilerini göstereceklerdir.

Join the Agents

• Artık multi-agent datacenterımızı oluşturalım.n1 adlı makinemize girelim ve orada n2 adlı makinemizde client modeda çalışan agentımızı bu datacenterımıza join edelim.

$ vagrant ssh n1
$ consul join 172.20.20.11

buradan da anlaşıldığı üzere n2 adlı makinemizin private network IP adresini join komutumuza veriyoruz , ardından “consul members” komutumuzu çalıştırdığımızda :

Node Address Status Type Build Protocol DC Segment
agent-one 172.20.20.10:8301 alive server 1.5.3 2 dc1 <all>
agent-two 172.20.20.11:8301 alive client 1.5.3 2 dc1 <default>

birbirlerini gördüklerini teyit edebileceğiz.

--

--

developer-guy
Trendyol Tech

🇹🇷KCD Turkey Organizer🎖Best Sigstore Evangelist🐦SSCS Twitter Community Admin✍️@chainguard_dev Fan📦Container Addict📅Organizer at @cloudnativetr•@devopstr