링크세상 링크모음
링크세상 링크모음 링크 애니 웹툰 링크 드라마 영화 링크 세상의모든링크

Strimzi를 사용하여 Kubernetes에서 Kafka 운영

Kubernetes는 Apache Kafka 클러스터를 실행하기 위해 가장 먼저 떠오르는 플랫폼이 아닙니다. 실제로 스토리지에 대한 Kafka의 강력한 의존성은 영구 스토리지와 관련하여 Kubernetes의 작업 방식에 대한 문제점이 될 수 있습니다. Kafka 브로커는 고유하고 상태를 저장합니다. 이를 Kubernetes에서 어떻게 구현할 수 있습니까?

Red Hat이 큐레이팅한 Kubernetes용 Kafka 연산자인 Strimzi의 기본 사항을 살펴보고 이것이 어떤 문제를 해결하는지 살펴보겠습니다.

추가 Kafka 도구를 Strimzi 설치에 연결하는 방법에 특히 중점을 둘 것입니다.

또한 Strimzi의 장단점을 제공하여 다른 Kafka 운영자와 비교할 것입니다.

스트림지


Streamzi 로고

Strimzi는 클라우드 네이티브 인프라에 Apache Kafka 클러스터를 배포하는 비용을 줄이는 것을 목표로 하는 Kubernetes 운영자입니다.

운영자로서 Strimzi는 다음을 포함하여 Kafka 리소스를 기본적으로 관리할 수 있는 리소스를 제공하여 Kubernetes API를 확장합니다.

  • 카프카 클러스터
  • 카프카 주제
  • 카프카 사용자
  • Kafka MirrorMaker2 인스턴스
  • Kafka Connect 인스턴스

이 프로젝트는 현재 Cloud Native Computing Foundation의 “샌드박스” 단계에 있습니다.

메모: CNCF 웹사이트에서는 “샌드박스” 프로젝트를 “최첨단 기술의 생산 환경에서 아직 널리 테스트되지 않은 실험적 프로젝트”로 정의합니다.

Strimzi를 사용하여 TLS 암호화된 브로커 3개 배포 무리 다음 YAML 파일을 적용하는 것만큼 간단합니다.

apiVersion: kafka.strimzi.io/v1beta2
kind: Kafka
metadata:
  name: my-cluster
spec:
  kafka:
    version: 3.2.3
    replicas: 3
    listeners:
      - name: plain
        port: 9092
        type: internal
        tls: false
      - name: tls
        port: 9093
        type: internal
        tls: true
    config:
      offsets.topic.replication.factor: 3
      transaction.state.log.replication.factor: 3
      transaction.state.log.min.isr: 2
      default.replication.factor: 3
      min.insync.replicas: 2
      inter.broker.protocol.version: "3.2"
    storage:
      type: jbod
      volumes:
        - id: 0
          type: persistent-claim
          size: 100Gi
          deleteClaim: false
        - id: 1
          type: persistent-claim
          size: 100Gi
          deleteClaim: false
  zookeeper:
    replicas: 3
    storage:
      type: persistent-claim
      size: 100Gi
      deleteClaim: false
  entityOperator:
    topicOperator: 
    userOperator: 

주제 다음과 같습니다:

apiVersion: kafka.strimzi.io/v1beta2
kind: KafkaTopic
metadata:
  name: my-topic
  labels:
    strimzi.io/cluster: my-cluster
spec:
  partitions: 1
  replicas: 1
  config:
    retention.ms: 7200000
    segment.bytes: 1073741824

이 두 가지 예는 모두 examples Strimzi 운영자의 디렉토리입니다. 이 디렉토리에는 Strimzi의 모든 기능을 다루는 더 많은 예제가 포함되어 있습니다.

보안

Strimzi의 흥미로운 기능은 즉시 사용 가능한 보안 기능. 기본적으로 브로커 내 통신은 TLS로 암호화되는 반면 ZooKeeper와의 통신은 mTLS로 인증 및 암호화됩니다.

Kafka 인스턴스를 지원하는 Apache ZooKeeper 클러스터는 Kubernetes 클러스터 외부에 노출되지 않으므로 추가 보안을 제공합니다.

이러한 구성은 실제로 재정의 불가능scholzj의 Tweak 프로젝트를 사용하여 ZooKeeper에 액세스하는 것이 가능하다고 생각했습니다.

