Jenkins-X构建Java应用

Posted by Zeusro on March 16, 2019
👈🏻 Select language

Jenkins-X默认提供了不同语言的各种例子,我们先学习默认的例子,再按照自身情况做一些适配.

先梳理一下构建流程

从git server(GitHub/gitea)拉取代码->构建docker镜像->推送到镜像仓库

建议一开始用jx create创建官方的例子,推送到 GitHub,熟悉以后再慢慢修改

1
2
3
4
5
6
7
8
9
10
11
12
13
jx create spring -d web -d actuator
jx create quickstart -l java
jx create quickstart \
 -l java \
 --docker-registry-org zeusro \
 --git-username zeusro \
 --org  zeusro \
 --git-provider-kind gitea \
 --git-provider-url  https://gitea.com \
 --git-host  https://gitea.com  \
 --import-commit-message init \
 --name java-abcde \
 --project-name  java-abcde

前置准备

Disable https certificate check

域名没证书的得勾上,路径在Manage Jenkins-Configure System

修改 Kubernetes Pod Template

Jenkins是拉取到Jenkins的工作目录(服务器),而Jenkins-X是根据设置的模板启动启动一个pod,这个pod有2个容器,一个是jnlp-slave,另外一个是构建工具的镜像,如果是gradle构建的话镜像就是gcr.io/jenkinsxio/builder-gradle.

所以需要一下模板.路径在Manage Jenkins-Configure System-Images-Kubernetes Pod Template,按照特定构建语言迁移,修改.

依赖项加速

  • maven加速
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="utf-8"?>
<settings xmlns="https://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
  <mirrors>
    <mirror>
      <id>alimaven</id>
      <mirrorOf>central</mirrorOf>
      <name>aliyun maven</name>
      <url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
    </mirror>
  </mirrors>
  <profiles>
    <profile/>
  </profiles>
</settings>
  • gradle加速
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
allprojects {
    apply plugin: 'maven'
    group = 'com.hh.onekey'
    version = '2.0.0'
}
subprojects {
    apply plugin: 'java'
    sourceCompatibility = 1.8
    targetCompatibility = 1.8

    repositories {
        mavenLocal()
        maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
        maven { url 'https://maven.aliyun.com/nexus/content/repositories/jcenter' }
        maven { url "https://plugins.gradle.org/m2/" }
    }


    dependencies {
        testCompile group: 'junit', name: 'junit', version: '4.12'
    }
}

allprojects {
    repositories {
        mavenLocal()
        maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
        maven { url 'https://maven.aliyun.com/nexus/content/repositories/jcenter' }
        maven { url "https://plugins.gradle.org/m2/" }
    }
}

构建前置依赖

有3种思路,任选一种即可.推荐第一种

[推荐]交付到mvn local

这个思路是在我构建缓存时想到的.普通的pipeline构建流程,每次构建都是一个从零开始的沙箱,需要重新下载包再去构建.非常浪费流量.因此如果把mvnlocal挂载到容器内部,那么直接在本地还原即可,有问题时再从网络拉取.

这样就能同时解决构建前置依赖开源依赖拉取的问题

目前支持的volume有

  1. PVC
  2. NFS
  3. hostpath

推荐用NFS.

gradle:挂载到/root/.gradle/caches

maven:挂载到/root/.mvnrepository

交付给Nexus

todo

关联其他pipeline

todo

从其他git server(gitea)拉取代码

1
2
3
jx create git server gitea http://xxx:1080
# jx delete git server gitea
jx get git

目前删除的命令还比较蠢,只能按类型删除,如果加了2个gitea类型的git server,删除的时候会先删除最早创建的那个gitea server

构建docker镜像

构建依赖于项目内的JenkinsfileDockerfile

关于Jenkinsfile的语法,另写一篇文章讲解

推送docker镜像到自定义源

  • 修改DOCKER_REGISTR

默认的设定是推送到创建Jenkins-X时建立的docker REGISTRY,要把它改成我们自己的服务器

