Jenkins

Установка

Jenkins server, docker compose

Источник

Для обучения на этом можно остановиться. 

Jenkins agent, docker compose

 jenkins_keys_1.JPG

jenkins_keys_2.JPGjenkins_keys_3.JPG

jenkins_keys_4.JPG

И установить следующий путь в настройках агента: jenkins_keys_5.JPG

Jenkins -> k8s

Видео по настройке взаимодействия

Описание плагина Kubernetes

Описание плагина Credentials

Детальное описание Pod

Шпаргалка по k8s

jenkins_k8s_1.JPG

 jenkins_k8s_2.JPG

jenkins_k8s_3.JPG

 jenkins_k8s_4.JPG

Для работы с kubernetes нужен файл авторизации. Формат файла и настройки админа (для примера) можно посмотреть на кластере Kubernetes в 

/etc/kubernetes/admin.conf

Сохраняем его в Credentials Jenkins и тип - файл. В данном случае ID textauth. jenkins_keys_6.JPG

Важно, что рабочая директория Jenkins может (и скорее всего будет) отличаться от homedir пользователя

Pipeline:

pipeline {
  agent {
          kubernetes (kubernetesAgent(name: 'mini'))
  }
  
  stages {
    stage('Integrate Remote k8s with Jenkins ') {
      steps {
            sh "mkdir ~/.kube"
            withCredentials([file(credentialsId: 'textauth', variable: 'FILE')]) {
                sh 'cp $FILE ~/.kube/config'
                }
            sh "curl -LO 'https://dl.k8s.io/release/v1.32.2/bin/linux/amd64/kubectl'"
            sh "chmod +x kubectl"
            sh "./kubectl get nodes"
        }
    }
  }
}

Разное

node('docker-agent-01') {
        stage ('Pulling repo and filling constants'){
            sh "rm *"
            git 'https://gitverse.ru/bobrobot/liteconnect_docker.git'
            withEnv(readFile('env.txt').split('\n') as List) {
                sh 'chmod +x replace_env.sh && ./replace_env.sh'
                }
            sh "cp env.txt .env"
    }
}

 

node() {
  stage('first') {
  withEnv(["PATH+HUIWAM=${HOME}/.local/bin"])
    {
        sh "printenv PATH"
    }
   sh "printenv PATH"
   }
}
withEnv([
    "PATH+EXTRA=/home/jenkins/.local/bin"])
{
    node() {
        stage('first') {
            sh "printenv PATH"
            }
    }
}
pipeline {
  agent {
            kubernetes (kubernetesAgent(name: 'mini'))
  }
  environment {
      PATH="${HOME}/.local/bin:${PATH}"
  }
  stages {
    stage('Integrate Remote k8s with Jenkins ') {
      steps {
            sh "printenv PATH"
             withCredentials([file(credentialsId: 'mysrc', variable: 'MYFILE')]) {
                sh 'cp $MYFILE new.sh'
                }
        }
    }
  }
  }
// для груви скрипта нужно упаковывать в withenv чтобы были видны определенные в скрипте параметры, 
//параметры из jenkins видны
//param_in_main - текстовый параметр,
//build_type - второй параметр. 
withEnv([
    'ENV1=It work ' + param_in_main, 
    'ENV2=ooo',
    'missingfname=thefilereallymissing.txt'])
{
    node('slave') {
        stage('first') {
            sh "mkdir ~/bin" 
            sh "printenv PATH"
            sh "echo $param_in_main" //обращение к параметру из параметров в jenkins
            sh "echo $ENV1" //обращение к составному параметру, определенному внутри скрипта
            sh "echo $ENV2" //обращение к независимому параметру внутри скрипта
            }
            
        stage('check type of pipeline'){
            if (build_type == 'prod') { //если проверяем вне sh - доллар не ставится
                sh "echo 'This is a prod'"
            }
        }
        
        stage('test exeptions'){
            try {
                sh 'rm $missingfname'
            }
            catch (exc) {
                echo 'Попытались удалить несуществующий файл ' + missingfname
            }
        }
        
        stage('check cycle'){
            sh 'mkdir "firstdir"'
            def fileNames = sh(returnStdout: true, script: 'ls').trim().split()
            for (item in fileNames) {
                echo "Processing item: ${item}"
                }
        }
    }
}
def buildPod = {
    def podYaml = """
kind: Pod
metadata:
  name: jenkins-agent
spec:
  containers:
  - name: my-jenkins-agent
    image: jenkins/inbound-agent:latest
    command:
    - cat
    tty: true
    volumeMounts:
    - mountPath: /var/run/docker.sock
      name: docker-sock
  volumes:
  - name: docker-sock
    hostPath:
      path: /var/run/docker.sock
"""
    return podYaml
}

