Jenkins slave

利用k8s去动态增减slave节点,运行一个job就创建一个pod作为jenkins slave,当job做完,就删除pod,这样就可以释放资源,大大减少成本。

设置JNLP访问协议

打开Jenkins/Configure Global Security,
找到Agents,如下图,设置Port 为 Random,Agent protocols选Inbound TCP Agent Protocol/4 (TLS encryption),保存

安装kubernetes plugins

打开Jenkins/Plugin Manager,搜索kubernetes并安装,结果如下:

安装这个插件时有可能提示jenkins版本不够,需要升级jenkins版本。jenkins大版本升级时需要注意,我这里是从jenkins-2.222.1升级到jenkins-2.222.4。小版本我这里就直接升级解决版本错误提示!

#下载离线包
rpm -Uvh jenkins-2.222.4-1.1.noarch.rpm

创建Kubernetes Namespace

kubectl create namespace devops

#查看创建后的命名空间
[root@kubemaster01 ~]# kubectl get ns
NAME              STATUS   AGE
default           Active   12d
devops            Active   11d
kube-node-lease   Active   12d
kube-public       Active   12d
kube-system       Active   12d

创建Service Account

在Kubernetes上为Jenkins构建创建有Cluster Admin权限的Service Account jenkins:

kubectl create clusterrolebinding jenkins --clusterrole cluster-admin --serviceaccount=devops:jenkins

注:上面语句–serviceaccount=devops:jenkins 这里是有点问题的。因为没有创建名为jenkins的serviceaccount。后面在构建时出现如下错误:

from server  is forbidden: User "system:serviceaccount:devops:default" cannot get resource "deployments" in API group "apps" in the namespace "devops"

修改一下:

 kubectl set subject clusterrolebinding jenkins --serviceaccount=devops:default

或者一开始创建语句就如下:

kubectl create clusterrolebinding jenkins --clusterrole cluster-admin --serviceaccount=devops:default

或者在这之前先创建名称为jenkins的serviceaccount


引申一下:
ServiceAccount:
ServiceAccount中主要保存的信息就是一个令牌(token),令牌格式就是JWT(json web token)。下面是从Kubernetes默认ServiceAccount中解码的PAYLOAD部分JWT内容:

{
  "iss": "kubernetes/serviceaccount",
  "kubernetes.io/serviceaccount/namespace": "default",
  "kubernetes.io/serviceaccount/secret.name": "default-token-7j4cw",
  "kubernetes.io/serviceaccount/service-account.name": "default",
  "kubernetes.io/serviceaccount/service-account.uid": "dde1fb85-d593-11e8-b939-e0d55ecb19d6",
  "sub": "system:serviceaccount:default:default" 
}

最后的sub由三个部分组成:

  • system:serviceaccount (用户所属的组)
  • default (namespace名称)
  • default (用户名称)

Kubernetes内置了几个特别的组:

  • system:unauthenticated 包括未认证的用户
  • system:authenticated 包括已经认证的用户
  • system:serviceaccounts 系统范围 serviceaccount中的所有用户
  • system:serviceaccounts: 特定名称空间范围内serviceaccount中的所有用户

当kubernetes集群搭建好后,系统中就存在多个ServiceAccount,它们隶属于不同的名称空间,不同名称空间之间的ServiceAccount名称可以相同。

[root@kubemaster01 ~]# kubectl get serviceaccounts
NAME      SECRETS   AGE
default   1         12d
[root@kubemaster01 ~]# kubectl get serviceaccounts --all-namespaces
NAMESPACE         NAME                                 SECRETS   AGE
default           default                              1         12d
devops            default                              1         11d
kube-node-lease   default                              1         12d
kube-public       default                              1         12d
kube-system       attachdetach-controller              1         12d
kube-system       bootstrap-signer                     1         12d
kube-system       calico-kube-controllers              1         12d
...

创建自己的ServiceAccount

[root@kubemaster01 ~]# kubectl create serviceaccount jenkins
serviceaccount/jenkins created

授权:
当认证通过,下一步要做的就是授权,授权决定一个用户可以干什么。Kubernetes可以配置多种授权方式,其中目前使用的是RBAC(Role Based Access Control)。RBAC涉及几个重要概念,它们是:

  • Role
  • RoleBinding
  • ClusterRole
  • ClusterRoleBinding

首先必须清楚一点:授权离不开认证,授权是基于ServiceAccount的。Role可以理解为权限(例如get,update,delete,add),它决定了ServiceAccount可以干什么,RoleBinding用于把Role绑定到指定的ServiceAccount。ClusterRole和ClusterRoleBinding的作用一样,不同的是,它们的作用域是整个集群,而Role和RoleBinding的作用域是namespace。

此次引申参考:https://www.sharpcode.cn/devops/kubernetes-authn-authz/


生成调度凭证

生成Kubernetes的 server certificate key和Client P12 Certificate File。
这个步骤主要是生成P12 Certificate File提供给jenkins Master去调用Kubenetes,具体步骤如下:
Kubernetes Master上,打开~/.kube/config文件,复制相对应的内容,运行以下命令分别生成生成ca.crt, client.crt, client.key

[root@kubemaster01 ~]# cat .kube/config

# 复制certificate-authority-data的内容,运行以下命令生成client.crt
echo "<certificate-authority-data>" | base64 -d > ca.crt
# 复制client-certificate-data的内容,运行以下命令生成client.crt
echo "<client-certificate-data>" | base64 -d > client.crt
# 复制client-key-data的内容,运行以下命令生成client.key
echo "<client-key-data>" | base64 -d > client.key

再根据前面步骤生成的ca.crt, client.crt和client.key来生成PKCS12格式的cert.pfx,以下命令运行时,需要输入4位以上的密码(这个密码在jenkins上配置时要用)

[root@kubemaster01 ~]# openssl pkcs12 -export -out cert.pfx -inkey client.key -in client.crt -certfile ca.crt
[root@kubemaster01 ~]# ls kube-cert/
ca.crt  cert.pfx  client.crt  client.key

在Jenkins上集成Kubernetes

将上面生成的cert.pfx下载下来,添加cert.pfx到Jenkins Global Credential

在Jenkins上配置Kubernetes Cloud

打开Manage Jenkins/Configure System, 找到Cloud ,点击Add a new cloud,选择Kubernetes。

  • 输入Name,比如kubernetes
  • 复制上面步骤生成的ca.crt文件内容到Kubernetes server certificate key
  • 输入上面创建的Kubernetes Namespace,devops
  • 选择刚刚配好的Credential
  • 点击“Test Connection”按钮测试Jenkins是否可以成功连接Kubernetes。
  • Pod Retention选择Never,这样每次Jenkins构建结束后(无论成功和失败)都会销毁Pod,达到动态创建和运行Jenkins Build Agent的目的


在Jenkins上配置Kubernetes Pod Template

点击 Add Pod Template,添加下面四个pod模板:

Jenkins_slave:

maven:

docker:

kubectl:

挂载卷:

创建声明式Pipeline,调用Jenkins Slave

pipeline {
  agent {
    node {
      label 'Jenkins_slave'
    }
  }
  stages {
  stage('Init') {
        steps{
            script{
                println "welcome to Nick learn"
            }
        }
    }
    stage('maven') {
            steps{
                script{
                container('maven') {
                  sh 'mvn -v'
                }
            }
        }
    }
  }
}

参考资料:https://blog.csdn.net/programer_bei/article/details/101289835#JenkinsKubernetes_56

文档更新时间: 2020-06-30 18:41   作者:子木