AWS Security Workshop - EKS로 웹 애플리케이션 구축(2)

Glen·2023년 6월 28일
1

aws security workshop

목록 보기
7/10
post-thumbnail

1편은 여기로
이어서 진행 합니다

6. Fargate 배포하기

  • 컨테이너에 적합한 서버리스 컴퓨팅 엔진
  • AWS ECS, EKS에서 모두 동작
cd /home/ec2-user/environment/manifests
  • pod를 배포하기 위해서는 pod가 실행될때 하나 이상의 fargate profile을 정의해야 함
cat <<EOF> eks-demo-fargate-profile.yaml
---
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
  name: eks-demo
  region: ${AWS_REGION}
fargateProfiles:
  - name: frontend-fargate-profile
    selectors:
      - namespace: default
        labels:
          app: frontend-fargate
EOF
  • fargate 생성 및 확인

  • 앞 실습에서 생성했던 프론트엔드 제거
kubectl delete -f frontend-deployment.yaml
#기존 프론트 디플로이 제거
  • 이후 deployment, service 수정한다음 재배포
kubectl apply -f frontend-deployment.yaml
kubectl apply -f frontend-service.yaml
  • kubectl get pod -o wide 로 fargate 배포 확인
  • fargate worket nodes 리스트 확인

    • kubectl get nodes -l eks.amazonaws.com/compute-type=fargate

7. Container Insights 사용하기

  • CloudWatch Container Insight는 컨테이너형 애플리케이션 및 마이크로 서비스에 대한 모니터링, 트러블 슈팅 및 알람을 위한 완전 관리형 관측 서비스.

  • CloudWatch Container Insight는 CPU, 메모리, 디스크 및 네트워크와 같은 인프라 메트릭을 자동으로 수집.

  • Fluent Bit를 사용하여 로그를 라우팅하는 작업을 수행.

  • 클러스터의 메트릭 값을 수집하기 위해 CloudWatch Agent 설치하고, CloudWatch Logs에 로그를 보내기 위해 Fluent Bit을 DaemonSet 형태로 설치.

  • manifest 파일을 관리하기 위해 폴더를 생성
cd ~/environment
mkdir -p manifests/cloudwatch-insight && cd manifests/cloudwatch-insight
  • amazon-cloudwatch 네임스페이스를 생성
kubectl create ns amazon-cloudwatch
  • namespace 확인
  • CloudWatch 에이전트 및 Fluent Bit를 설치
ClusterName=eks-demo
RegionName=$AWS_REGION
FluentBitHttpPort='2020'
FluentBitReadFromHead='Off'
[[ ${FluentBitReadFromHead} = 'On' ]] && FluentBitReadFromTail='Off'|| FluentBitReadFromTail='On'
[[ -z ${FluentBitHttpPort} ]] && FluentBitHttpServer='Off' || FluentBitHttpServer='On'
  • yaml을 다운로드
wget https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/quickstart/cwagent-fluent-bit-quickstart.yaml
  • 다운로드 받은 파일에 환경변수값을 적용
sed -i 's/{{cluster_name}}/'${ClusterName}'/;s/{{region_name}}/'${RegionName}'/;s/{{http_server_toggle}}/"'${FluentBitHttpServer}'"/;s/{{http_server_port}}/"'${FluentBitHttpPort}'"/;s/{{read_from_head}}/"'${FluentBitReadFromHead}'"/;s/{{read_from_tail}}/"'${FluentBitReadFromTail}'"/' cwagent-fluent-bit-quickstart.yaml
  • 위 다운로드 받은 yaml에 affinity 부분을 추가 해준다.
  • yaml 배포
  • 배포된 pod 확인
  • daemonset으로도 확인 가능.
  • cloudwatch 컨테이너 인사이트에서 맵 형태로 확인가능

8. Autoscaling Pod & Cluster

