CI/CD на основе Kubernetes и Jenkins (1)

Kubernetes

упоминается на основанииKuberneteизCI/CD, есть много инструментов, которые можно использовать, напримерJenkins,Gitlab CIвозникающийdroneИ так далее, здесь мы будем использовать наиболее знакомый.JenkinsсделатьCI/CDинструмент, это руководство основано наk8s 1.16.1.

Создание PVC

Полное название PVC: PersistentVolumeClaim (PersistentVolumeClaim), PVC — это декларация пользовательского хранилища, PVC похож на Pod, Pod потребляет узлы, PVC потребляет ресурсы PV, Pod может запрашивать ЦП и память, а также конкретное пространство хранения PVC и шаблоны доступа могут быть запрошены. Пользователям, которые фактически используют хранилище, не нужно заботиться о деталях реализации базового хранилища, им нужно только напрямую использовать PVC.

Однако запроса определенного пространства хранения через PVC может быть недостаточно для удовлетворения различных требований приложений к устройствам хранения, а разные приложения могут иметь разные требования к производительности хранения, например скорость чтения и записи, одновременная производительность и т. д. Чтобы решить эту проблему, Kubernetes ввел для нас новый объект ресурсов: StorageClass.Через определение StorageClass администраторы могут определять ресурсы хранения как определенные типы ресурсов, такие как быстрое хранилище, медленное хранилище и т. д. Описание StorageClass может быть очень интуитивно понятным. знать конкретные характеристики различных ресурсов хранения, чтобы вы могли подать заявку на подходящие ресурсы хранения в соответствии с характеристиками приложения.

NFS

Для удобства демонстрации мы решили использовать относительно простой ресурс хранилища NFS, далее воспользуемся узлом192.168.56.100Подходим и устанавливаем службу NFS, каталог данных: /data/k8s/

  1. отключить брандмауэр

    $ systemctl stop firewalld.service
    $ systemctl disable firewalld.service
    
  2. Установить и настроить нфс

    $ yum -y install nfs-utils rpcbind
    

Установите разрешения для общего каталога:

$ mkdir -p /data/k8s/
$ chmod 755 /data/k8s/

Настройка nfs. Файл конфигурации nfs по умолчанию находится в файле /etc/exports. Добавьте в файл следующую информацию о конфигурации:

$ vi /etc/exports
/data/k8s  *(rw,sync,no_root_squash)

Инструкции по настройке:

  • /data/k8s: общий каталог данных
  • *: Указывает, что у любого есть разрешение на подключение, конечно, это может быть сегмент сети, IP-адрес или доменное имя.
  • rw: права на чтение и запись
  • синхронизация: указывает, что файл записывается на жесткий диск и в память одновременно
  • no_root_squash: когда пользователь, который входит в систему NFS с помощью общего каталога, является пользователем root, его полномочия будут преобразованы в анонимного пользователя, обычно его UID и GID становятся никем.

Конечно, конфигураций nfs еще много, и заинтересованные студенты могут найти их в Интернете.

  1. Для запуска службы nfs необходимо зарегистрироваться в rpc, после перезапуска rpc зарегистрированные файлы будут потеряны, а зарегистрированные в нем службы необходимо перезапустить

Обратите внимание на последовательность запуска, сначала запустите rpcbind

$ systemctl start rpcbind.service
$ systemctl enable rpcbind
$ systemctl status rpcbind
● rpcbind.service - RPC bind service
   Loaded: loaded (/usr/lib/systemd/system/rpcbind.service; disabled; vendor preset: enabled)
   Active: active (running) since Tue 2018-07-10 20:57:29 CST; 1min 54s ago
  Process: 17696 ExecStart=/sbin/rpcbind -w $RPCBIND_ARGS (code=exited, status=0/SUCCESS)
 Main PID: 17697 (rpcbind)
    Tasks: 1
   Memory: 1.1M
   CGroup: /system.slice/rpcbind.service
           └─17697 /sbin/rpcbind -w

Jul 10 20:57:29 master systemd[1]: Starting RPC bind service...
Jul 10 20:57:29 master systemd[1]: Started RPC bind service.

Наблюдение Started выше доказывает, что запуск прошел успешно.

Затем запустите службу nfs:

