Search in sources :

Example 1 with KafkaRoller

use of io.strimzi.operator.cluster.operator.resource.KafkaRoller in project strimzi by strimzi.

the class CaReconciler method rollingUpdateForNewCaKey.

/**
 * Perform a rolling update of the cluster so that CA certificates get added to their truststores, or expired CA
 * certificates get removed from their truststores. Note this is only necessary when the CA certificate has changed
 * due to a new CA key. It is not necessary when the CA certificate is replace while retaining the existing key.
 */
Future<Void> rollingUpdateForNewCaKey() {
    List<String> reason = new ArrayList<>(2);
    if (clusterCa.keyReplaced()) {
        reason.add("trust new cluster CA certificate signed by new key");
    }
    if (clientsCa.keyReplaced()) {
        reason.add("trust new clients CA certificate signed by new key");
    }
    if (!reason.isEmpty()) {
        Future<Void> zkRollFuture;
        Function<Pod, List<String>> rollPodAndLogReason = pod -> {
            LOGGER.debugCr(reconciliation, "Rolling Pod {} to {}", pod.getMetadata().getName(), reason);
            return reason;
        };
        if (clusterCa.keyReplaced()) {
            // ZooKeeper is rolled only for new Cluster CA key
            Labels zkSelectorLabels = Labels.EMPTY.withStrimziKind(reconciliation.kind()).withStrimziCluster(reconciliation.name()).withStrimziName(KafkaResources.zookeeperStatefulSetName(reconciliation.name()));
            zkRollFuture = new ZooKeeperRoller(podOperator, zookeeperLeaderFinder, operationTimeoutMs).maybeRollingUpdate(reconciliation, zkSelectorLabels, rollPodAndLogReason, clusterCa.caCertSecret(), oldCoSecret);
        } else {
            zkRollFuture = Future.succeededFuture();
        }
        return zkRollFuture.compose(i -> {
            if (featureGates.useStrimziPodSetsEnabled()) {
                return strimziPodSetOperator.getAsync(reconciliation.namespace(), KafkaResources.kafkaStatefulSetName(reconciliation.name())).compose(podSet -> {
                    if (podSet != null) {
                        return Future.succeededFuture(KafkaCluster.generatePodList(reconciliation.name(), podSet.getSpec().getPods().size()));
                    } else {
                        return Future.succeededFuture(List.<String>of());
                    }
                });
            } else {
                return stsOperator.getAsync(reconciliation.namespace(), KafkaResources.kafkaStatefulSetName(reconciliation.name())).compose(sts -> {
                    if (sts != null) {
                        return Future.succeededFuture(KafkaCluster.generatePodList(reconciliation.name(), sts.getSpec().getReplicas()));
                    } else {
                        return Future.succeededFuture(List.<String>of());
                    }
                });
            }
        }).compose(replicas -> new KafkaRoller(reconciliation, vertx, podOperator, 1_000, operationTimeoutMs, () -> new BackOff(250, 2, 10), replicas, clusterCa.caCertSecret(), oldCoSecret, adminClientProvider, brokerId -> null, null, null, false).rollingRestart(rollPodAndLogReason)).compose(i -> {
            if (clusterCa.keyReplaced()) {
                // EO, KE and CC need to be rolled only for new Cluster CA key.
                return rollDeploymentIfExists(KafkaResources.entityOperatorDeploymentName(reconciliation.name()), reason.toString()).compose(i2 -> rollDeploymentIfExists(KafkaExporterResources.deploymentName(reconciliation.name()), reason.toString())).compose(i2 -> rollDeploymentIfExists(CruiseControlResources.deploymentName(reconciliation.name()), reason.toString()));
            } else {
                return Future.succeededFuture();
            }
        });
    } else {
        return Future.succeededFuture();
    }
}
Also used : BackOff(io.strimzi.operator.common.BackOff) KafkaExporterResources(io.strimzi.api.kafka.model.KafkaExporterResources) StrimziPodSetOperator(io.strimzi.operator.common.operator.resource.StrimziPodSetOperator) Date(java.util.Date) CertManager(io.strimzi.certs.CertManager) Annotations(io.strimzi.operator.common.Annotations) OwnerReference(io.fabric8.kubernetes.api.model.OwnerReference) Function(java.util.function.Function) Supplier(java.util.function.Supplier) FeatureGates(io.strimzi.operator.cluster.FeatureGates) ArrayList(java.util.ArrayList) CompositeFuture(io.vertx.core.CompositeFuture) KafkaCluster(io.strimzi.operator.cluster.model.KafkaCluster) KafkaResources(io.strimzi.api.kafka.model.KafkaResources) ClusterOperator(io.strimzi.operator.cluster.ClusterOperator) Ca(io.strimzi.operator.cluster.model.Ca) Map(java.util.Map) ZookeeperLeaderFinder(io.strimzi.operator.cluster.operator.resource.ZookeeperLeaderFinder) PodOperator(io.strimzi.operator.common.operator.resource.PodOperator) KafkaRoller(io.strimzi.operator.cluster.operator.resource.KafkaRoller) ResourceOperatorSupplier(io.strimzi.operator.cluster.operator.resource.ResourceOperatorSupplier) ReconcileResult(io.strimzi.operator.common.operator.resource.ReconcileResult) AbstractModel(io.strimzi.operator.cluster.model.AbstractModel) StatefulSetOperator(io.strimzi.operator.cluster.operator.resource.StatefulSetOperator) ModelUtils(io.strimzi.operator.cluster.model.ModelUtils) ReconciliationLogger(io.strimzi.operator.common.ReconciliationLogger) CertificateAuthority(io.strimzi.api.kafka.model.CertificateAuthority) OwnerReferenceBuilder(io.fabric8.kubernetes.api.model.OwnerReferenceBuilder) InvalidResourceException(io.strimzi.operator.cluster.model.InvalidResourceException) DeploymentOperator(io.strimzi.operator.common.operator.resource.DeploymentOperator) Promise(io.vertx.core.Promise) Vertx(io.vertx.core.Vertx) Pod(io.fabric8.kubernetes.api.model.Pod) SecretOperator(io.strimzi.operator.common.operator.resource.SecretOperator) ClientsCa(io.strimzi.operator.cluster.model.ClientsCa) ZooKeeperRoller(io.strimzi.operator.cluster.operator.resource.ZooKeeperRoller) Future(io.vertx.core.Future) CruiseControlResources(io.strimzi.api.kafka.model.CruiseControlResources) Reconciliation(io.strimzi.operator.common.Reconciliation) List(java.util.List) Util(io.strimzi.operator.common.Util) Labels(io.strimzi.operator.common.model.Labels) PasswordGenerator(io.strimzi.operator.common.PasswordGenerator) Secret(io.fabric8.kubernetes.api.model.Secret) AdminClientProvider(io.strimzi.operator.common.AdminClientProvider) Kafka(io.strimzi.api.kafka.model.Kafka) ClusterCa(io.strimzi.operator.cluster.model.ClusterCa) ClusterOperatorConfig(io.strimzi.operator.cluster.ClusterOperatorConfig) Pod(io.fabric8.kubernetes.api.model.Pod) ArrayList(java.util.ArrayList) Labels(io.strimzi.operator.common.model.Labels) BackOff(io.strimzi.operator.common.BackOff) ZooKeeperRoller(io.strimzi.operator.cluster.operator.resource.ZooKeeperRoller) ArrayList(java.util.ArrayList) List(java.util.List) KafkaRoller(io.strimzi.operator.cluster.operator.resource.KafkaRoller)

