From b8b7bc0a6c13a33ff8dcf8a8496ef7925550bdda Mon Sep 17 00:00:00 2001 From: Michael Edgar Date: Thu, 22 Aug 2024 05:53:02 -0400 Subject: [PATCH] wip: [Docs] Revamp the documentation, install files, and examples Signed-off-by: Michael Edgar --- .github/workflows/playwright-tests.yml | 98 +++++---- README.md | 133 +++++++++---- api/examples/configmap-kafka-metrics.yaml | 184 ----------------- .../kafka-ephemeral-ingress-kraft.yaml | 122 ------------ api/examples/kafka-ephemeral-ingress.yaml | 98 --------- .../metrics/prometheus-additional.yaml | 94 --------- .../metrics/prometheus-pod-monitors.yaml | 82 -------- api/examples/metrics/prometheus-rules.yaml | 186 ------------------ api/examples/metrics/prometheus.yaml | 75 ------- api/hack/binscripts.properties | 6 - api/hack/gen-ca.sh | 10 - api/hack/gen-kafka-certs.sh | 50 ----- api/hack/kcat.properties | 4 - examples/console/010-Console-example.yaml | 24 +++ .../010-ConfigMap-console-kafka-metrics.yaml | 1 + .../020-KafkaNodePool-console-nodepool.yaml | 1 + .../kafka/030-Kafka-console-kafka.yaml | 1 + .../040-KafkaUser-console-kafka-user1.yaml | 1 + ...viceAccount-console-prometheus-server.yaml | 0 ...ClusterRole-console-prometheus-server.yaml | 0 ...RoleBinding-console-prometheus-server.yaml | 0 .../040-PodMonitor-kafka-resources.yaml | 0 .../050-Secret-kubernetes-scrape-configs.yaml | 0 .../060-Prometheus-console-prometheus.yaml | 0 .../070-Service-console-prometheus.yaml | 0 .../080-Ingress-console-prometheus.yaml | 0 install/000-install-dependency-operators.sh | 48 ----- install/001-deploy-prometheus.sh | 35 ---- install/002-deploy-console-kafka.sh | 47 ----- install/003-install-console-operator.sh | 36 ---- install/README.md | 121 ------------ install/_common.sh | 82 -------- .../010-ServiceAccount-console-server.yaml} | 0 .../020-ClusterRole-console-server.yaml} | 0 ...30-ClusterRoleBinding-console-server.yaml} | 0 .../040-Deployment-console.yaml} | 0 .../050-Service-console-ui.yaml} | 0 .../060-Ingress-console-ui.yaml} | 0 .../000-OperatorGroup-console-operator.yaml} | 6 +- ...atalogSource-console-operator-catalog.yaml | 10 + .../020-Subscription-console-operator.yaml | 10 + .../resources/console/console-ui.route.yaml | 13 -- .../resources/console/console.instance.yaml | 13 -- .../kafka/console-kafka-zk.kafka.yaml | 65 ------ .../console-operators.operatorgroup.yaml | 8 - operator/src/main/kubernetes/kubernetes.yml | 31 +-- 46 files changed, 196 insertions(+), 1499 deletions(-) delete mode 100644 api/examples/configmap-kafka-metrics.yaml delete mode 100644 api/examples/kafka-ephemeral-ingress-kraft.yaml delete mode 100644 api/examples/kafka-ephemeral-ingress.yaml delete mode 100644 api/examples/metrics/prometheus-additional.yaml delete mode 100644 api/examples/metrics/prometheus-pod-monitors.yaml delete mode 100644 api/examples/metrics/prometheus-rules.yaml delete mode 100644 api/examples/metrics/prometheus.yaml delete mode 100644 api/hack/binscripts.properties delete mode 100755 api/hack/gen-ca.sh delete mode 100755 api/hack/gen-kafka-certs.sh delete mode 100644 api/hack/kcat.properties create mode 100644 examples/console/010-Console-example.yaml rename install/resources/kafka/console-kafka-metrics.configmap.yaml => examples/kafka/010-ConfigMap-console-kafka-metrics.yaml (99%) rename install/resources/kafka/console-nodepool.kafkanodepool.yaml => examples/kafka/020-KafkaNodePool-console-nodepool.yaml (98%) rename install/resources/kafka/console-kafka.kafka.yaml => examples/kafka/030-Kafka-console-kafka.yaml (99%) rename install/resources/kafka/console-kafka-user1.kafkauser.yaml => examples/kafka/040-KafkaUser-console-kafka-user1.yaml (97%) rename install/resources/prometheus/console-prometheus-server.serviceaccount.yaml => examples/prometheus/010-ServiceAccount-console-prometheus-server.yaml (100%) rename install/resources/prometheus/console-prometheus-server.clusterrole.yaml => examples/prometheus/020-ClusterRole-console-prometheus-server.yaml (100%) rename install/resources/prometheus/console-prometheus-server.clusterrolebinding.yaml => examples/prometheus/030-ClusterRoleBinding-console-prometheus-server.yaml (100%) rename install/resources/prometheus/kafka-resources.podmonitor.yaml => examples/prometheus/040-PodMonitor-kafka-resources.yaml (100%) rename install/resources/prometheus/kubernetes-scrape-configs.secret.yaml => examples/prometheus/050-Secret-kubernetes-scrape-configs.yaml (100%) rename install/resources/prometheus/console-prometheus.prometheus.yaml => examples/prometheus/060-Prometheus-console-prometheus.yaml (100%) rename install/resources/prometheus/console-prometheus.service.yaml => examples/prometheus/070-Service-console-prometheus.yaml (100%) rename install/resources/prometheus/console-prometheus.ingress.yaml => examples/prometheus/optional/080-Ingress-console-prometheus.yaml (100%) delete mode 100755 install/000-install-dependency-operators.sh delete mode 100755 install/001-deploy-prometheus.sh delete mode 100755 install/002-deploy-console-kafka.sh delete mode 100755 install/003-install-console-operator.sh delete mode 100644 install/README.md delete mode 100644 install/_common.sh rename install/{resources/console/console-server.serviceaccount.yaml => console/010-ServiceAccount-console-server.yaml} (100%) rename install/{resources/console/console-server.clusterrole.yaml => console/020-ClusterRole-console-server.yaml} (100%) rename install/{resources/console/console-server.clusterrolebinding.yaml => console/030-ClusterRoleBinding-console-server.yaml} (100%) rename install/{resources/console/console.deployment.yaml => console/040-Deployment-console.yaml} (100%) rename install/{resources/console/console-ui.service.yaml => console/050-Service-console-ui.yaml} (100%) rename install/{resources/console/console-ui.ingress.yaml => console/060-Ingress-console-ui.yaml} (100%) rename install/{resources/operators/console-operators.operatorgroup.yaml => operator-olm/000-OperatorGroup-console-operator.yaml} (60%) create mode 100644 install/operator-olm/010-CatalogSource-console-operator-catalog.yaml create mode 100644 install/operator-olm/020-Subscription-console-operator.yaml delete mode 100644 install/resources/console/console-ui.route.yaml delete mode 100644 install/resources/console/console.instance.yaml delete mode 100644 install/resources/kafka/console-kafka-zk.kafka.yaml delete mode 100644 install/resources/prometheus/console-operators.operatorgroup.yaml diff --git a/.github/workflows/playwright-tests.yml b/.github/workflows/playwright-tests.yml index 5afd51d3c..52100afe6 100644 --- a/.github/workflows/playwright-tests.yml +++ b/.github/workflows/playwright-tests.yml @@ -6,7 +6,6 @@ on: env: TARGET_NAMESPACE: "console-namespace" CI_CLUSTER: true - CONSOLE_INSTANCE_YAML: "./install/resources/console/console.instance.yaml" OLM_VERSION: "v0.28.0" YQ_VERSION: "v4.44.1" @@ -23,7 +22,7 @@ jobs: uses: medyagh/setup-minikube@latest with: cpus: 2 - memory: 4096m + memory: 8g addons: registry,ingress,ingress-dns insecure-registry: 'localhost:5000,10.0.0.0/24' start-args: '--extra-config=kubeadm.ignore-preflight-errors=SystemVerification --extra-config=apiserver.authorization-mode=RBAC,Node' @@ -89,16 +88,9 @@ jobs: set -x # Create the CatalogSource with the Console operator bundle - echo '--- - apiVersion: operators.coreos.com/v1alpha1 - kind: CatalogSource - metadata: - name: console-operator-catalog - spec: - displayName: StreamsHub - image: localhost:5000/streamshub/console-operator-catalog:${{ env.PROJECT_VERSION }} - publisher: StreamsHub - sourceType: grpc' | kubectl apply -n olm -f - + yq ea '.spec.image = "localhost:5000/streamshub/console-operator-catalog:${{ env.PROJECT_VERSION }}"' \ + ./install/operator-olm/010-CatalogSource-console-operator-catalog.yaml \ + | kubectl apply -n olm -f - kubectl wait catalogsource/console-operator-catalog -n olm \ --for=jsonpath='{.status.connectionState.lastObservedState}'=READY \ @@ -117,58 +109,56 @@ jobs: sourceNamespace: olm' | kubectl apply -n operators -f - # Install Console Operator - echo '--- - apiVersion: operators.coreos.com/v1alpha1 - kind: Subscription - metadata: - name: console-operator - spec: - channel: alpha - name: console-operator - source: console-operator-catalog - sourceNamespace: olm - config: - env: - - name: CONSOLE_DEPLOYMENT_DEFAULT_API_IMAGE - value: localhost:5000/streamshub/console-api:${{ env.PROJECT_VERSION }} - - name: CONSOLE_DEPLOYMENT_DEFAULT_UI_IMAGE - value: localhost:5000/streamshub/console-ui:${{ env.PROJECT_VERSION }} - ' | kubectl apply -n operators -f - - - # Wait for Strimzi Operator - kubectl get deployment --selector=operators.coreos.com/strimzi-kafka-operator.operators -n operators - - while [ $(kubectl get deployment --selector=operators.coreos.com/strimzi-kafka-operator.operators -n operators -o name | wc -l) -lt 1 ] ; do - echo "Waiting for Strimzi Deployment to be present" - sleep 10 - done - - STRIMZI_DEPLOYMENT=$(kubectl get deployment --selector=operators.coreos.com/strimzi-kafka-operator.operators -n operators -o name | tail -1) - echo "Found Strimzi Operator Deployment: ${STRIMZI_DEPLOYMENT}" - kubectl wait ${STRIMZI_DEPLOYMENT} --for=condition=available --timeout=180s -n operators - - # Wait for Console Operator - while [ $(kubectl get deployment --selector=operators.coreos.com/console-operator.operators -n operators -o name | wc -l) -lt 1 ] ; do - echo "Waiting for Console Operator Deployment to be present" - sleep 5 - done - - CONSOLE_DEPLOYMENT=$(kubectl get deployment --selector=operators.coreos.com/strimzi-kafka-operator.operators -n operators -o name | tail -1) - echo "Found Console Operator Deployment: ${CONSOLE_DEPLOYMENT}" - kubectl wait ${CONSOLE_DEPLOYMENT} --for=condition=available --timeout=180s -n operators + yq ea '.spec.sourceNamespace = "olm", .spec.config = { + "env": [{ + "name": "CONSOLE_DEPLOYMENT_DEFAULT_API_IMAGE", + "value": "localhost:5000/streamshub/console-api:${{ env.PROJECT_VERSION }}" + }, { + "name": "CONSOLE_DEPLOYMENT_DEFAULT_UI_IMAGE", + "value": "localhost:5000/streamshub/console-ui:${{ env.PROJECT_VERSION }}" + }] + }' ./install/operator-olm/020-Subscription-console-operator.yaml \ + | kubectl apply -n operators -f - + + wait_operator() { + local OPERATOR=${1} + + while [ $(kubectl get deployment --selector=operators.coreos.com/${OPERATOR}.operators -n operators -o name | wc -l) -lt 1 ] ; do + echo "Waiting for Deployment ${OPERATOR} to be present" + sleep 5 + done + + local OPERATOR_DEPLOYMENT=$(kubectl get deployment --selector=operators.coreos.com/${OPERATOR}.operators -n operators -o name | tail -1) + echo "Found Operator Deployment: ${OPERATOR_DEPLOYMENT}, waiting for condition 'Available'" + kubectl wait ${OPERATOR_DEPLOYMENT} --for=condition=available --timeout=180s -n operators + } + + export -f wait_operator + timeout 300s bash -c 'wait_operator "strimzi-kafka-operator"' + timeout 300s bash -c 'wait_operator "console-operator"' # replace with resources in docs PR - name: Deploy Kafka Cluster & Console run: | set -x - ./install/002-deploy-console-kafka.sh $TARGET_NAMESPACE $CLUSTER_DOMAIN + export LISTENER_TYPE=ingress + cat examples/kafka/*.yaml | envsubst | kubectl apply -n ${TARGET_NAMESPACE} -f - + kubectl wait kafka/console-kafka --for=condition=Ready --timeout=300s -n $TARGET_NAMESPACE kubectl wait kafkauser/console-kafka-user1 --for=condition=Ready --timeout=60s -n $TARGET_NAMESPACE - cat $CONSOLE_INSTANCE_YAML | envsubst && echo - cat $CONSOLE_INSTANCE_YAML | envsubst | kubectl apply -n $TARGET_NAMESPACE -f - + # Display the resource + export KAFKA_NAMESPACE="${TARGET_NAMESPACE}" + + cat examples/console/* | envsubst && echo + + # Apply the resource + cat examples/console/* | envsubst | kubectl apply -n ${TARGET_NAMESPACE} -f - + kubectl wait console/example --for=condition=Ready --timeout=300s -n $TARGET_NAMESPACE + + # Sleep to ensure ingress fully available sleep 10 - name: Console Smoke Test diff --git a/README.md b/README.md index 546d522f1..cb7cffde8 100644 --- a/README.md +++ b/README.md @@ -1,65 +1,123 @@ -# Console for Apache Kafka® on Kubernetes - +# StreamsHub Console for Apache Kafka® [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](http://www.apache.org/licenses/LICENSE-2.0) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=streamshub_console&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=streamshub_console) [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=streamshub_console&metric=coverage)](https://sonarcloud.io/summary/new_code?id=streamshub_console) - -This project is a web console designed to facilitate interactions with Apache Kafka® instances on Kubernetes, leveraging the [Strimzi](https://strimzi.io) Cluster Operator. +StreamsHub Console is a web application designed to facilitate interactions with Apache Kafka® instances, optionally leveraging the [Strimzi](https://strimzi.io) Cluster Operator for Kafka® instances running on Kubernetes. It is composed of three main parts: - - a [REST API](./api) backend developed with Java and [Quarkus](https://quarkus.io/) - a [user interface (UI)](./ui) built with [Next.js](https://nextjs.org/) and [PatternFly](https://patternfly.org) - a Kubernetes [operator](./operator) developed with Java and [Quarkus](https://quarkus.io/) -#### Roadmap / Goals +## Roadmap / Goals The future goals of this project are to provide a user interface to interact with and manage additional data streaming components such as: - - [Apicurio Registry](https://www.apicur.io/registry/) for message serialization and de-serialization + validation - [Kroxylicious](https://kroxylicious.io/) - [Apache Flink](https://flink.apache.org/) Contributions and discussions around use cases for these (and other relevant) components are both welcome and encouraged. -## Running the Application - -The console application may either be run in a Kubernetes cluster or locally to try it out. - -### Install to Kubernetes - -Please refer to the [installation README](./install/README.md) file for detailed information about how to install the latest release of the console in a Kubernetes cluster. - -### Run locally - -Running the console locally requires the use of a remote or locally-running Kubernetes cluster that hosts the Strimzi Kafka operator -and any Apache Kafka® clusters that will be accessed from the console. To get started, you will need to provide a console configuration -file and credentials to connect to the Kubernetes cluster where Strimzi and Kafka are available. +## Deployment +There are several ways to deploy the console - via the operator using the Operator Lifecycle Manager (OLM), via the operator using plain Kubernetes resources, or directly with Kubernetes resources (without the operator). + +Note, if you are using [minikube](https://minikube.sigs.k8s.io/) with the `ingress` addon as your Kubernetes cluster, SSL pass-through must be enabled on the nginx controller: +```shell +# Enable TLS passthrough on the ingress deployment +kubectl patch deployment -n ingress-nginx ingress-nginx-controller \ + --type='json' \ + -p='[{"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value":"--enable-ssl-passthrough"}]' +``` + +### Prerequisites +#### Kafka +The instructions below assume an existing Apache Kafka® cluster is available to use from the console. We recommend using [Strimzi](https://strimzi.io) to create and manage your Apache Kafka® clusters - plus the console provides additional features and insights for Strimzi Apache Kafka® clusters. + +If you already have Strimzi installed but would like to create an Apache Kafka® cluster for use with the console, example resources are available to get started. This example will create an Apache Kafka® cluster in KRaft mode with SCRAM-SHA-512 authentication, a Strimzi `KafkaNodePool` resource to manage the cluster nodes, and a Strimzi `KafkaUser` resource that may be used to connect to the cluster. + +Modify the `CLUSTER_DOMAIN` to match the base domain of your Kubernetes cluster (used for ingress configuration), use either `route` (OpenShift) or `ingress` (vanilla Kubernetes) for `LISTENER_TYPE`, and set `NAMESPACE` to be the namespace where the Apache Kafka® cluster will be created. +```shell +export CLUSTER_DOMAIN=apps-crc.testing +export NAMESPACE=kafka +export LISTENER_TYPE=route +cat examples/kafka/*.yaml | envsubst | kubectl apply -n ${NAMESPACE} -f - +``` +##### Kafka Authorization +In order to allow the necessary access for the console to function, a minimum level of authorization must be configured for the principal in use for each Kafka cluster connection. While the definition of the permissions may vary depending on the authorization framework in use (e.g. ACLs, Keycloak Authorization, OPA, or custom) the minimum required in terms of ACL types are: +1. `DESCRIBE`, `DESCRIBE_CONFIGS` for the `CLUSTER` resource +2. `READ`, `DESCRIBE`, `DESCRIBE_CONFIGS` for all `TOPIC` resources +3. `READ`, `DESCRIBE` for all `GROUP` resources + +#### Prometheus +Prometheus is an optional dependency of the console if cluster metrics are to be displayed. The operator currently installs a private Prometheus instance for each `Console` instance. However, when installing a single console deployment, Prometheus must be either installed separately or provided via a URL reference. This will be addressed below in the section dealing with creating a console via a `Deployment`. + +### Deploy the operator with OLM +The preferred way to deploy the console is using the Operator Lifecycle Manager, or OLM. The sample install files in `install/operator-olm` will install the operator with cluster-wide scope. This means that `Console` instances may be created in any namespace. If you wish to limit the scope of the operator, the `OperatorGroup` resource may be modified to specify only the namespace that should be watched by the operator. + +This example will create the operator's OLM resources in the `default` namespace. Modify the `NAMESPACE` variable according to your needs. +```shell +export NAMESPACE=default +cat install/operator-olm/*.yaml | envsubst | kubectl apply -n ${NAMESPACE} -f - +``` +#### Console Custom Resource Example +Once the operator is ready, you may then create a `Console` resource in the namespace where the console should be deployed. This example `Console` is based on the example Apache Kafka® cluster deployed above in the [prerequisites section](#prerequisites). Also see [examples/console/010-Console-example.yaml](examples/console/010-Console-example.yaml). +```yaml +apiVersion: console.streamshub.github.com/v1alpha1 +kind: Console +metadata: + name: example +spec: + hostname: example-console.apps-crc.testing # Hostname where the console will be accessed via HTTPS + kafkaClusters: + - name: console-kafka # Name of the `Kafka` CR representing the cluster + namespace: kafka # Namespace of the `Kafka` CR representing the cluster + listener: secure # Listener on the `Kafka` CR to connect from the console + properties: + values: [] # Array of name/value for properties to be used for connections + # made to this cluster + valuesFrom: [] # Array of references to ConfigMaps or Secrets with properties + # to be used for connections made to this cluster + credentials: + kafkaUser: + name: console-kafka-user1 # Name of the `KafkaUser` resource used to connect to Kafka + # This is optional if properties are used to configure the user +``` + +### Deploy the operator directly +Deploying the operator without the use of OLM requires applying the component Kubernetes resources for the operator directly. These resources are bundled and attached to each StreamsHub Console release. The latest release can be found [here](https://github.com/streamshub/console/releases/latest). The resource file is named `console-operator-x.y.z.yaml` where `x.y.z` is the released version. + +This example will create the operator's resources in the `default` namespace. Modify the `NAMESPACE` variable according to your needs and set `VERSION` to the [latest release](https://github.com/streamshub/console/releases/latest). +``` +export NAMESPACE=default +export VERSION=0.3.3 +curl -sL https://github.com/streamshub/console/releases/download/${VERSION}/console-operator-${VERSION}.yaml \ + | envsubst \ + | kubectl apply -n ${NAMESPACE} -f - +``` +Note: if you are not using the Prometheus operator you may see an error about a missing `ServiceMonitor` custom resource type. This error may be ignored. + +With the operator resources created, you may create a `Console` resource like the one shown in [Console Custom Resource Example](#console-custom-resource-example). + +## Running locally + +Running the console locally requires configuration of any Apache Kafka® clusters that will be accessed from the console and (optionally) the use of a Kubernetes cluster that hosts the Strimzi Kafka operator. To get started, you will need to provide a console configuration file and (optionally) credentials to connect to the Kubernetes cluster where Strimzi is operating. 1. Using the [console-config-example.yaml](./console-config-example.yaml) file as an example, create your own configuration in a file `console-config.yaml` in the repository root. The `compose.yaml` file expects this location to be used and and difference in name or location requires an adjustment to the compose file. - -2. Install the prerequisite software into the Kubernetes cluster. This step assumes none have yet been installed. - ```shell - ./install/000-install-dependency-operators.sh - ./install/001-deploy-prometheus.sh - ./install/002-deploy-console-kafka.sh - ``` - Note that the Prometheus instance will be available at `http://console-prometheus.` when this step - completes. - -3. Provide the Prometheus endpoint, the API server endpoint, and the service account token that you would like to use to connect to the Kubernetes cluster. These may be placed in a `compose.env` file that will be detected when starting the console. +2. Install the prerequisite software into the Kubernetes cluster. + * Install the [Strimzi operator](https://strimzi.io/docs/operators/latest/deploying#con-strimzi-installation-methods_str) + * Install the [Prometheus operator](https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/user-guides/getting-started.md) and create a `Prometheus` instance (_optional_, only if you want to see metrics in the console) + * Create an Apache Kafka® cluster. See the [example above](#kafka) This step is only required if you do not already have an existing cluster you would like to use with the console. +3. (_Skip this step if you are not using Kubernetes and Prometheus_) Provide the Prometheus endpoint, the API server endpoint, and the service account token that you would like to use to connect to the Kubernetes cluster. These may be placed in a `compose.env` file that will be detected when starting the console. ``` CONSOLE_API_SERVICE_ACCOUNT_TOKEN= CONSOLE_API_KUBERNETES_API_SERVER_URL=https://my-kubernetes-api.example.com:6443 CONSOLE_METRICS_PROMETHEUS_URL=http://console-prometheus. ``` - The service account token may be obtain using the `kubectl create token` command. For example, to create a service account - named "console-server" (from [console-server.serviceaccount.yaml](./install/resources/console/console-server.serviceaccount.yaml) - with the correct permissions and a token that expires in 1 year ([yq](https://github.com/mikefarah/yq/releases) required): + The service account token may be obtained using the `kubectl create token` command. For example, to create a service account named "console-server" with the correct permissions and a token that expires in 1 year ([yq](https://github.com/mikefarah/yq/releases) required): ```shell export NAMESPACE= - kubectl apply -n ${NAMESPACE} -f ./install/resources/console/console-server.clusterrole.yaml - kubectl apply -n ${NAMESPACE} -f ./install/resources/console/console-server.serviceaccount.yaml - yq '.subjects[0].namespace = strenv(NAMESPACE)' ./install/resources/console/console-server.clusterrolebinding.yaml | kubectl apply -n ${NAMESPACE} -f - + kubectl apply -n ${NAMESPACE} -f ./install/console/010-ServiceAccount-console-server.yaml + kubectl apply -n ${NAMESPACE} -f ./install/console/020-ClusterRole-console-server.yaml + cat ./install/console/030-ClusterRoleBinding-console-server.yaml | envsubst | kubectl apply -n ${NAMESPACE} -f - kubectl create token console-server -n ${NAMESPACE} --duration=$((365*24))h ``` @@ -96,3 +154,4 @@ Once approved and the pull request is merged, the release action will execute. T ## License This project is licensed under the Apache License 2.0 - see the LICENSE file for details. + diff --git a/api/examples/configmap-kafka-metrics.yaml b/api/examples/configmap-kafka-metrics.yaml deleted file mode 100644 index f06f14e98..000000000 --- a/api/examples/configmap-kafka-metrics.yaml +++ /dev/null @@ -1,184 +0,0 @@ ---- -kind: ConfigMap -apiVersion: v1 -metadata: - name: ${cluster_name}-kafka-metrics - labels: - app: strimzi -data: - kafka-metrics-config.yml: | - # See https://github.com/prometheus/jmx_exporter for more info about JMX Prometheus Exporter metrics - lowercaseOutputName: true - rules: - # Special cases and very specific rules - - pattern: kafka.server<>Value - name: kafka_server_$1_$2 - type: GAUGE - labels: - clientId: "$3" - topic: "$4" - partition: "$5" - - pattern: kafka.server<>Value - name: kafka_server_$1_$2 - type: GAUGE - labels: - clientId: "$3" - broker: "$4:$5" - - pattern: kafka.server<>connections - name: kafka_server_$1_connections_tls_info - type: GAUGE - labels: - cipher: "$2" - protocol: "$3" - listener: "$4" - networkProcessor: "$5" - - pattern: kafka.server<>connections - name: kafka_server_$1_connections_software - type: GAUGE - labels: - clientSoftwareName: "$2" - clientSoftwareVersion: "$3" - listener: "$4" - networkProcessor: "$5" - - pattern: "kafka.server<>(.+):" - name: kafka_server_$1_$4 - type: GAUGE - labels: - listener: "$2" - networkProcessor: "$3" - - pattern: kafka.server<>(.+) - name: kafka_server_$1_$4 - type: GAUGE - labels: - listener: "$2" - networkProcessor: "$3" - # Some percent metrics use MeanRate attribute - # Ex) kafka.server<>MeanRate - - pattern: kafka.(\w+)<>MeanRate - name: kafka_$1_$2_$3_percent - type: GAUGE - # Generic gauges for percents - - pattern: kafka.(\w+)<>Value - name: kafka_$1_$2_$3_percent - type: GAUGE - - pattern: kafka.(\w+)<>Value - name: kafka_$1_$2_$3_percent - type: GAUGE - labels: - "$4": "$5" - # Generic per-second counters with 0-2 key/value pairs - - pattern: kafka.(\w+)<>Count - name: kafka_$1_$2_$3_total - type: COUNTER - labels: - "$4": "$5" - "$6": "$7" - - pattern: kafka.(\w+)<>Count - name: kafka_$1_$2_$3_total - type: COUNTER - labels: - "$4": "$5" - - pattern: kafka.(\w+)<>Count - name: kafka_$1_$2_$3_total - type: COUNTER - # Generic gauges with 0-2 key/value pairs - - pattern: kafka.(\w+)<>Value - name: kafka_$1_$2_$3 - type: GAUGE - labels: - "$4": "$5" - "$6": "$7" - - pattern: kafka.(\w+)<>Value - name: kafka_$1_$2_$3 - type: GAUGE - labels: - "$4": "$5" - - pattern: kafka.(\w+)<>Value - name: kafka_$1_$2_$3 - type: GAUGE - # Emulate Prometheus 'Summary' metrics for the exported 'Histogram's. - # Note that these are missing the '_sum' metric! - - pattern: kafka.(\w+)<>Count - name: kafka_$1_$2_$3_count - type: COUNTER - labels: - "$4": "$5" - "$6": "$7" - - pattern: kafka.(\w+)<>(\d+)thPercentile - name: kafka_$1_$2_$3 - type: GAUGE - labels: - "$4": "$5" - "$6": "$7" - quantile: "0.$8" - - pattern: kafka.(\w+)<>Count - name: kafka_$1_$2_$3_count - type: COUNTER - labels: - "$4": "$5" - - pattern: kafka.(\w+)<>(\d+)thPercentile - name: kafka_$1_$2_$3 - type: GAUGE - labels: - "$4": "$5" - quantile: "0.$6" - - pattern: kafka.(\w+)<>Count - name: kafka_$1_$2_$3_count - type: COUNTER - - pattern: kafka.(\w+)<>(\d+)thPercentile - name: kafka_$1_$2_$3 - type: GAUGE - labels: - quantile: "0.$4" - # KRaft mode: uncomment the following lines to export KRaft related metrics - # KRaft overall related metrics - # distinguish between always increasing COUNTER (total and max) and variable GAUGE (all others) metrics - #- pattern: "kafka.server<>(.+-total|.+-max):" - # name: kafka_server_raftmetrics_$1 - # type: COUNTER - #- pattern: "kafka.server<>(.+):" - # name: kafka_server_raftmetrics_$1 - # type: GAUGE - # KRaft "low level" channels related metrics - # distinguish between always increasing COUNTER (total and max) and variable GAUGE (all others) metrics - #- pattern: "kafka.server<>(.+-total|.+-max):" - # name: kafka_server_raftchannelmetrics_$1 - # type: COUNTER - #- pattern: "kafka.server<>(.+):" - # name: kafka_server_raftchannelmetrics_$1 - # type: GAUGE - # Broker metrics related to fetching metadata topic records in KRaft mode - #- pattern: "kafka.server<>(.+):" - # name: kafka_server_brokermetadatametrics_$1 - # type: GAUGE - zookeeper-metrics-config.yml: | - # See https://github.com/prometheus/jmx_exporter for more info about JMX Prometheus Exporter metrics - lowercaseOutputName: true - rules: - # replicated Zookeeper - - pattern: "org.apache.ZooKeeperService<>(\\w+)" - name: "zookeeper_$2" - type: GAUGE - - pattern: "org.apache.ZooKeeperService<>(\\w+)" - name: "zookeeper_$3" - type: GAUGE - labels: - replicaId: "$2" - - pattern: "org.apache.ZooKeeperService<>(Packets\\w+)" - name: "zookeeper_$4" - type: COUNTER - labels: - replicaId: "$2" - memberType: "$3" - - pattern: "org.apache.ZooKeeperService<>(\\w+)" - name: "zookeeper_$4" - type: GAUGE - labels: - replicaId: "$2" - memberType: "$3" - - pattern: "org.apache.ZooKeeperService<>(\\w+)" - name: "zookeeper_$4_$5" - type: GAUGE - labels: - replicaId: "$2" - memberType: "$3" diff --git a/api/examples/kafka-ephemeral-ingress-kraft.yaml b/api/examples/kafka-ephemeral-ingress-kraft.yaml deleted file mode 100644 index a8b57abaf..000000000 --- a/api/examples/kafka-ephemeral-ingress-kraft.yaml +++ /dev/null @@ -1,122 +0,0 @@ -apiVersion: kafka.strimzi.io/v1beta2 -kind: KafkaNodePool -metadata: - name: dual-role - labels: - strimzi.io/cluster: ${cluster_name} -spec: - replicas: 3 - roles: - - controller - - broker - storage: - type: jbod - volumes: - - id: 0 - type: persistent-claim - size: 1Gi - deleteClaim: false ---- -apiVersion: kafka.strimzi.io/v1beta2 -kind: Kafka -metadata: - name: ${cluster_name} - annotations: - strimzi.io/node-pools: enabled - strimzi.io/kraft: enabled -spec: - kafka: - version: 3.6.0 - replicas: 3 - resources: - limits: - cpu: 500m - memory: 1Gi - requests: - cpu: 75m - memory: 1Gi - authorization: - type: simple - listeners: - - name: secure - port: 9092 - type: ingress - tls: true - configuration: - bootstrap: - host: bootstrap.${cluster_name}.${kube_ip}.nip.io - brokers: - - broker: 0 - host: broker-0.${cluster_name}.${kube_ip}.nip.io - - broker: 1 - host: broker-1.${cluster_name}.${kube_ip}.nip.io - - broker: 2 - host: broker-2.${cluster_name}.${kube_ip}.nip.io - # OAUTH LISTENER BEGIN - - name: oauth - port: 9093 - type: ingress - tls: true - configuration: - bootstrap: - host: bootstrap-oauth.${cluster_name}.${kube_ip}.nip.io - annotations: - "streamshub.github.com/console-listener": "true" - brokers: - - broker: 0 - host: broker-0-oauth.${cluster_name}.${kube_ip}.nip.io - - broker: 1 - host: broker-1-oauth.${cluster_name}.${kube_ip}.nip.io - - broker: 2 - host: broker-2-oauth.${cluster_name}.${kube_ip}.nip.io - authentication: - jwksEndpointUri: "${keycloak_realm_url}/protocol/openid-connect/certs" - type: oauth - userNameClaim: preferred_username - validIssuerUri: "${keycloak_realm_url}" - # OAUTH LISTENER END - 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.5" - allow.everyone.if.no.acl.found: "true" - storage: - volumes: - - type: "persistent-claim" - size: "1Gi" - deleteClaim: true - id: 0 - type: "jbod" - metricsConfig: - type: jmxPrometheusExporter - valueFrom: - configMapKeyRef: - name: ${cluster_name}-kafka-metrics - key: kafka-metrics-config.yml - # The ZooKeeper section is required by the Kafka CRD schema while the UseKRaft feature gate is in alpha phase. - # But it will be ignored when running in KRaft mode - zookeeper: - replicas: 3 - resources: - limits: - cpu: 200m - memory: 512Mi - requests: - cpu: 75m - memory: 512Mi - storage: - type: persistent-claim - size: 1Gi - deleteClaim: false - metricsConfig: - type: jmxPrometheusExporter - valueFrom: - configMapKeyRef: - name: ${cluster_name}-kafka-metrics - key: zookeeper-metrics-config.yml - entityOperator: - topicOperator: {} - userOperator: {} diff --git a/api/examples/kafka-ephemeral-ingress.yaml b/api/examples/kafka-ephemeral-ingress.yaml deleted file mode 100644 index 5e830f942..000000000 --- a/api/examples/kafka-ephemeral-ingress.yaml +++ /dev/null @@ -1,98 +0,0 @@ -apiVersion: kafka.strimzi.io/v1beta2 -kind: Kafka -metadata: - name: ${cluster_name} -spec: - kafka: - version: 3.6.0 - replicas: 3 - resources: - limits: - cpu: 500m - memory: 1Gi - requests: - cpu: 75m - memory: 1Gi - authorization: - type: simple - listeners: - - name: secure - port: 9092 - type: ingress - tls: true - configuration: - bootstrap: - host: bootstrap.${cluster_name}.${kube_ip}.nip.io - brokers: - - broker: 0 - host: broker-0.${cluster_name}.${kube_ip}.nip.io - - broker: 1 - host: broker-1.${cluster_name}.${kube_ip}.nip.io - - broker: 2 - host: broker-2.${cluster_name}.${kube_ip}.nip.io - # OAUTH LISTENER BEGIN - - name: oauth - port: 9093 - type: ingress - tls: true - configuration: - bootstrap: - host: bootstrap-oauth.${cluster_name}.${kube_ip}.nip.io - annotations: - "streamshub.github.com/console-listener": "true" - brokers: - - broker: 0 - host: broker-0-oauth.${cluster_name}.${kube_ip}.nip.io - - broker: 1 - host: broker-1-oauth.${cluster_name}.${kube_ip}.nip.io - - broker: 2 - host: broker-2-oauth.${cluster_name}.${kube_ip}.nip.io - authentication: - jwksEndpointUri: "${keycloak_realm_url}/protocol/openid-connect/certs" - type: oauth - userNameClaim: preferred_username - validIssuerUri: "${keycloak_realm_url}" - # OAUTH LISTENER END - 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.5" - allow.everyone.if.no.acl.found: "true" - storage: - volumes: - - type: "persistent-claim" - size: "1Gi" - deleteClaim: true - id: 0 - type: "jbod" - metricsConfig: - type: jmxPrometheusExporter - valueFrom: - configMapKeyRef: - name: ${cluster_name}-kafka-metrics - key: kafka-metrics-config.yml - zookeeper: - replicas: 3 - resources: - limits: - cpu: 200m - memory: 512Mi - requests: - cpu: 75m - memory: 512Mi - storage: - type: persistent-claim - size: 1Gi - deleteClaim: false - metricsConfig: - type: jmxPrometheusExporter - valueFrom: - configMapKeyRef: - name: ${cluster_name}-kafka-metrics - key: zookeeper-metrics-config.yml - entityOperator: - topicOperator: {} - userOperator: {} diff --git a/api/examples/metrics/prometheus-additional.yaml b/api/examples/metrics/prometheus-additional.yaml deleted file mode 100644 index 594123f26..000000000 --- a/api/examples/metrics/prometheus-additional.yaml +++ /dev/null @@ -1,94 +0,0 @@ ---- -apiVersion: v1 -kind: Secret -metadata: - name: additional-scrape-configs -type: Opaque -stringData: - prometheus-additional.yaml: | - - job_name: kubernetes-cadvisor - honor_labels: true - scrape_interval: 10s - scrape_timeout: 10s - metrics_path: /metrics/cadvisor - scheme: https - kubernetes_sd_configs: - - role: node - namespaces: - names: [] - bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token - tls_config: - ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt - insecure_skip_verify: true - relabel_configs: - - separator: ; - regex: __meta_kubernetes_node_label_(.+) - replacement: $1 - action: labelmap - - separator: ; - regex: (.*) - target_label: __address__ - replacement: kubernetes.default.svc:443 - action: replace - - source_labels: [__meta_kubernetes_node_name] - separator: ; - regex: (.+) - target_label: __metrics_path__ - replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor - action: replace - - source_labels: [__meta_kubernetes_node_name] - separator: ; - regex: (.*) - target_label: node_name - replacement: $1 - action: replace - - source_labels: [__meta_kubernetes_node_address_InternalIP] - separator: ; - regex: (.*) - target_label: node_ip - replacement: $1 - action: replace - metric_relabel_configs: - - source_labels: [container, __name__] - separator: ; - regex: POD;container_(network).* - target_label: container - replacement: $1 - action: replace - # - source_labels: [container] - # separator: ; - # regex: POD - # replacement: $1 - # action: drop - # - source_labels: [container] - # separator: ; - # regex: ^$ - # replacement: $1 - # action: drop - - source_labels: [__name__] - separator: ; - regex: container_(network_tcp_usage_total|tasks_state|memory_failures_total|network_udp_usage_total) - replacement: $1 - action: drop - - - job_name: kubernetes-nodes-kubelet - scrape_interval: 10s - scrape_timeout: 10s - scheme: https - kubernetes_sd_configs: - - role: node - namespaces: - names: [] - bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token - tls_config: - ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt - insecure_skip_verify: true - relabel_configs: - - action: labelmap - regex: __meta_kubernetes_node_label_(.+) - - target_label: __address__ - replacement: kubernetes.default.svc:443 - - source_labels: [__meta_kubernetes_node_name] - regex: (.+) - target_label: __metrics_path__ - replacement: /api/v1/nodes/${1}/proxy/metrics diff --git a/api/examples/metrics/prometheus-pod-monitors.yaml b/api/examples/metrics/prometheus-pod-monitors.yaml deleted file mode 100644 index cc8b17151..000000000 --- a/api/examples/metrics/prometheus-pod-monitors.yaml +++ /dev/null @@ -1,82 +0,0 @@ ---- -apiVersion: monitoring.coreos.com/v1 -kind: PodMonitor -metadata: - name: cluster-operator-metrics - labels: - app: strimzi -spec: - selector: - matchLabels: - strimzi.io/kind: cluster-operator - namespaceSelector: - matchNames: - - myproject - podMetricsEndpoints: - - path: /metrics - port: http ---- -apiVersion: monitoring.coreos.com/v1 -kind: PodMonitor -metadata: - name: entity-operator-metrics - labels: - app: strimzi -spec: - selector: - matchLabels: - app.kubernetes.io/name: entity-operator - namespaceSelector: - matchNames: - - myproject - podMetricsEndpoints: - - path: /metrics - port: healthcheck ---- -apiVersion: monitoring.coreos.com/v1 -kind: PodMonitor -metadata: - name: kafka-resources-metrics - labels: - app: strimzi -spec: - selector: - matchExpressions: - - key: "strimzi.io/kind" - operator: In - values: ["Kafka"] - namespaceSelector: - matchNames: - - myproject - podMetricsEndpoints: - - path: /metrics - port: tcp-prometheus - relabelings: - - separator: ; - regex: __meta_kubernetes_pod_label_(strimzi_io_.+) - replacement: $1 - action: labelmap - - sourceLabels: [__meta_kubernetes_namespace] - separator: ; - regex: (.*) - targetLabel: namespace - replacement: $1 - action: replace - - sourceLabels: [__meta_kubernetes_pod_name] - separator: ; - regex: (.*) - targetLabel: kubernetes_pod_name - replacement: $1 - action: replace - - sourceLabels: [__meta_kubernetes_pod_node_name] - separator: ; - regex: (.*) - targetLabel: node_name - replacement: $1 - action: replace - - sourceLabels: [__meta_kubernetes_pod_host_ip] - separator: ; - regex: (.*) - targetLabel: node_ip - replacement: $1 - action: replace diff --git a/api/examples/metrics/prometheus-rules.yaml b/api/examples/metrics/prometheus-rules.yaml deleted file mode 100644 index f50a04eeb..000000000 --- a/api/examples/metrics/prometheus-rules.yaml +++ /dev/null @@ -1,186 +0,0 @@ ---- -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - labels: - role: alert-rules - app: strimzi - name: prometheus-k8s-rules -spec: - groups: - - name: kafka - rules: - - alert: KafkaRunningOutOfSpace - expr: kubelet_volume_stats_available_bytes{persistentvolumeclaim=~"data(-[0-9]+)?-(.+)-kafka-[0-9]+"} * 100 / kubelet_volume_stats_capacity_bytes{persistentvolumeclaim=~"data(-[0-9]+)?-(.+)-kafka-[0-9]+"} < 15 - for: 10s - labels: - severity: warning - annotations: - summary: 'Kafka is running out of free disk space' - description: 'There are only {{ $value }} percent available at {{ $labels.persistentvolumeclaim }} PVC' - - alert: UnderReplicatedPartitions - expr: kafka_server_replicamanager_underreplicatedpartitions > 0 - for: 10s - labels: - severity: warning - annotations: - summary: 'Kafka under replicated partitions' - description: 'There are {{ $value }} under replicated partitions on {{ $labels.kubernetes_pod_name }}' - - alert: AbnormalControllerState - expr: sum(kafka_controller_kafkacontroller_activecontrollercount) by (strimzi_io_name) != 1 - for: 10s - labels: - severity: warning - annotations: - summary: 'Kafka abnormal controller state' - description: 'There are {{ $value }} active controllers in the cluster' - - alert: OfflinePartitions - expr: sum(kafka_controller_kafkacontroller_offlinepartitionscount) > 0 - for: 10s - labels: - severity: warning - annotations: - summary: 'Kafka offline partitions' - description: 'One or more partitions have no leader' - - alert: UnderMinIsrPartitionCount - expr: kafka_server_replicamanager_underminisrpartitioncount > 0 - for: 10s - labels: - severity: warning - annotations: - summary: 'Kafka under min ISR partitions' - description: 'There are {{ $value }} partitions under the min ISR on {{ $labels.kubernetes_pod_name }}' - - alert: OfflineLogDirectoryCount - expr: kafka_log_logmanager_offlinelogdirectorycount > 0 - for: 10s - labels: - severity: warning - annotations: - summary: 'Kafka offline log directories' - description: 'There are {{ $value }} offline log directories on {{ $labels.kubernetes_pod_name }}' - - alert: ScrapeProblem - expr: up{kubernetes_namespace!~"openshift-.+",kubernetes_pod_name=~".+-kafka-[0-9]+"} == 0 - for: 3m - labels: - severity: major - annotations: - summary: 'Prometheus unable to scrape metrics from {{ $labels.kubernetes_pod_name }}/{{ $labels.instance }}' - description: 'Prometheus was unable to scrape metrics from {{ $labels.kubernetes_pod_name }}/{{ $labels.instance }} for more than 3 minutes' - - alert: ClusterOperatorContainerDown - expr: count((container_last_seen{container="strimzi-cluster-operator"} > (time() - 90))) < 1 or absent(container_last_seen{container="strimzi-cluster-operator"}) - for: 1m - labels: - severity: major - annotations: - summary: 'Cluster Operator down' - description: 'The Cluster Operator has been down for longer than 90 seconds' - - alert: KafkaBrokerContainersDown - expr: absent(container_last_seen{container="kafka",pod=~".+-kafka-[0-9]+"}) - for: 3m - labels: - severity: major - annotations: - summary: 'All `kafka` containers down or in CrashLookBackOff status' - description: 'All `kafka` containers have been down or in CrashLookBackOff status for 3 minutes' - - alert: KafkaContainerRestartedInTheLast5Minutes - expr: count(count_over_time(container_last_seen{container="kafka"}[5m])) > 2 * count(container_last_seen{container="kafka",pod=~".+-kafka-[0-9]+"}) - for: 5m - labels: - severity: warning - annotations: - summary: 'One or more Kafka containers restarted too often' - description: 'One or more Kafka containers were restarted too often within the last 5 minutes' - - name: zookeeper - rules: - - alert: AvgRequestLatency - expr: zookeeper_avgrequestlatency > 10 - for: 10s - labels: - severity: warning - annotations: - summary: 'Zookeeper average request latency' - description: 'The average request latency is {{ $value }} on {{ $labels.kubernetes_pod_name }}' - - alert: OutstandingRequests - expr: zookeeper_outstandingrequests > 10 - for: 10s - labels: - severity: warning - annotations: - summary: 'Zookeeper outstanding requests' - description: 'There are {{ $value }} outstanding requests on {{ $labels.kubernetes_pod_name }}' - - alert: ZookeeperRunningOutOfSpace - expr: kubelet_volume_stats_available_bytes{persistentvolumeclaim=~"data-(.+)-zookeeper-[0-9]+"} < 5368709120 - for: 10s - labels: - severity: warning - annotations: - summary: 'Zookeeper is running out of free disk space' - description: 'There are only {{ $value }} bytes available at {{ $labels.persistentvolumeclaim }} PVC' - - alert: ZookeeperContainerRestartedInTheLast5Minutes - expr: count(count_over_time(container_last_seen{container="zookeeper"}[5m])) > 2 * count(container_last_seen{container="zookeeper",pod=~".+-zookeeper-[0-9]+"}) - for: 5m - labels: - severity: warning - annotations: - summary: 'One or more Zookeeper containers were restarted too often' - description: 'One or more Zookeeper containers were restarted too often within the last 5 minutes. This alert can be ignored when the Zookeeper cluster is scaling up' - - alert: ZookeeperContainersDown - expr: absent(container_last_seen{container="zookeeper",pod=~".+-zookeeper-[0-9]+"}) - for: 3m - labels: - severity: major - annotations: - summary: 'All `zookeeper` containers in the Zookeeper pods down or in CrashLookBackOff status' - description: 'All `zookeeper` containers in the Zookeeper pods have been down or in CrashLookBackOff status for 3 minutes' - - name: entityOperator - rules: - - alert: TopicOperatorContainerDown - expr: absent(container_last_seen{container="topic-operator",pod=~".+-entity-operator-.+"}) - for: 3m - labels: - severity: major - annotations: - summary: 'Container topic-operator in Entity Operator pod down or in CrashLookBackOff status' - description: 'Container topic-operator in Entity Operator pod has been or in CrashLookBackOff status for 3 minutes' - - alert: UserOperatorContainerDown - expr: absent(container_last_seen{container="user-operator",pod=~".+-entity-operator-.+"}) - for: 3m - labels: - severity: major - annotations: - summary: 'Container user-operator in Entity Operator pod down or in CrashLookBackOff status' - description: 'Container user-operator in Entity Operator pod have been down or in CrashLookBackOff status for 3 minutes' - - alert: EntityOperatorTlsSidecarContainerDown - expr: absent(container_last_seen{container="tls-sidecar",pod=~".+-entity-operator-.+"}) - for: 3m - labels: - severity: major - annotations: - summary: 'Container tls-sidecar Entity Operator pod down or in CrashLookBackOff status' - description: 'Container tls-sidecar in Entity Operator pod have been down or in CrashLookBackOff status for 3 minutes' - - name: kafkaExporter - rules: - - alert: UnderReplicatedPartition - expr: kafka_topic_partition_under_replicated_partition > 0 - for: 10s - labels: - severity: warning - annotations: - summary: 'Topic has under-replicated partitions' - description: 'Topic {{ $labels.topic }} has {{ $value }} under-replicated partition {{ $labels.partition }}' - - alert: TooLargeConsumerGroupLag - expr: kafka_consumergroup_lag > 1000 - for: 10s - labels: - severity: warning - annotations: - summary: 'Consumer group lag is too big' - description: 'Consumer group {{ $labels.consumergroup}} lag is too big ({{ $value }}) on topic {{ $labels.topic }}/partition {{ $labels.partition }}' - - alert: NoMessageForTooLong - expr: changes(kafka_topic_partition_current_offset{topic!="__consumer_offsets"}[10m]) == 0 - for: 10s - labels: - severity: warning - annotations: - summary: 'No message for 10 minutes' - description: 'There is no messages in topic {{ $labels.topic}}/partition {{ $labels.partition }} for 10 minutes' diff --git a/api/examples/metrics/prometheus.yaml b/api/examples/metrics/prometheus.yaml deleted file mode 100644 index bf66c7248..000000000 --- a/api/examples/metrics/prometheus.yaml +++ /dev/null @@ -1,75 +0,0 @@ ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: prometheus-server - labels: - app: strimzi -rules: - - apiGroups: [""] - resources: - - nodes - - nodes/proxy - - services - - endpoints - - pods - verbs: ["get", "list", "watch"] - - apiGroups: - - extensions - resources: - - ingresses - verbs: ["get", "list", "watch"] - - nonResourceURLs: ["/metrics"] - verbs: ["get"] ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: prometheus-server - labels: - app: strimzi ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: prometheus-server - labels: - app: strimzi -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: prometheus-server -subjects: - - kind: ServiceAccount - name: prometheus-server - namespace: myproject ---- -apiVersion: monitoring.coreos.com/v1 -kind: Prometheus -metadata: - name: console-prometheus - labels: - app: strimzi -spec: - replicas: 1 - serviceAccountName: prometheus-server - podMonitorSelector: - matchLabels: - app: strimzi - serviceMonitorSelector: {} - resources: - requests: - memory: 400Mi - enableAdminAPI: false - ruleSelector: - matchLabels: - role: alert-rules - app: strimzi - alerting: - alertmanagers: - - namespace: myproject - name: alertmanager - port: alertmanager - additionalScrapeConfigs: - name: additional-scrape-configs - key: prometheus-additional.yaml diff --git a/api/hack/binscripts.properties b/api/hack/binscripts.properties deleted file mode 100644 index a3ee4ff38..000000000 --- a/api/hack/binscripts.properties +++ /dev/null @@ -1,6 +0,0 @@ -security.protocol=SASL_PLAINTEXT -sasl.mechanism=PLAIN - -sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required \ - username="admin" \ - password="admin-secret" ; \ No newline at end of file diff --git a/api/hack/gen-ca.sh b/api/hack/gen-ca.sh deleted file mode 100755 index de6a4015b..000000000 --- a/api/hack/gen-ca.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh -set -e - -OUTDIR=${1:-$(pwd)} - -# create CA key -openssl genrsa -out ${OUTDIR}/ca.key 4096 - -# create CA certificate -openssl req -x509 -new -nodes -sha256 -days 3650 -subj "/CN=KafkaAdmin.io" -key ${OUTDIR}/ca.key -out ${OUTDIR}/ca.crt diff --git a/api/hack/gen-kafka-certs.sh b/api/hack/gen-kafka-certs.sh deleted file mode 100755 index 0db744e8d..000000000 --- a/api/hack/gen-kafka-certs.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/bin/sh - -set -e - -OUTDIR=${1:-$(pwd)} -CADIR=${2:-$(pwd)} -STOREPASS=${3:-Z_pkTh9xgZovK4t34cGB2o6afT4zZg0L} - -echo "${STOREPASS}" > ${OUTDIR}/kafka_secret.txt -echo "subjectAltName = DNS:kafka,DNS:localhost" > ${OUTDIR}/kafka-san.ext - -echo "#### Generate broker keystore" -keytool -keystore ${OUTDIR}/cluster.keystore.p12 \ - -alias localhost \ - -validity 380 \ - -genkey \ - -keyalg RSA \ - -dname "CN=my-cluster-kafka,O=io.strimzi" \ - -ext "SAN=DNS:kafka,DNS:localhost" \ - -deststoretype pkcs12 \ - -storepass $STOREPASS \ - -keypass $STOREPASS - -echo "#### Export the certificate from the keystore" -keytool -keystore ${OUTDIR}/cluster.keystore.p12 \ - -storetype pkcs12 \ - -alias localhost \ - -certreq \ - -dname "CN=my-cluster-kafka,O=io.strimzi" \ - -ext "SAN=DNS:kafka,DNS:localhost" \ - -file ${OUTDIR}/cert-file \ - -storepass $STOREPASS - -echo "#### Sign the certificate with the CA" -openssl x509 -req \ - -CA ${CADIR}/ca.crt \ - -CAkey ${CADIR}/ca.key \ - -extfile ${OUTDIR}/kafka-san.ext \ - -in ${OUTDIR}/cert-file \ - -out ${OUTDIR}/cert-signed \ - -days 400 \ - -CAcreateserial \ - -passin pass:$STOREPASS - -echo "#### Import the CA and the signed certificate into the broker keystore" -keytool -keystore ${OUTDIR}/cluster.keystore.p12 -deststoretype pkcs12 -alias CARoot -import -file ${CADIR}/ca.crt -storepass $STOREPASS -noprompt -keytool -keystore ${OUTDIR}/cluster.keystore.p12 -deststoretype pkcs12 -alias localhost -import -file ${OUTDIR}/cert-signed -storepass $STOREPASS -noprompt - -echo "#### Add the CA to the brokers’ truststore" -keytool -keystore ${OUTDIR}/cluster.truststore.p12 -deststoretype pkcs12 -storepass $STOREPASS -alias CARoot -importcert -file ${CADIR}/ca.crt -noprompt diff --git a/api/hack/kcat.properties b/api/hack/kcat.properties deleted file mode 100644 index d56198479..000000000 --- a/api/hack/kcat.properties +++ /dev/null @@ -1,4 +0,0 @@ -security.protocol=SASL_PLAINTEXT -sasl.mechanisms=PLAIN -sasl.username=admin -sasl.password=admin-secret diff --git a/examples/console/010-Console-example.yaml b/examples/console/010-Console-example.yaml new file mode 100644 index 000000000..b597bcba2 --- /dev/null +++ b/examples/console/010-Console-example.yaml @@ -0,0 +1,24 @@ +--- +apiVersion: console.streamshub.github.com/v1alpha1 +kind: Console +metadata: + name: example +spec: + hostname: example-console.${CLUSTER_DOMAIN} + kafkaClusters: + # + # The values below make use of the example Kafka cluster from examples/kafka. + # Adjust according to your environment. + # + - name: console-kafka # Name of the `Kafka` CR representing the cluster + namespace: ${KAFKA_NAMESPACE} # Namespace of the `Kafka` CR representing the cluster + listener: secure # Listener on the `Kafka` CR to connect from the console + properties: + values: [] # Array of name/value for properties to be used for connections + # made to this cluster + valuesFrom: [] # Array of references to ConfigMaps or Secrets with properties + # to be used for connections made to this cluster + credentials: + kafkaUser: + name: console-kafka-user1 # Name of the `KafkaUser` resource used to connect to Kafka + # This is optional if properties are used to configure the user diff --git a/install/resources/kafka/console-kafka-metrics.configmap.yaml b/examples/kafka/010-ConfigMap-console-kafka-metrics.yaml similarity index 99% rename from install/resources/kafka/console-kafka-metrics.configmap.yaml rename to examples/kafka/010-ConfigMap-console-kafka-metrics.yaml index b935a4f17..9f93d0219 100644 --- a/install/resources/kafka/console-kafka-metrics.configmap.yaml +++ b/examples/kafka/010-ConfigMap-console-kafka-metrics.yaml @@ -1,3 +1,4 @@ +--- kind: ConfigMap apiVersion: v1 metadata: diff --git a/install/resources/kafka/console-nodepool.kafkanodepool.yaml b/examples/kafka/020-KafkaNodePool-console-nodepool.yaml similarity index 98% rename from install/resources/kafka/console-nodepool.kafkanodepool.yaml rename to examples/kafka/020-KafkaNodePool-console-nodepool.yaml index 9613d27fb..9c92af5fa 100644 --- a/install/resources/kafka/console-nodepool.kafkanodepool.yaml +++ b/examples/kafka/020-KafkaNodePool-console-nodepool.yaml @@ -1,3 +1,4 @@ +--- apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaNodePool metadata: diff --git a/install/resources/kafka/console-kafka.kafka.yaml b/examples/kafka/030-Kafka-console-kafka.yaml similarity index 99% rename from install/resources/kafka/console-kafka.kafka.yaml rename to examples/kafka/030-Kafka-console-kafka.yaml index 514b909a9..66e1e225b 100644 --- a/install/resources/kafka/console-kafka.kafka.yaml +++ b/examples/kafka/030-Kafka-console-kafka.yaml @@ -1,3 +1,4 @@ +--- apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: diff --git a/install/resources/kafka/console-kafka-user1.kafkauser.yaml b/examples/kafka/040-KafkaUser-console-kafka-user1.yaml similarity index 97% rename from install/resources/kafka/console-kafka-user1.kafkauser.yaml rename to examples/kafka/040-KafkaUser-console-kafka-user1.yaml index 5638721d0..5f76ea158 100644 --- a/install/resources/kafka/console-kafka-user1.kafkauser.yaml +++ b/examples/kafka/040-KafkaUser-console-kafka-user1.yaml @@ -1,3 +1,4 @@ +--- apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaUser metadata: diff --git a/install/resources/prometheus/console-prometheus-server.serviceaccount.yaml b/examples/prometheus/010-ServiceAccount-console-prometheus-server.yaml similarity index 100% rename from install/resources/prometheus/console-prometheus-server.serviceaccount.yaml rename to examples/prometheus/010-ServiceAccount-console-prometheus-server.yaml diff --git a/install/resources/prometheus/console-prometheus-server.clusterrole.yaml b/examples/prometheus/020-ClusterRole-console-prometheus-server.yaml similarity index 100% rename from install/resources/prometheus/console-prometheus-server.clusterrole.yaml rename to examples/prometheus/020-ClusterRole-console-prometheus-server.yaml diff --git a/install/resources/prometheus/console-prometheus-server.clusterrolebinding.yaml b/examples/prometheus/030-ClusterRoleBinding-console-prometheus-server.yaml similarity index 100% rename from install/resources/prometheus/console-prometheus-server.clusterrolebinding.yaml rename to examples/prometheus/030-ClusterRoleBinding-console-prometheus-server.yaml diff --git a/install/resources/prometheus/kafka-resources.podmonitor.yaml b/examples/prometheus/040-PodMonitor-kafka-resources.yaml similarity index 100% rename from install/resources/prometheus/kafka-resources.podmonitor.yaml rename to examples/prometheus/040-PodMonitor-kafka-resources.yaml diff --git a/install/resources/prometheus/kubernetes-scrape-configs.secret.yaml b/examples/prometheus/050-Secret-kubernetes-scrape-configs.yaml similarity index 100% rename from install/resources/prometheus/kubernetes-scrape-configs.secret.yaml rename to examples/prometheus/050-Secret-kubernetes-scrape-configs.yaml diff --git a/install/resources/prometheus/console-prometheus.prometheus.yaml b/examples/prometheus/060-Prometheus-console-prometheus.yaml similarity index 100% rename from install/resources/prometheus/console-prometheus.prometheus.yaml rename to examples/prometheus/060-Prometheus-console-prometheus.yaml diff --git a/install/resources/prometheus/console-prometheus.service.yaml b/examples/prometheus/070-Service-console-prometheus.yaml similarity index 100% rename from install/resources/prometheus/console-prometheus.service.yaml rename to examples/prometheus/070-Service-console-prometheus.yaml diff --git a/install/resources/prometheus/console-prometheus.ingress.yaml b/examples/prometheus/optional/080-Ingress-console-prometheus.yaml similarity index 100% rename from install/resources/prometheus/console-prometheus.ingress.yaml rename to examples/prometheus/optional/080-Ingress-console-prometheus.yaml diff --git a/install/000-install-dependency-operators.sh b/install/000-install-dependency-operators.sh deleted file mode 100755 index 28ded6b24..000000000 --- a/install/000-install-dependency-operators.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -CONSOLE_INSTALL_PATH="$(cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P)" -RESOURCE_PATH=${CONSOLE_INSTALL_PATH}/resources - -export NAMESPACE="${1?Please provide the deployment namespace}" -source ${CONSOLE_INSTALL_PATH}/_common.sh - -echo -e "${INFO} Create/update operator group in namespace '${NAMESPACE}'" -${YQ} '.spec.targetNamespaces[0] = strenv(NAMESPACE)' ${RESOURCE_PATH}/operators/console-operators.operatorgroup.yaml | ${KUBE} apply -n ${NAMESPACE} -f - - -if ${KUBE} get packagemanifests amq-streams >/dev/null ; then - echo -e "${INFO} Create/update Apache Kafka Operator" - echo "apiVersion: operators.coreos.com/v1alpha1 -kind: Subscription -metadata: - name: amq-streams-operator -spec: - name: amq-streams - channel: stable - source: redhat-operators - sourceNamespace: openshift-marketplace" | ${KUBE} apply -n ${NAMESPACE} -f - -else - echo -e "${INFO} Create/update Strimzi Kafka Operator" - echo "apiVersion: operators.coreos.com/v1alpha1 -kind: Subscription -metadata: - name: strimzi-kafka-operator -spec: - name: strimzi-kafka-operator - channel: stable - source: community-operators - sourceNamespace: openshift-marketplace" | ${KUBE} apply -n ${NAMESPACE} -f - -fi - -echo -e "${INFO} Create/update Prometheus Operator" -echo "apiVersion: operators.coreos.com/v1alpha1 -kind: Subscription -metadata: - name: prometheus-operator -spec: - name: prometheus - channel: beta - source: community-operators - sourceNamespace: openshift-marketplace" \ - | ${KUBE} apply -n ${NAMESPACE} -f - diff --git a/install/001-deploy-prometheus.sh b/install/001-deploy-prometheus.sh deleted file mode 100755 index e3c3f0866..000000000 --- a/install/001-deploy-prometheus.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -CONSOLE_INSTALL_PATH="$(cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P)" -RESOURCE_PATH=${CONSOLE_INSTALL_PATH}/resources - -export NAMESPACE="${1?Please provide the deployment namespace}" -export CLUSTER_DOMAIN="${2:-}" -source ${CONSOLE_INSTALL_PATH}/_common.sh - -if ! ${KUBE} get crd prometheuses.monitoring.coreos.com >/dev/null ; then - echo -e "${ERROR} Prometheus Operator custom resource(s) not found" - display_suggested_subscription "prometheus-operator" "prometheus" - exit 1 -fi - -### Prometheus -echo -e "${INFO} Apply Prometheus security resources" -${KUBE} apply -n ${NAMESPACE} -f ${RESOURCE_PATH}/prometheus/console-prometheus-server.clusterrole.yaml -${KUBE} apply -n ${NAMESPACE} -f ${RESOURCE_PATH}/prometheus/console-prometheus-server.serviceaccount.yaml -${YQ} '.subjects[0].namespace = strenv(NAMESPACE)' ${RESOURCE_PATH}/prometheus/console-prometheus-server.clusterrolebinding.yaml | ${KUBE} apply -n ${NAMESPACE} -f - - -echo -e "${INFO} Apply Prometheus PodMonitor and Kubernetes scrape configurations" -${KUBE} apply -n ${NAMESPACE} -f ${RESOURCE_PATH}/prometheus/kafka-resources.podmonitor.yaml -${KUBE} apply -n ${NAMESPACE} -f ${RESOURCE_PATH}/prometheus/kubernetes-scrape-configs.secret.yaml - -echo -e "${INFO} Apply Prometheus instance" -${KUBE} apply -n ${NAMESPACE} -f ${RESOURCE_PATH}/prometheus/console-prometheus.prometheus.yaml -${KUBE} apply -n ${NAMESPACE} -f ${RESOURCE_PATH}/prometheus/console-prometheus.service.yaml - -if [ -n "${CLUSTER_DOMAIN}" ] ; then - # Replace env variables - ${YQ} '(.. | select(tag == "!!str")) |= envsubst(ne)' ${RESOURCE_PATH}/prometheus/console-prometheus.ingress.yaml | ${KUBE} apply -n ${NAMESPACE} -f - -fi diff --git a/install/002-deploy-console-kafka.sh b/install/002-deploy-console-kafka.sh deleted file mode 100755 index 1a01a284a..000000000 --- a/install/002-deploy-console-kafka.sh +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -CONSOLE_INSTALL_PATH="$(cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P)" -RESOURCE_PATH=${CONSOLE_INSTALL_PATH}/resources/kafka - -export NAMESPACE="${1?Please provide the deployment namespace}" -export CLUSTER_DOMAIN="${2?Please provide the base domain name for Kafka listener ingress}" -export MODE="${3:-kraft}" - -if [ "${MODE}" != "kraft" ] && [ "${MODE}" != "zk" ] ; then - echo "Unknown Kafka mode: '${MODE}'. Allowed values are [ 'kraft', 'zk' ]" - exit 1 -fi - -source ${CONSOLE_INSTALL_PATH}/_common.sh - -${KUBE} apply -n ${NAMESPACE} -f ${RESOURCE_PATH}/console-kafka-metrics.configmap.yaml - -if [ "$(${KUBE} api-resources --api-group=route.openshift.io -o=name)" != "" ] ; then - LISTENER_TYPE='route' -else - LISTENER_TYPE='ingress' -fi - -export LISTENER_TYPE - -if [ "${MODE}" == "kraft" ] ; then - if ! ${KUBE} get KafkaNodePool console-nodepool -n ${NAMESPACE} >/dev/null 2>&1 ; then - ${KUBE} delete Kafka console-kafka -n ${NAMESPACE} 2>/dev/null || true - fi - - # Replace env variables - ${YQ} '(.. | select(tag == "!!str")) |= envsubst(ne)' ${RESOURCE_PATH}/console-kafka.kafka.yaml | ${KUBE} apply -n ${NAMESPACE} -f - - ${KUBE} apply -n ${NAMESPACE} -f ${RESOURCE_PATH}/console-nodepool.kafkanodepool.yaml -else - if ${KUBE} get KafkaNodePool console-nodepool -n ${NAMESPACE} >/dev/null 2>&1 ; then - ${KUBE} delete Kafka console-kafka -n ${NAMESPACE} 2>/dev/null || true - ${KUBE} delete KafkaNodePool console-nodepool -n ${NAMESPACE} 2>/dev/null || true - fi - - # Replace env variables - ${YQ} '(.. | select(tag == "!!str")) |= envsubst(ne)' ${RESOURCE_PATH}/console-kafka-zk.kafka.yaml | ${KUBE} apply -n ${NAMESPACE} -f - -fi - -${KUBE} apply -n ${NAMESPACE} -f ${RESOURCE_PATH}/console-kafka-user1.kafkauser.yaml diff --git a/install/003-install-console-operator.sh b/install/003-install-console-operator.sh deleted file mode 100755 index b3e99b6b5..000000000 --- a/install/003-install-console-operator.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -CONSOLE_INSTALL_PATH="$(cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P)" -RESOURCE_PATH=${CONSOLE_INSTALL_PATH}/resources -DEFAULT_CATALOG='quay.io/streamshub/console-operator-catalog:latest' - -export NAMESPACE="${1?Please provide the deployment namespace}" -export CATALOG_IMAGE="${2:-${DEFAULT_CATALOG}}" -source ${CONSOLE_INSTALL_PATH}/_common.sh - -echo -e "${INFO} Create/update operator group in namespace '${NAMESPACE}' to watch all namespaces" -${YQ} '.spec.targetNamespaces = []' ${RESOURCE_PATH}/operators/console-operators.operatorgroup.yaml | ${KUBE} apply -n ${NAMESPACE} -f - - -echo -e "${INFO} Create/update operator group in namespace '${NAMESPACE}' with catalog '${CATALOG_IMAGE}'" -echo "apiVersion: operators.coreos.com/v1alpha1 -kind: CatalogSource -metadata: - name: console-operator-catalog -spec: - displayName: 'StreamsHub' - image: '${CATALOG_IMAGE}' - publisher: 'StreamsHub' - sourceType: grpc" | ${KUBE} apply -n ${NAMESPACE} -f - - -echo -e "${INFO} Create/update subscription in namespace '${NAMESPACE}'" -echo "apiVersion: operators.coreos.com/v1alpha1 -kind: Subscription -metadata: - name: console-operator -spec: - name: console-operator - channel: alpha - source: console-operator-catalog - sourceNamespace: ${NAMESPACE}" | ${KUBE} apply -n ${NAMESPACE} -f - diff --git a/install/README.md b/install/README.md deleted file mode 100644 index f6dbc4f95..000000000 --- a/install/README.md +++ /dev/null @@ -1,121 +0,0 @@ -# Console Installation - -This directory contains several resources that may be used directly or as examples for deploying the -console into a Kubernetes or OpenShift cluster. The scripts contained here may be run using the bash -shell and require that the `kubectl` (or `oc` for OpenShift) and `yq`[1] command line utilities -are available on the `PATH`. - -## Prerequisites - -### 0. Minikube Setup (optional) - -If using minikube, be sure to enable ingress with TLS passthrough and install OLM. - -```shell -minikube start - -# Enable ingress -minikube addons enable ingress - -# Enable TLS passthrough on the ingress deployment -kubectl patch deployment -n ingress-nginx ingress-nginx-controller \ - --type='json' \ - -p='[{"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value":"--enable-ssl-passthrough"}]' - -# Install OLM -curl -sL https://github.com/operator-framework/operator-lifecycle-manager/releases/download/v0.28.0/install.sh | bash -s "v0.28.0" -``` - -### 1. Strimzi & Prometheus - -The console requires that the Strimzi Kafka Operator is installed and available in the cluster before -deployment. Strimzi may be installed either using Operator Lifecycle Manager (OLM, preferred) or directly -using Kubernetes resources provided by the Strimzi project. - -Prometheus must also be installed and configured to scrape metrics from Kubernetes and Kafka clusters. The -Prometheus instance must be accessible to the console application using HTTP or HTTPS. If a Prometheus instance -is not available, the cluster metrics graphs on the Kafka cluster overview screens will be unavailable. - -Users who do not previously have Strimzi and Promethus installed may use the `000-install-dependency-operators.sh` -and `001-deploy-prometheus.sh` scripts to bootstrap the environment. The scripts will install either the community-supported -or commercially supported (i.e. streams for Apache Kafka) version of the two operators using OLM and deploy a Prometheus instance -configured to scrape metrics from Kafka clusters deployed by Strimzi within the cluster. - -```shell -000-install-dependency-operators.sh ${TARGET_NAMESPACE} -``` - -If not using the operator to create a console instance, a Prometheus instance must be deployed next. - -```shell -001-deploy-prometheus.sh ${TARGET_NAMESPACE} ${CLUSTER_DOMAIN} -``` - -Note, in this example the operators installed will only watch the `${TARGET_NAMESPACE}` namespace. This must -be taken into account when deploying the Apache Kafka cluster below where the namespace must be provided to the script. - -### 2. Apache Kafka Cluster - -Once the operators have been installed, the demo Kafka cluster may be created using the -`002-deploy-console-kafka.sh` script. This script will create a Strimzi `Kafka` custom resource as well as a -`KafkaUser` custom resource for a user to access the cluster. Additionally, the Kafka cluster will be configured via -a ConfigMap to export metrics in the way expected by the Prometheus instance that will be created along with the console -(if using the operator) or the instance created earlier with `001-deploy-prometheus.sh`. - -```shell -002-deploy-console-kafka.sh ${TARGET_NAMESPACE} ${CLUSTER_DOMAIN} -``` - -By default, the Kafka cluster will be created in KRaft mode (Zookeeper-less). If you would like to create a cluster -that uses ZooKeeper, an additional third argument with the value `zk` may be given. The value may also be `kraft` to -explicitly request a KRaft cluster. - -```shell -002-deploy-console-kafka.sh ${TARGET_NAMESPACE} ${CLUSTER_DOMAIN} zk -``` - -#### Kafka Authorization - -In order to allow the necessary access for the console to function, a minimum level of authorization must be configured -for the principal in use for each Kafka cluster connection. While the definition of the permissions may vary depending -on the authorization framework in use (e.g. ACLs, Keycloak Authorization, OPA, or custom) the minimum required in terms -of ACL types are: - -1. `DESCRIBE`, `DESCRIBE_CONFIGS` for the `CLUSTER` resource -1. `READ`, `DESCRIBE`, `DESCRIBE_CONFIGS` for all `TOPIC` resources -1. `READ`, `DESCRIBE` for all `GROUP` resources - -### 3. Console Operator - -The next step will install the StreamsHub console operator into the namespace provided. This step is optional -if, for example, you will be running either the console or the operator on your local machine in development mode. - -```shell -003-install-console-operator.sh ${CONSOLE_NAMESPACE} -``` - -## Creating a Console Instance - -With the prerequisites met, a `Console` custom resource instance can be created using `kubectl`. This resource must -contain a reference to the `Kafka` and `KafkaUser` resources created above by `002-deploy-console-kafka.sh`. - -```shell -echo 'apiVersion: console.streamshub.github.com/v1alpha1 -kind: Console -metadata: - name: example -spec: - hostname: example-console.'${CLUSTER_DOMAIN}' # Hostname where the console will be accessed via HTTPS - kafkaClusters: - - name: console-kafka # Name of the `Kafka` CR representing the cluster - namespace: '${STRIMZI_NAMESPACE}' # Namespace of the `Kafka` CR representing the cluster - listener: secure # Listener on the `Kafka` CR to connect from the console - credentials: - kafkaUser: - name: console-kafka-user1 # Name of the `KafkaUser` resource used to connect to Kafka -' | kubectl apply -n ${CONSOLE_NAMESPACE} -f - -``` - -## References - -[1] yq [releases](https://github.com/mikefarah/yq/releases) diff --git a/install/_common.sh b/install/_common.sh deleted file mode 100644 index 43c1ef3b3..000000000 --- a/install/_common.sh +++ /dev/null @@ -1,82 +0,0 @@ -RED='\033[0;31m' -GREEN='\033[0;32m' -NC='\033[0m' # No Color -INFO="[ \033[38;5;33mINFO${NC} ]" -WARN="[ \033[38;5;208mWARN${NC} ]" -ERROR="[ \033[38;5;196mERROR${NC} ]" - -KUBE="$(which oc 2>/dev/null || which kubectl 2>/dev/null)" || : - -if [ "${KUBE}" == "" ] ; then - echo -e "${ERROR} Neither 'oc' or 'kubectl' command line utilities found on the PATH" - exit 1 -fi - -YQ="$(which yq 2>/dev/null)" || : - -if [ "${YQ}" == "" ] ; then - echo -e "${ERROR} 'yq' command line utility found on the PATH" - exit 1 -fi - -if ${KUBE} get namespace/${NAMESPACE} >/dev/null 2>&1 ; then - echo -e "${INFO} Namespace '${NAMESPACE}' exists" -else - echo -e "${WARN} Namespace '${NAMESPACE}' not found... creating" - ${KUBE} create namespace ${NAMESPACE} >/dev/null - - if ${KUBE} get namespace/${NAMESPACE} >/dev/null 2>&1 ; then - echo -e "${INFO} Namespace '${NAMESPACE}' created" - else - echo -e "${WARN} Namespace '${NAMESPACE}' could not be created" - fi -fi - -OLM=$(kubectl get crd | grep operators.coreos.com) || : - -if [ "${OLM}" == "" ] && [ "${CI_CLUSTER}" == "" ] ; then - echo -e "${ERROR} Operator Lifecycle Manager not found, please install it. - -$ operator-sdk olm install - -For more info please visit https://sdk.operatorframework.io/ -" - exit 1 -fi - -function fetch_available_packages { - local NAME_PATTERN="${1}" - - for pm in $(${KUBE} get packagemanifests -o name | grep -E '^packagemanifest\.packages\.operators\.coreos\.com/('"${NAME_PATTERN}"')$') ; do - ${KUBE} get $pm -o yaml | ${YQ} -o=json '{ - "name": .status.packageName, - "channel": .status.defaultChannel, - "catalogSource": .status.catalogSource, - "catalogSourceNamespace": .status.catalogSourceNamespace - }' - done | ${YQ} ea -p=json '[.]' | ${YQ} -o=csv | tail -n +2 -} - -function display_suggested_subscription { - local OPERATOR_NAME="${1}" - local NAME_PATTERN="${2}" - - local AVAILABLE_PKGS="$(fetch_available_packages "${NAME_PATTERN}")" - echo -e "${INFO} ${OPERATOR_NAME} may be installed by creating one of the following resources:" - COUNTER=0 - - while IFS=, read -r PKG_NAME PKG_CHANNEL PKG_CTLG_SRC PKG_CTLG_SRC_NS; do - COUNTER=$(( COUNTER + 1 )) - echo -e "${INFO} ----- Option ${COUNTER} -----" - echo "apiVersion: operators.coreos.com/v1alpha1 -kind: Subscription -metadata: - name: ${OPERATOR_NAME} - namespace: ${NAMESPACE} -spec: - name: ${PKG_NAME} - channel: ${PKG_CHANNEL} - source: ${PKG_CTLG_SRC} - sourceNamespace: ${PKG_CTLG_SRC_NS}" | ${YQ} - done < <(echo "${AVAILABLE_PKGS}") -} diff --git a/install/resources/console/console-server.serviceaccount.yaml b/install/console/010-ServiceAccount-console-server.yaml similarity index 100% rename from install/resources/console/console-server.serviceaccount.yaml rename to install/console/010-ServiceAccount-console-server.yaml diff --git a/install/resources/console/console-server.clusterrole.yaml b/install/console/020-ClusterRole-console-server.yaml similarity index 100% rename from install/resources/console/console-server.clusterrole.yaml rename to install/console/020-ClusterRole-console-server.yaml diff --git a/install/resources/console/console-server.clusterrolebinding.yaml b/install/console/030-ClusterRoleBinding-console-server.yaml similarity index 100% rename from install/resources/console/console-server.clusterrolebinding.yaml rename to install/console/030-ClusterRoleBinding-console-server.yaml diff --git a/install/resources/console/console.deployment.yaml b/install/console/040-Deployment-console.yaml similarity index 100% rename from install/resources/console/console.deployment.yaml rename to install/console/040-Deployment-console.yaml diff --git a/install/resources/console/console-ui.service.yaml b/install/console/050-Service-console-ui.yaml similarity index 100% rename from install/resources/console/console-ui.service.yaml rename to install/console/050-Service-console-ui.yaml diff --git a/install/resources/console/console-ui.ingress.yaml b/install/console/060-Ingress-console-ui.yaml similarity index 100% rename from install/resources/console/console-ui.ingress.yaml rename to install/console/060-Ingress-console-ui.yaml diff --git a/install/resources/operators/console-operators.operatorgroup.yaml b/install/operator-olm/000-OperatorGroup-console-operator.yaml similarity index 60% rename from install/resources/operators/console-operators.operatorgroup.yaml rename to install/operator-olm/000-OperatorGroup-console-operator.yaml index cdcb7ff04..65df5ed05 100644 --- a/install/resources/operators/console-operators.operatorgroup.yaml +++ b/install/operator-olm/000-OperatorGroup-console-operator.yaml @@ -1,8 +1,8 @@ +--- apiVersion: operators.coreos.com/v1 kind: OperatorGroup metadata: - name: console-operators + name: console-operator spec: - targetNamespaces: - - ${NAMESPACE} + targetNamespaces: [] upgradeStrategy: Default diff --git a/install/operator-olm/010-CatalogSource-console-operator-catalog.yaml b/install/operator-olm/010-CatalogSource-console-operator-catalog.yaml new file mode 100644 index 000000000..40fa6e941 --- /dev/null +++ b/install/operator-olm/010-CatalogSource-console-operator-catalog.yaml @@ -0,0 +1,10 @@ +--- +apiVersion: operators.coreos.com/v1alpha1 +kind: CatalogSource +metadata: + name: console-operator-catalog +spec: + displayName: StreamsHub + image: quay.io/streamshub/console-operator-catalog:latest + publisher: StreamsHub + sourceType: grpc diff --git a/install/operator-olm/020-Subscription-console-operator.yaml b/install/operator-olm/020-Subscription-console-operator.yaml new file mode 100644 index 000000000..ee7c2f069 --- /dev/null +++ b/install/operator-olm/020-Subscription-console-operator.yaml @@ -0,0 +1,10 @@ +--- +apiVersion: operators.coreos.com/v1alpha1 +kind: Subscription +metadata: + name: console-operator +spec: + name: console-operator + channel: alpha + source: console-operator-catalog + sourceNamespace: ${NAMESPACE} diff --git a/install/resources/console/console-ui.route.yaml b/install/resources/console/console-ui.route.yaml deleted file mode 100644 index 86a7ae970..000000000 --- a/install/resources/console/console-ui.route.yaml +++ /dev/null @@ -1,13 +0,0 @@ -kind: Route -apiVersion: route.openshift.io/v1 -metadata: - name: console-ui-route -spec: - to: - kind: Service - name: console-ui - weight: 100 - tls: - termination: edge - insecureEdgeTerminationPolicy: Redirect - wildcardPolicy: None diff --git a/install/resources/console/console.instance.yaml b/install/resources/console/console.instance.yaml deleted file mode 100644 index fb3fe8671..000000000 --- a/install/resources/console/console.instance.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: console.streamshub.github.com/v1alpha1 -kind: Console -metadata: - name: example -spec: - hostname: example-console.$CLUSTER_DOMAIN - kafkaClusters: - - name: console-kafka - namespace: $TARGET_NAMESPACE - listener: secure - credentials: - kafkaUser: - name: console-kafka-user1 \ No newline at end of file diff --git a/install/resources/kafka/console-kafka-zk.kafka.yaml b/install/resources/kafka/console-kafka-zk.kafka.yaml deleted file mode 100644 index f25ca968e..000000000 --- a/install/resources/kafka/console-kafka-zk.kafka.yaml +++ /dev/null @@ -1,65 +0,0 @@ -apiVersion: kafka.strimzi.io/v1beta2 -kind: Kafka -metadata: - name: console-kafka -spec: - entityOperator: - topicOperator: {} - userOperator: {} - kafka: - authorization: - type: simple - config: - allow.everyone.if.no.acl.found: 'true' - default.replication.factor: 3 - inter.broker.protocol.version: '3.7' - min.insync.replicas: 2 - offsets.topic.replication.factor: 3 - transaction.state.log.min.isr: 2 - transaction.state.log.replication.factor: 3 - listeners: - - name: secure - port: 9093 - tls: true - type: ${LISTENER_TYPE} - authentication: - type: scram-sha-512 - configuration: - bootstrap: - host: bootstrap.console-kafka.${CLUSTER_DOMAIN} - annotations: - streamshub.github.com/console-listener: 'true' - brokers: - - broker: 0 - host: broker-0.console-kafka.${CLUSTER_DOMAIN} - - broker: 1 - host: broker-1.console-kafka.${CLUSTER_DOMAIN} - - broker: 2 - host: broker-2.console-kafka.${CLUSTER_DOMAIN} - replicas: 3 - storage: - type: jbod - volumes: - - id: 0 - type: persistent-claim - size: 10Gi - deleteClaim: false - metricsConfig: - type: jmxPrometheusExporter - valueFrom: - configMapKeyRef: - name: console-kafka-metrics - key: kafka-metrics-config.yml - version: 3.7.0 - zookeeper: - replicas: 3 - storage: - deleteClaim: false - size: 10Gi - type: persistent-claim - metricsConfig: - type: jmxPrometheusExporter - valueFrom: - configMapKeyRef: - name: console-kafka-metrics - key: zookeeper-metrics-config.yml diff --git a/install/resources/prometheus/console-operators.operatorgroup.yaml b/install/resources/prometheus/console-operators.operatorgroup.yaml deleted file mode 100644 index cdcb7ff04..000000000 --- a/install/resources/prometheus/console-operators.operatorgroup.yaml +++ /dev/null @@ -1,8 +0,0 @@ -apiVersion: operators.coreos.com/v1 -kind: OperatorGroup -metadata: - name: console-operators -spec: - targetNamespaces: - - ${NAMESPACE} - upgradeStrategy: Default diff --git a/operator/src/main/kubernetes/kubernetes.yml b/operator/src/main/kubernetes/kubernetes.yml index b37b5f9a3..8904206d3 100644 --- a/operator/src/main/kubernetes/kubernetes.yml +++ b/operator/src/main/kubernetes/kubernetes.yml @@ -2,7 +2,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: - name: console-operator-cluster-role + name: consolereconciler-additional-cluster-role rules: - apiGroups: - coordination.k8s.io @@ -18,6 +18,8 @@ rules: resources: # The cluster operator needs to access and manage leases for leader election - leases + resourceNames: + - console-operator-lease verbs: - get - list @@ -28,29 +30,6 @@ rules: # temporary until available: https://github.com/operator-framework/java-operator-sdk/pull/2456 - create - - apiGroups: - - apiextensions.k8s.io - resources: - - customresourcedefinitions - verbs: - - get - - list - - - apiGroups: - - console.streamshub.github.com - resources: - - consoles - - consoles/status - - consoles/finalizers - verbs: - - get - - list - - watch - - patch - - update - - create - - delete - # Granted to Prometheus instances - apiGroups: [ '' ] resources: @@ -83,11 +62,11 @@ rules: apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: - name: console-operator-cluster-role-binding + name: consolereconciler-additional-cluster-role-binding roleRef: kind: ClusterRole apiGroup: rbac.authorization.k8s.io - name: console-operator-cluster-role + name: consolereconciler-additional-cluster-role subjects: - kind: ServiceAccount name: console-operator