一文读懂自动化容器化部署(git+jenkins+harbor+kubernetes)

一. 什么是自动化容器部署

  简单来说,就是我们只需要点一下(或者通过gitlab钩子触发),代码就会自动完成构建 -> 镜像生成 -> 容器化部署。比起传统部署来可以省去很多步骤,特别适合频繁变更的敏捷开发项目(其实容器化部署的项目最好都使用自动化,相当省事)。
  本文主要是对各个组件的理解和使用,具体的安装步骤不展开。都是个人的简单理解,希望大家多多指正。
  下图是自动化容器部署的流程图和运用的工具。
一文读懂自动化容器化部署(git+jenkins+harbor+kubernetes)

二. 什么是jenkins

  Jenkins是一个开源的、提供友好操作界面的持续集成(CI)工具,主要用于持续、自动的构建/测试软件项目、监控外部任务的运行。简单来说,就是它负责我们自动化部署的整个流程,不论是构建还是生产镜像,又或是部署,都由它来一手调控,通过不同的配置能够自动完成很多种事情。
  Jenkins常用的版本控制工具有SVN、GIT,常用构建工具有Maven、Ant、Gradle。

三. 什么是镜像和dockerfile

  传统的项目,比如jar包,需要放在主机上java -jar运行,比如war包,需要放在主机上,安装一个tomcat,然后startup.sh启动tomcat运行。这些传统部署有一个缺点,就是环境和部署包是分离开来的,类似JDK和tomcat的版本是固定在主机上的,假如我们要迁移至新主机,还要安装新环境并保证环境的版本一致,这样既费心又容易出错导致部署失败。
  于是Docker镜像应运而生,它其实就相当于一个可运行的部署包以及该部署包运行的环境,操作系统,配置参数等一切运行时需要的东西。该镜像可以在任何主机上启动运行,且环境保持一致,解决了传统部署的一些痛点。而容器,其实就相当于运行起来的镜像。
  dockerfile就是描述镜像要怎么生成的文件,一般包含了基础镜像(比如操作系统或tomcat等),启动参数和启动命令等。

四. 什么是harbor

  Harbor就是镜像仓库,可以对镜像进行存取。kubernetes可以通过docker pull 镜像仓库/项目名/镜像名:标签 的命令来拉取镜像,jenkins可以把构建好的镜像推到镜像仓库。其他常用的镜像仓库还有Docker hub等。

五. 什么是kubernetes和rancher

  Kubernetes 是一个可移植的、可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化,简称为k8s。简单来说,就是一个可以进行容器编排,实现容器自动化运维和管理的工具,上面说到容器就是运行的镜像,镜像就是包含环境的可部署单位,而容器单单运行起来是不够的,我们还需要负载均衡,服务发现,健康检查,失败重启等等的功能,k8s就是这样的一个平台。
  Rancher是一个开源的企业级容器管理平台。它包含了kubernetes,属于容器编排工具的上层。k8s对于容器的管理功能已经非常强大了,但是由于是通过命令行进行管理的,可视化展示能力比较差。Rancher有UI界面,通过UI可以方便的执行k8s的各种功能,并且能加上日志收集,多k8s集群管理和监控等多种功能。可以认为是k8s增强版。

六. 开始配置

1. 首先先创建一个jenkins项目

一文读懂自动化容器化部署(git+jenkins+harbor+kubernetes)
一文读懂自动化容器化部署(git+jenkins+harbor+kubernetes)

一文读懂自动化容器化部署(git+jenkins+harbor+kubernetes)
  首先是项目描述,Discard old builds是抛弃旧构建,一般建议配置(因为每个项目构建一次就好几百mb,磁盘压力大),Days to keep builds 是保存几天内的构建, Max # of builds to keep是构建的最大数量。

2. 配置git

一文读懂自动化容器化部署(git+jenkins+harbor+kubernetes)
  配置gitlab拉取代码的url,注意如果报红的话,一般来说是网络不通或是凭证不对,Authentication failed是凭证不对,点击add后可以输入gitlab的账号密码配置一份凭证。