Example 2 with KafkaRoller

use of io.strimzi.operator.cluster.operator.resource.KafkaRoller in project strimzi-kafka-operator by strimzi.

the class KafkaReconciler method perBrokerKafkaConfiguration.

/**
 * Generates and creates the ConfigMaps with per-broker configuration for Kafka brokers used in PodSets. It will
 * also delete the ConfigMaps for any scaled-down brokers (scale down is done before this is called in the
 * reconciliation)
 *
 * @param metricsAndLogging     Metrics and Logging configuration
 *
 * @return  Future which completes when the Kafka Configuration is prepared
 */
protected Future<Void> perBrokerKafkaConfiguration(MetricsAndLogging metricsAndLogging) {
    return configMapOperator.listAsync(reconciliation.namespace(), kafka.getSelectorLabels()).compose(existingConfigMaps -> {
        // This is used during Kafka rolling updates -> we have to store it for later
        this.logging = kafka.loggingConfiguration(kafka.getLogging(), metricsAndLogging.getLoggingCm());
        this.loggingHash = Util.hashStub(Util.getLoggingDynamicallyUnmodifiableEntries(logging));
        List<ConfigMap> desiredConfigMaps = kafka.generatePerBrokerConfigurationConfigMaps(metricsAndLogging, listenerReconciliationResults.advertisedHostnames, listenerReconciliationResults.advertisedPorts, featureGates.controlPlaneListenerEnabled());
        // Has to use Raw type because of the CompositeFuture
        @SuppressWarnings({ "rawtypes" }) List<Future> ops = new ArrayList<>(existingConfigMaps.size() + kafka.getReplicas());
        // Delete all existing ConfigMaps which are not desired and are not the shared config map
        List<String> desiredNames = new ArrayList<>(desiredConfigMaps.size() + 1);
        // We do not want to delete the shared ConfigMap, so we add it here
        desiredNames.add(kafka.getAncillaryConfigMapName());
        desiredNames.addAll(desiredConfigMaps.stream().map(cm -> cm.getMetadata().getName()).collect(Collectors.toList()));
        for (ConfigMap cm : existingConfigMaps) {
            // We delete the cms not on the desired names list
            if (!desiredNames.contains(cm.getMetadata().getName())) {
                ops.add(configMapOperator.deleteAsync(reconciliation, reconciliation.namespace(), cm.getMetadata().getName(), true));
            }
        }
        // Create / update the desired config maps
        for (ConfigMap cm : desiredConfigMaps) {
            String cmName = cm.getMetadata().getName();
            int brokerId = getPodIndexFromPodName(cmName);
            // The advertised hostname and port might change. If they change, we need to roll the pods.
            // Here we collect their hash to trigger the rolling update. For per-broker configuration,
            // we need just the advertised hostnames / ports for given broker.
            String brokerConfiguration = listenerReconciliationResults.advertisedHostnames.get(brokerId).entrySet().stream().map(kv -> kv.getKey() + "://" + kv.getValue()).sorted().collect(Collectors.joining(" "));
            brokerConfiguration += listenerReconciliationResults.advertisedPorts.get(brokerId).entrySet().stream().map(kv -> kv.getKey() + "://" + kv.getValue()).sorted().collect(Collectors.joining(" "));
            brokerConfiguration += cm.getData().getOrDefault(KafkaCluster.BROKER_LISTENERS_FILENAME, "");
            // Changes to regular Kafka configuration are handled through the KafkaRoller which decides whether to roll the pod or not
            // In addition to that, we have to handle changes to configuration unknown to Kafka -> different plugins (Authorization, Quotas etc.)
            // This is captured here with the unknown configurations and the hash is used to roll the pod when it changes
            KafkaConfiguration kc = KafkaConfiguration.unvalidated(reconciliation, cm.getData().getOrDefault(KafkaCluster.BROKER_CONFIGURATION_FILENAME, ""));
            // We store hash of the broker configurations for later use in Pod and in rolling updates
            this.brokerConfigurationHash.put(brokerId, Util.hashStub(brokerConfiguration + kc.unknownConfigsWithValues(kafka.getKafkaVersion()).toString()));
            ops.add(configMapOperator.reconcile(reconciliation, reconciliation.namespace(), cmName, cm));
        }
        return CompositeFuture.join(ops).map((Void) null);
    });
}
Also used : IngressV1Beta1Operator(io.strimzi.operator.common.operator.resource.IngressV1Beta1Operator) Storage(io.strimzi.api.kafka.model.storage.Storage) StrimziPodSetOperator(io.strimzi.operator.common.operator.resource.StrimziPodSetOperator) Date(java.util.Date) Annotations(io.strimzi.operator.common.Annotations) KafkaException(org.apache.kafka.common.KafkaException) PodDisruptionBudget(io.fabric8.kubernetes.api.model.policy.v1.PodDisruptionBudget) ClusterRoleBindingOperator(io.strimzi.operator.common.operator.resource.ClusterRoleBindingOperator) KafkaResources(io.strimzi.api.kafka.model.KafkaResources) Ca(io.strimzi.operator.cluster.model.Ca) PodDisruptionBudgetV1Beta1Operator(io.strimzi.operator.common.operator.resource.PodDisruptionBudgetV1Beta1Operator) StrimziPodSetBuilder(io.strimzi.api.kafka.model.StrimziPodSetBuilder) Map(java.util.Map) PodOperator(io.strimzi.operator.common.operator.resource.PodOperator) ResourceOperatorSupplier(io.strimzi.operator.cluster.operator.resource.ResourceOperatorSupplier) AbstractModel(io.strimzi.operator.cluster.model.AbstractModel) StatefulSetOperator(io.strimzi.operator.cluster.operator.resource.StatefulSetOperator) KafkaVersionChange(io.strimzi.operator.cluster.model.KafkaVersionChange) ModelUtils(io.strimzi.operator.cluster.model.ModelUtils) ListenersUtils(io.strimzi.operator.cluster.model.ListenersUtils) ListenerAddress(io.strimzi.api.kafka.model.status.ListenerAddress) SecretOperator(io.strimzi.operator.common.operator.resource.SecretOperator) Set(java.util.Set) ClientsCa(io.strimzi.operator.cluster.model.ClientsCa) HasMetadata(io.fabric8.kubernetes.api.model.HasMetadata) NodeUtils(io.strimzi.operator.cluster.model.NodeUtils) Future(io.vertx.core.Future) Collectors(java.util.stream.Collectors) ListenerStatus(io.strimzi.api.kafka.model.status.ListenerStatus) List(java.util.List) KafkaConfiguration(io.strimzi.operator.cluster.model.KafkaConfiguration) Labels(io.strimzi.operator.common.model.Labels) StrimziPodSet(io.strimzi.api.kafka.model.StrimziPodSet) PersistentVolumeClaim(io.fabric8.kubernetes.api.model.PersistentVolumeClaim) Secret(io.fabric8.kubernetes.api.model.Secret) RouteOperator(io.strimzi.operator.common.operator.resource.RouteOperator) AdminClientProvider(io.strimzi.operator.common.AdminClientProvider) ClusterCa(io.strimzi.operator.cluster.model.ClusterCa) PodDisruptionBudgetOperator(io.strimzi.operator.common.operator.resource.PodDisruptionBudgetOperator) PlatformFeaturesAvailability(io.strimzi.operator.PlatformFeaturesAvailability) SuppressFBWarnings(edu.umd.cs.findbugs.annotations.SuppressFBWarnings) ClusterOperatorConfig(io.strimzi.operator.cluster.ClusterOperatorConfig) IntStream(java.util.stream.IntStream) ClusterRoleBinding(io.fabric8.kubernetes.api.model.rbac.ClusterRoleBinding) KafkaStatus(io.strimzi.api.kafka.model.status.KafkaStatus) GenericKafkaListener(io.strimzi.api.kafka.model.listener.arraylistener.GenericKafkaListener) BackOff(io.strimzi.operator.common.BackOff) IngressOperator(io.strimzi.operator.common.operator.resource.IngressOperator) NetworkPolicyOperator(io.strimzi.operator.common.operator.resource.NetworkPolicyOperator) HashMap(java.util.HashMap) ListenerAddressBuilder(io.strimzi.api.kafka.model.status.ListenerAddressBuilder) LocalObjectReference(io.fabric8.kubernetes.api.model.LocalObjectReference) Function(java.util.function.Function) Supplier(java.util.function.Supplier) FeatureGates(io.strimzi.operator.cluster.FeatureGates) StorageDiff(io.strimzi.operator.cluster.model.StorageDiff) MetricsAndLogging(io.strimzi.operator.common.MetricsAndLogging) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) ServiceOperator(io.strimzi.operator.common.operator.resource.ServiceOperator) CompositeFuture(io.vertx.core.CompositeFuture) KafkaCluster(io.strimzi.operator.cluster.model.KafkaCluster) ServiceAccountOperator(io.strimzi.operator.common.operator.resource.ServiceAccountOperator) ConfigMapOperator(io.strimzi.operator.common.operator.resource.ConfigMapOperator) ANNO_STRIMZI_IO_KAFKA_VERSION(io.strimzi.operator.cluster.model.KafkaCluster.ANNO_STRIMZI_IO_KAFKA_VERSION) KafkaRoller(io.strimzi.operator.cluster.operator.resource.KafkaRoller) Admin(org.apache.kafka.clients.admin.Admin) ReconcileResult(io.strimzi.operator.common.operator.resource.ReconcileResult) ConcurrentDeletionException(io.strimzi.operator.cluster.operator.resource.ConcurrentDeletionException) Node(io.fabric8.kubernetes.api.model.Node) JbodStorage(io.strimzi.api.kafka.model.storage.JbodStorage) ReconciliationLogger(io.strimzi.operator.common.ReconciliationLogger) NodeOperator(io.strimzi.operator.common.operator.resource.NodeOperator) Promise(io.vertx.core.Promise) Vertx(io.vertx.core.Vertx) Pod(io.fabric8.kubernetes.api.model.Pod) PodSetUtils(io.strimzi.operator.cluster.model.PodSetUtils) StorageClassOperator(io.strimzi.operator.common.operator.resource.StorageClassOperator) StatefulSet(io.fabric8.kubernetes.api.model.apps.StatefulSet) PvcOperator(io.strimzi.operator.common.operator.resource.PvcOperator) ConfigMap(io.fabric8.kubernetes.api.model.ConfigMap) ExecutionException(java.util.concurrent.ExecutionException) Reconciliation(io.strimzi.operator.common.Reconciliation) ImagePullPolicy(io.strimzi.operator.cluster.model.ImagePullPolicy) ANNO_STRIMZI_IO_STORAGE(io.strimzi.operator.cluster.model.AbstractModel.ANNO_STRIMZI_IO_STORAGE) Util(io.strimzi.operator.common.Util) Kafka(io.strimzi.api.kafka.model.Kafka) ConfigMap(io.fabric8.kubernetes.api.model.ConfigMap) ArrayList(java.util.ArrayList) Future(io.vertx.core.Future) CompositeFuture(io.vertx.core.CompositeFuture) KafkaConfiguration(io.strimzi.operator.cluster.model.KafkaConfiguration)

