Jenkins: запуск на AWS EC2 + Pipeline Plugin + Docker Pipeline Plugin

Автор: | 10/12/2016
 

Jenkins.sh-600x600Задача — поднять Jenkins 2 на AWS EC2, и создать два билда:

  1. с помощью плагина workflow-aggregator (Jenkins Pipeline Plugin) — вывести «Hello, World» через Pipeline Script;
  2. с помощью плагина docker-workflow (CloudBees Docker Pipeline Plugin) запустить Docker контейнер, в котором Maven-ом будет выполенна сборка Java-проекта.

Документация по Jenkins Pipeline Pluginтут>>>.

Документация по CloudBees Docker Pipeline Pluginтут>>>.

Создание EC2

Создаём EC2, на котором будет работать Jenkins.

Находим образ:

$ aws ec2 describe-images --owners 099720109477 --filters Name=platform,Values=linux,Name=name,Values='*ubuntu-trusty-14.04-amd64-server*' --query 'sort_by(Images, &Name)' --output text | head
x86_64  2014-06-27T00:18:25.000Z        xen     ami-8f6ca7f8    099720109477/ubuntu/images/ebs-io1/ubuntu-trusty-14.04-amd64-server-20140607.1  machine aki-52a34525    ubuntu/images/ebs-io1/ubuntu-trusty-14.04-amd64-server-20140607.1       099720109477    True    /dev/sda1      ebs             available       paravirtual
BLOCKDEVICEMAPPINGS     /dev/sda1
EBS     True    False   300     snap-e20ed21b   8       io1
BLOCKDEVICEMAPPINGS     /dev/sdb        ephemeral0
x86_64  2014-07-25T08:25:51.000Z        xen     ami-f36cbd84    099720109477/ubuntu/images/ebs-io1/ubuntu-trusty-14.04-amd64-server-20140724    machine aki-52a34525    ubuntu/images/ebs-io1/ubuntu-trusty-14.04-amd64-server-20140724 099720109477    True    /dev/sda1     ebs              available       paravirtual
BLOCKDEVICEMAPPINGS     /dev/sda1
EBS     True    False   200     snap-5ed700a6   8       io1
BLOCKDEVICEMAPPINGS     /dev/sdb        ephemeral0
x86_64  2014-08-14T00:44:47.000Z        xen     ami-7615c901    099720109477/ubuntu/images/ebs-io1/ubuntu-trusty-14.04-amd64-server-20140813    machine aki-52a34525    ubuntu/images/ebs-io1/ubuntu-trusty-14.04-amd64-server-20140813 099720109477    True    /dev/sda1     ebs              available       paravirtual
BLOCKDEVICEMAPPINGS     /dev/sda1

Запускаем:

$ aws ec2 run-instances --image-id ami-7615c901 --count 1 --instance-type t1.micro --key-name my-cluster

Проверяем:

