> ## Documentation Index
> Fetch the complete documentation index at: https://docs.befailproof.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Kubernetes Dağıtım Kılavuzu

> AgentEye Kubernetes Dağıtım Kılavuzu belgeleri.

Bu kılavuz, tam AgentEye yığınını adanmış bir Kubernetes kümesine dağıtır:

* **ClickHouse 24.8** -- kanonik olaylar ve değerlendirmeler analitikleri depolama (100 GiB kalıcı birimli StatefulSet). Gerekli: sunucu bunu olmadan başlamayı reddeder.
* **PostgreSQL 16** -- kuruluşlar, API anahtarları, kullanıcılar, panolar, kaydedilmiş sorgular ve kimlik doğrulama için ilişkisel/meta veri depolaması (50 GiB kalıcı birimli StatefulSet)
* **Redis 7.2** -- isteğe bağlı paylaşılan önbellek ve hız sınırlama arka ucu; sunucu ve panel kullanılamadığında zarif bir şekilde bozulur
* **AgentEye Sunucusu** -- olay alımı, analitikleri ve anahtar yönetimi için Rust API (2 kopya)
* **AgentEye Paneli** -- Next.js web kullanıcı arayüzü (2 kopya)
* **AI asistanı (ajan hizmeti)** -- isteğe bağlı panel içi salt okunur asistan, 9100 portunda; bir LLM uç noktası yapılandırılana kadar pasif
* **Traefik (genel)** -- toplayıcı trafiği için giriş denetleyicisi, mTLS ile korumalı
* **Traefik (panel)** -- panel için giriş denetleyicisi, yalnızca VPN/IP-izin listesi
* **cert-manager** -- TLS sertifikaları ve mTLS CA
* **Yedekleme CronJob** -- 03:00 UTC'de PostgreSQL + ClickHouse'un günlük birleştirilmiş dökümü
* **Sertifika Yenileme İzleyicisi** -- istemci sertifikaları sona ermek üzereyken uyarı gönderir

**Tahmini süre:** ilk dağıtım için 60-90 dakika.

Exosphere'nin tüm bunları sizin adınıza yönettiği yönetilen dağıtım modeli için [enterprise-docs/managed-deployment.md](/tr/agenteye/managed-deployment) bölümüne bakın.

***

## Ön Koşullar

Başlamadan önce her doğrulama komutunu çalıştırın. Her kontrol başarılı olmalıdır.

| Gereksinim                          | Minimum                                         | Doğrulama Komutu                                                 | Beklenen Sonuç                                                                            |
| ----------------------------------- | ----------------------------------------------- | ---------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| Kubernetes kümesi                   | 1.27+                                           | `kubectl version`                                                | Server Version >= v1.27                                                                   |
| Kustomize (kubectl ile paketlenmiş) | Kustomize v1.14+ (kubectl 1.27+ içinde bulunur) | `kubectl kustomize --help`                                       | Kullanım metni yazdırır                                                                   |
| Helm                                | v3                                              | `helm version`                                                   | `Version:"v3.x.x"`                                                                        |
| cluster-admin RBAC                  | --                                              | `kubectl auth can-i create namespaces`                           | `yes`                                                                                     |
| Varsayılan StorageClass             | --                                              | `kubectl get storageclass`                                       | En az bir satır `(default)` olarak işaretlenmiş                                           |
| LoadBalancer desteği                | --                                              | Buluta bağlı (EKS, GKE, AKS varsayılan olarak bunu destekler)    | --                                                                                        |
| GitHub PAT                          | --                                              | `echo $AGENTEYE_TOKEN`                                           | Boş olmayan ([enterprise-docs/github-token.md](/tr/agenteye/github-token) bölümüne bakın) |
| openssl                             | --                                              | `openssl version`                                                | OpenSSL 1.x veya 3.x                                                                      |
| Bulut depolama paketi               | --                                              | PostgreSQL + ClickHouse yedekleri için (S3, GCS veya Azure Blob) | --                                                                                        |

**Küme boyutlandırması:** Minimum 3 düğüm, her biri 4 vCPU / 8 GB RAM. Tam gereksinimler için [enterprise-docs/managed-deployment.md](/tr/agenteye/managed-deployment) bölümüne bakın.

### Tüm kontrolleri aynı anda çalıştırın

```bash theme={null}
echo "--- Prerequisites Check ---"
kubectl version --client -o yaml 2>/dev/null | grep -q gitVersion && echo "PASS: kubectl" || echo "FAIL: kubectl not found"
helm version --short 2>/dev/null | grep -q v3 && echo "PASS: helm v3" || echo "FAIL: helm v3 not found"
kubectl auth can-i create namespaces 2>/dev/null | grep -q yes && echo "PASS: cluster-admin" || echo "FAIL: no cluster-admin"
kubectl get storageclass 2>/dev/null | grep -q default && echo "PASS: default StorageClass" || echo "FAIL: no default StorageClass"
[ -n "$AGENTEYE_TOKEN" ] && echo "PASS: AGENTEYE_TOKEN set" || echo "FAIL: AGENTEYE_TOKEN not set"
openssl version >/dev/null 2>&1 && echo "PASS: openssl" || echo "FAIL: openssl not found"
echo "---"
```

### Dağıtım şekli

**Alım uç noktası** kontrol ettiğiniz bir ana bilgisayar adında sunulur (örn. `ingest.your-company.example`). cert-manager, Let's Encrypt'den HTTP-01 üzerinden genel olarak güvenilir bir TLS sertifikası talep eder, bu nedenle toplayıcılar sunucu sertifikasını sistem güven deposuna karşı doğrular ve müşteri başına CA sabitleme yoktur.

**Panel uç noktası** aynı şekilde çalışır: kontrol ettiğiniz ikinci bir ana bilgisayar adında sunulur (örn. `agenteye.your-company.example`) ve panel Traefik LoadBalancer'ına işaret eder; cert-manager, o LoadBalancer üzerinden Let's Encrypt sertifikasını yayınlar. Tarayıcılar uyarısız güvenilir bir sertifika alır.

> **Sertifika yayınlama ve yenileme HTTP-01 üzerinden doğrular**, bu nedenle her iki LoadBalancer de genel internetten 80 portu üzerinde erişilebilir olmalıdır. Panel LoadBalancer'ını IP ile kısıtlama yapmanız gerekiyorsa, yenileme sessizce başarısız olmayacağı için öncelikle destek ekibiyle DNS-01 çözücüsü koordine edin ve sertifika sona ermez.

***

## Manifestleri Alın

```bash theme={null}
git clone https://x:${AGENTEYE_TOKEN}@github.com/agenteye-enterprise/releases.git
cd releases/deploy
```

**Test edin:**

```bash theme={null}
ls base/kustomization.yaml
```