Example 3 with KafkaRoller

use of io.strimzi.operator.cluster.operator.resource.KafkaRoller in project strimzi by strimzi.

the class KafkaReconciler method perBrokerKafkaConfiguration.

/**
 * Generates and creates the ConfigMaps with per-broker configuration for Kafka brokers used in PodSets. It will
 * also delete the ConfigMaps for any scaled-down brokers (scale down is done before this is called in the
 * reconciliation)
 *
 * @param metricsAndLogging     Metrics and Logging configuration
 *
 * @return  Future which completes when the Kafka Configuration is prepared
 */
protected Future<Void> perBrokerKafkaConfiguration(MetricsAndLogging metricsAndLogging) {
    return configMapOperator.listAsync(reconciliation.namespace(), kafka.getSelectorLabels()).compose(existingConfigMaps -> {
        // This is used during Kafka rolling updates -> we have to store it for later
        this.logging = kafka.loggingConfiguration(kafka.getLogging(), metricsAndLogging.getLoggingCm());
        this.loggingHash = Util.hashStub(Util.getLoggingDynamicallyUnmodifiableEntries(logging));
        List<ConfigMap> desiredConfigMaps = kafka.generatePerBrokerConfigurationConfigMaps(metricsAndLogging, listenerReconciliationResults.advertisedHostnames, listenerReconciliationResults.advertisedPorts, featureGates.controlPlaneListenerEnabled());
        // Has to use Raw type because of the CompositeFuture
        @SuppressWarnings({ "rawtypes" }) List<Future> ops = new ArrayList<>(existingConfigMaps.size() + kafka.getReplicas());
        // Delete all existing ConfigMaps which are not desired and are not the shared config map
        List<String> desiredNames = new ArrayList<>(desiredConfigMaps.size() + 1);
        // We do not want to delete the shared ConfigMap, so we add it here
        desiredNames.add(kafka.getAncillaryConfigMapName());
        desiredNames.addAll(desiredConfigMaps.stream().map(cm -> cm.getMetadata().getName()).collect(Collectors.toList()));
        for (ConfigMap cm : existingConfigMaps) {
            // We delete the cms not on the desired names list
            if (!desiredNames.contains(cm.getMetadata().getName())) {
                ops.add(configMapOperator.deleteAsync(reconciliation, reconciliation.namespace(), cm.getMetadata().getName(), true));
            }
        }
        // Create / update the desired config maps
        for (ConfigMap cm : desiredConfigMaps) {
            String cmName = cm.getMetadata().getName();
            int brokerId = getPodIndexFromPodName(cmName);
            // The advertised hostname and port might change. If they change, we need to roll the pods.
            // Here we collect their hash to trigger the rolling update. For per-broker configuration,
            // we need just the advertised hostnames / ports for given broker.
            String brokerConfiguration = listenerReconciliationResults.advertisedHostnames.get(brokerId).entrySet().stream().map(kv -> kv.getKey() + "://" + kv.getValue()).sorted().collect(Collectors.joining(" "));
            brokerConfiguration += listenerReconciliationResults.advertisedPorts.get(brokerId).entrySet().stream().map(kv -> kv.getKey() + "://" + kv.getValue()).sorted().collect(Collectors.joining(" "));
            brokerConfiguration += cm.getData().getOrDefault(KafkaCluster.BROKER_LISTENERS_FILENAME, "");
            // Changes to regular Kafka configuration are handled through the KafkaRoller which decides whether to roll the pod or not
            // In addition to that, we have to handle changes to configuration unknown to Kafka -> different plugins (Authorization, Quotas etc.)
            // This is captured here with the unknown configurations and the hash is used to roll the pod when it changes
            KafkaConfiguration kc = KafkaConfiguration.unvalidated(reconciliation, cm.getData().getOrDefault(KafkaCluster.BROKER_CONFIGURATION_FILENAME, ""));
            // We store hash of the broker configurations for later use in Pod and in rolling updates
            this.brokerConfigurationHash.put(brokerId, Util.hashStub(brokerConfiguration + kc.unknownConfigsWithValues(kafka.getKafkaVersion()).toString()));
            ops.add(configMapOperator.reconcile(reconciliation, reconciliation.namespace(), cmName, cm));
        }
        return CompositeFuture.join(ops).map((Void) null);
    });
}
Also used : IngressV1Beta1Operator(io.strimzi.operator.common.operator.resource.IngressV1Beta1Operator) Storage(io.strimzi.api.kafka.model.storage.Storage) StrimziPodSetOperator(io.strimzi.operator.common.operator.resource.StrimziPodSetOperator) Date(java.util.Date) Annotations(io.strimzi.operator.common.Annotations) KafkaException(org.apache.kafka.common.KafkaException) PodDisruptionBudget(io.fabric8.kubernetes.api.model.policy.v1.PodDisruptionBudget) ClusterRoleBindingOperator(io.strimzi.operator.common.operator.resource.ClusterRoleBindingOperator) KafkaResources(io.strimzi.api.kafka.model.KafkaResources) Ca(io.strimzi.operator.cluster.model.Ca) PodDisruptionBudgetV1Beta1Operator(io.strimzi.operator.common.operator.resource.PodDisruptionBudgetV1Beta1Operator) StrimziPodSetBuilder(io.strimzi.api.kafka.model.StrimziPodSetBuilder) Map(java.util.Map) PodOperator(io.strimzi.operator.common.operator.resource.PodOperator) ResourceOperatorSupplier(io.strimzi.operator.cluster.operator.resource.ResourceOperatorSupplier) AbstractModel(io.strimzi.operator.cluster.model.AbstractModel) StatefulSetOperator(io.strimzi.operator.cluster.operator.resource.StatefulSetOperator) KafkaVersionChange(io.strimzi.operator.cluster.model.KafkaVersionChange) ModelUtils(io.strimzi.operator.cluster.model.ModelUtils) ListenersUtils(io.strimzi.operator.cluster.model.ListenersUtils) ListenerAddress(io.strimzi.api.kafka.model.status.ListenerAddress) SecretOperator(io.strimzi.operator.common.operator.resource.SecretOperator) Set(java.util.Set) ClientsCa(io.strimzi.operator.cluster.model.ClientsCa) HasMetadata(io.fabric8.kubernetes.api.model.HasMetadata) NodeUtils(io.strimzi.operator.cluster.model.NodeUtils) Future(io.vertx.core.Future) Collectors(java.util.stream.Collectors) ListenerStatus(io.strimzi.api.kafka.model.status.ListenerStatus) List(java.util.List) KafkaConfiguration(io.strimzi.operator.cluster.model.KafkaConfiguration) Labels(io.strimzi.operator.common.model.Labels) StrimziPodSet(io.strimzi.api.kafka.model.StrimziPodSet) PersistentVolumeClaim(io.fabric8.kubernetes.api.model.PersistentVolumeClaim) Secret(io.fabric8.kubernetes.api.model.Secret) RouteOperator(io.strimzi.operator.common.operator.resource.RouteOperator) AdminClientProvider(io.strimzi.operator.common.AdminClientProvider) ClusterCa(io.strimzi.operator.cluster.model.ClusterCa) PodDisruptionBudgetOperator(io.strimzi.operator.common.operator.resource.PodDisruptionBudgetOperator) PlatformFeaturesAvailability(io.strimzi.operator.PlatformFeaturesAvailability) SuppressFBWarnings(edu.umd.cs.findbugs.annotations.SuppressFBWarnings) ClusterOperatorConfig(io.strimzi.operator.cluster.ClusterOperatorConfig) IntStream(java.util.stream.IntStream) ClusterRoleBinding(io.fabric8.kubernetes.api.model.rbac.ClusterRoleBinding) KafkaStatus(io.strimzi.api.kafka.model.status.KafkaStatus) GenericKafkaListener(io.strimzi.api.kafka.model.listener.arraylistener.GenericKafkaListener) BackOff(io.strimzi.operator.common.BackOff) IngressOperator(io.strimzi.operator.common.operator.resource.IngressOperator) NetworkPolicyOperator(io.strimzi.operator.common.operator.resource.NetworkPolicyOperator) HashMap(java.util.HashMap) ListenerAddressBuilder(io.strimzi.api.kafka.model.status.ListenerAddressBuilder) LocalObjectReference(io.fabric8.kubernetes.api.model.LocalObjectReference) Function(java.util.function.Function) Supplier(java.util.function.Supplier) FeatureGates(io.strimzi.operator.cluster.FeatureGates) StorageDiff(io.strimzi.operator.cluster.model.StorageDiff) MetricsAndLogging(io.strimzi.operator.common.MetricsAndLogging) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) ServiceOperator(io.strimzi.operator.common.operator.resource.ServiceOperator) CompositeFuture(io.vertx.core.CompositeFuture) KafkaCluster(io.strimzi.operator.cluster.model.KafkaCluster) ServiceAccountOperator(io.strimzi.operator.common.operator.resource.ServiceAccountOperator) ConfigMapOperator(io.strimzi.operator.common.operator.resource.ConfigMapOperator) ANNO_STRIMZI_IO_KAFKA_VERSION(io.strimzi.operator.cluster.model.KafkaCluster.ANNO_STRIMZI_IO_KAFKA_VERSION) KafkaRoller(io.strimzi.operator.cluster.operator.resource.KafkaRoller) Admin(org.apache.kafka.clients.admin.Admin) ReconcileResult(io.strimzi.operator.common.operator.resource.ReconcileResult) ConcurrentDeletionException(io.strimzi.operator.cluster.operator.resource.ConcurrentDeletionException) Node(io.fabric8.kubernetes.api.model.Node) JbodStorage(io.strimzi.api.kafka.model.storage.JbodStorage) ReconciliationLogger(io.strimzi.operator.common.ReconciliationLogger) NodeOperator(io.strimzi.operator.common.operator.resource.NodeOperator) Promise(io.vertx.core.Promise) Vertx(io.vertx.core.Vertx) Pod(io.fabric8.kubernetes.api.model.Pod) PodSetUtils(io.strimzi.operator.cluster.model.PodSetUtils) StorageClassOperator(io.strimzi.operator.common.operator.resource.StorageClassOperator) StatefulSet(io.fabric8.kubernetes.api.model.apps.StatefulSet) PvcOperator(io.strimzi.operator.common.operator.resource.PvcOperator) ConfigMap(io.fabric8.kubernetes.api.model.ConfigMap) ExecutionException(java.util.concurrent.ExecutionException) Reconciliation(io.strimzi.operator.common.Reconciliation) ImagePullPolicy(io.strimzi.operator.cluster.model.ImagePullPolicy) ANNO_STRIMZI_IO_STORAGE(io.strimzi.operator.cluster.model.AbstractModel.ANNO_STRIMZI_IO_STORAGE) Util(io.strimzi.operator.common.Util) Kafka(io.strimzi.api.kafka.model.Kafka) ConfigMap(io.fabric8.kubernetes.api.model.ConfigMap) ArrayList(java.util.ArrayList) Future(io.vertx.core.Future) CompositeFuture(io.vertx.core.CompositeFuture) KafkaConfiguration(io.strimzi.operator.cluster.model.KafkaConfiguration)

