jenkins api获取构建日志_Jenkins master位于k8s集群外,实现jenkins slave的动态构建

2023-11-13

Jenkins基于"kubernetes plugin"与k8s集成,可以使Jenkins slave以pod的形式在k8s集群内部动态构建、运行、销毁等。

通过 jenkinsci/kubernetes-plugin 了解到,Jenkins master既可以运行在k8s集群内,也可运行在k8s集群外,但是Jenkins slave的整个生命周期都是在k8s集群内,并且通过JNLP与Jenkins master连接。

要想Jenkins master在k8s运行,我们必须提前创建StatefulSet、Service、Ingress、ServiceAccount等一系列yaml文件进行部署;而实际Jenkins master在生产中先于k8s使用并已独立运行,如果再次在K8S内部部署,那么我们还需进行迁移,增加了工作量。既然"kubernetes plugin"支持Jenkins master在k8s集群外部,那么就不必要再在k8s中创建了

下面我们就来详细介绍下jenkins master位于k8s集群外,实现jenkins slave的动态构建,其中有很多细节问题牵扯到docker、k8s的使用问题,我们一一讲解。

环境

  1. 三节点的k8s集群已经提前部署完毕。
  2. jenkins master 服务端口为8080;agent的端口为5000,用于agent通过JNLP与master连接。

k8s准备与规划

1.分配namespace

由于Jenkins slave运行在k8s集群内,为方便区分我们为其分配devops的命名空间,日后运维相关的操作都可以在此命名空间中进行。

kubectl create ns devops

2.rbac授权

Jenkins通过kubernetes-plugin对k8s进行操作,需要在k8s内提前进行rbac授权。为方便管理,我们为其绑定cluster-admin角色。当然也可以进一步缩小使用权限。

#创建serviceaccountskubectl create sa jenkins#对jenkins做cluster-admin绑定kubectl create clusterrolebinding jenkins --clusterrole cluster-admin --serviceaccount=devops:jenkins

3.获取token

kubernetes-plugin与k8s连接时,并不是直接使用serviceaccount,而是通过token。因此我们需要获取serviceaccount:jenkins对应的token,而此token是经过base64加密过的,必须解密后才能使用

# 1.查看sa# kubectl get sa -n devopsNAME      SECRETS   AGEdefault   1         113mjenkins   1         19m# 2.查看secret# kubectl get sa jenkins -n devops -o yamlapiVersion: v1kind: ServiceAccountmetadata:  creationTimestamp: "2020-07-28T08:27:55Z"  name: jenkins  namespace: devops  resourceVersion: "14403390"  selfLink: /api/v1/namespaces/devops/serviceaccounts/jenkins  uid: 43a98176-faa1-43f7-ad91-0352ca2dce2csecrets:- name: jenkins-token-44jkm# 3.获取token,从yaml中得到token# kubectl get secret  jenkins-token-44jkm -n devops -o yaml...省略...token: ZXlKaGJHY2lPaUpTV......省略...# 4.token解密# 由于此token是经过base64加密的,我们需要通过base64解密获取token值# echo "xxxxxxxx" |base64 -d

4.添加认证

获取到的token解密值,需要在Jenkins master中添加为secret text类型的secret,才能被kubernetes-plugin使用。

5.创建PV

通过构建时动态生成的Jenkins slave可以看出需要pvc会自动匹配pv,实现/home/jenkins/agent的存储挂载,因此我们需要提前创建pv,否则将会导致Jenkins slave无法成功创建。

注意:以下信息中的jenkins-pv就是我们已经提前创建好的pv。

# 查看pvc# kubectl describe pvc pvc-jenkins-slave-m4ptp -n devopsName:          pvc-jenkins-slave-m4ptpNamespace:     devopsStorageClass:  Status:        BoundVolume:        jenkins-pvLabels:        jenkins=slaveAnnotations:   pv.kubernetes.io/bind-completed: yes               pv.kubernetes.io/bound-by-controller: yesFinalizers:    [kubernetes.io/pvc-protection]Capacity:      15GiAccess Modes:  RWOVolumeMode:    FilesystemMounted By:    jenkins-slave-m4ptpEvents:        

