무인기 CI 사용

21560 단어 automationdevopsci

아주 오래된 무인기 인터페이스인데, 이것이 바로 무인기가 필요로 하는 것이다.

소개


우리는 프로젝트에서 Drone CI을 사용한 지 이미 몇 달이 되었다.최근에 나는 내 팀의 무인기 파이프에 대해 중대한 재구성을 해야만 했다. 그래서 나는 현재 무인기 배치가 나의 기억에 상당히 신선하다고 생각한다. 나는 무인기 CI를 사용한 경험에 관한 블로그 글을 쓸 수 있다.따라서 다음은 제가 개발자로서 무인기 CI를 사용한 경험입니다. 만약sysops를 찾고 있다면, 무인기 CI를 어떻게 설치하는지, 신분 검증을 어떻게 하는지 등입니다. 저는 이런 것들을 쓰고 있지 않습니다. 공식 무인기 문서를 읽어야 합니다.

무인기 CI 기초 지식


나는 무인기에 관한 강좌를 하지 않을 것이다. 너는 Drone CI home page에서 무인기에 관한 내용을 더 많이 읽을 수 있지만, 반대로 나는 무인기 CI의 중요한 부분, 내가 개발자로서 무인기 파이프를 유지하고 매일 무인기를 사용하여 응용 프로그램을 구축하고 배치하는 경험에 대해 썼다.
무인기는 컨테이너 구조를 채택한다.이것은 무인기 배열기가 Docker 용기에서 실행 중이라는 것을 의미한다. 무인기 파이프의 모든 단계는 새로운 용기를 촉발할 것이다. 이 용기는 이 특정한 파이프 단계에 좋은 격리 환경을 제공한다.샘플 파이프 설명은 다음과 같습니다.
local featureBranchPattern = "feature/*";
...
local buildApps() = {
    name: 'build-apps',
    user: user,
...
# Drone pipelines
[
{
    kind: 'pipeline',
    type:'kubernetes',
    name: 'feature-branch',
    trigger: {
        branch: [featureBranchPattern],
        event: ['push'],
    },
    steps: [
        changeRights(),
        cleanDirs(),
        buildApps(),
        startPostgresMinio(),
        runTests(),
...

그것은 jsonnet으로 가독성이 매우 좋다.이것은 쿠버네츠 내부에서 운행하는 파이프라는 것을 읽을 수 있다.기능 브랜치가 Git 저장소로 밀어넣으면 파이프가 트리거됩니다.jsonnet 대신 yaml을 사용하는 것을 강력히 권장합니다. 변수(예를 들어 위의 featureBranchPattern), 함수(예를 들어 위의 buildApps), 분기 구조(예를 들어 if)를 사용할 수 있기 때문입니다.Jsonnet은 파이프의 공공 부분을 템플릿화하고 상수 등을 제공하는 더 좋은 설정 언어를 제공합니다.
당신은 기본적으로 무인 비행기 단계에서 Docker image, 즉 Docker Hub의 기본 Docker 이미지(예를 들어 우리는 Docker Compose image을 사용하여 테스트에서 데이터베이스, S3 시뮬레이터, 각종 의존항 등을 설정), 사용자 정의 Docker 이미지, 즉 Drone Plugins을 사용할 수 있습니다.무인 항공기에서 특수 작업을 수행하거나 (예를 들어 AWS ECR Plugin으로 이미지를 구축하여 AWS ECR 등록표로 전송) 사용자 정의 Docker 이미지를 사용할 수 있습니다.
파이핑 단계를 작성할 때 Linux 셸(예: bash)을 사용할 수 있습니다.아래의 예는 무인기 파이프 절차 중의 간단한 공격을 보여 준다.
local user = 1000;
local buildBoxImage = 'circleci/clojure:openjdk-11-tools-deps-1.10.0.414-node';
local m2Repo = ' -Sdeps \'{:mvn/local-repo "/drone/src/.m2/repository"}\' ';
...
local buildApps() = {
    name: 'build-apps',
    user: user,
    image: buildBoxImage,
    commands: [
    'echo "Starting step: buildApps *********************"',
    'whoami',
    'pwd',
    'export ALL_BEGIN=$$(date +%s)',
    # Start actual jar building
    'echo "Building koodisto *********************"',
    'export COMMAND_BEGIN=$$(date +%s)',
    'cd koodisto',
    'export NPM_CONFIG_PREFIX=/drone/src/koodisto/.npm-global',
    'export PATH=$PATH:/drone/src/koodisto/.npm-global/bin',
    'npm install shadow-cljs',
    'npm install',
    'echo "css phase..."',
    'clj ' + m2Repo + ' -A:css -t target/shadow/prod/resources/public/css',
    'echo "frontend phase..."',
    'clj ' + m2Repo + ' -A:common:frontend -m shadow.cljs.devtools.cli release app',
    'echo "uberjar phase..."',
    'clj ' + m2Repo + ' -A:common:backend:uberjar',
    'cd ..',
    'export END=$$(date +%s)',
    'export KOODISTO_DURATION=$$(($${END}-$${COMMAND_BEGIN}))',
    'echo Koodisto build duration $$(($$KOODISTO_DURATION / 60)) minutes and $$(($$KOODISTO_DURATION % 60)) seconds',
...

보시다시피 가장 좋아하는 Linux 셸을 사용하여 작성하는 절차는 매우 익숙합니다.모든 Docker 이미지를 파이핑 단계에 사용할 수 있으며, 이 단계에서는 모든 Docker 컨테이너에서 기본 작업을 수행할 수 있습니다.docker 용기에서 구축할 수도 있습니다. dind (docker-in-docker) 이미지를 사용하여 docker 이미지를 구축하고 용기를 시작할 수 있습니다.
로컬 drone exec을 사용하여 자신의 워크스테이션에서 아날로그 파이프를 사용할 수 있기 때문에 무인 파이프를 개발하는 절차와 절차가 상당히 쉽다. 예를 들어.
# Convert .drone.jsonnet to .drone.yml...
drone jsonnet --source .drone.jsonnet --stream --target .drone.yml
# ... and run it.
DRONE_REPO_NAME="testing2" DRONE_BRANCH="testing2" DRONE_COMMIT_SHA="testing2aa2" drone exec --trusted --pipeline feature-branch --env-file=tmp/.env .drone.yml

...drone exec가 워크스테이션에서 구축 프로세스를 시작하는 것을 볼 수 있습니다.
[build-apps:0] + echo "Starting step: buildApps *********************"
[build-apps:1] Starting step: buildApps *********************
[build-apps:2] + whoami
[build-apps:3] node
[build-apps:4] + pwd
[build-apps:5] /drone/src
[build-apps:6] + export ALL_BEGIN=$(date +%s)
[build-apps:7] + echo "Building koodisto *********************"
[build-apps:8] Building koodisto *********************
[build-apps:9] + export COMMAND_BEGIN=$(date +%s)
[build-apps:10] + cd koodisto
[build-apps:11] + export NPM_CONFIG_PREFIX=/drone/src/koodisto/.npm-global
[build-apps:12] + export PATH=$PATH:/drone/src/koodisto/.npm-global/bin
[build-apps:13] + npm install shadow-cljs
[build-apps:14] 
[build-apps:15] > [email protected] install /drone/src/koodisto/node_modules/puppeteer
[build-apps:16] > node install.js
...

자신의 파이프가 워크스테이션에서 작동한다고 확신하면 Git로 분기를 밀어 CI 환경의 무인기 서버가 똑같은 방식으로 똑같은 파이프를 실행할 수 있습니다.
무인기 파이프에서 무인기는 각 절차 간에 공유되는 환경을 유지했다.E, g.git repo는 디렉터리에 서명되어 있으며, 이 디렉터리는 모든 단계 (docker 용기) 에 자동으로 불러옵니다.이렇게 하면 모든 용기에서 같은 코드 디렉터리 구조를 인용할 수 있고, 더 많은 영구적인 작업 (예를 들어 구축된jar 파일) 을 이 디렉터리 구조에 저장할 수 있습니다. 예를 들어 나중에 다른 단계에서 Docker 이미지를 구축하고jar (이전 단계에서 구축한) 를 Docker 이미지에 베이킹할 수 있습니다.이전 단계에서 Docker 네트워크 (예: Docker Compose 사용) 를 만들고 다른 단계에서 같은 네트워크에서 실행되는 다른 Docker 컨테이너를 사용하여 테스트를 회전할 수도 있습니다.
무인기 운행 테스트가 아주 좋아요.예:
...
local dockerComposePluginImage = 'docker/compose:1.25.4';
...
local startPostgresMinio() = {
    name: 'start-postgres-minio',
    image: dockerComposePluginImage,
...
    commands: [
        'echo "Starting docker-compose: postgres and minio..."',
        'docker-compose -p clojure-dc -f infra/docker-compose.yml up -d',
    ],
};
...

local koodistoTests() = {
    name: 'koodisto-tests',
    image: dockerComposePluginImage,
...
    commands: [
...
        'echo "Building koodisto unit test image..."',
        'docker build -f koodisto/infra/unit-test/Dockerfile -t ' + koodistoUtImage + ' koodisto',
        'echo "Starting testing koodisto..."',
        'docker run -u 1000 --name koodisto-unit-test --network clojure-network --env-file infra/.env -v /drone/src:/drone/src ' + koodistoUtImage,
    ],
};
...
# Drone pipelines
...
    steps: [
...
        buildApps(),
        startPostgresMinio(),
        koodistoTests(),
...

따라서 우선 dockercompose 설정에서 두 개의 용기를 시작합니다: Postgres(DB)와 Minio(아날로그 S3 bucket).그리고 우리는 다른 용기에서 테스트를 실행합니다. 이 용기는 이 프로그램의 테스트를 실행하기 위해 만들어진 이미지입니다. (단, 테스트 기간에 Postgres와 Minio를 시작하고 실행해야 합니다.)

일부 관찰 결과


이 장에서 나는 무인기를 사용할 때 발견한 특수한 관찰 결과를 열거했다.
캐시캐시가 약간 도전적일 수 있습니다. 왜냐하면 무인기 집행기는 절차를 위해 짧은 Docker 용기를 시작하고, 이 용기들은 작업이 끝날 때 죽기 때문입니다.단, 캐시 노드 모듈, 마븐 의존 등은 가능하지만, 단계에서 계획을 세워야 합니다.가장 간단한 방법은 이 의존항을 작업 디렉터리에 다운로드하고 파이프의 끝에 이 의존항을 저장하는 것이다. 예를 들어 AWS S3, 그곳에서 전용 무인기 플러그인(AWS S3 Cache)으로 이 의존항을 저장할 수 있다.
사용자 및 권한Docker hub에서 가져온 이미지는 사용자가 원하지 않을 수도 있는 다양한 내장 사용자를 사용합니다.실제 CI 환경은 고려해야 할 다른 측면을 초래할 수도 있습니다.개인적으로 가장 간단한 해결 방안은 특정한 사용자만 사용하고 이 사용자를 사용하는 것이다. 예를 들어 다음 예시의 user과 같다.
local user = 1000; # => Use this user.
...
local buildBoxImage = 'circleci/clojure:openjdk-11-tools-deps-1.10.0.414-node';
...
local buildApps() = {
    name: 'build-apps',
    user: user, # => This image provides that user
    image: buildBoxImage,
...
local changeRights() = {
    name: 'change-rights',
    image: 'alpine:3.11',
    commands:
    [
    'adduser -D -H -u 1000 node node', # => This image doesn't provide that user... so, just create it.
    'getent passwd | grep node',
    'chown -R node /drone/src',
    ],
...

디버깅 기술.간단한 디버깅 기법은 단계 내에 임시 "세계 정지"명령을 놓는 것이다.
local changeRights() = {
    name: 'change-rights',
    image: 'alpine:3.11',
    commands:
    [
    'sleep 100000', # => Stop the world!
    'adduser -D -H -u 1000 node node',

...멈추는 것을 봐라.
[print-time-start-pipeline:3] + echo $MYBUF >> drone-build.log
[change-rights:0] + sleep 100000 # => It stopped here!

...그리고 용기에서 셸 세션을 가져와 디버깅을 합니다...
λ> whoami
kari
λ> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
71ca3dd39a37 alpine:3.11 "/bin/sh /usr/drone/…" 16 minutes ago Up 16 minutes sun7x2doztrvwt72j058x9lcn9go3h81
c67686bcdcfb docker:dind "dockerd-entrypoint.…" 16 minutes ago Up 16 minutes 2375-2376/tcp 5hi9nwckg6dtufpg06znzf7l6qyqu1ir
λ> docker exec -it 71 /bin/sh
/drone/src # whoami # => We are in!
root
/drone/src # ls -lah
total 84K    
drwxrwxr-x 10 1000 1000 4.0K Aug 26 13:33 .
drwxr-xr-x 3 root root 4.0K Aug 26 13:33 ..
-rw-rw-r-- 1 1000 1000 11.2K Aug 26 13:32 .drone.jsonnet
-rw-rw-r-- 1 1000 1000 10.0K Aug 26 13:32 .drone.yml
drwxrwxr-x 8 1000 1000 4.0K Aug 26 11:11 .git

Jenkins와 Drone 비교


몇 년 전에는 CI 서버로 Jenkins을 주로 사용했습니다.나의 젠킨스와 무인기 체험을 비교할 때 나는 무인기를 더욱 좋아한다. 이유는 다음과 같다.

  • 셸 스크립트.위의 예시에서 보듯이 용기에서 간단한 셸 명령을 사용하여 파이프 절차를 작성하고 이 단계에서 원하는 동작을 수행할 수 있습니다.너는 "Groovy 같지만 완전하지는 않은 언어"를 사용할 필요가 없다. 나는 네가 나의 뜻을 알고 있다고 생각한다.

  • 용기용기는 당신의 구축에 좋은 격리 위치를 제공합니다. 무인기 용기 기반의 기본 구조를 이해하면 디버깅을 잘 할 수 있습니다.Jenkins 구축을 디버깅하는 것은 물론 매우 쉽다. 왜냐하면 항상 ssh 세션을 Jenkins 서버에 보내고 Jenkins workplace 디렉터리로 돌아가서 실험을 할 수 있기 때문이다.

  • 지방 발전.drone exec은 CI 파이프를 개발하는 데 매우 좋은 도구입니다.예를 들어 모든 단계에서 동일한 사용자인 경우...) 워크스테이션과 팀의 무인기 서버에서 파이프를 완전히 동일한 방식으로 실행할 수 있습니다.

  • UI 문제가 없습니다.만약 당신이 Jenkins에서 특정한 플러그인을 사용하고 싶다면, 당연히 Jenkins를 설치할 때 설치할 수 있지만, 이 플러그인에는 많은 설정이 있습니다. 보통 Jenkins UI를 사용해서 완성해야 합니다.무인기가 있으면 모든 것이 Docker 컨테이너일 뿐 특별한 구성은 없습니다.
  • 결론


    Drone은 완전히 다른 구조와 모델을 제공하여 파이프를 만드는 새로운 CI 도구입니다.해봐--네가 좋아할 것 같아!
    작성자는 Metosin에서 Clojure를 사용하여 클라우드 프로젝트를 진행하고 있습니다.만약 핀란드에서 Clojure 프로젝트를 시작하거나 핀란드에서 Clojure 교육을 받는 것에 관심이 있다면, 제 메일박스에 이메일을 보내거나 LinkedIn을 통해 연락 주십시오.
    Kari Marttila
  • Kari Marttila LinkedIn 홈페이지:
  • 좋은 웹페이지 즐겨찾기