필수 구성 요건 및 실행 환경
Nacos를 쿠버네티스(Kubernetes) 클러스터에 안정적으로 배포하려면 다음 두 가지 핵심 요소가 필요합니다:
- 외부 MySQL 데이터베이스: 버전 5.7 이상 권장
- ReadWriteMany (RWX) 지원 스토리지 클래스: NAS 기반 스토리지 사용 필수
지원하는 플랫폼 정보
| 환경 | 버전/설정 |
| 클러스터 관리 | 阿里云 ACK (Alibaba Cloud Container Service) |
| Kubernetes 버전 | 1.24 |
| Nacos 이미지 | nacos/nacos-server:v2.2.3 |
| 네임스페이스 | default (사용자 정의 가능) |
MySQL 데이터베이스 초기화 절차
Nacos 운영을 위한 메타데이터 저장소를 설정합니다. 공식 GitHub 저장소에서 제공하는 스키마 파일을 활용합니다.
wget https://raw.githubusercontent.com/alibaba/nacos/develop/distribution/conf/mysql-schema.sql
# MySQL CLI 접속 후 아래 명령어 실행
mysql -u root -p
CREATE DATABASE IF NOT EXISTS nacos CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE nacos;
SOURCE /root/mysql-schema.sql;
CREATE USER 'nacos'@'%' IDENTIFIED BY 'your_secure_password';
GRANT ALL PRIVILEGES ON nacos.* TO 'nacos'@'%';
FLUSH PRIVILEGES;
EXIT;
쿠버네티스 ConfigMap을 통한 DB 연결 정보 등록
외부 MySQL 인스턴스 접속 정보를 구성 객체로 관리합니다. 민감 정보는 추후 Secret으로 전환 권장.
apiVersion: v1
kind: ConfigMap
metadata:
name: nacos-config
namespace: default
data:
mysql.host: "your-rds-endpoint.mysql.rds.aliyuncs.com"
mysql.db.name: "nacos"
mysql.port: "3306"
mysql.user: "nacos"
mysql.password: "your_secure_password"
Headless 서비스 리소스 생성
StatefulSet 내 Pod 간 직접 통신을 위해 `clusterIP: None` 설정이 필수입니다. Nacos 2.x 버전은 gRPC 기반 통신을 위해 별도 포트를 사용합니다.
apiVersion: v1
kind: Service
metadata:
name: nacos-headless-svc
namespace: default
labels:
app: nacos-cluster
spec:
clusterIP: None
publishNotReadyAddresses: true
selector:
app: nacos-cluster
ports:
- name: http-api
port: 8848
targetPort: 8848
- name: grpc-client
port: 9848
targetPort: 9848
- name: raft-internal
port: 9849
targetPort: 9849
- name: legacy-raft
port: 7848
targetPort: 7848
StatefulSet 기반 클러스터 배포
영구적 식별자와 스토리지 유지가 필요한 Nacos 노드에 적합한 워크로드 유형입니다.
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: nacos-node
namespace: default
spec:
serviceName: nacos-headless-svc
replicas: 3
podManagementPolicy: Parallel
selector:
matchLabels:
app: nacos-cluster
template:
metadata:
labels:
app: nacos-cluster
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8848"
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- nacos-cluster
topologyKey: kubernetes.io/hostname
initContainers:
- name: install-peer-plugin
image: nacos/nacos-peer-finder-plugin:1.1
volumeMounts:
- name: storage-volume
mountPath: /home/nacos/plugins/peer-finder
subPath: peer-finder
containers:
- name: server
image: nacos/nacos-server:v2.2.3
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8848
name: api
- containerPort: 9848
name: rpc
- containerPort: 9849
name: raft
env:
- name: NACOS_REPLICAS
value: "3"
- name: SERVICE_NAME
value: "nacos-headless-svc"
- name: DOMAIN_NAME
value: "cluster.local"
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: MYSQL_SERVICE_HOST
valueFrom:
configMapKeyRef:
name: nacos-config
key: mysql.host
- name: MYSQL_SERVICE_DB_NAME
valueFrom:
configMapKeyRef:
name: nacos-config
key: mysql.db.name
- name: MYSQL_SERVICE_PORT
valueFrom:
configMapKeyRef:
name: nacos-config
key: mysql.port
- name: MYSQL_SERVICE_USER
valueFrom:
configMapKeyRef:
name: nacos-config
key: mysql.user
- name: MYSQL_SERVICE_PASSWORD
valueFrom:
configMapKeyRef:
name: nacos-config
key: mysql.password
- name: SPRING_DATASOURCE_PLATFORM
value: "mysql"
- name: NACOS_SERVER_PORT
value: "8848"
- name: PREFER_HOST_MODE
value: "hostname"
- name: NACOS_AUTH_ENABLE
value: "true"
- name: NACOS_AUTH_IDENTITY_KEY
value: "nacosAuthKey"
- name: NACOS_AUTH_IDENTITY_VALUE
value: "nacosSecurtyValue"
- name: NACOS_AUTH_TOKEN
value: "SecretKey012345678901234567890123456789012345678901234567890123456789"
- name: NACOS_AUTH_TOKEN_EXPIRE_SECONDS
value: "18000"
volumeMounts:
- name: storage-volume
mountPath: /home/nacos/data
subPath: data
- name: storage-volume
mountPath: /home/nacos/logs
subPath: logs
- name: storage-volume
mountPath: /home/nacos/plugins/peer-finder
subPath: peer-finder
resources:
requests:
memory: 2Gi
cpu: 500m
volumes: []
volumeClaimTemplates:
- metadata:
name: storage-volume
annotations:
volume.beta.kubernetes.io/storage-class: alicloud-disk-nas
spec:
accessModes: [ ReadWriteMany ]
resources:
requests:
storage: 20Gi
클러스터 구성 상태 확인 방법
모든 인스턴스가 동일한 클러스터 멤버십 정보를 공유하고 있는지 검증합니다.
for idx in 0 1 2; do
echo "=== nacos-node-$idx 클러스터 구성 ==="
kubectl exec nacos-node-$idx -c server -- cat conf/cluster.conf
done
외부 접근을 위한 Ingress 설정
HTTPS 기반 외부 엔드포인트를 제공하여 UI 및 API 접근을 활성화합니다.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-nacos-ui
namespace: default
annotations:
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
spec:
tls:
- hosts:
- nacos.example.com
secretName: example-com-tls-secret
rules:
- host: nacos.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nacos-headless-svc
port:
number: 8848