$ aws ec2 describe-instances --instance-ids i-dfeb1850
{
    "Reservations": [
        {                                                                                                                                                                                                                                                                      
            "OwnerId": "264418146286",
            "ReservationId": "r-c6e7ae4b",
            "Groups": [],
            "Instances": [
                {
                    "Monitoring": {
                        "State": "disabled"
                    },
                    "PublicDnsName": "ec2-52-212-51-109.eu-west-1.compute.amazonaws.com",
                    "RootDeviceType": "ebs",
                    "State": {
                        "Code": 16,
                        "Name": "running"
                    },
...

 

Создаём Security group:

$ aws ec2 create-security-group --group-name jenkins --description "Jenkins instance 80, 22"
{
    "GroupId": "sg-7414ed12"
}

Используя ID группы sg-cbbb9eac добавляем два правила – доступ по 80 и 22 портам:

$ aws ec2 authorize-security-group-ingress --group-id sg-7414ed12 --protocol tcp --port 22 --cidr 194.***.***.45/32
$ aws ec2 authorize-security-group-ingress --group-id sg-7414ed12 --protocol tcp --port 80 --cidr 0.0.0.0/0

Подключаем группу к инстансу:

$ aws ec2 modify-instance-attribute --instance-id  i-dfeb1850 --groups sg-7414ed12

Имейте ввиду, что при modify-instance-attribute текущая группа будет сброшена.

Проверяем:

$ telnet 52.212.51.109 22
Trying 52.212.51.109...
Connected to 52.212.51.109.
Escape character is '^]'.
SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2

Подключаемся:

$ ssh ubuntu@ec2-52-212-51-109.eu-west-1.compute.amazonaws.com -i ~/.ssh/my-cluster.pem

Установка NGINX, Docker

Устанавливаем:

# apt-get update && apt-get install nginx docker.io git

Проверяем:

# ps aux | grep 'nginx\|docker'
root      2080  0.0  0.2  85872  1340 ?        Ss   09:58   0:00 nginx: master process /usr/sbin/nginx
www-data  2081  0.0  0.2  86212  1760 ?        S    09:58   0:00 nginx: worker process
www-data  2082  0.0  0.2  86212  1760 ?        S    09:58   0:00 nginx: worker process
www-data  2083  0.0  0.2  86212  1760 ?        S    09:58   0:00 nginx: worker process
www-data  2084  0.0  0.2  86212  1760 ?        S    09:58   0:00 nginx: worker process
root      3710  0.8  1.5 237880  9432 ?        Ssl  10:03   0:00 /usr/bin/docker -d
root      3911  0.0  0.1  10436   628 pts/0    S+   10:04   0:00 grep --color=auto nginx\|docker

Проверяем автозапуск.

Docker стартует через initctl:

# initctl list | grep 'docker'
docker start/running, process 3710
network-interface (docker0) start/running
network-interface-security (network-interface/docker0) start/running

NGINX — через System V:

# service --status-all | grep nginx
...
 [ + ]  nginx
...

Подробнее о системах инициализации в Linux — в посте Linux: SysV, Upstart и Systemd – runlevels и общие сведения.

Установка Jenkins

Добавляем ключ, репозиторий и устанавливаем Jenkins:

# wget -q -O - https://pkg.jenkins.io/debian/jenkins-ci.org.key | sudo apt-key add -
OK
# echo deb http://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list
# apt-get update && apt-get install jenkins

Проверяем автостарт и статус:

# service --status-all | grep jenkins
...
 [ + ]  jenkins
...
# service jenkins status
Jenkins Continuous Integration Server is running with the pid 7788

Настройка NGINX

Т.к. Jenkins работает на порту 8080 — настроим NGINX в роли прокси с порта 80:

Создаём файл конфигурации /etc/nginx/conf.d/jenkins.conf:

server {
    listen 80 default_server
    server_name  _;

    location / {
            proxy_pass http://127.0.0.1:8080;
    }
}

Из файла /etc/nginx/sites-enabled/default убираем `default server` (либо установить редирект прямо тут):

...
server {
        listen 80;
        listen [::]:80 default_server ipv6only=on;
...

Проверяем, перезапускаем NGINX:

# nginx -t && service nginx reload
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
 * Reloading nginx configuration nginx

Проверяем:

# curl ec2-52-212-51-109.eu-west-1.compute.amazonaws.com
<html><head><meta http-equiv='refresh' content='1;url=/login?from=%2F'/><script>window.location.replace('/login?from=%2F');</script></head><body style='background-color:white; color:white;'>


Authentication required
<!--
You are authenticated as: anonymous
Groups that you are in:
  
Permission you need to have (but didn't): hudson.model.Hudson.Administer
-->

</body></html>

Добавляем пользователя jenkins в группу docker:

# usermod -a -G docker jenkins

Переключаемся, провеяем:

# su -l jenkins
$ docker run
docker: "run" requires a minimum of 1 argument. See 'docker run --help'.
jenkins@ip-172-31-35-179:~$ docker run ubuntu
Unable to find image 'ubuntu:latest' locally
latest: Pulling from ubuntu
31711d35995a: Downloading [==>                                                ] 2.024 MB/49.83 MB
...

Jenkins готов.

Настройка Jenkins, установка плагинов

Переходим в базуере на http://ec2-52-212-51-109.eu-west-1.compute.amazonaws.com:

aws_jenkins_ec2_install_1

Получаем пароль:

# cat /var/lib/jenkins/secrets/initialAdminPassword
4afb***a390

Логинимся:

aws_jenkins_ec2_install_2

Потребуются плагины:

Пропускаем Getting Started, дальше делаем всё руками.

Устанавливаем Locale плагин:

# cd /var/lib/jenkins/plugins/
# wget http://updates.jenkins-ci.org/latest/locale.hpi
# service jenkins restart
 * Restarting Jenkins Continuous Integration Server jenkins        [ OK ] 

Переходим в Настроить Jenkins > Конфигурирование системы и устанавливаем параметр “Ignore browser preference and force this language to all users“ и заодно — меняем Jenkins URL:

aws_jenkins_ec2_install_3

Далее  — ставим плагин docker-workflow.

Переходим в Manage Jenkins > Manage Plugins > Available:

aws_jenkins_ec2_install_4

aws_jenkins_ec2_install_5

Аналогично — ставим Pipeline и Git plugin плагины.

Jenkins Pipeline «Hellow, World»

Создадим задачу, которая через Pipeline script выведет «Hello, World«.

Кликаем Create new jobs, указываем имя и выбираем тип Pipeline:

aws_jenkins_ec2_install_7

Переходим на вкладку Pipeline, выбираем Pipeline script, справа Try sample Pipeline и Hello, World:

aws_jenkins_ec2_install_8

Если внизу нажать на Pipeline Syntax — то откроется редактор, который может генерировать Groovy автоматом.

Жмём Save, и стартуем задачу:

aws_jenkins_ec2_install_9

aws_jenkins_ec2_install_10

Готово.

Maven билд в Docker

Усложним задачу.

Соберем «Hello, World» Java-приложение в Docker через Jenkins.

Подготовка репозитория и groovy скрипта

Клонируем репозиторий:

$ git clone git@github.com:setevoy2/tests.git
Cloning into 'tests'...
warning: You appear to have cloned an empty repository.
Checking connectivity... done.
$ cd  tests/

Готовим два проекта — скрипт для Jenkins, и Java проект «Hello World» (детали сборки Java+Maven —  в посте Apache Maven: сборка Java Hello World).

При необходимости — устанавливаем Maven локально:

$ sudo apt-get install maven

Генерируем проект:

$ mvn archetype:generate -DgroupId=com.setevoy.javahello -DartifactId=javahello -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false
$ ls -l javahello/
total 8
-rw-rw-r-- 1 setevoy setevoy 723 жов 12 14:34 pom.xml
drwxrwxr-x 3 setevoy setevoy 4096 жов 12 14:34 src

В Jenkins с помощью Credentials Plugin (слева внизу) доабвляем данные доступа к репозиторию:

aws_jenkins_ec2_install_11

Создаём билд-скрипт javahello.docker-build.groovy:

node {
    stage 'build'
    docker.image('maven').inside {
        stage 'Git clone'
            git branch: 'master', credentialsId: 'githubSetevoy', url: 'https://github.com/setevoy2/tests.git'
        stage 'Maven build'
            sh 'mvn clean package -f javahello/pom.xml'
    }
}

Сохраняем всё, и пушим в репозиторий:

$ git add -A && git commit -m "Jenkins Docker pipeline build Java Hello, World" && git push

Билд в Docker

Кликаем Create new jobs, указываем имя и выбираем тип Pipeline:

aws_jenkins_ec2_install_12

Переходим на вкладку Pipeline, и выбираем тип «Pipeline script from SCM«:

В Repositories — указываем URL репозитория, в Credentials — выбираем добавленные ранее данные доступа, и в Script Path — путь к файлу javahello.docker-build.groovy:

aws_jenkins_ec2_install_13

Сохраняем, и запускаем:

aws_jenkins_ec2_install_14

aws_jenkins_ec2_install_15

Готово.

Ссылки по теме

How To Build Docker Images Automatically With Jenkins Pipeline

Installing Jenkins and Docker in an AWS EC2 Instance

Pipeline as Code with Jenkins

Pipeline as Code with JenkinsDon’t install software, define your environment with Docker and Pipeline