> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify-poc.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Integrate Kubernetes with Tiger Cloud

> Automate deployment, scaling, and management of your containerized workloads

export const SERVICE_LONG = 'Tiger Cloud service';

export const SELF_LONG_CAP = 'Self-hosted TimescaleDB';

export const CLOUD_LONG = 'Tiger Cloud';

export const TOOLKIT_LONG = 'TimescaleDB Toolkit';

export const TIMESCALE_DB = 'TimescaleDB';

export const SELF_LONG = 'self-hosted TimescaleDB';

export const PG = 'Postgres';

export const COMPANY = 'Tiger Data ';

[Kubernetes][kubernetes] is an open-source container orchestration system that automates the deployment, scaling, and management of containerized applications. You can connect Kubernetes to {CLOUD_LONG}, and deploy {TIMESCALE_DB} within your Kubernetes clusters.

This guide explains how to connect a Kubernetes cluster to {CLOUD_LONG}, configure persistent storage, and deploy {TIMESCALE_DB} in your kubernetes cluster.

## Prerequisites

To follow the steps on this page:

* Install [self-managed Kubernetes][kubernetes-install] or sign up for a Kubernetes [Turnkey Cloud Solution][kubernetes-managed].
* Install [kubectl][kubectl] for command-line interaction with your cluster.

[kubernetes-install]: https://kubernetes.io/docs/setup/

[kubectl]: https://kubernetes.io/docs/tasks/tools/

[kubernetes-managed]: https://kubernetes.io/docs/setup/production-environment/turnkey-solutions/

## Integrate TimescaleDB in a Kubernetes cluster