Beklenen sonuç: dosya var. Yoksa, klonlama başarısız oldu -- `AGENTEYE_TOKEN` öğesini kontrol edin.

**Dizin yapısı:**

```
deploy/
  base/           Paylaşılan Kustomize temeli (tüm K8s kaynakları)
  overlays/       Kümeye özgü geçersiz kılmalar (görüntü etiketleri, ana bilgisayar adları, kaynaklar)
  third-party/    Traefik, cert-manager ve (opt-in) Robusta sağlık izleme için Helm değerleri
```

**Temel**, yapılandırdığınız iki genel ana bilgisayar adı için Let's Encrypt sertifikaları da dahil olmak üzere tam bir dağıtım için gereken her kaynağı içerir. Bir **kaplama**, belirli bir ortam için temeli yamaları (örn. özel görüntü etiketleri, kaynak sınırları, env kablolama). **Üçüncü taraf** dizini harici altyapı için Helm değerleri dosyalarını içerir.

> **Sağlık izleme (isteğe bağlı):** sunucunun hazırlık sondası zaten Postgres + ClickHouse sağlığını yansıtır ve `third-party/robusta/`, Slack'e opt-in Kubernetes native pod-hata uyarısı ekler. [enterprise-docs/health-monitoring.md](/tr/agenteye/health-monitoring) bölümüne bakın.

***

## Aşama 1 -- Üçüncü Taraf Altyapısı (\~30 dk)

### 1.1 cert-manager'ı kurun

cert-manager, HTTPS için TLS sertifikalarını ve mTLS istemci sertifikaları için kullanılan özel CA'yı yönetir.

```bash theme={null}
helm repo add jetstack https://charts.jetstack.io
helm repo update

helm install cert-manager jetstack/cert-manager \
  --namespace cert-manager --create-namespace \
  --set crds.install=true
```

**Test edin:**

```bash theme={null}
kubectl get pods -n cert-manager
```

Beklenen sonuç: 3 pod tümü `Running` -- `cert-manager`, `cert-manager-cainjector`, `cert-manager-webhook`.

```bash theme={null}
kubectl get crds | grep cert-manager
```

Beklenen sonuç: en az `certificates.cert-manager.io`, `clusterissuers.cert-manager.io`, `issuers.cert-manager.io`.

**Başarısız olursa:** `CrashLoopBackOff` içindeki pod'lar genellikle CRD'lerin yüklenmediği anlamına gelir. `--set crds.install=true` ile yeniden çalıştırın. Webhook pod'ları hazırlık kontrolünde başarısız olursa, 30 saniye bekleyin ve tekrar kontrol edin -- başlamak biraz zaman alabilir.

***

### 1.2 Traefik'i kurun -- Genel Alım Denetleyicisi

Bu Traefik örneği, **harici** bir LoadBalancer'da toplayıcı trafiğini işler. TLS'yi sonlandırır ve alım uç noktasında mTLS (istemci sertifikası doğrulama) uygular.

```bash theme={null}
helm repo add traefik https://traefik.github.io/charts
helm repo update

helm install traefik-public traefik/traefik \
  --namespace traefik-public --create-namespace \
  --version 39.0.8 \
  -f third-party/traefik/values-public.yaml
```

**Test edin:**

```bash theme={null}
kubectl get pods -n traefik-public
```

Beklenen sonuç: 1 pod `Running`.

```bash theme={null}
kubectl get ingressclass traefik-public
```

Beklenen sonuç: IngressClass var (varsayılan sınıf değildir).

**Başarısız olursa:** `kubectl describe pod -n traefik-public <pod-name>` ile görüntü çekme hataları veya kaynak kısıtlamaları kontrol edin.

***

### 1.3 Traefik'i kurun -- Panel Denetleyicisi

Bu Traefik örneği, panel'i IP izin listesi ile sınırlandırılmış adanmış bir LoadBalancer'da sunar.

> **Bu örnek için iki izin listesi mekanizması verilir.** Bu kılavuz `values-dashboard.yaml` kullanır ve erişimi taşınabilir `service.loadBalancerSourceRanges` alanı ile kısıtlar. Parallel `values-internal.yaml` da AWS ortamları için sağlanır ve bunun yerine `service.beta.kubernetes.io/aws-load-balancer-source-ranges` ek açıklamasını tercih eder. Birini seçin ve tutarlı kullanın; aşağıdaki adımlar `values-dashboard.yaml` olduğunu varsayar.

