利用configmap覆盖tomcat项目数据库配置文件

利用configmap覆盖tomcat项目数据库配置文件

一、需求背景及问题引入

      这个实验之前本来是做一个k8s  jenkins发布tomcat项目的,想实现k8s的滚动升级:通过改pod 镜像名来触发系统完成deployment运行pod的滚动升级操作。(这个问题解决之后,后续会补充一篇结合jenkins发布整个流程的)

      大致交代下这篇文章的实验背景:测试项目来源于公司的一个线上举报违规项目,我特意在gitlab上克隆了一个专门做测试。数据库连接配置文件写的是天翼内网ip,线上项目也是部署在天翼云的机器上,也就是这个项目是通过内网方式连接数据库跑起来的。

     实验环境:基于公司个人办公电脑开的的vmware,开了4台虚拟机做的k8s集群(版本:v1.15.2),其中k8s-1,k8s-2既是工作节点也是master节点。

     所以要想把项目在pod上成功跑起来,肯定是不能用这个天翼内网ip去连数据库的,要把项目运行起来就要通过公网去连线上的数据库(包括mongo+mysql)  

     数据库内网ip:10.0.0.x;  外网ip:14.x.x.235  

 

二、实验尝试及报错

      实现环境说明:k8s已经部署好jenkins的pod(用的是blueocean的官方镜像),maven和jenkins通过nfs网络存储做了持久化,节点机器都已经挂载好对应的持久化目录。

       jenkins的持久化目录为:/data/nfs-volume/jenkins_home

       镜像tomcat1:v8.5.51事先从官方网站下载,上传到自己搭建的harbor仓库里(k8s-4),下载下来的tomcat镜像的工作目录默认在 /usr/local/tomcat/ 上。jenkins发布,pipeline脚本会把jenkins workspaces下maven编译好的项目war包(下图的 ./target/xx.war)复制到tomcat1:v8.5.51的镜像里面,形成需要跑应用项目的新镜像:tomcat-deploy:v1。最后通过交付给k8s资源文件把tomcat项目跑起来。

       这里我只发个tomcat项目的deployment.yaml的文件(这样子挂载上去是不认的),test-conf(spec.template.spec.volumes.name)引入的是configmap.yaml的配置文件内容

 1 kind: Deployment
 2 apiVersion: extensions/v1beta1
 3 metadata:
 4   name: tomcat
 5   namespace: public
 6   labels: 
 7     name: tomcat
 8 spec:
 9   replicas: 1
10   selector:
11     matchLabels: 
12       name: tomcat
13   template:
14     metadata:
15       labels: 
16         app: tomcat 
17         name: tomcat
18     spec:
19       volumes:
20       - name: test-conf
21         items:
22         - key: application-pro.properties
23           path: application-pro.properties
24       containers:
25       - name: tomcat 
26         image: harbor.odljy.com/infra/tomcat-deploy:v1
27         ports:
28         - containerPort: 8080
29           protocol: TCP
30         volumeMounts:
31         - name: test
32           mountPath: /usr/local/tomcat/webapps/ROOT/WEB-INF/classes/config/application-pro.properties
33           subpath: application-pro.properties
34         
View Code

     曾经试过在交付资源清单给k8s之前,用sed去更改这个配置文件的内网数据库ip。无论是改pod里面配置文件/usr/local/tomcat/.../application-pro.properties(不支持sed命令),还是改外面的 /data/nfs-volume/jenkins_home/tomcat_home/WEB-INF/classes/config/application-pro.properties(说没有找到该文件,该目录是nfs给jenkins做的持久化目录),这个问题后面参考解决的文章有说。

 

 

 

、实验最终解决方案

   这篇文章给了我解决思路(上面的一些错误文章也有说到):https://www.cnblogs.com/xxz-blog/articles/14293312.html

   最关键的一点是保证pod启动前,要把配置文件覆盖过去,新增了一个tomcat的运行脚本负责解压war包,覆盖文件及跑起tomat

   主要实现思路:
 (1)以tomcat8.5.31为基础镜像,把项目war包和运行tomcat的脚本打到镜像里。
 (2)编写运行脚本(runtomcat.sh)解压war包到tomcat上的webapps目录上,然后利用k8s的configmap通过挂载需要替换成的配置文件到某个临时目录/tmp,覆盖项目数据库配置文件,最后执行catalina.sh启动tomcat项目。
