Gitlab实践-分支触发-部署到k8s

Posted by 聪少 on 2018-09-05

大家好,又来了!CICD系列文章写的有点乱,因为我自己也在摸索中!本文重点介绍gitlab在做cicd的时候如何通过分支来区分已经如何推送到k8s中!有些细节前面几篇文章已经解释过了,不过也有些地方介绍的含糊不清,请见谅!~ 下面我会简单介绍从项目建立开始一直到部署到k8s的过程(有些过程适当省略,可以看前几篇)!

创建一个工程

在gitlab上tfcloud组织中创建一个zeus的新工程,不用多介绍!看下图

new project

配置cicd

这里可以看前面文章的介绍,这里要注意的是tags我打了两个标签! develop,master

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@web-helm-5 ~]# gitlab-runner register
Running in system-mode.

Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
http://10.100.7.46:8088
Please enter the gitlab-ci token for this runner:
NUWMQhB-X36UDiYs4QFA
Please enter the gitlab-ci description for this runner:
[web-helm-5]: zeus
Please enter the gitlab-ci tags for this runner (comma separated):
develop,master
Registering runner... succeeded runner=NUWMQhB-
Please enter the executor: kubernetes, docker-ssh, virtualbox, docker+machine, docker-ssh+machine, docker, parallels, shell, ssh:
docker
Please enter the default Docker image (e.g. ruby:2.1):
golang:alpine
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!

因为我选择的是docker环境,所以我要在配置文件里加上docker相关信息,打开config.toml文件(文件目录根据实际情况而定))

1
vim /etc/gitlab-runner/config.toml

1
volumes = ["/cache"]

改为

1
volumes = ["/cache", "/var/run/docker.sock:/var/run/docker.sock"]

编写.gitlab-ci.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
### 这里我自己打了一个golang翻墙的镜像!可以不使用我这个。
image: imscc/alpine_go:sslocal

stages:
- build
# job名字,随意
daily-build:
stage: build # 此job属于哪个阶段
only: # 此job匹配哪个branch或者tag或者trigger
- develop #- <一个匹配日常分支的正则>
except:
- master # 此job忽略tag
# - triggers # 此job忽略trigger
script:
- echo "I'm develop" # job执行的脚本
tags:
- develop

# 大概意思同上
publish-build:
stage: build
only:
- master
except:
- develop
script:
- echo "I'm master !!!!"
tags:
- master

测试

下载工程到本地

1
2
git clone http://10.100.7.46:8088/tfcloud/zeus.git
cd zeus

创建develop分支

1
2
git branch  develop
git checkout develop

创建源文件

1
touch main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
touch main.go

package main

import (
"fmt"
"log"
"net/http"
)

func sayhelloName(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello Wrold!")
}

func main() {
http.HandleFunc("/", sayhelloName)
err := http.ListenAndServe(":9090", nil)
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}

提交develop分支

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
➜  zeus git:(develop) ✗ git branch develop
fatal: A branch named 'develop' already exists.
➜ zeus git:(develop) ✗ git add .
➜ zeus git:(develop) ✗ git status
On branch develop
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)

new file: main.go
new file: zeus

➜ zeus git:(develop) ✗ git commit -m "commit develop"
[develop 6a1c8a1] commit develop
2 files changed, 19 insertions(+)
create mode 100644 main.go
create mode 100755 zeus
➜ zeus git:(develop) git push origin develop
Counting objects: 4, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 3.08 MiB | 4.40 MiB/s, done.
Total 4 (delta 0), reused 0 (delta 0)
remote:
remote: To create a merge request for develop, visit:
remote: http://10.100.7.46:8088/tfcloud/zeus/merge_requests/new?merge_request%5Bsource_branch%5D=develop
remote:
To http://10.100.7.46:8088/tfcloud/zeus.git
c2ab533..6a1c8a1 develop -> develop

