业务实战场景(十五)Devops之Jenkins持续交付基于K8S

目录

  • 系列总目录
  • 前提
    • 背景
    • 服务器
  • 整体架构
    • Jenkins之CI
    • Jenkins之CD
    • K8s部署并且对外暴露
  • 实战前置
    • Centos7安装Jenkins
    • Git安装
    • Maven安装
  • 远程SSH安装
    • K8S安装
      • shell脚本
      • KubeSphere
    • Nginx
  • 实战Jenkins
    • 配置git源码
    • 构建第一步,mvn编译
    • 构建第二步,上传到dockerhub
    • 构建第三步远程执行上面的shell脚本
    • 执行所有pipeline
  • 进阶
    • Jenkins结合Ansible
    • Walle
    • 项目K8s部署
  • 参考文章

系列总目录


前提

背景

  • 本文的例子是将SpringBoot项目持续集成,并持续交付到K8S部署,例子的主要目的是学习Jenkins持续集成,不作为生产使用

服务器

  • 采用的是腾讯云Centos7,2C4G,Jenkins是部署在腾讯云物理机上,而非Docker上面,之前本地MAC部署Jenkins在执行流水线Docker命令踩了坑,处理起来比较麻烦于是直接在Centos物理机上部署

整体架构

整体架构.png

Jenkins之CI

  • 从GIT上拉取代码
  • 使用mvn命令打包
  • docker推送到DockerHub私有远程仓库
  • 中间可以加一些比如单元测试检验,SonarQube静态检查等

Jenkins之CD

  • 远程到K8S master节点执行编写好的远程脚本,因为这里只是为了体验Devops功能,并不做生产使用,所以简单处理,而不是链接K8s的apiserver处理

K8s部署并且对外暴露

  • K8s删除旧的service和deployment,然后执行部署命令Kubectl apply -f配置,SpringBoot服务就可以部署起来了,这里只是demo, 所以没考虑不停机更新,灰度,回滚等

实战前置

Centos7安装Jenkins

  • 参考官网的指令安装Jenkins的Jenkins Redhat Packages, 这里是把JDK也安装了,安装完可以java -version看看
sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key
yum install fontconfig java-11-openjdk
yum install jenkins
  • 安装之后开启Jenkins之旅
sudo systemctl enable jenkins
sudo systemctl start jenkins
  • 如果启动不了看看jenkins状态是不是在安装中
sudo systemctl status jenkins
  • 本文是采用腾讯云的轻量应用服务器,为了方便本地MAC访问,增加了轻量服务器网关端口开放,本地MAC就可以用腾讯云公网Ip + 8080端口访问Jenkins了
  • 输入安装之后配置的密码,然后选择安装推荐插件,等待完成


    Jenkins.png

Git安装

yum -y install git
git --version

Maven安装

  • 下载maven
wget https://dlcdn.apache.org/maven/maven-3/3.8.6/binaries/apache-maven-3.8.6-bin.tar.gz 
  • 解压
tar -zxvf apache-maven-3.8.6-bin.tar.gz
mv apache-maven-3.8.6 /usr/local/maven/
  • 配置环境变量
export MAVEN_HOME=/usr/local/maven
export PATH=$PATH:$MAVEN_HOME/bin
  • 刷新并查看
source /etc/profile
mvn -v
  • 替换
vim /usr/local/maven/conf/settings.xml
# 找到<mirrors></mirrors>标签对,添加以下内容
<mirror>
   <id>alimaven</id>
    <name>aliyun maven</name>
    <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
    <mirrorOf>central</mirrorOf>
    <releases>
        <enabled>true</enabled>
        <updatePolicy>always</updatePolicy>
    </releases>
    <snapshots>
        <enabled>true</enabled>
        <updatePolicy>always</updatePolicy>
    </snapshots>
</mirror>

