一直有人说想了解微服务的自动化部署,今天它来了~

在微服务化的时代,自动化部署越来越成为企业的重中之重了,因为这样减少了人员的成本,开发人员将代码提交后,触发相关事件即可部署测试环境,甚至得到许可后部署到线上。这样,原先开发人员、运维人员等要做的事,通通不必再重复劳作了。这对于一个企业来说,leader比较在乎的一件事。今天讲解通过jenkins、gitlab、harbor、k8s来作简单的CI/CD平台,暂时未涉及到代码检测等。

4fd30c63db2b4ef1dfbdc0f6456f7a4e.png

环境:    ubuntu16.04    docker18.04    k8s1.13.x + 1. 准备 以上系统环境准备好,本文讲述的是用k8s来进行部署jenkins 2. 部署jenkins 新建部署脚本jenkins.yaml:

apiVersion: v1

kind: Service

metadata:

  name: jenkins-service

  namespace: default

  labels:

    app: jenkins

spec:

  type: NodePort

  ports:

  - port: 8080

    targetPort: 8080

    protocol: TCP

    nodePort: 30600

    name: jenkins

  - port: 30000

    targetPort: 30000

    nodePort: 30000

    protocol: TCP

    name: agent

  selector:

    app: jenkins

    tier: jenkins

---

apiVersion: apps/v1

kind: Deployment

metadata:

  name: jenkins-deployment

  labels:

    app: jenkins

spec:

  replicas: 1

  strategy:

    type: Recreate

  template:

    metadata:

      labels:

        app: jenkins

        tier: jenkins

    spec:

      containers:

      - name: jenkins

        image: jenkinsci/blueocean:latest

        imagePullPolicy: Always

        ports:

        - containerPort: 8080

          name: jenkins

        - containerPort: 30000

          name: agent

        volumeMounts:

        - mountPath: /var/jenkins_home

          name: jenkins-data

        - mountPath: /data/jenkins

          name: jenkins-log-path

      volumes:

      - name: jenkins-data

        hostPath:

          path: /home/demo/jenkins

      - name: jenkins-log-path

        hostPath:

          path: /data/jenkins

执行脚本: kubectl apply -f jenkins.yamlkubectl get pod 会看到部署成功的pod

a09f7fe5eb8325b2a79d596d539888e5.png

同时会看到一个service生成,映射端口到外部

0abd7ed20cac2230f22054dcff6ba07c.png

接下来通过页面访问该服务,首次打开后,会让输入一个admin的密钥,这一串字符可以在日志中找到,执行kubectl logs -f test-jenkins-c6bd58bf9-tgmsa即可,输入一串字符后,进入下一步,需要安装一些插件,在安装插件的时候,需要注意的是,选择jenkins的image不同,其所需安装的插件也是不一样的,有的可能image已经存在了。

具体请看:https://jenkins.io/zh/doc/book/installing/

安装完插件后,进入下一步,创建第一个账户,管理员账户,一般建议创建,方便后面使用,注:邮箱也需要填写。

完成以上后,我们进入正式界面:

e30fb8a8cc69729d97b477ed101a3ffe.png

第一步:点击系统管理--->插件管理,添加一些插件,这里有用到kubernetes的插件,故安装了kubernetes plugins,其他的可根据自行项目确定下载、安装。


第二步:点击系统管理--->系统设置

79e04986df7a0d5f0ab3520df13222ab.png

添加jenkins的地址以及邮件地址

第三步:拉动滚动框到最下面,新增一个云

0ad2a22b53861ea3db551ac5114658d3.png

这里我加了kubernetes的配置,为什么后面会讲。

第四步:新建任务

4f8ec17b83481a8b485de8e4dbc346c2.png

在触发器中新增规则,最下面要生成token。

第五步:

0b669b33cbaa3baf4215c23b7b58a40f.png

接下来就是选择与gitlab互动,gitlab的地址以及凭据,凭据可通过首页加上可访问gitlab的用户信息,脚本路径需要根据自身的Jenkinsfile路径情况填写。

第六步:

2617add0eaa9362fee34236985d1c2cc.png

如果启用全局安全,这个端口本身是50000,但由于k8s的默认nodePort范围是30000-32767,故可以修改在这区间内,比如:30000,这也是为什么上面创建时service的nodePort是30000了。

至此,jenkins环境配置完成

第七步:配置gitlab

9da25600dd96b99560b7d6119edd7b01.png

这里的url就是在新建任务时生成的Gitlab webhook,token就是上面截图生成的token,最后add webhook。

第八步:

关于Harbor,自己可以简单搭建一个harbor服务,找度娘问一下很多,此处略。

第九步:

新建Jenkinsfile文件,如果刚才的路径是在项目根目录,则直接在项目根目录下创建Jenkinsfile文件

def label = "mypod-${UUID.randomUUID().toString()}"

def k8sPodYaml = """

    apiVersion: "v1"

    kind: "Pod"

    metadata:

      labels:

        jenkins: "slave"

      name: "${label}"

    spec:

      containers:

      - env:

        - name: "CI_ENV"

          value: "YES"

        - name: "JENKINS_AGENT_WORKDIR"

          value: "/home/jenkins/agent"

        image: "jenkins/jnlp-slave"

        imagePullPolicy: "Always"

        name: "jnlp"

        resources:

          limits: {}

          requests: {}

        securityContext:

          privileged: false

        tty: false

        volumeMounts:

        - mountPath: "/home/jenkins/.kube"

          name: "volume-2"

          readOnly: false

        - mountPath: "/var/run/docker.sock"

          name: "volume-0"

          readOnly: false

        - mountPath: "/var/inference/config"

          name: "volume-1"

          readOnly: false

        - mountPath: "/usr/local/bin/kubectl"

          name: "volume-3"

          readOnly: false

        - mountPath: "/home/jenkins/agent"

          name: "workspace-volume"

          readOnly: false

        workingDir: "/home/jenkins/agent"

      nodeSelector: {}

      restartPolicy: "Never"

      volumes:

      - hostPath:

          path: "/var/run/docker.sock"

        name: "volume-0"

      - hostPath:

          path: "/home/leinao/.kube"

        name: "volume-2"

      - hostPath:

          path: "/home/leinao/inference-deploy/output_config"

        name: "volume-1"

      - emptyDir: {}

        name: "workspace-volume"

      - hostPath:

          path: "/usr/local/bin/kubectl"

        name: "volume-3"

"""

****************

下面是自己的任务构建项目时的逻辑,由于我们这块用了自己的框架写的编译逻辑,故比较简单的,这里不合适公开,但是逻辑都差不多,大家可自行编写。

这块解释上面的k8s的yaml,这个就是为了在k8s中启动一个pod,通过该pod来执行构建逻辑的过程。

到此,关于Jenkins结合harbor、gitlab、k8s来实现CI/CD结束了,有几点注意的地方:

    1. 如果jenkins是在容器中启动的一定要记得将这个端口(30000)暴露到外部,不然jenkins-master会不知道slave是否已经启动,会反复去创建pod直到超过重试次数。

    2. 如果提示Jenkins doesn’t have label jenkins-jnlp-slave,可能原因:

        1). 因为slave节点无法链接到jenkins节点开放端口50000导致

        2). 因为slave镜像中slave启动失败导致的

        3). 因为jenkins和k8s通信有延时导致超时jenkins会反复创建pod

        4). 因为slave pod启动失败

        5). 因为pipeline中指定的label与配置中的不一致导致

    3. 也可以通过Ingress暴露的方式来进行暴露。

Logo

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

更多推荐