$ systemctl start nfs.service
$ systemctl enable nfs
$ systemctl status nfs
● nfs-server.service - NFS server and services
   Loaded: loaded (/usr/lib/systemd/system/nfs-server.service; enabled; vendor preset: disabled)
  Drop-In: /run/systemd/generator/nfs-server.service.d
           └─order-with-mounts.conf
   Active: active (exited) since Tue 2018-07-10 21:35:37 CST; 14s ago
 Main PID: 32067 (code=exited, status=0/SUCCESS)
   CGroup: /system.slice/nfs-server.service

Jul 10 21:35:37 master systemd[1]: Starting NFS server and services...
Jul 10 21:35:37 master systemd[1]: Started NFS server and services.

Также см. Started, чтобы доказать, что сервер NFS запущен успешно.

Кроме того, мы также можем подтвердить с помощью следующей команды:

$ rpcinfo -p|grep nfs
    100003    3   tcp   2049  nfs
    100003    4   tcp   2049  nfs
    100227    3   tcp   2049  nfs_acl
    100003    3   udp   2049  nfs
    100003    4   udp   2049  nfs
    100227    3   udp   2049  nfs_acl

Просмотр определенных разрешений на монтирование каталога:

$ cat /var/lib/nfs/etab
/data/k8s    *(rw,sync,wdelay,hide,nocrossmnt,secure,no_root_squash,no_all_squash,no_subtree_check,secure_locks,acl,no_pnfs,anonuid=65534,anongid=65534,sec=sys,secure,no_root_squash,no_all_squash)

На данный момент мы успешно установили сервер nfs, а затем установим его на узел10.151.30.62 (замените на свой ip)Подойди и установи клиент nfs для проверки nfs

  1. В настоящее время для установки nfs также необходимо сначала закрыть брандмауэр:
    $ systemctl stop firewalld.service
    $ systemctl disable firewalld.service
    

затем установите нфс

$ yum -y install nfs-utils rpcbind

После завершения установки, как указано выше, сначала запустите rpc, затем запустите nfs:

$ systemctl start rpcbind.service 
$ systemctl enable rpcbind.service 
$ systemctl start nfs.service    
$ systemctl enable nfs.service
  1. Монтируем каталог данных. После запуска клиента монтируем тест nfs на клиенте:

Сначала проверьте, есть ли в nfs общий каталог:

$ showmount -e 192.168.56.100
Export list for 192.168.56.100:
/data/k8s *

Затем мы создаем новый каталог на клиенте:

$ mkdir -p /root/course/kubeadm/data

Смонтируйте общий каталог nfs в указанный выше каталог:

$ mount -t nfs 192.168.56.100:/data/k8s /root/course/kubeadm/data

После успешного монтирования создаем новый файл в каталоге выше клиента, а затем наблюдаем, появляется ли файл также в общем каталоге сервера nfs:

$ touch /root/course/kubeadm/data/test.txt

Затем проверьте на сервере nfs:

$ ls -ls /data/k8s/
total 4
4 -rw-r--r--. 1 root root 4 Jul 10 21:50 test.txt

Если файл test.txt появляется выше, это доказывает, что наше монтирование nfs прошло успешно.

PV

С вышеупомянутым общим хранилищем NFS мы теперь можем использовать PV и PVC. В качестве ресурса хранения PV в основном включает ключевую информацию, такую ​​как емкость хранилища, режим доступа, тип хранилища и стратегию восстановления.Давайте создадим новый объект PV, используем внутреннее хранилище типа nfs, пространство хранения 1G, режим доступа ReadWriteOnce и стратегию восстановления. Recyle, соответствующий файл YAML выглядит следующим образом: (pv1-demo.yaml)

apiVersion: v1
kind: PersistentVolume
metadata:
  name:  pv1
spec:
  capacity: 
    storage: 1Gi
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  nfs:
    path: /data/k8s
    server: 192.168.56.100

Существует множество типов PV, поддерживаемых Kubernetes, таких как распространенный Ceph, GlusterFs, NFS и даже HostPath. Однако, как мы уже говорили ранее, HostPath можно использовать только для тестирования на одной машине. Дополнительные поддерживаемые типы см.Официальная документация Kubernetes PVПроверьте, потому что каждый тип хранилища имеет свои особенности, поэтому мы можем проверить соответствующие документы, чтобы установить соответствующие параметры при их использовании.

