devops-k8s部署jenkins和动态创建slave节点

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: 1. K8S部署jenkins2. 动态创建slave集群节点3. 使用PodTemplate构建流水线


环境准备


k8s环境:node1 和  node2



创建命名空间



╰─# kubectl create ns devopsnamespace/devops created


创建jenkins-master


deployment文件:


kind: Deployment
apiVersion: apps/v1
metadata:  labels:    k8s-app: jenkins
  name: jenkins
  namespace: devops
spec:  replicas: 1  revisionHistoryLimit: 10  selector:    matchLabels:      k8s-app: jenkins
  template:    metadata:      labels:        k8s-app: jenkins
      namespace: devops
      name: jenkins
    spec:      containers:        - name: jenkins
          image: jenkins/jenkins:2.381          imagePullPolicy: IfNotPresent
          ports:            - containerPort: 30080              name: web
              protocol: TCP
            - containerPort: 30081              name: agent
              protocol: TCP
          resources:            limits:              cpu: 1000m
              memory: 2Gi
            requests:              cpu: 500m
              memory: 512Mi
          livenessProbe:            httpGet:              path: /login
              port: 30080            initialDelaySeconds: 60            timeoutSeconds: 5            failureThreshold: 12          readinessProbe:            httpGet:              path: /login
              port: 30080            initialDelaySeconds: 60            timeoutSeconds: 5            failureThreshold: 12          volumeMounts:            - name: jenkins-home
              mountPath: /var/lib/jenkins
          env:            - name: JENKINS_HOME
              value: /var/lib/jenkins
            - name: JENKINS_OPTS 
              value: --httpPort=30080
            - name: JENKINS_SLAVE_AGENT_PORT
              value: "30081"      volumes:        - name: jenkins-home
          hostPath:             path: /data/devops/jenkins
            type: Directory
      serviceAccountName: jenkins
---apiVersion: v1
kind: ServiceAccount
metadata:  labels:    k8s-app: jenkins
  name: jenkins
  namespace: devops
---kind: Service
apiVersion: v1
metadata:  labels:    k8s-app: jenkins
  name: jenkins
  namespace: devops
spec:  type: NodePort
  ports:    - name: web
      port: 30080      targetPort: 30080      nodePort: 30080    - name: slave
      port: 30081      targetPort: 30081      nodePort: 30081  selector:    k8s-app: jenkins
---kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata: name: jenkins
 namespace: devops
rules: - apiGroups: [""]   resources: ["pods","configmaps","namespaces"]   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/v1
kind: RoleBinding
metadata: name: jenkins
 namespace: devops
roleRef: apiGroup: rbac.authorization.k8s.io
 kind: Role
 name: jenkins
subjects: - kind: ServiceAccount
   name: jenkins
   namespace: devops



通过一下命令启动jenkins-master


kubectl create -f deployment.yml


在启动jenkins过程中,容器状态为 CrashLoopBackOff  ,查看日志出现 java.nio.file.AccessDeniedException: /var/lib/jenkins/war

错误信息时,容器挂载的宿主机目录,无权限访问,需要 执行 chmod 777 /data/devops/jenkins , 然后在重启一下pod





╰─# kubectl get pods -n devops                                                                                                                                                                                                1 ↵
NAME                       READY   STATUS             RESTARTS   AGE
jenkins-65dbc65fbd-kkxbc   0/1     CrashLoopBackOff   5          5m26s
╭─root@k201 ~/jenkins-k8s 
╰─# kubectl logs pods/jenkins-65dbc65fbd-kkxbc -n devops                                                               
Running from: /usr/share/jenkins/jenkins.war
webroot: /var/lib/jenkins/war
2022-12-12 09:47:16.120+0000 [id=1] INFO  winstone.Logger#logInternal: Beginning extraction from war file
2022-12-12 09:47:16.139+0000 [id=1] WARNING winstone.Logger#logInternal: Failed to recreate dirs /var/lib/jenkins/war
java.nio.file.AccessDeniedException: /var/lib/jenkins/war
  at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:90)
  at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
  at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:116)
  at java.base/sun.nio.fs.UnixFileSystemProvider.createDirectory(UnixFileSystemProvider.java:389)
  at java.base/java.nio.file.Files.createDirectory(Files.java:690)
  at java.base/java.nio.file.Files.createAndCheckIsDirectory(Files.java:797)
  at java.base/java.nio.file.Files.createDirectories(Files.java:783)
  at winstone.HostConfiguration.getWebRoot(HostConfiguration.java:265)
  at winstone.HostConfiguration.<init>(HostConfiguration.java:87)
  at winstone.HostGroup.initHost(HostGroup.java:65)
  at winstone.HostGroup.<init>(HostGroup.java:44)
  at winstone.Launcher.<init>(Launcher.java:150)
  at winstone.Launcher.main(Launcher.java:389)
  at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.base/java.lang.reflect.Method.invoke(Method.java:566)
  at executable.Main.main(Main.java:356)
