Jenkins+GitLab+Docker+SpringCloud+Kubernetes实现可持续自动化微服务

编辑:Discuz论坛 发布于2019-07-10 09:21

  现有混合云平台的场景下,即有线下和线上的环境,又有测试与正式的场景,而且结合了Docker,导致打包内容有所区分,且服务的发布流程复杂起来,手工打包需要在编译阶段就要根据环境到处更改配置,因此纯手工发布增加了实施的难度,需要一个统一的适应各种环境部署的方案。

基于微服务的发布流程

  手动/自动构建 -> Jenkins 调度 K8S API ->动态生成 Jenkins Slave pod -> Slave pod 拉取 Git 代码/编译/打包镜像 ->推送到镜像仓库 Harbor -> Slave工作完成,Pod 自动销毁 ->部署到测试或生产 Kubernetes(K8S)平台。

  上面是理想状况下的将服务编译打包成镜像上传到镜像库后部署到Kubernetes平台的一个流程,但问题是:

  1. 我们有线上线下平台,代码在线下GitLab,是出不了外网的,因此线上K8S集群无法拉取代码编译。
  2. Jenkins的master所在服务器是CentOS6.5,没有Docker环境,也没有在K8S集群服务器内,因此无法直接执行docker build镜像和 kubectl apply 发布服务到K8S集群。
  3. Jenkins的slave节点都是无法访问外网的,
  4. 线上服务需要Pinpoint而线下环境暂时不需要启用Pinpoint,否则一直报错,因此需要根据选择的环境动态的构建Dockerfile,而且要求整个发布流程可选择。

就上面现实问题,我们将发布流程简化:

关键点:

Docker镜像的打包使用com.spotify的docker-maven-plugin插件结合Dockerfile,调用远程服务器的Docker环境生成镜像。

K8S服务部署采用的是ssh方式,将Deployment文件上传到K8S集群服务器,然后执行部署命令。

如何利用Dockerfile打包镜像

  之前也是用com.spotify的docker-maven-plugin插件来打包镜像并推送到私有镜像仓库,但问题是无法根据环境写条件判断,如动态选择是否需要启动pinpoint,线上线下库地址动态更换,导致镜像名前缀也是要动态变化的,此时直接配置无法满足,需要结合Dockerfile来实现。

先更改pom文件,指定本项目的Dockerfile文件地址,默认是放在项目根目录下:

           <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <version>1.2.0</version>
                <configuration>
                    <!--覆盖相同标签镜像-->
                    <forceTags>true</forceTags>
                    <!-- 与maven配置文件settings.xml一致 -->
                    <serverId>nexus-releases</serverId>
                    <!--私有仓库地址 -->
                    <registryUrl>https://${docker.repostory}</registryUrl>
                    <!--远程Docker地址 -->
                    <dockerHost>http://10.3.87.210:2375</dockerHost>
                    <!-- 注意imageName一定要是符合正则[a-z0-9-_.]的,否则构建不会成功 -->
                    <!--指定镜像名称 仓库/镜像名:标签-->
<imageName>${docker.repostory}/${project.artifactId}:${project.version}</imageName>
                    <dockerDirectory>${project.basedir}</dockerDirectory>
                    <resources>
                        <resource>
                            <!-- 指定要复制的目录路径,这里是当前目录 -->
                            <!-- 将打包文件放入dockerDirectory指定的位置 -->
                            <targetPath>/app/</targetPath>
                            <!-- 指定要复制的根目录,这里是target目录 -->
                            <directory>${project.build.directory}</directory>
                            <!-- 指定需要拷贝的文件,这里指最后生成的jar包 -->
                            <include>${project.build.finalName}.jar</include>
                        </resource>
                    </resources>
                </configuration>
            </plugin>