
# Strimzi Kafka Operator 배포

## 1. 배포 방법

### 1) 배포시 주의 사항
- Strimzi Kafka Operator는 Kubernetes 1.25+ 버전이 필요합니다.
- CRD(Custom Resource Definitions) 업데이트가 필요할 수 있으므로 배포 전 확인이 필요합니다.
- 클러스터 범위 리소스 생성 권한이 필요합니다.
- ZooKeeper 기반 클러스터 지원이 제거되었으므로 KRaft 모드를 사용해야 합니다.

### 2) CRD 업데이트 방법
- Helm 업그레이드 시 CRD는 자동으로 업데이트되지 않으므로 수동으로 적용해야 합니다.

```sh
# CRD 수동 업데이트
kubectl apply -f https://github.com/strimzi/strimzi-kafka-operator/releases/download/0.47.0/strimzi-crds-0.47.0.yaml
```

### 3) 배포 방법
```sh
git clone https://github.com/paasup/service-catalog.git
cd charts/strimzi-kafka-operator
helm upgrade strimzi-kafka-operator ./ -f custom-values.yaml --install -n kafka --create-namespace
```

## 2. custom-values.yaml 예시

다음은 배포 시 사용할 수 있는 custom-values.yaml 파일의 예시입니다:

```yaml
# Global 설정
defaultImageRegistry: ""  # paasup.io (오프라인 환경에서 설정)
defaultImageRepository: "strimzi"
defaultImageTag: "0.47.0"

# Operator 기본 설정
replicas: 1

# 네임스페이스 감시 설정
watchAnyNamespace: true  # 전체 클러스터 감시 (기본값)
watchNamespaces: []      # watchAnyNamespace가 false일 때 감시할 특정 네임스페이스 목록

# 로그 설정
logLevel: INFO
logConfiguration: ""

# 타임아웃 설정
fullReconciliationIntervalMs: 120000
operationTimeoutMs: 300000

# 리소스 설정
resources:
  limits:
    memory: 384Mi
    cpu: 1000m
  requests:
    memory: 384Mi
    cpu: 200m

# RBAC 설정
rbac:
  create: yes
serviceAccountCreate: yes
serviceAccount: strimzi-cluster-operator

# 보안 설정
createGlobalResources: true
createAggregateRoles: false

# 네트워크 정책
generateNetworkPolicy: true
generatePodDisruptionBudget: true

# 모니터링 설정 (선택사항)
dashboards:
  enabled: false
  namespace: ~
  label: grafana_dashboard
  labelValue: "1"
  annotations: {}
  extraLabels: {}

# Pod Disruption Budget
podDisruptionBudget:
  enabled: false
  minAvailable: 1
  maxUnavailable:
  unhealthyPodEvictionPolicy: IfHealthyBudget

# 고급 설정
featureGates: ""
labelsExclusionPattern: ""
connectBuildTimeoutMs: 300000

# 환경 변수 (선택사항)
extraEnvs: []
# extraEnvs:
#   - name: JAVA_OPTS
#     value: "-Xms256m -Xmx256m"

# 스케줄링 설정 (선택사항)
tolerations: []
affinity: {}
nodeSelector: {}
priorityClassName: ""

# 보안 컨텍스트 (선택사항)
podSecurityContext: {}
securityContext: {}
```

## 3. custom-values.yaml 설정 설명

### 1) 전역 설정
- 오프라인 환경 배포시 사용한다.

| Name                      | 설명                                                         | 기본값      |
| ------------------------- | ------------------------------------------------------------ | ----------- |
| `defaultImageRegistry`    | 오프라인 설치 시에 설정. <br />paasup 설치시에는 "paasup.io"으로 설정 | `quay.io`   |
| `defaultImageRepository`  | 기본 이미지 리포지토리                                        | `strimzi`   |
| `defaultImageTag`         | 기본 이미지 태그                                             | `0.47.0`    |

### 2) Operator 설정

