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搭建和管理企业级网站应用
相关文章
|
4天前
|
Kubernetes Devops 持续交付
DevOps实践:使用Docker和Kubernetes实现持续集成和部署网络安全的守护盾:加密技术与安全意识的重要性
【8月更文挑战第27天】本文将引导读者理解并应用DevOps的核心理念,通过Docker和Kubernetes的实战案例,深入探讨如何在现代软件开发中实现自动化的持续集成和部署。文章不仅提供理论知识,还结合真实示例,旨在帮助开发者提升效率,优化工作流程。
|
1天前
|
Java Devops 持续交付
探索Java中的Lambda表达式:简化代码,提升效率DevOps实践:持续集成与部署的自动化之路
【8月更文挑战第30天】本文深入探讨了Java 8中引入的Lambda表达式如何改变了我们编写和管理代码的方式。通过简化代码结构,提高开发效率,Lambda表达式已成为现代Java开发不可或缺的一部分。文章将通过实际例子展示Lambda表达式的强大功能和优雅用法。
|
1天前
|
监控 安全 Devops
DevOps实践:持续集成和部署的自动化之旅
【8月更文挑战第30天】在软件开发的快节奏世界中,DevOps已成为推动项目成功的关键因素。本文将深入探讨如何通过持续集成(CI)和持续部署(CD)实现自动化,以加速开发流程、提升软件质量并确保快速交付。我们将从基础概念出发,逐步过渡到实际操作,最后讨论如何克服实施过程中的挑战。
|
3天前
|
Kubernetes 监控 Devops
【独家揭秘】.NET项目中的DevOps实践:从代码提交到生产部署,你不知道的那些事!
【8月更文挑战第28天】.NET 项目中的 DevOps 实践贯穿代码提交到生产部署全流程,涵盖健壮的源代码管理、GitFlow 工作流、持续集成与部署、容器化及监控日志记录。通过 Git、CI/CD 工具、Kubernetes 及日志框架的最佳实践应用,显著提升软件开发效率与质量。本文通过具体示例,助力开发者构建高效可靠的 DevOps 流程,确保项目成功交付。
28 0
|
8天前
|
Kubernetes jenkins 持续交付
在K8S中,Jenkins如何集成K8S集群?
在K8S中,Jenkins如何集成K8S集群?
|
12天前
|
敏捷开发 运维 测试技术
阿里云云效产品使用合集之如何同时部署多个主机
云效作为一款全面覆盖研发全生命周期管理的云端效能平台,致力于帮助企业实现高效协同、敏捷研发和持续交付。本合集收集整理了用户在使用云效过程中遇到的常见问题,问题涉及项目创建与管理、需求规划与迭代、代码托管与版本控制、自动化测试、持续集成与发布等方面。
|
1天前
|
监控 安全 Devops
DevOps实践:从代码到部署的无缝过渡
【8月更文挑战第30天】本文通过深入浅出的方式,向读者展示了DevOps文化和实践如何帮助团队实现从代码编写到软件部署的高效、自动化流程。我们将探讨持续集成(CI)、持续交付(CD)以及监控和日志记录的最佳实践,旨在为希望优化软件开发周期的专业人士提供实用指南。文章不展示具体代码示例,而是聚焦于概念理解和实践应用,确保内容即便在没有代码的情况下也具有实质性价值。
|
1天前
|
监控 Devops jenkins
DevOps实践:持续集成与部署的自动化之旅
【8月更文挑战第30天】本文旨在揭示DevOps文化中,持续集成和持续部署(CI/CD)如何成为现代软件开发的加速器。我们将深入探讨自动化流程的构建,从代码提交到产品上线的无缝衔接,以及这一过程如何提升团队协作、加快交付速度并保障产品质量。文章不仅分享理论知识,还提供实用的代码示例,帮助读者将抽象概念转化为具体操作。
|
2天前
|
Kubernetes jenkins 持续交付
jenkins学习笔记之二十一:k8s部署jenkins及动态slave
jenkins学习笔记之二十一:k8s部署jenkins及动态slave
|
2天前
|
jenkins Java 持续交付
jenkins学习笔记之十九:Docker安装jenkins master及动、静态配置slave
jenkins学习笔记之十九:Docker安装jenkins master及动、静态配置slave
下一篇
云函数