Затем таким же образом вы можете создать его непосредственно с помощью kubectl:

$ kubectl create -f pv1-demo.yaml
persistentvolume "pv1" created
$ kubectl get pv
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM               STORAGECLASS   REASON    AGE
pv1       1Gi        RWO            Recycle          Available                                                12s

Мы видим, что pv1 успешно создана, и статус Доступен, что означает, что pv1 готов и может быть запрошен PVC. Давайте интерпретируем вышеперечисленные свойства отдельно.

Разверните Jenkins на основе установки K8s

Большинство студентов, слушающих наши курсы, должны были в большей или меньшей степени о нем слышать.Jenkins, мы не будем здесь подробно останавливаться на том, что такое Дженкинс, а перейдем сразу к теме, позже у нас будет отдельный обучающий курс о Дженкинсе, и студенты, которые хотят узнать больше, также могут обратить внимание. Поскольку он основан наKubernetesсделатьCI/CD, разумеется, нужно установить Jenkins в кластер Kubernetes и создать новый Deployment: (jenkins2.yaml)

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: jenkins2
  namespace: kube-ops
spec:
  selector:
    matchLabels:
      app: jenkins2
  template:
    metadata:
      labels:
        app: jenkins2
    spec:
      terminationGracePeriodSeconds: 10
      serviceAccount: jenkins2
      containers:
      - name: jenkins
        image: jenkins/jenkins:lts
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080
          name: web
          protocol: TCP
        - containerPort: 50000
          name: agent
          protocol: TCP
        resources:
          limits:
            cpu: 1000m
            memory: 1Gi
          requests:
            cpu: 500m
            memory: 512Mi
        livenessProbe:
          httpGet:
            path: /login
            port: 8080
          initialDelaySeconds: 60
          timeoutSeconds: 5
          failureThreshold: 12
        readinessProbe:
          httpGet:
            path: /login
            port: 8080
          initialDelaySeconds: 60
          timeoutSeconds: 5
          failureThreshold: 12
        volumeMounts:
        - name: jenkinshome
          subPath: jenkins2
          mountPath: /var/jenkins_home
      securityContext:
        fsGroup: 1000
      volumes:
      - name: jenkinshome
        persistentVolumeClaim:
          claimName: opspvc

---
apiVersion: v1
kind: Service
metadata:
  name: jenkins2
  namespace: kube-ops
  labels:
    app: jenkins2
spec:
  selector:
    app: jenkins2
  type: NodePort
  ports:
  - name: web
    port: 8080
    targetPort: web
    nodePort: 30002
  - name: agent
    port: 50000
    targetPort: agent

Для удобства демонстрации мы поместили все ресурсы объекта в этом уроке под пространством имен с именем kube-ops, поэтому нам нужно добавить и создать пространство имен:

$ kubectl create namespace kube-ops

Здесь мы используем образ с именем jenkins/jenkins:lts, который является официальным образом Docker для jenkins, а также имеет некоторые переменные среды.Конечно, мы также можем настроить образ в соответствии с нашими собственными потребностями.Например, мы можем упаковать некоторые плагины в нашей собственной Среди определенных изображений вы можете обратиться к документации:GitHub.com/Дженкинс Таймс/…, здесь мы можем использовать официальный образ по умолчанию.Еще одна вещь, которую следует отметить, это то, что мы монтируем каталог контейнера /var/jenkins_home к объекту PVC с именем opspvc, поэтому мы также должны заранее создать соответствующий объект PVC, конечно, мы также можем используйте наш предыдущий объект StorageClass для автоматического создания: (pvc.yaml)

apiVersion: v1
kind: PersistentVolume
metadata:
  name: opspv
spec:
  capacity:
    storage: 20Gi
  accessModes:
  - ReadWriteMany
  persistentVolumeReclaimPolicy: Delete
  nfs:
    server: 192.168.56.100
    path: /data/k8s

---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: opspvc
  namespace: kube-ops
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 20Gi

Создайте необходимые объекты PVC:

$ kubectl create -f pvc.yaml