配置路径: Manage Jenkins-Global properties

修改DOCKER_REGISTRY这个变量

1
2
# 阿里云深圳vpc
registry-vpc.cn-shenzhen.aliyuncs.com/
1
2
3
4
jx create docker auth \
--host "registry-vpc.cn-shenzhen.aliyuncs.com" \
--user "foo" --secret "FooDockerHubToken" \
--email "[email protected]"

之后在部署该Jenkins-X实例的kubernetes 命名空间,会出现jenkins-docker-cfg的secret,这个secret是一个json

1
2
3
4
5
6
7
8
{
	"auths": {
		"registry-vpc.cn-shenzhen.aliyuncs.com": {
			"auth": "xxxxxxxxxx",
			"email": "[email protected]"
		}
	}
}

要让容器通过这个json里面的auth字段,实现对docker registry的登录.

所以还需要把这个secret挂载到容器内部,还好这一步默认的pod template已经设置了.

Image

除此以外,还有其他的授权方法

参考链接:

  1. Jenkins X构建例子
  2. pod-templates
  3. 基于 Kubernetes 实践弹性的 CI/CD 系统

Jenkins-X provides various examples for different languages by default. We first learn the default examples, then adapt them according to our own situation.

First, let’s understand the build process:

Pull code from git server (GitHub/gitea) -> Build docker image -> Push to image registry

It’s recommended to use jx create to create official examples at the beginning, push to GitHub, and then slowly modify after getting familiar.

1
2
3
4
5
6
7
8
9
10
11
12
13
jx create spring -d web -d actuator
jx create quickstart -l java
jx create quickstart \
 -l java \
 --docker-registry-org zeusro \
 --git-username zeusro \
 --org  zeusro \
 --git-provider-kind gitea \
 --git-provider-url  https://gitea.com \
 --git-host  https://gitea.com  \
 --import-commit-message init \
 --name java-abcde \
 --project-name  java-abcde

Prerequisites

Disable https certificate check

For domains without certificates, check this. Path: Manage Jenkins-Configure System

Modify Kubernetes Pod Template

Jenkins pulls to Jenkins’ working directory (server), while Jenkins-X starts a pod based on the configured template. This pod has 2 containers, one is jnlp-slave, and the other is the build tool image. If it’s a gradle build, the image is gcr.io/jenkinsxio/builder-gradle.

So you need the following template. Path: Manage Jenkins-Configure System-Images-Kubernetes Pod Template, migrate and modify according to specific build language.

Dependency Acceleration

  • maven acceleration
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="utf-8"?>
<settings xmlns="https://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
  <mirrors>
    <mirror>
      <id>alimaven</id>
      <mirrorOf>central</mirrorOf>
      <name>aliyun maven</name>
      <url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
    </mirror>
  </mirrors>
  <profiles>
    <profile/>
  </profiles>
</settings>
  • gradle acceleration
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
allprojects {
    apply plugin: 'maven'
    group = 'com.hh.onekey'
    version = '2.0.0'
}
subprojects {
    apply plugin: 'java'
    sourceCompatibility = 1.8
    targetCompatibility = 1.8

    repositories {
        mavenLocal()
        maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
        maven { url 'https://maven.aliyun.com/nexus/content/repositories/jcenter' }
        maven { url "https://plugins.gradle.org/m2/" }
    }


    dependencies {
        testCompile group: 'junit', name: 'junit', version: '4.12'
    }
}

allprojects {
    repositories {
        mavenLocal()
        maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
        maven { url 'https://maven.aliyun.com/nexus/content/repositories/jcenter' }
        maven { url "https://plugins.gradle.org/m2/" }
    }
}

Build Prerequisites

There are 3 approaches, choose any one. The first is recommended.

This idea came to me when building cache. In a normal pipeline build process, each build is a sandbox from scratch, requiring re-downloading packages before building. Very wasteful of traffic. So if mvnlocal is mounted inside the container, then directly restore locally, and pull from network when there are problems.

