// This assembly is included in the following assemblies:
//
// master.adoc

[id='appendix-faq_{context}']
= Frequently asked questions

== Questions related to the Cluster Operator

[id='co-faq-admin-privileges_{context}']
=== Why do I need cluster administrator privileges to install Strimzi?

To install Strimzi, you need to be able to create the following cluster-scoped resources:

* Custom Resource Definitions (CRDs) to instruct Kubernetes about resources that are specific to Strimzi, such as `Kafka` and `KafkaConnect`
* `ClusterRoles` and `ClusterRoleBindings`

Cluster-scoped resources, which are not scoped to a particular Kubernetes namespace, typically require _cluster administrator_ privileges to install.

As a cluster administrator, you can inspect all the resources being installed (in the `/install/` directory) to ensure that the `ClusterRoles` do not grant unnecessary privileges.

After installation, the Cluster Operator runs as a regular `Deployment`, so any standard (non-admin) Kubernetes user with privileges to access the `Deployment` can configure it.
The cluster administrator can grant standard users the privileges necessary to manage `Kafka` custom resources.

See also:

* xref:co-faq-cluster-role-bindings_{context}[Why does the Cluster Operator need to create `ClusterRoleBindings`?]
* xref:co-faq-standard-users_{context}[Can standard Kubernetes users create Kafka custom resources?]

[id='co-faq-cluster-role-bindings_{context}']
=== Why does the Cluster Operator need to create `ClusterRoleBindings`?

Kubernetes has built-in link:https://kubernetes.io/docs/reference/access-authn-authz/rbac/#privilege-escalation-prevention-and-bootstrapping[privilege escalation prevention^],
which means that the Cluster Operator cannot grant privileges it does not have itself, specifically, it cannot grant such privileges in a namespace it cannot access.
Therefore, the Cluster Operator must have the privileges necessary for _all_ the components it orchestrates.

The Cluster Operator needs to be able to grant access so that:

* The Topic Operator can manage  `KafkaTopics`, by creating `Roles` and `RoleBindings` in the namespace that the operator runs in
* The User Operator can manage `KafkaUsers`, by creating `Roles` and `RoleBindings` in the namespace that the operator runs in
* The failure domain of a `Node` is discovered by Strimzi, by creating a `ClusterRoleBinding`

When using rack-aware partition assignment, the broker pod needs to be able to get information about the `Node` it is running on,
for example, the Availability Zone in Amazon AWS.
A `Node` is a cluster-scoped resource, so access to it can only be granted through a `ClusterRoleBinding`, not a namespace-scoped `RoleBinding`.

[id='co-faq-standard-users_{context}']
=== Can standard Kubernetes users create Kafka custom resources?

By default, standard Kubernetes users will not have the privileges necessary to manage the custom resources handled by the Cluster Operator.
The cluster administrator can grant a user the necessary privileges using Kubernetes RBAC resources.

For more information, see link:{BookURLDeploying}#adding-users-the-strimzi-admin-role-str[Designating Strimzi administrators^] in the _Deploying Strimzi_ guide.

=== What do the _failed to acquire lock_ warnings in the log mean?

For each cluster, the Cluster Operator executes only one operation at a time.
The Cluster Operator uses locks to make sure that there are never two parallel operations running for the same cluster.
Other operations must wait until the current operation completes before the lock is released.

INFO:: Examples of cluster operations include _cluster creation_, _rolling update_, _scale down_ , and _scale up_.

If the waiting time for the lock takes too long, the operation times out and the following warning message is printed to
the log:

[source,shell]
----
2018-03-04 17:09:24 WARNING AbstractClusterOperations:290 - Failed to acquire lock for kafka cluster lock::kafka::myproject::my-cluster
----

Depending on the exact configuration of `STRIMZI_FULL_RECONCILIATION_INTERVAL_MS` and `STRIMZI_OPERATION_TIMEOUT_MS`, this
warning message might appear occasionally without indicating any underlying issues.
Operations that time out are picked up in the next periodic reconciliation, so that the operation can acquire the lock and execute again.

Should this message appear periodically, even in situations when there should be no other operations running for a given
cluster, it might indicate that the lock was not properly released due to an error.
If this is the case, try restarting the Cluster Operator.

=== Why is hostname verification failing when connecting to NodePorts using TLS?

Currently, off-cluster access using NodePorts with TLS encryption enabled does not support TLS hostname verification.
As a result, the clients that verify the hostname will fail to connect.
For example, the Java client will fail with the following exception:

[source,java]
Caused by: java.security.cert.CertificateException: No subject alternative names matching IP address 168.72.15.231 found
 at sun.security.util.HostnameChecker.matchIP(HostnameChecker.java:168)
 at sun.security.util.HostnameChecker.match(HostnameChecker.java:94)
 at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:455)
 at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:436)
 at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:252)
 at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:136)
 at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1501)
 ... 17 more

To connect, you must disable hostname verification.
In the Java client, you can do this by setting the configuration option `ssl.endpoint.identification.algorithm` to an empty string.

When configuring the client using a properties file, you can do it this way:

[source,properties]
ssl.endpoint.identification.algorithm=

When configuring the client directly in Java, set the configuration option to an empty string:

[source,java]
props.put("ssl.endpoint.identification.algorithm", "");