一文读懂自动化容器化部署(git+jenkins+harbor+kubernetes)

3. 配置钩子

  提一下钩子就是webhook,就是提供给gitlab一个接口,让它推送事件告诉jenkins要开始自动化部署了。
一文读懂自动化容器化部署(git+jenkins+harbor+kubernetes)
  勾选Build when a change is pushed to GitLab. GitLab webhook URL,点击高级选项,再生成密钥,拿着URL和密钥就可以到gitlab上配置钩子了。
一文读懂自动化容器化部署(git+jenkins+harbor+kubernetes)
  进入gitlab的项目,点击左侧setting进入钩子配置的页面,填上jenkins那边拿到的URL和密钥填上,勾选Trigger点击保存,钩子就配置好了。要注意的是push events是每次代码推送都触发钩子,tag push event是只有标签推送才会触发钩子,一般来说都选择标签推送,防止过于频繁的进行构建,并且标签可以同时作为镜像标签方便区分每次构建的镜像。

4. 配置构建和镜像生成

一文读懂自动化容器化部署(git+jenkins+harbor+kubernetes)

#!/bin/bash
#harbor环境变量配置
export REGISTRY=harbor域名
export PROJECT=harbor项目名
export BUILD_IMAGE_NAME=镜像名称
#git_tag_name是gitlab钩子推送时的标签,一般也用来作为镜像的标签
export BUILD_IMAGE_TAG=${GIT_TAG_NAME}
export HORBOR_USERNAME=harbor账号
export HORBOR_PASSWORD=harbor密码
#镜像名称
export IMAGE_ADDRESS=${REGISTRY}/${PROJECT}/${BUILD_IMAGE_NAME}:${BUILD_IMAGE_TAG}

#根据Dockerfile制作镜像,并推送镜像到harbor
#开启docker服务
service docker start
#登录镜像仓库
docker login ${REGISTRY} -u ${HORBOR_USERNAME} -p ${HORBOR_PASSWORD}
#根据-f指定dockerfile,并根据dockerfile打包镜像,-t指定镜像名称
docker build -f ${WORKSPACE}/scripts/apollo-on-kubernetes/apollo-portal-server/Dockerfile -t ${IMAGE_ADDRESS} .
#镜像推送至仓库
docker push ${IMAGE_ADDRESS}
#删除镜像(为了减轻jenkins磁盘压力)
docker rmi -f  ${IMAGE_ADDRESS}

  点击add post step并选择execute shell,执行shell脚本来打包镜像。

5. 配置k8s推送

  Jenkins要支持k8s需要插件,一般主要有下面几种:
  Kubernetes Cli Plugin:该插件可直接在Jenkins中使用kubernetes命令行进行操作。
  Kubernetes plugin: 使用kubernetes则需要安装该插件
  Kubernetes Continuous Deploy Plugin:kubernetes部署插件,可根据需要使用
  通过点击Manage jenkins进入jenkins设置,然后点击manage plugins可以进行插件管理,大部分插件可以直接搜索安装,如果网络不支持,也可以通过插件网站,如https://mirrors.tuna.tsinghua.edu.cn/jenkins/(清华大学的镜像)或者官网https://plugins.jenkins.io/进行插件下载后再安装。
  再点击add post step并选择deploy to kubernetes(需要插件支持)。
一文读懂自动化容器化部署(git+jenkins+harbor+kubernetes)
  若没有凭证,需要从kubernetes集群中获取kubernetes config文件,点击集群后点击kubeconfig文件,然后将内容复制。
一文读懂自动化容器化部署(git+jenkins+harbor+kubernetes)
一文读懂自动化容器化部署(git+jenkins+harbor+kubernetes)
  在jenkins凭证那里点击add,kind选择kubeconfig,勾选enter directly,将之前复制的kubeconfig内容粘贴到content里,输入id和description方便辨识,然后保存。
一文读懂自动化容器化部署(git+jenkins+harbor+kubernetes)
  至此jenkins的配置就完成了,通过钩子或者点击立即构建就可以一键自动化容器部署了。
  注意:要先在harbor和k8s集群里创建好对应的命名空间和项目,yaml文件可以参考下面的示例,或者在Rancher里面手动部署服务,导出yaml,并删除一些时间及唯一id的参数。
