jenkins X实践系列(1) —— 背景知识
本文介绍jenkins X(以下简称jx)相关的背景技术。
jenkins X 简介
Jenkins X 是一个高度集成化的CI/CD平台,基于Jenkins和Kubernetes实现,旨在解决微服务体系架构下的云原生应用的持续交付的问题,简化整个云原生应用的开发、运行和部署过程。
jx 基于gitops,将k8s分为preview、staging、production几个环境,
详细的devops可以查看下图:
jx是云原生CICD,devops的一个最佳实践之一,目前在快速的发展成熟中。最近调研了JX,准备写一个jx实践系列,这里为第一篇,介绍jx用到的一些相关组件,作为了解jx的背景知识。
jenkins pipeline
jx使用Jenkins Pipeline来执行CI流程,Jenkins Pipeline是jenkins的一套插件,支持将连续输送Pipeline实施和整合到Jenkins。Pipeline 提供了一组可扩展的工具,用于通过Pipeline DSL为代码创建简单到复杂的传送Pipeline 。
Jenkinsfile pipeline使用Groovy脚本来定义CI流程,来看一个jx生成的实际案例:
pipeline {
agent {
label "jenkins-maven"
}
environment {
ORG = 'jqpeng'
APP_NAME = 'x-nginx'
CHARTMUSEUM_CREDS = credentials('jenkins-x-chartmuseum')
}
stages {
stage('CI Build and push snapshot') {
when {
branch 'PR-*'
}
environment {
PREVIEW_VERSION = "0.0.0-SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER"
PREVIEW_NAMESPACE = "$APP_NAME-$BRANCH_NAME".toLowerCase()
HELM_RELEASE = "$PREVIEW_NAMESPACE".toLowerCase()
}
steps {
container('maven') {
sh "mvn versions:set -DnewVersion=$PREVIEW_VERSION"
sh "mvn package -DskipTests"
sh 'export VERSION=$PREVIEW_VERSION && skaffold build -f skaffold.yaml'
sh "jx step post build --image $DOCKER_REGISTRY/$ORG/$APP_NAME:$PREVIEW_VERSION"
}
dir ('./charts/preview') {
container('maven') {
sh 'helm init --client-only --stable-repo-url=http://charts.iflyresearch.com/'
sh "make preview"
sh "jx preview --app $APP_NAME --dir ../.."
}
}
}
}
stage('Build Release') {
when {
branch 'master'
}
steps {
container('maven') {
// ensure we're not on a detached head
sh "git checkout master"
sh "git config --global credential.helper store"
sh "jx step git credentials"
// so we can retrieve the version in later steps
sh "echo \$(jx-release-version) > VERSION"
sh "mvn versions:set -DnewVersion=\$(cat VERSION)"
}
dir ('./charts/x-nginx') {
container('maven') {
sh "make tag"
}
}
container('maven') {
sh 'mvn package -DskipTests'
sh 'export VERSION=`cat VERSION` && skaffold build -f skaffold.yaml'
sh "jx step post build --image $DOCKER_REGISTRY/$ORG/$APP_NAME:\$(cat VERSION)"
}
}
}
stage('Promote to Environments') {
when {
branch 'master'
}
steps {
dir ('./charts/x-nginx') {
container('maven') {
sh 'jx step changelog --version v\$(cat ../../VERSION)'
sh 'helm init --client-only --stable-repo-url=http://charts.iflyresearch.com/'
// release the helm chart
sh 'jx step helm release'
// promote through all 'Auto' promotion Environments
sh 'jx promote -b --all-auto --timeout 1h --version \$(cat ../../VERSION)'
}
}
}
}
}
post {
always {
cleanWs()
}
}
}
- pipeline 定义是一个pipeline
- environment 定义环境变量
- stages 定义流程
- stage('CI Build and push snapshot') 定义子流程
- when 匹配条件
- environment 定义子流程环境变量
- steps 定义流程制定的具体步骤
- container('maven') 使用maven镜像来构建
- sh "git checkout master" 在maven镜像执行命令
- stage('CI Build and push snapshot') 定义子流程
- 其余的看字面意思就可以理解了
执行构建后,打开jenkins web页面,可以看到构建pipelines
同时可以查看Blue Ocean页面
helm与charts
Helm是管理Kubernetes charts的工具,charts是预先配置好的安装包资源,有点类似于Ubuntu的APT和CentOS中的yum。
可以使用helm来:
- 查找并使用已打包为Helm charts的热门应用在Kubernetes中运行
- 封装并分享自己的应用
- 创建可重复的Kubernetes应用程序版本
- 智能管理应用依赖
- 管理Helm软件包的版本
安装helm
安装helm很简单,下载离线二进制包,加压后加入path即可
wget https://kubernetes-helm.storage.googleapis.com/helm-canary-linux-amd64.tar.gz
helm需要服务端Tiller支持,需要安装到集群中,可以使用下面的命令来安装最新的2.11版本:
helm init --tiller-image anjia0532/kubernetes-helm.tiller:v2.11.0 --skip-refresh
参见:google gcr.io、k8s.gcr.io 国内镜像
helm错误解决
Helm: Error: no available release name found
helm报这个错误 Helm: Error: no available release name found
错误的原因大概是因为 tiller没有正确的角色权限。
执行以下命令可解决这个问题。
kubectl create serviceaccount --namespace kube-system tiller
kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
kubectl patch deploy --namespace kube-system tiller-deploy -p '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}'
charts入门
先来看一个jx生成的charts文件:
tree charts/
charts/
├── preview
│ ├── Chart.yaml
│ ├── Makefile
│ ├── requirements.yaml
│ └── values.yaml
├── x-nginx
│ ├── Chart.yaml
│ ├── Makefile
│ ├── README.md
│ ├── templates
│ │ ├── deployment.yaml
│ │ ├── _helpers.tpl
│ │ ├── NOTES.txt
│ │ └── service.yaml
│ └── values.yaml
Chart.yaml
chart文件首先是一个Chart.yaml描述文件,描述chart的基本信息,包含name,version等描述信息
cat charts/x-nginx/Chart.yaml
apiVersion: v1
description: A Helm chart for Kubernetes
icon: https://raw.githubusercontent.com/jenkins-x/jenkins-x-platform/master/images/java.png
name: x-nginx
version: 0.1.0-SNAPSHOT
~
templates
templates存放的是模板文件,遵循Go template语法,结合values.yaml的数据,可以生成部署到K8S所需的yaml配置文件。
来简单看下deployment.yaml:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: {{ template "fullname" . }}
labels:
draft: {{ default "draft-app" .Values.draft }}
chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}"
spec:
replicas: {{ .Values.replicaCount }}
template:
metadata:
labels:
draft: {{ default "draft-app" .Values.draft }}
app: {{ template "fullname" . }}
{{- if .Values.podAnnotations }}
annotations:
{{ toYaml .Values.podAnnotations | indent 8 }}
{{- end }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- containerPort: {{ .Values.service.internalPort }}
terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }}
注意,模板遵循Go template语法,都是go生态,可以稍微学习了解下。上面的模板是Deployment的yaml配置文件,大括号包裹起来的部分是Go template,对应的Values是在values.yaml
文件中定义的:
# Default values for Maven projects.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
image:
repository: draft
tag: dev
pullPolicy: IfNotPresent
service:
name: x-nginx
type: ClusterIP
externalPort: 80
internalPort: 8080
annotations:
fabric8.io/expose: "true"
fabric8.io/ingress.annotations: "kubernetes.io/ingress.class: nginx"
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 400m
memory: 512Mi
terminationGracePeriodSeconds: 10
简单学习下常用语法:
- {{ .Values.replicaCount }} 对应
values.yaml
中的replicaCount,通过{{ .Values.$varname }} 语法引用 - {{ default "draft-app" .Values.draft }} 如果draft没有定义,使用默认的"draft-app"
- {{- if .Values.podAnnotations }} {{- end }} 条件语法
- {{ toYaml .Values.podAnnotations | indent 8 }} 输出为yaml,indent指定缩进
验证模板
charts通过go模板渲染后,最后生成yaml格式部署文件,可以使用helm install --dry-run --debug <chart_dir>
命令来验证chart配置,查看最终生成的配置文件。
$:~/workspace/xnginx/charts/x-nginx$ helm install --dry-run --debug .
[debug] Created tunnel using local port: '40868'
[debug] SERVER: "127.0.0.1:40868"
[debug] Original chart version: ""
[debug] CHART PATH: /workspace/xnginx/charts/x-nginx
NAME: messy-seastar
REVISION: 1
RELEASED: Tue Nov 20 09:20:39 2018
CHART: x-nginx-0.1.0-SNAPSHOT
USER-SUPPLIED VALUES:
{}
COMPUTED VALUES:
image:
pullPolicy: IfNotPresent
repository: draft
tag: dev
replicaCount: 1
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 400m
memory: 512Mi
service:
annotations:
fabric8.io/expose: "true"
fabric8.io/ingress.annotations: 'kubernetes.io/ingress.class: nginx'
externalPort: 80
internalPort: 8080
name: x-nginx
type: ClusterIP
terminationGracePeriodSeconds: 10
HOOKS:
MANIFEST:
---
# Source: x-nginx/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: x-nginx
labels:
chart: "x-nginx-0.1.0-SNAPSHOT"
annotations:
fabric8.io/expose: "true"
fabric8.io/ingress.annotations: 'kubernetes.io/ingress.class: nginx'
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 8080
protocol: TCP
name: http
selector:
app: messy-seastar-x-nginx
---
# Source: x-nginx/templates/deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: messy-seastar-x-nginx
labels:
draft: draft-app
chart: "x-nginx-0.1.0-SNAPSHOT"
spec:
replicas: 1
template:
metadata:
labels:
draft: draft-app
app: messy-seastar-x-nginx
spec:
containers:
- name: x-nginx
image: "draft:dev"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
terminationGracePeriodSeconds: 10
其他命令
- 部署
helm install .
- 打包分享
helm package .
charts mirror 镜像
官方的charts镜像由于GFW原因,不能访问,可以使用github镜像:
helm repo add stable https://burdenbear.github.io/kube-charts-mirror/
当然,为了更好使用,可以部署本地镜像
- clone mirror仓库到本地,存放到cephfs /charts目录,然后创建一个nginx,挂载这个pv即可。
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolume
metadata:
name: cephfs-charts-pv
namespace: nginx-ingress
labels:
name: cephfs-charts-pv
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteMany
cephfs:
monitors:
- 192.168.86.156:6789
path: /charts/kube-charts-mirror-master/docs/
user: admin
secretRef:
name: ceph-secret
readOnly: false
persistentVolumeReclaimPolicy: Retain
EOF
skaffold
Skaffold 是谷歌开源的简化本地 Kubernetes 应用开发的工具。它将构建镜像、推送镜像以及部署 Kubernetes 服务等流程自动化,可以方便地对 Kubernetes 应用进行持续开发。其功能特点包括
没有服务器组件
自动检测代码更改并自动构建、推送和部署服务
自动管理镜像标签
支持已有工作流
保存文件即部署
直接进入正题,skaffold通过skaffold.yaml
来定义build、deploy,并且可以区分dev环境和正式环境:
apiVersion: skaffold/v1alpha2
kind: Config
build:
tagPolicy:
envTemplate:
template: "{{.DOCKER_REGISTRY}}/jqpeng/x-nginx:{{.VERSION}}"
artifacts:
- imageName: changeme
workspace: ./xnginx-admin
docker: {}
local: {}
deploy:
kubectl:
manifests:
profiles:
- name: dev
build:
tagPolicy:
envTemplate:
template: "{{.DOCKER_REGISTRY}}/jqpeng/x-nginx:{{.DIGEST_HEX}}"
artifacts:
- docker: {}
local: {}
deploy:
helm:
releases:
- name: x-nginx
chartPath: charts/x-nginx
setValueTemplates:
image.repository: "{{.DOCKER_REGISTRY}}/jqpeng/x-nginx"
image.tag: "{{.DIGEST_HEX}}"
- apiVersion 指定API版本,jx用的还是v1alpha2,相对较老
- build.tagPolicy.template 配置了image的名称模板,DOCKER_REGISTRY,Version等是环境变量
- artifacts 数组,用于指定构建docker镜像,可以有多个,workspace制定工作目录(新版本的api变为了context)
- deploy 指定部署方式
- profiles 区分环境,这里定义了dev环境
- 设置template ,image的tag为DIGEST_HEX,校验码
- 部署使用helm
如上的配置,在jx里如何运作的呢?
- 正式构建环境,只进行构建
在jenkinsfile里
sh 'export VERSION=`cat VERSION` && skaffold build -f skaffold.yaml'
在devpod里,实现构建和部署
skaffold run -p dev
Draft
draft 是微软开源的“A tool for developers to create cloud-native applications on Kubernetes”,一个为方便开发者在K8S创建云原生应用的工具,它可以帮助开发人员简化容器应用程序的开发流程。
上面我们了解了JENKINSFile,charts配置文件,难道每个项目需要按我们自己来写这些配置文件吗?
Draft告诉你,可以不!Draft最大的益处是,可以自动识别你的工程,然后根据模板库生成对应的配置文件,酷不酷?
Draft 主要由三个命令组成
draft init
:初始化 docker registry 账号,并在 Kubernetes 集群中部署 draftd(负责镜像构建、将镜像推送到 docker registry 以及部署应用等)draft create
:draft 根据 packs 检测应用的开发语言,并自动生成 Dockerfile 和 Kubernetes Helm Chartsdraft up
:根据 Dockfile 构建镜像,并使用 Helm 将应用部署到 Kubernetes 集群(支持本地或远端集群)。同时,还会在本地启动一个 draft client,监控代码变化,并将更新过的代码推送给 draftd。
不过,在jx中,仅仅只使用了draft的识别语言,生成配置文件的功能,相关的draft模板可以在# draft-packs 里看到。
Nexus
jx使用Nexus 来做默认的制品仓库(Artifact repository),Nexus大家应该不默认,好多公司和团队的maven仓库均是通过Nexus搭建的。
Nexus还可以作为npm,nuget,docker仓库。
Chartmuseum 与Monocular
Chartmuseum - 是一个helm chart仓库,jx用他来做chart仓库。
Monocular是一个web应用可以用来从helm charts仓库搜索和发现charts。
作者:Jadepeng
出处:jqpeng的技术记事本--http://www.cnblogs.com/xiaoqi
您的支持是对博主最大的鼓励,感谢您的认真阅读。
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
jenkins X实践系列(1) —— 背景知识的更多相关文章
- jenkins X实践系列(3) —— jenkins X 安装拾遗
jx是云原生CICD,devops的一个最佳实践之一,目前在快速的发展成熟中.最近调研了JX,这里为第3篇,介绍下如何安装jenkins x. 前置条件 安装K8S 安装ceph集群(jx需要stor ...
- jenkins X实践系列(4) —— jenkins X 构建提速
jx是云原生CICD,devops的一个最佳实践之一,目前在快速的发展成熟中.最近调研了JX,这里为第4篇,介绍如何加入jx构建和部署. builder镜像下载慢 先在一台机器上下载好,然后放到本地仓 ...
- jenkins X实践系列(2) —— 基于jx的DevOps实践
jx是云原生CICD,devops的一个最佳实践之一,目前在快速的发展成熟中.最近调研了JX,这里为第2篇,使用已经安装好的jx来实践CICD,旨在让大家了解基于jx的DevOps是如何运转的,感兴趣 ...
- 「持续集成实践系列」Jenkins 2.x 搭建CI需要掌握的硬核要点
1. 前言 随着互联网软件行业快速发展,为了抢占市场先机,企业不得不持续提高软件的交付效率.特别是现在国内越来越多企业已经在逐步引入DevOps研发模式的变迁,在这些背景催促之下,对于企业研发团队所需 ...
- 「持续集成实践系列 」Jenkins 2.x 构建CI自动化流水线常见技巧
在上一篇文章中,我们介绍了Jenkins 2.x实现流水线的两种语法,以及在实际工作中该如何选择脚本式语法或声明式语法.原文可查阅:「持续集成实践系列」Jenkins 2.x 搭建CI需要掌握的硬核要 ...
- .NET Core微服务架构学习与实践系列文章索引目录
一.为啥要总结和收集这个系列? 今年从原来的Team里面被抽出来加入了新的Team,开始做Java微服务的开发工作,接触了Spring Boot, Spring Cloud等技术栈,对微服务这种架构有 ...
- .NET Core 微服务学习与实践系列文章目录索引(2019版)
参考网址: https://archy.blog.csdn.net/article/details/103659692 2018年,我开始学习和实践.NET Core,并开始了微服务的学习,以及通过各 ...
- .NET同步与异步之相关背景知识(六)
在之前的五篇随笔中,已经介绍了.NET 类库中实现并行的常见方式及其基本用法,当然.这些基本用法远远不能覆盖所有,也只能作为一个引子出现在这里.以下是前五篇随笔的目录: .NET 同步与异步之封装成T ...
- 【转】RHadoop实践系列之二:RHadoop安装与使用
RHadoop实践系列之二:RHadoop安装与使用 RHadoop实践系列文章,包含了R语言与Hadoop结合进行海量数据分析.Hadoop主要用来存储海量数据,R语言完成MapReduce 算法, ...
随机推荐
- Docker 入门 第六部分:部署app
目录 Docker 入门 第六部分:部署app 先决条件 介绍 选择一个选项 Docker CE(Cloud provider) Enterprise(Cloud provider)这里不做介绍 En ...
- DotNetBar TextBoxDropDown响应按键事件
textBoxDropDownHelp.TextBox.KeyDown += new KeyEventHandler(textBoxDropDownHelp_KeyDown); private voi ...
- Android studio 自动导入(全部)包 import
http://blog.csdn.net/buaaroid/article/details/44979629 1 Android studio 只有import单个包的快捷键:Alt+Enter.没有 ...
- Postfix 邮件服务 - 邮箱组件 cyrus-sasl
cyrus-sasl 简单认证安全层, SASL主要是用于SMTP认证.cyrus-sasl(Simple Authentication Security Layer)简单认证安全层, SASL主要是 ...
- JavaScript之不规则Table转化为可定点索引td节点的网格矩阵【插件】
由于解析课程表的缘故,有如下需求: 1. 将任意表格解析成独立的单元格矩阵[本次博文的缘由] 2. 根据矩阵坐标,确定任意一格的节点 /* 表格-->网格化 标记表格的位置及其对应的节点 * ...
- 参数在一个线程中各个函数之间互相传递的问题(ThreadLocal)
ThreadLocal最常用的地方就是为每个线程绑定一个数据库连接,HTTP请求,用户身份信息等,这样一个线程的所有调用到的处理函数都可以非常方便地访问这些资源. 一个ThreadLocal变量虽然是 ...
- jquery 学习(一) - 选择器
基本选择器(html) <div>123</div> <div id="n1">123</div> <span>321& ...
- wFuzz使用帮助
******************************************************** * Wfuzz 2.0 - The Web Bruteforcer * ******* ...
- struts2在配置文件与JSP中用OGNL获取Action属性
参考:Struts与OGNL结合 struts2在配置文件中可以调用Action的属性,在JSP页面也可以取出Action的属性值(前提是属性有get,set方法). 第一个例子: 1.Action中 ...
- ubuntu14.04 下安装 gsl 科学计算库
GSL(GNU Scientific Library)作为三大科学计算库之一,除了涵盖基本的线性代数,微分方程,积分,随机数,组合数,方程求根,多项式求根,排序等,还有模拟退火,快速傅里叶变换,小波, ...