前言

本文的一键部署,其实就是将部署流程化的命令转成shell脚本,当然,因为是发布到k8s集群上,所以发布的命令和需要的东西会有些不一样。本文的一键部署脚本是基于 打造一款适合自己的快速开发框架-持续部署之一键发布脚本设计与实现这篇文章进行改造的。所以建议大家先把该篇文章先看一篇。

知识准备

关于基础镜像制作

基础镜像一般可以直接使用openjdk: 8u212-jdk-alpine,但是直接使用的话,其功能还是不够,所以我们需要在其基础上进行加工。加入一些必要安装包。以及进行一些初始化工作。修改源地址

安装时tzdata-时区相关的包

ttf-dejavu和fontconfig,图片验证码需要该库

curl-简单的安装一个curl工具

tini- 正确注册了信号处理程序(比如 pid) ,如果不使用,容器中的服务默认pid都为1

ospd-netstat网络诊断工具

初始化springboot运行目录

修改一下默认时区

arthas 阿里巴巴开源的 Java 诊断工具 ,需要5中的tini配合

其他--暂时未考虑,希望大佬回复建议。

cat < /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

复制代码

build

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 .

复制代码

login

docker login -u _username -p password registry-vpc.cn-zhangjiakou.aliyuncs.com

复制代码

push

docker push registry-vpc.cn-zhangjiakou.aliyuncs.com/mldong/java/8u212-jdk-alpine-mldong:1.0

复制代码

关于服务镜像制作镜像制作使用Dockerfile文件定义

使用 openjdk: 8u212-jdk-alpine做为基础镜像

将jar包复制到容器

将配置文件复制到容器

定义外部访问端口

定义容器启动后运行命令(可不定义,由k8s的yaml的command去定义即可)

关于镜像版本号

​ 镜像版本号建议使用当前时间+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.jarjar包

├── k8s.tplk8s发布模板

├── 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

流程:编译打包

构建镜像

推送到私服

使用模板生成发布yaml

发布

#!/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

# 删除本地镜像

docker rmi $registry_url/$registry_ns/$project_name:$image_tag

if [ $? -ne 0 ]; then

echo "构建镜像推送到私服失败"

else

cat k8s.yaml

kubectl apply -f k8s.yaml

fi

fi

复制代码

验证结果

小结

本文以前段时间开源的快速开发框架为例,将之前的一键部署脚本修改成k8s。其实就之前的脚本来说,就是新增了打包镜像、推送私服、制作模板、发布的过程。也就是增加多几个命令而已。当然,真实的部署上可能还会有点小区别,比如可能模板的内容会多一点、也可能将该脚本转成jenikns的流水线。不过基本的原理都差不多,流程也大同小异。

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