**Kurmadan önce**, izin verilen kaynak IP'lerini ayarlamak için `third-party/traefik/values-dashboard.yaml` öğesini düzenleyin. `loadBalancerSourceRanges` alanı, hangi IP'lerin panele erişebileceğini kontrol eder. Varsayılan olarak `0.0.0.0/0` (tüm IP'ler) olarak ayarlanır; bunu VPN, ofis veya bilinen çıkış IP'lerinize kısıtlayın.

#### Tek bir IP'yi izin listesine ekleyin

```yaml theme={null}
service:
  loadBalancerSourceRanges:
    - "<YOUR_VPN_IP>/32"
```

#### Birden fazla IP'yi izin listesine ekleyin

Her IP veya CIDR bloğu için bir giriş ekleyin. `/32` soneki tek bir IPv4 adresini eşleştirir; CIDR bloğu (örn. `/24`) bir aralığı eşleştirir. Tek tek IP'leri ve aralıkları serbestçe karıştırabilirsiniz:

```yaml theme={null}
service:
  loadBalancerSourceRanges:
    - "203.0.113.10/32"       # office gateway
    - "203.0.113.11/32"       # backup office gateway
    - "198.51.100.0/24"       # VPN pool
    - "192.0.2.50/32"         # on-call engineer home IP
```

Listeyi korurken ipuçları:

* Her satırda bir giriş tutun ve her IP'nin sahibini veya amacını tanımlayan kısa `#` yorumu ekleyin; gelecekteki operatörlerin bir giriş hala gerekli olup olmadığını belirlemek için kullandığı şey budur.
* Her zaman CIDR gösterimini kullanın. `203.0.113.10` gibi çıplak IP, bulut sağlayıcı tarafından reddedilir; `203.0.113.10/32` kullanın.
* IPv6 aralıkları için eşdeğer `/128` (tek adres) veya daha büyük CIDR'ı kullanın, örn. `2001:db8::1/128`. Tüm bulut sağlayıcılar IPv6 kaynak aralıklarını desteklemez; sağlayıcınızın LoadBalancer belgelerine bakın.
* Liste bir **VEYA**'dır: trafik, kaynak herhangi bir giriş ile eşleşirse izin verilir.

Dosyayı düzenledikten sonra aşağıdaki `helm install` adımına gidin. Denetleyici zaten kuruluysa, aynı bayraklarla `helm upgrade` çalıştırın veya çalışma zamanında Service'i yamalayın (sonraki bölüm).

#### İzin listesini çalışma zamanında güncelleyin

Helm yükseltmesi yapıştırmadan, Service'i doğrudan yamalayarak izin verilen IP'leri değiştirebilirsiniz. **Yama tüm listeyi değiştirir**; yalnızca yenisini değil, tutmak istediğiniz her IP'yi dahil edin.

Listeyi yeni bir IP seti ile değiştirmek için:

```bash theme={null}
kubectl patch svc traefik-dashboard -n traefik-dashboard \
  -p '{"spec":{"loadBalancerSourceRanges":["203.0.113.10/32","198.51.100.0/24","192.0.2.50/32"]}}'
```

Mevcut girişleri kaybetmeden bir IP'yi güvenli bir şekilde **eklemek** için, önce geçerli listeyi okuyun, sonra birleştirilmiş küme ile yamalayın:

```bash theme={null}
# 1. Geçerli izin listesini gösterin
kubectl get svc traefik-dashboard -n traefik-dashboard \
  -o jsonpath='{.spec.loadBalancerSourceRanges}'

# 2. Yeni IP dahil tam liste ile yamalayın
kubectl patch svc traefik-dashboard -n traefik-dashboard \
  -p '{"spec":{"loadBalancerSourceRanges":["<EXISTING_IP_1>/32","<EXISTING_IP_2>/32","<NEW_IP>/32"]}}'
```

> Çalışma zamanı yamaları `values-dashboard.yaml` öğesine geri kaydedilmez. Değişikliği gelecekteki Helm yükseltmeleri arasında tutmak için değerleri dosyasını da güncelleyin ve işleyin.

Sonra kurun:

```bash theme={null}
helm install traefik-dashboard traefik/traefik \
  --namespace traefik-dashboard --create-namespace \
  --version 39.0.8 \
  -f third-party/traefik/values-dashboard.yaml
```

**Test edin:**

```bash theme={null}
kubectl get pods -n traefik-dashboard
```

Beklenen sonuç: 1 pod `Running`.

```bash theme={null}
kubectl get ingressclass traefik-dashboard
```

Beklenen sonuç: IngressClass var.

***

### 1.4 LoadBalancer'ları bekleyin

Devam etmeden önce her iki Traefik örneğinin harici IP'leri olması gerekir.

```bash theme={null}
kubectl get svc -n traefik-public
kubectl get svc -n traefik-dashboard
```

**Test edin:** Her iki service de `EXTERNAL-IP` gösterir (`<pending>` değil).

Hala beklemede ise, atamayı izleyin:

```bash theme={null}
kubectl get svc -n traefik-public -w
```

IP göründükten sonra `Ctrl+C` tuşuna basın. IP ataması tipik olarak 2-5 dakika alır.

**Başarısız olursa:** 10 dakika sonra `<pending>` genellikle bulut sağlayıcının LoadBalancer sağlayamadığı anlamına gelir. Kontrol edin: alt ağ etiketleri (EKS `kubernetes.io/role/elb` gerektirir), VPC yapılandırması, hizmet kotaları ve iç LB ek açıklamasının iç örnek için ayarlandığını kontrol edin.

***

## Aşama 2 -- Gizlilikler Oluşturun (\~10 dk)

Tüm gizlilikler, uygulama dağıtılmadan önce el ile oluşturulur. Bu, hassas değerlerin hiçbir zaman manifest dosyalarında görünmemesini sağlar.

### 2.1 Ad alanını oluşturun

```bash theme={null}
kubectl create namespace agenteye
```

**Test edin:**

```bash theme={null}
kubectl get namespace agenteye
```

Beklenen sonuç: durum `Active`.

***

### 2.2 Görüntü çekme gizliliği

Bu gizlilik, `ghcr.io` ile doğrulama yapar ve AgentEye kapsayıcı görüntülerini çeker. PAT'ınızı nasıl oluşturacağınız hakkında [enterprise-docs/github-token.md](/tr/agenteye/github-token) bölümüne bakın.

```bash theme={null}
kubectl create secret docker-registry agenteye-image-pull \
  --namespace agenteye \
  --docker-server=ghcr.io \
  --docker-username=agenteye-enterprise \
  --docker-password="${AGENTEYE_TOKEN}"
```

**Test edin:**

```bash theme={null}
kubectl get secret agenteye-image-pull -n agenteye -o jsonpath='{.type}'
```

Beklenen sonuç: `kubernetes.io/dockerconfigjson`.

**Test edin (derin)** -- jetonu yapabilir doğrula gerçekten görüntüleri çeker:

Kaplamanızda `kustomization.yaml` dosyasında sabitlenen `server` görüntü etiketini kullanın (şu anda hem paketlenmiş `acme` kaplamasında hem de temel dağıtımda `v0.0.1-beta.48`). Bu kontrol sürümler arasında kaymaması için aşağıdaki etiketi dağıttığınız etiket ile değiştirin:

```bash theme={null}
kubectl run test-pull \
  --image=ghcr.io/agenteye-enterprise/server:v0.0.1-beta.48 \
  --overrides='{"spec":{"imagePullSecrets":[{"name":"agenteye-image-pull"}]}}' \
  --restart=Never -n agenteye --command -- echo ok

# Çekme için birkaç saniye bekleyin, sonra:
kubectl logs test-pull -n agenteye
kubectl delete pod test-pull -n agenteye
```

Beklenen sonuç: günlüklerde `ok` yazdırıldı.

**Başarısız olursa:** `ErrImagePull` veya `401 Unauthorized` PAT'ın geçersiz olduğu veya `read:packages` kapsamından yoksun olduğu anlamına gelir. [enterprise-docs/github-token.md](/tr/agenteye/github-token) öğesini yeniden kontrol edin.

***

### 2.3 PostgreSQL kimlik bilgileri

```bash theme={null}
POSTGRES_PASSWORD=$(openssl rand -hex 24)

kubectl create secret generic agenteye-postgres \
  --namespace agenteye \
  --from-literal=POSTGRES_USER=postgres \
  --from-literal=POSTGRES_PASSWORD="${POSTGRES_PASSWORD}" \
  --from-literal=POSTGRES_DB=agenteye
```

> **Önemli:** `-hex` (değil `-base64`) kullanarak parolayı oluştururuz. Base64 çıkışı `+`, `/` ve `=` içerebilir ve bu da `DATABASE_URL` bağlantı dizesini bozar. Ayrıntılar için [enterprise-docs/troubleshooting.md](/tr/agenteye/troubleshooting) bölümüne bakın.

> **`POSTGRES_PASSWORD` öğesini hemen gizli yöneticiye depolayin.** Yedekten geri yüklerseniz veya doğrudan veritabanına bağlanırseniz buna ihtiyacınız olur.

**Test edin:**

```bash theme={null}
kubectl get secret agenteye-postgres -n agenteye
```

Beklenen sonuç: gizlilik var.

```bash theme={null}
kubectl get secret agenteye-postgres -n agenteye \
  -o jsonpath='{.data.POSTGRES_PASSWORD}' | base64 -d | wc -c
```

Beklenen sonuç: `48` (24 hex bayt = 48 karakter).

***

### 2.4 Yönetici API anahtarı

```bash theme={null}
ADMIN_KEY=$(openssl rand -hex 32)

kubectl create secret generic agenteye-admin-key \
  --namespace agenteye \
  --from-literal=ADMIN_KEY="${ADMIN_KEY}"
```

Yönetici anahtarı bootstrap kimlik bilgisidir. Sunucu, her başlangıçta tüm izinleriyle bunu upsert eder. 3. Aşama'da kapsam alınmış toplayıcı anahtarları oluşturmak için kullanın. Tam izinler modeli için [enterprise-docs/api-keys.md](/tr/agenteye/api-keys) bölümüne bakın.

> **`ADMIN_KEY` öğesini hemen gizli yöneticiye depolayin.**

**Test edin:**

```bash theme={null}
kubectl get secret agenteye-admin-key -n agenteye
```

Beklenen sonuç: gizlilik var.

***

### 2.5 Kimlik doğrulama yapılandırması (panel girişi)

Panel, kullanıcı girişi için e-posta + OTP kullanır. Bu gizlilik olmadan sunucu hala başlar ve `ADMIN_KEY` API yolu çalışır, ancak **hiçbir kullanıcı UI üzerinden giriş yapamaz**.

Tüm anahtarlar temel manifestte `optional: true` olarak başvurulur, bu nedenle kısmi gizlilikler (veya hiç gizlilik) iyidir; sunucu belgelenen varsayılanlara geri döner. Her şeyi bir `agenteye-auth` gizliliğine bundleme, yetkilendirme yüzeyinin tek bir yerde döndürülebilir olmasını sağlar.

```bash theme={null}
kubectl create secret generic agenteye-auth \
  --namespace agenteye \
  --from-literal=ADMIN_EMAIL="admin@yourcompany.com" \
  --from-literal=ALLOWED_EMAILS="*@yourcompany.com" \
  --from-literal=SMTP_HOST="smtp.yourprovider.com" \
  --from-literal=SMTP_PORT="587" \
  --from-literal=SMTP_USERNAME="your-smtp-user" \
  --from-literal=SMTP_PASSWORD="your-smtp-password" \
  --from-literal=SMTP_FROM="noreply@yourcompany.com" \
  --from-literal=SMTP_TLS="starttls" \
  --from-literal=DEFAULT_ORG_NAME="Acme Corp" \
  --from-literal=DEFAULT_ORG_SLUG="acme"
```

| Anahtar                                                                 | Amaç                                                                                                                                                                                                                                                                                  |
| ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ADMIN_EMAIL`                                                           | Bootstrap yönetici kullanıcısı. Her başlangıçta tüm izinlerle oluşturulur ve dashboard aracılığıyla silme/izin düzenlemelerinden korunur. Olmadan hiçbir yönetici tohumlanmaz ve ilk giriş imkansızdır.                                                                               |
| `ALLOWED_EMAILS`                                                        | Virgülle ayrılmış izin listesi. Tam adresleri (`user@example.com`) ve alan adı joker karakterlerini (`*@example.com`) destekler. Olmadan **hiçbir kullanıcı giriş yapamaz veya oluşturulamaz**.                                                                                       |
| `SMTP_HOST`, `SMTP_PORT`, `SMTP_USERNAME`, `SMTP_PASSWORD`, `SMTP_FROM` | OTP kodları göndermek için SMTP röle. `SMTP_HOST` ayarlanmazsa, OTP kodları gerçek e-posta teslimatı yerine sunucunun stdout'una kaydedilir (ilk başlangıç sigara testleri için yararlı). Gerçek e-posta teslimi için tüm SMTP anahtarlarını birlikte sağlayın.                       |
| `SMTP_TLS`                                                              | `starttls` (varsayılan), `tls` veya `none` birisi.                                                                                                                                                                                                                                    |
| `DEFAULT_ORG_NAME`, `DEFAULT_ORG_SLUG`                                  | İsteğe bağlı. Yerleşik `default` kuruluşa dostça bir görüntü adı ve URL slug'u verin, böylece örn. `/default` yerine `/acme` adresinde yaşasın. Slug 1-40 küçük harfli alfasayısal ile tek iç tire olmalıdır. Her iki tarafı da ayarlı bırakın jenerik `default` öğesini tutmak için. |

> **SMTP kimlik bilgilerini gizli yöneticiye depolayin.**

**Test edin:**

```bash theme={null}
kubectl get secret agenteye-auth -n agenteye \
  -o jsonpath='{.data}' | grep -o '"[A_-Z]*"' | sort -u
```

Beklenen sonuç: doldurduğunuz anahtarlar çıkışta görünür.

***

### 2.6 Çok kiracılı org izolasyon anahtarı (isteğe bağlı)

Tek kiracılı bir dağıtım için bunu atlayın; sunucu yerleşik bir geliştirme varsayılanında çalışır ve bir `default` org'u iyiyse sunmaktadır. **İkinci bir kuruluş oluşturmadan önce**, güçlü, kararlı bir `ORG_CH_SECRET` ayarlayın: her org'un ClickHouse parolası `HMAC(ORG_CH_SECRET, org_id)` olarak türetilir, bu nedenle genel olarak bilinen geliştirme varsayılanı genel olarak türetilebilir per-org kimlik bilgileri sağlayacaktır. `agenteye-orgctl org create` komutu ([§7.6 Sağlama kuruluşları](#76-provision-organizations-multi-tenant) bölümüne bakın) sunucu hala yerleşik geliştirme varsayılanında iken çalışmayı reddeder.

```bash theme={null}
kubectl create secret generic agenteye-org-ch-secret \
  --namespace agenteye \
  --from-literal=ORG_CH_SECRET="$(openssl rand -base64 48)"

# Sunucuyu yeniden başlatın, böylece yeni değeri alır.
kubectl -n agenteye rollout restart deployment/server
```

Sunucu bunu **isteğe bağlı** bir `secretKeyRef` üzerinden okur, bu nedenle asla oluşturmayan tek kiracılı bir küme hala normal şekilde başlar. **Değeri kararlı ve tüm çoğaltmalar arasında özdeş tutun**; döndürme her org'un türetilmiş ClickHouse parolasını geçersiz kılar ve bu yapı zamanı yeniden sağlanması tüm çoğaltmalar arasında değer tutarlı olduğunda iyileştirir (kararlı bir değerle kayan bir yeniden başlatma işlemi bunu iyileştirir). `deploy/base/server/secret.example.yaml` bölümüne bakın.

> **`ORG_CH_SECRET` öğesini gizli yöneticiye depolayin ve sırası olmadan döndürmeyin.**

***

### 2.7 Tüm gizlilikleri doğrulayın

```bash theme={null}
kubectl get secrets -n agenteye -o custom-columns='NAME:.metadata.name,TYPE:.type'
```

Beklenen çıkış (herhangi bir varsayılan gizlilik arasında):

```
NAME                    TYPE
agenteye-admin-key      Opaque
agenteye-auth           Opaque
agenteye-image-pull     kubernetes.io/dockerconfigjson
agenteye-postgres       Opaque
agenteye-org-ch-secret  Opaque   # yalnızca §2.6 (çok kiracılı) tamamladıysanız
```

Dört temel gizlilik (`agenteye-admin-key`, `agenteye-auth`, `agenteye-image-pull`, `agenteye-postgres`) devam etmeden önce mevcut olmalıdır. `agenteye-org-ch-secret` yalnızca çok kiracılı dağıtımlar için gereklidir (bkz. §2.6).

***

## Aşama 3 -- Uygulamayı Dağıtın (\~5 dk)

### 3.1 Genel ana bilgisayar adlarını yapılandırın

cert-manager, Let's Encrypt sertifikalarını istemeden önce alım ve panel ana bilgisayar adlarına ihtiyaç duyar. Şablonu kopyalayın ve her ikisini ayarlayın:

```bash theme={null}
cp base/certificates/domain.env.example base/certificates/domain.env
# base/certificates/domain.env adresini düzenleyin ve ayarlayın:
#   INGEST_DOMAIN=ingest.your-company.example      (genel Traefik LB'de çözümlenir)
#   DASHBOARD_DOMAIN=agenteye.your-company.example (panel Traefik LB'de çözümlenir)
```

`domain.env` gitignore edilir; her dağıtıma yerel kalır. Kustomize yapı, eğer herhangi bir anahtar eksikse sessizce başarısız olur.

> **DNS önce çözümlenmelidir.** LB'leri henüz işaret etmek zorunda değilsiniz (Aşama 1.2 tamamlanana kadar yoklar), ancak 3.2 adımında ACME yayını her ana bilgisayar adı LoadBalancer'ına çözümlenene kadar yeniden dener. Şimdi DNS ayarlayabilir (Aşama 1.4'te yakalanan LB ana bilgisayar adlarını kullanarak) veya devam edin ve kayıtları Aşama 4'te ekleyin.

***

### 3.2 Manifestleri uygulayın

Taze bir yükleme için tabanı doğrudan uygulayın veya bu ortam için bir kaplamayı kestiyseniz (kaplamalar görüntü etiketlerini, env değişkenlerini ve kaynak sınırlarını sabitler; temel sertifikalarını ve yönlendirmesini devralırlar):

```bash theme={null}
kubectl apply -k base/
# veya
kubectl apply -k overlays/<your-env>/
```

Kaplamalar tabanı otomatik olarak içerir; birini uygulayın, her ikisini değil.

***

### 3.3 Pod'ları bekleyin

```bash theme={null}
kubectl wait --for=condition=Ready pod -l 'app in (server,dashboard,postgres,clickhouse)' \
  -n agenteye --timeout=180s
```

Bekleme, veri düzlemi pod'larına kapsama alınır. İsteğe bağlı `agent` (AI asistanı) ve `redis` pod'ları onlarla birlikte başlar; asistan LLM uç noktasını sağlayana kadar pasif kalır ([enterprise-docs/assistant.md](/tr/agenteye/assistant) bölümüne bakın) ve Redis, en iyi çalışma şansı yapan bir önbellektir, bu nedenle ne platform'un trafik sunmasına hazır olması gerekir.

**Test edin:**

```bash theme={null}
kubectl get pods -n agenteye
```

Beklenen sonuç (isteğe bağlı `agent` ve `redis` pod'ları da görünür ve `Running` öğesine ulaşır):

```
NAME                         READY   STATUS    RESTARTS   AGE
agent-xxxxxxxxxx-xxxxx       1/1     Running   0          ...
clickhouse-0                 1/1     Running   0          ...
dashboard-xxxxxxxxxx-xxxxx   1/1     Running   0          ...
dashboard-xxxxxxxxxx-xxxxx   1/1     Running   0          ...
postgres-0                   1/1     Running   0          ...
redis-0                      1/1     Running   0          ...
server-xxxxxxxxxx-xxxxx      1/1     Running   0          ...
server-xxxxxxxxxx-xxxxx      1/1     Running   0          ...
```

**Başarısız olursa:**

| Pod Durumu         | Muhtemel Neden                               | Hata Ayıklama Komutu                                              |
| ------------------ | -------------------------------------------- | ----------------------------------------------------------------- |
| `ImagePullBackOff` | Kötü görüntü çekme gizliliği veya PAT        | `kubectl describe pod <name> -n agenteye`                         |
| `CrashLoopBackOff` | Kötü ortam değişkenleri (örn. DATABASE\_URL) | `kubectl logs <name> -n agenteye`                                 |
| `Pending`          | Yetersiz CPU/bellek veya düğüm yok           | `kubectl describe pod <name> -n agenteye` (Olayları kontrol edin) |

***

### 3.4 Depolamayı doğrulayın

```bash theme={null}
kubectl get pvc -n agenteye
```

Beklenen sonuç, her ikisi de `Bound` durumuyla:

| PVC                            | Kapasite | Yedekler                                                       |
| ------------------------------ | -------- | -------------------------------------------------------------- |
| `postgres-data-postgres-0`     | `50Gi`   | PostgreSQL ilişkisel/meta veri depolaması                      |
| `clickhouse-data-clickhouse-0` | `100Gi`  | ClickHouse olayları + değerlendirmeler analitikleri depolaması |

İsteğe bağlı önbellek için bir `redis-data-redis-0` PVC (1Gi) de görünür.

**Başarısız olursa:** `Pending` anlamına gelir StorageClass ses seslerini sağlayamaz. `kubectl get storageclass` öğesini kontrol edin ve varsayılan bir tane olduğundan emin olun. Üretim için, ClickHouse birimini hızlı bir SSD StorageClass'a yerleştirin (örn. AWS'de gp3, GCP'de pd-ssd); kompaksiyon verimlilik yavaş diskler üzerinde zarar görür.

***

### 3.5 Sertifikaları doğrulayın

```bash theme={null}
kubectl get certificates -n agenteye
```

Beklenen sonuç: 3 sertifika, tümü `Ready: True`:

| Ad              | İhraçcı            | Amaç                                                                     |
| --------------- | ------------------ | ------------------------------------------------------------------------ |
| `mtls-ca`       | `selfsigned`       | mTLS istemci sertifikaları yayınlayan özel CA (10 yıl geçerlilik)        |
| `ingest-tls`    | `letsencrypt-prod` | Alım uç noktası için genel TLS sertifikası (90 gün, otomatik yenilenmiş) |
| `dashboard-tls` | `letsencrypt-prod` | Panel için genel TLS sertifikası (90 gün, otomatik yenilenmiş)           |

**Eğer `ingest-tls` veya `dashboard-tls` Ready değilse:**

`kubectl describe certificate <name> -n agenteye` çalıştırın ve Olayları okuyun. Yaygın nedenler:

* **DNS henüz LB'ye işaret etmiyor.** Let's Encrypt, ana bilgisayar adını çözümler ve doğrulamak için 80 numaralı porta çarpar -- `INGEST_DOMAIN` genel LB'ye, `DASHBOARD_DOMAIN` panel LB'ye çözümlenmelidir. CNAME/Diğer ad yayılana kadar, sipariş `pending` kalır. DNS doğru olduktan sonra, cert-manager otomatik olarak yeniden dener (Sertifika'yı silmeye gerek yok).
* **Ana bilgisayar adı yerine konmamış.** `dnsNames` hala `INGEST_DOMAIN_PLACEHOLDER` / `DASHBOARD_DOMAIN_PLACEHOLDER` okuyorsa, 3.1. adımı atlattınız -- `base/certificates/domain.env` öğesini oluşturun ve yeniden uygulayın.
* **Dashboard Traefik, zorluk sunmıyor** (`dashboard-tls` sadece). Panel Traefik örneği, paketlenmiş değerler dosyasıyla kurulmalıdır (Aşama 1.2), cert-manager'ın HTTP-01 çözücüsünü sunan kapsama alınmış Ingress sağlayıcısını etkinleştirir. Olmadan kurulu bir örnek, zorluk yönlendirilemez ve sipariş `pending` sonsuza kadar kalır.

**Eğer `mtls-ca` Ready değilse:** cert-manager kendisi sağlıksızdır. Aşama 1.1'den cert-manager pod'larını yeniden kontrol edin.

***

### 3.6 CronJob'ları doğrulayın

```bash theme={null}
kubectl get cronjobs -n agenteye
```

Beklenen sonuç:

| Ad                   | Zamanlama      | Amaç                                                  |
| -------------------- | -------------- | ----------------------------------------------------- |
| `agenteye-backup`    | `0 3 * * *`    | 03:00 UTC'de günlük Postgres + ClickHouse yedeklemesi |
| `cert-renewal-check` | `0 3,15 * * *` | 03:00 ve 15:00 UTC'de sertifika sona erme uyarıları   |

***

### 3.7 Sunucunun doğru şekilde başlatıldığını doğrulayın

```bash theme={null}
kubectl logs -n agenteye -l app=server --tail=20
```

**Test edin:** Sunucunun 8080 portunda dinlediğini gösteren bir başlangıç satırı arayın. Veritabanı bağlantısı hataları olmamalıdır (sunucu Ready raporlamadan önce PostgreSQL ve ClickHouse'a erişilebildiğini gerektirir).

**Başarısız olursa:** En yaygın neden, `DATABASE_URL` öğesini kıran `POSTGRES_PASSWORD` içinde URL-güvenli olmayan karakterlerdir. [enterprise-docs/troubleshooting.md](/tr/agenteye/troubleshooting) bölümüne bakın.

***

### 3.8 Panel'in sunucuya bağlandığını doğrulayın

```bash theme={null}
kubectl logs -n agenteye -l app=dashboard --tail=20
```

**Test edin:** Çıkışta `ECONNREFUSED` veya benzer hatalar olmadan `Ready` arayın.

**Başarısız olursa:** `server` Service'in var olup olmadığını kontrol edin (`kubectl get svc server -n agenteye`) ve `AGENTEYE_SERVER_URL` panel dağıtımında `http://server:8080` olarak ayarlandığını kontrol edin.

***

## Aşama 4 -- Ağ Erişimi (\~5 dk)

### 4.1 LoadBalancer adreslerini alın

```bash theme={null}
PUBLIC_IP=$(kubectl get svc -n traefik-public \
  -o jsonpath='{.items[0].status.loadBalancer.ingress[0].ip}')

INTERNAL_IP=$(kubectl get svc -n traefik-dashboard \
  -o jsonpath='{.items[0].status.loadBalancer.ingress[0].ip}')
```

> AWS EKS'te LoadBalancer'lar IP yerine ana bilgisayar adı döndürür. Yukarıdaki komutlarda `.ip` öğesini `.hostname` ile değiştirin.

**Test edin:**

```bash theme={null}
echo "Public  (ingest):    $PUBLIC_IP"
echo "Internal (dashboard): $INTERNAL_IP"
```

Her ikisi de boş olmayan olmalıdır.

***

### 4.2 DNS'i LoadBalancer'lara işaret edin

`base/certificates/domain.env` öğesinden ana bilgisayar adlarının LoadBalancer'larına çözümlenecek şekilde DNS kayıtları oluşturun -- `INGEST_DOMAIN` **genel** Traefik LB'ye, `DASHBOARD_DOMAIN` **panel** Traefik LB'ye:

* **AWS Route 53:** `Alias = Yes` ile `A` kaydı, hedef = LB ana bilgisayar adı. Düz A → IP kullanmayın; ELB IP'leri döner.
* **Başka herhangi bir sağlayıcı:** Ana bilgisayar adından LB ana bilgisayar adına `CNAME`.

Doğrulayın:

```bash theme={null}
dig +short ingest.your-company.example
dig +short agenteye.your-company.example
```

Sırasıyla `$PUBLIC_IP` ve `$INTERNAL_IP` ile aynı adres döndürmelidir (veya EKS'te aynı `*.elb.amazonaws.com` ana bilgisayar adlarına çözümlenmelidir).

DNS çözümlendikten sonra, cert-manager 3.5. Aşamadaki beklemede olan ACME siparişlerini bir dakika içinde tamamlar. Hem `ingest-tls` hem de `dashboard-tls` `Ready: True` gösterin kadar `kubectl get certificates -n agenteye` öğesini yeniden çalıştırın.

***

### 4.3 Alım uç noktasına ulaşın

Genel alım uç noktası karşılıklı TLS'yi uygular, bu nedenle her istek (`/health` dahil) istemci sertifikası sunmalıdır. İlk istemci sertifikasını 5. Aşama'da yayınlarsınız; zaten birini varsa, şimdi erişilebilirliği doğrulayın:

```bash theme={null}
curl -s --cert issued/<cluster-name>/client.crt \
        --key issued/<cluster-name>/client.key \
        https://ingest.your-company.example/health
```

Beklenen sonuç: `{"status":"ok"}`. `-k` gerekmez -- sunucu sertifikası `INGEST_DOMAIN` için genel bir CA'ya zincirler, bu nedenle sistem güven deposuna karşı doğrulanır. Raw LoadBalancer IP/ana bilgisayar adı tarafından değil, `INGEST_DOMAIN` ana bilgisayar adı (sertifika ile eşleşen) tarafından alım uç noktasına ulaşın.

Panel uç noktası, genel olarak güvenilir bir sertifika ile `DASHBOARD_DOMAIN` öğesinde sunulur ve mTLS arkasında değildir, bu nedenle `-k` ve istemci sertifikası yoktur:

```bash theme={null}
curl -s https://agenteye.your-company.example/ -o /dev/null -w '%{http_code}\n'
```

Raw LB adresinden değil, ana bilgisayar adı tarafından panele ulaşın -- sertifika `DASHBOARD_DOMAIN` öğesine bağlanır, bu nedenle ham adres sertifika adı uyuşmazlığı gösterir.

**Başarısız olursa:** `curl` asılı kalırsa, LB'nin makinenizden erişilebildiğini kontrol edin (VPN, güvenlik grupları, güvenlik duvarı kuralları). Alım ana bilgisayar adında `certificate required` el sıkışma hatası, hiçbir istemci sertifikasının sunulmadığı anlamına gelir; önce 5. Aşama'yı tamamlayın. Alım ana bilgisayar adında TLS doğrulama hatası, sunucu sertifikasının henüz bitmemiş olduğu anlamına gelir; 3.5. Aşamaya geri dönün ve orada sorunu çözün.

***

## Aşama 5 -- mTLS İstemci Sertifikaları Yayınlayın (\~10 dk her küme)

Toplayıcılar **iki faktör** ile kimlik doğrulama yapar: istemci sertifikası (taşıma katmanı, isteğin yetkili bir kümeden geldiğini kanıtlar) ve API anahtarı (uygulama katmanı, isteğin `events:add` izni olan bir toplayıcıdan geldiğini kanıtlar). Sızan anahtar sertifika olmadan işe yaramaz; çalınan sertifika geçerli anahtar olmadan işe yaramaz.

### 5.1 Sertifika yayınlayın

Toplayıcıları çalıştıran her kümenin kendi istemci sertifikasına ihtiyacı vardır. Manifest dizininden:

```bash theme={null}
cd base/certificates/client-certs
./issue-client-cert.sh <cluster-name>
```

`<cluster-name>` öğesini anlamlı bir tanımlayıcıyla değiştirin (örn. `us-east-1-prod`, `staging`).

**Test edin:** Komut `==> Done!` yazdırır ve çıkış dosyalarını listeler.

```bash theme={null}
kubectl get certificate mtls-client-<cluster-name> -n agenteye
```

Beklenen sonuç: `Ready: True`.

`issued/<cluster-name>/` içindeki çıkış dosyaları:

| Dosya                        | Amaç                                                        |
| ---------------------------- | ----------------------------------------------------------- |
| `client.crt`                 | İstemci sertifikası (90 gün geçerlilik)                     |
| `client.key`                 | İstemci özel anahtarı                                       |
| `ca.crt`                     | Sunucu doğrulaması için CA sertifikası                      |
| `collector-mtls-secret.yaml` | Toplayıcı kümesi için uygulamaya hazır Kubernetes Gizliliği |

***

### 5.1b Alternatif teslimat: AWS Gizlilikler Yöneticisi

Sertifikanın tüketeni diskten `client.crt` ve `client.key` gereken bir Kubernetes Pod'u ise -- uygulamayı uygulama pod'ında kenar aracı olarak çalıştırdığınızda tipik durum -- sertifika paketini AWS Gizlilikler Yöneticisi'ne itin. Uygulama pod'u ardından [Gizlilikler Depolama CSI Sürücüsü](https://secrets-store-csi-driver.sigs.k8s.io/) üzerinden IRSA ile bunu takar ve sertifika döndürme tamamen uygunsuz.

```bash theme={null}
cd base/certificates/client-certs
export AWS_REGION=us-east-1     # iş yükünüzün çalıştığı bölge
./issue-client-cert.sh <cluster-name> --save-to aws-secrets-manager
```

Yeniden çalıştırıldıktan sonra (yenileme), komut dosyası aynı gizlilik üzerinde `PutSecretValue` öğesini çağırır, bu nedenle ARN ve ad kararlı kalır. CSI Sürücüsü, döndürme yoklama aralığını seçer ve dosyaları pod'un içinde yeniden yazar.

**Önkoşullar:**

* `aws` CLI v2 AWS hesabınıza kimlik doğrulama.
* `jq` yüklü.
* `AWS_REGION` ortam değişkeni ayarlandı.
* Arayanızın kimliğinde IAM izinleri (`Resource` `arn:aws:secretsmanager:<region>:<account>:secret:agenteye/mtls-client/*` kapsamı):
  * `secretsmanager:CreateSecret`
  * `secretsmanager:DescribeSecret`
  * `secretsmanager:PutSecretValue`
  * `secretsmanager:TagResource`

**Komut dosyası bu modda ne yapar:**

| Adım | İşlem                                                                                                                                                                                                                                                                 |
| ---- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1    | Cert-manager aracılığıyla sertifikayı yayınlar / yeniden çıkarır (varsayılan mod gibi).                                                                                                                                                                               |
| 2    | `agenteye/mtls-client/<cluster-name>` üzerinde `DescribeSecret` öğesini çağırır ve oluştur-vs-güncelle'ye karar verir.                                                                                                                                                |
| 3    | İlk çalıştırmada: `CreateSecret` öğesini üç tuşlu JSON yükü (`client.crt`, `client.key`, `ca.crt`) ile, etiketli `AgentEyeCluster=<cluster-name>`. Sonraki çalıştırmalarda: yeni sürüm yayınlamak için `PutSecretValue`; etiket `TagResource` aracılığıyla yenilenir. |
| 4    | Başarılı yükleme sonrasında `issued/<cluster-name>/` adresini siler. Herhangi bir başarısızlıkta, dizin korunur, böylece yeniden deneyin.                                                                                                                             |

**Gizlilik silme işaretlenmişse**, komut dosyası size yeniden denemeden önce `aws secretsmanager restore-secret --secret-id agenteye/mtls-client/<cluster-name>` çalıştırmanız gerektiğini söyleyen açık bir hatayla başarısız olur.

Tam pod kablolama (SecretProviderClass, IRSA kurulumu, döndürme davranışı, sorun giderme) için [enterprise-docs/single-pod-deployment.md](/tr/agenteye/single-pod-deployment) bölümüne bakın.

***

### 5.2 Sertifikanın çalıştığını doğrulayın

Verilen sertifikayı mTLS giriş tablosuna karşı test edin:

```bash theme={null}
curl -sk --cert issued/<cluster-name>/client.crt \
     --key issued/<cluster-name>/client.key \
     https://${PUBLIC_IP}/health
```

Beklenen sonuç: `{"status":"ok"}`

**Başarısız olursa:**

| Hata                   | Neden                                        | Çözüm                                                                                                                             |
| ---------------------- | -------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `certificate required` | Sertifika sunulmuyor                         | `curl` komutundaki dosya yollarını kontrol edin                                                                                   |
| `bad certificate`      | CA uyuşmazlığı                               | Sertifikanın `mtls-ca-issuer` tarafından yayınlandığını doğrulayın: `kubectl describe certificate mtls-client-<name> -n agenteye` |
| `connection refused`   | Yanlış ana bilgisayar adı veya LB erişilemez | `/etc/hosts` veya DNS'i kontrol edin                                                                                              |

***

### 5.3 Toplayıcı kümesine teslim edin

`collector-mtls-secret.yaml` öğesini toplayıcı kümesini işleten ekibe gönderin. Bunu uygularlar:

```bash theme={null}
kubectl apply -f collector-mtls-secret.yaml -n <collector-namespace>
```

Sonra toplayıcıyı gizliliği takmak ve sertifika yollarını kullanmak için yapılandırın:

```json theme={null}
{
  "tls_cert": "/etc/agenteye/tls/client.crt",
  "tls_key": "/etc/agenteye/tls/client.key"
}
```

Kubernetes birim bağlamalarını içeren tam toplayıcı kurulumu için [enterprise-docs/collector-installation.md](/tr/agenteye/collector-installation) bölümüne bakın.

**Test edin (toplayıcı kümesinde):**

```bash theme={null}
kubectl get secret agenteye-collector-mtls -n <collector-namespace>
```

Beklenen sonuç: 3 veri anahtarı (`client.crt`, `client.key`, `ca.crt`) ile gizlilik var.

***

### 5.4 Sertifika yaşam döngüsü

| Özellik                       | Değer                                                     |
| ----------------------------- | --------------------------------------------------------- |
| İstemci sertifika geçerliliği | 90 gün                                                    |
| Otomatik yenileme             | cert-manager sona ermeden 15 gün önce yeniler             |
| CA geçerliliği                | 10 yıl                                                    |
| Sona erme uyarıları           | CronJob sona ermeden 30 gün önce uyarı gönderir (Aşama 6) |

cert-manager, **AgentEye kümesinde** sertifikayı otomatik olarak yeniler, ancak yenilenen sertifika toplayıcı kümesine yeniden teslim edilmelidir. `issue-client-cert.sh` öğesini yeniden çalıştırın ve eski sertifika sona ermeden önce `collector-mtls-secret.yaml` öğesini yeniden uygulayın.

`--save-to aws-secrets-manager` kullanıyorsanız (bkz. § 5.1b), aynı komutu yeniden çalıştırın. Komut dosyası aynı gizlilik üzerinde `PutSecretValue` öğesini çağırır; pod'lar Gizlilikler Depolama CSI Sürücüsü aracılığıyla gizliliği taksa, sonraki döndürme yoklaması (varsayılan: her saat) yeni sürümü seçer, pod yeniden başlatması gerekmez.

***

### 5.5 Sertifikayı iptal edin

Bir kümenin toplayıcı erişimini hemen engellemek için:

```bash theme={null}
kubectl delete certificate mtls-client-<cluster-name> -n agenteye
```

**Test edin:** 5.2. adımdan `curl` komutu artık TLS el sıkışma hatası ile başarısız olur.

***

## Aşama 6 -- Sertifika Yenileme İzlemesi (\~2 dk)

Yerleşik bir CronJob, her 12 saatte bir (03:00 ve 15:00 UTC) çalışır ve `agenteye.io/cert-type=mtls-client` ile etiketlenmiş tüm istemci sertifikalarını kontrol eder. Herhangi bir sertifika sona ermesine 30 gün kaldığında uyarı gönderir.

### 6.1 Slack bildirimlerini etkinleştirin (isteğe bağlı)

```bash theme={null}
kubectl create secret generic cert-renewal-notify-config \
  --namespace agenteye \
  --from-literal=SLACK_WEBHOOK_URL="https://hooks.slack.com/services/YOUR/WEBHOOK/URL"
```

Bu gizlilik olmadan, CronJob hala çalışır ve sertifika durumunu stdout'a kaydeder.

**Test edin:**

```bash theme={null}
kubectl get secret cert-renewal-notify-config -n agenteye
```

Beklenen sonuç: gizlilik var.

***

### 6.2 CronJob'u test edin

```bash theme={null}
kubectl create job --from=cronjob/cert-renewal-check test-cert-check -n agenteye

kubectl wait --for=condition=Complete job/test-cert-check -n agenteye --timeout=60s

kubectl logs -n agenteye -l job-name=test-cert-check
```

Beklenen sonuç: sertifikaların ve sona erme durumlarının bir listesi. Slack web kancası yapılandırılmışsa, Slack kanalında uyarı mesajını kontrol edin.

**Başarısız olursa:** RBAC'ı kontrol edin -- CronJob'un ServiceAccount'u cert-manager Certificate kaynaklarında `get, list` izinlerine ihtiyaç duyar. Şu komutla doğrulayın: `kubectl describe role cert-renewal-check -n agenteye`.

Test işini temizleyin:

```bash theme={null}
kubectl delete job test-cert-check -n agenteye
```

***

## Aşama 7 -- Uçtan Uca Doğrulama

Bu aşama, tüm işlem hattının çalıştığını doğrular: sağlık kontrolü, anahtar oluşturma, olay alımı ve panel görüntüsü.

> **Not:** Aşağıdaki örnekler, alım uç noktasına ham LoadBalancer adresi (`${PUBLIC_IP}`) tarafından ulaşır; bu nedenle `-k` geçerler; sunucu sertifikası `INGEST_DOMAIN` öğesine bağlanır, host adı değil, `INGEST_DOMAIN` LB IP'ye bağlanır, bu nedenle ana bilgisayar adı kontrol atlanır. Alım uç noktası **her** yola mTLS uygular, bu nedenle her çağrı istemci sertifikası (`--cert`/`--key`) da sunmalıdır. Genel sertifikayı da doğrulamak için `https://ingest.your-company.example/...` yerine `${PUBLIC_IP}` öğesini hedefleyin ve `-k` kaybı düşürün.

### 7.1 Sağlık kontrolü

```bash theme={null}
curl -sk --cert issued/<cluster-name>/client.crt \
        --key issued/<cluster-name>/client.key \
        https://${PUBLIC_IP}/health
```

Beklenen sonuç: HTTP 200 ile `{"status":"ok"}`.

***

### 7.2 Kapsamlı toplayıcı anahtarları oluşturun