This can solve both the build prerequisites and open source dependency pulling problems.

Currently supported volumes are:

  1. PVC
  2. NFS
  3. hostpath

NFS is recommended.

gradle: Mount to /root/.gradle/caches

maven: Mount to /root/.mvnrepository

Deliver to Nexus

todo

Associate Other Pipelines

todo

Pull Code from Other git server (gitea)

1
2
3
jx create git server gitea http://xxx:1080
# jx delete git server gitea
jx get git

Currently the delete command is still quite stupid, can only delete by type. If 2 gitea-type git servers are added, when deleting, it will delete the earliest created gitea server first.

Build docker Image

Build depends on Jenkinsfile and Dockerfile in the project.

Regarding Jenkinsfile syntax, I’ll write another article to explain.

Push docker Image to Custom Registry

  • Modify DOCKER_REGISTR

The default setting is to push to the docker REGISTRY established when creating Jenkins-X. We need to change it to our own server.

Configuration path: Manage Jenkins-Global properties

Modify the DOCKER_REGISTRY variable

1
2
# Alibaba Cloud Shenzhen vpc
registry-vpc.cn-shenzhen.aliyuncs.com/
1
2
3
4
jx create docker auth \
--host "registry-vpc.cn-shenzhen.aliyuncs.com" \
--user "foo" --secret "FooDockerHubToken" \
--email "[email protected]"

After that, in the kubernetes namespace where this Jenkins-X instance is deployed, a secret named jenkins-docker-cfg will appear. This secret is a json.

1
2
3
4
5
6
7
8
{
	"auths": {
		"registry-vpc.cn-shenzhen.aliyuncs.com": {
			"auth": "xxxxxxxxxx",
			"email": "[email protected]"
		}
	}
}

To let containers log into the docker registry through the auth field in this json.

So this secret also needs to be mounted inside the container. Fortunately, the default pod template has already set this step.

Image

Besides this, there are other authorization methods

  1. Jenkins X Build Examples
  2. pod-templates
  3. Practicing Elastic CI/CD Systems Based on Kubernetes

Jenkins-X по умолчанию предоставляет различные примеры для разных языков. Сначала мы изучаем примеры по умолчанию, затем адаптируем их согласно нашей собственной ситуации.

Сначала давайте разберемся с процессом сборки:

Получить код с git-сервера (GitHub/gitea) -> Собрать docker-образ -> Отправить в реестр образов

Рекомендуется использовать jx create для создания официальных примеров в начале, отправить в GitHub, а затем медленно изменять после ознакомления.

1
2
3
4
5
6
7
8
9
10
11
12
13
jx create spring -d web -d actuator
jx create quickstart -l java
jx create quickstart \
 -l java \
 --docker-registry-org zeusro \
 --git-username zeusro \
 --org  zeusro \
 --git-provider-kind gitea \
 --git-provider-url  https://gitea.com \
 --git-host  https://gitea.com  \
 --import-commit-message init \
 --name java-abcde \
 --project-name  java-abcde

Предварительные требования

Отключить проверку https-сертификата

Для доменов без сертификатов установите это. Путь: Manage Jenkins-Configure System

Изменить Kubernetes Pod Template

Jenkins получает в рабочий каталог Jenkins (сервер), в то время как Jenkins-X запускает под на основе настроенного шаблона. Этот под имеет 2 контейнера, один — jnlp-slave, а другой — образ инструмента сборки. Если это сборка gradle, образ — gcr.io/jenkinsxio/builder-gradle.

Поэтому вам нужен следующий шаблон. Путь: Manage Jenkins-Configure System-Images-Kubernetes Pod Template, мигрируйте и изменяйте в соответствии с конкретным языком сборки.