Кроме того, нам также нужно использовать serviceAccount с соответствующими разрешениями: jenkins 2. Здесь мы даем jenkins только некоторые необходимые разрешения. Конечно, если вы не очень знакомы с разрешениями serviceAccount, если jenkins нужно динамически публиковать в разные пространства имен. ,subjectsЧтобы связать разные пространства имен, я связываю kube-ops и default ниже.Также можно привязать разрешение роли кластера-администратора к этому sa.Конечно, это имеет определенные риски безопасности: (rbac.yaml)

apiVersion: v1
kind: ServiceAccount
metadata:
  name: jenkins2
  namespace: kube-ops

---

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: jenkins2
rules:
  - apiGroups: ["extensions", "apps"]
    resources: ["deployments"]
    verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
  - apiGroups: [""]
    resources: ["services"]
    verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["create","delete","get","list","patch","update","watch"]
  - apiGroups: [""]
    resources: ["pods/exec"]
    verbs: ["create","delete","get","list","patch","update","watch"]
  - apiGroups: [""]
    resources: ["pods/log"]
    verbs: ["get","list","watch"]
  - apiGroups: [""]
    resources: ["secrets"]
    verbs: ["get"]

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: jenkins2
  namespace: kube-ops
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: jenkins2
subjects:
  - kind: ServiceAccount
    name: jenkins2
    namespace: kube-ops
 - kind: ServiceAccount
    name: jenkins2
    namespace: default

Создайте объекты ресурсов, связанные с rbac:

$ kubectl create -f rbac.yaml
serviceaccount "jenkins2" created
role.rbac.authorization.k8s.io "jenkins2" created
rolebinding.rbac.authorization.k8s.io "jenkins2" created

Наконец, чтобы облегчить наше тестирование, мы выставляем веб-службу Jenkins в виде NodePort, который фиксируется на порту 30002. Кроме того, нам нужно выставить порт агента, который в основном используется для связи между мастером и раб Дженкинса.

После того, как все подготовленные ресурсы готовы, непосредственно создаем сервис Jenkins:

$ chown -R 1000 /data/k8s/jenkins2
$ kubectl create -f jenkins2.yaml
deployment.extensions "jenkins2" created
service "jenkins2" created

После завершения создания образ может занять некоторое время, а затем мы проверяем статус пода:

$ kubectl get pods -n kube-ops
NAME                        READY     STATUS    RESTARTS   AGE
jenkins2-7f5494cd44-pqpzs   0/1       Running   0          2m

Вы можете видеть, что модуль находится в состоянии «Работает», но значение READY действительно равно 0. Затем мы используем команду описания для просмотра сведений о модуле:

$ kubectl describe pod jenkins2-7f5494cd44-pqpzs -n kube-ops
...
Normal   Created                3m                kubelet, node01    Created container
  Normal   Started                3m                kubelet, node01    Started container
  Warning  Unhealthy              1m (x10 over 2m)  kubelet, node01    Liveness probe failed: Get http://10.244.1.165:8080/login: dial tcp 10.244.1.165:8080: getsockopt: connection refused
  Warning  Unhealthy              1m (x10 over 2m)  kubelet, node01    Readiness probe failed: Get http://10.244.1.165:8080/login: dial tcp 10.244.1.165:8080: getsockopt: connection refused

Вы можете увидеть предупреждающую информацию выше, проверка работоспособности не удалась, в чем конкретная причина? Вы можете узнать больше, просмотрев журналы:

$ kubectl logs -f jenkins2-7f5494cd44-pqpzs -n kube-ops
touch: cannot touch '/var/jenkins_home/copy_reference_file.log': Permission denied
Can not write to /var/jenkins_home/copy_reference_file.log. Wrong volume permissions?

Очевидно, вы можете увидеть приведенное выше сообщение об ошибке, которое означает, что у нас нет разрешения на создание файлов в домашнем каталоге jenkins, это связано с тем, что образ по умолчанию использует пользователя jenkins, и мы монтируем его в общий каталог данных nfs. сервер через PVC Ниже приведен пользователь root, поэтому нет разрешения на доступ к каталогу.Решить эту проблему очень просто.Мне просто нужно переназначить права доступа к нашему каталогу под каталогом общих данных nfs:

