Skip to content

Commit

Permalink
feat: Support configuring JVM arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
sbernauer committed Jan 28, 2025
1 parent 25d9a9c commit caf4ce4
Show file tree
Hide file tree
Showing 11 changed files with 318 additions and 82 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ All notable changes to this project will be documented in this file.
- The lifetime of auto generated TLS certificates is now configurable with the role and roleGroup
config property `requestedSecretLifetime`. This helps reducing frequent Pod restarts ([#722]).
- Run a `containerdebug` process in the background of each Nifi container to collect debugging information ([#730]).
- Support configuring JVM arguments ([#724]).
- Aggregate emitted Kubernetes events on the CustomResources ([#742]).

### Fixed
Expand All @@ -21,6 +22,7 @@ All notable changes to this project will be documented in this file.
[#717]: https://github.com/stackabletech/nifi-operator/pull/717
[#718]: https://github.com/stackabletech/nifi-operator/pull/718
[#722]: https://github.com/stackabletech/nifi-operator/pull/722
[#724]: https://github.com/stackabletech/nifi-operator/pull/724
[#730]: https://github.com/stackabletech/nifi-operator/pull/730
[#742]: https://github.com/stackabletech/nifi-operator/pull/742

Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

52 changes: 52 additions & 0 deletions deploy/helm/nifi-operator/crds/crds.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,32 @@ spec:
default: {}
description: '`envOverrides` configure environment variables to be set in the Pods. It is a map from strings to strings - environment variables and the value to set. Read the [environment variable overrides documentation](https://docs.stackable.tech/home/nightly/concepts/overrides#env-overrides) for more information and consult the operator specific usage guide to find out about the product specific environment variables that are available.'
type: object
jvmArgumentOverrides:
default:
add: []
remove: []
removeRegex: []
description: Allows overriding JVM arguments. Please read on the [JVM argument overrides documentation](https://docs.stackable.tech/home/nightly/concepts/overrides#jvm-argument-overrides) for details on the usage.
properties:
add:
default: []
description: JVM arguments to be added
items:
type: string
type: array
remove:
default: []
description: JVM arguments to be removed by exact match
items:
type: string
type: array
removeRegex:
default: []
description: JVM arguments matching any of this regexes will be removed
items:
type: string
type: array
type: object
podOverrides:
default: {}
description: In the `podOverrides` property you can define a [PodTemplateSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#podtemplatespec-v1-core) to override any property that can be set on a Kubernetes Pod. Read the [Pod overrides documentation](https://docs.stackable.tech/home/nightly/concepts/overrides#pod-overrides) for more information.
Expand Down Expand Up @@ -1116,6 +1142,32 @@ spec:
default: {}
description: '`envOverrides` configure environment variables to be set in the Pods. It is a map from strings to strings - environment variables and the value to set. Read the [environment variable overrides documentation](https://docs.stackable.tech/home/nightly/concepts/overrides#env-overrides) for more information and consult the operator specific usage guide to find out about the product specific environment variables that are available.'
type: object
jvmArgumentOverrides:
default:
add: []
remove: []
removeRegex: []
description: Allows overriding JVM arguments. Please read on the [JVM argument overrides documentation](https://docs.stackable.tech/home/nightly/concepts/overrides#jvm-argument-overrides) for details on the usage.
properties:
add:
default: []
description: JVM arguments to be added
items:
type: string
type: array
remove:
default: []
description: JVM arguments to be removed by exact match
items:
type: string
type: array
removeRegex:
default: []
description: JVM arguments matching any of this regexes will be removed
items:
type: string
type: array
type: object
podOverrides:
default: {}
description: In the `podOverrides` property you can define a [PodTemplateSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#podtemplatespec-v1-core) to override any property that can be set on a Kubernetes Pod. Read the [Pod overrides documentation](https://docs.stackable.tech/home/nightly/concepts/overrides#pod-overrides) for more information.
Expand Down
2 changes: 1 addition & 1 deletion docs/modules/nifi/pages/usage_guide/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,4 @@ spec:
<3> xref:usage_guide/extra-volumes.adoc[Extra volumes] with files that can be referenced in custom workflows.
<4> xref:usage_guide/resource-configuration.adoc[CPU and memory configuration] can be set per role group.

Not shown are the common settings for xref:usage_guide/operations/cluster-operations.adoc[starting and stopping the cluster] and xref:usage_guide/operations/pod-placement.adoc[distributing Pods]. Additionally, you can set any NiFi setting using xref:usage_guide/configuration-environment-overrides.adoc[overrides]. You can also configure xref:usage_guide/log-aggregation.adoc[log aggregation].
Not shown are the common settings for xref:usage_guide/operations/cluster-operations.adoc[starting and stopping the cluster] and xref:usage_guide/operations/pod-placement.adoc[distributing Pods]. Additionally, you can set any NiFi setting using xref:usage_guide/overrides.adoc[overrides]. You can also configure xref:usage_guide/log-aggregation.adoc[log aggregation].
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,8 @@ spec:
value: "value1"
effect: "NoSchedule"
----

== JVM argument overrides

Stackable operators automatically determine the set of needed JVM arguments, such as memory settings or trust- and keystores.
Using JVM argument overrides you can configure the JVM arguments xref:concepts:overrides.adoc#jvm-argument-overrides[according to the concepts page].
2 changes: 1 addition & 1 deletion docs/modules/nifi/partials/nav.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
** xref:nifi:usage_guide/log-aggregation.adoc[]
** xref:nifi:usage_guide/monitoring.adoc[]
** xref:nifi:usage_guide/updating.adoc[]
** xref:nifi:usage_guide/configuration-environment-overrides.adoc[]
** xref:nifi:usage_guide/overrides.adoc[]
** xref:nifi:usage_guide/writing-to-iceberg-tables.adoc[]
** xref:nifi:usage_guide/operations/index.adoc[]
*** xref:nifi:usage_guide/operations/cluster-operations.adoc[]
Expand Down
4 changes: 2 additions & 2 deletions rust/crd/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use stackable_operator::{
memory::{BinaryMultiple, MemoryQuantity},
product_config_utils::{self, Configuration},
product_logging::{self, spec::Logging},
role_utils::{GenericRoleConfig, Role, RoleGroupRef},
role_utils::{GenericRoleConfig, JavaCommonConfig, Role, RoleGroupRef},
schemars::{self, JsonSchema},
status::condition::{ClusterCondition, HasStatusCondition},
time::Duration,
Expand Down Expand Up @@ -107,7 +107,7 @@ pub struct NifiSpec {

// no doc - docs in Role struct.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub nodes: Option<Role<NifiConfigFragment>>,
pub nodes: Option<Role<NifiConfigFragment, GenericRoleConfig, JavaCommonConfig>>,

// no doc - docs in ProductImage struct.
pub image: ProductImage,
Expand Down
1 change: 1 addition & 0 deletions rust/operator-binary/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ url.workspace = true

[dev-dependencies]
rstest.workspace = true
serde_yaml.workspace = true

[build-dependencies]
built.workspace = true
83 changes: 83 additions & 0 deletions rust/operator-binary/src/config/jvm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
use snafu::{OptionExt, ResultExt, Snafu};
use stackable_nifi_crd::{NifiConfig, NifiConfigFragment};
use stackable_operator::{
memory::{BinaryMultiple, MemoryQuantity},
role_utils::{self, GenericRoleConfig, JavaCommonConfig, JvmArgumentOverrides, Role},
};

use super::{JVM_SECURITY_PROPERTIES_FILE, NIFI_CONFIG_DIRECTORY};

// Part of memory resources allocated for Java heap
const JAVA_HEAP_FACTOR: f32 = 0.8;

#[derive(Snafu, Debug)]
pub enum Error {
#[snafu(display("invalid memory resource configuration - missing default or value in crd?"))]
MissingMemoryResourceConfig,

#[snafu(display("invalid memory config"))]
InvalidMemoryConfig {
source: stackable_operator::memory::Error,
},

#[snafu(display("failed to merge jvm argument overrides"))]
MergeJvmArgumentOverrides { source: role_utils::Error },
}

/// Create the NiFi bootstrap.conf
pub fn build_merged_jvm_config(
merged_config: &NifiConfig,
role: &Role<NifiConfigFragment, GenericRoleConfig, JavaCommonConfig>,
role_group: &str,
) -> Result<JvmArgumentOverrides, Error> {
let heap_size = MemoryQuantity::try_from(
merged_config
.resources
.memory
.limit
.as_ref()
.context(MissingMemoryResourceConfigSnafu)?,
)
.context(InvalidMemoryConfigSnafu)?
.scale_to(BinaryMultiple::Mebi)
* JAVA_HEAP_FACTOR;
let java_heap = heap_size
.format_for_java()
.context(InvalidMemoryConfigSnafu)?;

let jvm_args = vec![
// Heap settings
format!("-Xmx{java_heap}"),
format!("-Xms{java_heap}"),
// The G1GC is known to cause some problems in Java 8 and earlier, but the issues were addressed in Java 9. If using Java 8 or earlier,
// it is recommended that G1GC not be used, especially in conjunction with the Write Ahead Provenance Repository. However, if using a newer
// version of Java, it can result in better performance without significant \"stop-the-world\" delays.
"-XX:+UseG1GC".to_owned(),
// Set headless mode by default
"-Djava.awt.headless=true".to_owned(),
// Disable JSR 199 so that we can use JSP's without running a JDK
"-Dorg.apache.jasper.compiler.disablejsr199=true".to_owned(),
// Note(sbernauer): This has been here since ages, leaving it here for compatibility reasons.
// That being said: IPV6 rocks :rocket:!
"-Djava.net.preferIPv4Stack=true".to_owned(),
// allowRestrictedHeaders is required for Cluster/Node communications to work properly
"-Dsun.net.http.allowRestrictedHeaders=true".to_owned(),
"-Djava.protocol.handler.pkgs=sun.net.www.protocol".to_owned(),
// Sets the provider of SecureRandom to /dev/urandom to prevent blocking on VMs
"-Djava.security.egd=file:/dev/urandom".to_owned(),
// Requires JAAS to use only the provided JAAS configuration to authenticate a Subject, without using any "fallback" methods (such as prompting for username/password)
// Please see https://docs.oracle.com/javase/8/docs/technotes/guides/security/jgss/single-signon.html, section "EXCEPTIONS TO THE MODEL"
"-Djavax.security.auth.useSubjectCredsOnly=true".to_owned(),
// Zookeeper 3.5 now includes an Admin Server that starts on port 8080, since NiFi is already using that port disable by default.
// Please see https://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_adminserver_config for configuration options.
"-Dzookeeper.admin.enableServer=false".to_owned(),
// JVM security properties include especially TTL values for the positive and negative DNS caches.
format!(
"-Djava.security.properties={NIFI_CONFIG_DIRECTORY}/{JVM_SECURITY_PROPERTIES_FILE}"
),
];

let operator_generated = JvmArgumentOverrides::new_with_only_additions(jvm_args);
role.get_merged_jvm_argument_overrides(role_group, &operator_generated)
.context(MergeJvmArgumentOverridesSnafu)
}
Loading

0 comments on commit caf4ce4

Please sign in to comment.