DroneCI+Github указывает на север

CI/CD

Введение

Automate Software Testing and Delivery Drone is a self-service Continuous Delivery platform for busy development teams.

Drone — это платформа непрерывной доставки самообслуживания для занятых команд разработчиков.

Помимо более зрелых, которые сейчас делает Drone, есть Gitlab-CI, Jenkins и недавно запущенный Github-Actions. Поскольку Drone потребляет меньше ресурсов и ему нравится концепция контейнеров в качестве плагинов (Это было написано мной на Голанге), поэтому решил использовать его, чтобы испытать CI.

! Но я должен пожаловаться, что документация Drone ужасна. . Поэтому я надеюсь, что эта статья поможет вам избежать обходных путей 😇

В этой статье используется последняя версия Drone, не так много версий до 1.0 в Интернете.Если вы будете следовать этому руководству, проблем не возникнет.

настроить

Весь процесс CI должен пройти черезgit hookДля запуска Drone поддерживает Github, GitLab, Gitea, Gogs, Bitbucket Cloud, Bitbucket Server, несколько SCM (управление исходным кодом), я использовал gogs для сборки в начале из-за ошибки x509, вызванной проблемой сертификата https, и, наконец, отказался по схеме gogs, в итоге я использовал github+drone.

Конфигурация, связанная с Github

Взаимодействие между Drone и Github должно быть аутентифицировано через OAuth, поэтому сначала вам нужно подать заявку на приложение OAuth.

Открытымgithub.comНажмите на аватарку, чтобы выбратьSettings / Developer settings / OAuth Apps, затем нажмитеNew OAuth AppСоздайте приложение OAuth.

вhttp://cici.xxxx.comЭто доменное имя, на котором вы развертываете Drone. Будьте осторожны, чтобы не указать неправильно URL-адрес обратного вызова.

urigiT.png

Затем зарегистрируйте приложение и запишитеClientIDиClientSecretиспользовать ниже

urFN01.png

конфигурация, связанная с docker-compose

Я установил его здесь с помощью docker, оркестровки docker-compose.

Для установки дрона требуетсяdrone-serverиdrone-runner,

Дрон-раннер не требуется. Официально не рекомендуется устанавливать раннер и сервер на один инстанс. Если вы устанавливаете на один инстанс, вы можете установить DRONE_AGENTS_ENABLED=false, дрон-сервер будет использоваться как раннер по умолчанию. Я здесь для демонстрация Runner и сервер находятся на одном сервере.

файл docker-compose.yml:

version: '2'

services:
  drone-server:
    image: drone/drone:latest
    container_name: drone-server
    networks: 
      - dronenet        # 让drone-server和drone-agent处于一个网络中,方便进行RPC通信
    ports:
      - '10081:80'      # Web管理面板的入口 PROTO=http  时使用该端口
      - '10082:443'     # Web管理面板的入口 PROTO=https 时使用该端口
      - '10083:9000'    # RPC服务端口
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock   # docker.sock [1]
      - /var/data/drone/:/var/lib/drone             # drone数据存放路径
    environment:
      - DRONE_AGENTS_ENABLED=true                   # 使用Runner
      - DRONE_GITHUB_SERVER=https://github.com                    # github的地址
      - DRONE_GITHUB_CLIENT_ID=${DRONE_GITHUB_CLIENT_ID}          # 上一步获得的ClientID
      - DRONE_GITHUB_CLIENT_SECRET=${DRONE_GITHUB_CLIENT_SECRET}  # 上一步获得的ClientSecret
      - DRONE_RPC_SECRET=${DRONE_RPC_SECRET}                      # RPC秘钥	[2]
      - DRONE_SERVER_HOST=${DRONE_SERVER_HOST}                    # RPC域名(在一个实例上可以不用)
      - DRONE_SERVER_PROTO=${DRONE_SERVER_PROTO}                  # git webhook使用的协议(我建议http)
      - DRONE_OPEN=true                                           # 开发drone
      - DRONE_DATABASE_DATASOURCE=/var/lib/drone/drone.sqlite     # 数据库文件
      - DRONE_DATABASE_DRIVER=sqlite3                             # 数据库驱动,我这里选的sqlite
      - DRONE_DEBUG=true                                          # 调试相关,部署的时候建议先打开
      - DRONE_LOGS_DEBUG=true                                     # 调试相关,部署的时候建议先打开
      - DRONE_LOGS_TRACE=true                                     # 调试相关,部署的时候建议先打开
      - DRONE_USER_CREATE=username:TheWinds,admin:true           # 初始管理员用户
      - TZ=Asia/Shanghai                                          # 时区
    restart: always
  drone-agent:
    image: drone/agent:latest
    container_name: drone-agent
    networks: 
      - dronenet     # 让drone-server和drone-agent处于一个网络中,方便进行RPC通信
    depends_on:
      - drone-server 
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock # docker.sock [1]
    environment:
      - DRONE_RPC_SERVER=http://drone-server  # RPC服务地址
      - DRONE_RPC_SECRET=${DRONE_RPC_SECRET}  # RPC秘钥
      - DRONE_RPC_PROTO=${DRONE_RPC_PROTO}    # RPC协议(http || https)
      - DRONE_RUNNER_CAPACITY=2               # 最大并发执行的 pipeline 数
      - DRONE_DEBUG=true                      # 调试相关,部署的时候建议先打开
      - DRONE_LOGS_DEBUG=true                 # 调试相关,部署的时候建议先打开
      - DRONE_LOGS_TRACE=true                 # 调试相关,部署的时候建议先打开
      - TZ=Asia/Shanghai
    restart: always
