本文的一键部署,其实就是将部署流程化的命令转成shell脚本,当然,因为是发布到k8s集群上,所以发布的命令和需要的东西会有些不一样。本文的一键部署脚本是基于 打造一款适合自己的快速开发框架-持续部署之一键发布脚本设计与实现 这篇文章进行改造的。所以建议大家先把该篇文章先看一篇。
基础镜像一般可以直接使用openjdk: 8u212-jdk-alpine,但是直接使用的话,其功能还是不够,所以我们需要在其基础上进行加工。加入一些必要安装包。以及进行一些初始化工作。
cat <<EOF > /mldong/docker/8u212-jdk-alpine-mldong/Dockerfile # 指定基础镜像 FROM openjdk:8u212-jdk-alpine # 维护者信息 MAINTAINER mldong <524719755@qq.com> # 修改源地址和安装一些必要库 RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories / && apk --update add --no-cache tzdata ttf-dejavu fontconfig curl tini ospd-netstat && rm -rf /var/cache/apk/* / && mkdir -p /app && mkdir -p /app/config / && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime / && echo "Asia/Shanghai" > /etc/timezone # 安装arthas-这里是从另一个镜像复制过来,小技巧 COPY --from=hengyunabc/arthas:latest /opt/arthas /opt/arthas EOF 复制代码
docker build -f /mldong/docker/8u212-jdk-alpine-mldong/Dockerfile -t registry-vpc.cn-zhangjiakou.aliyuncs.com/mldong/java/8u212-jdk-alpine-mldong:1.0 . 复制代码
docker login -u _username -p password registry-vpc.cn-zhangjiakou.aliyuncs.com 复制代码
docker push registry-vpc.cn-zhangjiakou.aliyuncs.com/mldong/java/8u212-jdk-alpine-mldong:1.0 复制代码
镜像版本号建议使用当前时间+git版本
模板变量最主要的是镜像版本,不过为了做成通用模板,建议模板变量为:
参数 | 说明 |
---|---|
APP_NAME | 应用名 |
NAMESPACE | 命名空间 |
PROFILES | 环境定义(prod->生产,test->测试) |
IMAGE_URL | 镜像地址 |
IMAGE_TAG | 镜像版本 |
PORT | 对外端口 |
这里可能了不能叫做模板引擎吧,其实就简单将上述的变量替换一下,这里有两个方案。
方案一:使用sed
使用说明:
sed 's#模板变量1#值1#g;s#模板变量2#值2#g' 模板文件 > 生成的新文件 复制代码
例:
文件内容如下:
cat << EOF > test.tpl apiVersion: v1 kind: Namespace metadata: name: {{APP_NAME}}-nodeport namespace: {{NAMESPACE}}-{{PROFILES}} EOF 复制代码
生成模板
sed -e 's#{{APP_NAME}}#mldong-admin#g;s#{{NAMESPACE}}#mldong#g;s#{{PROFILES}}#test#g' test.tpl > test.yaml 复制代码
方案二:使用envsubst
通常我们需要获取某一个或者几个环境去替换系统中的某些变量,这种情况下我们只需使用sed去简单的替换掉即可,在这种场景中,sed就可以满足我们的需求,但是如果我们需要修改的变量较多,envsubst就排上用场了。
使用说明:
envsubst < 模板文件 > 生成的新文件 复制代码
例:
文件内容如下:
cat << EOF > test2.tpl apiVersion: v1 kind: Namespace metadata: name: ${APP_NAME}-nodeport namespace: ${NAMESPACE}-${PROFILES} EOF 复制代码
先定义环境变量
export APP_NAME=mldong-admin export NAMESPACE=mldong export PROFILES=test 复制代码
再执行envsubst命令生成模板
envsubst < test2.tpl > test2.yaml 复制代码
本文中使用的是sed的方式。
├── /java_projects 管理端接口 ├── mldong-admin ├── config └── application-test.yml ├── app.jar jar包 ├── k8s.tpl k8s发布模板 ├── Dockerfile 镜像定义文件 └── buildAndPublish.sh 重新构建项目并发布项目到k8s集群 └── source ├── back ├── mldong 源码根目录 ├── mldong-admin └── pom.xml ├── mldong-common └── pom.xml ├── mldong-generator └── pom.xml ├── mldong-mapper └── pom.xml 复制代码
/java_projects/mldong-admin/config/application-test.yml
测试环境配置(为了简单起见,这里暂时不考虑模板中加入mysql,使用的是小A同学上的数据库)
# jdbc 配置 jdbc.driver-class-name: com.mysql.cj.jdbc.Driver jdbc.url: jdbc:mysql://172.26.22.105:3306/mldong?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false&serverTimezone=Asia/Shanghai jdbc.username: u_mldong jdbc.password: D5fopH@B7Q jdbc.max-idle: 10000 jdbc.max-wait: 10000 jdbc.min-idle: 5 复制代码
/java_projects/mldong-admin/app.jar
这个jar包由源码编译后复制生成,打包镜像时需要在Dockerfile文件同一目录下
/java_projects/mldong-admin/Dockerfile
镜像定义文件
# 使用上述制作的基础镜像 FROM registry-vpc.cn-zhangjiakou.aliyuncs.com/mldong/java/8u212-jdk-alpine-mldong:1.0 # 维护者信息 MAINTAINER mldong <524719755@qq.com> # 创建应用目录 # RUN mkdir -p /app && mkdir -p /app/config # 进入工作目录 WORKDIR /app # 复制jar COPY app.jar . # 配置配置文件 COPY config/* . # EXPOSE 映射端口 EXPOSE 8080 # ENTRYPOINT 处理pid=1的问题 ENTRYPOINT ["/sbin/tini", "--"] # CMD 运行以下命令(如果yaml文件定义了command会被覆盖) CMD ["/bin/sh","-c","set -e && java -jar app.jar --spring.profiles.active=dev --server.port=8080"] 复制代码
/java_projects/mldong-admin/k8s.tpl
k8s服务部署模板
apiVersion: v1 kind: Namespace metadata: name: {{NAMESPACE}} --- apiVersion: v1 kind: Service metadata: name: {{APP_NAME}}-nodeport namespace: {{NAMESPACE}} spec: type: NodePort ports: - port: 8080 targetPort: 8080 selector: app: {{APP_NAME}} --- apiVersion: v1 kind: Service metadata: name: {{APP_NAME}} namespace: {{NAMESPACE}} spec: type: ClusterIP ports: - port: 8080 protocol: TCP targetPort: 8080 selector: app: {{APP_NAME}} --- apiVersion: apps/v1 kind: Deployment metadata: name: {{APP_NAME}} namespace: {{NAMESPACE}} spec: selector: matchLabels: app: {{APP_NAME}} replicas: 1 template: metadata: labels: app: {{APP_NAME}} spec: containers: - name: {{APP_NAME}} image: {{IMAGE_URL}}:{{IMAGE_TAG}} imagePullPolicy: IfNotPresent ports: - containerPort: 8080 name: port protocol: TCP command: ["/bin/sh"] args: ["-c", "set -e && java -jar app.jar --spring.profiles.active={{PROFILES}} --server.port=8080"] --- apiVersion: extensions/v1beta1 kind: Ingress metadata: annotations: name: {{APP_NAME}}-ingress namespace: {{NAMESPACE}} spec: rules: - host: {{HOST}} http: paths: - backend: serviceName: {{APP_NAME}} servicePort: 8080 path: / 复制代码
/java_projects/mldong-admin/buildAndPublish.sh
流程:
#!/bin/bash # 源码存放根目录 source_dir=/java_projects/source/back # 父工程目录 parent_dir=$source_dir/mldong # 需要打包的项目名称 project_name=mldong-admin # 项目部署目录 project_dir=/java_projects/$project_name # git仓库地址(使用ssh方式的,需要去配置部署公钥) git_url=git@gitee.com:mldong/mldong.git # 镜像仓库地址 registry_url=registry-vpc.cn-zhangjiakou.aliyuncs.com # 镜像仓库空间 registry_ns=mldong/java # 镜像仓库用户名 registry_username=username # 镜像仓库密码 registry_password=password # 生成的镜像地址 image_url=$registry_url/$registry_ns/$project_name # 服务绑定的域名 host=c.mldong.com # 环境定义 profiles=test if [ -d "$source_dir" ]; then echo "源码存放根目录${source_dir}已存在" else echo "源码存放根目录不存在,创建${source_dir}" cp -p $source_dir fi if [ -d "$parent_dir" ]; then echo "源码已存在,git pull" cd $parent_dir git pull else echo "源码不存在,git clone" git clone $git_url $parent_dir fi git_version=$(git rev-parse HEAD) echo "当前版本号:${git_version}" image_tag=`date +"%Y%m%d%H%M"_``git describe --tags --always` cd $parent_dir mvn clean package -B # 这里需要判断打包是否成功 if [ $? -ne 0 ]; then echo "打包失败" else # 复制jar包 cp -r -f $parent_dir/$project_name/target/$project_name.jar $project_dir/app.jar # 进入项目目录 cd $project_dir # 构建镜像 docker build -t $registry_url/$registry_ns/$project_name:$image_tag . # 登录私服 docker login -u $registry_username -p ${registry_password} $registry_url # 退送到私服 docker push $registry_url/$registry_ns/$project_name:$image_tag sed -e "s#{{APP_NAME}}#$project_name#g;s#{{NAMESPACE}}#$project_name-$PROFILES#g;s#{{PROFILES}}#$profiles#g;s#{{IMAGE_URL}}#$image_url#g;s#{{IMAGE_TAG}}#$image_tag#g;s#{{HOST}}#$host#g" k8s.tpl > k8s.yaml if [ $? -ne 0 ]; then echo "构建镜像推送到私服失败" else cat k8s.yaml kubectl apply -f k8s.yaml fi fi 复制代码