经测试数据库配置文件有改成功,不然项目是会报jdbc连不上的错误
 
文件组织结构如下:

 

####### 1、构建发布镜像和启动服务脚本

(1)Dockerfile 文件

1 From harbor.odljy.com/public/tomcat:8.5.31
2 RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone
3 
4 #将webapps下的全部清空
5 RUN rm -rf /usr/local/tomcat/webapps/*
6 COPY wdtz-0.0.1-SNAPSHOT.war /usr/local/tomcat/webapps/ROOT.war
7 ADD runtomcat.sh bin/runtomcat.sh
8 CMD ["sh", "bin/runtomcat.sh"]

 

 (2)runtomcat.sh(跟参考文章中复制路径不同,我直接复制到ROOT的,这样不需要带项目名,直接访问静态页面路径就行)

1 cd /usr/local/tomcat/webapps
2 unzip /usr/local/tomcat/webapps/ROOT.war -d ROOT
3 rm -rf ROOT.war
4 \cp /tmp/application-pro.properties /usr/local/tomcat/webapps/ROOT/WEB-INF/classes/config/application-pro.properties
5 cd /usr/local/tomcat
6 sh /usr/local/tomcat/bin/catalina.sh run

 

####### 2、 k8s 资源交付部分

(1)configmap.yaml(后面省略)
apiVersion: v1
kind: ConfigMap
metadata:
  name: tomcat-mysql-conf
  namespace: public 
  labels:
    name: tomcat-mysql-conf
data:
  application-pro.properties: |
    spring.datasource.url=jdbc:mysql://14.xx.xx.235:8xx5/数据库名?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
    spring.datasource.username=yourusername
    spring.datasource.password=yourpwd
  。。。

(2)deployment.yaml

 1 kind: Deployment
 2 apiVersion: extensions/v1beta1
 3 metadata:
 4   name: tomcat
 5   namespace: public 
 6   labels: 
 7     name: tomcat
 8 spec:
 9   replicas: 1
10   selector:
11     matchLabels: 
12       name: tomcat
13   template:
14     metadata:
15       labels: 
16         app: tomcat 
17         name: tomcat
18     spec:
19       volumes:
20       - name: tomcat-mysql-conf
21         configMap:
22           name: tomcat-mysql-conf
23       containers:
24       - name: tomcat
25         image: tomcat:v2.0
26         ports:
27         - containerPort: 8080
28           protocol: TCP
29         volumeMounts:
30         - name: tomcat-mysql-conf
31           mountPath: /tmp/application-pro.properties
32           subPath: application-pro.properties   #这个不太清楚用法,先记下

(3)service.yaml(可要可不要,增加nodePort,为了给svc映射外网访问)

 1 apiVersion: v1
 2 kind: Service
 3 metadata:
 4   name: tomcat
 5   namespace: public
 6 spec:
 7   type: NodePort
 8   ports:
 9   - protocol: TCP
10     port: 8080 
11     targetPort: 8080
12     nodePort: 3009
13   selector:
14     app: tomcat
View Code

(4)ingress.yaml(通过域名访问:tomcat.odljy.com)

 1 kind: Ingress
 2 apiVersion: extensions/v1beta1
 3 metadata: 
 4   name: tomcat
 5   namespace: public
 6 spec:
 7   rules:
 8   - host: tomcat.odljy.com
 9     http:
10       paths:
11       - path: /
12         backend: 
13           serviceName: tomcat
14           servicePort: 8080
View Code

 

####### 3、交付资源清单给k8s后,及测试项目可用性

[root@k8s-1 tomcat]# kubectl get pods -n public
NAME                      READY   STATUS    RESTARTS   AGE
tomcat-5bfc545688-tt2n9   1/1     Running   0          17h


1、进去容器确认读了新的配置文件,证明数据库连接信息被覆盖了

 

2、 tomcat日志,没有jdbc连接错误

 

3、项目确实能跑起来了,测试发短信

 

 

 

4、证明项目能跑(不想搞坏数据库数据,就不提交了表单信息了)

posted @ 2021-01-21 10:27  windysai  阅读(1010)  评论(0编辑  收藏  举报