Example 4 with KafkaRoller

use of io.strimzi.operator.cluster.operator.resource.KafkaRoller in project strimzi-kafka-operator by strimzi.

the class CaReconciler method rollingUpdateForNewCaKey.

/**
 * Perform a rolling update of the cluster so that CA certificates get added to their truststores, or expired CA
 * certificates get removed from their truststores. Note this is only necessary when the CA certificate has changed
 * due to a new CA key. It is not necessary when the CA certificate is replace while retaining the existing key.
 */
Future<Void> rollingUpdateForNewCaKey() {
    List<String> reason = new ArrayList<>(2);
    if (clusterCa.keyReplaced()) {
        reason.add("trust new cluster CA certificate signed by new key");
    }
    if (clientsCa.keyReplaced()) {
        reason.add("trust new clients CA certificate signed by new key");
    }
    if (!reason.isEmpty()) {
        Future<Void> zkRollFuture;
        Function<Pod, List<String>> rollPodAndLogReason = pod -> {
            LOGGER.debugCr(reconciliation, "Rolling Pod {} to {}", pod.getMetadata().getName(), reason);
            return reason;
        };
        if (clusterCa.keyReplaced()) {
            // ZooKeeper is rolled only for new Cluster CA key
            Labels zkSelectorLabels = Labels.EMPTY.withStrimziKind(reconciliation.kind()).withStrimziCluster(reconciliation.name()).withStrimziName(KafkaResources.zookeeperStatefulSetName(reconciliation.name()));
            zkRollFuture = new ZooKeeperRoller(podOperator, zookeeperLeaderFinder, operationTimeoutMs).maybeRollingUpdate(reconciliation, zkSelectorLabels, rollPodAndLogReason, clusterCa.caCertSecret(), oldCoSecret);
        } else {
            zkRollFuture = Future.succeededFuture();
        }
        return zkRollFuture.compose(i -> {
            if (featureGates.useStrimziPodSetsEnabled()) {
                return strimziPodSetOperator.getAsync(reconciliation.namespace(), KafkaResources.kafkaStatefulSetName(reconciliation.name())).compose(podSet -> {
                    if (podSet != null) {
                        return Future.succeededFuture(KafkaCluster.generatePodList(reconciliation.name(), podSet.getSpec().getPods().size()));
                    } else {
                        return Future.succeededFuture(List.<String>of());
                    }
                });
            } else {
                return stsOperator.getAsync(reconciliation.namespace(), KafkaResources.kafkaStatefulSetName(reconciliation.name())).compose(sts -> {
                    if (sts != null) {
                        return Future.succeededFuture(KafkaCluster.generatePodList(reconciliation.name(), sts.getSpec().getReplicas()));
                    } else {
                        return Future.succeededFuture(List.<String>of());
                    }
                });
            }
        }).compose(replicas -> new KafkaRoller(reconciliation, vertx, podOperator, 1_000, operationTimeoutMs, () -> new BackOff(250, 2, 10), replicas, clusterCa.caCertSecret(), oldCoSecret, adminClientProvider, brokerId -> null, null, null, false).rollingRestart(rollPodAndLogReason)).compose(i -> {
            if (clusterCa.keyReplaced()) {
                // EO, KE and CC need to be rolled only for new Cluster CA key.
                return rollDeploymentIfExists(KafkaResources.entityOperatorDeploymentName(reconciliation.name()), reason.toString()).compose(i2 -> rollDeploymentIfExists(KafkaExporterResources.deploymentName(reconciliation.name()), reason.toString())).compose(i2 -> rollDeploymentIfExists(CruiseControlResources.deploymentName(reconciliation.name()), reason.toString()));
            } else {
                return Future.succeededFuture();
            }
        });
    } else {
        return Future.succeededFuture();
    }
}
Also used : BackOff(io.strimzi.operator.common.BackOff) KafkaExporterResources(io.strimzi.api.kafka.model.KafkaExporterResources) StrimziPodSetOperator(io.strimzi.operator.common.operator.resource.StrimziPodSetOperator) Date(java.util.Date) CertManager(io.strimzi.certs.CertManager) Annotations(io.strimzi.operator.common.Annotations) OwnerReference(io.fabric8.kubernetes.api.model.OwnerReference) Function(java.util.function.Function) Supplier(java.util.function.Supplier) FeatureGates(io.strimzi.operator.cluster.FeatureGates) ArrayList(java.util.ArrayList) CompositeFuture(io.vertx.core.CompositeFuture) KafkaCluster(io.strimzi.operator.cluster.model.KafkaCluster) KafkaResources(io.strimzi.api.kafka.model.KafkaResources) ClusterOperator(io.strimzi.operator.cluster.ClusterOperator) Ca(io.strimzi.operator.cluster.model.Ca) Map(java.util.Map) ZookeeperLeaderFinder(io.strimzi.operator.cluster.operator.resource.ZookeeperLeaderFinder) PodOperator(io.strimzi.operator.common.operator.resource.PodOperator) KafkaRoller(io.strimzi.operator.cluster.operator.resource.KafkaRoller) ResourceOperatorSupplier(io.strimzi.operator.cluster.operator.resource.ResourceOperatorSupplier) ReconcileResult(io.strimzi.operator.common.operator.resource.ReconcileResult) AbstractModel(io.strimzi.operator.cluster.model.AbstractModel) StatefulSetOperator(io.strimzi.operator.cluster.operator.resource.StatefulSetOperator) ModelUtils(io.strimzi.operator.cluster.model.ModelUtils) ReconciliationLogger(io.strimzi.operator.common.ReconciliationLogger) CertificateAuthority(io.strimzi.api.kafka.model.CertificateAuthority) OwnerReferenceBuilder(io.fabric8.kubernetes.api.model.OwnerReferenceBuilder) InvalidResourceException(io.strimzi.operator.cluster.model.InvalidResourceException) DeploymentOperator(io.strimzi.operator.common.operator.resource.DeploymentOperator) Promise(io.vertx.core.Promise) Vertx(io.vertx.core.Vertx) Pod(io.fabric8.kubernetes.api.model.Pod) SecretOperator(io.strimzi.operator.common.operator.resource.SecretOperator) ClientsCa(io.strimzi.operator.cluster.model.ClientsCa) ZooKeeperRoller(io.strimzi.operator.cluster.operator.resource.ZooKeeperRoller) Future(io.vertx.core.Future) CruiseControlResources(io.strimzi.api.kafka.model.CruiseControlResources) Reconciliation(io.strimzi.operator.common.Reconciliation) List(java.util.List) Util(io.strimzi.operator.common.Util) Labels(io.strimzi.operator.common.model.Labels) PasswordGenerator(io.strimzi.operator.common.PasswordGenerator) Secret(io.fabric8.kubernetes.api.model.Secret) AdminClientProvider(io.strimzi.operator.common.AdminClientProvider) Kafka(io.strimzi.api.kafka.model.Kafka) ClusterCa(io.strimzi.operator.cluster.model.ClusterCa) ClusterOperatorConfig(io.strimzi.operator.cluster.ClusterOperatorConfig) Pod(io.fabric8.kubernetes.api.model.Pod) ArrayList(java.util.ArrayList) Labels(io.strimzi.operator.common.model.Labels) BackOff(io.strimzi.operator.common.BackOff) ZooKeeperRoller(io.strimzi.operator.cluster.operator.resource.ZooKeeperRoller) ArrayList(java.util.ArrayList) List(java.util.List) KafkaRoller(io.strimzi.operator.cluster.operator.resource.KafkaRoller)