def label = "jenkins-agent-${UUID.randomUUID().toString()}"

podTemplate(label: label, yaml: buildPod()) {
    node(label) {
        stage('Build') {
            container('my-jenkins-agent') {
                echo 'Start stage build'
                sh 'ls -al'
                echo 'End stage build'
            }
        }
        stage('Deploy') {
            container('my-jenkins-agent') {
                echo 'Start stage deploy'
                  try {
                    sh "rm my.txt"
                }
                catch(exc) {
                    echo "The ERROR!"
                    echo "${exc}"
                }
            }
        }
    }
}

Интеграция Jenkins и GitVerse

Настройка доступа в GitVerse

Профиль -> Управление токенами, создаем токен и сохраняем его

jenkins_gitverse_1.JPG

Добавляем токен доступ в Jenkins 

Home -> Настроить Jenkins -> Credentials Затем System -> global credentials -> Add credential 

jenkins_gitverse_2.JPG

Настройка доступа к GitVerse

Home -> Настроить Jenkins -> System

jenkins_gitverse_3.JPG

Создаем в проекте Jenkinsfile

Создаем новый pipeline в Jenkins

jenkins_gitverse_6.JPG

Устанавливаем github project

jenkins_gitverse_7.JPG

В разделе Triggers установить GitHub hook trigger

jenkins_gitverse_8.JPG

Устанавливаем тип Pipeline from SCM

jenkins_gitverse_9.JPG

В первый раз сделать сборку вручную. После успешной сборки перейти в Settings пайплайна и нажать Save

Получилось собирать из Jenkinsfile в проекте, но webhook не поехал. Сервер снаружи виден. Поэтому пока оставим ручной запуск на исполнение.

Ssh агент

SSH Agent plugin нахер в данном случае не нужен. Он необходим только для подключения внутри stage с существующего агента к другому серверу.

Сервер, на котором будем выполнять команды:

Добавить пользователя jenkins и добавить нового пользователя в группу sudo, docker (в случае моей задачи) 

sudo adduser jenkins
sudo usermod -aG sudo jenkins
sudo usermod -aG docker jenkins

Авторизоваться на сервере под пользователем jenkins

Установить java

sudo apt update
sudo apt install fontconfig openjdk-17-jre

Создать приватный и публичный ключи для доступа к серверу по ssh пользователя jenkins. 

  mkdir ~/.ssh && cd ~/.ssh
  ssh-keygen -t rsa -C "Access key for Jenkins slaves"
cat id_rsa.pub >> ~/.ssh/authorized_keys

Ключ из файла id_rsa потребуется для настройки доступа Jenkins

Jenkins web интерфейс:

Настройки Jenkins -> Credentials -> System -> Global credentials -> Add credential jenkins_ssh_1.JPG

В раздел ключ вставить текст из файла id_rsa целиком (включая -----BEGIN... ------END...)

Перейти в Настроить Jenkins -> Nodes и создать узел

 jenkins_ssh_2.JPG

Параметры агента:

Параметр Значение
Удаленная корневая директория /home/jenkins/jenkins-agent
Метки docker-agent-01
Host key verification strategy Manually trusted key verification

jenkins_ssh_3.JPG

После настройки в узлах агент должен быть активен.

Тестовый pipeline 

node('docker-agent-01') {
        stage ('second'){
            sh 'hostname'
    }
}

должен вывести хост агента.

В Jenkins текущая рабочая директория -

/home/jenkins/jenkins-agent/workspace/<имя pipeline>