쿠버네티스에는 크게 두 가지의 오토 스케일링 기능이 있다.

  • HPA(Horizontal Pod AutoScaler)
    • HPA는 CPU 사용량 또는 사용자 정의 매트릭을 관찰하여 파드 개수를 자동으로 스케일합니다.
  • Cluster Autoscaler
    • 해당 파드가 올라가는 EKS 클러스터 노드 그룹의 자원이 모자라게 되는 경우, Cluster Autoscaler를 고려해야 합니다.

HPA 적용하기

  • HPA(Horizontal Pod Autoscaler) 컨트롤러는 메트릭 값에 값에 따라 파드의 개수를 할당
  • 파드 스케일링을 적용하기 위해 컨테이너에 필요한 리소스 양을 명시하고, HPA를 통해 스케일할 조건을 작성
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

kubectl get deployment metrics-server -n kube-system
  • flask deployment yaml을 수정
  • 레플리카를 1로 수정하고 리소스를 수정
cd /home/ec2-user/environment/manifests

cat <<EOF> flask-deployment.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-flask-backend
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: demo-flask-backend
  template:
    metadata:
      labels:
        app: demo-flask-backend
    spec:
      containers:
        - name: demo-flask-backend
          image: $ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/demo-flask-backend:latest
          imagePullPolicy: Always
          ports:
            - containerPort: 8080
          resources:
            requests:
              cpu: 250m
            limits:
              cpu: 500m
EOF

kubectl apply -f flask-deployment.yaml
  • hpa 설정을 위한 yaml
cat <<EOF> flask-hpa.yaml
---
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  name: demo-flask-backend-hpa
  namespace: default
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: demo-flask-backend
  minReplicas: 1
  maxReplicas: 5
  targetCPUUtilizationPercentage: 30
EOF

kubectl apply -f flask-hpa.yaml
  • kubectl get hpa
  • pod의 변화량을 파악하기 위한 옵션
  • siege로 pod의 부하를 주고 변화량을 파악한다
  • replicas가 5까지 늘어나는 것을 확인할수 있다.

9. Cluster Autoscaler

  • 트래픽에 따라 파드가 올라가는 워커 노드 자원이 모자라게 되는 경우도 발생하게 된다.
    • 워커 노드가 가득 차서 파드가 스케줄될 수 없는 상태
  • 이때, 사용하는 것이 Cluster Autoscaler(CA)
  • 클러스터의 상태를 시각화 하기 위해 kube-ops-view를 참고(저는 설치하지 않고 건너뜀)
  • 클러스터 워커노드에 적용된 ASG값 확인
    - code
        ```yaml
        aws autoscaling \
            describe-auto-scaling-groups \
            --query "AutoScalingGroups[? Tags[? (Key=='eks:cluster-name') && Value=='eks-demo']].[AutoScalingGroupName, MinSize, MaxSize,DesiredCapacity]" \
            --output table
        ```

auto scaling과 관련된 IAM policy 작업을 수행 해야됨.

  • iam setting

  • auto scaling 그룹 > 편집에서 최대용량을 5로 수정
  • Cluster Autoscaler 프로젝트에서 제공하는 배포 예제 파일 다운로드
wget https://raw.githubusercontent.com/kubernetes/autoscaler/master/cluster-autoscaler/cloudprovider/aws/examples/cluster-autoscaler-autodiscover.yaml
  • 다운받은 yaml에서 command 마지막 부분을 배포한 클러스터 이름으로 수정 후 배포
kubectl apply -f cluster-autoscaler-autodiscover.yaml
  • 워커노드 수 변화량을 체크하기 위해 w옵션으로 확인
  • 이후 100개의 파드를 배포하는 명령을 수
kubectl get nodes -w

kubectl create deployment autoscaler-demo --image=nginx
kubectl scale deployment autoscaler-demo --replicas=100

10. CI/CD 파이프라인 구성

  • github action, ecr, kustomize, argocd를 이용하여 배포 파이프라인을 구성해본다.

github repo생성

  • front-app-repo: Frontend 소스가 위치한 레파지토리

  • k8s-manifest-repo: K8S 관련 매니페스트가 위치한 레파지토리

  • frontend 폴더에 있는 데이터를 front-app-repo로 push

  • push 결과

파이프라인을 위한 iam 생성

  • cli로 iam user 생성
