Skip to content

Conversation

bobbyiliev
Copy link
Contributor

@bobbyiliev bobbyiliev commented Mar 7, 2025

Motivation

As per: https://github.com/MaterializeInc/cloud/issues/10880

Things that still need to be handled here:

@bobbyiliev bobbyiliev force-pushed the self-hosted-lgalloc-setup branch from df2f61e to 1aafe74 Compare March 7, 2025 18:49

1. Automatically detects NVMe instance store devices on your nodes
2. Creates an LVM volume group from these devices
3. Configures OpenEBS to provision persistent volumes from this storage
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
3. Configures OpenEBS to provision persistent volumes from this storage
3. Configures OpenEBS LVM Local-PV to provision persistent volumes from this storage

OpenEBS is a whole family of providers, we should be specific about which we're using.


# Disable Materialize Operator installation as it will require the storage class
# TODO: The module will support this configuration in the future
install_materialize_operator = false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably want to support this before releasing lgalloc support.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Started working on that already here: MaterializeInc/terraform-aws-materialize#41

docker build -t your-registry/nvme-bootstrap:latest .

# Push to your registry
docker push your-registry/nvme-bootstrap:latest
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If they are pushing it themselves, where do we configure which bootstrap image to use in the terraform?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes this is more of a note for myself while testing, next on my list is to add this to CI so we push the image to Docker hub. Open to suggestions on the Docker image name though!


# Delete OpenEBS if no longer needed
helm uninstall openebs -n openebs
kubectl delete namespace openebs
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this cleanup section cleaning up? If they ran the terraform, this would likely break their stack.

# Function to detect cloud provider
detect_cloud_provider() {
# Check for AWS
if curl -s -m 5 http://169.254.169.254/latest/meta-data/ >/dev/null; then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The metadata service may not be available in all clusters. It is generally good security practice to disallow this.

Can we just pass in the cloud provider as an arg instead?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, lets just pass this in, if some doesn't know what what cloud they're deploying into then that's on them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've changed this so now users can pass --cloud-provider same as we have it in orchestratord

# the Business Source License, use of this software will be governed
# by the Apache License, Version 2.0.

set -xeo pipefail
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
set -xeo pipefail
set -xeuo pipefail

;;
*)
echo "Usage: $0 [add|remove]"
exit 0 # Exit with success to avoid crash loop
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above, we probably want it to crash.

serviceAccountName: nvme-setup-sa
initContainers:
- name: apply-taint
image: bobbyiliev/nvme-bootstrap:latest
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This image is fine for testing, but probably should be moved to the materialize org with some automation for building/pushing it.

initContainers:
- name: apply-taint
image: bobbyiliev/nvme-bootstrap:latest
command: ["/usr/local/bin/manage-taints.sh", "add"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be set using a startup taint, not by the daemonset.

effect: NoSchedule
- key: node-role.kubernetes.io/control-plane
operator: Exists
effect: NoSchedule
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why these other two tolerations?

Copy link
Contributor

@jubrad jubrad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if this is the norm, but we could potentially make the nvme setup container an init container on the daemonset and have the main container be a pause image.

Comment on lines 36 to 49
# Handle both standard Linux and Bottlerocket paths
if [ -d "/.bottlerocket" ]; then
# Bottlerocket specific path
BOTTLEROCKET_ROOT="/.bottlerocket/rootfs"
mapfile -t SSD_NVME_DEVICE_LIST < <(lsblk --json --output-all | jq -r '.blockdevices[] | select(.model // empty | contains("Amazon EC2 NVMe Instance Storage")) | .path')
for device in "${SSD_NVME_DEVICE_LIST[@]}"; do
nvme_devices+=("$BOTTLEROCKET_ROOT$device")
done
else
# Standard EC2 instances
mapfile -t nvme_devices < <(lsblk --json --output-all | jq -r '.blockdevices[] | select(.model // empty | contains("Amazon EC2 NVMe Instance Storage")) | .path')
fi
;;
# Add more cloud providers here
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you're doing a case on cloud, I would turn this into a handle_aws function for readability... or an internal case/if for check_bottlerocket, check_linux.

# the Business Source License, use of this software will be governed
# by the Apache License, Version 2.0.

set -xeo pipefail
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you may want to include u in this -u as well

  -u    When the shell tries to expand an unset parameter other than
             the '@' and '*' special parameters, it shall write a message
             to standard error and the expansion shall fail with the
             consequences specified in Section 2.8.1, Consequences of
             Shell Errors.

return 0
}

# Main execution
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I think I prefer a main function function main() {...} to scope this logic.. it makes the script sourceable.

if [ "$0" == "${BASH_SOURCE[0]}" ]; then
    # shellcheck disable=SC2068
    main $@
fi

Comment on lines 38 to 44
kubectl --server="https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}" \
--token="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
--certificate-authority="/var/run/secrets/kubernetes.io/serviceaccount/ca.crt" \
taint nodes "$NODE_NAME" "$TAINT_KEY=$TAINT_VALUE:$TAINT_EFFECT" --overwrite || {
echo "Warning: Failed to add taint, but continuing anyway"
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already discussed, but we shouldn't add the taint here, that should be part of the node_group, or whatever defines nodes in the particular k8s cluster.

@@ -0,0 +1,249 @@
# OpenEBS NVMe Bootstrap for Materialize
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might delete this readme file all together, most of this is already available in the helm chart readme anyway, and the AWS specific implementation will be done via Terraform.

@@ -0,0 +1,72 @@
# Copyright Materialize, Inc. and contributors. All rights reserved.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bobbyiliev bobbyiliev marked this pull request as draft March 19, 2025 13:23
@bobbyiliev bobbyiliev closed this Mar 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants