Ana içeriğe geç

.NET Entegrasyonu

Consul Guardian, .NET uygulamanızın yanında sidecar olarak çalışır. Uygulamanız Consul KV'den konfigürasyonu her zamanki gibi okur. Guardian aynı anahtarları bağımsız olarak izler, her değişikliği Git'e commit eder ve bir şeyler ters gittiğinde herhangi bir anahtarı önceki değerine geri yükleyebilir.

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

.NET uygulamaları Consul'dan nasıl okur

.NET uygulamaları genellikle şu paketlerden birini kullanır:

PaketAçıklama
Winton.Extensions.Configuration.ConsulConsul KV'yi IConfiguration ile entegre eder
Consul (G-Research).NET için düşük seviye Consul istemcisi
SteeltoeConsul config desteği olan cloud-native .NET framework

Örnek: Winton.Extensions.Configuration.Consul

Consul KV'den konfigürasyon yükleyen tipik bir Program.cs:

var builder = WebApplication.CreateBuilder(args);

builder.Configuration.AddConsul(
"config/myapp",
options =>
{
options.ConsulConfigurationOptions = co =>
{
co.Address = new Uri("http://consul:8500");
};
options.ReloadOnChange = true;
options.Optional = false;
}
);

var app = builder.Build();

app.MapGet("/", (IConfiguration config) =>
{
var connectionString = config["ConnectionString"];
var featureFlag = config.GetValue<bool>("EnableNewFeature");
return Results.Ok(new { connectionString, featureFlag });
});

app.Run();

Consul KV yapınız şöyle görünür:

config/myapp/ConnectionString  →  "Server=db.prod;Database=orders;..."
config/myapp/EnableNewFeature → "true"
config/myapp/MaxRetries → "3"

Bu kurulum iyi çalışır -- ta ki biri gece 2'de ConnectionString değerini yanlış bir şeyle değiştirip uygulamanız SqlException fırlatmaya başlayana kadar. Önceki değerin ne olduğunu bilmenin yolu yoktur.

Guardian ekleme

Guardian, uygulamanızın okuduğu aynı config/ prefix'ini izler. Uygulamanızın içinde değil, yanında çalışır.

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:
- "5000:5000"
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:

Hepsi bu kadar. myapp servisinde hiçbir değişiklik yok. Guardian aynı Consul instance'ını izleyen ayrı bir container olarak çalışır.

Kubernetes

apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
replicas: 2
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myregistry/myapp:latest
ports:
- containerPort: 5000
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/,feature-flags/"
- name: CONSUL_GUARDIAN_GIT_REPO_PATH
value: "/data/repo"
volumeMounts:
- name: guardian-data
mountPath: /data
volumes:
- name: guardian-data
persistentVolumeClaim:
claimName: guardian-pvc

Guardian kendi Deployment'ı olarak tek replika ile çalışır. Uygulama pod'unuzun içine sidecar container olarak eklenmesine gerek yoktur -- Consul'u bağımsız olarak izler.

Geri yükleme senaryosu

Gerçek bir senaryo: biri ConnectionString değerini yanlış bir değerle günceller ve .NET uygulamanız SqlException hatası vermeye başlar.

1. Yanlış değişiklik yapılır

consul kv put config/myapp/ConnectionString "Server=yanlis-host;Database=orders;..."

Uygulamanız yeni değeri alır (ReloadOnChange = true sayesinde) ve hata vermeye başlar.

2. Guardian ile önceki değeri bulun

# Bu anahtarın değişiklik geçmişini görün
consul-guardian log --key config/myapp/ConnectionString

# Çıktı:
# 2024-03-15T14:32:01Z abc1234 config/myapp/ConnectionString modified
# 2024-03-15T09:00:00Z def5678 config/myapp/ConnectionString modified
# 2024-01-10T11:20:00Z aaa1111 config/myapp/ConnectionString created

3. Anahtarı geri yükleyin

# Yanlış değişiklikten önceki commit'e geri yükleyin
consul-guardian restore --key config/myapp/ConnectionString --commit def5678

Guardian, CAS (Check-And-Set) kullanarak eski değeri Consul'a yazar. .NET uygulamanız konfigürasyonu otomatik olarak yeniden yükler ve tekrar çalışmaya başlar.

4. Doğrulayın

consul kv get config/myapp/ConnectionString
# Server=db.prod;Database=orders;... ← doğru değer geri yüklendi

Tüm olay bir dakikadan kısa sürede çözülür. Yeniden deployment gerekmez, eski değerin ne olduğunu tahmin etmeye gerek kalmaz.

Kod değişikliği gerekmez

Açıkça belirtmek gerekirse: Guardian, .NET uygulamanızda hiçbir değişiklik gerektirmez. IConfiguration pipeline'ınıza kendini enjekte etmez, Consul isteklerini proxy'lemez ve uygulamanızın davranışını hiçbir şekilde değiştirmez.

Uygulamanız Consul ile konuşur. Guardian da Consul ile konuşur. Birbirlerinden bağımsızdırlar.