| Name                      | 설명                                                         | 기본값      |
| ------------------------- | ------------------------------------------------------------ | ----------- |
| `replicas`                | Cluster Operator의 replica 수                                | `1`         |
| `watchAnyNamespace`       | 전체 클러스터(모든 네임스페이스) 감시 여부.<br />true: 모든 네임스페이스 감시<br />false: watchNamespaces에 지정된 네임스페이스만 감시 | `true`      |
| `watchNamespaces`         | watchAnyNamespace가 false일 때 감시할 특정 네임스페이스 목록.<br />예: ["kafka", "streaming"] | `[]`        |
| `logLevel`                | 로그 레벨 설정                                               | `INFO`      |
| `fullReconciliationIntervalMs` | 전체 재조정 간격 (밀리초)                               | `120000`    |
| `operationTimeoutMs`      | 작업 타임아웃 (밀리초)                                       | `300000`    |

#### 네임스페이스 감시 설정 예시

**전체 클러스터 감시 (기본 설정):**
```yaml
watchAnyNamespace: true
watchNamespaces: []  # 이 값은 무시됨
```

**특정 네임스페이스만 감시:**
```yaml
watchAnyNamespace: false
watchNamespaces: 
  - kafka
  - streaming
  - production
```

### 3) 이미지 설정
- 각 컴포넌트별 이미지 설정을 오버라이드할 수 있다.

| Name                      | 설명                                                         | 기본값      |
| ------------------------- | ------------------------------------------------------------ | ----------- |
| `image.registry`          | Cluster Operator 이미지 레지스트리 오버라이드                 | `""`        |
| `image.repository`        | Cluster Operator 이미지 리포지토리 오버라이드                 | `""`        |
| `image.name`              | Cluster Operator 이미지 이름                                 | `operator`  |
| `image.tag`               | Cluster Operator 이미지 태그 오버라이드                       | `""`        |

### 4) 리소스 설정

| Name                      | 설명                                                         | 기본값      |
| ------------------------- | ------------------------------------------------------------ | ----------- |
| `resources.limits.memory` | 메모리 제한                                                  | `384Mi`     |
| `resources.limits.cpu`    | CPU 제한                                                     | `1000m`     |
| `resources.requests.memory` | 메모리 요청                                                | `384Mi`     |
| `resources.requests.cpu`  | CPU 요청                                                     | `200m`      |

### 5) RBAC 및 보안 설정

| Name                      | 설명                                                         | 기본값      |
| ------------------------- | ------------------------------------------------------------ | ----------- |
| `rbac.create`             | RBAC 관련 리소스 생성 여부                                   | `yes`       |
| `serviceAccountCreate`    | ServiceAccount 생성 여부                                     | `yes`       |
| `serviceAccount`          | Cluster Operator의 ServiceAccount 이름                      | `strimzi-cluster-operator` |
| `createGlobalResources`   | 클러스터 범위 리소스 생성 허용                               | `true`      |
| `createAggregateRoles`    | Strimzi CRD와 상호작용하는 집계된 클러스터 역할 생성          | `false`     |

### 6) 네트워크 및 정책 설정

| Name                      | 설명                                                         | 기본값      |
| ------------------------- | ------------------------------------------------------------ | ----------- |
| `generateNetworkPolicy`   | Strimzi가 네트워크 정책 리소스를 생성할지 제어               | `true`      |
| `generatePodDisruptionBudget` | Strimzi가 Pod Disruption Budget 리소스를 생성할지 제어   | `true`      |

### 7) 모니터링 설정

| Name                      | 설명                                                         | 기본값      |
| ------------------------- | ------------------------------------------------------------ | ----------- |
| `dashboards.enabled`      | Grafana 대시보드 ConfigMap 생성                              | `false`     |
| `dashboards.label`        | 사이드카용 대시보드 레이블                                   | `grafana_dashboard` |
| `dashboards.labelValue`   | 사이드카용 대시보드 레이블 값                                | `"1"`       |

### 8) 고급 설정

| Name                      | 설명                                                         | 기본값      |
| ------------------------- | ------------------------------------------------------------ | ----------- |
| `featureGates`            | 기능 게이트 설정                                             | `""`        |
| `labelsExclusionPattern`  | 일부 레이블을 제외하기 위한 패턴 오버라이드                   | `""`        |
| `connectBuildTimeoutMs`   | 새로운 Kafka Connect 빌드의 기본 타임아웃 값 오버라이드       | `300000`    |