我们在master创建nfs主目录,但是在主目录下通过子目录对k8s中的服务提供存储,这样可以通过子目录对所有服务的资源进行隔离

注意:此时的accessModes为ReadWriteOnce,需要和上面pvc的Access Modes: RWO一致。下面我会演示不一致情况下出现的问题。

# 1.master上创建nfs主目录mkdir -p /App/nfs# 2. jenkins子目录作为jenkins slave的工作目录mkdir -p /App/nfs/jenkins# 3.nfs服务,还可创建其他子目录可以为其他服务提供目录挂载# vim /etc/exports/App/nfs *(rw,no_root_squash,no_all_squash,sync)# 4.创建pv,这样k8s集群中的服务可自行匹配绑定pv# vim jenkins-storage.yamlapiVersion: v1kind: PersistentVolumemetadata:  name: jenkins-pvspec:  persistentVolumeReclaimPolicy: Recycle  capacity:    storage: 15Gi  accessModes:    - ReadWriteOnce  nfs:    server: 192.168.3.217    path: /App/nfs/jenkins

至此我们已经提前将准备工作完成了,后续的操作需要配置Jenkins master了。

注意:如果此时我们还没有Jenkins master的话,可以参考以下链接在k8s中部署Jenkins master。

https://github.com/jenkinsci/kubernetes-plugin/tree/master/src/main/kubernetes

其中:

  • jenkins.yml是部署StatefulSet、Service、Ingress;
  • service-account.yml是添加ServiceAccount认证信息;

Jenkins Master配置

由于Jenkins master先于k8s存在并已独立运行,为避免再次在K8S部署而产生的迁移问题,我们将直接使用Jenkins master。

1.安装kubernetes插件

2.kubernetes plugin与k8s连接配置

添加kubernetes云
“Manager Jenkins”-“Configure System”-“Cloud”

以上为kubernetes plugin与k8s连接是配置,其中:

  • kubernetes地址:为k8s api server地址,通过调用apiserver操作k8s。可通过以下来查看:
# kubectl cluster-infoKubernetes master is running at https://192.168.3.217:6443KubeDNS is running at https://192.168.3.217:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxyMetrics-server is running at https://192.168.3.217:6443/api/v1/namespaces/kube-system/services/https:metrics-server:/proxy
  • 凭据:kubernetes plugin可以通过key或凭据的方式与k8s进行认证,方便起见,我们采用凭据的方式,使用我们此前创建的secret text凭据,此时我们需要禁用HTTPS证书检查
  • kubernetes命令空间:使用我们提前规划的devops,同时serviceaccount也在此空间内。
  • Jenkins 地址:Jenkins master的地址。
  • Jenkins 通道:Jenkins slave通过此通道与Jenkins master连接,注意此为tcp连接不要加上http

通过以上配置,我们使用连接测试即可测试kubernetes plugin与k8s是否能够正常连接。但是连接成功并不代表后续Jenkins slave就会如愿正常构建,请继续耐心往下看。

3.配置 pod template

k8s中最小单元为pod,在此我们定义Jenkins slave所在pod的信息。

其中:

  • 名称:pod名称,在k8s中实际名称为jenkins-slave-随机值。
  • 命令空间: pod运行在devops命名空间内。
  • 标签列表:此处标签即标识Jenkins agent的,如流水线中agent定义调度在哪个slave上运行。

4.配置 container template

容器模板是我们在pod中运行的容器,此处我们可理解为在pod中创建Jenkins slave容器。
当然此处我们也可不配置,kubernetes plugin将会默认使用jenkins/jnlp-slave:alpine镜像创建。但是kubernetes-plugin官方已停止维护此镜像,而统一使用jenkins/inbound-agent。因此我们需要进行重新设置。

