A newer version of this documentation is available.

View Latest

Deploying Sync Gateway cluster

    +

    This guide demonstrates how to deploy a Sync Gateway cluster on Kubernetes.

    Prerequisites

    Before you begin, you must have the following:

    • A Couchbase Server cluster already running on Kubernetes. If you don’t already have one, you can refer to this guide for instructions.

    • A Couchbase Server RBAC user with application access privileges. Sync Gateway will connect to the Couchbase Server as this RBAC user. Refer to this section for instructions.

    • If you have configured your Couchbase Server cluster to use exposedFeatures then you must include "client" in the exposedFeatures list. This is required for Sync Gateway to be able to connect to the server. Alternatively, remove the exposedFeatures section altogether in the server configuration if you don’t need it.

    Deploying a Sync Gateway Cluster

    The Sync Gateway nodes in a cluster have a homogeneous configuration with the exception of import node.

    Import node

    Under convergence/shared bucket access, it is recommended that one Sync Gateway node in a cluster be configured for handling document import processing. For high availability, you can configure more than one Sync Gateway node in your cluster to be the import node, although it is strongly discouraged for multiple Sync Gateway nodes in the cluster to be configured for import processing. The configuration of the Sync Gateway import node is slightly different than the "regular" or "non-import" Sync Gateway nodes (see databases.$db.import_docs).

    The following sections cover the steps to deploy regular or import Sync Gateway nodes.

    You will have to repeat the steps in this section once for the "regular" or non-import nodes and once for the "import" node. The difference is the Sync Gateway configuration file and the Kubernetes Deployment Controller config file.

    Sync Gateway Configuration File

    In this section, you will create a Kubernetes secret from a new or existing Sync Gateway configuration.

    1. Open the Sync Gateway configuration file corresponding to your deployment. If you don’t have a configuration file you may also use our sample configuration shown below as a starting point.

      Regular Node Import Node

      sgw-config.json

      sgw-config-import.json

    2. Replace the server key with the addressable Couchbase Server hostname. The following example shows the configuration file for a regular node.

      {
        "logging": {
          "log_file_path": "/var/tmp/sglogs",
          "console": {
            "enabled": true,
            "log_level": "info",
            "log_keys": ["*"]
          }
        },
        "databases": {
          "db": {
            "server": "cb-example-0000.cb-example.default.svc:8091", (1)
            "bucket": "default",
            "username": "admin", (2)
            "password": "password",
            "users": { "GUEST": { "disabled": false, "admin_channels": ["*"] } },
            "allow_conflicts": false,
            "revs_limit": 20,
            "enable_shared_bucket_access": true
          }
        }
      }
      1 The server key should point to any pod in the Couchbase Server cluster. This would typically be of the form CB_SERVER_POD.CB_SERVER_SERVICE_NAME.NAMESPACE.svc:8091.
      2 The username/password keys should match what was setup in the pre-requisites section when you configured the Sync Gateway RBAC user.
    3. You will use a Kubernetes Secret to pass the configuration file to Sync Gateway on launch. Alternatively, you could use a Kubernetes configMap if you are not concerned about security. However, since the Sync Gateway contains sensitive information, it is recommended that you create a secret from the config file and pass that to the Sync Gateway. Run the following command to create a secret called "sgw-config" or "sgw-config-import" corresponding to regular and import versions of Sync Gateway configuration file respectively

      • Regular node

      • Import node

       kubectl create secret generic sgw-config --from-file sgw-config.json
      kubectl create secret generic sgw-config-import --from-file sgw-config-import.json

      If successful, you will see the following.

      • Regular node

      • Import node

      secret "sgw-config" created
      secret "sgw-config-import" created

    Deployment controller

    In this section you will deploy the Sync Gateway cluster with the configuration file that you created above.

    You will be using a Kubernetes deployment controller. A deployment controller allows you to define the number of Sync Gateway replicas and other parameters.

    1. Open the controller file corresponding to your deployment.

      Regular Node Import Node

      sgw-deployment.yaml

      sgw-deployment-import.yaml

      The following example shows the controller file for a regular node.

      apiVersion: extensions/v1beta1
      kind: Deployment
      metadata:
        name: sync-gateway (1)
      spec:
        replicas: 2 (2)
        template:
          metadata:
            labels:
              app: sync-gateway
          spec:
            affinity: (3)
              podAntiAffinity:
                requiredDuringSchedulingIgnoredDuringExecution:
                - labelSelector:
                    matchExpressions:
                    - key: app
                      operator: In
                      values:
                      - sync-gateway
                  topologyKey: "kubernetes.io/hostname"
            containers:
              - name: sync-gateway
                image: couchbase/sync-gateway:2.6.0-enterprise (4)
                args: ["/sync-gateway-config/sgw-config.json"] (5)
                volumeMounts: (6)
                  - name: sgw-config-volume
                    mountPath: /sync-gateway-config
                    readOnly: true
                env:
                  - name: GOMAXPROCS (7)
                    value: "1"
                resources:
                  requests:
                    cpu: 500m
                  limits:
                    cpu: 500m (8)
            volumes: (9)
              - name: sgw-config-volume
                secret:
                  secretName: sgw-config
      1 metadata.name: The name of the deployment is "sync-gateway".
      2 spec.replicas: 2 Sync Gateway replicas that are deployed at most.
      • For import node deployment, this is recommended to be 1. If high availability is important, you may want at least 2 Sync Gateway import nodes. However, given the overhead of redundant import docs processing by multiple nodes, this is not typically recommended.

      3 spec.template.spec.affinity: Anti-affinity entry.
      • The "anti-affinity" setting will not schedule two Sync Gateway pods on the same node. This setting is recommended to enable high availability and to prevent "noisy neighbor" issues.

      • If you are on a test/development environment, you can remove this property to have all nodes on a single node.

      4 containers[].image: Points to the docker image for Sync Gateway.
      5 containers[].args: Points to the Sync Gateway configuration file named "sgw-config-working.json" which is mounted at the path specified via the volumeMounts config. If you are using the sample config files, this would be "sgw-config-import.json" for the import node.
      6 volumeMounts: Specifies where to mount the volume into the container.
      7 GOMAXPROCS: This GO runtime environment variable is used to limit the number of system threads that are allocated to Sync Gateway.
      8 containers[].resources.limits.cpu: This is used to specify the CPU limit for the Sync Gateway pod. If you do not specify one, the Sync Gateway could spawn as many processes as CPU cores and potentially use up all CPU resources. You can learn more about CPU resource assignment here. We recommend a value of 2 but you should use what is suited for your environment.
      9 volumes: Specifies what to mount. In our case, the "secret" with name "sgw-config" corresponding to the Sync Gateway configuration that was created in the previous step is mounted. Learn more about Kubernetes volumes here.
    2. Deploy the Sync Gateway cluster from the specified deployment controller file.

      • Regular node

      • Import node

      kubectl create -f sgw-deployment.yaml
      kubectl create -f sgw-deployment-import.yaml

      If successful, you will see the following.

      • Import node

      • Regular node

      deployment.extensions "sync-gateway" created
      deployment.extensions "sync-gateway" created
    3. You can check the status of the deployment with the following command until all the pods corresponding to the Sync Gateway are in the "Ready" state and the status is "Running".

      kubectl get pods --watch

      The --watch option is optional but you use it to be asynchronously notified of updates to status of the pods instead of having to repeatedly run the command.

      If successful, you will see a listing of the Sync Gateway pods that were deployed. In the sample output below, we have Couchbase Server and Sync Gateway pods running in the same namespace. In a production deployment, you may have Couchbase Server deployed on a separate namespace.

      NAME                                 READY     STATUS    RESTARTS   AGE
      cb-example-0000                      1/1       Running   0          3d
      cb-example-0001                      1/1       Running   0          3d
      cb-example-0002                      1/1       Running   0          3d
      couchbase-operator-fd8db588b-9fzsw   1/1       Running   1          3d
      sync-gateway-7474f5df4b-c29xw        1/1       Running   2          18m
      sync-gateway-7474f5df4b-p98sq        1/1       Running   0          18m

      Make sure that you have sufficient CPU resources on the node on which the pods are being deployed. Failure to do so will result in an "insufficient resource" exception when attempting to deploy the pods.

    Deploying a Load Balancer

    In a production deployment, you will likely have one or more Sync Gateway nodes fronted by a load balancer.

    You will deploy the load balancer using the Kubernetes Load Balancer service. The load balancer service provides an externally accessible IP address and routes traffic to the right ports in the cluster.

    Load balancers only work on Cloud Environments (e.g. AWS, GCP etc). So if you are deploying on premise or using something like minikube for your test deployment, this option will not work. Please use a service such as NodePort or Ingress instead.

    Follow these steps to deploy a load balancer in front of the Sync Gateway cluster.

    1. Create a new file called sgw-load-balancer.yaml with the following.

      kind: Service
      apiVersion: v1
      metadata:
        name: sgw-load-balancer (1)
      spec:
        selector:
          app: sync-gateway (2)
        ports:
        - protocol: TCP
          port: 4984 (3)
          targetPort: 4984
        type: LoadBalancer
      1 metadata.name: The name of the load balancer is "sgw-load-balancer".
      2 spec.selector.app: This value corresponds to the pods targeted by the load balancer. In this case, it targets any pods with the app=sync-gateway label which are the Sync Gateway nodes - this corresponds to what was specified in the deployment yaml file.
      3 spec.ports[].targetPort: The load balancer service targets port 4984 on the Sync Gateway cluster. This is the Sync Gateway port corresponding to the REST API. For security purposes, it is recommended that you do not expose the admin port (4985) over the Internet.
    2. Deploy the load balancer.

      kubectl create -f sgw-load-balancer.yaml

      If successful, you will see the following.

      service "sgw-load-balancer" created
    3. Verify the status of the service creation with the following.

      kubectl get services

      If successful, you will see a new service corresponding to the load balancer. In the sample output below, we have the sgw-load-balancer service.

      NAME                TYPE           CLUSTER-IP     EXTERNAL-IP
      cb-example          ClusterIP      None           <none>
      cb-example-srv      ClusterIP      None           <none>
      cb-example-ui       NodePort       10.3.246.239   <none>
      kubernetes          ClusterIP      10.3.240.1     <none>
      sgw-load-balancer   LoadBalancer   10.3.253.17    35.184.19.17

      The sgw-load-balancer's EXTERNAL-IP is the load balancer’s publicly accessible hostname.

    4. Verify the pods that the load balancer is targeting.

      kubectl describe service sgw-load-balancer

      You should see the equivalent of the following.

      Name:                     sgw-load-balancer
      Namespace:                default
      Labels:                   <none>
      Annotations:              <none>
      Selector:                 app=sync-gateway
      Type:                     LoadBalancer
      IP:                       10.3.253.17
      LoadBalancer Ingress:     35.184.19.17
      Port:                     <unset>  4984/TCP
      TargetPort:               4984/TCP
      NodePort:                 <unset>  32397/TCP
      Endpoints:                10.0.0.34:4984,10.0.0.35:4984
      Session Affinity:         None
      External Traffic Policy:  Cluster
      Events:

      Notice the "endpoints" field and confirm that it corresponds to the Sync Gateway nodes. In this example, we have 2 Sync Gateway nodes.

    5. Verify the Sync Gateway cluster is accessible with the following command; where EXTERNAL-IP is the IP that was copied in step 3.

      curl  http://EXTERNAL-IP:4984

      It should return the following.

      {"couchdb":"Welcome","vendor":{"name":"Couchbase Sync Gateway","version":"2.1"},"version":"Couchbase Sync Gateway/2.1.1(17;fea9947)"}

    You have successfully deployed a Sync Gateway cluster on Kubernetes. The Manage a Cluster page contains additional details related to the management of the cluster.