networks:
  dronenet:					# 让drone-server和drone-agent处于一个网络中,方便进行RPC通信
  • [1]Поскольку сам плагин тоже является контейнером, необходимо запускать контейнер в контейнере (docker-server, drone-runnere). Установка docker.sock в контейнер позволяет контейнеру получить возможность управлять контейнером через API сокетов docker unix.
  • [2]ты можешь пройтиopenssl rand -hex 16Эта команда генерирует случайный ключ

.env-файл:

DRONE_GITHUB_CLIENT_ID=your_github_client_id
DRONE_GITHUB_CLIENT_SECRET=your_github_client_secret 
DRONE_RPC_SECRET=your_rpc_secret
DRONE_SERVER_HOST=cici.xxxx.com
DRONE_SERVER_PROTO=http
DRONE_RPC_SERVER=rpc.cici.xxxx.com
DRONE_RPC_PROTO=http

запускать

будетdocker-compose.ymlи.envЗагрузите файл в тот же каталог на сервере, а затем выполните

docker-compose up -d

Запустите сервис, откройте свое доменное имя, если все пойдет хорошо, и вы увидите

Страница авторизации OAuth, после авторизации вы можете увидеть панель управления 💜

urmY80.png

использовать

Для базового использования вы можете в основном обратиться к документам выше https://docs.drone.io/.Там нечего сказать.Далее я в основном хочу поговорить о секретном управлении и использовании частных складов.

Тайное управление

Оркестровка рабочего процесса CI записывается на складе.drone.ymlСреди них, если мы хотим выполнить некоторые частные операции (например, ssh_key, пароль учетной записи для уведомления...), нам нужно записать эту конфиденциальную информацию в yml, и раскрытие этой частной информации определенно не допускается. Таким образом, эта секретная информация обычно используется инструментом CI в процессе сборки.Внедрить в переменную окружениясередина.

Дрон поддерживает множество секретных методов управления, самый простой и удобный способ — управлять напрямую через веб-фон.

ОткрытымRepositories/your_repo_name/settingsНайдите вкладку «Секреты», введите «Имя секрета» и «Значение секрета», чтобы добавить пару «ключ-значение» Имя => Значение, которая будет введена в процессе сборки.

Давай попробуем

  1. Гитхаб создать проектdrone_test_pub
.
├── .drone.yml
└── main.go
  • main.go
package main

import (
	"fmt"
	"os"
	"strings"
)

func main() {
	aSecret := os.Getenv("A_SECRET")
	fmt.Println(aSecret)
	fmt.Println(reverseString(aSecret))
}

func reverseString(s string) string {
	r := []rune(s)
	sb := strings.Builder{}
	for i := len(r) - 1; i >= 0; i-- {
		sb.WriteRune(r[i])
	}
	return sb.String()
}
  • .drone.yml
---
kind: pipeline
type: docker
name: default

steps:
- name: build
  image: golang
  environment:
    A_SECRET:
      from_secret: a_secret
  commands:
  - echo ?A_SECRET
  - go run . > test_secret.txt
  - cat test_secret.txt
  1. Панель администратора дрона, активируйте репозиторий drone_test_pub и создайте секрет уровня репозиторияa_secret = terces elbakaepsnu

ur8ZPe.md.png

  1. Отправьте код на Github, чтобы проверить статус сборки.
▶ git commit --allow-empty
[master 0460b0d] test push

▶ git push
Enumerating objects: 1, done.
Counting objects: 100% (1/1), done.
Writing objects: 100% (1/1), 179 bytes | 179.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To github.com:TheWinds/drone_test_pub.git
   0ccca9b..0460b0d  master -> master

4. Постройте результаты

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

Из результата выполнения сборки мыecho $A_SECRETкогда ты получишь маску********, то после инвертирования $A_SECRET в main.go мы получилиunspeakable secretУказывает, что введенный секрет был успешно получен.

Взглянув на исходный код Drone-Runtime, вы можете увидеть, что Secret Value будет добавлен к заменителю строки для контента, который будет отображаться на консоли во время работы, и он будет заменен маской равномерно.********.Однако это бесполезно: путем манипуляций со строками он может вывести незамаскированный секрет, а затем его можно будет восстановить. .

urGPzj.md.png

urGALq.md.png

Клонировать частное репо

Drone будет иметь шаг Clone по умолчанию.Чтобы клонировать приватный репозиторий, этот шаг должен быть отключен.

Затем поместите Github репозиторияdeploy_keyсоответствующийзакрытый ключУстановите секрет, который будет введен в переменную среды SSH_KEY.

Следующим шагом будет создание клона, здесь я использую образ alpine/git черезecho "?SSH_KEY" > /root/.ssh/id_rsaЗапишите закрытый ключ в id_rsa, и git clone заполните ssh-адрес вашего частного хранилища для клонирования.

По сравнению с гитхабовым глобальным sshkey, deploy_key может управлять только разрешением на клонирование хранилища, которое подходит для операций деплоя, я не буду вдаваться в подробности, как его задать.

Чтобы сгенерировать пару sshkeys, вы можете использоватьssh-keygen -t rsa -b 4096 -C "your_email"эта команда

  • .drone.yml
---
kind: pipeline
type: docker
name: default

clone:
  disable: true
steps:
- name: clone
  image: alpine/git
  environment:
    SSH_KEY:
      from_secret: ssh_key
  commands:
    - mkdir -p /root/.ssh/
    - echo "?SSH_KEY" > /root/.ssh/id_rsa
    - chmod -R 600 /root/.ssh/
    - ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts
    - git clone -v git@github.com:TheWinds/drone_test.git .
- name: build
  image: golang
  commands:
  - go run . > hello.txt
  - cat hello.txt

Эпилог

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

удачи.