其中:

  • 名称:pod中容器的名称,注意此处必须设置为jnlp,才能对镜像重写使用jenkins/inbound-agent,否则将会出现以下问题:
    k8s同时拉取jenkins/inbound-agent和jenkins/jnlp-slave:alpine两个镜像,第一个为重写后的实际使用镜像,第二个为默认镜像,导致jenkins-slave无法正常运行,不断重复构建。
# kubectl describe pod jenkins-slave-3sgv0 -n devopsEvents:  Type     Reason            Age                From                   Message  ----     ------            ----               ----                   -------  Warning  FailedScheduling  57s                default-scheduler      persistentvolumeclaim "pvc-jenkins-slave-3sgv0" not found  Warning  FailedScheduling  25s (x5 over 57s)  default-scheduler      running "VolumeBinding" filter plugin for pod "jenkins-slave-3sgv0": pod has unbound immediate PersistentVolumeClaims  Normal   Scheduled         14s                default-scheduler      Successfully assigned devops/jenkins-slave-3sgv0 to uvmsvr-3-218  Normal   Pulled            13s                kubelet, uvmsvr-3-218  Container image "jenkins/inbound-agent" already present on machine  Normal   Created           12s                kubelet, uvmsvr-3-218  Created container jenkins-slave  Normal   Started           12s                kubelet, uvmsvr-3-218  Started container jenkins-slave  Normal   Pulled            12s                kubelet, uvmsvr-3-218  Container image "jenkins/jnlp-slave:alpine" already present on machine  Normal   Created           12s                kubelet, uvmsvr-3-218  Created container jnlp  Normal   Started           12s                kubelet, uvmsvr-3-218  Started container jnlp  Normal   Killing           8s                 kubelet, uvmsvr-3-218  Stopping container maven  Normal   Killing           8s                 kubelet, uvmsvr-3-218  Stopping container jnlp
  • Docker镜像:当名称设置为jnlp后,jenkins/inbound-agent即为重写后的镜像,否则默认使用jenkins/jnlp-slave:alpine
  • 工作目录:Jenkins slave的默认工作目录,构建时将会在此目录下创建workspace。
  • 运行的命令和命令参数: 其中运行的命令必须要留空,否则会重写镜像的默认entrypoint,导致agent 无法连接到master,下面我们会进行演示说明。
  • 资源限制:默认的容器是没有资源限制的,我们在此添加了cpu和memory限制,大家可根据实际情况进行修改。

5.Jenkins slave动态构建

“万事俱备,只欠东风”,接下来我们在Jenkins master上创建普通的流水线来测试下是否能够动态构建Jenkins slave来进行CI/CD。

pipeline {  agent {      label 'jenkins-slave-k8s'  }  stages {      stage('test') {          script {              println "test"          }      }  }}

通过此流水线来验证Jenkins slave是否动态构建成功。

如果有问题,我们还需进一步排查。下面我将介绍下我所遇到的一些问题。

问题处理

问题信息的排查主要通过以下三种方式:

  • k8s集群错误信息:kubectl describe pod jenkins-slave-xxx -n devops
  • Jenkins master日志:Manage Jenkins--System Log--All Logs
  • node节点docker 日志:docker logs xxxxxx
  • node节点docker 信息:docker inspect xxxxx

由于Jenkins slave动态构建,一旦构建不成功,则会不断重建。如果手速不够快,将无法捕获有效的错误信息。

1.构建时k8s创建Jenkins slave失败

现象:查看pod状态,发现jenkins-slave不断重建

# kubectl get pod -n devopsNAME                  READY   STATUS    RESTARTS   AGEjenkins-slave-tsz20   0/2     Pending   0          54s

原因排查:

