• 把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 http://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 http://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 配置连接

    成功启动后访问http://localhost:8082就能登陆控制台了。如下:

    Driver Classorg.h2.Driver,驱动类;

    JDBC URLjdbc: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:][] jdbc:h2:~/test jdbc:h2:file:/data/sample jdbc:h2:file:C:/data/sample (Windows only)
    In-memory (private) jdbc:h2:mem:
    In-memory (named) jdbc:h2:mem: jdbc:h2:mem:test_mem
    Server mode (remote connections) using TCP/IP jdbc:h2:tcp://[:]/[] jdbc:h2:tcp://localhost/~/test jdbc:h2:tcp://dbserv:8084/~/sample jdbc:h2:tcp://localhost/mem:test
    Server mode (remote connections) using TLS jdbc:h2:ssl://[:]/[] jdbc:h2:ssl://localhost:8085/~/sample;
    Using encrypted files jdbc:h2:;CIPHER=AES jdbc:h2:ssl://localhost/~/test;CIPHER=AES jdbc:h2:file:~/secure;CIPHER=AES
    File locking methods jdbc:h2:;FILE_LOCK={FILE|SOCKET|NO} jdbc:h2:file:~/private;CIPHER=AES;FILE_LOCK=SOCKET
    Only open if it already exists jdbc:h2:;IFEXISTS=TRUE jdbc:h2:file:~/sample;IFEXISTS=TRUE
    Don't close the database when the VM exits jdbc:h2:;DB_CLOSE_ON_EXIT=FALSE
    Execute SQL on connection jdbc:h2:;INIT=RUNSCRIPT FROM '~/create.sql' jdbc:h2:file:~/sample;INIT=RUNSCRIPT FROM '~/create.sql';RUNSCRIPT FROM '~/populate.sql'
    User name and/or password jdbc:h2:[;USER=][;PASSWORD=] jdbc:h2:file:~/sample;USER=sa;PASSWORD=123
    Debug trace settings jdbc:h2:;TRACE_LEVEL_FILE=<level 0..3> jdbc:h2:file:~/sample;TRACE_LEVEL_FILE=3
    Ignore unknown settings jdbc:h2:;IGNORE_UNKNOWN_SETTINGS=TRUE
    Custom file access mode jdbc:h2:;ACCESS_MODE_DATA=rws
    Database in a zip file jdbc:h2:zip:!/ jdbc:h2:zip:~/db.zip!/test
    Compatibility mode jdbc:h2:;MODE= jdbc:h2:~/test;MODE=MYSQL;DATABASE_TO_LOWER=TRUE
    Auto-reconnect jdbc:h2:;AUTO_RECONNECT=TRUE jdbc:h2:tcp://localhost/~/test;AUTO_RECONNECT=TRUE
    Automatic mixed mode jdbc:h2:;AUTO_SERVER=TRUE jdbc:h2:~/test;AUTO_SERVER=TRUE
    Page size jdbc:h2:;PAGE_SIZE=512
    Changing other settings jdbc:h2:;=[;=...] jdbc:h2:file:~/sample;TRACE_LEVEL_SYSTEM_OUT=3

    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界面连接

    成功启动后,访问http://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

    ServiceIngress对应的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方式简单,通过访问http://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-servicesConfigMap,那我们就添加上:

    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],我们这样配置相当于把Nginx9092端口,指向H29092端口。

    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 DatabaseKubernetes,希望大家能从整个过程学到一些知识吧。我们解决了之前安装Ingress不支持TCP的问题,但始终不是一个太好的方案。如果我们把连接数据库的应用都部署在Kubernetes上,那就没有必要把H2 TCP暴露出去了。


    欢迎关注微信公众号<南瓜慢说>,将持续为你更新...

    多读书,多分享;多写作,多整理。

  • 相关阅读:
    Android平台下基于XMPP的IM研究
    Android File数据存储
    Android 获取屏幕分辨率的方式
    Android TabHost 动态修改图标或者动态改变标题
    Android DatePickerDialog用法
    SharedPreference Demo
    progressdialog 去边框
    [LCT学习时的一些笔记]
    [ZJOI2007]最大半连通子图
    【Matrixtree Theorem学习笔记】
  • 原文地址:https://www.cnblogs.com/larrydpk/p/13496644.html
Copyright © 2020-2023  润新知