diff --git a/content/en/examples/resource-provisioners/default/kafka-topic/score-k8s/template/kafka-topic.md b/content/en/examples/resource-provisioners/default/kafka-topic/score-k8s/template/kafka-topic.md new file mode 100644 index 00000000..5afb5dd0 --- /dev/null +++ b/content/en/examples/resource-provisioners/default/kafka-topic/score-k8s/template/kafka-topic.md @@ -0,0 +1,24 @@ +--- +title: "kafka-topic" +draft: false +mermaid: true +type: examples +source: "default" +implementation: "score-k8s" +resourceType: "kafka-topic" +provisionerType: "template" +flavor: "kafka" +excerpt: '' +description: 'Provisions a dedicated Kafka topic on an in-cluster Kafka broker.' +expectedOutputs: + - host + - port + - name + - num_partitions +hasMore: false + +--- + +{{% resource-provisioner-content description="Provisions a dedicated Kafka topic on an in-cluster Kafka broker." type="kafka-topic" expectedOutputs="host,port,name,num_partitions" %}} + +{{% example-file filename="provisioners.yaml" dir="resource-provisioners/default/kafka-topic/score-k8s" githubUrl="https://github.com/score-spec/score-k8s/blob/main/internal/provisioners/default/zz-default.provisioners.yaml" %}} diff --git a/gen/external-content/resource-provisioners/default/kafka-topic/score-compose/provisioners.yaml b/gen/external-content/resource-provisioners/default/kafka-topic/score-compose/provisioners.yaml index 08c3b6b1..c8f68949 100644 --- a/gen/external-content/resource-provisioners/default/kafka-topic/score-compose/provisioners.yaml +++ b/gen/external-content/resource-provisioners/default/kafka-topic/score-compose/provisioners.yaml @@ -10,16 +10,20 @@ shared_kafka_instance_name: {{ dig "shared_kafka_instance_name" (print "kafka-" (randAlphaNum 6)) .Shared | quote }} services: | {{ .Shared.shared_kafka_instance_name }}: - image: bitnami/kafka:latest + image: apache/kafka:latest restart: always environment: - KAFKA_CFG_NODE_ID: "0" - KAFKA_CFG_PROCESS_ROLES: controller,broker - KAFKA_CFG_LISTENERS: "PLAINTEXT://:{{ .Init.brokerPort }},CONTROLLER://:{{ .Init.ctrlPort }}" - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP: "CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT" - KAFKA_CFG_CONTROLLER_QUORUM_VOTERS: "0@{{ .Shared.shared_kafka_instance_name }}:{{ .Init.ctrlPort }}" - KAFKA_CFG_CONTROLLER_LISTENER_NAMES: CONTROLLER - KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE: "false" + KAFKA_NODE_ID: "1" + KAFKA_PROCESS_ROLES: broker,controller + KAFKA_LISTENERS: "PLAINTEXT://:{{ .Init.brokerPort }},CONTROLLER://:{{ .Init.ctrlPort }}" + KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: "CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT" + KAFKA_CONTROLLER_QUORUM_VOTERS: "1@{{ .Shared.shared_kafka_instance_name }}:{{ .Init.ctrlPort }}" + KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER + KAFKA_AUTO_CREATE_TOPICS_ENABLE: "false" + KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: "1" + KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: "1" + KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: "1" + KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: "0" healthcheck: test: ["CMD", "kafka-topics.sh", "--list", "--bootstrap-server=localhost:{{ .Init.brokerPort }}"] interval: 2s @@ -34,11 +38,11 @@ volumes: - type: volume source: {{ .Shared.shared_kafka_instance_name }}-data - target: /bitnami/kafka + target: /var/lib/kafka/data {{ .State.topic }}-init: - image: bitnami/kafka:latest + image: apache/kafka:latest entrypoint: ["/bin/sh"] - command: ["-c", "kafka-topics.sh --topic={{.State.topic}} --bootstrap-server=localhost:{{ .Init.brokerPort }} --describe || kafka-topics.sh --topic={{.State.topic}} --bootstrap-server=localhost:{{ .Init.brokerPort }} --create --partitions=3"] + command: ["-c", "kafka-topics.sh --topic={{.State.topic}} --bootstrap-server=localhost:{{ .Init.brokerPort }} --describe || kafka-topics.sh --topic={{.State.topic}} --bootstrap-server=localhost:{{ .Init.brokerPort }} --create --partitions=3 --replication-factor=1"] network_mode: "service:{{ .Shared.shared_kafka_instance_name }}" labels: dev.score.compose.labels.is-init-container: "true" diff --git a/gen/external-content/resource-provisioners/default/kafka-topic/score-k8s/provisioners.yaml b/gen/external-content/resource-provisioners/default/kafka-topic/score-k8s/provisioners.yaml new file mode 100644 index 00000000..0f4e6016 --- /dev/null +++ b/gen/external-content/resource-provisioners/default/kafka-topic/score-k8s/provisioners.yaml @@ -0,0 +1,202 @@ +- uri: template://default-provisioners/kafka-topic + type: kafka-topic + description: Provisions a dedicated Kafka topic on an in-cluster Kafka broker. + init: | + brokerPort: 9092 + ctrlPort: 9093 + randomTopic: topic-{{ randAlphaNum 6 }} + state: | + topic: {{ dig "topic" .Init.randomTopic .State | quote }} + shared: | + shared_kafka_instance_name: {{ dig "shared_kafka_instance_name" (print "kafka-" (randAlphaNum 6)) .Shared | quote }} + outputs: | + host: {{ .Shared.shared_kafka_instance_name }} + port: {{ .Init.brokerPort }} + name: {{ .State.topic }} + num_partitions: 3 + manifests: | + {{ $broker := .Shared.shared_kafka_instance_name }} + - apiVersion: apps/v1 + kind: StatefulSet + metadata: + name: {{ $broker }} + {{ if ne .Namespace "" }} + namespace: {{ .Namespace }} + {{ end }} + annotations: + k8s.score.dev/source-workload: {{ .SourceWorkload }} + k8s.score.dev/resource-uid: {{ .Uid }} + k8s.score.dev/resource-guid: {{ .Guid }} + labels: + app.kubernetes.io/managed-by: score-k8s + app.kubernetes.io/name: {{ $broker }} + app.kubernetes.io/instance: {{ $broker }} + spec: + replicas: 1 + serviceName: {{ $broker }} + selector: + matchLabels: + app.kubernetes.io/instance: {{ $broker }} + template: + metadata: + labels: + app.kubernetes.io/managed-by: score-k8s + app.kubernetes.io/name: {{ $broker }} + app.kubernetes.io/instance: {{ $broker }} + annotations: + k8s.score.dev/source-workload: {{ .SourceWorkload }} + k8s.score.dev/resource-uid: {{ .Uid }} + k8s.score.dev/resource-guid: {{ .Guid }} + spec: + automountServiceAccountToken: false + containers: + - name: kafka + image: apache/kafka:latest + ports: + - name: kafka + containerPort: {{ .Init.brokerPort }} + env: + - name: KAFKA_NODE_ID + value: "1" + - name: KAFKA_PROCESS_ROLES + value: broker,controller + - name: KAFKA_LISTENERS + value: "PLAINTEXT://:{{ .Init.brokerPort }},CONTROLLER://:{{ .Init.ctrlPort }}" + - name: KAFKA_ADVERTISED_LISTENERS + value: "PLAINTEXT://{{ $broker }}:{{ .Init.brokerPort }}" + - name: KAFKA_LISTENER_SECURITY_PROTOCOL_MAP + value: "CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT" + - name: KAFKA_CONTROLLER_QUORUM_VOTERS + value: "1@{{ $broker }}:{{ .Init.ctrlPort }}" + - name: KAFKA_CONTROLLER_LISTENER_NAMES + value: CONTROLLER + - name: KAFKA_AUTO_CREATE_TOPICS_ENABLE + value: "false" + - name: KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR + value: "1" + - name: KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR + value: "1" + - name: KAFKA_TRANSACTION_STATE_LOG_MIN_ISR + value: "1" + - name: KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS + value: "0" + readinessProbe: + exec: + command: + - /opt/kafka/bin/kafka-topics.sh + - --list + - --bootstrap-server=localhost:{{ .Init.brokerPort }} + initialDelaySeconds: 10 + periodSeconds: 5 + failureThreshold: 12 + securityContext: + allowPrivilegeEscalation: false + privileged: false + capabilities: + drop: + - ALL + volumeMounts: + - name: kafka-data + mountPath: /var/lib/kafka/data + securityContext: + fsGroup: 1000 + runAsGroup: 1000 + runAsNonRoot: true + runAsUser: 1000 + seccompProfile: + type: RuntimeDefault + volumeClaimTemplates: + - metadata: + name: kafka-data + annotations: + k8s.score.dev/source-workload: {{ .SourceWorkload }} + k8s.score.dev/resource-uid: {{ .Uid }} + k8s.score.dev/resource-guid: {{ .Guid }} + labels: + app.kubernetes.io/managed-by: score-k8s + app.kubernetes.io/name: {{ $broker }} + app.kubernetes.io/instance: {{ $broker }} + spec: + accessModes: ["ReadWriteOnce"] + resources: + requests: + storage: 1Gi + - apiVersion: v1 + kind: Service + metadata: + name: {{ $broker }} + {{ if ne .Namespace "" }} + namespace: {{ .Namespace }} + {{ end }} + annotations: + k8s.score.dev/source-workload: {{ .SourceWorkload }} + k8s.score.dev/resource-uid: {{ .Uid }} + k8s.score.dev/resource-guid: {{ .Guid }} + labels: + app.kubernetes.io/managed-by: score-k8s + app.kubernetes.io/name: {{ $broker }} + app.kubernetes.io/instance: {{ $broker }} + spec: + selector: + app.kubernetes.io/instance: {{ $broker }} + type: ClusterIP + ports: + - port: {{ .Init.brokerPort }} + targetPort: {{ .Init.brokerPort }} + - apiVersion: batch/v1 + kind: Job + metadata: + name: {{ $broker }}-{{ .State.topic | replace "." "-" }}-init + {{ if ne .Namespace "" }} + namespace: {{ .Namespace }} + {{ end }} + annotations: + k8s.score.dev/source-workload: {{ .SourceWorkload }} + k8s.score.dev/resource-uid: {{ .Uid }} + k8s.score.dev/resource-guid: {{ .Guid }} + labels: + app.kubernetes.io/managed-by: score-k8s + app.kubernetes.io/name: {{ $broker }}-{{ .State.topic | replace "." "-" }}-init + app.kubernetes.io/instance: {{ $broker }} + spec: + backoffLimit: 10 + template: + metadata: + labels: + app.kubernetes.io/managed-by: score-k8s + app.kubernetes.io/name: {{ $broker }}-{{ .State.topic | replace "." "-" }}-init + app.kubernetes.io/instance: {{ $broker }} + spec: + restartPolicy: OnFailure + automountServiceAccountToken: false + containers: + - name: kafka-topic-init + image: apache/kafka:latest + command: + - /bin/sh + - -c + - | + /opt/kafka/bin/kafka-topics.sh \ + --bootstrap-server={{ $broker }}:{{ .Init.brokerPort }} \ + --describe --topic={{ .State.topic }} \ + || /opt/kafka/bin/kafka-topics.sh \ + --bootstrap-server={{ $broker }}:{{ .Init.brokerPort }} \ + --create \ + --topic={{ .State.topic }} \ + --partitions=3 \ + --replication-factor=1 + securityContext: + allowPrivilegeEscalation: false + privileged: false + capabilities: + drop: + - ALL + securityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + expected_outputs: + - host + - port + - name + - num_partitions \ No newline at end of file