一文读懂自动化容器化部署(git+jenkins+harbor+kubernetes)

七. dockerfile示例

一般的springBoot项目示例

# 基础镜像,这里一般是基础操作系统镜像(带JDK的centos之类)
FROM xxxxx/xxxx/docker-base-os-centos-jdk8:1.0.0
# 时区
ENV TZ Asia/Shanghai
# 将原项目的jar复制过来改个名字
ADD ${WORKSPACE}/src/webapp/target/webapp-1.0.0.jar server.jar
# 启动命令
ENTRYPOINT ["java","-jar","-Xms4000m","-Xmx4000m","-Xss256k","-Xmn200m","/server.jar"]

tomcat项目示例

# 基础镜像,这里是tomcat基础镜像,地址从镜像仓库获取
FROM xxxxx/xxxx//tomcat
# 时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
#将webapp下的文件全部删除
RUN rm -rf /usr/local/tomcat/webapps/*
#将target下的xx.war拷贝到/usr/local/tomcat/webapps/下
ADD ./src/target/javafw-1.0.war /usr/local/tomcat/webapps/ROOT.war
#端口
EXPOSE 8080
#设置启动命令
ENTRYPOINT ["/usr/local/tomcat/bin/catalina.sh","run"]

八. yaml文件示例

工作负载配置示例,deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    workload.user.cattle.io/workloadselector: deployment-web-admin-web
  name: admin-web
  namespace: web
spec:
  replicas: 1
  selector:
    matchLabels:
      workload.user.cattle.io/workloadselector: deployment-uac-web-admin-web
  strategy:
    rollingUpdate:
      maxSurge: 0
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        workload.user.cattle.io/workloadselector: deployment-web-admin-web
    spec:
      containers:
      - args:
        - --spring.profiles.active=test
# 镜像名,注意,git_tag_name为jenkins从gitlab获取的推送时的标签
        image: XXXXXXXXX/XXXXX/image-name:${GIT_TAG_NAME}
        imagePullPolicy: Always
        name: admin-web
        ports:
#容器端口
        - containerPort: 8081
          name: web-8081
          protocol: TCP
      restartPolicy: Always

集群服务(供集群内部访问),clusterlp-service.yaml:

# 对内暴露的端口
apiVersion: v1
kind: Service
metadata:
  annotations:
    field.cattle.io/targetWorkloadIds: '["deployment:web:admin-web"]'  # 配置命名空间和工作负载
  name: admin-web
  namespace: web
spec:
  ports:
  - name: web-8081-admin-web
    port: 8081
    protocol: TCP
    targetPort: 8081
  selector:
    workload.user.cattle.io/workloadselector: uac-web-admin-web
  type: ClusterIP

公共服务,端口暴露(供集群外部访问),nodeport-service.yaml:

# 对外暴露的端口
apiVersion: v1
kind: Service
metadata:
  annotations:
    field.cattle.io/targetWorkloadIds: '["deployment:web:admin-web"]'    # 配置命名空间和工作负载
  name: admin-web-nodeport
  namespace: web
spec:
  ports:
  - name: uac-web-8081
#对外暴露的端口
    nodePort: 8555
#容器内部端口
    port: 8081
    protocol: TCP
    targetPort: 8081
  selector:
    workload.user.cattle.io/workloadselector: deployment-web-admin-web
  type: NodePort

九. 常见问题记录

一般构建失败时,可以点击单次构建,点击console output来查看构建日志和失败原因。
一文读懂自动化容器化部署(git+jenkins+harbor+kubernetes)
一文读懂自动化容器化部署(git+jenkins+harbor+kubernetes)

  1. jenkins用spring-boot-maven-plugin构建出错:repackage failed: Unable to find main class
    https://blog.csdn.net/qq_35530005/article/details/109333356
上一篇:「Harbor」- HTTP status 504 Gateway Time-out @20210318


下一篇:docker容器3:Docker构建registry