环境准备 部署gitlab 1 docker run --detach --hostname 10.8.242.28 --publish 443:443 --publish 80:80 --publish 1022:22 --name gitlab --restart always --volume /srv/gitlab/config:/etc/gitlab --volume /srv/gitlab/logs:/var/log/gitlab --volume /srv/gitlab/data:/var/opt/gitlab gitlab/gitlab-ce:12.10.3-ce.0
替换hostname为实际节点外网IP
部署Harbor Harbor部署与管理 部署前先修改docker 编辑docker
1 2 3 4 vim /etc/docker/daemon.json { "insecure-registries" : ["0.0.0.0/0"] }
重启docker
1 systemctl restart docker
安装docker-compose
1 2 curl -L https://github.com/docker/compose/releases/download/1.24.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose
下载harbor
1 https://github.com/goharbor/harbor/releases/download/v1.10.2/harbor-online-installer-v1.10.2.tgz
配置harbo.yaml
1 hostname: 172.31.48.86 //修改为实际节点IP
屏蔽https配置
安装harbor
1 ./install.sh --with-clair
1 2 3 4 5 6 7 8 9 10 11 12 13 14 docker-compose ps Name Command State Ports --------------------------------------------------------------------------------------------- clair /docker-entrypoint.sh Up (healthy) 6060/tcp, 6061/tcp harbor-core /harbor/start.sh Up (healthy) harbor-db /entrypoint.sh postgres Up (healthy) 5432/tcp harbor-jobservice /harbor/start.sh Up harbor-log /bin/sh -c /usr/local/bin/ ... Up (healthy) 127.0.0.1:1514->10514/tcp harbor-portal nginx -g daemon off; Up (healthy) 80/tcp nginx nginx -g daemon off; Up (healthy) 0.0.0.0:80->80/tcp redis docker-entrypoint.sh redis ... Up 6379/tcp registry /entrypoint.sh /etc/regist ... Up (healthy) 5000/tcp registryctl /harbor/start.sh Up (healthy)
访问http://node_ip
admin/Harbor12345
Drone配置使用 Rancher应用商店已经提供了Drone的部署安装及配置,通过Rancher应用商店即可将Drone部署并配置对接
在gitlab上创建一个项目名为go-server,编写个应用 server.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 package main import ( "fmt" "log" "net/http" ) func hello(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello World") } func main() { http.HandleFunc("/", hello) if err := http.ListenAndServe(":8080", nil); err != nil { log.Fatal(err) } }
创建Dockerfile Dockerfile
1 2 3 4 FROM golang WORKDIR /go ADD server /go CMD ["./server"]
1、配置gitlab外部认证
回调接口填写其中一个节点的http://ip/login 如下
保存好对应的ApplicationID和secret
部署Drone
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 docker run \ --volume=/var/run/docker.sock:/var/run/docker.sock \ --volume=/var/lib/drone:/data \ --env=DRONE_LOGS_DEBUG=true \ --env=DRONE_GIT_ALWAYS_AUTH=false \ --env=DRONE_GITLAB_SERVER=http://114.215.25.58 \ --env=DRONE_GITLAB_CLIENT_ID=d6272993ac02c3bb4069d73bf0ff8dabeaff47c0739ae27d1a23e8b80e33faa5 \ --env=DRONE_GITLAB_CLIENT_SECRET=01f454fe0a55256a974d420b8ca023df6efc80b33d8a917dd16138b152b73253 \ --env=DRONE_RPC_SECRET=12345678\ --env=DRONE_RUNNER_CAPACITY=3 \ --env=DRONE_SERVER_HOST=114.215.130.36\ --env=DRONE_SERVER_PROTO=http \ --env=DRONE_TLS_AUTOCERT=false \ --publish=80:80 \ --publish=443:443 \ --restart=always \ --detach=true \ --name=drone \ drone/drone:1
参数说明:
参数
说明
DRONE_RPC_SECRET
runner连接server的凭证
DRONE_RUNNER_CAPACITY
server调用runner的并发数
DRONE_SERVER_HOST
server的ip
DRONE_SERVER_PROTO
server对外提供的协议可选http和https
部署Drone-runner 采用Docker的方式
1 2 3 4 5 6 7 8 9 10 11 12 docker run -d \ -v /var/run/docker.sock:/var/run/docker.sock \ -e DRONE_RPC_PROTO=http \ -e DRONE_RPC_HOST=172.31.227.147 \ -e DRONE_RPC_SECRET=12345678 \ -e DRONE_RUNNER_CAPACITY=3 \ -e DRONE_RUNNER_NAME=${HOSTNAME} \ -p 3000:3000 \ --restart always \ --name runner \ drone/drone-runner-docker:1
检查日志查看是否部署成功
在gitlab go-server项目创建名为.drone文件填入以下内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 kind: pipeline type: docker name: build steps: - name: build-code image: golang:alpine pull: if-not-exists # always never commands: - pwd - ls - go build server.go - ls - name: build-image image: plugins/docker settings: repo: 172.31.227.151/go-server/go-server registry: 172.31.227.151 use_cache: true username: from_secret: registry_username password: from_secret: registry_password tags: ${DRONE_BUILD_NUMBER} insecure: true mirror: https://yefnfc9c.mirror.aliyuncs.com/ trigger: branch: - master event: - push
连接镜像仓库的凭证环境变量可在Drone对应的项目中定义好
参数说明:
参数
说明
DRONE_RPC_PROTO
runner连接server协议
DRONE_RPC_HOST
server的地址
DRONE_RPC_SECRET
连接server的凭证
commit代码后会自动运行CI
Jenkins配置使用 应用概述
整体CICD流程
push code to trigger Gitlab webhook
compiling the code and build image
test
upload image to harbor
Generate a new YML file
deploy/upgrade
先决条件 1、clone front-end项目
1 git clone https://gitee.com/wanshaoyuan/front-end.git
2、并上传到内部gitlab上
3、在harbor中创建front-ent项目
4、在jenkins中安装好gitlab、docker、Kubernetes插件
5、部署sock-shap
1 git clone https://gitee.com/wanshaoyuan/microservices-demo.git
1 2 kubectl create namespace sock-shop kubectl apply -f microservices-demo/deploy/kubernetes/manifests/.
访问
Jenkins安装
1 docker run -itd --name jenkins -u root -p 50000:50000 -p 8080:8080 -v /var/jenkins_home:/var/jenkins_home -v /var/run/docker.sock:/var/run/docker.sock jenkins/jenkins:lts
节点安装git
获取jenkins密码
1 docker logs jenkins |grep password
安装推荐的Jenkins插件
Jenkins对接Gitlab 安装gitlab插件
Gitlab中申请AccessToken
将申请成功的token保存好
配置Jenkins对接gitlab
测试连接
测试
在gitlab中创建项目 上传个test.txt文件通过Jenkins读取
配置连接gitlab私有项目的密钥可以用ssh密钥也可以使用账号密码
构建
去cat这个文件输出内容
执行立即构建
输出结果
Jenkins对接Kubernetes 安装Kubernetes插件
Jenkins-CI对接Kubernetes 配置 系统管理—>系统设置—>新增一个云
配置Jenkins URL,这里我们没有配置api-server地址和证书key,连接kubernetes,所以默认会去读取放在JENKINS_HOME的.kube/目录的kubeconfig文件,用于连接集群。我这里是通过安装包的方式安装的Jenkins HOME在/var/lib/jenkins/目录,如果是通过容器方式启动,将kubeconfig文件直接放~/.kube/目录。
从RancherUI上复制配置文件
保存到Jenkins主机的config文件中 复制粘贴到Jenkins容器内的~/.kube/config文件中
1 2 docker exec -it jenkins mkdir /root/.kube/ docker cp config jenkins:/root/.kube/config
在编译集群对应项目下创建secret
在jenkins系统设置中创建一个Kubernetes云
演示效果
修改前,先展示前端。(https://github.com/microservices-demo/front-end)这里我们演示修改前端logo,然后git push到代码仓库,触发Jenkins进行cicd操作,修改front-end/public/navbar.html的<img src=”img/logo.png”为新的图片地址,然后将代码提交触发cicd重新打开前端看见logo变了。
创建cicd Pipeline 生成连接gitlab的凭证Grove语句
添加Harbor凭证
创建流水线任务
添加以下Pipeline任务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 pipeline { environment { registry = "172.31.227.151" project_name = "/front-end" app_name = "/front-end" registryCredential = 'harbor' } agent { kubernetes { defaultContainer 'wanshaoyuan/jnlp-slave:3.27-1-alpine' yaml """ apiVersion: v1 kind: Pod metadata: labels: some-label: some-label-value spec: containers: - name: jnlp image: 'wanshaoyuan/jnlp-slave:3.27-1-alpine' args: ['\$(JENKINS_SECRET)', '\$(JENKINS_NAME)'] - name : docker image: wanshaoyuan/docker:19.03.2 tty: true volumeMounts: - name: repo-docker-sock mountPath: /var/run/docker.sock - name: kubectl image: wanshaoyuan/jenkins-tools:v1.0 tty: true volumeMounts: - mountPath: "/root/.kube" name: "volume-0" readOnly: false volumes: - name: "volume-0" secret: secretName: "kubeconfig" - name: repo-docker-sock hostPath: path: /var/run/docker.sock """ } } stages { stage('clone code') { steps { git credentialsId: '9371d980-6bc2-47aa-a47f-04cf78871e7a', url: 'http://114.215.25.58/root/front-end.git' } } stage('image build ') { steps { container('docker') { script { docker.withRegistry( 'http://172.31.227.151', registryCredential ) { def dockerImage=docker.build registry + project_name + app_name +":$BUILD_NUMBER" dockerImage.push() } } } } } stage('deploy app ') { steps { container('kubectl') { sh 'sed -i "s/image: .*front-end:.*/image: 172.31.227.151\\/front-end\\/front-end:$BUILD_ID/g" front-end-dep.yaml' sh 'kubectl apply -f front-end-dep.yaml' } } } } }
定义环境变量:镜像仓库地址、项目名称、应用名称、连接镜像仓库的认证信息。
定义jnlp-agent POD所启动的container,包括jnlp容器,用于根jenkins进行通信,maven容器用于代码编译、docker 容器,用于容器镜像编译,kubectl容器用于连接对应的kubernetes集群用于应用创建和更新。
定义四个阶段,每个阶段定义对应的步骤,调用对应的容器实现功能(clone代码阶段、代码编译阶段、容器镜像构建阶段、应用部署阶段)
每个阶段调用对应的容器实现,如代码编译阶段调用编译容器进行、容器镜像构建阶段调用docker镜像映射宿主机socket进行。
配置gitlab自动触发Jenkins CICD
编辑jenkins项目 配置使用Build when a change is pushed to GitLab. GitLab CI Service URL: http://191.8.2.112:12000/project/test-go-dev
当代码有更新的时候触发,通过GitLab CI
打开gitlab,配置webhook回掉地址,填入jenkins对应项目地址 gitlab对应的项目设置页
默认触发器是push事件时,触发webhook,需要注意的是因为我们这里的Jenkins配置了用户名和密码所以 url需要在原来基础上添加用户名和密码其他不变 格式为http://username:password@192.168.1.4:1080/project/dashboard-build
默认测试webhook调用
默认一个代码commit的请求 下载logo放置
1 wget https://rancher.com/img/brand-guidelines/assets/logos/png/cow/rancher-logo-cow-blue.png
修改前端logo,然后git push到代码仓库,触发Jenkins进行cicd操作,修改front-end/public/navbar.html的<img src=”img/logo.png”为新的图片地址,然后将代码提交触发cicd重新打开前端看见logo变了。
Rancher-Pipeline配置使用 概述 Rancher2.x Pipeline支持在发布阶段直接将应用发布到应用商店,部署阶段直接从应用商店部署应用,以下为操作步骤
先决条件
提前创建好存放统一chart的目录目录结构如下: ./charts/app_name/version
将app_name和Version替换为实际应用名和版本号
CICD到应用商店流程 1 2 3 4 5 6 7 8 graph LR A[源码库]-- "Jenkins clone源码完成其他CI环节" --> B[clone catalog 模板并通过Jenkins修改模板] B -- "git push" --> C[push到统一存放catalog目录] C-- "Rancher-server自动同步更新" --> c[UI显示新版本可更新]
应用chart制作 继续使用go-server项目的例子
创建应用源码目录创建专属chart目录
目录结构如下
创建目录
1 mkdir /go-server/go-server-chart
在目录go-server-chartt内创建以下文件和文件夹
1 2 3 4 5 6 7 8 9 10 11 go-server-chart │ ├── 0 │ │ ├── Chart.yaml │ │ ├── questions.yml │ │ ├── templates │ │ │ ├── _helpers.tpl │ │ │ ├── go-server-dep.yaml │ │ │ └── go-server-svc.yaml │ │ └── values.yaml │ └── README.md
0表示版本文件夹,如果要发布新版本只需要创建个1或者另外文件夹,然后修改Chart.yaml文件里面的版本号。
README.md 内定义对应用的说明 Chart.yaml
1 2 3 4 5 apiVersion: v1 description: go-server name: go-server version: ${CICD_EXECUTION_SEQUENCE} icon: http://ohx02qrb8.bkt.clouddn.com/micheling.png
详细环境变量参考
1 https://rancher.com/docs/rancher/v2.x/en/k8s-in-rancher/pipelines/
定义软件的描述、名字、版本、图标地址
questions.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 questions: - variable: replicaCount default: "1" description: "Replica count" type: string required: true label: Replicas - variable: imageName default: "172.31.227.151/go-server/go-server" description: "image name" type: string required: true label: image_name - variable: imageTage default: "latest" description: "image version" type: string required: true label: image_version - variable: nodeport default: "30000" description: "NodePort port number(to set explicitly, choose port between 30000-32767)" type: string required: true label: nginx Service NodePort number
定义变量,主要与ui上对应 variable: 对应template里面的.Values.xxx值 default:当用户没有设置自定义值时的默认值 description: ui上用户自定义值的描述 type: 自定义值的数据类型 required: 是否必填 label:标签
values.yaml: values.yaml 则提供了这些配置参数的默认值。
templates :放置实际要执行的应用的yaml文件
go-server-dep.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 apiVersion: apps/v1 kind: Deployment metadata: labels: cattle.io/creator: norman workload.user.cattle.io/workloadselector: deployment-default-test name: test namespace: default spec: replicas: {{ .Values.replicaCount }} selector: matchLabels: workload.user.cattle.io/workloadselector: deployment-default-test template: metadata: labels: workload.user.cattle.io/workloadselector: deployment-default-test spec: containers: - image: {{ .Values.imageName }}:{{ .Values.imageTage }} imagePullPolicy: Always name: test ports: - containerPort: 8080 name: 8080tcp01 protocol: TCP stdin: true tty: true
go-server-svc.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 apiVersion: v1 kind: Service metadata: labels: cattle.io/creator: norman name: test-nodeport namespace: default spec: ports: - name: 8080tcp01 nodePort: {{ .Values.nodeport }} port: 8080 protocol: TCP targetPort: 8080 selector: workload.user.cattle.io/workloadselector: deployment-default-test type: NodePort
_helpers.tpl 定义一些系统通用的继承变量一般不需要,直接用默认就好。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 {{/* vim: set filetype=mustache: */}} {{/* Expand the name of the chart. */}} {{- define "name" -}} {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} {{- end -}} {{/* Create a default fully qualified app name. We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). */}} {{- define "fullname" -}} {{- $name := default .Chart.Name .Values.nameOverride -}} {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} {{- end -}}
同时创建实际的catalog目录 继续按上面方式创建一个go-server的chart应用,需要修改Chart.yaml文件这里就不能在用变量了,因为使用添加私有应用商店时是读取不出变量的,在源码库内的chart.yaml用变量是因为需要动态更新。
Chart.yaml
1 2 3 4 5 apiVersion: v1 description: go-server name: go-server version: v1.0 icon: http://ohx02qrb8.bkt.clouddn.com/micheling.png
然后push到代码仓库的chart项目
Pipeline配置 创建secret用于push时的代码仓库的帐号密码
如果push是ssh方式这里的secret就放置公钥
USERNAME和PASSWORD两个key
创建镜像仓库凭证用于上传镜像
选择代码库创建Pipeline
创建代码编译步骤
创建编译上传镜像步骤
创建发布应用模板步骤
类型选择Publish Catalog Template
Chart Folder:填写源码库内的chart的相对路径
Catalog Template Version:这里填写Rancher Pipeline环境变量根在代码库内chart目录Chart.yaml Version一致
Catalog Template Name:为你的catalog应用的名称,如果你是生成一个新的catalog。统一存放catalog目录没有这个应用则可以根据实际需求取名字,如果是在原有基础上更新则有已有的catalog,则用原目录名
运行Pipeline
catalog自动更新
对应代码目录下 .rancher-pipeline.yml
文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 stages: - name: cod_build steps: - runScriptConfig: image: golang:latest shellScript: go build server.go - name: image_build steps: - publishImageConfig: dockerfilePath: ./Dockerfile buildContext: . tag: go-server/go-server:${CICD_GIT_COMMIT} pushRemote: true registry: 172.31.227.151 env: PLUGIN_INSECURE: "true" PLUGIN_MIRROR: https://yefnfc9c.mirror.aliyuncs.com - name: update_catalog steps: - publishCatalogConfig: path: ./go-server-chart/0 catalogTemplate: go-server version: ${CICD_EXECUTION_SEQUENCE} gitUrl: http://114.215.25.58/root/chart.git gitBranch: master gitAuthor: root gitEmail: shaoyua@rancher.com envFrom: - sourceName: gitlab sourceKey: USERNAME targetKey: USERNAME - sourceName: gitlab sourceKey: PASSWORD targetKey: PASSWORD timeout: 60