基于Kubernetes+GitLab+Jenkins+动态slave-自动化项目部署
基于Kubernetes+GitLab+Jenkins+动态slave-自动化项目部署
科技在进步,技术在更新,革命就不停止。
一、部署流程
开发人员把做好的项目代码通过git推送到gitlab,然后Jenkins通过 gitlab webhook (前提是配置好),自动从拉取gitlab上面拉取代码下来,
然后进行build,编译、生成镜像、然后把镜像推送到Harbor仓库;然后在部署的时候通过k8s拉取Harbor上面的代码进行创建容器和服务,
最终发布完成,然后可以用外网访问。
部署流程如下:
(大佬的图,大概这个过程)
环境准备:
IP | 角色 |
172.25.0.30 | master1、Jenkins |
172.25.0.31 | node1、Gitlab |
172.25.0.32 | node2、Harbor、Jenkins-slave |
二、K8s 安装
1. 安装要求
在开始之前,部署Kubernetes集群机器需要满足以下几个条件:
² 一台或多台机器,操作系统 CentOS7.x-86_x64
² 硬件配置:2GB或更多RAM,2个CPU或更多CPU,硬盘30GB或更多
² 可以访问外网,需要拉取镜像,如果服务器不能上网,需要提前下载镜像并导入节点
² 禁止swap分区
2. 准备环境
角色色 | IP | k8s版本 |
k8s-master | 172.25.0.30 | kubernetes1.21.0 |
k8s-node1 | 172.25.0.31 | kubernetes1.21.0 |
k8s-node2 | 172.25.0.32 | kubernetes1.21.0 |
# 关闭防火墙
systemctl firewalld systemctl disable firewalld
# 关闭swap
swapoff /etc/fstab
# 根据规划设置主机名
hostnamectl set-hostname <hostname>
# 在master添加hosts
hostnamectl set-hostname <hostname>
# 在master添加hosts
>> /etc/hosts
# 将桥接的IPv4流量传递到iptables的链
> /etc/sysctl.d/k8s.conf
sysctl
# 时间同步
yum install ntpdate ntpdate pool.ntp.org
添加定时
crontab */20 * * * * /sbin/ntpdate pool.ntp.org > /dev/null >&1
3. 所有节点安装Docker/kubeadm/kubelet
Kubernetes默认CRI(容器运行时)为Docker,因此先安装Docker。
3.1 安装Docker
device-mapper-persistent-data \ lvm2
\ https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo
#yum install docker-ce -y
{: []} EOF
3.2 添加阿里云YUM软件源
> /etc/yum.repos.d/kubernetes.repo
3.3 安装kubeadm,kubelet和kubectl
由于版本更新频繁,这里指定版本号部署:
install kubelet-1.21.0 kubeadm-1.21.0 kubectl-1.21.0 enable kubelet
4. 部署Kubernetes Master
在172.25.0.30(Master)执行。
init \ .25.0.30 \ registry.aliyuncs.com/google_containers \ v1.21.0 \ .96.0.0/12 \ .244.0.0/16
安装1.21版本时报错发现coredns,无法下载
手动拉取
docker pull registry.aliyuncs.com/google_containers/coredns:1.8.0
重命名
docker tag registry.aliyuncs.com/google_containers/coredns:1.8.0 registry.aliyuncs.com/google_containers/coredns/coredns:v1.8.0
重新初始化
由于默认拉取镜像地址k8s.gcr.io国内无法访问,这里指定阿里云镜像仓库地址。
使用kubectl工具:
/.kube /etc/kubernetes/admin.conf /.kube/config : /.kube/config
nodes
5. 加入Kubernetes Node
在172.25.0.31/32(Node)执行。
向集群添加新节点,执行在kubeadm init输出的kubeadm join命令:
join .25.0.30:6443 amdbyn.a02my1ugmoblwy4q sha256:18462463a7db86052399e97b18efe3f12edc5999293abdccf7529669df0ad3fa
默认token有效期为24小时,当过期之后,该token就不可用了。这时就需要重新创建token,操作如下:
kubeadm token create
6. 部署CNI网络插件
https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
kubectl apply kube-flannel.yml
默认镜像地址无法访问,sed命令修改为docker hub镜像仓库。
kubectl apply https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
查看k8spod状态
kubectl pods kube-system NAME READY STATUS RESTARTS AGE coredns-545d6fc579-2cgr8 /1 Running 72s
7. 测试kubernetes集群
在Kubernetes集群中创建一个pod,验证是否正常运行:
create deployment nginx nginx expose deployment nginx NodePort pod,svc
访问地址:http://NodeIP:Port
三、部署gitlab
1、使用docker方式部署
docker run gitlab.xxx.cn \ :443 :80 :22 \ gitlab always /srv/gitlab/config:/etc/gitlab \ /srv/gitlab/logs:/var/log/gitlab \ /srv/gitlab/data:/var/opt/gitlab \ gitlab/gitlab-ce:latest
2、配置gitlab
按上面的方式,gitlab容器运行没问题,但在gitlab上创建项目的时候,生成项目的URL访问地址是按容器的hostname来生成的,也就是容器的id。
作为gitlab服务器,我们需要一个固定的URL访问地址,于是需要配置gitlab.rb
/srv/gitlab/config/gitlab.rb
# 配置http协议所使用的访问地址,不加端口号默认为80
external_url
# 配置ssh协议所使用的访问地址和端口
gitlab_rails[] gitlab_rails[]
gitlab默认使用的内存越来越大,我们需要优化一下
减少数据库内存大小
worker_processesworker_processes /srv/gitlab/config/gitlab.rb
减少数据库并发数
shared_buffersshared_buffers /srv/gitlab/config/gitlab.rb
max_worker_processesmax_worker_processes /srv/gitlab/config/gitlab.rb
配置sidekia并发数
max_concurrencymax_concurrency /srv/gitlab/config/gitlab.rb min_concurrencymin_concurrency /srv/gitlab/config/gitlab.rb
# 重启gitlab容器
gitlab
3、配置管理员passwd
默认管理员账号passwd:root 5iveL!fe,如果不过登陆,重新配置新passwd
1、进入容器
docker exec gitlab /bin/bash
启用gitlab的ruby
gitlab-rails console production
2、进入管理员用户
user User.where(id: ).first
3、更改password
user.password user.password_confirmation sxi
4、保存
user.save!
配置过程
4、访问gitlab
登陆,如下图所示:
账号:root password:abcd1234
四、部署harbor镜像仓库
注意:额外的还需要 安装docker
1、docker-compose 安装
docker-compose安装
https://github.com/docker/compose/releases/download/1.22.0/docker-compose- > /usr/bin/docker-compose
赋予权限:
ax /usr/bin/docker-compose
2、Harbor配置、ssl证书生产
1、下载包,这里是v2.2.3:
https://github.com/goharbor/harbor/releases/download/v2.2.3/harbor-offline-installer-v2.2.3.tgz
其他版本 :https://github.com/goharbor/harbor/releases
2、解压harbor
tar harbor-offline-installer-v2.2.3.tgz && harbor /usr/local/
3、配置并安装
准备配置文件:
harbor.yml.tmpl harbor.yml
配置harbor.yml
harbor.yml
配置域名
hub.sx.com /data/cert/server.crt /data/cert/server.key harbor12345 root123 /data/harbor
#创建目录
/data/{cert,harbor}
4、证书生成
/data/cert && /data/cert
生成ssl证书
genrsa server.key
输入两次相同的password即可:
创建证书请求csr
req server.key server.csr
按步骤 输入server.key password、国家如CN、省如BJ、城市如BJ、组织如sx、机构如:sx、hostname:hub.sx.com、邮箱123@qq.com。
备份ssl证书
server.key server.key.org
推出password,引导证书有password时,会有问题,需要解锁password
rsa server.key.org server.key
证书请求签名
x509 server.csr server.key server.crt
赋予权限
ax *
3、harbor安装
1、运行prepare文件
/usr/local/harbor ./prepare
2、执行脚本安装
./install.sh
4、登录访问
1、页面登录
域名绑定hosts
https://hub.**.com (hub.**.com为自己的机名harbor.yaml的hostname) 。
管理员用户名/password为 admin / harbor12345
登录后如下:
创建项目
项目ops主要是用来存放的jenkins镜像和jenkins-slave镜像;projectdemo主要存放部署项目的镜像,供k8s拉取。
如果你运行正常,查看容器会如下:
2、docker登录
所以节点配置hosts
.25.0.32 hub.sx.com >> /etc/hosts
dokcer登录
docker login https://hub.sx.com
账号password:admin / harbor12345
从官方文档提示,客户端要使用tls与Harbor通信,使用的还是自签证书,那么必须建立一个目录:/etc/docker/certs.d
在这个目录下建立签名的域名的目录,比如域名为hub.sx.com, 那么整个目录为: /etc/docker/certs.d/hub.sx.com, 然后把harbor的证书拷贝到这个目录即可。
创建目录
/etc/docker/certs.d/hub.sx.com
复制证书到域名目录下
rsync root@172.25.0.32:/data/cert/server.crt /etc/docker/certs.d/hub.sx.com/
登录测试
五、部署Jenkins-slave分布式环境
Jenkins的Master-Slave分布式架构主要是为了解决Jenkins单点构建任务多、负载较高、性能不足的场景。Master-Slave相当于Server和Agent的概念。
Master提供web接口让用户来管理job和Slave,job可以运行在Master本机或者被分配到Slave上运行构建。
一个Master(Jenkins服务所在机器)可以关联多个Slave用来为不同的job或相同的job的不同配置来。
这里可以直接使用我个人的slave镜像
xiaozhagn/jenkins-slave
一、Master-Slave文件下载:
链接: https://pan.baidu.com/s/1Hu5iul1BYZNe7fWTBBn49A password: sg9d
二、制作镜像
构建镜像
jenkins-docker
docker build jenkins-slave:latest .
构建成功
三、推送镜像到harbor
打标签
docker tag jenkins-slave hub.sx.com/ops/jenkins-slave
开始推送:
docker push hub.sx.com/ops/jenkins-slave
到了这里镜像推送已经完毕。
六、k8s部署Jenkins
1、创建nfs
master上操作:
yum install nfs-utils /data/nfs/jenkins
/etc/exports /data/nfs/jenkins .25.0.30/24(sync,rw,no_root_squash)
systemctl nfs rpcbind systemctl enable nfs rpcbind
其他节点操作:
yum install nfs-utils systemctl nfs && systemctl enable nfs
showmount .25.0.30
2、yaml部署jenkins
1、创建namespace,用于安装jenkins
kubectl create namespace jenkins
查看已经创建的namespace
kubectl namespace
2、创建 PV & PVC
jenkins-storage.yaml
v1 PersistentVolume jenkins jenkins 20Gi ReadWriteMany Retain hard nfsvers=4.1 /data/nfs/jenkins 172.25.0.30 PersistentVolumeClaim v1 jenkins jenkins ReadWriteMany 20Gi jenkins
#创建
-n:指定 namespace
Yaml文件指定了namespce 运行时可以不指定namespce
kubectl apply jenkins-storage.yaml jenkins
查看pv 、pvc
kubectl pv kubectl pvc jenkins
3、创建 ServiceAccount & ClusterRoleBinding
Kubernetes 集群一般情况下都默认开启了 RBAC 权限,所以需要创建一个角色和服务账户,设置角色拥有一定权限,
然后将角色与 ServiceAccount 绑定,最后将 ServiceAccount 与 Jenkins 绑定,
这样来赋予 Jenkins 一定的权限,使其能够执行一些需要权限才能进行的操作。
这里为了方便,将 cluster-admin 绑定到 ServiceAccount 来保证 Jenkins 拥有足够的权限。
jenkins-rbac.yaml
v1 ServiceAccount jenkins-admin jenkins jenkins ClusterRoleBinding rbac.authorization.k8s.io/v1 jenkins-admin jenkins jenkins ServiceAccount jenkins-admin jenkins ClusterRole cluster-admin rbac.authorization.k8s.io
#创建 RBAC
创建时记得指定namespace
kubectl apply jenkins-rbac.yaml jenkins
4、创建 Service & Deployment
这里开始部署 Jenkins 服务,创建 Service 与 Deployment,其中 Service 暴露两个接口 8080 与 50000。
而Deployment 里面要注意的是要设置上面创建的 ServiceAccount ,并且设置容器安全策略为“runAsUser: 0”
以 Root 权限运行容器,而且暴露8080、50000两个端口。
创建部署的yaml,对外暴露的端口是32000
jenkins-deployment.yaml
v1 Service jenkins jenkins jenkins NodePort http 8080 32000 jnlp 50000 jenkins apps/v1 Deployment jenkins jenkins jenkins jenkins jenkins k8s-master jenkins-admin jenkins jenkins/jenkinslts 0 true http jnlp 2Gi 512Mi LIMITS_MEMORY limits.memory 1Mi -Xmx$(LIMITS_MEMORY)m -XshowSettings:vm -Dhudson.slaves.NodeProvisioner.initialDelay=0 -Dhudson.slaves.NodeProvisioner.MARGIN=50 -Dhudson.slaves.NodeProvisioner.MARGIN0=0.85 -Duser.timezone=Asia/Shanghai data /var/jenkins_home data jenkins
参数说明:
² JAVA_OPTS: JVM 参数设置
² JENKINS_OPTS: Jenkins 参数设置
² 其它参数: 默认情况下,Jenkins 生成代理是保守的。例如,如果队列中有两个构建,它不会立即生成两个执行器。它将生成一个执行器,
并等待某个时间释放第一个执行器,然后再决定生成第二个执行器。Jenkins 确保它生成的每个执行器都得到了最大限度的利用。
如果你想覆盖这个行为,并生成一个执行器为每个构建队列立即不等待,所以在 Jenkins 启动时候添加这些参数:
-Dhudson.slaves.NodeProvisioner.initialDelay=0
-Dhudson.slaves.NodeProvisioner.MARGIN=50
-Dhudson.slaves.NodeProvisioner.MARGIN0=0.85
有了上面的部署文件后,再将 Jenkins 部署到 Kuberntes 中:
-n:指定应用启动的 namespace
部署
kubectl apply jenkins-deployment.yaml jenkins
部署发现pod一直为Pending
kubectl describe pod jenkins
发现以下错误:
错误一:
处理办法:
添加指定运行在node
k8s-master
错误二:
这个是我们的设置的资源过高导致,调整jenkins的资源大小设置
1Gi 512Mi
5、配置私有仓库的镜像下载与访问
对私有仓库的镜像下载与访问
node1上操作(之前登陆过harbor仓库的节点)
docker login hub.sx.com
#查看登陆凭据
# cat .docker/config.json |base64 -w 0
ewoJImF1dGhzIjogewoJCSJodWIuc3guY29tIjogewoJCQkiYXV0aCI6ICJZV1J0YVc0NmFHRnlZbTl5TVRJek5EVT0iCgkJfQoJfSwKCSJIdHRwSGVhZGVycyI6IHsKCQkiVXNlci1BZ2VudCI6ICJEb2NrZXItQ2xpZW50LzE5LjAzLjggKGxpbnV4KSIKCX0KfQ==
在Master上操作
#创建secret资源
registry-pull-secret.yaml
v1 Secret registry-pull-secret jenkins ewoJImF1dGhzIjogewoJCSJodWIuc3guY29tIjogewoJCQkiYXV0aCI6ICJZV1J0YVc0NmFHRnlZbTl5TVRJek5EVT0iCgkJfQoJfSwKCSJIdHRwSGVhZGVycyI6IHsKCQkiVXNlci1BZ2VudCI6ICJEb2NrZXItQ2xpZW50LzE5LjAzLjggKGxpbnV4KSIKCX0KfQ== kubernetes.io/dockerconfigjson
kubectl apply registry-pull-secret.yaml jenkins
#查看secret资源
kubectl secret
3、获取 Jenkins 生成的 Token
在安装 Jenkins 时候,它默认生成一段随机字符串,用于安装验证。这里访问它的安装日志,获取它生成的 Token 字符串。
(1)、查看 Jenkins Pod 启动日志
注意:这里“-n”指的是要 namespace,后面跟的 namespace 请替换成你jenkins 启动的 namespace
kubectl logs jenkins
(2)、查看日志中生成的 Token 字符串
查看日志,默认给的token为:
bf0c6fcb10b845239a06ff9362a6843c
4、访问Jenkins
访问:集群ip+ Nodeport
http://172.25.0.30:32000/jenkins/
按提示输入token
配置管理员password:
账号:admin password:admin
下一步,使用admin账号
保存完成
到这里已经进入jenkins
七、Jenkins、gitlab配置
一、安装k8s的相关插件
1、jenkins 设置中文显示
Plugin Manager,搜索 Localization: Chinese (Simplified),然后点击Install without restart
安装后如下:
2、安装项目插件
安装Kubernetes Continuous Deploy、Kubernetes、Gitlab Hook 、GitLab、Build Authorization Token、Pipeline: Stage Step、Pipeline: Basic Steps、Pipeline的插件
1、页面安装插件
2、手动上传安装
Gitlab 、gitlab hook安装不成功,手动安装
下载地址
https://updates.jenkins-ci.org/download/plugins/
Gitlab-hook Gitlab、下载最新的
浏览器下载地址
进入jenkins的系统设置->插件管理->高级->上传插件,把下载到本地文件的插件上传到jenkins的服务器进行安装
上传文件安装
重启jenkins的容器
docker (k8s_jenkins_jenkins容器)
二、构建项目
新建一个流水线
三、设置jenkins挂钩k8s的环境
“系统管理” -->“系统配置置”。找到cloud ,点击“separate configuration page.”,点击“新增一个云”,选择k8s,如果这边没有出现k8s,则代表你的插件没有安装成功,需要重新安装。
1、创建kubernets云
2、配置kubernets云
然后配置一下里面的内容,配置这Kubernetes 地址、空间名、Jenkins 地址两个地方。针对URL,可以采用kube-dns来做服务发现,
(kube-dns默认已经安装),不需要实际的ip地址进行输入。不过还得配置一下SSH密钥。
² Kubernetes 地址:https://kubernetes.default 或者 k8s的地址https://172.25.0.30:6443
² 空间名:jenkins (自己创建的空间名)
² Jenkins 地址:http://jenkins.jenkins.svc.cluster.local:8080
这里的格式为:服务名.namespace.svc.cluster.local:8080 或者你的jenkins IP地址 http://172.25.0.30:32000/
注意:这里的jenkins的地址,可以把开始配置Jenkins“实例配置”复制进去
我这里的镜像,它的访问地址是ip:port/jenkins
配置完毕后,测试链接k8s集群
结果Connected to Kubernetes v1.21.0
如果出现:
Error testing connection https://172.25.0.30:6443: java.io.FileNotFoundException: /root/.kube/config (No such file or directory)
那么你创建jenkins的认证的,并不是jenkins-admin
四、jenkins添加凭证
需要添加了两个凭证,一个是ssh,和k8s的凭证。这个可自行添加一下即可。这里要注意一下:凭证生成后,进入凭证里面会有一个自动生成的ID,
此ID需要在asp.net core项目中的Jenkinsfile里面配置。
Dashboard-->系统管理-->Manage Credentials-->全局-->添加凭据
root中的密钥时私钥id_rsa,把对应公钥id_rsa.pub配置到gitlab上
查看本地的私钥,没有手动生成
1、添加私钥认证
注意:id会自动生成
2、添加k8s认证
查看配置好的凭据
五、gitlab添加凭证
创建一个项目demo
添加ssh key
查看jenkins的公钥
Gitlab添加公钥
八、jenkins+gitlab挂钩
jenkins配置任务里面的内容并且与gitlab挂钩
进入项目
1、test项目配置。
配置触发器
点击高级
生成token
流水线配置
当然deploy的目录必须存在你的代码根目录下
配完毕保存
2、配置gitlab
我的gitlab的最新的,界面配置不一样,所以我直接配置webooks
进入我demo项目
创建webhooks
Setting-->webhooks
添加URL、Secret token
哪里找,他们都在jenkins的test项目可以看到
URl:http://172.25.0.30:32000/jenkins/project/test Secret token:c07ebaae20ced8e74c8c0d93890708b0
3、配置添加webhook报错处理
处理
进入Menu-->Admin-->setting-->network--> Outbound requests
重新添加
测试是否成功
点击test-->Push events
九、部署代码
1、拉去测试代码,修改并推送到demo
测试项目地址
https://github.com/xiaozhagn/jenkinsfiles.git
注:Jenkinsfile里面这两个地方需要配置为你们在Jenkins里面创建的两个授权的ID,ID内容可以进入到凭证里面看。我这里使用sh代替 kubernetsconfig
拉去到代码到本地,deploy目录下
修改Jenkinsfile
deploy.yaml修改镜像地址(我这里是域名,如果jenkins访问不了,需要配置hosts)
查看deploy.yaml
推送到gitlab
2、查看jenkins任务是否已经触发并构建成功
可以发现都已经成功了
查看输入日志
查看pod是否已经起来了
3、访问测试
页面访问
到这里整个构建过程就完成了
十、jenkins报错以及处理
1、报错一:
Failed to connect to http://jenkins.jenkins.svc.cluster.local:8080/jenkins/tcpSlaveAgentListener/: jenkins.jenkins.svc.cluster.local
这里是kubernetss、cdns解析失败导致,重新构建flannel cni网络
kubectl delete kube-flannel.yml kubectl create kube-flannel.yml
继续报错
直接删除cdns pod
kubectl pods kube-system |grep coredns |xargs kubectl delete kube-system
编辑coredns部署yaml文件
kubectl edit deploy coredns kube-system
把
image: registry.aliyuncs.com/google_containers/coredns/coredns:v1.8.0
改为
image: registry.aliyuncs.com/google_containers/coredns:1.8.0
wq保存退出
2、报错二:
Illegal tunneling parameter: http://jenkins.jenkins.svc.cluster.local:50000
解决办法:这个是配置Jenkins 通道导致的,说这个选择配置为空就好
3、报错三:
with name:[null] in namespace:[kube-ops] failed.
解决办法:这个需要看一下的rbac时是否给对应的account账号对应的namespace权限
4、报错四:
ERROR:ERROR:java.lang.RuntimeException:io.kubernetes.client.openapi.ApiException: Bad Request
Caused by: hudson.remoting.ProxyException: io.kubernetes.client.openapi.ApiException: Bad Request
解决办法:
这个错误是通过config凭据无法调用kubernetes API接口,导致Bad request,所以在动态slave 里面挂在kubectl 与config文件,
在pipfile文件里面,我们直接通过执行shell,来调用k8s创建pod。
目录 返回
首页