<Tabs>
  <Tab title={CLOUD_LONG}>
    To connect your Kubernetes cluster to your {SERVICE_LONG}:

    1. **Create a default namespace for your {CLOUD_LONG} components**

       1. Create a namespace:

          ```shell theme={"dark"}
          kubectl create namespace timescale
          ```

       2. Set this namespace as the default for your session:

          ```shell theme={"dark"}
          kubectl config set-context --current --namespace=timescale
          ```

       For more information, see [Kubernetes Namespaces][kubernetes-namespace].

    2. **Create a Kubernetes secret that stores your {SERVICE_LONG} credentials**

       Update the following command with your [connection details][connection-info], then run it:

       ```shell theme={"dark"}
       kubectl create secret generic timescale-secret \
        --from-literal=PGHOST=<host> \
        --from-literal=PGPORT=<port> \
        --from-literal=PGDATABASE=<dbname> \
        --from-literal=PGUSER=<user> \
        --from-literal=PGPASSWORD=<password>
       ```

    3. **Configure network access to {CLOUD_LONG}**

       * **Managed Kubernetes**: outbound connections to external databases like {CLOUD_LONG} work by default.
         Make sure your cluster's security group or firewall rules allow outbound traffic to {CLOUD_LONG} IP.

       * **Self-hosted Kubernetes**: If your cluster is behind a firewall or running on-premise, you may need to allow
         egress traffic to {CLOUD_LONG}. Test connectivity using your [connection details][connection-info]:

         ```shell theme={"dark"}
         nc -zv <host> <port>
         ```

         If the connection fails, check your firewall rules.

    4. **Create a Kubernetes deployment that can access your {CLOUD_LONG}**

       Run the following command to apply the deployment:

       ```shell theme={"dark"}
       kubectl apply -f - <<EOF
       apiVersion: apps/v1
       kind: Deployment
       metadata:
         name: timescale-app
       spec:
         replicas: 1
         selector:
           matchLabels:
             app: timescale-app
         template:
           metadata:
             labels:
               app: timescale-app
           spec:
             containers:
             - name: timescale-container
               image: postgres:latest
               envFrom:
                 - secretRef:
                     name: timescale-secret
       EOF
       ```

    5. **Test the connection**

       1. Create and run a pod that uses the [connection details][connection-info] you added to `timescale-secret` in
          the `timescale` namespace:

          ```shell theme={"dark"}
          kubectl run test-pod --image=postgres --restart=Never \
           --env="PGHOST=$(kubectl get secret timescale-secret -o=jsonpath='{.data.PGHOST}' | base64 --decode)" \
           --env="PGPORT=$(kubectl get secret timescale-secret -o=jsonpath='{.data.PGPORT}' | base64 --decode)" \
           --env="PGDATABASE=$(kubectl get secret timescale-secret -o=jsonpath='{.data.PGDATABASE}' | base64 --decode)" \
           --env="PGUSER=$(kubectl get secret timescale-secret -o=jsonpath='{.data.PGUSER}' | base64 --decode)" \
           --env="PGPASSWORD=$(kubectl get secret timescale-secret -o=jsonpath='{.data.PGPASSWORD}' | base64 --decode)" \
           -- sleep infinity
          ```

       2. Launch a psql shell in the `test-pod` you just created:

          ```shell theme={"dark"}
          kubectl exec -it test-pod -- bash -c "psql -h \$PGHOST -U \$PGUSER -d \$PGDATABASE"
          ```

       You start a `psql` session connected to your {SERVICE_LONG}.
  </Tab>

  <Tab title={SELF_LONG_CAP}>
    Running {TIMESCALE_DB} on Kubernetes is similar to running {PG}. This procedure outlines the steps for a non-distributed system.

    To connect your Kubernetes cluster to {SELF_LONG} running in the cluster:

    1. **Create a default namespace for {COMPANY} components**

       1. Create the {COMPANY} namespace:

          ```shell theme={"dark"}
          kubectl create namespace timescale
          ```

       2. Set this namespace as the default for your session:

          ```shell theme={"dark"}
          kubectl config set-context --current --namespace=timescale
          ```

       For more information, see [Kubernetes Namespaces][kubernetes-namespace].

    2. **Set up a persistent volume claim (PVC) storage**

       To manually set up a persistent volume and claim for self-hosted Kubernetes, run the following command:

       ```yaml theme={"dark"}
       kubectl apply -f - <<EOF
       apiVersion: v1
       kind: PersistentVolumeClaim
       metadata:
         name: timescale-pvc
       spec:
         accessModes:
           - ReadWriteOnce
         resources:
           requests:
             storage: 10Gi
       EOF
       ```

    3. **Deploy {TIMESCALE_DB} as a StatefulSet**

       By default, the [{TIMESCALE_DB} HA Docker image][timescale-ha-docker-image] you are installing on Kubernetes uses the
       default {PG} database, user and password. This image includes {TIMESCALE_DB} and {TOOLKIT_LONG}.
       To deploy {TIMESCALE_DB} on Kubernetes, run the following command:

       ```yaml theme={"dark"}
       kubectl apply -f - <<EOF
       apiVersion: apps/v1
       kind: StatefulSet
       metadata:
         name: timescaledb
       spec:
         serviceName: timescaledb
         replicas: 1
         selector:
           matchLabels:
             app: timescaledb
         template:
           metadata:
             labels:
               app: timescaledb
           spec:
             containers:
               - name: timescaledb
                 image: 'timescale/timescaledb-ha:pg18'
                 env:
                   - name: POSTGRES_USER
                     value: postgres
                   - name: POSTGRES_PASSWORD
                     value: postgres
                   - name: POSTGRES_DB
                     value: postgres
                   - name: PGDATA
                     value: /var/lib/postgresql/data/pgdata
                 ports:
                   - containerPort: 5432
                 volumeMounts:
                   - mountPath: /var/lib/postgresql/data
                     name: timescale-storage
             volumes:
               - name: timescale-storage
                 persistentVolumeClaim:
                   claimName: timescale-pvc
       EOF
       ```

    4. **Allow applications to connect by exposing {TIMESCALE_DB} within Kubernetes**

       ```yaml theme={"dark"}
       kubectl apply -f - <<EOF
       apiVersion: v1
       kind: Service
       metadata:
         name: timescaledb
       spec:
         selector:
           app: timescaledb
         ports:
           - protocol: TCP
             port: 5432
             targetPort: 5432
         type: ClusterIP
       EOF
       ```

    5. **Create a Kubernetes secret to store the database credentials**

       ```shell theme={"dark"}
       kubectl create secret generic timescale-secret \
       --from-literal=PGHOST=timescaledb \
       --from-literal=PGPORT=5432 \
       --from-literal=PGDATABASE=postgres \
       --from-literal=PGUSER=postgres \
       --from-literal=PGPASSWORD=postgres
       ```

    6. **Deploy an application that connects to {TIMESCALE_DB}**

       ```shell theme={"dark"}
       kubectl apply -f - <<EOF
       apiVersion: apps/v1
       kind: Deployment
       metadata:
         name: timescale-app
       spec:
         replicas: 1
         selector:
           matchLabels:
             app: timescale-app
         template:
           metadata:
             labels:
               app: timescale-app
           spec:
             containers:
             - name: timescale-container
               image: postgres:latest
               envFrom:
                 - secretRef:
                     name: timescale-secret
       EOF
       ```

    7. **Test the database connection**

       1. Create and run a pod to verify database connectivity using your [connection details][connection-info] saved in `timescale-secret`:

          ```shell theme={"dark"}
          kubectl run test-pod --image=postgres --restart=Never \
          --env="PGHOST=$(kubectl get secret timescale-secret -o=jsonpath='{.data.PGHOST}' | base64 --decode)" \
          --env="PGPORT=$(kubectl get secret timescale-secret -o=jsonpath='{.data.PGPORT}' | base64 --decode)" \
          --env="PGDATABASE=$(kubectl get secret timescale-secret -o=jsonpath='{.data.PGDATABASE}' | base64 --decode)" \
          --env="PGUSER=$(kubectl get secret timescale-secret -o=jsonpath='{.data.PGUSER}' | base64 --decode)" \
          --env="PGPASSWORD=$(kubectl get secret timescale-secret -o=jsonpath='{.data.PGPASSWORD}' | base64 --decode)" \
          -- sleep infinity
          ```

       2. Launch the {PG} interactive shell within the created `test-pod`:

          ```shell theme={"dark"}
          kubectl exec -it test-pod -- bash -c "psql -h \$PGHOST -U \$PGUSER -d \$PGDATABASE"
          ```

       You see the {PG} interactive terminal.

    [connection-info]: /integrations/find-connection-details

    [kubernetes-namespace]: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/

    [timescale-ha-docker-image]: https://hub.docker.com/r/timescale/timescaledb-ha/tags
  </Tab>
</Tabs>

You have successfully integrated Kubernetes with {CLOUD_LONG}.

[connection-info]: /integrations/find-connection-details

[kubernetes]: https://kubernetes.io/

[kubernetes-namespace]: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
