Skip to content

Commit b7db3bf

Browse files
authored
Integrations: Kubernetes (#3877)
* chore: work on the procedure. * fixed integration for self-hosted --------- Signed-off-by: Iain Cox <iain@timescale.com>
1 parent 48a0fc0 commit b7db3bf

File tree

3 files changed

+328
-1
lines changed

3 files changed

+328
-1
lines changed

use-timescale/integrations/index.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ Some of the most in-demand integrations are listed below.
4848
| [Pulumi][pulumi] | Define and manage cloud infrastructure using code in multiple languages. |
4949
| [Render][render] | Deploy and scale web applications, databases, and services easily. |
5050
| [Terraform][terraform] | Safely and predictably provision and manage infrastructure in any cloud. |
51+
| [Kubernetes][kubernetes] | Deploy, scale, and manage containerized applications automatically. |
52+
5153

5254
## Data engineering and extract, transform, load
5355

@@ -172,6 +174,7 @@ Some of the most in-demand integrations are listed below.
172174
| [Tooljet][tooljet] | Develop internal tools and business applications with a low-code builder. |
173175
| [Zapier][zapier] | Automate workflows by connecting different applications and services. |
174176

177+
175178
[ads]: /use-timescale/:currentVersion:/integrations/azure-data-studio/
176179
[airbyte]: https://docs.airbyte.com/integrations/sources/postgres
177180
[amazon-sagemaker]: /use-timescale/:currentVersion:/integrations/amazon-sagemaker
@@ -243,6 +246,7 @@ Some of the most in-demand integrations are listed below.
243246
[power-bi]: /use-timescale/:currentVersion:/integrations/power-bi
244247
[prisma]: https://www.prisma.io/docs/orm/overview/databases/postgresql
245248
[prometheus]: /use-timescale/:currentVersion:/integrations/prometheus
249+
[kubernetes]: /use-timescale/:currentVersion:/integrations/kubernetes
246250
[psql]: /use-timescale/:currentVersion:/integrations/psql/
247251
[pulumi]: https://www.pulumi.com/registry/packages/timescale/
248252
[python]: /quick-start/:currentVersion:/python/
@@ -272,3 +276,4 @@ Some of the most in-demand integrations are listed below.
272276
[tooljet]: https://docs.tooljet.ai/docs/data-sources/postgresql/
273277
[typeorm]: https://typeorm.biunav.com/en/connection-options.html#postgres-cockroachdb-connection-options
274278
[zapier]: https://zapier.com/apps/postgresql/integrations
279+
Lines changed: 312 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,312 @@
1+
---
2+
title: Integrate Kubernetes with Timescale Cloud
3+
excerpt: Learn how to integrate Kubernetes with Timescale Cloud to enable seamless deployment and scaling of your PostgreSQL workloads
4+
products: [cloud, mst, self_hosted]
5+
keywords: [Kubernetes, Timescale Cloud, PostgreSQL, container orchestration]
6+
---
7+
8+
import IntegrationPrereqs from "versionContent/_partials/_integration-prereqs.mdx";
9+
10+
# Integrate Kubernetes with $CLOUD_LONG
11+
12+
[Kubernetes][kubernetes] is an open-source container orchestration system that automates the deployment, scaling, and management of containerized applications. You can deploy $CLOUD_LONG within your Kubernetes clusters.
13+
14+
This guide explains how to connect a Kubernetes cluster to $CLOUD_LONG, configure persistent storage, and manage deployments effectively.
15+
16+
## Prerequisites
17+
18+
<IntegrationPrereqs />
19+
20+
- Install [self-managed Kubernetes][kubernetes-install] or sign up for a Kubernetes [Turnkey Cloud Solution][kubernetes-managed].
21+
- Install [kubectl][kubectl] for command-line interaction with your cluster.
22+
23+
## Integrate Timescale in a Kubernetes cluster
24+
25+
<Tabs>
26+
27+
<Tab title="Timescale Cloud">
28+
29+
To connect your Kubernetes cluster to your $SERVICE_LONG:
30+
31+
<Procedure>
32+
33+
1. **Create a default namespace for your $CLOUD_LONG components**
34+
35+
1. Create the Timescale namespace:
36+
37+
```shell
38+
kubectl create namespace timescale
39+
```
40+
41+
1. Set this namespace as the default for your session:
42+
43+
```shell
44+
kubectl config set-context --current --namespace=timescale
45+
```
46+
47+
For more information, see [Kubernetes Namespaces][kubernetes-namespace].
48+
49+
1. **Create a Kubernetes secret that stores your $SERVICE_LONG credentials**
50+
51+
Update the following command with your [connection details][connection-info], then run it:
52+
53+
```shell
54+
kubectl create secret generic timescale-secret \
55+
--from-literal=PGHOST=<host> \
56+
--from-literal=PGPORT=<port> \
57+
--from-literal=PGDATABASE=<dbname> \
58+
--from-literal=PGUSER=<user> \
59+
--from-literal=PGPASSWORD=<password>
60+
```
61+
62+
1. **Configure network access to $CLOUD_LONG**
63+
64+
- **Managed Kubernetes**: outbound connections to external databases like $CLOUD_LONG work by default.
65+
Make sure your cluster’s security group or firewall rules allow outbound traffic to $CLOUD_LONG IP.
66+
67+
- **Self-hosted Kubernetes**: If your cluster is behind a firewall or running on-premise, you may need to allow
68+
egress traffic to $CLOUD_LONG. Test connectivity using your [connection details][connection-info]:
69+
70+
```shell
71+
nc -zv <host> <port>
72+
```
73+
74+
If the connection fails, check your firewall rules.
75+
76+
1. **Create a Kubernetes deployment that can access your $CLOUD_LONG**
77+
78+
Run the following command to apply the deployment:
79+
80+
```shell
81+
kubectl apply -f - <<EOF
82+
apiVersion: apps/v1
83+
kind: Deployment
84+
metadata:
85+
name: timescale-app
86+
spec:
87+
replicas: 1
88+
selector:
89+
matchLabels:
90+
app: timescale-app
91+
template:
92+
metadata:
93+
labels:
94+
app: timescale-app
95+
spec:
96+
containers:
97+
- name: timescale-container
98+
image: postgres:latest
99+
envFrom:
100+
- secretRef:
101+
name: timescale-secret
102+
EOF
103+
```
104+
105+
1. **Test the connection**
106+
107+
1. Create and run a pod that uses the [connection details][connection-info] you added to `timescale-secret` in
108+
the `timescale` namespace:
109+
110+
```shell
111+
kubectl run test-pod --image=postgres --restart=Never \
112+
--env="PGHOST=$(kubectl get secret timescale-secret -o=jsonpath='{.data.PGHOST}' | base64 --decode)" \
113+
--env="PGPORT=$(kubectl get secret timescale-secret -o=jsonpath='{.data.PGPORT}' | base64 --decode)" \
114+
--env="PGDATABASE=$(kubectl get secret timescale-secret -o=jsonpath='{.data.PGDATABASE}' | base64 --decode)" \
115+
--env="PGUSER=$(kubectl get secret timescale-secret -o=jsonpath='{.data.PGUSER}' | base64 --decode)" \
116+
--env="PGPASSWORD=$(kubectl get secret timescale-secret -o=jsonpath='{.data.PGPASSWORD}' | base64 --decode)" \
117+
-- sleep infinity
118+
```
119+
120+
2. Launch a psql shell in the `test-pod` you just created:
121+
122+
```shell
123+
kubectl exec -it test-pod -- bash -c "psql -h \$PGHOST -U \$PGUSER -d \$PGDATABASE"
124+
```
125+
126+
You start a `psql` session connected to your $SERVICE_LONG.
127+
128+
</Procedure>
129+
130+
</Tab>
131+
132+
<Tab title="Self-hosted TimescaleDB">
133+
134+
To connect your Kubernetes cluster to self-hosted $TIMESCALE_DB running in the cluster:
135+
136+
<Procedure>
137+
138+
1. **Create a default namespace for $COMPANY components**
139+
140+
1. Create the $COMPANY namespace:
141+
142+
```shell
143+
kubectl create namespace timescale
144+
```
145+
146+
1. Set this namespace as the default for your session:
147+
148+
```shell
149+
kubectl config set-context --current --namespace=timescale
150+
```
151+
152+
For more information, see [Kubernetes Namespaces][kubernetes-namespace].
153+
154+
1. **Set up a persistent volume claim (PVC) storage**
155+
156+
To manually set up a persistent volume and claim for self-hosted Kubernetes, run the following command:
157+
158+
```yaml
159+
kubectl apply -f - <<EOF
160+
apiVersion: v1
161+
kind: PersistentVolumeClaim
162+
metadata:
163+
name: timescale-pvc
164+
spec:
165+
accessModes:
166+
- ReadWriteOnce
167+
resources:
168+
requests:
169+
storage: 10Gi
170+
EOF
171+
```
172+
173+
1. **Deploy $TIMESCALE_DB as a StatefulSet**
174+
175+
By default, the [Timescale Docker image][timescale-docker-image] you are installing on Kubernetes uses the
176+
default $PG database, user and password. To deploy $TIMESCALE_DB on Kubernetes, run the following command:
177+
178+
```yaml
179+
kubectl apply -f - <<EOF
180+
apiVersion: apps/v1
181+
kind: StatefulSet
182+
metadata:
183+
name: timescaledb
184+
spec:
185+
serviceName: timescaledb
186+
replicas: 1
187+
selector:
188+
matchLabels:
189+
app: timescaledb
190+
template:
191+
metadata:
192+
labels:
193+
app: timescaledb
194+
spec:
195+
containers:
196+
- name: timescaledb
197+
image: 'timescale/timescaledb:latest-pg17'
198+
env:
199+
- name: POSTGRES_USER
200+
value: postgres
201+
- name: POSTGRES_PASSWORD
202+
value: postgres
203+
- name: POSTGRES_DB
204+
value: postgres
205+
- name: PGDATA
206+
value: /var/lib/postgresql/data/pgdata
207+
ports:
208+
- containerPort: 5432
209+
volumeMounts:
210+
- mountPath: /var/lib/postgresql/data
211+
name: timescale-storage
212+
volumes:
213+
- name: timescale-storage
214+
persistentVolumeClaim:
215+
claimName: timescale-pvc
216+
EOF
217+
```
218+
219+
1. **Allow applications to connect by exposing $TIMESCALE_DB within Kubernetes**
220+
221+
```yaml
222+
kubectl apply -f - <<EOF
223+
apiVersion: v1
224+
kind: Service
225+
metadata:
226+
name: timescaledb
227+
spec:
228+
selector:
229+
app: timescaledb
230+
ports:
231+
- protocol: TCP
232+
port: 5432
233+
targetPort: 5432
234+
type: ClusterIP
235+
EOF
236+
```
237+
238+
1. **Create a Kubernetes secret to store the database credentials**
239+
240+
```shell
241+
kubectl create secret generic timescale-secret \
242+
--from-literal=PGHOST=timescaledb \
243+
--from-literal=PGPORT=5432 \
244+
--from-literal=PGDATABASE=postgres \
245+
--from-literal=PGUSER=postgres \
246+
--from-literal=PGPASSWORD=postgres
247+
```
248+
249+
1. **Deploy an application that connects to $TIMESCALE_DB**
250+
251+
```shell
252+
kubectl apply -f - <<EOF
253+
apiVersion: apps/v1
254+
kind: Deployment
255+
metadata:
256+
name: timescale-app
257+
spec:
258+
replicas: 1
259+
selector:
260+
matchLabels:
261+
app: timescale-app
262+
template:
263+
metadata:
264+
labels:
265+
app: timescale-app
266+
spec:
267+
containers:
268+
- name: timescale-container
269+
image: postgres:latest
270+
envFrom:
271+
- secretRef:
272+
name: timescale-secret
273+
EOF
274+
```
275+
276+
1. **Test the database connection**
277+
278+
1. Create and run a pod to verify database connectivity using your [connection details][connection-info] saved in `timescale-secret`:
279+
280+
```shell
281+
kubectl run test-pod --image=postgres --restart=Never \
282+
--env="PGHOST=$(kubectl get secret timescale-secret -o=jsonpath='{.data.PGHOST}' | base64 --decode)" \
283+
--env="PGPORT=$(kubectl get secret timescale-secret -o=jsonpath='{.data.PGPORT}' | base64 --decode)" \
284+
--env="PGDATABASE=$(kubectl get secret timescale-secret -o=jsonpath='{.data.PGDATABASE}' | base64 --decode)" \
285+
--env="PGUSER=$(kubectl get secret timescale-secret -o=jsonpath='{.data.PGUSER}' | base64 --decode)" \
286+
--env="PGPASSWORD=$(kubectl get secret timescale-secret -o=jsonpath='{.data.PGPASSWORD}' | base64 --decode)" \
287+
-- sleep infinity
288+
```
289+
290+
1. Launch the PostgreSQL interactive shell within the created `test-pod`:
291+
292+
```shell
293+
kubectl exec -it test-pod -- bash -c "psql -h \$PGHOST -U \$PGUSER -d \$PGDATABASE"
294+
```
295+
296+
You see the PostgreSQL interactive terminal.
297+
298+
</Procedure>
299+
300+
</Tab>
301+
302+
</Tabs>
303+
304+
You have successfully integrated Kubernetes with $CLOUD_LONG.
305+
306+
[connection-info]: /use-timescale/:currentVersion:/integrations/find-connection-details/
307+
[kubernetes]: https://kubernetes.io/
308+
[kubectl]: https://kubernetes.io/docs/tasks/tools/
309+
[kubernetes-namespace]: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
310+
[kubernetes-install]: https://kubernetes.io/docs/setup/
311+
[kubernetes-managed]: https://kubernetes.io/docs/setup/production-environment/turnkey-solutions/
312+
[timescale-docker-image]: https://hub.docker.com/r/timescale/timescaledb

use-timescale/page-index/page-index.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,11 @@ module.exports = [
791791
href: "decodable",
792792
excerpt: "Integrate Decodable with Timescale Cloud",
793793
},
794+
{
795+
title: "Debezium",
796+
href: "debezium",
797+
excerpt: "Integrate Debezium with Timescale products",
798+
},
794799
{
795800
title: "Fivetran",
796801
href: "fivetran",
@@ -806,6 +811,11 @@ module.exports = [
806811
href: "grafana",
807812
excerpt: "Integrate Grafana with Timescale products",
808813
},
814+
{
815+
title: "Kubernetes",
816+
href: "kubernetes",
817+
excerpt: "Integrate Kubernetes with Timescale products",
818+
},
809819
{
810820
title: "Microsoft Azure",
811821
href: "microsoft-azure",
@@ -819,7 +829,7 @@ module.exports = [
819829
{
820830
title: "PostgreSQL",
821831
href: "postgresql",
822-
excerpt: "Integrate PostgreSQL with Timescale Cloud",
832+
excerpt: "Integrate PostgreSQL with Timescale products",
823833
},
824834
{
825835
title: "Prometheus",

0 commit comments

Comments
 (0)