1.查看失败原因:找不到pvc# kubectl describe pod jenkins-slave-tsz20 -n devopsEvents:  Type     Reason            Age                From               Message  ----     ------            ----               ----               -------  Warning  FailedScheduling  74s                default-scheduler  persistentvolumeclaim "pvc-jenkins-slave-tsz20" not found  Warning  FailedScheduling  12s (x2 over 74s)  default-scheduler  running "VolumeBinding" filter plugin for pod "jenkins-slave-tsz20": pod has unbound immediate PersistentVolumeClaims2.查看pvc:无法创建pvc# kubectl get pvc -n devopsNAME                      STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGEpvc-jenkins-slave-v1tw8   Pending3.查看pv:pvc和pv无法绑定# kubectl describe pvc pvc-jenkins-slave-v1tw8 -n devopsEvents:  Type    Reason         Age                From                         Message  ----    ------         ----               ----                         -------  Normal  FailedBinding  11s (x4 over 44s)  persistentvolume-controller  no persistent volumes available for this claim and no storage class is set

原因: 由于pvc无法和pv绑定,无法为Jenkins slave分配存储,导致Jenkins slave创建失败。

具体分析: 从k8s内默认自动创建的jenkins slave 所使用的pvc 以及我们事先建好的pv来看,由于其"Access modes"不匹配将会导致pv和pvc无法绑定,从而使jenkins slave镜像创建不成功。因此只要保证pv的access mode 和 默认pvc一致为RWO即可,而我当时pv设置为ReadWriteMany。

# PV信息# kubectl describe pv jenkins-pvName:            jenkins-pvLabels:          Annotations:     Finalizers:  [kubernetes.io/pv-protection]StorageClass:    Status:          AvailableClaim:           Reclaim Policy:  RecycleAccess Modes:    RWXVolumeMode:      FilesystemCapacity:        15GiNode Affinity:   Message:         Source:    Type:      NFS (an NFS mount that lasts the lifetime of a pod)    Server:    192.168.3.217    Path:      /App/nfs    ReadOnly:  falseEvents:        # PVC信息# kubectl describe pvc pvc-jenkins-slave-m4ptp -n devopsName:          pvc-jenkins-slave-m4ptpNamespace:     devopsStorageClass:  Status:        BoundVolume:        jenkins-pvLabels:        jenkins=slaveAnnotations:   pv.kubernetes.io/bind-completed: yes               pv.kubernetes.io/bound-by-controller: yesFinalizers:    [kubernetes.io/pvc-protection]Capacity:      15GiAccess Modes:  RWOVolumeMode:    FilesystemMounted By:    jenkins-slave-m4ptpEvents:        

解决: 将pv的accessModes 设置为ReadWriteOnce。

2.agent 无法连接到master

现象:通过Jenkins master日志发现报如下信息:

Aug 05, 2020 11:04:52 AM INFO org.csanchez.jenkins.plugins.kubernetes.KubernetesLauncher launchWaiting for agent to connect (0/100): jenkins-slave-kzxzgAug 05, 2020 11:04:53 AM INFO org.csanchez.jenkins.plugins.kubernetes.KubernetesLauncher launchWaiting for agent to connect (1/100): jenkins-slave-kzxzgAug 05, 2020 11:04:54 AM INFO org.csanchez.jenkins.plugins.kubernetes.KubernetesLauncher launchWaiting for agent to connect (2/100): jenkins-slave-kzxzg

在Jenkins master查看node状态:

原因排查:

  1. 此时我们根据提示在宿主机上单独执行java -jar agent.jar -jnlpUrl http://jenkins.test.cn/computer/jenkins-slave-p591m/slave-agent.jnlp -secret 6bd8d43952fe6dc199d95aa55cb975ad2ebde2648c2b260e8dfc1ea6a53042cb -workDir "/root"
    进一步查看是否能够运行成功。注意:此命令一定要在jenkins-slave-p591m存活期间执行,否则将运行不成功。

通过输出可以看到,agent此时通过Jenkins 通道能够发现Jenkins master。如果此处有问题,请检查你的Jenkins master上的配置:

  • Manage Jenkins–Configure Global Security–Agents,端口是否设置为5000或其他
  • kubernetes 插件中Jenkins 通道是否设置为192.168.3.133:5000,注意不要加http
  1. 分析jenkins/inbound-agent镜像
