k8s部署jenkins,并且配置动态生成slave
一. 部署jenkins
1.deploy.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: jenkins2
namespace: kube-ops
spec:
selector:
matchLabels:
app: jenkins2
template:
metadata:
labels:
app: jenkins2
spec:
terminationGracePeriodSeconds: 10
serviceAccount: jenkins2
containers:
- name: jenkins
image: jenkins/jenkins:lts
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
name: web
protocol: TCP
- containerPort: 50000
name: agent
protocol: TCP
resources:
limits:
cpu: 1000m
memory: 1Gi
requests:
cpu: 500m
memory: 512Mi
livenessProbe:
httpGet:
path: /login
port: 8080
initialDelaySeconds: 60
timeoutSeconds: 5
failureThreshold: 12
readinessProbe:
httpGet:
path: /login
port: 8080
initialDelaySeconds: 60
timeoutSeconds: 5
failureThreshold: 12
volumeMounts:
- name: jenkinshome
subPath: jenkins2
mountPath: /var/jenkins_home
securityContext:
fsGroup: 1000
volumes:
- name: jenkinshome
persistentVolumeClaim:
claimName: opspvc
---
apiVersion: v1
kind: Service
metadata:
name: jenkins2
namespace: kube-ops
labels:
app: jenkins2
spec:
selector:
app: jenkins2
type: NodePort
ports:
- name: web
port: 8080
targetPort: web
nodePort: 30002
- name: agent
port: 50000
targetPort: agent
2.创建ns
kubectl create namespace kube-ops
3.创建pvc
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: opspvc
namespace: kube-ops
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 20Gi
4.创建rbac
另外我们这里还需要使用到一个拥有相关权限的 serviceAccount:jenkins2,我们这里只是给 jenkins 赋予了一些必要的权限,当然如果你对 serviceAccount 的权限不是很熟悉的话,我们给这个 sa 绑定一个 cluster-admin 的集群角色权限也是可以的,当然这样具有一定的安全风险:(rbac.yaml)
apiVersion: v1
kind: ServiceAccount
metadata:
name: jenkins2
namespace: kube-ops
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: jenkins2
rules:
- apiGroups: ["extensions", "apps"]
resources: ["deployments"]
verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
- apiGroups: [""]
resources: ["services"]
verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["create","delete","get","list","patch","update","watch"]
- apiGroups: [""]
resources: ["pods/exec"]
verbs: ["create","delete","get","list","patch","update","watch"]
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get","list","watch"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: jenkins2
namespace: kube-ops
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: jenkins2
subjects:
- kind: ServiceAccount
name: jenkins2
namespace: kube-ops
5.排错
创建pod后可能会报权限错误,这是因为默认的镜像使用的是 jenkins 这个用户,而我们通过 PVC 挂载到 nfs 服务器的共享数据目录下面却是 root 用户的,所以没有权限访问该目录,要解决该问题,也很简单,我只需要在 nfs 共享数据目录下面把我们的目录权限重新分配下即可:
chown -R 1000 /data/k8s/jenkins2
等到服务启动成功后,我们就可以根据任意节点的 IP:30002 端口就可以访问 jenkins 服务了,可以根据提示信息进行安装配置即可:
初始化的密码我们可以在 jenkins 的容器的日志中进行查看,也可以直接在 nfs 的共享数据目录中查看:
cat /data/k8s/jenkins2/secrets/initAdminPassword
然后选择安装推荐的插件即可。
二. 配置
接下来我们就需要来配置 Jenkins,让他能够动态的生成 Slave 的 Pod。
1.安装kubernetes plugin
点击 Manage Jenkins -> Manage Plugins -> Available -> Kubernetes plugin 勾选安装即可。
2.填写 Kubernetes 和 Jenkins 配置信息
注意 namespace,我们这里填 kube-ops,然后点击Test Connection,如果出现 Connection test successful 的提示信息证明 Jenkins 已经可以和 Kubernetes 系统正常通信了,然后下方的 Jenkins URL 地址:http://jenkins2.kube-ops.svc.cluster.local:8080,格式为:服务名.namespace.svc.cluster.local:8080
3.配置 Pod Template
其实就是配置 Jenkins Slave 运行的 Pod 模板,命名空间我们同样是用 kube-ops,Labels写slave-jnlp, 这里的标签也非常重要,对于后面执行 Job 的时候需要用到该值
首先构建slave自定义镜像
Dockerfile文件内容如下, 镜像中包含了docker, kubectl命令
FROM jenkins/inbound-agent:4.11-1-jdk11
LABEL AUTHOR HONG
COPY kubectl /usr/local/bin/kubectl
USER root
RUN apt-get update \
&& apt upgrade -y \
&& apt install -y curl vim wget gnupg apt-transport-https lsb-release ca-certificates \
&& wget -O /usr/share/keyrings/docker.asc http://mirrors.aliyun.com/docker-ce/linux/debian/gpg \
&& echo "deb [signed-by=/usr/share/keyrings/docker.asc] http://mirrors.aliyun.com/docker-ce/linux/debian $(lsb_release -sc) stable" > /etc/apt/sources.list.d/docker.list \
&& apt update -y \
#&& apt-cache madison docker-ce \
&& apt-get install -y docker-ce \
&& usermod -a -G docker jenkins
#&& sed -i '/^root/a\jenkins ALL=(ALL:ALL) NOPASSWD:ALL' /etc/sudoers
WORKDIR /home/jenkins
USER jenkins
ENTRYPOINT ["jenkins-slave"]
这里生成镜像标签名jenkins/slave:v3.0
然后填写模板如下
1)填写标签和镜像名
2)挂载两个主机目录
一个是/var/run/docker.sock
,该文件是用于 Pod 中的容器能够共享宿主机的 Docker,这就是大家说的 docker in docker 的方式,Docker 二进制文件我们已经打包到上面的镜像中了,需要修改node节点上的docker.sock权限为777,但是重启服务器后docker.sock的权限会丢失,处理方法如下
创建一个service文件/etc/systemd/system/docker-sock-permissions
[Unit]
Description=Set permissions for docker.sock
[Service]
ExecStart=/bin/chmod o+rw /var/run/docker.sock
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
设置权限及开机启动
chmod 644 /etc/systemd/system/docker-sock-permissions.service
systemctl enable docker-sock-permissions.service
另外一个目录是/root/.kube
目录,我们将这个目录挂载到容器的/root/.kube
目录下面,这是为了让我们能够在 Pod 的容器中能够使用 kubectl 工具来访问我们的 Kubernetes 集群,方便我们后面在 Slave Pod 部署 Kubernetes 应用。需要注意的是我们要从master节点上把.kube文件夹拷贝到node节点的/root目录下
3)设置生成的slave容器的存活时间
这里我们最好留空,slave作业完成后,相应的pod会立刻销毁,设置时间过长的话,任务结束后pod也会一直存在。
4)设置service account,这里的值就是我们部署jenkins时,deploy.yaml文件中的sa
注意点
1.slave镜像java版本,要和jenkins server中的java版本一样,进入server容器中,使用java --version查看版本发现版本号是11
测试使用jenkins/jnlp-slave:4.13.3-1-jdk11
这个镜像版本可以使用基本的bash命令,但是没有kubectl, docker这些命令
2.测试使用odavid/jenkins-jnlp-slave:latest 默认安装了docker