NACK (NATS Controllers for Kubernetes)

repository·main·Indexed 42 days ago

https://github.com/nats-io/nack

Kubernetes controllers for managing NATS JetStream resources—including Streams, Consumers, Key/Value stores, and Object Stores—and NATS Server configurations using Custom Resource Definitions (CRDs). Features a JetStream Controller with Legacy and Control-loop modes, a NATS Server Config Reloader sidecar, and NATS Boot Config utility.

Tokens
13.4K
Snippets
32
Records
57
Agent score
54%

What's inside NACK

  1. What is NACK (NATS Controllers for Kubernetes)

    main
    NACK (NATS Controllers for Kubernetes) provides controllers to manage NATS resources directly via Kubernetes Custom Resource Definitions (CRDs). It is primarily used to manage NATS JetStream resources and NATS Server configurations within a Kubernetes environment.
  2. Use the Account Resource for Connection and TLS

    main

    The Account resource functions as a connection and authentication configuration for managed resources. It does not create or manage NATS accounts on the server side; instead, it provides the credentials and server information that NACK uses to connect to NATS.

    You can define servers, creds (via Kubernetes secrets), and tls settings (via Kubernetes secrets) within an Account resource. Once defined, you can link a Stream to it using the spec.account field.

    apiVersion: jetstream.nats.io/v1beta2
    kind: Account
    metadata:
      name: a
    spec:
      name: a
      servers:
        - nats://nats:4222
      tls:
        secret:
          name: nack-a-tls
        ca: "ca.crt"
        cert: "tls.crt"
        key: "tls.key"
    ---
    apiVersion: jetstream.nats.io/v1beta2
    kind: Stream
    metadata:
      name: foo
    spec:
      name: foo
      subjects: ["foo", "foo.">"]
      storage: file
      replicas: 1
      account: a # Links this stream to Account 'a'
  3. Configure KeyValue mirroring

    main

    You can create a mirror of a KV Store using the mirror field in KeyValue.spec. This allows you to replicate a KV Store to another location.

    Mirror Configuration (KeyValue.spec.mirror):

    • name: Name of the mirror.
    • externalApiPrefix: Prefix for external API.
    • externalDeliverPrefix: Prefix for external delivery.
    • filterSubject: Subject to filter.
    • optStartSeq: Optional starting sequence.
    • optStartTime: Optional start time (must be RFC3339 format).
    • subjectTransforms: A list of source/dest pairs to transform subjects during mirroring.
    # Example mirror configuration snippet
    spec:
      mirror:
        name: "my-mirror"
        optStartTime: "2023-01-01T00:00:00Z"
        subjectTransforms:
          - source: "old.subject"
            dest: "new.subject"
  4. Understand Account.status

    main

    The Account.status field provides information about the current state of the Account resource.

    • observedGeneration: The last generation of the spec that the controller observed.
    • conditions: An array of status conditions. Each condition includes:
      • type: The type of condition.
      • status: The status of the condition.
      • reason: A machine-readable reason for the condition.
      • message: A human-readable message describing the condition.
      • lastTransitionTime: When the condition last changed.
  5. JetStream Controller and its modes

    main

    The JetStream Controller manages NATS JetStream resources via Kubernetes CRDs. It operates in two distinct modes, which determine the level of resource support available:

    1. Legacy (default): Supports Streams and Consumers.
    2. Control-loop (enabled via --control-loop flag): Provides full support for Streams, Consumers, Key/Value stores, Object Stores, and Accounts.

    Critical Requirement: Key/Value stores and Object stores require the controller to be running in control-loop mode. If you attempt to create KeyValue or ObjectStore resources while the controller is in Legacy mode, they will not be reconciled.

  6. Manage Multiple NATS Systems and Accounts

    main

    NACK provides three primary ways to manage multiple NATS systems or accounts within a single Kubernetes cluster:

    1. Run Multiple Namespaced Controllers: By setting namespaced: true (or --set config.namespaced=true), the controller will only reconcile resources within its own namespace. This is useful for isolation.
    2. Use the Accounts Resource: Define Account resources that act as connection configurations. Each Account can point to different NATS servers and use different credentials. You can then link a Stream or other resource to a specific Account using the account field.
    3. Define Connection Config in the CRD Manifest: You can specify connection details (like servers) directly within the resource manifest (e.g., a Stream).
      • If using the --control-loop mode, resource-level config always overrides global config.
      • If NOT using --control-loop, you must set the --crd-connect flag in the controller configuration.
  7. Develop or Build NATS Boot Config locally

    main

    You can build the NATS Boot Config project and run it locally, or build a Docker image using the Makefile.

    # Build the project
    make nats-boot-config
    
    # Run the project
    ./nats-boot-config
    
    # Build Docker image
    make nats-boot-config-docker ver=1.2.3
  8. Use Kubernetes Secrets for Account credentials

    main

    Instead of providing raw strings or file paths, you can reference Kubernetes Secrets for sensitive information in an Account resource.

    Credential Secrets (spec.creds.secret)

    Use the name field to specify the name of the Secret containing the NATS credentials file.

    TLS Secrets (spec.tls.secret)

    Use the name field to specify the name of the Secret containing the TLS certificates.

    Token Secrets (spec.token.secret)

    Use the name field to specify the Secret, and the token field to specify the specific key within that Secret that holds the token.

    User/Password Secrets (spec.user.secret)

    Use the name field to specify the Secret. Use the user field to specify the key for the username and the password field to specify the key for the password.

    spec:
      creds:
        secret:
          name: nats-creds-secret
      token:
        secret:
          name: nats-token-secret
        token: "AUTH_TOKEN_KEY"
      user:
        secret:
          name: nats-user-secret
        user: "USERNAME_KEY"
        password: "PASSWORD_KEY"
  9. Set up NACK for Local Development

    main

    To develop locally, you can build the jetstream-controller and run it against a local NATS server with JetStream enabled.

    1. Build the controller using make.
    2. Start a local NATS server with JetStream (-js).
    3. Run the controller pointing to your local NATS server.

    Tip: Use the -v flag to adjust log verbosity. -v=10 will print raw HTTP requests and responses.

    # Build the controller
    make jetstream-controller
    
    # Start a local JetStream-enabled NATS server
    nats-server -DV -js
    
    # Run the controller
    ./jetstream-controller -kubeconfig ~/.kube/config -s nats://localhost:4222
    
    # For high verbosity debugging
    ./jetstream-controller -v=10
  10. Enable ObjectStore support in the JetStream controller

    main

    To use ObjectStore resources, you must run the JetStream controller in control-loop mode by using the --control-loop flag. ObjectStore resources are not supported in the default legacy mode.

    # Example command to enable control-loop mode
    # (Actual command depends on your deployment method, e.g., kubectl or a binary execution)
    jetstream-controller --control-loop
  11. Enable Experimental `controller-runtime` Controllers

    main

    You can enable the updated controller-runtime controllers by passing the --control-loop argument. These controllers more reliably enforce resource state. When enabled, the jetstream-controller logs will contain a diff of any changes the controller has made.

    Note: If you are migrating from an older version of NACK, no modifications are expected as long as all NATS resources are in-sync with NACK resources.

    helm upgrade nack nats/nack \
      --set jetstream.nats.url=nats://nats.default.svc.cluster.local:4222 \
      --set jetstream.additionalArgs={--control-loop} --wait
  12. Install the NATS Server Config Reloader with Helm

    main

    The NATS Server Config Reloader is a sidecar used to automatically reload your NATS Server configuration file. You can install it using the official NATS Helm chart.

    helm repo add nats https://nats-io.github.io/k8s/helm/charts/
    helm upgrade --install nats nats/nats