$ chown -R 1000 /data/k8s/jenkins2

Конечно, у нас есть и другой способ настроить образ, также есть возможность указать пользователя root в образе.

Затем воссоздаем:

$ kubectl delete -f jenkins.yaml
deployment.extensions "jenkins2" deleted
service "jenkins2" deleted
$ kubectl create -f jenkins.yaml
deployment.extensions "jenkins2" created
service "jenkins2" created

Теперь давайте проверим, что у только что сгенерированного пода нет сообщения об ошибке:

$ kubectl get pods -n kube-ops
NAME                        READY     STATUS        RESTARTS   AGE
jenkins2-7f5494cd44-smn2r   1/1       Running       0          25s

После успешного запуска службы мы можем получить доступ к службе jenkins по порту IP: 30002 любого узла, и мы можем установить и настроить ее в соответствии с подсказкой:

1. Войдите в систему управления jenkins 2. Войдите в управление плагинами 3. Дополнительно

cd {ваш каталог заданий Jenkins}/updates #Введите расположение конфигурации обновления

Измените файл default.json.

sed -i 's/http:\/\/updates.jenkins-ci.org\/download/https:\/\/mirrors.tuna.tsinghua.edu.cn\/jenkins/g' default.json && sed -i 's/http:\/\/www.google.com/https:\/\/www.baidu.com/g' default.json

setup jenkinsМы можем просмотреть инициализированный пароль в журнале контейнера jenkins или непосредственно в каталоге общих данных nfs:

$ cat /data/k8s/jenkins2/secrets/initAdminPassword

Затем выберите установку рекомендуемого плагина.setup plugin

После завершения установки добавьте учетную запись администратора для входа в основной интерфейс jenkins:jenkins home

преимущество

Установка Jenkins завершена, то нам не нужно торопиться его использовать, нам нужно понять, в чем преимущества использования Jenkins в среде Kubernetes.

Мы знаем, что непрерывная разработка и выпуск являются важным шагом в нашей повседневной работе.В настоящее время большинство компаний используют кластеры Jenkins для построения процессов CI/CD, отвечающих их потребностям.Однако традиционный метод Jenkins Slave с одним ведущим и несколькими подчиненными некоторые болевые точки, например:

  • Когда основной Мастер имеет единую точку отказа, весь процесс недоступен.
  • Среда конфигурации каждого ведомого устройства различна для завершения компиляции и упаковки различных языков, но эти дифференцированные конфигурации делают ее очень неудобной в управлении и сложной в обслуживании.
  • Несбалансированное распределение ресурсов, некоторые подчиненные задания поставлены в очередь на выполнение, а некоторые подчиненные находятся в состоянии ожидания.
  • Ресурсы имеют трату, каждый слейв может быть физической или виртуальной машиной, когда слейв простаивает, он не будет полностью освобождать ресурс.

Из-за вышеуказанных проблем мы стремимся к более эффективному и надежному способу завершения этого процесса CI / CD, и контейнерная технология виртуализации Docker может очень хорошо решить эту проблему, особенно в кластерной среде Kubernetes. , на следующем рисунке представлена ​​простая схема построения кластера Jenkins на базе Kubernetes:k8s-jenkins

Как видно из рисунка, Jenkins Master и Jenkins Slave запускаются на узле кластера Kubernetes в виде Pod, Master запускается на одном из узлов и хранит данные своей конфигурации в томе, Slave запускается на каждом узле , и он не работает всегда, он будет динамически создаваться и автоматически удаляться по мере необходимости.

Рабочий процесс этого метода примерно таков: когда Jenkins Master получает запрос на сборку, он динамически создает Jenkins Slave, работающий в Pod, в соответствии с настроенной меткой и регистрирует его на Master.После запуска задания, Slave выйти из системы, а Pod будет автоматически удален и возвращен в исходное состояние.

