Skip to content

ablmnzde/ionoscloud-endpointslice-controller

Repository files navigation

ionos-endpointslice-controller

Minimal controller that keeps a managed EndpointSlice in sync with the current private worker IPs of a remote Kubernetes cluster.

Goal

The project exists to keep a selector-less Service stable even when the upstream cluster rotates or replaces nodes.

It periodically:

  • discovers eligible worker nodes in a remote cluster
  • resolves their private IPs via IONOS NIC data
  • health-checks candidate backends
  • updates a managed EndpointSlice in the local cluster with minimal churn

Current scope

  • core reconciliation logic
  • source abstraction for secured node IP discovery
  • store abstraction for EndpointSlice reads and writes
  • fail-open protection for empty source results
  • kubectl-backed EndpointSlice persistence
  • JSON inventory file source
  • command-backed inventory source
  • unit tests for update semantics

Not implemented yet

  • direct Kubernetes client integration
  • direct IONOS API integration
  • metrics and Kubernetes Events
  • leader election

Run tests

go test ./...

Main configuration

The binary reads configuration from environment variables:

  • SOURCE_POLL_INTERVAL
  • TARGET_NAMESPACE
  • TARGET_SERVICE_NAME
  • TARGET_ENDPOINTSLICE_NAME
  • TARGET_MANAGED_BY
  • TARGET_PORT
  • SECURED_SUBNET_CIDR
  • EMPTY_RESULT_THRESHOLD
  • SOURCE_KIND (static, file, or command)
  • STORE_KIND (memory or kubectl)
  • INVENTORY_FILE_PATH
  • INVENTORY_COMMAND
  • INVENTORY_COMMAND_ARGS
  • HEALTH_CHECK_MODE (off, tcp, or http)
  • HEALTH_CHECK_PATH
  • HEALTH_CHECK_TIMEOUT

Pragmatic runtime modes

SOURCE_KIND=file reads a JSON inventory with records like:

[
  {
    "name": "target-worker-1",
    "private_ip": "10.0.0.12",
    "ready": true,
    "worker": true
  }
]

STORE_KIND=kubectl persists the managed EndpointSlice by shelling out to kubectl get and kubectl apply. This is a practical integration path for early rollout without pulling in client-go.

SOURCE_KIND=command runs an external command and expects the same JSON array on stdout. This is the cleanest current bridge to an IONOS inventory script.

Backend Health Checks

The controller can probe candidate backend IPs before writing them into the managed EndpointSlice.

  • HEALTH_CHECK_MODE=off disables probing
  • HEALTH_CHECK_MODE=tcp requires a successful TCP connect to TARGET_PORT
  • HEALTH_CHECK_MODE=http requires an HTTP success response on TARGET_PORT

For the current http-echo backend, the recommended setting is:

SOURCE_POLL_INTERVAL=5s
HEALTH_CHECK_MODE=http
HEALTH_CHECK_PATH=/
HEALTH_CHECK_TIMEOUT=3s

Repository Layout

deploy/ contains cluster manifests only:

  • service.example.yaml
  • rbac.example.yaml
  • controller-config.example.yaml
  • controller-deployment.example.yaml
  • scripts-configmap.ionos.example.yaml
  • inventory.example.json
  • ionos-token-secret.example.yaml
  • kubeconfigs-secret.example.yaml

helm/ contains a Helm chart for production-style installation:

  • helm/ionos-endpointslice-controller

hack/ contains local and operational helper scripts:

  • build-and-push.sh
  • set-image.sh
  • apply-order.sh
  • restart-controller.sh
  • logs-controller.sh
  • run-maintenance-curl.sh
  • recreate-ionos-node.sh
  • verify-endpointslice.sh
  • run-local-inventory.sh
  • check-secured-nodes.sh

docs/ contains runbooks and checklists:

  • first-run-checklist.md

Local Dry Run With direnv

Copy the example and load it with direnv:

cp .envrc.example .envrc
direnv allow

Then validate the secured cluster view first:

./hack/check-secured-nodes.sh

Then run the inventory helper locally:

./hack/run-local-inventory.sh

The expected result is a JSON array with only Ready worker nodes and private IPs in the configured private subnet.

IONOS Inventory Helper

The repository now includes scripts/render_inventory.py. It is intended to run behind SOURCE_KIND=command and emits the JSON inventory format expected by the controller.

Current behavior:

  • reads Ready worker nodes from target-k8s using kubectl
  • maps each node to an IONOS server using node name, providerID, or systemUUID
  • resolves the private NIC IP from the configured IONOS LAN
  • emits only IPs matching the configured subnet prefix
  • writes EndpointSlices in the target cluster using in-cluster service account access

Required environment:

  • IONOS_TOKEN
  • IONOS_DATACENTER_ID
  • IONOS_PRIVATE_LAN_ID
  • SECURED_KUBECONFIG

Optional environment:

  • SECURED_KUBECTL_CONTEXT
  • SECURED_SUBNET_PREFIX default: 10.0.0.

Cluster Access Model

The intended runtime model is:

  • target-k8s read access via mounted kubeconfig and optional SECURED_KUBECTL_CONTEXT
  • source-k8s write access via in-cluster service account and RBAC

The controller does not require a separate target-cluster kubeconfig in the recommended deployment shape.

Container Build

The repository includes Dockerfile. The runtime image contains:

  • the controller binary
  • kubectl
  • python3

This matches the current pragmatic architecture where:

  • inventory generation uses Python
  • cluster read/write integration uses kubectl

Suggested First Deploy Commands

Build the image:

./hack/build-and-push.sh 0.0.1

This helper uses:

  • docker buildx build
  • --platform linux/amd64
  • explicit tags such as 0.0.1, 0.0.2

Apply the baseline manifests:

./hack/set-image.sh 0.0.1
vim deploy/controller-config.example.yaml
./hack/apply-order.sh

Install via Helm instead:

helm upgrade --install ionos-endpointslice-controller ./helm/ionos-endpointslice-controller \
  --namespace upstream-system \
  --create-namespace \
  --set image.tag=0.0.1 \
  --set controller.ionosDatacenterId=REPLACE_ME \
  --set controller.ionosPrivateLanId=REPLACE_ME

Restart the controller after config or image changes:

./hack/restart-controller.sh

Follow controller logs:

./hack/logs-controller.sh

Inspect the resulting managed EndpointSlice:

./hack/verify-endpointslice.sh

About

Minimal controller that keeps a managed EndpointSlice in sync with the current private worker IPs of a remote Kubernetes cluster.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors