把H2數據庫從jar包部署到Kubernetes,並解決Ingress不支持TCP的問題
1 前言
歡迎訪問南瓜慢說 www.pkslow.com獲取更多精彩文章!
H2 Database
是一個優秀的數據庫,又小又方便,支持內存和文件形式,經常會在測試
、POC(proof of concept)
或開發環境
用到它。在Springboot
的許多應用中,也是內置了H2數據庫
,很常用。接下來我們來一步步把它推上k8s
,讓它坐上一個不一樣的位置。
建議閱讀下面文章以幫助理解:
Kubernetes用Helm安裝Ingress並踩一下使用的坑
2 本地jar包運行
2.1 下載和啟動
下載官網jar
包如下:
$ curl //www.h2database.com/h2-2019-03-13.zip -o h2-2019-03-13.zip
解壓:
$ unzip h2-2019-03-13.zip
啟動H2數據庫
:
$ java -cp h2/bin/h2*.jar org.h2.tools.Server -ifNotExists
TCP server running at tcp://localhost:9092 (only local connections)
PG server running at pg://localhost:5435 (only local connections)
Web Console server running at //localhost:8082 (others can connect)
如果需要修改配置,如端口號、數據存儲目錄,可以在啟動時添加參數:
java -cp h2/bin/h2*.jar org.h2.tools.Server -ifNotExists \
-web -webAllowOthers -webPort 8082 \
-tcp -tcpAllowOthers -tcpPort 9092 \
-baseDir ${DATA_DIR} ${H2_OPTIONS}
2.2 配置連接
成功啟動後訪問//localhost:8082
就能登陸控制台了。如下:
Driver Class
:org.h2.Driver
,驅動類;
JDBC URL
:jdbc:h2:mem:pkslow
,使用內存數據庫,數據庫名為pkslow
;
賬號密碼設置為admin/123456
。
設置完成後,點擊連接即可創建數據庫。
如果我們把JDBC URL
改為jdbc:h2:file:~/pkslow
,就是以文件形式存在,這樣能把數據持久化,所以我們採取這種方式。這裡就會在~
目錄,即${HOME}
目錄生成文件pkslow.mv.db
以保存數據。還有文件 ~/.h2.server.properties
。
更多URL
的配置方法如下表:
Topic | URL Format and Examples |
---|---|
Embedded (local) connection | jdbc:h2:[file:][] |
In-memory (private) | jdbc:h2:mem: |
In-memory (named) | jdbc:h2:mem: |
Server mode (remote connections) using TCP/IP | jdbc:h2:tcp:// |
Server mode (remote connections) using TLS | jdbc:h2:ssl:// |
Using encrypted files | jdbc:h2: |
File locking methods | jdbc:h2: |
Only open if it already exists | jdbc:h2: |
Don’t close the database when the VM exits | jdbc:h2: |
Execute SQL on connection | jdbc:h2: |
User name and/or password | jdbc:h2: |
Debug trace settings | jdbc:h2: |
Ignore unknown settings | jdbc:h2: |
Custom file access mode | jdbc:h2: |
Database in a zip file | jdbc:h2:zip: |
Compatibility mode | jdbc:h2: |
Auto-reconnect | jdbc:h2: |
Automatic mixed mode | jdbc:h2: |
Page size | jdbc:h2: |
Changing other settings | jdbc:h2: |
3 在Docker運行
3.1 創建鏡像並啟動
編寫Dockerfile
文件:
FROM adoptopenjdk/openjdk8-openj9:latest
COPY h2/ h2/
ENV DATA_DIR /opt/h2-data
RUN mkdir -p ${DATA_DIR}
EXPOSE 8082 9092
ENTRYPOINT java -cp h2/bin/h2-1.4.199.jar org.h2.tools.Server -ifNotExists \
-web -webAllowOthers \
-tcp -tcpAllowOthers \
-baseDir ${DATA_DIR} ${H2_OPTIONS}
這裡把數據存儲文件放在/opt/h2-data
目錄上,使用默認端口,所以只對外暴露8082/9092
端口。
通過Dockerfile
創建鏡像:
$ docker build -t h2:1.4.199 .
啟動Docker
容器:
$ docker run -itd --name h2 -p 8082:8082 -p 9092:9092 h2:1.4.199
3.2 通過Web和TCP方式連接
3.2.1 Web界面連接
成功啟動後,訪問//localhost:8082
配置連接如下:
進入容器,查看在/opt/h2-data
目錄生成了存儲文件:
$ docker exec -it h2 /bin/bash
root@0121e369b933:/opt/h2-data# l
test.mv.db
3.2.2 TCP方式連接
通過IDEA
配置連接H2
時要注意路徑,通過TCP
方式,不用加baseDir
,配置為jdbc:h2:tcp://localhost:9092/test
。如果要加,應該配置為jdbc:h2:tcp://localhost:9092//opt/h2-data/test
。
4 部署在Kubernetes上運行
4.1 部署上Kubernetes看看
4.1.1 創建PersistentVolumeClaim
PersistentVolumeClaim
,簡稱PVC
,是Kubernetes
用於存儲的單元,為了可以使H2
的數據持久化,在Pod
死掉後重啟數據不丟失,我們來創建對應的PVC
:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: h2-db
labels:
app: h2-db
annotations:
volume.alpha.kubernetes.io/storage-class: default
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 0.05Gi
這裡空間只給0.05G
,反正實驗為主,不作其它用途。
4.1.2 創建Deployment
這裡最關鍵的是要注意PVC
的配置:
apiVersion: apps/v1
kind: Deployment
metadata:
name: h2-db
labels:
app: h2-db
spec:
replicas: 1
selector:
matchLabels:
app: h2-db
template:
metadata:
labels:
app: h2-db
spec:
containers:
- image: h2:1.4.199
name: h2-db
ports:
- containerPort: 8082
name: h2-web
- containerPort: 9092
name: h2-tcp
volumeMounts:
- name: data
mountPath: /opt/h2-data
volumes:
- name: data
persistentVolumeClaim:
claimName: h2-db
mountPath
對應的是之前在製作Docker
鏡像時指定的路徑。
4.1.3 創建Service和Ingress
Service
和Ingress
對應的yaml
文件如下:
apiVersion: v1
kind: Service
metadata:
name: h2-db
labels:
app: h2-db
spec:
ports:
- port: 8082
name: web
- port: 9092
name: tcp
selector:
app: h2-db
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: h2-ingress
annotations:
kubernetes.io/ingress.class: nginx
spec:
rules:
- http:
paths:
- path: /
backend:
serviceName: h2-db
servicePort: 8082
host: h2-web.localhost
- http:
paths:
- path: /
backend:
serviceName: h2-db
servicePort: 9092
host: h2-tcp.localhost
4.1.4 訪問
Web
方式簡單,通過訪問//h2-web.localhost/
配置連接即可。
TCP
方式就麻煩了,無論如何配置,死活連不上。具體原因接下來繼續討論。
4.2 讓Ingress支持TCP
之前TCP
連不上的原因是Ingress
是不支持TCP
路由轉發的,雖然Ingress
是基於Nginx
,而Nginx
又可以轉發代理TCP/UDP
。那就來探索一番吧。
4.2.1 修改nginx-ingress-controller
為了讓它支持TCP/UDP
,我們要修改Ingress-Controller
,在它的配置文件增加參數:
- --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
- --udp-services-configmap=$(POD_NAMESPACE)/udp-services
在下面內容中插入:
containers:
- args:
- /nginx-ingress-controller
- --default-backend-service=default/pki-nginx-ingress-default-backend
- --election-id=ingress-controller-leader
- --ingress-class=nginx
- --configmap=default/pki-nginx-ingress-controller
- --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
- --udp-services-configmap=$(POD_NAMESPACE)/udp-services
4.2.2 添加tcp-services config
上面的Controller
指定了tcp-services
的ConfigMap
,那我們就添加上:
kind: ConfigMap
apiVersion: v1
metadata:
name: tcp-services
namespace: default
data:
"9092": default/h2-db:9092
其中,"9092": default/h2-db:9092
表示:<Nginx port>: <namespace/service name>:<service port>:[PROXY]:[PROXY]
,我們這樣配置相當於把Nginx
的9092
端口,指向H2
的9092
端口。
4.2.3 修改Ingress Service的端口
在只有http/https
的基礎上,增加H2
配置:
spec:
externalTrafficPolicy: Cluster
ports:
- name: http
nodePort: 32231
port: 80
protocol: TCP
targetPort: http
- name: https
nodePort: 30370
port: 443
protocol: TCP
targetPort: https
- name: h2-tcp
nodePort: 30371
port: 9092
protocol: TCP
targetPort: 9092
4.2.4 連接使用
完成以上步驟後,就可以連接了,如下:
配置後連接成功。
5 總結
至此,我們一步步從jar
包到部署H2 Database
上Kubernetes
,希望大家能從整個過程學到一些知識吧。我們解決了之前安裝Ingress
不支持TCP
的問題,但始終不是一個太好的方案。如果我們把連接數據庫的應用都部署在Kubernetes
上,那就沒有必要把H2 TCP
暴露出去了。
歡迎關注微信公眾號<南瓜慢說>,將持續為你更新…
多讀書,多分享;多寫作,多整理。