Deploy Nacos with PostgreSQL on Kubernetes: Step‑by‑Step Guide
Learn how to deploy a highly available Nacos service on Kubernetes using PostgreSQL as the backend, covering prerequisites, database initialization, configuration, Helm‑free manifests, driver installation, and verification steps to build a reliable micro‑service platform.
Introduction
In the cloud‑native era, micro‑service architecture is mainstream, and Nacos is a popular service discovery and configuration management platform. Using PostgreSQL as its backend ensures data safety, persistence, and performance. This article explains how to deploy Nacos in a Kubernetes cluster and integrate it with PostgreSQL.
Prerequisites
Kubernetes cluster is available
StorageClass is configured
Ingress controller is available
PostgreSQL cluster is available
Initialize Nacos database schema
Download the initialization script and create the PostgreSQL user and database:
<code>$ sudo mkdir /etc/kubernetes/addons/nacos
$ sudo curl -L -o /etc/kubernetes/addons/nacos/nacos-pg.sql https://github.com/wuchubuzai2018/nacos-datasource-extend-plugins/raw/refs/heads/main/nacos-datasource-plugin-ext/nacos-postgresql-datasource-plugin-ext/src/main/resources/schema/nacos-pg.sql
$ CREATE USER nacos WITH PASSWORD '123456';
$ CREATE DATABASE nacos_prod OWNER nacos;
$ psql -h 172.139.20.188 -p 9999 -U nacos -W nacos_prod < /etc/kubernetes/addons/nacos/nacos-pg.sql</code>Deploy Nacos service
Create a namespace and a ConfigMap with the Nacos configuration that enables PostgreSQL support and authentication:
<code>$ kubectl create ns nacos
$ cat <<'EOF' | sudo tee /etc/kubernetes/addons/nacos/application.properties > /dev/null
# Spring Boot related configurations
server.error.include-message=ALWAYS
server.port=8848
# Config module
spring.sql.init.platform=postgresql
db.num=1
db.url.0=jdbc:postgresql://172.139.20.188:9999/nacos_prod?tcpKeepAlive=true&reWriteBatchedInserts=true&ApplicationName=nacos_java
db.user.0=nacos
db.password.0=123456
db.pool.config.maximumPoolSize=20
# Authentication
nacos.core.auth.enabled=true
nacos.core.auth.server.identity.key=authKey
nacos.core.auth.server.identity.value=shigzh
EOF
$ kubectl create configmap nacos-config --from-file=application.properties=/etc/kubernetes/addons/nacos/application.properties -n nacos</code>Download the PostgreSQL driver jar:
<code>$ sudo curl -o /etc/kubernetes/addons/nacos/nacos-postgresql-plugin-1.0.0.jar -L https://github.com/wuchubuzai2018/nacos-datasource-extend-plugins/releases/download/1.0.0/nacos-postgresql-plugin-1.0.0.jar</code>Apply the Kubernetes manifests for Service, Headless Service, StatefulSet, and Ingress:
<code>$ cat <<'EOF' | sudo tee /etc/kubernetes/addons/nacos/deploy.yml > /dev/null
---
apiVersion: v1
kind: Service
metadata:
name: nacos
namespace: nacos
spec:
ports:
- port: 8848
name: server
targetPort: 8848
- port: 9848
name: client-rpc
targetPort: 9848
- port: 9849
name: raft-rpc
targetPort: 9849
- port: 7848
name: old-raft-rpc
targetPort: 7848
selector:
app: nacos
---
apiVersion: v1
kind: Service
metadata:
name: nacos-headless
namespace: nacos
spec:
publishNotReadyAddresses: true
ports:
- port: 8848
name: server
targetPort: 8848
- port: 9848
name: client-rpc
targetPort: 9848
- port: 9849
name: raft-rpc
targetPort: 9849
- port: 7848
name: old-raft-rpc
targetPort: 7848
clusterIP: None
selector:
app: nacos
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: nacos
namespace: nacos
spec:
replicas: 3
podManagementPolicy: Parallel
serviceName: nacos-headless
selector:
matchLabels:
app: nacos
template:
metadata:
labels:
app: nacos
spec:
containers:
- name: nacos
image: core.jiaxzeng.com/library/nacos/nacos-server:v2.4.3-slim
ports:
- containerPort: 8848
name: client-port
- containerPort: 9848
name: client-rpc
- containerPort: 9849
name: raft-rpc
- containerPort: 7848
name: old-raft-rpc
env:
- name: NACOS_REPLICAS
value: "3"
- name: SERVICE_NAME
value: "nacos-headless"
- name: DOMAIN_NAME
value: "cluster.local"
- name: POD_NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
- name: NACOS_SERVER_PORT
value: "8848"
- name: NACOS_APPLICATION_PORT
value: "8848"
- name: PREFER_HOST_MODE
value: "hostname"
volumeMounts:
- name: config
mountPath: /home/nacos/conf/application.properties
subPath: application.properties
volumes:
- name: config
configMap:
name: nacos-config
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nacos
namespace: nacos
annotations:
cert-manager.io/cluster-issuer: "selfsigned-cluster-issuer"
spec:
ingressClassName: nginx
rules:
- host: nacos.jiaxzeng.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: nacos
port:
number: 8848
tls:
- secretName: nacos.jiaxzeng.com-tls
hosts:
- nacos.jiaxzeng.com
EOF
$ kubectl apply -f /etc/kubernetes/addons/nacos/deploy.yml</code>Copy the driver into each Nacos pod:
<code>for i in `seq 0 2`; do
kubectl -n nacos cp /etc/kubernetes/addons/nacos/nacos-postgresql-plugin-1.0.0.jar nacos-${i}:plugins/peer-finder
done</code>Verification
Check the deployed resources:
<code>$ kubectl -n nacos get pod,svc,pvc,ingress</code>Access the Nacos console at
http://nacos.jiaxzeng.com(default credentials:
nacos/nacos).
Conclusion
By following these steps, Nacos can be successfully deployed on Kubernetes with PostgreSQL as a reliable data store, enhancing system reliability and simplifying micro‑service development and operations.
Linux Ops Smart Journey
The operations journey never stops—pursuing excellence endlessly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.