From dceee19b3a4103e5223e860bb379d91dbd105872 Mon Sep 17 00:00:00 2001 From: Waldemar Quevedo Date: Mon, 20 Jan 2020 16:51:06 -0800 Subject: [PATCH] Add single node examples Signed-off-by: Waldemar Quevedo --- docs/simple-setup.md | 69 ++++++++++ nats-server/single-server-nats.yml | 135 +++++++++++++++++++ nats-streaming-server/single-server-stan.yml | 115 ++++++++++++++++ 3 files changed, 319 insertions(+) create mode 100644 docs/simple-setup.md create mode 100644 nats-server/single-server-nats.yml create mode 100644 nats-streaming-server/single-server-stan.yml diff --git a/docs/simple-setup.md b/docs/simple-setup.md new file mode 100644 index 00000000..6b0ffd84 --- /dev/null +++ b/docs/simple-setup.md @@ -0,0 +1,69 @@ +# Basic NATS and NATS Streaming setup in K8S + +## Minimal NATS and NATS Streaming setup + +To try NATS with the minimal components, you can start with the following: + +```sh +# Single server NATS +kubectl apply -f https://raw.githubusercontent.com/nats-io/k8s/master/nats-server/single-server-nats.yml + +kubectl apply -f https://raw.githubusercontent.com/nats-io/k8s/master/nats-streaming-server/single-server-stan.yml +``` + +This will setup for you: + +- A statefulset with a single NATS server (no auth nor TLS) + +- A single NATS Streaming node using file store with persistence + +- A `nats` headless service to which you can connect. + +- A NATS Streaming Server that uses the cluster name `stan`. + +Note that the only service that your applications have to connect is +the `nats` service, the NATS Streaming server will be available by +using NATS as a transport. + +Next, try using `nats-box` to connect to the `nats` service to confirm +that you have set both NATS and NATS Streaming correctly. + +```sh +kubectl run -i --rm --tty nats-box --image=synadia/nats-box --restart=Never + +# Send message to NATS +nats-box:~# nats-sub -s nats hello & +Listening on [hello] + +nats-box:~# nats-pub -s nats hello world +[#1] Received on [hello]: 'world' + +# Send/Receive message to STAN +nats-box:~# stan-pub -s nats -c stan hello world +Published [hello] : 'world' + +nats-box:~# stan-sub -s nats -c stan hello +Connected to nats clusterID: [stan] clientID: [stan-sub] +Listening on [hello], clientID=[stan-sub], qgroup=[] durable=[] +[#1] Received: sequence:1 subject:"hello" data:"world" timestamp:1579544643374163630 +``` + +## HA setup using StatefulSets + +In order to have higher availability you can setup NATS and NATS +Streaming (STAN) to run in clustering mode. The following commands +will setup a 3-node NATS cluster as well as a 3-node NATS Streaming +cluster that has an attached volume for persistence. + +```sh +# Create NATS cluster +kubectl apply -f https://raw.githubusercontent.com/nats-io/k8s/master/nats-server/simple-nats.yml + +# Create STAN cluster +kubectl apply -f https://raw.githubusercontent.com/nats-io/k8s/master/nats-streaming-server/simple-stan.yml +``` + +For NATS Streaming, it is actually recommended to use the Fault +Tolerance mode as that would show better performance than clustering +mode and better failover. You can follow this guide to setup +[NATS Streaming with Fault Tolerance](https://docs.nats.io/nats-on-kubernetes/stan-ft-k8s-aws). diff --git a/nats-server/single-server-nats.yml b/nats-server/single-server-nats.yml new file mode 100644 index 00000000..f4631d5f --- /dev/null +++ b/nats-server/single-server-nats.yml @@ -0,0 +1,135 @@ +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: nats-config +data: + nats.conf: | + pid_file: "/var/run/nats/nats.pid" + http: 8222 +--- +apiVersion: v1 +kind: Service +metadata: + name: nats + labels: + app: nats +spec: + selector: + app: nats + clusterIP: None + ports: + - name: client + port: 4222 + - name: cluster + port: 6222 + - name: monitor + port: 8222 + - name: metrics + port: 7777 + - name: leafnodes + port: 7422 + - name: gateways + port: 7522 +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: nats + labels: + app: nats +spec: + selector: + matchLabels: + app: nats + replicas: 1 + serviceName: "nats" + template: + metadata: + labels: + app: nats + spec: + # Common volumes for the containers + volumes: + - name: config-volume + configMap: + name: nats-config + - name: pid + emptyDir: {} + + # Required to be able to HUP signal and apply config reload + # to the server without restarting the pod. + shareProcessNamespace: true + + ################# + # # + # NATS Server # + # # + ################# + terminationGracePeriodSeconds: 60 + containers: + - name: nats + image: nats:2.1.0-alpine3.10 + ports: + - containerPort: 4222 + name: client + hostPort: 4222 + - containerPort: 7422 + name: leafnodes + hostPort: 7422 + - containerPort: 6222 + name: cluster + - containerPort: 8222 + name: monitor + - containerPort: 7777 + name: metrics + command: + - "nats-server" + - "--config" + - "/etc/nats-config/nats.conf" + + # Required to be able to define an environment variable + # that refers to other environment variables. This env var + # is later used as part of the configuration file. + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: CLUSTER_ADVERTISE + value: $(POD_NAME).nats.$(POD_NAMESPACE).svc + volumeMounts: + - name: config-volume + mountPath: /etc/nats-config + - name: pid + mountPath: /var/run/nats + + # Liveness/Readiness probes against the monitoring + # + livenessProbe: + httpGet: + path: / + port: 8222 + initialDelaySeconds: 10 + timeoutSeconds: 5 + readinessProbe: + httpGet: + path: / + port: 8222 + initialDelaySeconds: 10 + timeoutSeconds: 5 + + # Gracefully stop NATS Server on pod deletion or image upgrade. + # + lifecycle: + preStop: + exec: + # Using the alpine based NATS image, we add an extra sleep that is + # the same amount as the terminationGracePeriodSeconds to allow + # the NATS Server to gracefully terminate the client connections. + # + command: ["/bin/sh", "-c", "/nats-server -sl=ldm=/var/run/nats/nats.pid && /bin/sleep 60"] diff --git a/nats-streaming-server/single-server-stan.yml b/nats-streaming-server/single-server-stan.yml new file mode 100644 index 00000000..4f2870a9 --- /dev/null +++ b/nats-streaming-server/single-server-stan.yml @@ -0,0 +1,115 @@ +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: stan-config +data: + stan.conf: | + port: 4222 + http: 8222 + + streaming { + ns: "nats://nats:4222" + id: stan + store: file + dir: /data/stan/store + } +--- +apiVersion: v1 +kind: Service +metadata: + name: stan + labels: + app: stan +spec: + selector: + app: stan + clusterIP: None + ports: + - name: metrics + port: 7777 +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: stan + labels: + app: stan +spec: + selector: + matchLabels: + app: stan + serviceName: stan + replicas: 1 + volumeClaimTemplates: + - metadata: + name: stan-sts-vol + spec: + accessModes: + - ReadWriteOnce + volumeMode: "Filesystem" + resources: + requests: + storage: 1Gi + template: + metadata: + labels: + app: stan + spec: + # Prevent NATS Streaming pods running in same host. + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - topologyKey: "kubernetes.io/hostname" + labelSelector: + matchExpressions: + - key: app + operator: In + values: + - stan + # STAN Server + containers: + - name: stan + image: nats-streaming:0.16.2 + ports: + - containerPort: 8222 + name: monitor + - containerPort: 7777 + name: metrics + args: + - "-sc" + - "/etc/stan-config/stan.conf" + + # Required to be able to define an environment variable + # that refers to other environment variables. This env var + # is later used as part of the configuration file. + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + volumeMounts: + - name: config-volume + mountPath: /etc/stan-config + - name: stan-sts-vol + mountPath: /data/stan + + # Disable CPU limits. + resources: + requests: + cpu: 0 + + livenessProbe: + httpGet: + path: / + port: 8222 + initialDelaySeconds: 10 + timeoutSeconds: 5 + volumes: + - name: config-volume + configMap: + name: stan-config