🧩 ClusterIP とは?
ClusterIPは、Kubernetesクラスター内部からのみアクセスできる仮想IPアドレス(内部サービス)を提供します。
つまり:
- 外部からアクセスはできません
- 同じクラスター内のPodや他のServiceからはアクセスできます
- クラスター内部での**通信の中継役(ロードバランサー)**になります
✅ ClusterIP の特徴
| 特徴 | 説明 |
|---|---|
| 内部通信専用 | クラスタ内のPodからしかアクセスできない |
| 仮想IPを付与 | 10.x.x.x のような内部IPが付く |
| ロードバランサー機能 | バックエンドPod(レプリカなど)に均等にトラフィックを分散 |
| 自動DNS名割り当て | service-name.namespace.svc.cluster.local という名前で参照可能 |
🧠 典型的な用途
- アプリケーションの バックエンド をフロントエンドから参照する
- Webアプリ → APIサーバー
- Odoo → PostgreSQL のような構成
✅ 方法③:pgAdminをKubernetes内にデプロイして同じNamespaceからアクセス
Kubernetesクラスター内にpgAdminもPodとして立て、postgres-service.default.svc.cluster.local に接続する構成。
- 外部公開せずに K8sダッシュボードのようにpgAdminへWebアクセス
- Helmチャートやマニフェストで
dpage/pgadmin4イメージを使う
管理がやや複雑ですが、長期運用や共有環境には向いています。

🧱 PostgreSQL Service(ClusterIP)
apiVersion: v1
kind: Service
metadata:
name: postgres-service
spec:
type: ClusterIP
selector:
app: postgres
ports:
- port: 5432
targetPort: 5432
全てのコンテナ(Odoo・pgAdmin・Sidecar)がこのpostgres-service:5432に接続
2. 🧩 pgAdmin Pod構成
apiVersion: apps/v1
kind: Deployment
metadata:
name: pgadmin
spec:
replicas: 1
selector:
matchLabels:
app: pgadmin
template:
metadata:
labels:
app: pgadmin
spec:
containers:
- name: pgadmin
image: dpage/pgadmin4
env:
- name: PGADMIN_DEFAULT_EMAIL
value: admin@example.com
- name: PGADMIN_DEFAULT_PASSWORD
value: admin123
ports:
- containerPort: 80
■ Service定義(NodePort or Ingressで外部アクセス可)
apiVersion: v1
kind: Service
metadata:
name: pgadmin-service
spec:
type: NodePort
ports:
- port: 80
nodePort: 30080
selector:
app: pgadmin
ローカルPCからアクセスするには → http://<NodeIP>:30080
3. 🚛 Sidecar Podでデータ抽出 → Snowflake書込
■ Sidecar Pod内処理(Python例)
import snowflake.connector
import psycopg2
# PostgreSQLから抽出
pg_conn = psycopg2.connect(
host="postgres-service", port=5432,
user="odoo", password="secret", dbname="odoodb"
)
cur = pg_conn.cursor()
cur.execute("SELECT id, amount_total FROM sale_order WHERE date_order > current_date - interval '1 day'")
rows = cur.fetchall()
# Snowflakeに書き込み
sf_conn = snowflake.connector.connect(
user='user', password='pass',
account='youraccount.ap-northeast-1',
warehouse='MY_WH', database='MY_DB', schema='PUBLIC'
)
sf_cur = sf_conn.cursor()
for row in rows:
sf_cur.execute("INSERT INTO orders (id, amount_total) VALUES (%s, %s)", row)
■ Sidecar定義(Deployment or CronJob)
apiVersion: batch/v1
kind: CronJob
metadata:
name: snowflake-writer
spec:
schedule: "0 * * * *" # 毎時
jobTemplate:
spec:
template:
spec:
containers:
- name: writer
image: python:3.11
command: ["python", "/app/export.py"]
volumeMounts:
- name: code
mountPath: /app
restartPolicy: OnFailure
volumes:
- name: code
configMap:
name: export-script
🛠 Kubernetes内の役割分担
| コンポーネント | 役割 | サービスタイプ | 外部アクセス |
|---|---|---|---|
| PostgreSQL | データストア | ClusterIP | ❌ |
| pgAdmin | GUIで確認用 | NodePort or Ingress | ✅ |
| Sidecar | データ抽出・転送 | Pod内 or CronJob | ❌ |
| Snowflake | 外部SaaS(クラウドDB) | N/A(HTTPS) | ✅(Sidecarから) |
✅ まとめ
| 要件 | 構成 |
|---|---|
| Odoo/pgAdmin/Sidecar → DBアクセス | ✅ ClusterIP(Service)で接続統一 |
| pgAdminのGUIアクセス | ✅ NodePort(簡易) or Ingress(本番)で公開 |
| Snowflakeへの書き込み | ✅ Sidecarが外部HTTPS接続で実行 |
| 抽出対象テーブルの管理 | ✅ ConfigMap or Helm values.yaml で切替可能 |
コメントを残す