远程SSH安装

  • 正常情况下是连接k8s的apiserver手把手教你用 Jenkins + K8S 打造流水线环境,但是本文是dev体验devops功能,所以简单ssh连接到K8s的master宿主机,然后执行写的的K8s部署脚本
  • Jenkins安装远程SSH插件,选择插件管理


    插件安装1.png
  • 在可选插件选择SSH第一个


    插件安装2.png
  • 等待安装完成,然后重启Jenkins, 可以手动ip:8080/restart重启
  • 然后配置k8s的master节点对应的宿主机


    配置SSH.png
  • 需要配置hostname也就是腾讯云的公网ip, 凭证就需要添加,点2下面的添加选择Jenkins全局,输入腾讯云用户账号密码,不要root账号注意,忘记密码可以直接用root账号改密码,修改密码 linux修改密码,root账号输入password xxx可修改
    配置SSH_2.jpg

    配置SSH_3.png
  • 然后测试连接OK的话保存

K8S安装

  • 本文使用minikube安装K8s集群,目的是为了体验功能,参考了 CentOS 7安装minikube,安装步骤安装下来即可
  • minikube start我这边直接底下命令启动
minikube start --image-mirror-country='cn'
K8s部署服务并对外暴露
  • 新建一个springboot-demo项目,demo的话只需要springboot里面加个简单的controller,并没maven管理
  • pom文件
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.0</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
  • 在根目录底下(src同级)新建dockerfile
FROM java:8
COPY target/demo-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
  • dockerhub里面注册账号
  • deployment.yaml文件, 这里面Service将会以nodePort的形式对外暴露,端口为31999,springboot项目服务端口是8888,k8s对外暴露了一个端口为31999的springboot-demo服务
apiVersion: v1
kind: Service
metadata:
  name: springboot-demo
  namespace: default
  labels:
    app: springboot-demo
spec:
  type: NodePort
  ports:
    - port: 8888
      nodePort: 31999
  selector:
    app: springboot-demo
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: springboot-demo
  labels:
    app: springboot-demo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: springboot-demo
  template:
    metadata:
      labels:
        app: springboot-demo
    spec:
      containers:
        - name: springboot-demo
          image: XXX(你dockerhub的项目前缀)/springboot-demo:latest
          imagePullPolicy: Always
          ports:
            - containerPort: 8888
  • 本地Mac或者Windows将项目推送到DockerHub,需要先docker login你的远程dockerhub项目
  • 腾讯云服务器执行以下命令
kubectl apply -f deployment.yaml
  • 查看service, 能看到springboot-demo说明启动成功,刚开始K8s拉取远程Dockerhub的springboot-demo项目比较慢,耐心等待
kubectl get service
service.png
  • 查看deployment,这里都是默认命令空间所有不用加-n
kubectl get deployment
deployment.png
  • 如果启动有问题也可以查看日志先kubectl get pods


    pods.png
  • 然后查看pod的日志 kubectl logs springboot-demo-67bfb65c5d-nqhpl -f


    pod的日志.png
  • 本地访问测试, 查看K8s集群信息, kubectl cluster-info,看到对应的Ip地址,然后curl一下看下springboot-demo能不能访问到


    访问.png
  • 想要本地Mac外网访问,需要开启腾讯云防火墙端口规则,并且安装Nginx对外暴露,Nginx下面讲到


    开启腾讯云防火墙端口规则.png
ssh脚本
  • 在/shell目录底下touch一个test.sh,先删除部署的service和deployment, 然后重新部署,更高级的版本回退等在这里不体验了, 有兴趣可以体验下这里K8S 滚动升级与回滚
#!/bin/bash
echo deploy start
cd /home/xxx
pwd
kubectl delete service springboot-demo
kubectl delete deployment springboot-demo
kubectl apply -f deployment.yaml
# kubectl get pods -A
echo deploy end
KubeSphere
wget https://github.com/kubesphere/ks-installer/releases/download/v3.3.0/kubesphere-installer.yaml
wget https://github.com/kubesphere/ks-installer/releases/download/v3.3.0/cluster-configuration.yaml
  • 如果要体验devops功能,请先编译下cluster-configuration.yaml,里面有个devops开关,默认false,给他开启来,因为我腾讯只有4g内存,所以先关了jenkins等其他功能才能开kubespere,当然小于4g内存的就用不了kubesphere的devops等功能了
  • 开始部署