2022-12-12 09:47:16.143+0000 [id=1] WARNING winstone.Logger#logInternal: Failed to create dirs /var/lib/jenkins/war/META-INF
2022-12-12 09:47:16.229+0000 [id=1] INFO  winstone.Logger#logInternal: Jetty shutdown successfully
java.io.FileNotFoundException: /var/lib/jenkins/war/META-INF/MANIFEST.MF (No such file or directory)
  at java.base/java.io.FileOutputStream.open0(Native Method)
  at java.base/java.io.FileOutputStream.open(FileOutputStream.java:298)
  at java.base/java.io.FileOutputStream.<init>(FileOutputStream.java:237)
  at java.base/java.io.FileOutputStream.<init>(FileOutputStream.java:187)
  at winstone.HostConfiguration.getWebRoot(HostConfiguration.java:309)
  at winstone.HostConfiguration.<init>(HostConfiguration.java:87)
  at winstone.HostGroup.initHost(HostGroup.java:65)
  at winstone.HostGroup.<init>(HostGroup.java:44)
  at winstone.Launcher.<init>(Launcher.java:150)
  at winstone.Launcher.main(Launcher.java:389)
  at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.base/java.lang.reflect.Method.invoke(Method.java:566)
  at executable.Main.main(Main.java:356)
2022-12-12 09:47:16.232+0000 [id=1] SEVERE  winstone.Logger#logInternal: Container startup failed
java.io.FileNotFoundException: /var/lib/jenkins/war/META-INF/MANIFEST.MF (No such file or directory)
  at java.base/java.io.FileOutputStream.open0(Native Method)
  at java.base/java.io.FileOutputStream.open(FileOutputStream.java:298)
  at java.base/java.io.FileOutputStream.<init>(FileOutputStream.java:237)
  at java.base/java.io.FileOutputStream.<init>(FileOutputStream.java:187)
  at winstone.HostConfiguration.getWebRoot(HostConfiguration.java:309)
  at winstone.HostConfiguration.<init>(HostConfiguration.java:87)
  at winstone.HostGroup.initHost(HostGroup.java:65)
  at winstone.HostGroup.<init>(HostGroup.java:44)
  at winstone.Launcher.<init>(Launcher.java:150)
  at winstone.Launcher.main(Launcher.java:389)
  at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.base/java.lang.reflect.Method.invoke(Method.java:566)
  at executable.Main.main(Main.java:356)
╭─root@k201 ~/jenkins-k8s 
╰─#




动态配置jenkins Slave节点




安装kubernetes插件(安装完成后最好重启一下)。配置插件信息 系统设置 ->  节点管理 -> Configure Clouds ->增加一个云。

制作Kubernetes证书

  • 进入集群服务器 .kube/config
  • 复制config文件中的certificate-authority-data内容,生成base64文件 ca.crt
  • 复制config文件中的client-certificate-data内容,生成base64文件 client.crt
  • 复制config文件中的client-key-data内容,生成base64文件 client.key
  • echo zzzzzzzzz | base64 –d > client.key
  • 生成证书(会输入密码需要记住后面jenkins需要配置)
  • openssl pkcs12 -export -out cert.pfx -inkey client.key -in client.crt -certfile ca.crt
  • 下载证书 cert.pfx




Jenkins新建凭据



image-20221212182838093.png



注意:这里上传证书文件,通过 openssl 文件生成的 cert.pfx 的文件





配置Salve集群节点



将ca.crt 内容复制到 服务证书key 选择证书凭据 测试连接



image-20221212182632670.png



注意:


获取kubenetes地址方式:


╰─# kubectl config view  | grep server 
    server: https://192.168.10.201:6443╭─root@k201 ~/jenkins-k8s 
╰─# 


kubernetes 服务证书key为 ca.crt  文件中的内容




创建pipeline


image-20221213171434168.png





流水线示例


以PodTemplate模板创建脚本