aws iam create-user --user-name github-action

  • ecr policy 생성
    • ecr policy json
      cd ~/environment
      cat <<EOF> ecr-policy.json
      {
          "Version": "2012-10-17",
          "Statement": [
              {
                  "Sid": "AllowPush",
                  "Effect": "Allow",
                  "Action": [
                      "ecr:GetDownloadUrlForLayer",
                      "ecr:BatchGetImage",
                      "ecr:BatchCheckLayerAvailability",
                      "ecr:PutImage",
                      "ecr:InitiateLayerUpload",
                      "ecr:UploadLayerPart",
                      "ecr:CompleteLayerUpload"
                  ],
                  "Resource": "arn:aws:ecr:${AWS_REGION}:${ACCOUNT_ID}:repository/demo-frontend"
              },
              {
                  "Sid": "GetAuthorizationToken",
                  "Effect": "Allow",
                  "Action": [
                      "ecr:GetAuthorizationToken"
                  ],
                  "Resource": "*"
              }
          ]
      }
      EOF
  • iam policy 생성
    aws iam create-policy --policy-name ecr-policy --policy-document file://ecr-policy.json
  • 생성한 policy를 user에 attach
    ```bash
    aws iam attach-user-policy --user-name github-action --policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/ecr-policy
    ```

github secrets(AWS Credential, github token) 생성

AWS Credential 생성

  • github action이 빌드된 front-app 을 docker image 로 만들어 ECR로 push 한다. 이 과정에서 AWS credential 을 사용 합니다.
  • 이를 위해 앞서 github-action이라는 별도의 least privilege 를 갖는 IAM User를 생성했다.
  • 이제 이 User의 Access Key, Secret Key를 생성 합다.
  • 키생성 명령 cli
aws iam create-access-key --user-name github-action
  • 생성 확인

github personal token 생성

  • github.com 로그인 후 User profile > Settings > Developer settings > Personal access tokens > 우측 상단에 위치한 Generate new token을 선택.
  • Note 에 access token for github action 라 입력 하고 Select scopes 에서 repo 를 선택
  • 화면 아래에서 Generate token 을 클릭.

github secret 설정

  • front-app-repo 레파지토리로 돌아가 Settings > Secrets > 화면 우측 상단의 New repository secret 클릭.
  • ACTION_TOKEN에 앞서 복사한 personal access token 값을 저장.
  • AccessKeyId 와 SecretAccessKey의 값을 Secret 에 저장.
    - AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY 로 지정

github action

  • build.yaml

name: Build Front

