Обзор паттернов
Kubernetes предоставляет примитивы (Pod, Container), из которых складываются архитектурные паттерны. Эти паттерны решают типовые задачи: логирование, мониторинг, проксирование, инициализация.
| Паттерн | Описание | Количество контейнеров |
|---|---|---|
| Init Container | Выполняется до основного | 1+ init + 1 main |
| Sidecar | Работает рядом с основным | 2+ (main + sidecar) |
| Ambassador | Прокси для внешних вызовов | 2 (main + proxy) |
| Adapter | Преобразование формата данных | 2 (main + adapter) |
| Operator | Расширение API Kubernetes | Отдельный Pod |
Init Container
Init Container выполняется перед запуском основного контейнера. Используется для подготовки среды.
# Init container: wait for database and run migrations
apiVersion: v1
kind: Pod
metadata:
name: api-server
spec:
initContainers:
# Init 1: Wait for PostgreSQL to be ready
- name: wait-for-db
image: busybox:1.36
command: ['sh', '-c']
args:
- |
until nc -z postgres-service 5432; do
echo "Waiting for PostgreSQL..."
sleep 2
done
echo "PostgreSQL is ready!"
# Init 2: Run database migrations
- name: run-migrations
image: myapp/api:v1.2.3
command: ['php', 'bin/console', 'doctrine:migrations:migrate', '--no-interaction']
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: db-credentials
key: url
# Init 3: Warm up cache
- name: warmup-cache
image: myapp/api:v1.2.3
command: ['php', 'bin/console', 'cache:warmup']
containers:
- name: api
image: myapp/api:v1.2.3
ports:
- containerPort: 8080
Типичные задачи для Init Container
| Задача | Описание |
|---|---|
| Ожидание зависимостей | Подождать пока БД/Redis станут доступны |
| Миграции БД | Запустить migrations перед стартом |
| Скачивание конфигов | Загрузить конфигурацию из Vault/S3 |
| Настройка прав | Изменить owner/permissions для volumes |
| Прогрев кэша | Сгенерировать кэш Symfony/Laravel |
Sidecar
Sidecar работает параллельно основному контейнеру в одном Pod, расширяя его функциональность.
# Sidecar: log collector + metrics exporter
apiVersion: v1
kind: Pod
metadata:
name: api-with-sidecars
spec:
containers:
# Main container: PHP application
- name: api
image: myapp/api:v1.2.3
ports:
- containerPort: 8080
volumeMounts:
- name: logs
mountPath: /var/log/app
# Sidecar 1: Log shipping to centralized logging
- name: log-shipper
image: fluent/fluent-bit:2.1
volumeMounts:
- name: logs
mountPath: /var/log/app
readOnly: true
- name: fluent-bit-config
mountPath: /fluent-bit/etc
resources:
requests:
cpu: "50m"
memory: "64Mi"
limits:
cpu: "100m"
memory: "128Mi"
# Sidecar 2: Prometheus metrics exporter
- name: php-fpm-exporter
image: hipages/php-fpm_exporter:2.2
ports:
- containerPort: 9253
name: metrics
env:
- name: PHP_FPM_SCRAPE_URI
value: "tcp://127.0.0.1:9000/status"
resources:
requests:
cpu: "10m"
memory: "32Mi"
volumes:
- name: logs
emptyDir: {}
- name: fluent-bit-config
configMap:
name: fluent-bit-config
<?php
declare(strict_types=1);
/**
* PHP application designed for sidecar pattern
*
* Writes structured logs to file (sidecar ships them)
* Exposes FPM status for metrics sidecar
*/
final class SidecarAwareApplication
{
/**
* Write structured JSON logs to file
* Sidecar (Fluent Bit) reads and ships to Elasticsearch
*/
public function log(string $level, string $message, array $context = []): void
{
$entry = json_encode([
'timestamp' => (new \DateTimeImmutable())->format('c'),
'level' => $level,
'message' => $message,
'context' => $context,
'request_id' => $_SERVER['HTTP_X_REQUEST_ID'] ?? uuid_create(),
'service' => 'api',
]) . "\n";
file_put_contents('/var/log/app/app.log', $entry, FILE_APPEND | LOCK_EX);
}
}
Ambassador -- прокси-контейнер для управления исходящими соединениями. Основной контейнер общается с Ambassador через localhost.
# Ambassador: connection pooling proxy for PostgreSQL
apiVersion: v1
kind: Pod
metadata:
name: api-with-pgbouncer
spec:
containers:
# Main: PHP application connects to localhost:5432
- name: api
image: myapp/api:v1.2.3
env:
- name: DATABASE_URL
value: "pgsql://app:password@localhost:5432/myapp"
# Ambassador: PgBouncer connection pooler
- name: pgbouncer
image: bitnami/pgbouncer:1.21
ports:
- containerPort: 5432
env:
- name: POSTGRESQL_HOST
value: "postgres-primary.default.svc.cluster.local"
- name: POSTGRESQL_PORT
value: "5432"
- name: PGBOUNCER_POOL_MODE
value: "transaction"
- name: PGBOUNCER_MAX_CLIENT_CONN
value: "200"
- name: PGBOUNCER_DEFAULT_POOL_SIZE
value: "20"
resources:
requests:
cpu: "50m"
memory: "64Mi"
Типичные Ambassador-прокси
| Прокси | Назначение |
|---|---|
| PgBouncer | Connection pooling для PostgreSQL |
| Envoy | Service mesh proxy (Istio sidecar) |
| stunnel | TLS termination для legacy протоколов |
| HAProxy | Load balancing для внешних сервисов |
Adapter
Adapter преобразует данные или интерфейс основного контейнера для совместимости с внешними системами.
# Adapter: convert PHP logs format to Prometheus metrics
apiVersion: v1
kind: Pod
metadata:
name: api-with-adapter
spec:
containers:
- name: api
image: myapp/api:v1.2.3
volumeMounts:
- name: metrics
mountPath: /tmp/metrics
# Adapter: reads custom metrics file, exposes as Prometheus
- name: metrics-adapter
image: prom/statsd-exporter:v0.26
ports:
- containerPort: 9102
name: metrics
args:
- "--statsd.mapping-config=/config/mapping.yml"
volumeMounts:
- name: adapter-config
mountPath: /config
volumes:
- name: metrics
emptyDir: {}
- name: adapter-config
configMap:
name: metrics-adapter-config
Operator
Operator -- расширение Kubernetes, которое автоматизирует управление сложными приложениями. Operator следит за Custom Resources и выполняет действия.
┌─────────────────┐
│ Custom Resource │
│ (CRD) │
│ │
│ spec: │
│ replicas: 3 │
│ version: 16 │
└────────┬────────┘
│ watches
┌────────┴────────┐
│ Operator │
│ Controller │
│ │
│ Reconcile loop: │
│ observe → diff │
│ → act │
└────────┬────────┘
│ manages
┌──────────────┼──────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Pod: PG │ │ Pod: PG │ │ Pod: PG │
│ Primary │ │ Replica │ │ Replica │
└──────────┘ └──────────┘ └──────────┘
Популярные операторы
| Operator | Управляет |
|---|---|
| CloudNativePG | PostgreSQL clusters |
| Strimzi | Apache Kafka clusters |
| Redis Operator | Redis Sentinel/Cluster |
| cert-manager | TLS certificates |
| Prometheus Operator | Monitoring stack |
# Using CloudNativePG Operator
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: app-database
spec:
instances: 3
postgresql:
parameters:
max_connections: "200"
shared_buffers: "256MB"
work_mem: "8MB"
storage:
size: 50Gi
storageClass: fast-ssd
backup:
barmanObjectStore:
destinationPath: s3://my-backups/pgdata
s3Credentials:
accessKeyId:
name: s3-creds
key: ACCESS_KEY_ID
secretAccessKey:
name: s3-creds
key: SECRET_ACCESS_KEY
retentionPolicy: "30d"
monitoring:
enablePodMonitor: true
Когда какой паттерн
| Задача | Паттерн |
|---|---|
| Подготовка среды перед запуском | Init Container |
| Сбор логов, метрик | Sidecar |
| Connection pooling, proxy | Ambassador |
| Преобразование формата данных | Adapter |
| Управление stateful приложением | Operator |
| Service mesh (mTLS, routing) | Sidecar (Envoy) |
| Миграции БД | Init Container |
| TLS termination | Ambassador/Sidecar |
Итоги
- Init Container решает задачи подготовки: ожидание зависимостей, миграции, прогрев кэша
- Sidecar расширяет функциональность основного контейнера без изменения его кода
- Ambassador проксирует исходящие соединения (PgBouncer, Envoy)
- Adapter преобразует форматы данных для совместимости с внешними системами
- Operator автоматизирует управление сложными приложениями через CRD и reconciliation loop