- 将web应用及其运行环境(tomcat)制作成镜像
- 部署mysql并挂载数据
- 创建configmap
- 编写web应用的deployment,并使用configmap
一、将web应用及其运行环境(tomcat)制作成镜像
在制作镜像时,为什么要将web应用的war包解压,而不是直接使用CPOY命令将这个war包拷贝到webapps下?
答:由于
War包一般是在进行Web开发时,通常是一个网站Project下的所有源码的集合,里面包含前台HTML/CSS/JS的代码,也包含Java的代码。
当开发人员在自己的开发机器上调试所有代码并通过后,为了交给测试人员测试和未来进行产品发布,都需要将开发人员的源码打包成War进行发布。
War包可以放在Tomcat下的webapps或者word目录下,随着tomcat服务器的启动,它可以自动被解压。
step 1. 编写dockerfile文件
# Dockerfile
FROM docker.io/tomcat
MAINTAINER dongjia
RUN cd webapps && rm -rf ROOT/*
COPY ROOT.war /usr/local/tomcat/webapps/ROOT/
RUN cd webapps/ROOT/ && unzip -oq /usr/local/tomcat/webapps/ROOT/ROOT.war && rm -rf ROOT.war
EXPOSE 8080
CMD ["/usr/local/tomcat/bin/catalina.sh","run"]
注:为什么上面unzip之后要删除ROOT.war文件? CMD后面是什么意思? 这个地方暴露端口和在yaml暴露端口的区别,再去熟悉Dockerfile的写法
step 2. 执行Dockerfile并将镜像打tag,同时推向私有仓库
docker buile -t myweb:v1.0 -f . #要保证Dockerfile这个文件在当前目录下
#docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/nginx_wy/nginx_wy:[镜像版本号]
#registry.cn-hangzhou.aliyuncs.com/nginx_wy/nginx_wy:远程仓库域名及名称
docker tag e0b6717ddddf 192.168.132.155:5000/myweb:v1.0
#docker push registry.cn-hangzhou.aliyuncs.com/nginx_wy/nginx_wy:[镜像版本号]
docker push 192.168.132.155:5000/myweb:v1.0
二、部署mysql并挂载数据
step 1. 编写mysql的deployment (mysql-dep.yaml)
apiVersion: extensions/v1beta1 #apiserver的版本
kind: Deployment #副本控制器deployment,管理pod和RS
metadata:
name: mysql #deployment的名称,全局唯一
spec:
replicas: 1 #Pod副本期待数量
selector:
matchLabels: #定义RS的标签
app: mysql #符合目标的Pod拥有此标签
strategy: #定义升级的策略
type: RollingUpdate #滚动升级,逐步替换的策略
template: #根据此模板创建Pod的副本(实例)
metadata:
labels:
app: mysql #Pod副本的标签,对应RS的Selector
spec:
containers: #Pod里容器的定义部分
- name: mysql #容器的名称
image: mysql:5.7 #容器对应的docker镜像
volumeMounts: #容器内挂载点的定义部分
- name: mysql-data
mountPath: /var/lib/mysql #容器内mysql的数据目录
readOnly: false
ports:
- containerPort: 3306 #容器暴露的端口号
env: #写入到容器内的环境容量
- name: MYSQL_ROOT_PASSWORD #定义了一个mysql的root密码的变量
value: "1234"
volumes: #本地需要挂载到容器里的数据卷定义部分
- name: mysql-data
nfs:
server: 192.168.132.155
path: /data #by dong 这个目录下要求没有任何数据,如果有容器将启动失败,挂载成功后,此目录下的内容与/var/lib/mysql目录下的内容一模一样,外面变化里面也跟着改变
注:特别注意mountPath的路径和nfs的 /data目录
在做的过程中遇到的问题:当时将windows主机上存放mysql数据的目录(通过sql语句SELECT @@datadir
找到) 下如下图:
直接将上面的那个文件拷贝到 /data目录下(/data 是nfs挂载的目录,拷贝完成后此目录下目前只有db_library_seats目录),然后通过上面定义的 mysql-dep.yaml 文件启动mysql,发现pod始终起不来,describe看,说是 同步数据失败(Err sync)最后将/data目录中的db_library_seats删除,然后再pod就可以正常起来了,等pod起来之后,查看 /data目录,发现此目录中已将mysql的data目录同步过来了(其中有很多文件,包括系统库文件mysql, sys等)如下图:
再将db_library_seats拷贝进 /data目录下,做个svc让外部的navicat可连接,登录,进入,发现数据库中已经有db_library_seats这个库了,但这仅仅是个空库(没有表),查询资料才发现,在拷贝时要将数据目录下的一个叫 ibdata1一同拷贝进 /data目录,于是将windows中data目录中的ibdata1文件拷入进去,发现db_library_seats库中就有表和数据了(疑问:存储结构、触发器、表关联图、视图还在吗?不同版本的mysql能相互拷吗? 问了一个运维,他们平时都是怎样做数据库的迁移的,他们是先将 mysql的配置文件考入目标库,修改一下配置,然后再将要转移的库的数据目录,和ibdata1拷入,最后再启动数据库)。
总结:通过直接拷贝mysql的data目录中的 以库名命名的目录和ibdata1文件,可以实现将数据库的快速迁移,特别是数据量巨大的数据库,另外一个方式就是通过sql迁移数据库,这种方式当数据量太大时,效率会非常低!
待扩展:mysql集群和主从怎样弄?
step 2. 创建mysql的svc
apiVersion: v1
kind: Service #表示Kubernetes Service
metadata:
name: djmysql #Service的名称
spec:
type: NodePort
ports:
- port: 3306 #Service提供服务的端口号
targetPort: 3306
selector:
app: mysql #Service对应的Pod的标签
外面都可以访问:
疑问:怎样才能让mysql只能在集群内被访问?不想让外部访问
三、创建并修改configmap
#创建,这个以文件的形式创建的cm,共有4共方式创建,注意, --from-file 文件路径
kubectl create configmap cumulx-test --from-file=config.properties
#查看
kubectl get cm
kubectl get cm tom-mysql -o yaml
#修改,目前只能通过edit的形式来修改,但这种方式是危险的,很可能产生乱码
kubectl edit cm tom-mysql
四、编写web应用的deployment,并使用configmap
myweb.yaml
apiVersion: extensions/v1beta1 #接口版本
kind: Deployment #接口类型
metadata: #基础标签名称信息
name: library #创建的pod名称
namespace: default #创建的pod属于mt-math命名空间
spec: #详细参数设置
replicas: 1 #副本数量
selector: #标签选择器
matchLabels:
app: dj-library #正对标签为wyl-nginx的pod进行副本的创建
strategy:
rollingUpdate: #由于replicas为3,则整个升级,pod个数在2-4个之间
maxSurge: 1 #滚动升级时会先启动1个pod
maxUnavailable: 1 #滚动升级时允许的最大Unavailable的pod个数
template: #模板
metadata:
labels:
app: dj-library #模板pod名称必填
spec: #定义容器模板信息,该模板可以包含多个容器
containers:
- name: dj-library
image: 192.168.132.155:5000/myweb:v1.0 #by dong 最好写上前面的私有仓库地址,不然就会去公库拉(除非设置了镜像加速)
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 8080 #by dong 制作镜像时EXPOSE的8080,这里就必须使用8080
volumeMounts:
- name: tomcat-nfs
mountPath: /usr/local/tomcat/webapps/ROOT/WEB-INF/classes/config.properties
subPath: config.properties
volumes: #设置挂载
- name: tomcat-nfs #挂载的数据节点名称
configMap:
name: tom-mysql
注:特别注意subPath,cm和Volume挂载有什么区别?
踩坑记录:之前没有写subPath, mountPath只写到/usr/local/tomcat/webapps/ROOT/WEB-INF/classes/ 当pod起来进入pod查看到classes目录中只有一个文件了,即config.properties文件,其它的文件都被覆盖了。