记录日常工作关于系统运维,虚拟化云计算,数据库,网络安全等各方面问题。

基于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

 

启用gitlabruby


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.yamlhostname) 。

管理员用户名/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 0ewoJImF1dGhzIjogewoJCSJodWIuc3guY29tIjogewoJCQkiYXV0aCI6ICJZV1J0YVc0NmFHRnlZbTl5TVRJek5EVT0iCgkJfQoJfSwKCSJIdHRwSGVhZGVycyI6IHsKCQkiVXNlci1BZ2VudCI6ICJEb2NrZXItQ2xpZW50LzE5LjAzLjggKGxpbnV4KSIKCX0KfQ==

 

在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、下载最新的

浏览器下载地址

gitlab-hook.hpi

gitlab-plugin.hpi


进入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。





转载请标明出处【基于Kubernetes+GitLab+Jenkins+动态slave-自动化项目部署】。

《www.micoder.cc》 虚拟化云计算,系统运维,安全技术服务.

网站已经关闭评论