kubectl apply -f kubesphere-installer.yaml
   
kubectl apply -f cluster-configuration.yaml

  • 过程比较慢可以查看日志
kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l 'app in (ks-install, ks-installer)' -o jsonpath='{.items[0].metadata.name}') -f

  • 成功之后可以看到kubeshere的界面,比原生好看很多


    集群部署界面
  • devops功能开启后可以体验,这个网上可以找资料体验下
  • 本地想要访问远程的腾讯云部署的kubesphere,依然需要开启腾讯云防火墙端口,并且nginx开放端口

Nginx

sudo yum install -y epel-release
sudo yum -y update
sudo yum install -y nginx
  • 腾讯云防火墙打开对应的端口,测试环境我这边全开了
  • 启动重启nginx, 还有开机启动
systemctl start nginx
systemctl restart nginx
systemctl enable nginx
  • nginx配置, 192.168.49.2是我本地docker的ip, 通过kubectl cluster-info可以看到
# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
        }

        location /k8s-test {
            proxy_pass http://192.168.49.2:31999/test;
        }

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }

    server {
        listen    8888;

        location / {
              proxy_pass http://192.168.49.2:30880;
        }
    }

    server {
        listen    8889;

        location / {
              proxy_pass http://192.168.49.2:32183;

        }
    }

}
  • 本地mac访问


    本地mac访问

实战Jenkins

  • 安装上面前置配置,配置好了之后,新建一个任务叫springboot-demo,然后就是配置流水线执行, 新建任务选择自由风格

配置git源码

  • 1选择gitee地址 2填上面配置好的凭证,然后底下分支选择master


    配置git源码.png

构建第一步,mvn编译

  • 构建第一步,构建时选择调用顶层 Maven 目标,clean package -Dmaven.test.skip=true


    构建第一步,mvn编译.png

构建第二步,上传到dockerhub

  • 里面XXX需要改成你对应的dockerhub的项目,账户密码,构建时选择执行 shell , 项目名称可以自己本地编译下就知道了


    项目名称
docker build -f Dockerfile --build-arg jar_name=target/demo-0.0.1-SNAPSHOT.jar -t springboot-demo:latest . 
docker tag  springboot-demo:latest  XXX/springboot-demo:latest
docker login --username=XXX -p XXX
docker push XXX/springboot-demo:latest
构建第二步,上传到dockerhub

构建第三步远程执行上面的shell脚本

  • XXX改成自己的远程服务器配置的用户名,test.sh脚本上面讲到是放到shell目录底下,构建时选择Execute shell script on remote host using ssh
hostname
cd /home/XXX/shell
pwd
sh test.sh
构建第三步远程执行上面的shell脚本

执行所有pipeline

  • 注意Jenkins第一次跑时,要拉很多依赖跑的会比较慢, 耐心等待即可

  • 点新建的任务


    点新建的任务
  • 立即构建


    立即构建
  • 查看结果,截图那个16可以点进去看看


    查看结果,截图那个16可以点进去看看
  • 看下控制台输出


    看下控制台输出
  • 先按照流程从git拉下来,然后编译


    查看

    git拉取

    mvn打包
  • 熟悉的编译


    image.png
  • 然后执行推送dockhub,然后执行远程SSH,然后成功


    image.png

进阶

Jenkins结合Ansible

Walle

项目K8s部署


参考文章

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,864评论 6 494
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,175评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,401评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,170评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,276评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,364评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,401评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,179评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,604评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,902评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,070评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,751评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,380评论 3 319
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,077评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,312评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,924评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,957评论 2 351