def label = "slave-${UUID.randomUUID().toString()}"podTemplate(cloud: 'kubernetes', namespace:'devops',label: label, serviceAccount: 'jenkins',containers: [  containerTemplate(name: 'golang', image: 'golang:1.14.2-alpine3.11', command: 'cat', ttyEnabled: true),  containerTemplate(name: 'docker', image: 'docker:latest', command: 'cat', ttyEnabled: true),  containerTemplate(name: 'kubectl', image: 'cnych/kubectl', command: 'cat', ttyEnabled: true)
],volumes: [  hostPathVolume(mountPath: '/home/jenkins/.kube', hostPath: '/root/.kube'),  hostPathVolume(mountPath: '/var/run/docker.sock', hostPath: '/var/run/docker.sock')
]) {  node(label) {    stage('单元测试') {      echo "测试阶段"}    stage('代码编译打包') {      container('golang') {        echo "代码编译打包阶段"}}    stage('构建 Docker 镜像') {      container('docker') {        echo "构建 Docker 镜像阶段"}}    stage('运行 Kubectl') {      container('kubectl') {        echo "查看 K8S 集群 Pod 列表"        sh "kubectl get pods"}}}}







































相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
18天前
|
jenkins Devops Java
DevOps实践:Jenkins在持续集成与持续部署中的价值
【10月更文挑战第27天】在快速发展的软件开发领域,DevOps实践日益重要。Jenkins作为一款流行的开源自动化服务器,在持续集成(CI)和持续部署(CD)中扮演关键角色。本文通过案例分析,探讨Jenkins在Java项目中的应用,展示其自动化构建、测试和部署的能力,提高开发效率和软件质量。
40 2
|
1月前
|
Kubernetes API 调度
k8s中节点无法启动Pod
【10月更文挑战第3天】
82 6
|
1月前
|
Kubernetes 持续交付 Docker
利用 Docker 和 Kubernetes 实现微服务部署
【10月更文挑战第2天】利用 Docker 和 Kubernetes 实现微服务部署
|
1月前
|
Prometheus Kubernetes 监控
k8s部署针对外部服务器的prometheus服务
通过上述步骤,您不仅成功地在Kubernetes集群内部署了Prometheus,还实现了对集群外服务器的有效监控。理解并实施网络配置是关键,确保监控数据的准确无误传输。随着监控需求的增长,您还可以进一步探索Prometheus生态中的其他组件,如Alertmanager、Grafana等,以构建完整的监控与报警体系。
121 60
|
1月前
|
Prometheus Kubernetes 监控
k8s部署针对外部服务器的prometheus服务
通过上述步骤,您不仅成功地在Kubernetes集群内部署了Prometheus,还实现了对集群外服务器的有效监控。理解并实施网络配置是关键,确保监控数据的准确无误传输。随着监控需求的增长,您还可以进一步探索Prometheus生态中的其他组件,如Alertmanager、Grafana等,以构建完整的监控与报警体系。
210 62
|
19天前
|
jenkins Devops 测试技术
DevOps实践:Jenkins在持续集成与持续部署中的价值
【10月更文挑战第26天】随着DevOps理念的普及,Jenkins作为一款开源自动化服务器,在持续集成(CI)与持续部署(CD)中发挥重要作用。本文通过某中型互联网企业的实际案例,展示了Jenkins如何通过自动化构建、持续集成和持续部署,显著提升开发效率、代码质量和软件交付速度,帮助企业解决传统手工操作带来的低效和错误问题。
45 4
|
1月前
|
NoSQL 关系型数据库 Redis
高可用和性能:基于ACK部署Dify的最佳实践
本文介绍了基于阿里云容器服务ACK,部署高可用、可伸缩且具备高SLA的生产可用的Dify服务的详细解决方案。
|
1月前
|
Kubernetes Cloud Native 流计算
Flink-12 Flink Java 3分钟上手 Kubernetes云原生下的Flink集群 Rancher Stateful Set yaml详细 扩容缩容部署 Docker容器编排
Flink-12 Flink Java 3分钟上手 Kubernetes云原生下的Flink集群 Rancher Stateful Set yaml详细 扩容缩容部署 Docker容器编排
73 0
|
1月前
|
Kubernetes 网络协议 安全
[kubernetes]二进制方式部署单机k8s-v1.30.5
[kubernetes]二进制方式部署单机k8s-v1.30.5
|
1月前
|
Kubernetes 应用服务中间件 Linux
多Master节点的k8s集群部署
多Master节点的k8s集群部署