Ana içeriğe geç

Go Entegrasyonu

Consul Guardian, Go uygulamanızın yanında sidecar olarak çalışır. Uygulamanız resmi istemci veya Viper ile Consul KV'den konfigürasyon okur. Guardian aynı anahtarları bağımsız olarak izler, her değişikliği Git'e commit eder ve herhangi bir anahtarı önceki değerine geri yüklemenizi sağlar.

Uygulama kodunuzda hiçbir değişiklik gerekmez.

Go uygulamaları Consul'dan nasıl okur

PaketAçıklama
hashicorp/consul/apiResmi Consul istemci kütüphanesi
spf13/viperConsul KV backend desteği olan config kütüphanesi

Örnek: Resmi Consul istemcisi

package main

import (
"fmt"
"log"
"net/http"

consul "github.com/hashicorp/consul/api"
)

func main() {
client, err := consul.NewClient(&consul.Config{
Address: "http://consul:8500",
})
if err != nil {
log.Fatal(err)
}

kv := client.KV()

http.HandleFunc("/config", func(w http.ResponseWriter, r *http.Request) {
pair, _, err := kv.Get("config/myapp/db_host", nil)
if err != nil {
http.Error(w, err.Error(), 500)
return
}
if pair == nil {
http.Error(w, "anahtar bulunamadi", 404)
return
}
fmt.Fprintf(w, "db_host = %s", string(pair.Value))
})

log.Fatal(http.ListenAndServe(":8080", nil))
}

Örnek: Viper ile Consul backend

package main

import (
"log"

"github.com/spf13/viper"
_ "github.com/spf13/viper/remote"
)

func main() {
viper.AddRemoteProvider("consul", "http://consul:8500", "config/myapp")
viper.SetConfigType("json")

if err := viper.ReadRemoteConfig(); err != nil {
log.Fatalf("Consul'dan config okunamadi: %v", err)
}

dbHost := viper.GetString("db_host")
dbPort := viper.GetInt("db_port")
maxRetries := viper.GetInt("max_retries")

log.Printf("Config yuklendi: db=%s:%d retries=%d", dbHost, dbPort, maxRetries)
}

Her iki yaklaşım da çalışır. Go uygulamanız başlangıçta veya istek bazında Consul KV'den okur. Sorun şu: biri yanlış bir config değeri gönderdiğinde, önceki değerin ne olduğunu görmenin dahili bir yolu yoktur.

Guardian ekleme

Docker Compose

version: "3.8"

services:
consul:
image: hashicorp/consul:1.17
ports:
- "8500:8500"
command: agent -dev -client=0.0.0.0

myapp:
build: .
ports:
- "8080:8080"
environment:
- CONSUL_HTTP_ADDR=http://consul:8500
depends_on:
- consul

guardian:
image: ghcr.io/consul-guardian/consul-guardian:latest
environment:
- CONSUL_GUARDIAN_CONSUL_ADDRESS=http://consul:8500
- CONSUL_GUARDIAN_WATCH_PREFIXES=config/,env/
- CONSUL_GUARDIAN_GIT_REPO_PATH=/data/repo
volumes:
- guardian-data:/data
depends_on:
- consul

volumes:
guardian-data:

Go uygulamanızda hiçbir değişiklik yok. Guardian ayrı bir container olarak çalışır.

Kubernetes

apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myregistry/myapp:latest
ports:
- containerPort: 8080
env:
- name: CONSUL_HTTP_ADDR
value: "http://consul.consul.svc.cluster.local:8500"

---
apiVersion: apps/v1
kind: Deployment
metadata:
name: consul-guardian
spec:
replicas: 1
selector:
matchLabels:
app: consul-guardian
template:
metadata:
labels:
app: consul-guardian
spec:
containers:
- name: guardian
image: ghcr.io/consul-guardian/consul-guardian:latest
env:
- name: CONSUL_GUARDIAN_CONSUL_ADDRESS
value: "http://consul.consul.svc.cluster.local:8500"
- name: CONSUL_GUARDIAN_WATCH_PREFIXES
value: "config/,env/"
- name: CONSUL_GUARDIAN_GIT_REPO_PATH
value: "/data/repo"
volumeMounts:
- name: guardian-data
mountPath: /data
volumes:
- name: guardian-data
persistentVolumeClaim:
claimName: guardian-pvc

CI pipeline'ında drift tespiti

Guardian'ın drift tespiti Go CI pipeline'larında oldukça faydalıdır. Deploy etmeden önce canlı Consul durumunun Git'teki ile eşleştiğini doğrulayabilirsiniz:

# .github/workflows/deploy.yml
name: Deploy

on:
push:
branches: [main]

jobs:
check-drift:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Guardian'i yukle
run: |
curl -sL https://github.com/consul-guardian/consul-guardian/releases/latest/download/consul-guardian-linux-amd64 -o consul-guardian
chmod +x consul-guardian

- name: Config drift kontrolu
run: |
./consul-guardian drift \
--consul-addr ${{ secrets.CONSUL_ADDR }} \
--consul-token ${{ secrets.CONSUL_TOKEN }} \
--prefix config/myapp/
# Drift tespit edilirse sifir olmayan cikis kodu doner

- name: Deploy
if: success()
run: make deploy

Birisi normal deployment sureci disinda bir Consul anahtarini manuel olarak degistirdiyse, drift kontrolu bunu yeni surum cikarmadan once yakalar. Bilinmeyen bir durumun uzerine deploy yapmanizi onler.

Geri yukleme senaryosu

Bir takim arkadasiniz config/myapp/db_host degerini yanlistikla staging veritabanina yonlendirir:

consul kv put config/myapp/db_host "staging-db.internal"

Go uygulamaniz production'dan staging DB'ye ulasamadigi icin hata vermeye baslar.

Bulun ve geri yukleyin:

# Neyin degistigini gorun
consul-guardian log --key config/myapp/db_host

# Onceki degeri geri yukleyin
consul-guardian restore --key config/myapp/db_host --commit abc1234

Dogru deger Consul'a geri yazilir. Uygulamaniz bir sonraki okumada degeri alir. Uygulamaniz istek bazinda config okuyorsa yeniden baslatma gerekmez. Baslangiçta config cache'liyorsa, restart veya SIGHUP yeni degeri alir.

Kod degisikligi gerekmez

Guardian, Go binary'nizi degistirmez, Consul cagrilarini proxy'lemez ve middleware enjekte etmez. Consul'u bagimsiz olarak izler. Uygulamaniz ve Guardian, her ikisi de Consul ile konusan iki ayri surectir.