Ускорение зависимостей

  • ускорение maven
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="utf-8"?>
<settings xmlns="https://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
  <mirrors>
    <mirror>
      <id>alimaven</id>
      <mirrorOf>central</mirrorOf>
      <name>aliyun maven</name>
      <url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
    </mirror>
  </mirrors>
  <profiles>
    <profile/>
  </profiles>
</settings>
  • ускорение gradle
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
allprojects {
    apply plugin: 'maven'
    group = 'com.hh.onekey'
    version = '2.0.0'
}
subprojects {
    apply plugin: 'java'
    sourceCompatibility = 1.8
    targetCompatibility = 1.8

    repositories {
        mavenLocal()
        maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
        maven { url 'https://maven.aliyun.com/nexus/content/repositories/jcenter' }
        maven { url "https://plugins.gradle.org/m2/" }
    }


    dependencies {
        testCompile group: 'junit', name: 'junit', version: '4.12'
    }
}

allprojects {
    repositories {
        mavenLocal()
        maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
        maven { url 'https://maven.aliyun.com/nexus/content/repositories/jcenter' }
        maven { url "https://plugins.gradle.org/m2/" }
    }
}

Предпосылки сборки

Есть 3 подхода, выберите любой. Первый рекомендуется.

[Рекомендуется] Доставить в mvn local

Эта идея пришла мне в голову при сборке кэша. В обычном процессе сборки pipeline каждая сборка — это песочница с нуля, требующая повторной загрузки пакетов перед сборкой. Очень расточительно по трафику. Поэтому, если mvnlocal смонтирован внутри контейнера, то можно напрямую восстановить локально, а при проблемах загрузить из сети.

Это может решить как проблему предпосылок сборки, так и проблему загрузки зависимостей с открытым исходным кодом.

В настоящее время поддерживаемые тома:

  1. PVC
  2. NFS
  3. hostpath

Рекомендуется NFS.

gradle: Монтировать в /root/.gradle/caches

maven: Монтировать в /root/.mvnrepository

Доставить в Nexus

todo

Связать с другими pipeline

todo

Получить код с другого git-сервера (gitea)

1
2
3
jx create git server gitea http://xxx:1080
# jx delete git server gitea
jx get git

В настоящее время команда удаления все еще довольно глупа, может удалять только по типу. Если добавлено 2 git-сервера типа gitea, при удалении сначала удалится самый ранний созданный gitea-сервер.

Собрать docker-образ

Сборка зависит от Jenkinsfile и Dockerfile в проекте.

Что касается синтаксиса Jenkinsfile, я напишу другую статью для объяснения.

Отправить docker-образ в пользовательский реестр

  • Изменить DOCKER_REGISTR

Настройка по умолчанию — отправка в docker REGISTRY, созданный при создании Jenkins-X. Нужно изменить на наш собственный сервер.

Путь конфигурации: Manage Jenkins-Global properties

Изменить переменную DOCKER_REGISTRY

1
2
# Alibaba Cloud Shenzhen vpc
registry-vpc.cn-shenzhen.aliyuncs.com/
1
2
3
4
jx create docker auth \
--host "registry-vpc.cn-shenzhen.aliyuncs.com" \
--user "foo" --secret "FooDockerHubToken" \
--email "[email protected]"

После этого в пространстве имен kubernetes, где развернут этот экземпляр Jenkins-X, появится секрет с именем jenkins-docker-cfg. Этот секрет — это json.

1
2
3
4
5
6
7
8
{
	"auths": {
		"registry-vpc.cn-shenzhen.aliyuncs.com": {
			"auth": "xxxxxxxxxx",
			"email": "[email protected]"
		}
	}
}

Чтобы контейнеры могли войти в docker-реестр через поле auth в этом json.

Поэтому этот секрет также нужно смонтировать внутри контейнера. К счастью, шаблон пода по умолчанию уже установил этот шаг.

Image

Кроме этого, есть другие методы авторизации

Ссылки:

  1. Примеры сборки Jenkins X
  2. pod-templates
  3. Практика эластичных систем CI/CD на основе Kubernetes