스트림 PodSet

Kubernetes에는 분산 상태 저장 애플리케이션을 관리하기 위한 자체 솔루션이 함께 제공됩니다. StatefulSet.

공식 문서에는 다음과 같이 명시되어 있습니다.

(StatefulSets)는 포드 세트의 배포 및 확장을 관리하고 이러한 포드의 순서와 고유성에 대한 보장을 제공합니다.

StatfulSet은 Kubernetes 기본 리소스라는 이점이 있지만 몇 가지 제한 사항이 있습니다.

다음은 몇 가지 예입니다.

  • 확장 및 축소는 선형입니다. Pod-1, Pod-2, Pod-3의 3개 Pod가 있는 StatefulSet가 있는 경우 확장하면 Pod-4가 생성되고 축소하면 Pod-4만 삭제할 수 있습니다. 이는 배포의 특정 포드를 제거하려는 경우 문제가 될 수 있습니다. Kafka에 적용하면 잘못된 주제로 인해 브로커가 불안정해질 수 있는 상황에 처할 수 있습니다. StatefulSets를 사용하면 이 특정 브로커를 삭제하고 새 새 브로커를 확장할 수 없습니다.
  • 모든 포드는 동일한 사양(CPU, 메모리, PVC 수 등)을 공유합니다.
  • 심각한 노드 오류에는 수동 개입이 필요합니다.

이러한 제한 사항은 Strimzi 팀이 자체 리소스를 개발하여 해결했습니다. StrimziPodSetsStrimzi 0.29.0에 도입된 기능입니다.

StrimziPodSets를 사용하면 다음과 같은 이점이 있습니다.

  • 확장 및 축소가 더욱 유연해졌습니다.
  • 브로커별 구성
  • ZooKeeper가 없는 Kafka가 GA되면 브로커 전문화를 위한 문이 열립니다(KIP-500, 이 주제에 대해서는 기사 뒷부분에서 자세히 설명).

약점 StrimziPodSets를 사용하면 Strimzi Operator 인스턴스가 중요해집니다.

Strimzi PodSet에 대해 더 자세히 알고 싶으시면 StrimziPodSets를 시청해 보세요 – 그것이 무엇이며 왜 관심을 가져야 합니까? Jakub Scholz의 비디오.

Strimzi 배포

Strimzi의 Quickstart 문서는 완벽하게 완벽하고 기능적입니다.

우리는 Strimzi에서 다루지 않는 유용한 문제를 해결하는 데 기사의 나머지 부분을 집중적으로 다룰 것입니다.

Strimzi 기반의 Kafka UI

Strimzi는 Kubernetes에서 Kafka 리소스를 관리할 때 사용자에게 많은 편안함을 제공합니다. 우리는 기본 Kubernetes 리소스로 Strimzi 클러스터 위에 Kafka UI를 배포하는 방법을 보여줌으로써 뭔가를 테이블에 가져오고 싶었습니다.

몇 가지를 인용하자면 GitHub에는 여러 오픈 소스 Kafka UI 프로젝트가 있습니다.

가자 카프카 UI 경쟁사 중에서 가장 깨끗한 UI(IMO)를 가지고 있습니다.

이 프로젝트는 문서에서 볼 수 있듯이 공식 Docker 이미지를 제공합니다. 이 이미지를 활용하고 Kafka UI 인스턴스를 Kubernetes 배포로 배포하겠습니다.

다음 YAML은 다음을 통해 구성된 Kafka UI 인스턴스의 예입니다. SCRAM-SHA-512 인증된 Strimzi Kafka 클러스터. UI는 다음을 통해 OpenLDAP에 대해 인증됩니다. ldaps.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: cluster-kafka-ui
  namespace: kafka