Итак, каковы преимущества использования этого метода?

  • Сервис высокой доступности, при сбое Jenkins Master Kubernetes автоматически создаст новый контейнер Jenkins Master и назначит Volume только что созданному контейнеру, чтобы гарантировать, что данные не будут потеряны, тем самым обеспечив высокую доступность служб кластера.
  • Динамическое масштабирование, использовать ресурсы разумно, каждый раз при запуске задания будет автоматически создан подчиненный Jenkins.После завершения задания подчиненный автоматически выйдет из системы и удалит контейнер, а ресурсы будут автоматически освобождены, а Kubernetes будет динамически выделять Ведомый к бездействующему в соответствии с использованием каждого ресурса.Создается на узле, что снижает вероятность появления узла, ожидающего в очереди, из-за высокого использования ресурсов узла.
  • Хорошая масштабируемость, когда ресурсов кластера Kubernetes серьезно не хватает и задание поставлено в очередь, вы можете легко добавить узел Kubernetes в кластер для расширения.

Ушли ли различные проблемы, с которыми мы сталкивались в прошлом, в кластерную среду Kubernetes? Это выглядит идеально.

настроить

Далее нам нужно настроить Jenkins, чтобы он мог динамически генерировать ведомые модули.

Шаг 1. Нам нужно установитьkubernetes plugin, нажмите «Управление Jenkins» -> «Управление плагинами» -> «Доступно» -> «Плагин Kubernetes» и проверьте установку.kubernetes plugin

Шаг 2. После установки нажмите Управление Jenkins —> Настроить систему —> (перетащите вниз) Добавить новое облако —> Выберите Kubernetes, а затем заполните информацию о конфигурации Kubernetes и Jenkins.kubernetes plugin config1

Обратите внимание на namespace, здесь заливаем kube-ops, а потом нажимаемTest Connection, если появляется сообщение об успешном завершении теста подключения, подтверждающее, что Jenkins может нормально взаимодействовать с системой Kubernetes, URL-адрес Jenkins ниже:jenkins2.kube-ops.svc.cluster.local:8080, здесь используется следующий формат: имя службы.пространство имен.svc.cluster.local:8080,Заполните в соответствии с именем службы jenkins, созданным выше, здесь имя jenkins, созданное ранее, если оно создано выше, это должно быть jenkins2

Кроме того, следует отметить, что если здесь не удается выполнить тестовое соединение, это, вероятно, проблема с правами доступа.Здесь нам нужно добавить секрет, соответствующий созданной нами служебной учетной записи jenkins, в учетные данные здесь.

Шаг 3. Настройте шаблон пода, который фактически предназначен для настройки шаблона пода, который запускает Jenkins Slave Мы также используем kube-ops для пространства имен.cnych/jenkins:jnlpЭтот образ используется в качестве основы, и добавляются некоторые полезные инструменты, такие как maven и kubectl.

Dockerfile

FROM cnych/jenkins:jnlp6
COPY maven.zip /usr/local/
COPY kubectl /usr/bin/
RUN \
   cd /usr/local/ && \
   unzip -qo maven.zip && \
   chmod -R 777 /usr/local/maven && \
   chmod +x /usr/bin/kubectl && \
   rm -rf /usr/local/bin/kubectl && \
   ln -s /usr/local/maven/bin/mvn /usr/bin/mvn

Подготовьте полный пакет maven, измените settings.xml, и этот путь смонтирован выше

 <localRepository>/.m2/repository</localRepository>

Измените адрес зеркала следующим образом:

 <mirror>
      <id>alimaven</id>
      <name>aliyun maven</name>
      <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
      <mirrorOf>central</mirrorOf>        
</mirror>

Скопируйте kubectl в /opt/jenkins/maven

cp /usr/bin/kubectl /opt/jenkins/maven

Структура каталогов следующая:

[root@master maven]# tree
.
├── Dockerfile
├── kubectl
└── maven.zip

0 directories, 3 files

Изображение пакета:

docker build -t yourtag/jenkins:jnlp6 .

Изображение Docker ниже изменено на yourtag/jenkins:jnlp6 (на рисунке ниже показано, что cnych/jenkins:jnlp игнорируется)

kubernetes plugin config2

Примечание. Поскольку в новой версии плагина Kubernetes много изменений, если используемая вами версия Jenkins выше версии 2.176.x, замените приведенное выше изображение наyourtag/jenkins:jnlp6 , иначе будет сообщено об ошибке, конфигурация показана ниже:

kubernetes slave image config
kubernetes slave image config

