CI/CD는 잘 정립된 소프트웨어 개발 교리입니다. 인터넷에는 CI/CD에 관한 기사와 페이지가 가득합니다. 항상 동일한 CI/CD 이미지를 갖습니다. 제가 말하는 이미지가 어떤 것인지 아시리라 믿습니다.
해당 주제에 대한 수십 개의 기사를 읽었으며 엔드투엔드 CI/CD 파이프라인 구현을 경험했습니다. 현실은 CI/CD 파이프라인을 구현하는 것이 기사를 읽고, CI/CD 전체 그림을 이해하고, 이론을 사용하는 것보다 훨씬 더 복잡하다는 것입니다. CI/CD 파이프라인 개발에는 학제간 경험이 풍부한 팀이 필요합니다.
이 문서에서는 Python 애플리케이션의 최소 실행 가능한 CI 파이프라인을 구축하는 방법을 설명합니다. 기사 내용을 다른 언어 및 요구 사항에 맞게 조정할 수 있습니다. 샘플에서는 FastAPI 및 GitHub Actions를 사용합니다.
기존 지속적 통합 설명에 2센트를 추가하겠습니다. 지속적인 통합은 자동으로 테스트되고 승인되었으며 제공 가능한 코드 변경 사항을 프로젝트 저장소에 정기적으로 병합하는 것을 의미합니다.
이 예에서는 GitHub Actions를 사용하여 각 'Pull Request' 또는 'Push to Main' 이벤트에 대해 필요한 검사를 자동으로 실행하여 코드가 저장소 품질 표준을 준수하는지 확인합니다. 시장에서는 Jenkins , Travis , CircleCI , GitLab 등 다양한 CI/CD 도구 컬렉션을 제공합니다. 파이프라인 요구 사항에 가장 적합한 도구를 선택하세요.
예제 워크플로에서는 새 코드가 pre-commit 을 실행하는 형식 지정 규칙을 따르는지 확인합니다. 그런 다음 Pytest를 사용하여 소규모 테스트를 실행하고 마지막으로 Kin D 클러스터에 애플리케이션 Helm Chart를 설치하는 중간 테스트를 실행합니다.
지속적인 통합 워크플로는 팀 규모, 성숙도, 애플리케이션 요구 사항 및 분기 전략에 따라 달라집니다.
코드 변경 사항을 실행하지 않고 분석합니다. 정적 분석 도구는 코드가 형식 지정 규칙을 준수하는지, 더 이상 사용되지 않거나 손상된 종속성을 사용하지 않는지, 읽기 쉽고 충분히 간단한지 확인합니다. 또한 프로그래밍 언어에 따라 안티 패턴 및 버그 코딩을 제안합니다.
Pre-commit을 설치, 구성, 실행하는 방법을 설명하겠습니다. Pre-commit을 Sonar 또는 Synk 와 같은 다른 분석 도구와 결합할 수 있습니다.
사전 커밋은 Python으로 작성된 도구입니다. 저장소에서 이를 구성하는 것은 YAML 파일을 생성하고 모든 커밋 전에 실행하려는 버전이 지정된 후크를 추가하는 것만큼 간단합니다. 사전 커밋은 후크에 필요한 종속성을 자동으로 관리하고 발견된 오류를 자동 수정합니다. JSON, YAML, tf, py, ts 등 다양한 파일 형식을 지원합니다.
코드 검사를 푸시하기 전에 로컬에서 실행하여 인프라 비용을 절약하세요. CI에서 사전 커밋을 실행하여 푸시된 코드의 형식을 확인할 수 있습니다.
사전 커밋 도구를 설치, 구성 및 실행합니다.
repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v2.3.0 hooks: - id: check-yaml - id: end-of-file-fixer - id: trailing-whitespace
$ pip install pre-commit $ pre-commit install $ pre-commit run --all-files
Python 후크 제안:
단위, 통합 및 종단 간 테스트 정의와 범위가 분산되어 있는 경우가 있습니다. 지속적인 통합 설명에서와 마찬가지로 Google의 소프트웨어 엔지니어링 테스트 유형에 2센트를 추가하겠습니다.
소규모 : 빠른 테스트. 작은 코드 조각을 테스트합니다. 테스트 더블 또는 모의 환경(예: SQLite)을 사용하세요. 아티팩트를 빌드할 필요는 없습니다. 시간: ~ 60초.
중간 : 여러 코드 조각 간의 상호 작용을 테스트합니다. 여기에는 아티팩트 구축, 타사 아티팩트(예: 데이터베이스 ) 사용 및 로컬 호스트 네트워크에 연결이 포함될 수 있습니다. 가짜 환경(예: docker-compose, Kind, Minikube 등) 또는 외부 서비스(예: Azure Blob Storage 또는 AWS S3) 사용. 시간: ~ 300초.
대규모 : 프로덕션과 유사한 환경(예: 성능 테스트)을 사용합니다. 시간: + 900초.
지속적인 통합 파이프라인에 대한 중간/대규모 테스트가 있는지 여부는 요구 사항에 따라 다릅니다.
이 예제에서는 Pytest를 사용하여 테스트를 실행하고 FastAPI 테스트 클라이언트를 사용하여 환경을 모의합니다. 비밀은 없습니다. 프로그래밍 언어 테스트 도구는 애플리케이션을 테스트하는 데 필요한 모든 종속성을 제공해야 합니다.
또한 최소 테스트 적용 범위 확인을 추가하고 결과의 일부로 업로드할 수 있습니다. 테스트 범위는 까다로운 측정 기준입니다. 높은 테스트 적용 범위가 암묵적으로 잘 테스트된 코드를 의미하는 것은 아니지만 50%는 0% 테스트된 코드보다 높습니다.
Kin D는 로컬 개발 또는 CI에 사용되는 docker-in-docker 경량 Kubernetes 클러스터입니다. Kind를 사용하여 테스트 환경을 설정하고 이에 대해 테스트를 실행합니다.
Kind는 레지스트리에서 이미지를 다운로드할 수 없기 때문에 이미지를 다운로드하지 못합니다. Kind를 사용하려면 이미지를 로드해야 합니다.
MetalLB 는 베어메탈 Kubernetes 로드 밸런서입니다. MetalLB 웹페이지에서 로드 밸런서가 필요한 이유에 대해 자세히 알아보세요.
Helm Chart를 사용하여 설치한 후에는 필수 CRD를 생성할 수 있습니다.
--- apiVersion: metallb.io/v1beta1 kind: L2Advertisement metadata: name: kind-advertisement --- apiVersion: metallb.io/v1beta1 kind: IPAddressPool metadata: name: kind-address-pool spec: addresses: - "172.26.255.0/24"
Docker는 Kind 클러스터(예: 172.26.0.0/16)에 대한 서브넷을 생성합니다. Kind 네트워크 인터페이스를 검사하여 할당된 IP 주소 범위를 확인하고 해당 주소를 IPAddressPool 리소스의 값으로 사용합니다. MetalLB 구성에 대한 자세한 내용은 KinD 웹 페이지에 있습니다.
Ingress-Nginx Helm 차트를 설치합니다. 그런 다음 Ingress 객체를 정의하는 애플리케이션 Helm Chart를 설치합니다. ingressClassName 속성을 nginx로 설정하고 호스트(예: api.local)를 정의합니다. 마지막으로 /etc/host를 수정하여 다음 줄을 추가합니다.
192.168.1.10 api.local
동일한 주소를 가리키는 호스트를 원하는 만큼 정의할 수 있습니다. Nginx가 나머지 작업을 수행합니다.
Kind를 사용하여 로컬 환경을 시작, 업데이트, 삭제하는 도구를 개발합니다. 개발자는 이를 사용하여 쉽게 애플리케이션을 디버깅하고, 보고된 버그를 로컬로 재현하거나, CI에서 테스트를 실행할 수 있습니다.
이 예제는 Linux 기반 배포판에서 작동합니다. Windows/MacOS의 경우 그대로 작동하지 않을 수 있으므로 변경이 필요할 수 있습니다.
필요한 아티팩트를 제공하기 전에 워크플로는 린팅 및 테스트 단계를 실행합니다.
우리는 Commitizen을 사용하여 아티팩트 릴리스를 관리합니다. Commtizen은 자동으로 아티팩트 버전을 업데이트하고 변경 사항을 푸시합니다. 구성된 태그 형식으로 새 git 태그를 생성합니다. 최신 변경 사항으로 변경 로그를 업데이트하도록 Commtizen을 구성할 수도 있습니다.
[tool.commitizen] tag_format = "v$major.$minor.$patch" version_scheme = "semver" version_provider = "pep621" major_version_zero = true update_changelog_on_bump = true version_files = [ "charts/ci-example/Chart.yaml:version", "charts/ci-example/Chart.yaml:appVersion" ]
워크플로는 Commitizen 출력 버전을 사용하여 Docker 이미지 및 Helm 차트 태그를 설정합니다.
각 아티팩트(이미지 및 차트)에 대해 서로 다른 버전을 가질 수 있습니다. 그러나 차트 및 이미지 변경 사항은 이전 버전과 호환되어야 합니다. 개발 및 출시 프로세스가 복잡해집니다. 이를 방지하기 위해 두 아티팩트에 동일한 버전을 사용합니다.
이 문서에서는 간단하지만 기능적인 연속 통합 워크플로를 개략적으로 설명합니다. 다른 프로그래밍 언어에서 작동하거나 요구 사항에 맞게 변경해야 할 수도 있지만 일부 단계는 쉽게 내보낼 수 있고 그대로 작동해야 합니다.
CI/CD 실습: 지속적인 배포 [2부] 출시 예정…