spec:
  selector:
    matchLabels:
      app: cluster-kafka-ui
  template:
    metadata:
      labels:
        app: cluster-kafka-ui
    spec:
      containers:
        - image: provectuslabs/kafka-ui:v0.4.0
          name: kafka-ui
          ports:
            - containerPort: 8080
          env:
            - name: KAFKA_CLUSTERS_0_NAME
              value: "cluster"
            - name: KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS
              value: "cluster-kafka-bootstrap:9092"
            - name: KAFKA_CLUSTERS_0_PROPERTIES_SECURITY_PROTOCOL
              value: SASL_PLAINTEXT
            - name: KAFKA_CLUSTERS_0_PROPERTIES_SASL_MECHANISM
              value: SCRAM-SHA-512
            - name: KAFKA_CLUSTERS_0_PROPERTIES_SASL_JAAS_CONFIG
              value: 'org.apache.kafka.common.security.scram.ScramLoginModule required username="admin" password="XSnBiq6pkFNp";'
            
            - name: AUTH_TYPE
              value: LDAP
            - name: SPRING_LDAP_URLS
              value: ldaps://myldapinstance.company:636
            - name: SPRING_LDAP_DN_PATTERN
              value: uid=0,ou=People,dc=company
            - name: SPRING_LDAP_ADMINUSER
              value: uid=admin,ou=Apps,dc=company
            - name: SPRING_LDAP_ADMINPASSWORD
              value: Adm1nP@ssw0rd!
            
            - name: JAVA_OPTS
              value: "-Djdk.tls.client.cipherSuites=TLS_RSA_WITH_AES_128_GCM_SHA256 -Djavax.net.ssl.trustStore=/etc/kafka-ui/ssl/truststore.jks"
          volumeMounts:
            - name: truststore
              mountPath: /etc/kafka-ui/ssl
              readOnly: true
      volumes:
        - name: truststore
          secret:
            secretName: myldap-truststore

메모: 활용하여 PLAINTEXT 포트 9092의 내부 수신기에서는 KAFKA_CLUSTERS_0_PROPERTIES_SSL_TRUSTSTORE_LOCATION 구성.

이 구성을 사용하면 사용자는 LDAP를 통해 Kafka UI에 인증해야 합니다. 로그인한 후에는 Kafka 클러스터와의 상호 작용에 사용되는 기본 사용자는 다음에 정의된 관리자입니다. KAFKA_CLUSTERS_0_PROPERTIES_SASL_JAAS_CONFIG. 이 문제와 관련하여 최근 역할 기반 액세스 제어가 도입되었습니다.

Strimzi를 사용한 스키마 레지스트리

우리는 기능적으로 다음을 배포해야 했습니다. 스키마 레지스트리 Kubernetes에서 실행되는 Kafka 클러스터용 인스턴스입니다.

Strimzi는 Kafka Connect 또는 MirrorMaker 인스턴스와 같은 추가 도구를 관리하여 추가 노력을 기울이고 있지만 아직 스키마 레지스트리를 배포할 수는 없습니다.

이 문제를 완화하기 위해 Rubin Observatory Science 품질 및 신뢰성 엔지니어링 팀은 strimzi-registry-operator를 작업했습니다.

우리가 사용한 구성은 README의 예제 섹션에 표시된 구성입니다.

우리가 직면한 유일한 문제는 운영자가 아직 백업된 스키마 레지스트리를 배포할 수 없다는 것입니다. SCRAM-SHA-512 보안 클러스터.

ZooKeeper가 없는 Kafka는 어떻습니까?

KIP-500에 대한 수년간의 작업 끝에 Apache Kafka 팀은 마침내 Kafka를 다음에서 실행한다고 발표했습니다. 파워 패션 (ZooKeeper less)가 생산 준비가 되었습니다. 이 발표는 Kafka 3.3 릴리스의 일부로 이루어졌습니다.

Strimzi 팀은 Strimzi 0.29.0에서 KRaft 모드 작업을 시작했습니다. Strimzi 문서에 명시된 대로 이 기능은 Kafka 및 Strimzi 수준 모두에서 아직 실험적입니다.

Strimzi의 주요 기여자인 Jakub Scholz는 이 문제에 대해 다음과 같이 논평했습니다.

새로운 클러스터를 위한 프로덕션 준비가 완료되었다고 말하는 것이 조금 이상하다고 생각합니다. 이는 업그레이드가 보장되는 등 두 개의 병렬 코드 경로를 아마도 오랫동안 유지해야 함을 의미합니다. 그래서 TBH, 저는 우리가 이 시점에서 훨씬 더 많은 진전을 이루고 ZooKeeper 제거에 더 잘 대비할 수 있기를 바랐습니다. 하지만 내 개인적인 의견으로는 어쨌든 현 단계에서 제작 준비가 완료된 제품이라고 말하기는 매우 꺼릴 것 같습니다.

