- 本实验基于开源软件建立了一个全流程的CICD环境,为实现devops落地提供最基本的解决方案。
- 对gitlab、jenkins进行详细安装部署及使用描述。
- 探索**从k8s到paas**。。。
一、CI/CD拓扑图
CI/CD实验机器:(本实验使用4台虚拟机完成)
应用 | 主机 | 配置 | 安装软件 |
---|---|---|---|
gitlab | vms24(192.168.26.24) | 2核4G | gitlab-ce-13.0.6-ce.0.el7.x86_64.rpm |
jenkins | vms25(192.168.26.25) | 2核4G | jdk-11.0.7_linux-x64_bin.rpm、jenkins-2.222.4-1.1.noarch.rpm、docker(使用默认安装或docker ce最新版本)、git、kubectl(版本与集群对应) |
docker registry | vms32(192.168.26.32) | 2核2G | docker 由于主机内存不够,将registry移到vms25 |
k8s-master | vms61(192.168.26.61) | 2核2G | k8s集群master |
k8s-worker1 | vms62(192.168.26.62) | 2核2G | k8s集群node-1 (启动) |
k8s-worker2 | vms63(192.168.26.63) | 2核2G | k8s集群node-2 (由于主机内存不够,此节点不启动) |
说明:
- 由于主机内存不够,k8s集群只启动master和worker1节点,worker2节点不启动。k8s版本v1.18.2。
- 客户端使用windows主机,安装Git客户端,使用
Git Bash
二、安装gitlab(vms24)
1、下载:https://packages.gitlab.com/gitlab/gitlab-ce
2、将下载的rpm(gitlab-ce-13.0.6-ce.0.el7.x86_64.rpm)上传到vms24
3、安装:[root@vms24 ~]# rpm -ivh gitlab-ce-13.0.6-ce.0.el7.x86_64.rpm
会发生错误,使用yum install安装:警告:gitlab-ce-13.0.6-ce.0.el7.x86_64.rpm: 头V4 RSA/SHA1 Signature, 密钥 ID f27eab47: NOKEY错误:依赖检测失败:
policycoreutils-python 被 gitlab-ce-13.0.6-ce.0.el7.x86_64 需要
[root@vms24 ~]# yum install gitlab-ce-13.0.6-ce.0.el7.x86_64.rpm
4、编辑/etc/gitlab/gitlab.rb,修改external_url的值为主机名或主机IP:external_url 'http://192.168.26.24'
5、初始化gitlab:[root@vms24 ~]# gitlab-ctl reconfigure
6、在浏览器地址栏输入192.168.26.24,
6.1 提示设置密码:(这里设置的root密码)
6.2 然后用root登录
7、创建project
7.1 点击create a project
7.2 项目名设置为project1,vaisibility设置为public
7.3 然后点击Create project
7.4 点击Clone
,可以看到git下载地址
可以看到,可以通过ssh的方式clone,也可以通过http的方式clone代码。
8、git客户端
8.1 下载:https://git-scm.com/downloads
8.2 安装并使用git windows客户端(linux客户端安装:yum install git)
新建目录并打开,右键选择Git Bash Here
8.3 通过http的方式克隆$ git clone
http://192.168.26.24/root/project1.git
进入到project1创建一个文件,内容为111,然后推送到仓库
$ cd project1/
$ echo 111 > index.html
$ git add .
$ git config --global user.name "test" #第一次使用时需要,按提示操作
$ git config --global user.email you@example.com #第一次使用时需要,按提示操作
$ git commit -m "111"
$ git push
输入用户名及密码。在gitlab查看项目变化
8.4 以ssh的方式clone$ rm -rf project1/
通过命令ssh-keygen -N “”生成密钥对
$ ssh-keygen -N ""
Generating public/private rsa key pair.
Enter file in which to save the key (/c/Users/swcode/.ssh/id_rsa):
Your identification has been saved in /c/Users/swcode/.ssh/id_rsa.
Your public key has been saved in /c/Users/swcode/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:ehhIh2XKR9oEEpFiGQo2AarnnpbatNH/wCEFvGqqK8M swcode@DESKTOP-SWCODE
The key's randomart image is:
+---[RSA 2048]----+
|+=B=o.= |
|*ooo.@ |
|+. *.= |
|. ..= |
|. ..o o S |
| oo. o = |
|.o+.. = . |
|+Eo+ . o |
|*== ... |
+----[SHA256]-----+
$ cat /c/Users/swcode/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7L0WG3fq+0X80eBwnj25RiobtFWGzDVG5CThM9qS9EwUuAIQCt41nPTcyJUCUoRbQkORr1wXxQK2TW7Y5QTPsA1GeJczTg6c9j63+7HKoLmQbdMtFxsP8aGb6mgXp8EZVpUvkFFn2iHyBQ6uqsdCB3xVA7Nh5dW//r4c1Syn+S6WMz51Cz3ec3qA3SsqZq22PEBdJTM2ITdw1/kSTsrgIr7vRrmyTrIhI1fu/IVIaL8jO4bAVRZptV2ckuduTEYOChHyazv0RFi6cH1oLcdpKwCs3dhNvHeiE/CFMxGidNnZDdm+oFnZL1AW2d2t4vBDBj1KYYMtoF5pvWiyI2Nhb swcode@DESKTOP-SWCODE
复制公钥的内容到:
- 初始时:
- 没有初始提示时:点击右上角
再左侧选择SSH keys
:(复制公钥内容)
以ssh的方式克隆,进入到project1,修改index.html的文件。(可以不用密码就可以上传了)
$ git clone git@192.168.26.24:root/project1.git
$ cd project1/
$ ls
$ echo 11111 > index.html
$ git add .
$ git commit -m "xxx"
$ git push
三、安装Jenkins(vms25)
1、下载:https://www.jenkins.io/
2、上传下载的rpm包(jenkins-2.222.4-1.1.noarch.rpm、jdk-11.0.7_linux-x64_bin.rpm)到vms25
3、安装[root@vms25 ~]# yum install jenkins-2.222.4-1.1.noarch.rpm -y
启动[root@vms25 ~]# /etc/init.d/jenkins start
这时启动失败,因为没安装jdk
4、安装jdk[root@vms25 ~]# yum install jdk-11.0.7_linux-x64_bin.rpm -y
再次启动jenkins[root@vms25 ~]# /etc/init.d/jenkins start
设置开机启动[root@vms25 ~]# chkconfig jenkins on
查看监听端口:[root@vms25 ~]# netstat -ntulp |grep 8080
5、在浏览器打开[http://192.168.26.25:8080/](http://192.168.26.25:8080/)
解锁 Jenkins:从服务器查看/var/lib/jenkins/secrets/initialAdminPassword
[root@vms25 ~]# cat /var/lib/jenkins/secrets/initialAdminPassword
2c9363e202aa4968a33d7c5778c06476
复制密码后,继续:
6、安装推荐的插件
点击
安装推荐的插件
(将所插件安装,有安装不成功的插件时可能需要多次重试,使之安装成功)
安装好之后跳转到注册页面:(如果没有跳转,需要刷新页面)
7、创建第一个管理员用户
输入如上信息,点击保存并完成
,跳转到:
点击保存并完成
:
点击重启。登录(如果没有出现登录页面,可刷新页面)
输入用户名和密码,点击登录。
8、安装git、kubectl、docker
- 安装
git
[root@vms25 ~]# yum install git -y
- 安装
kubectl
(版本需要与访问的k8s集群)从k8s集群获取
kubectl
版本
[root@vms61 ~]# rpm -qa |grep kubectl
kubectl-1.18.2-0.x86_64
安装
kubectl-1.18.2-0.x86_64
[root@vms25 ~]# yum install kubectl -y #默认安装最新版本
[root@vms25 ~]# yum remove kubectl #删除: kubectl.x86_64 0:1.18.3-0
[root@vms25 ~]# yum install kubectl-1.18.2-0.x86_64 -y #安装与k8s版本一致的``kubectl
验证访问:
#在vms61(k8s master)查看是否有访问用户,如果没有就需要添加
[root@vms61 ~]# ls /etc/kubernetes/pki
[root@vms61 ~]# cat /etc/kubernetes/pki/aa.csv
redhat,admin,1
redhat,tom,2
redhat,bob,3
#在vms25(jenkins主机)进行k8s集群访问测试
[root@vms25 ~]# kubectl -s="https://192.168.26.61:6443" --insecure-skip-tls-verify=true --username="admin" --password="redhat" get nodes
NAME STATUS ROLES AGE VERSION
vms61.example.com Ready master 46d v1.18.2
vms62.example.com NotReady worker 46d v1.18.2
vms63.example.com NotReady worker2 46d v1.18.2
- 安装
docker
参见后文
配置docker本地仓库
9、安装docker插件
- 点击
Manage Jenkins
- 选择
Manage Plugins
- 点击可选插件,在右上角过滤栏输入
docker
回车:
- 在搜索出来的所有插件里选择:
docker-build-step
、Docker
、Docker API
等docker相关插件
- 点击
直接安装
:
等待所有插件安装完成之后,点击返回首页
。
查看已安装插件:
10、配置jenkins管理docker
- 在docker镜像仓库主机(这里是vms25)添加启动配置项
tcp://0.0.0.0:2376
(用于jenkins调用docker API)在配置文件
/etc/sysconfig/docker
中OPTIONS
后增加-H tcp://0.0.0.0:2376 -H unix:///var/run/docker.sock
(docker v1.11后以systemd方式管理docker,默认没有创建配置文件,要按照以下方法进行编辑配置)
[root@vms25 ~]# systemctl status docker #获取启动配置文件
/usr/lib/systemd/system/docker.service
编辑配置文件,在
ExecStart=
一行中增加-H tcp://0.0.0.0:2376 -H unix:///var/run/docker.sock
[root@vms25 ~]# vi /usr/lib/systemd/system/docker.service
[root@vms25 ~]# systemctl daemon-reload
[root@vms25 ~]# systemctl restart docker
- 配置jenkins连接docker,点击
Manage Jenkins
,选择Configure System
在Docker Builder里输入tcp://192.168.26.32:2376
,点击Test Connection
:
确保高级
下面出现Connected to tcp://192.168.26.25:2376
,表示连接成功。
页面拉到最下面:
点击Cloud-Add a new cloud-docker
:
点击Docker Cloud details
,在Docker Host URI
里输入tcp://192.168.26.25:2376
,点击Test Connection
:
下面出现Version = 19.03.11, API Version = 1.40
,表示连接成功,点击最下面Save
保存。
11、创建任务
点击创建一个新任务
任务名输入k8sxx
,选择 Freestyle project
:
点击确定
后,页面跳转:
在构建触发器
里,选中触发远程构建 (例如,使用脚本)
,在身份验证令牌里输入一段字符串,这里输入123123,
记住并替换:JENKINS_URL
/job/k8sxx/build?token=TOKEN_NAME
替换为[http://192.168.26.25:8080/job/k8sxx/build?token=123123](http://192.168.26.25:8080/job/k8sxx/build?token=123123)
,这个将在gitlab里用到。
然后下拉,在构建
-增加构建步骤
里选择Execute shell
:
在Execute shell
里输入:
echo $USER
cd /zz
sudo rm -rf *
git clone http://192.168.26.24/root/project1.git
version=$(date +"%Y.%m.%d.%H.%M.%S")
name=192.168.26.25:5000/cka/nginx:$version
docker build -t $name project1
docker push $name
kubectl -s="https://192.168.26.61:6443" --insecure-skip-tls-verify=true --username="admin" --password="redhat" set image deployment/nginx nginx="$name" -n ns5
点击下方保存
按钮。
12、配置gitlab和Jenkins联动
- 在jenkins上做相关安全设置,点击
Manage Jenkins
- 在
授权策略
里,勾选匿名用户具有读权限
跨站点请求伪造保护
,jenkins低版本中可以直接在防止跨站点请求伪造
前面的勾去掉。高版本jenkins不能在页面禁用跨站请求伪造保护。禁用跨站请求伪造保护操作如下:修改jenkins的配置文件。
vim /etc/sysconfig/jenkins
JENKINS_JAVA_OPTIONS="-Djava.awt.headless=true -Dhudson.security.csrf.GlobalCrumbIssuerConfiguration.DISABLE_CSRF_PROTECTION=true"
配置后重启jenkins:
service jenkins restart
或/etc/init.d/jenkins restart
访问网页查看,如下图效果:
13、设置jenkins用户的sudo权限
在系统命令行里,设置jenkins用户的sudo权限,保证其可以无密码执行rm命令:
[root@vms25 ~]# vi /etc/sudoers.d/jenkins
jenkins vms25.example.com=(root) NOPASSWD: /bin/rm
jenkins加入到root组,然后重启jenkins:
[root@vms25 ~]# gpasswd -a jenkins root
正在将用户“jenkins”加入到“root”组中[root@vms25 ~]# /etc/init.d/jenkins restart
Restarting jenkins (via systemctl): [ 确定 ]
创建jenkins的工作目录/zz,并把所有者所属组设置为jenkins
[root@vms25 ~]# mkdir /zz
[root@vms25 ~]# chown jenkins.jenkins /zz
14、gitlab上相关配置
- 在gitlab页面最上面,点击扳手图标
- 点击左下侧
Settings
—>Network
(点击展开菜单中或在浮动菜单上点击)
- 展开Outbound requests,
勾选Allow requests to the local network from web hooks and services
:
点击Save changes
。
- 进入到
首页
,进入到project1项目页面,
点击左下角Settings
—> Webhooks
:
在URL
填写内容:
http://192.168.26.25:8080/job/k8sxx/build?token=123123
这其中URL的值是前面jenkins创建任务配置构建触发器
的时候保留的,往下拉下拉框到 SSL verfication
,点击Add webhook
,之后结果为:
至此,gitlab和jenkins的联动配置结束。
四、安装docker并配置本地仓库(vms32 或 vms25)
1、安装docker
- 配置yum
yum install -y yum-utils #安装yum管理工具
yum-config-manager --add-repo [https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo](https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo)
- 安装
yum list docker-ce --showduplicates|sort -r #查看版本
yum install docker-ce #安装最新版本
yum install docker -y #安装的是1.13.1版本
启动docker并设置开机自动启动,导入镜像
systemctl start docker
systemctl enable docker
或 systemctl enable docker --now
- 配置docker加速器-阿里云加速器
您可以通过修改daemon配置文件/etc/docker/daemon.json来使用加速器
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://5gce61mx.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
2、搭建镜像仓库
设置http方式访问仓库(默认是https访问)
[root@vms32 ~]# vi /etc/docker/daemon.json
{
"registry-mirrors": ["https://5gce61mx.mirror.aliyuncs.com"],
"insecure-registries": ["192.168.26.32:5000"]
}
[root@vms32 ~]# systemctl restart docker
下载镜像
[root@vms32 ~]# docker pull hub.c.163.com/library/registry:latest
[root@vms32 ~]# docker pull hub.c.163.com/library/nginx:latest
[root@vms32 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hub.c.163.com/library/registry latest 751f286bc25e 2 years ago 33.2MB
hub.c.163.com/library/nginx latest 46102226f2fd 3 years ago 109MB
创建容器作为docker镜像仓库
[root@vms32 ~]# docker run -d --name registry -p 5000:5000 --restart=always -v /myreg:/var/lib/registry hub.c.163.com/library/registry
[root@vms32 ~]# docker`` ps
3、在其他docker节点(vms25、vms61、vms62、vms63)设置http访问vi /etc/docker/daemon.json
{
"registry-mirrors": ["https://5gce61mx.mirror.aliyuncs.com"],
"insecure-registries": ["192.168.26.32:5000"]
}
systemctl restart docker
如果把vms32(docker镜像仓库)合到vms25上,则上面配置中的IP改为192.168.26.25:5000
五、实战演练
在k8s集群创建deployment、svc
[root@vms61 5-deployment]# kubectl create ns ns5
[root@vms61 5-deployment]# kubens ns5
[root@vms61 5-deployment]# vi dep.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx
spec:
replicas: 1
selector:
matchLabels:
pod-name: nginx
strategy: {}
template:
metadata:
labels:
pod-name: nginx
name: nginx
app: nginx
spec:
containers:
- image: nginx:1.7.9
imagePullPolicy: IfNotPresent
name: nginx
[root@vms61 5-deployment]# kubectl apply -f dep.yaml
[root@vms61 5-deployment]# kubectl get deployments.apps -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
nginx 1/1 1 1 8s nginx nginx:1.7.9 pod-name=nginx
[root@vms61 5-deployment]# kubectl expose deployment nginx --name=nginx --port=80 --type=NodePort
service/nginx exposed
[root@vms61 5-deployment]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx NodePort 10.96.149.129 <none> 80:30007/TCP 15s
在浏览器访问:http://192.168.26.61:30007
在client的机器上,clone下来的project1目录里,创建Dockerfile文件,内容如下:
$ git clone git@192.168.26.24:root/project1.git
$ cd project1/
$ vi Dockerfile
FROM docker.io/nginx
MAINTAINER testCICD
ADD index.html /usr/share/nginx/html/
EXPOSE 80
CMD ["nginx", "-g","daemon off;"]
$ echo "welcome to CICD! 33333" >index.html
$ git commit -m "33333"
$ git push
切换到jenkins,可以看到已经触发了编译
点击控制台输出
可以看到整个编译过程:
Started by remote host 192.168.26.24
Running as SYSTEM
Building in workspace /var/lib/jenkins/workspace/k8sxx
[k8sxx] $ /bin/sh -xe /tmp/jenkins544872612701596181.sh
+ echo jenkins
jenkins
+ cd /zz
+ sudo rm -rf project1
+ git clone http://192.168.26.24/root/project1.git
正克隆到 'project1'...
++ date +%Y.%m.%d.%H.%M.%S
+ version=2020.06.20.14.54.47
+ name=192.168.26.25:5000/cka/nginx:2020.06.20.14.54.47
+ docker build -t 192.168.26.25:5000/cka/nginx:2020.06.20.14.54.47 project1
Sending build context to Docker daemon 73.73 kB
Step 1/5 : FROM docker.io/nginx
---> 2622e6cca7eb
Step 2/5 : MAINTAINER testCICD
---> Using cache
---> 2f3e9064a62f
Step 3/5 : ADD index.html /usr/share/nginx/html/
---> 27d0e7be4d69
Removing intermediate container 93770fa4604e
Step 4/5 : EXPOSE 80
---> Running in b4dd5a9ef2e3
---> 0d5e799aa973
Removing intermediate container b4dd5a9ef2e3
Step 5/5 : CMD nginx -g daemon off;
---> Running in 880adccc18e7
---> 696851424492
Removing intermediate container 880adccc18e7
Successfully built 696851424492
+ docker push 192.168.26.25:5000/cka/nginx:2020.06.20.14.54.47
The push refers to a repository [192.168.26.25:5000/cka/nginx]
5c7aec829481: Preparing
f978b9ed3f26: Preparing
9040af41bb66: Preparing
7c7d7f446182: Preparing
d4cf327d8ef5: Preparing
13cb14c2acd3: Preparing
13cb14c2acd3: Waiting
9040af41bb66: Layer already exists
13cb14c2acd3: Layer already exists
d4cf327d8ef5: Layer already exists
f978b9ed3f26: Layer already exists
7c7d7f446182: Layer already exists
5c7aec829481: Pushed
2020.06.20.14.54.47: digest: sha256:4938108afb0fe18637319ce9f10c927371db37e54e642793162baf54344395db size: 1569
+ kubectl -s=https://192.168.26.61:6443 --insecure-skip-tls-verify=true --username=admin --password=redhat set image deployment/nginx nginx=192.168.26.25:5000/cka/nginx:2020.06.20.14.54.47 -n ns5
deployment.apps/nginx image updated
Finished: SUCCESS
在浏览器访问:http://192.168.26.61:30007/ 查看到信息已经修改了。
出现如下错误的处理:
docker进程使用Unix Socket而不是TCP端口。而默认情况下,Unix socket属于root用户,因此需要root权限才能访问。sudo groupadd docker #添加docker用户组
sudo gpasswd -a jenkins docker #将用户jenkins添加至docker用户组
newgrp docker #更新docker用户组
- 权限问题
[root@vms25 ~]# cat /etc/group |grep docker #查看docker用户组与用户
/etc/group 的内容包括用户组(Group)、用户组口令、GID及该用户组所包含的用户(User),每个用户组一条记录;格式如下group_name:passwd:GID:user_list
在/etc/group 中的每条记录分四个字段:
- 第一字段:用户组名称;
- 第二字段:用户组密码;
- 第三字段:GID
- 第四字段:用户列表,每个用户之间用,号分割;本字段可以为空;如果字段为空表示用户组为GID的用户名;
把jenkins用户加入到dockerroot用户组[root@vms25 ~]# gpasswd -a jenkins dockerroot #将登陆用户jenkins加入到docker用户组中
[root@vms25 ~]# newgrp dockerroot #更新用户组
重启jenkins[root@vms25 ~]# /etc/init.d/jenkins restart
- 普通用户使用docker的方法:添加用户组,将用户添加到组,重启docker即可
# groupadd docker
# groups
root
# usermod -a -G docker jenkins
# grep docker /etc/group
dockerroot:x:994:
docker:x:1001:jenkins
[root@localhost ~]# service docker restart
Redirecting to /bin/systemctl restart docker.service
[root@localhost ~]# sudo jenkins
[jenkins @localhost ~]$ docker image ls
至此,完美成功完成一个基本的CICD环境部署。