k8s Pipline CI/CD
一、Pipeline介绍
pipeline是一套jenkins官方提供的插件,它可以用来在jenkins中实现和集成连续交付
用户可以利用Pipeline的许多功能:
代码:pipeline在代码中实现,通常检查到源代码控制,使团队能够编辑,审查和迭代其交付管道。
持久:pipeline可以在Jenkins master的计划内和计划外重启中存活。
Pausable:在继续pipeline运行之前,pipeline可以选择停止并等待人工输入或批准。
多功能:pipeline支持复杂的实际CD要求,包括并行分叉/连接,循环和执行工作的能力。
可扩展:Pipeline插件支持其DSL的自定义扩展 和多个与其他插件集成的选项
二、k8s实现集成/部署/交付
三、创建一个gitlab的测试项目(网上找的简单代码测试)
1、测试代码
代码结构
- [root@node2 test1]# tree
- .
- ├── pom.xml
- └── src
- └── main
- └── java
- └── hello
- ├── Greeter.java
- └── HelloWorld.java
- package hello;
- public class HelloWorld {
- public static void main(String[] args) {
- Greeter greeter = new Greeter();
- System.out.println(greeter.sayHello());
- }
- }
HelloWorld.java
- package hello;
- public class Greeter {
- public String sayHello() {
- return "Hello world!";
- }
- }
Greeter.java
- <?xml version="1.0" encoding="UTF-8"?>
- <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <groupId>org.springframework</groupId>
- <artifactId>gs-maven</artifactId>
- <packaging>jar</packaging>
- <version>0.1.0</version>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-shade-plugin</artifactId>
- <version>2.1</version>
- <executions>
- <execution>
- <phase>package</phase>
- <goals>
- <goal>shade</goal>
- </goals>
- <configuration>
- <transformers>
- <transformer
- implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
- <mainClass>hello.HelloWorld</mainClass>
- </transformer>
- </transformers>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
- </project>
pom.xml
2、git的测试项目
四、jenkins配置
1、插件安装
安装好git、GitLab Plugin、Gitlab Hook Plugin、Gitlab API Plugin、Pipeline、Kubernetes plugin插件。
2、在jenkins中配置kubernetes
3、简单测试(创建一个Pipline项目)
测试的Pipline脚本
- def label = "mypod-${UUID.randomUUID().toString()}"
- podTemplate(label: 'label', cloud: 'kubernetes') {
- node('label') {
- stage('Run shell') {
- sh 'echo hello world'
- }
- }
- }
4、pipline中配置gi凭证
创建凭证,username是gitlab的账号,password是gitlab账号对应的密码。
5、Pipline中视图git凭证
6、重新构建jnlp-slave镜像(添加maven)
- mkdir myjenkins
- cd myjenkins/
- wget https://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.5.4/binaries/apache-maven-3.5.4-bin.tar.gz
- tar xf apache-maven-3.5.-bin.tar.gz
- [root@node2 myjenkins]# cat Dockerfile
- FROM jenkins/jnlp-slave:3.27-
- LABEL maintainer="maven@qq.com"
- ENV MAVEN_HOME /usr/local/maven
- ENV PATH=$PATH:$MAVEN_HOME/bin
- COPY apache-maven-3.5. /usr/local/maven
- [root@node2 myjenkins]# docker build -t myjnlp-slave:1.0 ./
7、配置好镜像仓库(我使用的aliyun)
8、把dokcer组的gid改成10000(容器中jenkins账号的ugid)
- groupmod -g10000 docker
chown root.docker /var/run/docker.sock
9、配置gitlab和jenkins的交互(我使用的webhook方式,并设置提交tag就触发构建)
10、重新更改Pipline脚本,使执行jenkins构建后能直接创建镜像并提交到镜像仓库
Pipline脚本
- def label = "mypod-${UUID.randomUUID().toString()}"
- def registry = "registry-vpc.cn-hongkong.aliyuncs.com"
- def app_name = "javatest"
- def namespace = "aliyun-zhang"
- def username = "xxxxxxxxxxxxxxxxxx"
- def regpass = "xxxxxxxxxxxxxxxxxxx"
- podTemplate(label: 'label', cloud: 'kubernetes', containers: [
- containerTemplate(
- name: 'jnlp',
- image: 'myjnlp-slave:1.0'
- ),
- ],
- volumes: [
- hostPathVolume(mountPath: '/var/run/docker.sock', hostPath: '/var/run/docker.sock'),
- hostPathVolume(mountPath: '/usr/bin/docker', hostPath: '/usr/bin/docker')
- ],)
- {
- node('label') {
- stage('Task') {
- stage('拉取代码') {
- git credentialsId: 'gitlab-auth', url: 'http://mygitlab-gitlab-ce.default.svc.cluster.local/root/test1.git'
- def mytag = sh returnStdout: true, script: 'git describe --always --tag'
- sh "git checkout -b $mytag"
- echo "mytag $mytag ${mytag} ----"
- }
- stage('编译打包') {
- echo "mvn clean package -Dmaven.test.skip=true"
- }
- stage('构建上传镜像') {
- def mytag = sh returnStdout: true, script: 'git describe --always --tag'
- def image_name = "${app_name}:${mytag}".minus("\n")
- echo "image_name $image_name"
- sh label: '', script: ''' echo \'
- FROM tomcat:latest
- ADD pom.xml /usr/local/tomcat/webapps/
- \' > Dockerfile
- '''
- sh """
- docker build -t "${registry}/${namespace}/${image_name}" ./
- docker login -u ${username} -p \"${regpass}\" ${registry}
- docker push ${registry}/${namespace}/${image_name}
- """
- }
- }
- }
- }
11、jenkins构建测试与查看
五、自动部署到k8s集群
1、jenkins下载kubernetes continuous deploy插件(官方文档:https://plugins.jenkins.io/kubernetes-cd)
2、配置kubeconfig凭证
添加 kubeconfig
文件,我选择的是直接粘贴文件内容(master端的.kube/config文件)
3、记录凭证ID值
4、创建一个deploy.yaml文件,并把文件上传到项目的git中
- [root@k8s-m ~]# cat java-deploy.yaml
- apiVersion: apps/v1
- kind: Deployment
- metadata:
- name: mydeploy
- namespace: default
- spec:
- replicas:
- selector:
- matchLabels:
- test_node: k8s-node
- template:
- metadata:
- labels:
- test_node: k8s-node
- spec:
- containers:
- - name: myjava-server
- image: tomcat:latest
- ports:
- - name: http
- containerPort:
5、更改Pipline脚本内容
- def label = "mypod-${UUID.randomUUID().toString()}"
- def registry = "registry-vpc.cn-hongkong.aliyuncs.com"
- def app_name = "javatest"
- def namespace = "aliyun-zhang"
- def username = "xxxxxxxxxxxx"
- def regpass = "xxxxxxxxx"
- def k8s_auth = "5ce0993e-e2e9-4126-a910-2acd0a77fefb"
- podTemplate(label: 'label', cloud: 'kubernetes', containers: [
- containerTemplate(
- name: 'jnlp',
- image: 'myjnlp-slave:1.0'
- ),
- ],
- volumes: [
- hostPathVolume(mountPath: '/var/run/docker.sock', hostPath: '/var/run/docker.sock'),
- hostPathVolume(mountPath: '/usr/bin/docker', hostPath: '/usr/bin/docker')
- ],)
- {
- node('label') {
- stage('Task') {
- stage('拉取代码') {
- git credentialsId: 'gitlab-auth', url: 'http://mygitlab-gitlab-ce.default.svc.cluster.local/root/test1.git'
- def mytag = sh returnStdout: true, script: 'git describe --always --tag'
- sh "git checkout -b $mytag"
- echo "mytag $mytag ${mytag} ----"
- }
- stage('编译打包') {
- sh "mvn clean package -Dmaven.test.skip=true"
- }
- stage('构建上传镜像') {
- def mytag = sh returnStdout: true, script: 'git describe --always --tag'
- def image_name = "${app_name}:${mytag}".minus("\n")
- echo "image_name $image_name"
- sh label: '', script: ''' echo \'
- FROM tomcat:latest
- ADD target/*.jar /usr/local/tomcat/webapps/
- \' > Dockerfile
- '''
- sh """
- docker build -t "${registry}/${namespace}/${image_name}" ./
- docker login -u ${username} -p \"${regpass}\" ${registry}
- docker push ${registry}/${namespace}/${image_name}
- """
- }
- stage('部署到K8S'){
- def mytag = sh returnStdout: true, script: 'git describe --always --tag'
- def image_name = "${app_name}:${mytag}".minus("\n")
- sh """
- sed -i 's#tomcat:latest#${registry}/${namespace}/${image_name}#' java-deploy.yaml
- """
- kubernetesDeploy configs: 'java-deploy.yaml', kubeconfigId: "${k8s_auth}"
- }
- }
- }
- }
6、构建测试
我配置了jenkins和gitlab的webhook配置,提交tag后会自动构建到部署到k8s集群
测试
- [root@node2 test1]# echo >> README.md
- [root@node2 test1]# git commit -a -m ''
- [master bda4c6f]
- file changed, insertion(+), deletion(-)
- [root@node2 test1]# git tag 10.0
- [root@node2 test1]# git push origin master 10.0
- Username for 'http://10.101.58.237': root
- Password for 'http://root@10.101.58.237':
- Counting objects: , done.
- Delta compression using up to threads.
- Compressing objects: % (/), done.
- Writing objects: % (/), bytes | bytes/s, done.
- Total (delta ), reused (delta )
- To http://10.101.58.237/root/test1.git
- da0fbc3..bda4c6f master -> master
- * [new tag] 10.0 -> 10.0
jenkins构建过程
k8s集群查看
- [root@k8s-m ~]# kubectl get deploy mydeploy
- NAME READY UP-TO-DATE AVAILABLE AGE
- mydeploy / 64s
- [root@k8s-m ~]# kubectl get pod
- NAME READY STATUS RESTARTS AGE
- mydeploy-746bb8db64-4fpvz / Running 69s
- mydeploy-746bb8db64-pp7tw / Running 69s
- [root@k8s-m ~]# kubectl get pod mydeploy-746bb8db64-4fpvz -o yaml|grep image:
- - image: registry-vpc.cn-hongkong.aliyuncs.com/aliyun-zhang/javatest:10.0
- image: registry-vpc.cn-hongkong.aliyuncs.com/aliyun-zhang/javatest:10.0
六、版本回滚
基于k8s镜像的回滚还是比较简单的
回滚上一个版本
- kubectl rollout undo deployment/deploy-name
查看历史版本信息
- #查看 deployment 升级历史
- [root@k8s-m ~]# kubectl rollout history deployment/mydeploy
- deployment.extensions/mydeploy
- REVISION CHANGE-CAUSE
- <none>
- <none>
- #看历史版本更加详细的升级信息
- [root@k8s-m ~]# kubectl rollout history deployment/mydeploy --revision=
- deployment.extensions/mydeploy with revision #
- Pod Template:
- Labels: pod-template-hash=746bb8db64
- test_node=k8s-node
- Containers:
- myjava-server:
- Image: registry-vpc.cn-hongkong.aliyuncs.com/aliyun-zhang/javatest:10.0
- Port: /TCP
- Host Port: /TCP
- Environment: <none>
- Mounts: <none>
- Volumes: <none>
回滚指定版本
- kubectl rollout undo deployment/mydeploy --to-revision=
回滚指定版本2
直接修改delpoy中的镜像
七、Deployment升级策略
1、介绍
deployment 有 2 种策略,分别是Recreate和RollingUpdate,RollingUpdate是默认的策略
RollingUpdate也有相对应的升级策略,如果策略设置的不合理,那么升级的过程就有可能导致服务中断
Max Unavailable
最多有几个 pod 处于无法工作的状态,默认值是25%
Max Surge
升级过程中可以比预设的 pod 的数量多出的个数,默认值是25%
minReadySeconds
等待容器启动的时间,默认值是 0,单位是:秒,容器运行成功之后直接执行下一步
根据应用启动时间,设定相应的minReadySeconds,保证应用不中断
2、查看deploy的更新策略
- [root@k8s-m recreate]# kubectl explain deploy.spec.strategy.type
- KIND: Deployment
- VERSION: extensions/v1beta1
- FIELD: type <string>
- DESCRIPTION:
- Type of deployment. Can be "Recreate" or "RollingUpdate". Default is
- RollingUpdate.
3、recreate策略测试
结论:recreate方式会先停止所有就版本,停止完后才部署新版本
- [root@k8s-m ~]# kubectl get pod -w
- NAME READY STATUS RESTARTS AGE
- my-app-bb9cc7597-dn5bv / Running 3m36s
- my-app-bb9cc7597-gqfx4 / Running 3m36s
- my-app-bb9cc7597-p4dfb / Running 3m36s
- my-app-bb9cc7597-p4dfb / Terminating 3m44s
- my-app-bb9cc7597-dn5bv / Terminating 3m44s
- my-app-bb9cc7597-gqfx4 / Terminating 3m44s
- my-app-bb9cc7597-p4dfb / Terminating 3m45s
- my-app-bb9cc7597-gqfx4 / Terminating 3m45s
- my-app-bb9cc7597-dn5bv / Terminating 3m45s
- my-app-bb9cc7597-p4dfb / Terminating 3m57s
- my-app-bb9cc7597-p4dfb / Terminating 3m57s
- my-app-db47b56bf-kwd2c / Pending 0s
- my-app-db47b56bf-kwd2c / Pending 0s
- my-app-db47b56bf-xkqdz / Pending 0s
- my-app-db47b56bf-5v4r5 / Pending 0s
- my-app-db47b56bf-xkqdz / Pending 0s
- my-app-db47b56bf-kwd2c / ContainerCreating 0s
4、RollingUpdate策略测试
结论: 一个接一个地以滚动更新方式发布新版本,滚动的方式可以定义,即先删除多少pod在添加多少pod,或者是闲添加在删除。
- [root@k8s-m ~]# kubectl get pod -w
- NAME READY STATUS RESTARTS AGE
- my-app-db47b56bf-2c2c6 / Running 19s
- my-app-db47b56bf-k7k5z / Running 19s
- my-app-db47b56bf-mclj8 / Running 19s
- my-app-bb9cc7597-hgz6r / Pending 0s
- my-app-bb9cc7597-hgz6r / Pending 0s
- my-app-bb9cc7597-hgz6r / ContainerCreating 1s
- my-app-bb9cc7597-hgz6r / ContainerCreating 1s
- my-app-bb9cc7597-hgz6r / Running 5s
- my-app-bb9cc7597-hgz6r / Running 6s
- my-app-db47b56bf-mclj8 / Terminating 29s
- my-app-bb9cc7597-84ngs / Pending 0s
- my-app-bb9cc7597-84ngs / Pending 0s
- my-app-bb9cc7597-84ngs / ContainerCreating 1s
- my-app-bb9cc7597-84ngs / ContainerCreating 2s
- my-app-db47b56bf-mclj8 / Terminating 31s
- my-app-db47b56bf-mclj8 / Terminating 34s
- my-app-db47b56bf-mclj8 / Terminating 34s
- my-app-bb9cc7597-84ngs / Running 6s
- my-app-bb9cc7597-84ngs / Running 7s
- [root@k8s-m recreate]# kubectl explain deploy.spec.strategy.rollingUpdate
- KIND: Deployment
- VERSION: extensions/v1beta1
- RESOURCE: rollingUpdate <Object>
- DESCRIPTION:
- Rolling update config params. Present only if DeploymentStrategyType =
- RollingUpdate.
- Spec to control the desired behavior of rolling update.
- FIELDS:
- maxSurge <string>
- The maximum number of pods that can be scheduled above the desired number
- of pods. Value can be an absolute number (ex: ) or a percentage of desired
- pods (ex: %). This can not be if MaxUnavailable is . Absolute number
- is calculated from percentage by rounding up. By default, a value of is
- used. Example: when this is set to %, the new RC can be scaled up
- immediately when the rolling update starts, such that the total number of
- old and new pods do not exceed % of desired pods. Once old pods have
- been killed, new RC can be scaled up further, ensuring that total number of
- pods running at any time during the update is at most % of desired pods.
- maxUnavailable <string>
- The maximum number of pods that can be unavailable during the update. Value
- can be an absolute number (ex: ) or a percentage of desired pods (ex:
- %). Absolute number is calculated from percentage by rounding down. This
- can not be if MaxSurge is . By default, a fixed value of is used.
- Example: when this is set to %, the old RC can be scaled down to % of
- desired pods immediately when the rolling update starts. Once new pods are
- ready, old RC can be scaled down further, followed by scaling up the new
- RC, ensuring that the total number of pods available at all times during
- the update is at least % of desired pods.
5、其它更新策略(金丝雀等)
https://zhuanlan.zhihu.com/p/55964678
k8s Pipline CI/CD的更多相关文章
- k8s、CI/CD、pipline介绍
参照文档: https://blog.csdn.net/qq_35299863/article/details/84329798 https://github.com/xgh2016/k8s-CICD ...
- k8s Gitlab CI/CD 之自动编译Docker镜像并推送到指定的Registry
环境介绍: 说明 节点 ip 系统 Gitlab Server git.ds.com 10.0.1.179 CentOS 7.5.1804 Gitlab Runner 10.0.1.178 Cen ...
- forge k8s/kubernetes ci/cd 最佳实践
forge的官网是: http://forge.sh forge工具是一个部署工具, 将你的应用自动更新到kubernets集群中, 只需要配置简洁的配置文件和模板即可. 其它的就交给forge, 它 ...
- 实例演示:如何在Kubernetes上大规模运行CI/CD
本周四晚上8:30,第二期k3s在线培训如约开播!本期课程将介绍k3s的核心架构,如高可用架构以及containerd.一起来进阶探索k3s吧! 报名及观看链接:http://z-mz.cn/PmwZ ...
- .Net Core2.1 秒杀项目一步步实现CI/CD(Centos7.2)系列一:k8s高可用集群搭建总结以及部署API到k8s
前言:本系列博客又更新了,是博主研究很长时间,亲自动手实践过后的心得,k8s集群是购买了5台阿里云服务器部署的,这个集群差不多搞了一周时间,关于k8s的知识点,我也是刚入门,这方面的知识建议参考博客园 ...
- Jenkins和Gitlab CI/CD自动更新k8s中pod使用的镜像说明
Jenkins 使用Jenkins的话,完成的工作主要有如下步骤: 1.从Gogs或Gitlab仓库上拉取代码 2.使用Maven编译代码,打包成jar文件 3.根据jar文件使用相对应的Docker ...
- 超详细实操教程!在现有K8S集群上安装JenkinsX,极速提升CI/CD体验!
在2018年年初,Jenkins X首次发布,它由Apache Groovy语言的创建者Jame Strachan创建.Jenkins X 是一个高度集成化的 CI/CD 平台,基于 Jenkins ...
- 手把手详解持续集成之GitLab CI/CD
一.环境准备 首先需要有一台 GitLab 服务器,然后需要有个项目:这里示例项目以 Spring Boot 项目为例,然后最好有一台专门用来 Build 的机器,实际生产中如果 Build 任务不频 ...
- Jenkins 基于 Docker git JAVA CI/CD
准备两台机器 192.168.31.200 centos7 docker harbor git 192.168.31.201 centos7 docker jenkins maven git Ha ...
随机推荐
- 大白话原型模式(Prototype Pattern)
意图 原型模式是创建型设计模式,可以复制已存在的对象而无需依赖它的类. 问题 假如现在有一个对象,我们想完全复制一份新的,我们该如何做? 创建同一个类的新对象 遍历所有已存在对象的值,然后将他们的值复 ...
- django count(*) 慢查询优化
分页显示是web开发常见需求,随着表数据增加,200万以上时,翻页越到后面越慢,这个时候慢查询成为一个痛点,关于count(*)慢的原因,简单说会进行全表扫描,再排序,导致查询变慢.这里介绍postg ...
- playbooks框架部署远程主机
进入到ansible和python环境 进入python3.6虚拟环境 #su - deploy #source .py3-a2.5-env/bin/activate 加载ansible 2.5版本 ...
- 一行代码去掉Devexpress弹窗
使用的是.net hook方法: 使用代码: using System; using System.Windows.Forms; namespace AlexDevexpressToolTest { ...
- http的异步请求
需要用到的包(包版本应该可能不同): httpcore-4.1.4.jar httpsayncclient-4.0-alpha3.jar httpcore-nio-4.2-alpha3.jar /** ...
- jdbc实现批量提交rollback
最近上了一个老项目,要修改一些业务,具体的思路是在jsp中实现对数据的某些批量操作,因此做一下笔记. 1.整体jdbc建立连接/关闭连接 conn = DbUtil.getConnection(); ...
- Beat our dice game and get the flag 击败我们的骰子游戏拿到旗子
文件名:ebCTF-Teaser-BIN100-Dice.exe 话不多说 用PEID一看没壳 拖进OD 让我们摇出31337这五个数字才能拿到正确的flag cmp dword ptr ss:[eb ...
- IO系统-基本知识
注:本文档主要整理了Linux下IO系统的基本知识,是整理的网易云课堂的学习笔记,老师讲得很不错,链接如下:Linux IO系统 1.Linux操作系统的基本构成 内核:操作系统的核心,负责管理系统的 ...
- DFS(深度优先搜索遍历有向图)-03-有向图-太平洋大西洋水流问题
给定一个 m x n 的非负整数矩阵来表示一片大陆上各个单元格的高度.“太平洋”处于大陆的左边界和上边界,而“大西洋”处于大陆的右边界和下边界. 规定水流只能按照上.下.左.右四个方向流动,且只能从高 ...
- python笔记11
今日内容 函数小高级 lambda 表达式 内置函数 内容回顾 函数基本结构 参数 形参 基本参数:def func(a1,a2):pass 默认值:def func(a1,a2=123):pass ...