1편은 여기로
이어서 진행 합니다
cd /home/ec2-user/environment/manifests
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
#기존 프론트 디플로이 제거
kubectl apply -f frontend-deployment.yaml
kubectl apply -f frontend-service.yaml
fargate worket nodes 리스트 확인
CloudWatch Container Insight는 컨테이너형 애플리케이션 및 마이크로 서비스에 대한 모니터링, 트러블 슈팅 및 알람을 위한 완전 관리형 관측 서비스.
CloudWatch Container Insight는 CPU, 메모리, 디스크 및 네트워크와 같은 인프라 메트릭을 자동으로 수집.
Fluent Bit를 사용하여 로그를 라우팅하는 작업을 수행.
클러스터의 메트릭 값을 수집하기 위해 CloudWatch Agent 설치하고, CloudWatch Logs에 로그를 보내기 위해 Fluent Bit을 DaemonSet 형태로 설치.
cd ~/environment
mkdir -p manifests/cloudwatch-insight && cd manifests/cloudwatch-insight
kubectl create ns amazon-cloudwatch
ClusterName=eks-demo
RegionName=$AWS_REGION
FluentBitHttpPort='2020'
FluentBitReadFromHead='Off'
[[ ${FluentBitReadFromHead} = 'On' ]] && FluentBitReadFromTail='Off'|| FluentBitReadFromTail='On'
[[ -z ${FluentBitHttpPort} ]] && FluentBitHttpServer='Off' || FluentBitHttpServer='On'
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
쿠버네티스에는 크게 두 가지의 오토 스케일링 기능이 있다.
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
kubectl get deployment metrics-server -n kube-system
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
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
```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
wget https://raw.githubusercontent.com/kubernetes/autoscaler/master/cluster-autoscaler/cloudprovider/aws/examples/cluster-autoscaler-autodiscover.yaml
kubectl apply -f cluster-autoscaler-autodiscover.yaml
kubectl get nodes -w
kubectl create deployment autoscaler-demo --image=nginx
kubectl scale deployment autoscaler-demo --replicas=100
front-app-repo: Frontend 소스가 위치한 레파지토리
k8s-manifest-repo: K8S 관련 매니페스트가 위치한 레파지토리
frontend 폴더에 있는 데이터를 front-app-repo로 push
aws iam create-user --user-name github-action
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
aws iam create-policy --policy-name ecr-policy --policy-document file://ecr-policy.json
```bash
aws iam attach-user-policy --user-name github-action --policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/ecr-policy
```
github-action
이라는 별도의 least privilege 를 갖는 IAM User를 생성했다.aws iam create-access-key --user-name github-action
access token for github action
라 입력 하고 Select scopes 에서 repo 를 선택ACTION_TOKEN
에 앞서 복사한 personal access token 값을 저장.AccessKeyId
와 SecretAccessKey
의 값을 Secret 에 저장.AWS_ACCESS_KEY_ID
, AWS_SECRET_ACCESS_KEY
로 지정
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
- 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
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
디렉토리 아래 >> base
, overlays/dev
구조가 생깁니다.base
: kubernetes manifest 원본이 위치한 디렉토리.
overlays
아래에 위치한 kustomize.yaml 파일에 담긴 사용자 지정 설정 내용에 따라 변경됨.overlays
: 사용자 입맛에 맞는 설정 값이 위치한 디렉토리.
dev
디렉토리는 실습을 위해 만든 것으로, 개발 환경에 적용할 설정 파일을 모아 두기 위함.base폴더에 manifest 확인
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 정보로 업데이트 함.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
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
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
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
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
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
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'
export ARGOCD_SERVER=`kubectl get svc argocd-server -n argocd -o json | jq --raw-output .status.loadBalancer.ingress[0].hostname`
echo $ARGOCD_SERVER
ARGO_PWD=`kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d`
echo $ARGO_PWD
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
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/>
k8s manifest 를 배포 하기 전에 Checkov 와 Trivy를 이용하여 k8s manifest 및 container image 가 security, misconfiguration 문제가 없는지 검사하는 단계를 ci/cd 파이프라인에 추가 한다.
그리고, 기존에 사용하던 ArgoCD admin과 분리된 CI/CD 전용의 별도 ArgoCD 계정을 생성
이를 위해 변경 사항이 발생하면 곧바로 CD 작업이 시작 되던 기존 방식을 다음과 같이 변경 함.
각 단계가 수행 되는 repository는 다음과 같다.
- 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'**
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
devops
입니다.kubectl -n argocd edit configmap argocd-cm -o yaml
devops
가 사용할 auth-token 을 생성 합니다.argocd account generate-token --account devops
#failed connection 일때는 로그인부터.
argocd login $ARGOCD_SERVER
argocd-rbac-cm
을 수정해야함.kubectl -n argocd edit configmap argocd-rbac-cm -o yaml
- name: Run Checkov action
id: checkov
uses: bridgecrewio/checkov-action@master
with:
directory: kustomize-build/
framework: kubernetes
**check: CKV_K8S_17**
App.js
더블 클릭하여 파일을 오픈.EKS DEMO Blog version 2
으로 변경 하고 저장.