## 4. KafkaConnect 및 KafkaConnector 생성 예시

Strimzi Kafka Operator 배포 후 KafkaConnect와 KafkaConnector를 생성하는 예시:

### 1) KafkaConnect 클러스터 생성

```yaml
apiVersion: kafka.strimzi.io/v1beta2
kind: KafkaConnect
metadata:
  name: my-connect-cluster
  namespace: kafka
  annotations:
    strimzi.io/use-connector-resources: "true"
spec:
  version: 3.8.0
  replicas: 3
  bootstrapServers: my-cluster-kafka-bootstrap:9092
  config:
    group.id: connect-cluster
    offset.storage.topic: connect-offsets
    config.storage.topic: connect-configs
    status.storage.topic: connect-status
    key.converter: org.apache.kafka.connect.json.JsonConverter
    value.converter: org.apache.kafka.connect.json.JsonConverter
    plugin.path: /opt/kafka/plugins
  authentication:
    type: plain
    username: user1
    passwordSecret:
        secretName: kafka-cluster-passoword-secret
        password: password
  logging:
    type: inline
    loggers:
      rootLogger.level: INFO
---
apiVersion: kafka.strimzi.io/v1beta2
kind: KafkaConnector
metadata:
  name: debezium-postgres-source
  namespace: kafka
  labels:
    strimzi.io/cluster: my-connect-cluster
spec:
  class: io.debezium.connector.postgresql.PostgresConnector
  tasksMax: 1
  config:
    database.hostname: "postgresql-host"
    database.port: "5432"
    database.user: postgres
    database.password: changeme
    database.dbname: testdb
    database.server.name: pgserver1
    plugin.name: pgoutput
    slot.name: debezium_slot
    publication.autocreate.mode: filtered
    topic.prefix: pg

```

## 5. 주요 기능

### 1) 지원하는 Kafka 생태계 컴포넌트
- **Kafka Cluster**: KRaft 모드로 실행되는 Apache Kafka 클러스터
- **Kafka Connect**: 데이터 소스와 싱크 간의 데이터 이동
- **Kafka MirrorMaker 2**: 서로 다른 Kafka 클러스터 간 데이터 미러링
- **Kafka Bridge**: HTTP 프로토콜을 통한 Kafka 클러스터 접근
- **Cruise Control**: Kafka 클러스터의 파티션 자동 밸런싱

### 2) 관리 기능
- **Topic Management**: Kafka 토픽 생성 및 관리
- **User Management**: Kafka 사용자 생성 및 관리
- **Connector Management**: Kafka Connect 커넥터 생성 및 관리
- **Auto-rebalancing**: 스케일 업/다운 시 자동 리밸런싱
- **Tiered Storage**: 오래된 데이터를 저비용 스토리지로 오프로드

### 3) 모니터링 및 관찰성
- **Prometheus 모니터링**: 내장된 Prometheus 모니터링 지원
- **Grafana 대시보드**: Grafana 사이드카를 통한 대시보드 로딩 지원
- **JMX 메트릭**: Kafka 및 관련 컴포넌트의 JMX 메트릭 노출

## 6. 트러블슈팅

### 1) 일반적인 문제
- **CRD 버전 불일치**: 새 버전 배포 전 CRD를 수동으로 업데이트해야 함
- **권한 부족**: 클러스터 범위 리소스 생성 권한 필요
- **네임스페이스 충돌**: `watchNamespaces`와 `.Release.Namespace`가 같으면 RoleBinding 중복 생성 오류

### 2) 로그 확인
```sh
# Operator 로그 확인
kubectl logs -n kafka deployment/strimzi-cluster-operator

# Kafka 클러스터 상태 확인
kubectl get kafka -n kafka
kubectl describe kafka my-cluster -n kafka
```

### 3) 리소스 상태 확인
```sh
# 모든 Strimzi 리소스 확인
kubectl get strimzi -n kafka

# 특정 리소스 상태 확인
kubectl get kafkatopic -n kafka
kubectl get kafkauser -n kafka