激动人心的时刻到了,去看下cicd是否触发!
commit develop
develop job
上图就是我们提并触发的!

下面我们合并一下代码到master,然后看下结果!!!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
➜  zeus git:(develop) git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
➜ zeus git:(master) git merge origin/develop
Merge made by the 'recursive' strategy.
main.go | 19 +++++++++++++++++++
zeus | Bin 0 -> 6473572 bytes
2 files changed, 19 insertions(+)
create mode 100644 main.go
create mode 100755 zeus
➜ zeus git:(master) git push origin master
Counting objects: 2, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 305 bytes | 305.00 KiB/s, done.
Total 2 (delta 1), reused 0 (delta 0)
To http://10.100.7.46:8088/tfcloud/zeus.git
d1fc152..95b4797 master -> master

master job

OK!!! 分支触发cicd基本上就到这里了!祝你好运!下面进行k8s部署环节!!!

部署

思考一下部署一个应用到k8s环境需要准备些什么?

  • 应用镜像
  • k8s授权操作
  • 服务配置文件
  • 部署脚本
  • kubectl

根据上述需求我们一步一步来!

应用镜像

具体细节我就不啰嗦了,可以参考前面都文章
Dockerfile:

1
2
3
4
5
6
7
8
FROM alpine:latest

MAINTAINER imscc<imscc@qq.com>

WORKDIR /httx/run/zeus/
COPY zeus /httx/run/zeus
EXPOSE 9090
CMD [ "./zeus" ]

k8s授权操作

我这里是最简单都做法,把k8s都config文件放到工程中,直接使用的,各位看官也可以将文件放到gitlab-runner的宿主机上!

服务配置文件

这个是k8s服务部署的基础,不懂的可以google一下如何部署一个简单的服务!
我这里直接上配置文件了!配置里面注意下面两个配置!这里我会根据不同的分支做不同的处理的(高亮的部分)!!!一个是运行空间!一个是版本号!!!

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
apiVersion: v1
kind: Service
metadata:
name: zeus-svc
namespace: RUN_ENV
spec:
type: NodePort
selector:
run: zeus
ports:
- protocol: TCP
# nodePort: 30020
port: 9090
targetPort: 9090
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: zeus
namespace: RUN_ENV
spec:
replicas: 3
template:
metadata:
labels:
run: zeus
spec:
containers:
- name: zeus
image: harbor.tf.cn/tfcloud/zeus:Image_Version
ports:
- containerPort: 9090

部署脚本

这个没啥好介绍的,说白了就一句话

1
kubectl apply -f kube_zeus.yml

kubectl

