NATS messaging
The GitLab chart can configure GitLab Rails to connect to an external NATS JetStream server. NATS is used for audit event streaming.
NATS support is experimental and intended for testing purposes only at the moment.
The chart does not deploy NATS. You must provide an external NATS server.
Configuration
NATS is configured under global.appConfig.nats. The chart renders the nats block
into gitlab.yml for the Webservice, Sidekiq, and Toolbox components.
| Parameter | Description |
|---|---|
global.appConfig.nats.servers | List of NATS server URLs. For example, tls://nats.example.com:4222. |
global.appConfig.nats.connectTimeout | Connection timeout in seconds. |
global.appConfig.nats.streamReplicas | JetStream stream replication factor. Use 1 for single-node and 3 for clustered deployments. |
global.appConfig.nats.tls.enabled | Whether to connect over mutual TLS. |
global.appConfig.nats.tls.secret | Name of the secret that holds the client certificate. |
An empty or absent servers list means NATS is not configured. In that case, the
nats block is omitted from gitlab.yml and Rails falls back to the Sidekiq delivery
path for audit event streaming.
Mutual TLS
The GitLab NATS clusters use verify_and_map. Each client must present a client
certificate whose common name (CN) maps to a NATS user. When tls.enabled is true,
the referenced secret must contain these keys:
ca.crttls.crttls.key
The chart mounts these files into each component and points gitlab.yml at the mounted
paths under /srv/gitlab/config/nats/.
Per-component client certificates
Because verify_and_map maps each certificate CN to a distinct NATS user, each Rails
component can use its own client certificate. Set global.appConfig.nats.tls.secret as
a shared default, then override it per component:
gitlab.webservice.nats.tls.secretgitlab.sidekiq.nats.tls.secretgitlab.toolbox.nats.tls.secret
A component that does not set its own secret uses the shared
global.appConfig.nats.tls.secret.
Enabling audit event streaming through NATS
Configuring the connection does not route audit events through NATS on its own. After
NATS is configured, an administrator must enable the use_nats_for_audit_streaming
application setting. Until then, Rails continues to use the Sidekiq delivery path.
Test plan and development setup
Use this procedure to check authentication and mutual TLS between GitLab Rails and NATS.
The commands use the gitlab namespace and the gl release name.
Issue the certificates
Prepare a development Kubernetes cluster.
Set up the common GitLab dependencies. Do not install GitLab yet.
Install cert-manager to issue the certificates for mutual TLS.
Create the certificate authority, the server certificate, and the client certificate:
kubectl apply -f examples/nats/mtls.certs.yaml
Install a NATS server
Add the NATS chart repository:
helm repo add nats https://nats-io.github.io/k8s/helm/charts/ helm repo updateCreate a
nats.values.yamlfile:config: jetstream: enabled: true nats: tls: enabled: true secretName: server-cert-secret merge: verify: true tlsCA: enabled: true secretName: my-ca-secretInstall the NATS chart:
helm upgrade --install nats nats/nats -n gitlab -f nats.values.yaml
Install GitLab with NATS configured
Create a
gitlab.nats.values.yamlfile:global: appConfig: nats: tls: enabled: true secret: client-cert-secret servers: - "tls://nats.gitlab.svc.cluster.local:4222" connectTimeout: 2 streamReplicas: 1Install the GitLab chart:
helm upgrade --install gl . -n gitlab \ -f .values/dev-external.values.yaml \ -f gitlab.nats.values.yaml \ --set global.hosts.domain=example.com \ --set certmanager-issuer.email=test@example.com \ --set installCertmanager=falseinstallCertmanager=falseskips the bundled cert-manager, because cert-manager is already installed in the cluster. The domain and the issuer email do not have to be valid, because this procedure needs no external connectivity.
Check the client connection
Wait for the rollout to complete.
Open a Rails console in the Toolbox pod:
kubectl exec -tin gitlab deployments/gl-toolbox -- gitlab-rails consolePublish a message to a test subject:
client = Gitlab::Nats.client client.publish('test.subject', '{"test": "data"}', message_id: 'test-123') # => NATS::JetStream::Error::NoStreamResponse: nats: no response from stream client.connected? # => true
The NoStreamResponse error is expected, because no stream serves the test subject.
A connected client confirms that Rails authenticated to NATS over mutual TLS.