ARG version=4.3-7-alpineFROM jenkins/agent:$versionARG versionLABEL Description="This is a base image, which allows connecting Jenkins agents via JNLP protocols" Vendor="Jenkins project" Version="$version"ARG user=jenkinsUSER rootCOPY jenkins-agent /usr/local/bin/jenkins-agentRUN chmod +x /usr/local/bin/jenkins-agent &&    ln -s /usr/local/bin/jenkins-agent /usr/local/bin/jenkins-slaveUSER ${user}ENTRYPOINT ["jenkins-agent"]

镜像默认通过entrypoint启动,通过docker run直接运行

# docker run jenkins/inbound-agenttwo arguments required, but got []java -jar agent.jar [options...]   -agentLog FILE                        : Local agent error log destination                                         (overrides workDir) -cert VAL                             : Specify additional X.509 encoded PEM                                         certificates to trust when connecting......输出省略......

可见镜像entrypoint设置的jenkins-agent就是运行类似上文的java -jar agent.jar -jnlpUrl http://jenkins.test.cn/computer/jenkins-slave-p591m/slave-agent.jnlp -secret 6bd8d43952fe6dc199d95aa55cb975ad2ebde2648c2b260e8dfc1ea6a53042cb -workDir "/root"来连接agent。

再次查看docker ps -a发现容器的entrypoint被重写为/bin/sh -c cat,导致默认的jenkins-agent无法运行。

# docker ps -aCONTAINER ID        IMAGE                                                           COMMAND                  CREATED             STATUS                      PORTS               NAMESc53e446efb44        d7be84a67382                                                    "/bin/sh -c cat"         6 seconds ago       Up 5 seconds                                    k8s_jnlp_jenkins-slave-hhx00_devops_246d322a-1bde-4fc8-b436-d0fb3b5b076e_0

解决:
务必将运行的命令留空,否则会重写镜像的entrypoint,而命令参数可有可无。

重新设置后,实际此问题仍存在,进一步排查发现:

# 在jenkins slave所在节点上查看容器日志# docker logs 49f51724e101Aug 05, 2020 3:06:23 AM hudson.remoting.jnlp.Main createEngineINFO: Setting up agent: jenkins-slave-z1fqnAug 05, 2020 3:06:23 AM hudson.remoting.jnlp.Main$CuiListener INFO: Jenkins agent is running in headless mode.Aug 05, 2020 3:06:23 AM hudson.remoting.Engine startEngineINFO: Using Remoting version: 4.3Exception in thread "main" java.io.IOException: The specified working directory should be fully accessible to the remoting executable (RWX): /home/jenkins/agent  at org.jenkinsci.remoting.engine.WorkDirManager.verifyDirectory(WorkDirManager.java:249)  at org.jenkinsci.remoting.engine.WorkDirManager.initializeWorkDir(WorkDirManager.java:201)  at hudson.remoting.Engine.startEngine(Engine.java:288)  at hudson.remoting.Engine.startEngine(Engine.java:264)  at hudson.remoting.jnlp.Main.main(Main.java:284)  at hudson.remoting.jnlp.Main._main(Main.java:279)  at hudson.remoting.jnlp.Main.main(Main.java:231)

由此可见/home/jenkins/agent 没有写入权限,由于容器目录是通过pvc绑定pv,因此我们只需将pv的目录192.168.3.217:/App/nfs 的权限改为777,最终问题解决。

总结

通过k8s+jenkins的部署不仅仅是实现了CI/CD的需求,而且让我们发现了一些细节性问题,解决这些问题可以帮助我们更好的了解与使用k8s和docker:

  • serviceaccount与rbac授权
  • pv和pvc的匹配规则
  • docker entrypoint的作用