이러한 의견에 따라 우리는 ZooKeeper가 없는 Kafka가 다음 릴리스(작성 당시 0.34.0)에서 Strimzi의 기본 구성이 아닐 것이라고 추측할 수 있지만 어느 시점에서는 확실히 그렇게 될 것입니다.

스토리지는 어떻습니까?

스토리지는 베어메탈 Kubernetes 클러스터의 문제점인 경우가 많으며 Kafka도 예외는 아닙니다.

Kubernetes에서 스토리지 프로비저닝에 대한 커뮤니티 합의는 다른 솔루션이 존재한다고 생각하는 Rook과 Ceph를 통해 이루어집니다(오픈 소스 측에서는 Longhorn 또는 OpenEBS, 독점 솔루션은 Portworx 또는 Linstor).

베어메탈 Kubernetes 클러스터의 스토리지 엔진을 비교하는 것은 이 기사에 포함하기에는 너무 큰 주제이지만, Rook에 대한 자세한 내용은 이전 기사 “Rook을 사용하는 Kubernetes 클러스터 내의 Ceph 객체 스토리지”를 자유롭게 확인하세요.

우리는 Strimzi/Rook Ceph를 사용한 3개의 브로커 Kafka 설치와 직접 디스크 액세스를 통해 동일한 시스템에서 실행되는 3개의 브로커 Kafka 클러스터 간의 성능을 비교할 기회를 가졌습니다.

벤치마크의 사양과 결과는 다음과 같습니다.

명세서

Kubernetes 환경:

  • Strimzi를 통해 Kubernetes의 Kafka 버전 3.2.0
  • 브로커 3개(노드당 포드 1개)
  • 브로커당 RBD 장치 6개(Rook Ceph Storage Class에서 제공)
  • Xms 자바 기본값(2g)
  • Xmx 자바 기본값(29g)

베어메탈 환경:

  • Apache 릴리스가 포함된 JVM 프로세스인 Kafka 버전 3.2.0
  • 브로커 3개(노드당 JVM 1개)
  • 브로커당 RBD 장치 6개(ext4 형식의 JBOD)
  • Xms 자바 기본값(2g)
  • Xmx 자바 기본값(29g)

노트: 벤치마크는 RHEL 7.9가 설치된 동일한 시스템(192Gb RAM 및 6 x 2TB 디스크가 있는 HP Gen 7)에서 실행되었습니다. Kafka as JVM 프로세스가 실행 중일 때 Kubernetes가 실행되지 않았으며 그 반대의 경우도 마찬가지였습니다.

kafka-producer-perf-test \
--topic my-topic-benchmark \
--record-size 1000 \
--throughput -1 \
--producer.config /mnt/kafka.properties \
--num-records 50000000

메모: 주제 my-topic-benchmark 100개의 파티션과 1개의 복제본이 있습니다.

결과

각 구성에 대해 이전 벤치마크를 10회 실행하고 결과를 평균화했습니다.

미터법 JBOD 베어메탈 세프 RBD 성능 차이
레코드/초 75223 65207 – 13.3%
평균 대기 시간 1.45 1.28 + 11.1%

결과는 흥미롭습니다. 쓰기 성능은 JBOD에서 더 좋았지만 Ceph를 사용하면 대기 시간이 더 느려졌습니다.

Strimzi 대안

Kubernetes에서 Kafka를 운영하는 경우 Strimzi에 대한 두 가지 주요 대안이 있습니다.

우리는 Koperator를 철저히 테스트하지 않았으므로 이 기사에서 Strimzi와 비교하는 것은 불공평합니다.

Confluent 연산자의 경우 Strimzi에는 없는 많은 기능을 제공합니다. 다음은 우리가 흥미롭다고 생각한 몇 가지 사항입니다.

  • 스키마 레지스트리 통합
  • ksqlDB 통합
  • LDAP 인증 지원
  • 관리자와 개발자 모두를 위한 기본 UI(Confluent Control Center)
  • 경고
  • 계층형 스토리지

이 모든 것에는 Confluent에서 상업용 라이센스를 구입하는 비용(말 그대로)이 포함됩니다. 운영자와 제어 센터는 30일 평가판 기간 동안 테스트할 수 있습니다.