Aggregations

Pod (io.fabric8.kubernetes.api.model.Pod)4 Secret (io.fabric8.kubernetes.api.model.Secret)4 Kafka (io.strimzi.api.kafka.model.Kafka)4 KafkaResources (io.strimzi.api.kafka.model.KafkaResources)4 ClusterOperatorConfig (io.strimzi.operator.cluster.ClusterOperatorConfig)4 FeatureGates (io.strimzi.operator.cluster.FeatureGates)4 AbstractModel (io.strimzi.operator.cluster.model.AbstractModel)4 Ca (io.strimzi.operator.cluster.model.Ca)4 ClientsCa (io.strimzi.operator.cluster.model.ClientsCa)4 ClusterCa (io.strimzi.operator.cluster.model.ClusterCa)4 KafkaCluster (io.strimzi.operator.cluster.model.KafkaCluster)4 ModelUtils (io.strimzi.operator.cluster.model.ModelUtils)4 KafkaRoller (io.strimzi.operator.cluster.operator.resource.KafkaRoller)4 ResourceOperatorSupplier (io.strimzi.operator.cluster.operator.resource.ResourceOperatorSupplier)4 StatefulSetOperator (io.strimzi.operator.cluster.operator.resource.StatefulSetOperator)4 AdminClientProvider (io.strimzi.operator.common.AdminClientProvider)4 Annotations (io.strimzi.operator.common.Annotations)4 BackOff (io.strimzi.operator.common.BackOff)4 Reconciliation (io.strimzi.operator.common.Reconciliation)4 ReconciliationLogger (io.strimzi.operator.common.ReconciliationLogger)4