以上问题虽小,但其实是花了很长时间才解决的,在此分享出来,希望对大家有所帮助。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

jenkins api获取构建日志_Jenkins master位于k8s集群外,实现jenkins slave的动态构建 的相关文章

  • C#基于串行通讯不同计算机数据库之间数据交换系统(原创作品,送论文查重报告)

    论文编号 C 005 论文题目 基于串行通讯不同计算机数据库之间数据交换系统 开发语言 C 包括内容 论文 可执行程序 源码 答辩ppt 外文翻译 进度表 程序操作演示录像 数 据 库 SQL 论文字数 7000字以上
  • c++ 关于opencv 的基本操作

    读取影像 include
  • 没钱也能创业么?没钱怎样创业?

    一 先说结果不但并不是没钱就不能创业 反而是一切追求完美资本的人 无论有钱没钱 都能够且应当创业 二 界定问题我还在风投领域当上五六年兵线 眼界过上百个各式各样企业和创业者 项目投资总额度过亿人民币 也用掉过他人项目投资帮我的上百万用以创业
  • 组成最大数 华为机试

    题目描述 给定一组非负整数 重新排列它们的顺序使之组成一个最大的整数 示例 输入 10 2 输出 210 输入 3 30 34 5 9 输出 9534330 解题思路 回溯法 代码 package Huawei import java ut
  • Mysql分库分表实战(一)——一文搞懂Mysql数据库分库分表

    由于业务需要 需要对Mysql数据库进行分库分表 故而最近一直在整理分库分表的相关知识 现手上的工作也告一段落了 抽空将自己最近的学习结果转化为博文 分享给大家 本博文打算做成一个系列的 首先是分库分表的理论知识的了解 其次是基于Java编
  • 方差分析中怎么看有无显著性影响_一文带你轻松掌握,重复测量方差分析

    在某些实验研究中 常常需要考虑时间因素对实验的影响 当需要对同一观察单位在不同时间重复进行多次测量 每个样本的测量数据之间存在相关性 因而不能简单的使用方差分析进行研究 而需要使用重复测量方差分析 案例 当前有这样一项关于抑郁症的研究 共有
  • html中%20是什么意思?

    两个空格的话就是两个 20 转载于 https www cnblogs com linsx p 6943985 html
  • shell select用法

    select 是 Bash shell 中的一个命令 用于在终端中创建交互式菜单 select 语法格式如下 select varname in list do command1 command2 done 其中 varname 是一个变量
  • 竞争条件(race condition)

    在一些操作系统中 协作的进程可能共享一些彼此都能读写的公用存储区 这个公用存储区可能在内存中 可能是在内核数据结构中 也可能是一个共享文件 这里共享存储区的位置并不影响通信的本质及其带来的问题 为了理解实际中进程间通信如何工作 我们考虑一个
  • linux下五颜六色的文件——具体含义

    1 有一个伟人说过 Linux下一切都是文件 没错 他说的很对 但是文件又有很多汇总类型 Linux系统中用不同的颜色先大致区分一下 2 LINUX下不同的文件类型有不同的颜色 绿色文件 可执行文件 可执行的程序 红色文件 压缩文件或者包文
  • 【数论基础】—— 二项式定理

    二项式定理 内容 x y n
  • MySQL 使用方法简单教程

    目录 启动MySQL服务器 进入mysql交互操作界面 退出MySQL操作界面 第一条命令 多行语句 使用SHOW语句找出在服务器上当前存在什么数据库 创建一个数据库abccs 选择你所创建的数据库 创建一个数据库表 显示表的结构 查询所有
  • stm32cubemx 多路adc采集

    采用的软件是STM32CUBEMX KEIL5 硬件为stm32F103C8T6 我与原文作者做的区别在于 External Trigger Conversion Edge 我在进行配置的时间没有None选项 我选择的是默认的Regular
  • 线代矩阵相乘笔算的新简捷方法

    本矩阵相乘简捷笔算方法做法与传统本质一样 但对部分人来说这样列式子图更容易记忆和准确计算 O O 2013年12月写 2016年5月23日略修正 摘 矩阵的乘法定义 以前这种笔算方法太麻烦 难以快速看出所得矩阵的行列数或者是容易算少算多了一
  • Raki的NLP竞赛topline解读:NBME - Score Clinical Patient Notes

    Description 当你去看医生时 他们如何解释你的症状可以决定你的诊断是否准确 当他们获得执照时 医生们已经有了很多写病人笔记的练习 这些笔记记录了病人的主诉历史 体检结果 可能的诊断和后续护理 学习和评估写病人笔记的技能需要其他医生
  • MySql 生成自定义格式的编码_并更新保存到表指定的表字段

    生成出来的编码格式例子 YHCF0000000001 YHCF0000000002 YHCF0000000010 YHCF0000000011 mysql sql 获取最大的编码数据 生成新的自定义格式的编码 并更新保存到表指定的表字段 u
  • PHP加密方式

    PHP加密方式分为单项散列加密 对称加密 非对称加密这几类 像常用的MD5 hash crypt sha1这种就是单项散列加密 单项散列加密是不可逆的 像URL编码 base64编码这种就是对称加密 是可逆的 就是说加密解密都是用的同一秘钥
  • Unity3D 5 官方教程:地形设置

    地形工具栏的最后一个工具是设置 设置检视器 设置被提供用于如下描述的一些全局使用和渲染选项 基本地形 属性 功能 Draw 切换地形渲染开关 Pixel Error 在地形贴图 高度图 纹理等等 与生成地形之间的贴图精确度 更高的值为更低的
  • 剑指offer--顺时针打印矩阵

    题目描述 输入一个矩阵 按照从外向里以顺时针的顺序依次打印出每一个数字 例如 如果输入如下矩阵 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1 2 3 4 8 12 16 15 14 13