Кроме того, следует отметить, что нам нужно смонтировать две директории хоста ниже, одна/var/run/docker.sock, этот файл представляет собой Docker, используемый для контейнеров в Pod для совместного использования хоста. Это то, как вы вызываете docker в docker. Мы упаковали двоичный файл Docker в приведенный выше образ и в другой каталог./root/.kubeкаталог, мы смонтируем этот каталог в контейнер/root/.kube目录下面这是为了让我们能够在 Pod 的容器中能够使用 kubectl 工具来访问我们的 Kubernetes 集群,方便我们后面在 Slave Pod 部署 Kubernetes 应用。 

путь монтирования

/var/run/docker.sock
/root/.kube
/usr/bin/docker
/usr/bin/kubectl
#maven包
/root/.m2/repository #宿主机路径
/.m2/repository #容器路径


kubernetes plugin config3

Есть также несколько параметров, на которые следует обратить внимание, как показано на следующем рисунке.Time in minutes to retain slave when idle, этот параметр означает, как долго держать Slave Pod, когда он находится в состоянии простоя. Нам лучше сохранить этот параметр по умолчанию. Если вы установите слишком большое значение, после выполнения задачи Job соответствующий Slave Pod будет не быть уничтоженным немедленно.kubernetes plugin config4

Некоторые другие учащиеся имеют проблемы с разрешениями при запуске ведомого модуля после настройки.Поскольку в ведомом модуле Jenkins нет разрешений на настройку, необходимо настроить учетную запись службы.Нажмите «Дополнительно» ниже, где настроен ведомый модуль, и добавьте соответствующую учетную запись службы. .:kubernetes plugin config5

Некоторые студенты обнаружили, что при запуске Jenkins Slave Pod после завершения настройки, Slave Pod не может быть подключен, а затем Pod уничтожается после 100 попыток подключения, а затем создается еще один Slave Pod для продолжения попыток подключения в бесконечный цикл, аналогичный следующей информации:

Если это произойдет, вам необходимо очистить два значения текущей команды и параметров в Slave Pod.

На этом этапе наш подключаемый модуль Kubernetes настроен.

контрольная работа

Настройка плагина Kubernetes завершена. Теперь давайте добавим задачу Job, чтобы посмотреть, может ли она быть выполнена в подчиненном модуле. После выполнения задачи посмотрим, будет ли уничтожен модуль.

Нажмите на домашнюю страницу Дженкинсаcreate new jobs, создаем тестовое задание, вводим название задания, а затем выбираем задание типа Freestyle project:jenkins demo

Обратите внимание, что приведенное ниже выражение метки необходимо заполнить здесь.haimaxy-jnlp, который является меткой в ​​подчиненном модуле, который мы настроили ранее, эти два места должны быть согласованыconfig

Затем потяните вниз и выберите в области сборкиExecute shell Build

Затем введите нашу тестовую команду

echo "测试 Kubernetes 动态生成 jenkins slave"

echo "==============docker in docker==========="
docker info

echo "=============maven============="
mvn -version

echo "=============kubectl============="
kubectl get pods -n kube-ops

Наконец нажмите сохранитьcommand

Теперь мы можем напрямую щелкнуть завершенную сборку прямо сейчас на странице, чтобы запустить сборку, а затем наблюдать за изменениями пода в кластере Kubernetes.

$ kubectl get pods -n kube-ops
NAME                       READY     STATUS              RESTARTS   AGE
jenkins2-7c85b6f4bd-rfqgv   1/1       Running             3          1d
jnlp-hfmvd                 0/1       ContainerCreating   0          7s

Мы видим, что новый Pod создается, когда мы нажимаем Build Now: jnlp-hfmvd, который является нашим Jenkins Slave. После выполнения задачи мы можем увидеть информацию о задаче.Например, здесь мы потратили 5,2 с на слейве jnlp-hfmvdjnlp slave

Вы также можете просмотреть соответствующую информацию о консоли:jnlp output

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

$ kubectl get pods -n kube-ops
NAME                       READY     STATUS    RESTARTS   AGE
jenkins2-7c85b6f4bd-rfqgv   1/1       Running   3          1d

На данный момент мы завершили метод динамического создания Jenkins Slave с использованием Kubernetes. На следующем уроке мы покажем вам, как опубликовать наше приложение Kubernetes в Jenkins.