on:
  push:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout source code
        uses: actions/checkout@v2

      - name: Check Node v
        run: node -v

      - name: Build front
        run: |
          npm install
          npm run build

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: \${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: \${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: $AWS_REGION

      - name: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v1

      - name: Get image tag(verion)
        id: image
        run: |
          VERSION=\$(echo \${{ github.sha }} | cut -c1-8)
          echo VERSION=\$VERSION
          echo "::set-output name=version::\$VERSION"

      - name: Build, tag, and push image to Amazon ECR
        id: image-info
        env:
          ECR_REGISTRY: \${{ steps.login-ecr.outputs.registry }}
          ECR_REPOSITORY: demo-frontend
          IMAGE_TAG: \${{ steps.image.outputs.version }}
        run: |
          echo "::set-output name=ecr_repository::\$ECR_REPOSITORY"
          echo "::set-output name=image_tag::\$IMAGE_TAG"
          docker build -t \$ECR_REGISTRY/\$ECR_REPOSITORY:\$IMAGE_TAG .
          docker push \$ECR_REGISTRY/\$ECR_REPOSITORY:\$IMAGE_TAG

EOF
  • github action 코드 수정 필요(삽질)
    • code
      - name: nvm yarn install
              run: |
                curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.1/install.sh | bash
                export NVM_DIR="$HOME/.nvm"
                [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
                [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
                nvm install 16
                nvm use v16
                npm install
                npm run build
    • node18에서 에러, 16으로 다운필요
    • nvm 설치, v16설치
    • run에서 build 명령어를 파이프로 주지않고 별도로 name 하위에 구성하면 v18이 동작하게됨
  • action 결과 확인
  • ecr에 이미지 업로드 확인

Kustomize

Overview

  • Kustomize 는 쿠버네티스 manifest 를 사용자 입맛에 맞도록 정의 하는데 도움을 주는 도구 .
    • 여기서 "사용자 입맛에 맞도록 정의"에 포함 되는 경우는, 모든 리소스에 동일한 네임스페이스를 정의 하거나, 동일한 네임 접두사/접미사를 준다거나, 동일한 label 을 주거나, 이미지 태그 값을 변경 하는 것들
  • 본 실습 에서는 Kustomize 를 활용해 kuberenetes Deployment 리소스에 동일한 label, metadata 값 을 주며, front app의 새로운 변경 사항 발생에 따른 새로운 Image Tag를 Deployment 리소스에 적용.

Kustomize 사용을 위한 디렉토리 구조화

디렉토리 생성

  • Kubernetes manifest 들은 이제 별도의 독립된 github repository를 갖는다.
  • 그리고 Kustomize를 통해 manifest 들을 구성. 이를 위해 디렉토리 구조를 생성한다.
cd ~/environment
mkdir -p ./k8s-manifest-repo/base
mkdir -p ./k8s-manifest-repo/overlays/dev
cd ~/environment/manifests
cp *.yaml ../k8s-manifest-repo/base
cd ../k8s-manifest-repo/base
ls -rlt
  • 결과적으로 만들어지는 디렉토리 구조는 다음과 같습니다.

    • k8s-manifest-repo 디렉토리 아래 >> baseoverlays/dev 구조가 생깁니다.
  • base : kubernetes manifest 원본이 위치한 디렉토리.

    • 이 안에 위치한 manifest 들은 overlays 아래에 위치한 kustomize.yaml 파일에 담긴 사용자 지정 설정 내용에 따라 변경됨.
  • overlays : 사용자 입맛에 맞는 설정 값이 위치한 디렉토리.

    • 이 설정은 kustomize.yaml 에 담습니다. 이 하위에 있는 dev 디렉토리는 실습을 위해 만든 것으로, 개발 환경에 적용할 설정 파일을 모아 두기 위함.
  • base폴더에 manifest 확인

Kustomize manifest 생성

  • 이번 실습은 frontend app에 대한 배포 체계를 만드는데 목표로 한다. 따라서 frontend-deployment.yaml 과 frontend-service.yaml 파일을 kustomize 를 통해 배포 시점에 의도한 값(e.g. Image Tag)을 반영. 아래는 반영될 값 입니다.
    - metadata.labels: "env: dev"을 frontend-deployment.yaml, frontend-service.yaml 에 일괄 반영 함.
    - spec.selector : "select.app: frontend-fargate" 를 frontend-deployment.yaml, frontend-service.yaml 에 일괄 반영 함.
    - spec.template.spec.containers.image : "image: " 값을 새롭게 변경된 Image Tag 정보로 업데이트 함.
  • kustomization.yaml
    • kustomize을 통해 관리/변경 할 kubernetes manifest 대상을 정의 하는 목적.
cd ~/environment/k8s-manifest-repo/base
cat <<EOF> kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - frontend-deployment.yaml
  - frontend-service.yaml
EOF
  • 먼저 fronted-deployment.yaml 을 위한 설정 값을 정의.
cd ~/environment/k8s-manifest-repo/overlays/dev
cat <<EOF> front-deployment-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-frontend
  namespace: default
  labels:
    env: dev
spec:
  selector:
    matchLabels:
      app: frontend-fargate
  template:
    metadata:
      labels:
        app: frontend-fargate
EOF
  • frontend-service.yaml 을 위한 설정 값을 정의.
cd ~/environment/k8s-manifest-repo/overlays/dev
cat <<EOF> front-service-patch.yaml
apiVersion: v1
kind: Service
metadata:
  name: demo-frontend
  annotations:
    alb.ingress.kubernetes.io/healthcheck-path: "/"
  labels:
    env: dev
spec:
  selector:
    app: frontend-fargate
EOF
  • 마지막으로 위에서 설정 한 파일들(값)을 사용하고 frontend app 빌드에 따라 만들어진 새로운 Image Tag 를 정의.
    • name 에 지정된 image는 newName의 image와 newTag의 값으로 사용
  • 이를 활용해 newTag 값을 변경해 새로운 배포가 이루어질 때 마다 이를 kubernetes 클러스터에 반영.
cd ~/environment/k8s-manifest-repo/overlays/dev
cat <<EOF> kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
images:
- name: ${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/demo-frontend
  newName: ${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/demo-frontend
  newTag: abcdefg
resources:
- ../../base
patchesStrategicMerge:
- front-deployment-patch.yaml
- front-service-patch.yaml
EOF
  • 이것으로 -patch.yaml 파일에 정의한 내용들은 배포 과정에서 kustomize 에 의해 자동으로 kubernetes manifest 에 반영 됩니다.

  • 이제 앞서 생성한 kubernetes manifests를 새로 생성한 k8s-manifest-repo 에 push 합니다.

cd ~/environment/k8s-manifest-repo/
git init
git add .
git commit -m "first commit"
git branch -M main
git remote add origin https://github.com/$GITHUB_USERNAME/k8s-manifest-repo.git
git push -u origin main

ArgoCD

  • ArgoCD를 eks cluster 에 설치 합니다.
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
  • argocd cli 설치(이후 실습에 사용함)
cd ~/environment
VERSION=$(curl --silent "https://api.github.com/repos/argoproj/argo-cd/releases/latest" | grep '"tag_name"' | sed -E 's/.*"([^"]+)".*/\1/')

sudo curl --silent --location -o /usr/local/bin/argocd https://github.com/argoproj/argo-cd/releases/download/$VERSION/argocd-linux-amd64

sudo chmod +x /usr/local/bin/argocd
  • ArgoCD 서버는 기본적으로 퍼블릭 하게 노출되지 않습니다. 실습의 목적상 이를 변경하여 ELB 를 통해 접속 가능하도록 하겠습니다.
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'
  • elb 주소 확인하기
export ARGOCD_SERVER=`kubectl get svc argocd-server -n argocd -o json | jq --raw-output .status.loadBalancer.ingress[0].hostname`
echo $ARGOCD_SERVER

  • argoCD의 패스워드 찾기
    • id는 admin
ARGO_PWD=`kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d`
echo $ARGO_PWD

  • 로그인 이후 화면
  • argocd에서 사용할 앱 설정
  • 앞서 설정한 kustomize 부분 입력
  • 배포될 곳 설정
  • 앱 생성 화면
  • kustomize 빌드단계 추가
    • build.yml 수정
cd ~/environment/amazon-eks-frontend/.github/workflows
cat <<EOF>> build.yaml

      - name: Setup Kustomize
        uses: imranismail/setup-kustomize@v1

      - name: Checkout kustomize repository
        uses: actions/checkout@v2
        with:
          repository: $GITHUB_USERNAME/k8s-manifest-repo
          ref: main
          token: \${{ secrets.ACTION_TOKEN }}
          path: k8s-manifest-repo

      - name: Update Kubernetes resources
        run: |
          echo \${{ steps.login-ecr.outputs.registry }}
          echo \${{ steps.image-info.outputs.ecr_repository }}
          echo \${{ steps.image-info.outputs.image_tag }}
          cd k8s-manifest-repo/overlays/dev/
          kustomize edit set image \${{ steps.login-ecr.outputs.registry}}/\${{ steps.image-info.outputs.ecr_repository }}=\${{ steps.login-ecr.outputs.registry}}/\${{ steps.image-info.outputs.ecr_repository }}:\${{ steps.image-info.outputs.image_tag }}
          cat kustomization.yaml

      - name: Commit files
        run: |
          cd k8s-manifest-repo
          git config --global user.email "github-actions@github.com"
          git config --global user.name "github-actions"
          git commit -am "Update image tag"
          git push -u origin main

EOF
  • front-app-repo의 action 트리거로 인해 k8s repo의 kustomization이 커밋된것을 확인.
    - 이미지 태그값이 수정됨
  • argocd 이미지 버전 확인

check argoCD

  • 배포 상태를 확인.
    • Applications > eksworkshop-cd-pipeline으로 이동 하여 확인 해보면 CURRENT SYNC STATUS의 값이 Out of Synced다.
  • git repository 가 변경되면 자동으로 sync 작업이 수행 하도록 하려면 Auto-Sync 를 활성화
    - APP DETAILS 로 이동 하여 ENABLE AUTO-SYNC 버튼을 눌러 활성화 한다.
  • auto sync가 되는지 테스트 해보자.
    • fronted app.js의 67번째 라인 수정 후 commit, push로 배포 테스트
return (
    <div className={classes.root}>
      <AppBar position="static" style={{ background: '#2E3B55' }}>
        <Toolbar>
          <IconButton edge="start" className={classes.menuButton} color="inherit" aria-label="menu">
            <CloudIcon />
          </IconButton>
          <Typography
            variant="h6"
            align="center"
            className={classes.title}
          >
            **EKS DEMO Blog version 1**
          </Typography>
          {new Date().toLocaleTimeString()}
        </Toolbar>
      </AppBar>
      <br/>
  • repo에 push된 commit값과 argocd에서 auto sync 확인
  • 홈페이지 반영 확인

11. CI/CD 파이프라인에 security 추가

  • k8s manifest 를 배포 하기 전에 Checkov 와 Trivy를 이용하여 k8s manifest 및 container image 가 security, misconfiguration 문제가 없는지 검사하는 단계를 ci/cd 파이프라인에 추가 한다.

  • 그리고, 기존에 사용하던 ArgoCD admin과 분리된 CI/CD 전용의 별도 ArgoCD 계정을 생성

    • ArgoCD RBAC 에 따라 설정 되어 ArgoCD 의 보안을 향상시킴.
  • 이를 위해 변경 사항이 발생하면 곧바로 CD 작업이 시작 되던 기존 방식을 다음과 같이 변경 함.

    1. application repo 변경 작업이 발생 되고 새로운 image tag 값과 함께 docker image 가 생성 된다
    2. 새로운 docker image 에 보안 취약점이 없는지 Trivy 를 이용해 점검 한다
    3. k8s manifest repo에 새로운 image tag 값이 commit 되면 kustomize 를 이용해 최종 k8s manifest를 생성 한다(kustomize build)
    4. 생성된 최종 k8s manifests에 대해 Checkov 를 통해 정적 코드 분석 작업을 수행 한다
    5. 분석 작업 결과에 문제가 없으면 ArgoCD application 의 Sync 작업을 시작 한다
  • 각 단계가 수행 되는 repository는 다음과 같다.

    • 1~2 : Application repository 의 github Action
    • 3~5 : k8s manifest repository 의 github Action

frontend build yml에 trivy 추가

  • build.yml
          - name: Build, tag, and push image to Amazon ECR
            id: image-info
            env:
              ECR_REGISTRY: \${{ steps.login-ecr.outputs.registry }}
              ECR_REPOSITORY: demo-frontend
              IMAGE_TAG: \${{ steps.image.outputs.version }}
            run: |
              echo "::set-output name=ecr_repository::\$ECR_REPOSITORY"
              echo "::set-output name=image_tag::\$IMAGE_TAG"
              docker build -t \$ECR_REGISTRY/\$ECR_REPOSITORY:\$IMAGE_TAG .
    
          **- name: Run Trivy vulnerability scanner
            uses: aquasecurity/trivy-action@master
            with:
              image-ref: '\${{ steps.login-ecr.outputs.registry}}/\${{ steps.image-info.outputs.ecr_repository }}:\${{ steps.image-info.outputs.image_tag }}'
              format: 'table'
              exit-code: '0'
              ignore-unfixed: true
              vuln-type: 'os,library'
              severity: 'CRITICAL,HIGH'**
  • high가 발견됐지만 action은 그대로 진행.
    - exit-code: '0' 이기 때문, 1로 변경하면 멈춤.

k8s repo 수정

  • 생성된 kustomize yml에 대한 정적분석을 위해 action 추가
    • build.yml
      cat <<EOF> build.yaml
      name: "ArgoCD sync"
      on: "push"
      
      jobs:
        build:
          runs-on: ubuntu-latest
          steps:
      
            - name: Checkout source code
              uses: actions/checkout@v2
      
            - name: Setup Kustomize
              uses: imranismail/setup-kustomize@v1
      
            - name: Build Kustomize
              run: |
                pwd
                mkdir kustomize-build
                kustomize build ./overlays/dev > ./kustomize-build/kustomize-build-output.yaml
                ls -rlt
                cd kustomize-build
                cat kustomize-build-output.yaml
      
            - name: Run Checkov action
              id: checkov
              uses: bridgecrewio/checkov-action@master
              with:
                directory: kustomize-build/
                framework: kubernetes
      
            - name: Install ArgoCD and execute Sync in ArgoCD
              run: |
                curl -sSL -o /usr/local/bin/argocd https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64
                chmod +x /usr/local/bin/argocd
                ARGO_SERVER=$ARGOCD_SERVER
                argocd app sync eksworkshop-cd-pipeline --auth-token \${{ secrets.ARGOCD_TOKEN }} --server $ARGOCD_SERVER --insecure
      
      EOF
  • argoCD auto sync비활성화

ArgoCD 신규 account 생성

  • k8s repo의 github action이 ArgoCD Sync 를 호출 하기 위해 사용할 새로운 ArgoCD account 를 생성한다.
    • 새로운 account 는 devops 입니다.
  • ArgoCD 의 account 추가는 ArgoCD의 Configmap을 통해서 가능합니다.
kubectl -n argocd edit configmap argocd-cm -o yaml

신규 account 에 대한 auth-token 생성

  • 새로운 ArgoCD account 인 devops 가 사용할 auth-token 을 생성 합니다.
    • 이는 argocd api를 이용해 작업을 호출할 때 사용하는 인증 토큰. 즉 login password 와 별개
  • 아래 명령을 실행 하고 출력 되는 토큰 값을 별도로 저장
argocd account generate-token --account devops

#failed connection 일때는 로그인부터.
argocd login $ARGOCD_SERVER
  • k8 repo에 sercret 변수로 위 토큰값을 추가해줌.

Argo RBAC 설정

  • 새로 생성한 ArgoCD account 는 Sync를 호출할 수 있는 permission 이 없다. 따라서 ArgoCD가 사용하는 RBAC 규칙에 맞게 새롭게 permission 을 할당해줘야함.
  • ArgoCD RBAC 을 추가하려면 ArgoCD Confimap 인 argocd-rbac-cm 을 수정해야함.
  • 다음 명령을 실행 하여 수정.
kubectl -n argocd edit configmap argocd-rbac-cm -o yaml

  • 수정한 결과 push해서 action 결과 확인
    - checkov에서 오류 발견
  • ckv_k8s_17에 대해만 분석하도록 수정해본다.
      - name: Run Checkov action
        id: checkov
        uses: bridgecrewio/checkov-action@master
        with:
          directory: kustomize-build/
          framework: kubernetes
          **check: CKV_K8S_17**

파이프라인 동작 확인

  • 실제로 frontend application 코드를 변경하여 앞서 만든 pipeline 전체 과정이 정상적으로 구동되는지 확인 해본다.

frontend application 소스 코드 변경

  • Cloud9 으로 이동해, 좌측 폴더 구조에서 amazon-eks-frontend/src/ 로 이동하여 App.js 더블 클릭하여 파일을 오픈.
  • line 67의 값을 EKS DEMO Blog version 2 으로 변경 하고 저장.
  • front repo > k8s repo
  • k8s repo action에서 sync 부분 진행 확인
profile
어제보다 나은 엔지니어가 되기 위해서 공부중

0개의 댓글