kubectl是操作k8s集群的工具,我这里使用的是docker中运行的,我自己打包了一个docker镜像
[地址] (https://github.com/shaocongcong/alpine)

回炉.gitlab-ci.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
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
image: imscc/alpine_go:sslocal

stages:
- build
- release
- deploy

# 编译develop分支
build-develop:
stage: build
only:
- develop
except:
- master
script:
- mkdir -p /go/src/github.com/$CI_PROJECT_NAMESPACE
- cd /go/src/github.com/$CI_PROJECT_NAMESPACE
- ln -s $CI_PROJECT_DIR
- cd $CI_PROJECT_NAME
# 写go的人都知道在编译的时候有时候会需要依赖,下载依赖的时候可能会背墙
# 所以我这里打包了一个shadowsocks的golang编译环境,不过前提是你已经部署了代理服务
# 配置shadowsocks代理
# - sslocal -s ip地址 -p 端口 -l 1080 -k 密码 -t 600 -m 加密协议 &
# - polipo &
# - export http_proxy=localhost:8123
# - export ALL_PROXY=$http_proxy
# - sleep 3
# - go get ./...
- go build -o zeus
- cd $CI_PROJECT_DIR
artifacts:
name: binary-files
paths:
- ./zeus
tags:
- develop
- master

# 编译master分支
build-master:
stage: build
only:
- master
except:
- develop
script:
- mkdir -p /go/src/github.com/$CI_PROJECT_NAMESPACE
- cd /go/src/github.com/$CI_PROJECT_NAMESPACE
- ln -s $CI_PROJECT_DIR
- cd $CI_PROJECT_NAME
# - sslocal -s ip地址 -p 端口 -l 1080 -k 密码 -t 600 -m 加密协议 &
# - polipo &
# - export http_proxy=localhost:8123
# - export ALL_PROXY=$http_proxy
# - sleep 3
# - go get ./...
- go build -o zeus
- cd $CI_PROJECT_DIR
artifacts:
name: binary-files
paths:
- ./zeus
tags:
- develop
- master

# 打包develop镜像
release-develop:
image: docker
stage: release
only:
- develop
except:
- master
script:
- echo "hi , release !"
- ls .
- docker info
# 这里的变量配置参考前面文章
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD https://harbor.tf.cn
# CI_COMMIT_SHA是提交的sha值,我用来做版本号了!
- docker build --pull -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
- docker rmi $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
tags:
- develop
- master

# 打包master镜像
release-master:
image: docker
stage: release
only:
- master
except:
- develop
script:
- echo "hi , release !"
- ls .
- docker info
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD https://harbor.tf.cn
- docker build --pull -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
- docker rmi $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
tags:
- develop
- master

# 部署develop环境
deploy-develop-kubernetes:
stage: deploy
image: imscc/alpine:latest
only:
- develop
except:
- master
script:
- mkdir /root/.kube
- cp ./config /root/.kube/
- kubectl cluster-info
# 这里一定要用双引号,不然$不会生效!
- sed -i "s/RUN_ENV/develop/g" kube_zeus.yml
- sed -i "s/Image_Version/$CI_COMMIT_SHA/g" kube_zeus.yml
- cat kube_zeus.yml
- kubectl apply -f kube_zeus.yml
tags:
- develop
- master

# 部署master环境
deploy-master-kubernetes:
stage: deploy
image: imscc/alpine:latest
only:
- master
except:
- develop
script:
- mkdir /root/.kube
- cp ./config /root/.kube/
- kubectl cluster-info
# 这里一定要用双引号,不然$不会生效!
- sed -i "s/RUN_ENV/master/g" kube_zeus.yml
- sed -i "s/Image_Version/$CI_COMMIT_SHA/g" kube_zeus.yml
- cat kube_zeus.yml
- kubectl apply -f kube_zeus.yml
tags:
- develop
- master

提交测试

在测试之前现在k8s环境创建测试空间

1
2
kubectl create namespace master
kubectl create namespace develop
1
2
3
4
5
6
7
8
9
10
11
12
➜  zeus git:(develop) git push origin  develop
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 284 bytes | 284.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0)
remote:
remote: To create a merge request for develop, visit:
remote: http://10.100.7.46:8088/tfcloud/zeus/merge_requests/new?merge_request%5Bsource_branch%5D=develop
remote:
To http://10.100.7.46:8088/tfcloud/zeus.git
7c035e8..ccaad31 develop -> develop

部署develop

1
2
3
4
5
6
7
➜  zeus git:(develop) kubectl get service -n develop
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
zeus-svc NodePort 10.43.106.4 <none> 9090:30020/TCP 5m

➜ zeus git:(develop) curl 10.100.7.45:30020

Hello Wrold!%

同样把代码合并到master上,看看效果

部署master

1
2
3
4
5
➜  zeus git:(master) kubectl get service -n master
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
zeus-svc NodePort 10.43.243.171 <none> 9090:31642/TCP 30s
➜ zeus git:(master) curl 10.100.7.45:31642
Hello Wrold!%

好了,本文基本结束!本篇文章是前面几篇的基础上总结了一下!要成功还是要认真看下前面几篇文章的,祝你好运!!!!