随机推荐

  • stop容器

    docker ps 查看所有正在运行容器 docker stop containerId containerId 是容器的ID docker ps a 查看所有容器 docker ps a q 查看所有容器ID docker stop do
  • Google Protocol Buffer 的使用和原理

    Google Protocol Buffer 的使用和原理 刘 明 软件工程师 上海交大电子与通信系 简介 Protocol Buffers 是一种轻便高效的结构化数据存储格式 可以用于结构化数据串行化 很适合做数据存储或 RPC 数据交换
  • 程序设计十二:线上聊天室(网络编程+多线程)

    程序设计十二 网络编程 1 Manager类 使用Manager类实现服务器功能 recv 内部方法接收消息 broadcast 方法向所有用户广播 private chat 方法发送私信 定向转发 chat 方法实现收发消息的完整过程 并
  • R包——maftools可视化神器

    参考 http bioconductor org packages release bioc vignettes maftools inst doc maftools html 目录 介绍 准备 格式转换 总体分析框架 maftools安装
  • 每个工程师都应该知道的 5 个射频发射器测量指标(自NI官网翻译)

    概述 射频发射器是现代通信的重要组成部分 射频发射器由核心射频组件设计和组装而成 具有多种不同的形式和应用 我们经常想到无线通信中的射频发射器 但这个概念同样适用于有线应用 如有线电视 蜂窝电话 雷达 军事通信 航空电子设备 无线局域网 调
  • 第三节课笔记(条件语句与循环语句)

    条件语句与循环语句 一 数据类型 标准数据类型 Python3中有六个标准的数据类型 Number 数字 支持int float bool complex 复数 Sring 字符串 Python中的字符串用单引号 或双引号 括起来 同时使用
  • 18650锂电池保护板接线图_锂电池保护板的过流保护测试方案

    电池保护板 顾名思义锂电池保护板主要是针对可充电 一般指锂电池 起保护作用的集成电路板 锂电池 可充型 之所以需要保护 是由它本身特性决定的 由于锂电池本身的材料决定了它不能被过充 过放 过流 短路及超高温充放电 因此锂电池锂电组件总会跟着
  • java long 详解_JavaSE之Long 详解 Long的方法简介以及用法

    基本功能 Long 类在对象中包装了基本类型 long 的值 每个 Long 类型的对象都包含一个 long 类型的字段 static long MAX VALUElong 8个字节 最大值2 63 1 十六进制 0x80000000000
  • android Intent启动flag

    android Intent启动flag 分类 android框架 2013 10 30 14 47 1318人阅读 评论 0 收藏 举报 FLAG GRANT READ URI PERMISSION 如果设置这个标记 Intent的接受者
  • react中@withrouter_React系列十 - 高阶组件以及组件补充

    源自 coderwhy 一 高阶组件 1 1 认识高阶组件 什么是高阶组件呢 相信很多同学都听说过 也用过 高阶函数 它们非常相似 所以我们可以先来回顾一下什么是 高阶函数 高阶函数的维基百科定义 至少满足以下条件之一 接受一个或多个函数作
  • Qt+webservice的多线程实现

    原文地址 https blog csdn net qq 29176963 article details 82776588 相关文章 1 Qt 之 QtSoap 访问WebService https blog csdn net liang1
  • linux lvm在线扩容

    步骤 创建新的PV 将新的PV加入到当前VG 扩容现有LV 扩容文件系统 1 fdisk dev sda n 新增 p 主分区 大小自己调整 可以默认 记得用 t 转换格式为 8e lvm分区号 最后 w 保存 2 partprobe de
  • GitHub访问量超百万的阿里大佬总结图解Java小册火了,完整版限时开源

    什么是Java Java是Sun Microsystems于1995年首次发布的一种编程语言和计算平台 Java是快速 安全和可靠的 从笔记本电脑到数据中心 从游戏机到科学超级计算机 从手机到互联网 Java无处不在 Java的特点 Jav
  • npm依赖更新无效

    项目场景 项目是使用ice 2 0 0搭建的react项目 项目需要替换新版本的sdk 使用npm进行对应sdk的版本升级 问题描述 卸载sdk tnpm uninstall tds sdk 安装最新版本sdk tnpm i tds sdk
  • 互转(经纬度、地心坐标、东北天坐标)

    Part1三种坐标系介绍 经纬度坐标 假设空间某点P 用经纬度表示的话 你们B代表纬度 L代表经度 H代表大地高 纬度B P点沿着地球法线方向与赤道面的夹角 向北为正称为北纬 0 90 向南为负称为南纬 0 90 实际表示可以用 90 90
  • Error:(6, 46) java: 程序包org.springframework.context.annotation不存在

    IDEA 莫名其妙突然出现出错 Error 6 46 java 程序包org springframework context annotation不存在 经本地测试采用如下方法可以解决 1 修改在File gt settings gt Bu
  • MATLAB基础篇——基本语法

    MATLAB基础篇 基本语法 一 数据类型与变量 数据类型 变量 二 矩阵 字符串 三 运算 四 MATLAB常用函数 五 矩阵分析与处理 六 程序设计 七 符号计算 MATLAB Matrix laboratory 一般操作 1 操作界面
  • vue高级篇

    笔记 脚手架文件结构 node modules public favicon ico 页签图标 index html 主页面 src assets 存放静态资源 logo png component 存放组件 HelloWorld vue
  • 算法之路--高斯分布(一)

    正态分布 英语 normal distribution 又名高斯分布 英语 Gaussian distribution 是一个非常常见的连续概率分布 正态分布在统计学上十分重要 经常用在自然和社会科学来代表一个不明的随机变量 可以判断各种情
  • jenkins api获取构建日志_Jenkins master位于k8s集群外,实现jenkins slave的动态构建

    Jenkins基于 kubernetes plugin 与k8s集成 可以使Jenkins slave以pod的形式在k8s集群内部动态构建 运行 销毁等 通过 jenkinsci kubernetes plugin 了解到 Jenkins