Github 작업을 통해 Kubernetes에 지속적으로 배포됩니다.

출신 배경


우리는 베를린에 있는 젊은 초창기 회사로 구글 클라우드 플랫폼에 있다.우리는 이전에 우리 회사가 사용했던 다른 클라우드 공급자에 비해 GCP가 개발자에게 더욱 우호적이라는 것을 발견했다.Google Cloud는 플랫폼에서 클라우드 자원을 상호 작용하고 관리하는 CLI 도구인 gcloud을 제공합니다.이것은 dockerkubectl)와 같은 다른 도구에 대한 인증 및 구성에 사용할 수 있습니다.GCP의 개념은 Service-Accounts으로 적당한 IAM 권한을 분배하여 서비스를 관리할 수 있다.

Github 작업을 선택해야 하는 이유


이전 회사의 SRE/DevOps/Platform 팀의 가장 큰 문제점 중 하나는 CI/CD 작업을 실행하는 Jenkins 집단을 관리하는 것이다.일반적인 자가 관리 설치에는 다음과 같은 문제가 있습니다.
  • 은 당일 필요에 따라 자동으로 축소됩니다.핵심 업무 시간 내에 작업을 즉시 실행할 수 있도록 용량을 늘려야 합니다. 그렇지 않으면 용량을 줄여야 합니다.
  • 개의 작업에 서로 다른 버전의 소프트웨어를 설치해야 할 수 있습니다.예제 - 한 서비스는 Java 11이 필요할 수 있고, 다른 서비스는 Java 15에 적응할 수 있습니다.
  • 같은 공유 작업 노드에서 실행되는 작업이 정확하게 격리되지 않으면 같은 파일과 라이브러리에 의존하고 덮어쓰기를 통해 서로 방해할 수 있습니다.
  • 같은 작업 노드에서 실행되는
  • 개의 작업은 자원을 경쟁할 수 있어 구축 시간이 증가하고 때로는 시간을 초과하여 파이프에 편상이 생길 수도 있다.
  • 메인 서버와 작업 노드의 지속적인 소프트웨어 유지 보수.여기에는 기본 운영 체제 업그레이드, 설치된 소프트웨어 패치 또는 수동 업데이트가 포함됩니다.
  • 우리가 플랫폼의 구조를 토론할 때 관계자들은 그들이 과거에 CD 서버를 사용한 (고통스러운) 경험을 제기했다.우리는 모두 동의합니다. 우리는 자신의 CI/CD 서버 집단을 관리하고 싶지 않습니다.
    상술한 모든 문제와 기타 몇 가지 원인을 해결하기 위해서 우리는 Github Actions을 사용하기로 결정했다

    Github 작업은 모든 Github 이벤트 (예: push, merge에서 메인 지점 등) 에서 작업을 설정할 수 있는 간단한 YAML 기반 문법을 제공합니다. 이 작업은 Microsoft Azure의 사용 가능한 서버에서 실행됩니다.
    우리는 간단한 작업부터 끊임없이 통합, 구축, 테스트를 시작하여docker 용기를 만들고 용기 등록표로 전송합니다.이것은 java 서비스의 예입니다.
    on:
      push:
        branches:
          - master
    
    jobs:
      build:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v2 # checkout repo
          - uses: actions/setup-java@v1 # Set up latest Java 14
            with:
              java-version: 14
    
          - name: Build with Gradle
            run: ./gradlew clean build
    
          - uses: GoogleCloudPlatform/github-actions/setup-gcloud@master # Setup gcloud
            with:
              service_account_key: ${{ secrets.GCP_SA_KEY }} # ServiceAccount key with necessary rights added as a secret on Github.
    
            # Configure credentials for docker
          - run: gcloud auth configure-docker
    
            # Build the Docker image
          - run: docker build -t gcr.io/example.com/${{ github.event.repository.name }}:${{ github.sha }} .
    
            # Push the Docker image to Google Container Registry
          - run: docker push gcr.io/example.com/${{ github.event.repository.name }}:${{ github.sha }}
    

    GKE에 애플리케이션 배포


    이 구조의 또 다른 관건은 서비스를 배치하는 Kubernetes 집단이다.우리는 Google Kubernetes Engine을 자랑스럽게 사용했는데 지금까지 우리의 체험은 적극적이었다. 왜냐하면 관리와 확장이 쉽고 운영 비용을 없앴기 때문이다.
    Kubernetes는 kubectl으로 관리되며 gcloud CLI는 필요한 kubeconfig을 생성하여 구성 자격 증명에 사용할 수 있습니다.
    응용 프로그램은 Helm개의 도표로 포장되고 환경 수요에 따라 설정된다.이 점을 언급하는 것은 매우 중요하다. 왜냐하면 helmkubeconfig을 사용하여 집단과 상호작용을 하기 때문이다.
    배포는 다음과 같이 컨테이너 레지스트리의 최신 이미지를 사용하여 생성 및 업데이트됩니다.
    # Creating a deployment
    helm install -f values.yml --set image.version=<latest> example-service example-service
    
    # Updating a deployment
    helm upgrade -f values.yml --set image.version=<latest> example-service example-service
    
    
    GKE hardening guide은 Kubernetes 집단에 대한 네트워크 접근을 제한하고 private cluster으로 만드는 것을 권장합니다.이것은 노드를 공공 인터넷과 격리시키고 Kubernetes API 서버에 대한 접근은 특정한 신뢰받는 네트워크 IP로만 제한할 수 있다.
    우리가 시작했을 때, 우리는 allow-list을 만들었고, 그 IP는 신뢰받는 기계로 집단을 관리하고 수동으로 업그레이드를 배치하는 데 사용되었다.또한 배포, 복구 및 확장을 위한 매우 멋진 UI 도구를 구축했습니다.
    이 점에서 이 모든 것은 보기에 이렇다

    우리가 지속적인 배치가 필요하다고 느낄 때까지 오랫동안 이 모든 것이 좋았다.나는 here의 논점에 동의한다.

    도전하다


    파이핑에 연속 배치를 추가하는 가장 간단한 방법은 Github 작업 파이핑에 또 다른 절차를 추가하여 최신 이미지를 그룹에 배치하는 것이다.작업을 업데이트하는 방법:
        # ...
        # same as before
        # ...
    
          - uses: GoogleCloudPlatform/github-actions/setup-gcloud@master # Setup gcloud
            with:
              service_account_key: ${{ secrets.GCP_SA_KEY }} # ServiceAccount key with necessary rights added as a secret on Github.
    
            # Configure credentials for docker
          - run: gcloud auth configure-docker
    
            # Build the Docker image
          - run: docker build -t gcr.io/example.com/${{ github.event.repository.name }}:${{ github.sha }} .
    
            # Push the Docker image to Google Container Registry
          - run: docker push gcr.io/example.com/${{ github.event.repository.name }}:${{ github.sha }}
    
            # Generate kubeconfig entry
          - run: gcloud container clusters get-credentials <cluster-name> --zone <zone> --project <project>
    
            # Install helm
          - uses: azure/setup-helm@v1
            id: install
    
            # Deploy latest version
          - run: helm upgrade -f values.yaml --set image.version=${{ github.sha }} example-service example-service
    
    
    불행하게도 이것은 작용하지 않고 파이프가 마지막 단계에서 실패했다.Kubernetes 서버가 공용 인터넷을 통해 액세스할 수 없기 때문입니다.

    가능한 해결 방안(그리고 그에 따른 문제)

  • 집단을 공개적으로 설정하는 간단한 방법은 집단이 인터넷을 통해 접근할 수 있도록 하는 것이다.그러나 이것은 집단을 노출하는 대가로 설정의 안전성을 떨어뜨릴 것이다.이런 저울질은 가치가 없다.
  • 은 조작 실행 프로그램 IP를 허용 목록에 추가합니다. 이 생각은 시작할 때 보기 좋았지만 깊이 파고들었을 때 이 작업을 실행하는 서버는 5 Azure regions in the US의 모든 서버가 될 수 있다는 것을 발견했습니다.Github 페이지에는 정기적으로 업데이트되는 IP 범위를 포함하는 JSON 파일을 다운로드하는 방법이 나와 있습니다.이 길을 따라 내려가면 목록을 계속 가져오고 허용 목록을 업데이트하는 것을 의미합니다.
    자동화 솔루션은 원래 가장 좋은 것이지만, 나는 파일을 분석하고 싶지 않다.다행히도 Azure 클라우드는 Service Tags의 IP 범위를 얻을 수 있습니다.문제는 모든 5개 영역의 IP 범위가 총 1100+(지난번 내가 검사했을 때)로 GKE는 50 entries for authorized networks밖에 되지 않는다는 것이다.
    <이미지 삽입--머리 충돌 벽>
  • 에는 Azure Ip 범위에서만 접근할 수 있는 실행 중인 경형 프록시 서버가 있습니다.프로그래밍 구성을 통해 IP 목록의 업데이트를 유지할 수 있는 간단하고 기존 솔루션은 없습니다.
  • 배치를 트리거하기 위해 호출할 수 있는 공공 접근 가능한 API를 만들어야 합니까?아마도 나는 Basic Auth을 통해 신분 검증을 하고 안전하다고 할 수 있을 것이다.( It's not! ). 나는 단지 이 길을 가는 것이 옳지 않다고 생각했을 뿐이다.
  • 여러 가지 이유로 이 모든 것이 부자연스러운 해결 방안인 것 같다.프로그래밍 방식으로 방화벽을 설정할 수 없어서 문제가 생긴 것 같습니다.

    솔루션


    다른 임무를 처리할 때, 나는 줄곧 해결 방안을 생각하고 있다.CD 서버를 관리하고 싶지 않습니다. 집단을 노출하고 싶지 않습니다. helm에서 Kubernetes 제어 서버에 도착하고 싶습니다.
    나는 행동하는 YAML을 쳐다보며 해결 방안을 찾는 횟수가 내가 인정하고 싶은 것보다 훨씬 많았다. 결국 나를 맞힐 때까지. 나는 신뢰받는 IP에서 배치 절차를 실행할 수 있을 뿐이다.
    나는 일을 2-builddeploy으로 나눈다.
  • build 부분은 CPU와 메모리 집약형 부분으로 코드를 컴파일하고 테스트를 실행하며 공작물을 만들고docker 이미지를 구축하여 용기 등록표로 보내는 데 사용된다.
  • deploy 부품은 helm이 있는 최신 이미지만 배치합니다.
    Github 호스팅된 운영 프로그램에서 build을 완료하면 deployself-hosted action-runner에서 실행됩니다.
  • 이 자동 위탁 관리 프로그램은 구글 클라우드에 있는 정적 IP를 갖춘 컴퓨터 기기다.현재 이 정적 IP를 Kubernetes 인증 IP 목록의 허용 목록에 설정할 수 있습니다.
    업데이트된 설정은 다음과 같습니다.

    다음은 업데이트된 actions.yaml입니다.
    on:
      push:
        branches:
          - master
    
    jobs:
      build:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v2 # checkout repo
          - uses: actions/setup-java@v1 # Set up latest Java 14
            with:
              java-version: 14
    
          - name: Build with Gradle
            run: ./gradlew clean build
    
          - uses: GoogleCloudPlatform/github-actions/setup-gcloud@master # Setup gcloud
            with:
              service_account_key: ${{ secrets.GCP_SA_KEY }} # ServiceAccount key with necessary rights added as a secret on Github.
    
            # Configure credentials for docker
          - run: gcloud auth configure-docker
    
            # Build the Docker image
          - run: docker build -t gcr.io/example.com/${{ github.event.repository.name }}:${{ github.sha }} .
    
            # Push the Docker image to Google Container Registry
          - run: docker push gcr.io/example.com/${{ github.event.repository.name }}:${{ github.sha }}
    
      deploy:
        runs-on: self-hosted
        needs: [build] # to block for the build step to complete successfully
        steps:
          - uses: actions/checkout@v2
    
          - uses: GoogleCloudPlatform/github-actions/setup-gcloud@master # Setup gcloud
            with:
              service_account_key: ${{ secrets.GCP_SA_KEY }}
    
            # Generate kubeconfig entry
          - run: gcloud container clusters get-credentials <cluster-name> --zone <zone> --project <project>
    
            # Install helm
          - uses: azure/setup-helm@v1
            id: install
    
            # Deploy latest version
          - run: helm upgrade -f values.yaml --set image.version=${{ github.sha }} example-service example-service
    
    
    제가 해봤는데 효과가 좋아요.🎉.
    그때부터 우리는 모든 서비스를 업데이트했고 유사한 패턴으로 builddeploy개의 작업을 분할하였으며, 지금은 코드를 매번 변경에 따라 모든 환경에 발송하게 되어 매우 기쁩니다.

    만약 네가 지금까지 읽었다면, 나는 너에게 공부하는 것이 매우 궁금하다.
  • 솔루션에 대해 어떻게 생각하십니까?
  • Github 를 사용하십니까?
  • 또한 Kubernetes에 지속적으로 배포됩니까?
  • 당신은 지금 어떻게 합니까?가능하다면, 당신은 어떻게 바뀔 것입니까?
  • 면책 성명


    여기에 표시된 설정은 위의 주제에 집중하기 위해 실제 환경에 존재하는 다른 핵심 구성 요소를 포함하지 않는 단순화 버전입니다.

    좋은 웹페이지 즐겨찾기