실습 4탄 = 2/17
웹 프론트 : html 을 s3 에 저장, Cloudfront로 서비스
백엔드 : ELB통해 서비스, EKS 워커노드에 배포, RDS 접속 , ECR 를 통해 이미지 저장
배치 : EKS , S3 저장된 파일 처리, RDS 에 쓰기 실행
앞에서 Cloudformation을 이용해 Private Subnet 3개 + RDS 를 구축했다.
https://brunch.co.kr/@topasvga/1814
1
vpc1개
Public Subnet 3개
Private Subnet 3개 - Private Subnet에 rds 1개를 구축한다.
시크릿 매니저를 사용한다.
2
eks-work-host ec2에 로그인해서 db관련 내용을 확인한다.
// Secrets Manager에서 admin 암호 확인
수명 주기 동안 보안 암호를 손쉽게 교체, 관리 및 검색
3
DB 관리자 암호 확인 ?
aws secretsmanager list-secrets
AWS콘솔 > AWS Secret Manager의 보안 암호 이름 : RdsMasterSecret , RdsUserSecret 로 검색
보안 암호키 : password로 검색
AdminDbPw=`aws secretsmanager get-secret-value --secret-id RdsMasterSecret | jq --raw-output .SecretString | jq -r ."password"`
echo $AdminDbPw
+glH>th4Ds_T?Dp2
4
AWS콘솔 > AWS Secret Manager의 보안 암호 이름 : RdsMasterSecret , RdsUserSecret 로 검색
보안 암호키 : password로 검색
사용자 암호 확인 ?
AppDbPw=`aws secretsmanager get-secret-value --secret-id RdsUserSecret | jq --raw-output .SecretString | jq -r ."password"`
echo $AppDbPw
C:Nbiz)P0eIck~Ql
5
rds 엔드포인트를 변수로 지정 - 스택 이름이 맞아야 한다. eks-work-rds
RDSEP=`aws cloudformation describe-stacks --stack-name eks-work-rds --query 'Stacks[*].Outputs[0].OutputValue' --output text`
echo $RDSEP
eks-work-db.cn5kwtftpfwb.ap-northeast-2.rds.amazonaws.com
// stack name을 rds1 으로 만든경우
RDSEP=`aws cloudformation describe-stacks --stack-name rds1 --query 'Stacks[*].Outputs[0].OutputValue' --output text`
echo $RDSEP
6
postgresql 클라이언트로 mywork 라는 사용자 생성 ?
createuser -d -U eksdbadmin -P -h $RDSEP mywork
Enter password for new role: ( app 암호 )
Enter it again : ( app 암호 )
Password : (admin 암호)
참고 userdata 파일
7
애플리케이션 db 생성
PGPASSWORD=$AppDbPw createdb -U mywork -h $RDSEP -E UTF8 myworkdb
8
접속 확인
PGPASSWORD=$AppDbPw psql -U mywork -h $RDSEP myworkdb
[root@eksctl-host ~]# PGPASSWORD=$AppDbPw psql -U mywork -h $RDSEP myworkdb
psql (11.12)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.
myworkdb=>
나오기
myworkdb=> \q
9
EC2 로그인 / 소스 다운로드
git clone https://github.com/dybooksIT/k8s-aws-book.git
10
예제 실행
테이블 생성
데이터 입력
확인
#
PGPASSWORD=$AppDbPw psql -U mywork -h $RDSEP myworkdb -c '\i k8s-aws-book/backend-app/scripts/10_ddl.sql'
PGPASSWORD=$AppDbPw psql -U mywork -h $RDSEP myworkdb -c '\i k8s-aws-book/backend-app/scripts/20_insert_sample_data.sql'
확인 ?
PGPASSWORD=$AppDbPw psql -U mywork -h $RDSEP myworkdb -c 'SELECT * FROM region;' -c 'SELECT * FROM location;'
1
백엔드 구성 ?
L4 CLB 사용
컨테이너
DB를 불러옴
2
소스 빌드
EC2 로그인 / 소스 다운로드
git clone https://github.com/dybooksIT/k8s-aws-book.git
3
순서?
EC2에서 소스 빌드한다.
ECR생성
ECR에 Push 한다.
워커 노드의 컨테이너에 배포한다.(디플로이먼트 생성)
서비스 LB 생성해 서비스 한다.
DB는 PostgreSQL 사용
<3> EC2에서 소스 빌드한다.
EC2에서 소스 빌드한다.
// 아래 하나는 설치해줘야 한다.
yum install java-11-amazon-corretto -y
cd $HOME/k8s-aws-book/backend-app/
./gradlew clean build
(10분 걸림)
gradle wrapper 줄여서 gradlew 는
새로운 환경에서 프로젝트를 설정할 때 java나 gradle을 설치하지 않고 바로 빌드할 수 있게 해주는 역할을 한다.
4
컨테이너 이미지 생성 (참고)
Corretto는 Amazon의 장기적인 지원을 받는 OpenJDK(Open Java Development Kit) 바이너리 배포판
https://hub.docker.com/_/amazoncorretto
5
이미지 생성을 위해 도커 허브 ID가 있어야 한다.
도커 허브 id
MyID=masterseo11
echo $MyID
6
도커 이미지 로컬 생성
// 도커가 설치되어 있어야 한다.
docker build -t $MyID/backend-app:1.0.0 --build-arg JAR_FILE=build/libs/backend-app-1.0.0.jar .
7
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
masterseo11/backend-app 1.0.0 8aafddccff56 About a minute ago 749MB
amazoncorretto 11 2b27f3c83c92 2 weeks ago 445MB
8
docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: masterseo11
Password: g102!
9
docker push $MyID/backend-app:1.0.0
10
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
masterseo11/backend-app 1.0.0 8aafddccff56 13 minutes ago 749MB
amazoncorretto 11 2b27f3c83c92 2 weeks ago 445MB
9
amazoncorretto:11 에 들어가 확인 (선택)
docker run -it amazoncorretto:11 /bin/bash
java -version
javac -version
exit
1
account id 확인
ACCOUNT_ID=`aws sts get-caller-identity --query 'Account' --output text`
echo $ACCOUNT_ID
2
로그인 인증
aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin $ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
[root@eksctl-host ~]# cat /root/.docker/config.json
{
"auths": {
"451032684083.dkr.ecr.ap-northeast-2.amazonaws.com": {
3
레파지토리 생성
k8sbook/backend-app 이름으로 만듬
aws ecr create-repository --repository-name k8sbook/backend-app --image-scanning-configuration scanOnPush=true --region $AWS_REGION
4
ecr 확인
aws ecr describe-repositories
1
ECR에 Push 하기위해 컨테이너 이미지에 태그 설정
직접 빌드의 경우
docker tag $MyID/backend-app:1.0.0 $ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/k8sbook/backend-app:1.0.0
2
태그 확인
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
.ecr.ap-northeast-2.amazonaws.com/k8sbook/backend-app 1.0.0 8aafddccff56 17 749MB
masterseo11/backend-app 1.0.0 8aafddccff56 17 minutes ago 749MB
amazoncorretto 11 2b27f3c83c92 2 weeks ago 445MB
3
컨테이너 이미지 push 하기
ecr로 push
docker push $ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/k8sbook/backend-app:1.0.0
4
확인
aws ecr list-images --repository-name k8sbook/backend-app --output text
IMAGEIDS sha256:11c2e580127314f8
aws ecr describe-images --repository-name k8sbook/backend-app
5
AWS 콘솔에서 ECR 가서 확인
k8sbook/backend-app
1
순서?
네임스페이스 생성과 변경
kubeconfig 네임스페이스 반영
db 시크릿 등록
애플리케이션 배포
애플리케이션 외부 공개
2
터미널 2에서 모니터링
watch -d 'kubectl get deploy,pods,svc,ep -o wide'
3
kubeconfig 설정?
eksctl은 클러스터 구축중에 kubeconfig 파일을 자동 업데이트 한다.
eksctl이 이용할 설정파일
접속 정보를 저장 한다. 컨트롤 플레인 URL , 인증정보 , 네임스페이스등
4
네임스페이스 확인, 생성, 변경
5
네임스페이스 확인
kubens
default
kube-node-lease
kube-public
kube-system
6
생성
kubectl create namespace eks-work
kubens
7
변경
kubens eks-work
[root@eksctl-host backend-app]# kubens eks-work
Context "i-05cb09ed85ec0b51c@first-eks.ap-northeast-2.eksctl.io" modified.
Active namespace is "eks-work".
kubens
default
eks-work
kube-node-lease
kube-public
kube-system
[root@eksctl-host backend-app]#
1
RDSEP=`aws cloudformation describe-stacks --stack-name eks-work-rds --query 'Stacks[*].Outputs[0].OutputValue' --output text` AppDbPw=`aws secretsmanager get-secret-value --secret-id RdsUserSecret | jq --raw-output .SecretString | jq -r ."password"`
echo $RDSEP
echo $AppDbPw
eks-work-db.cu95crn7o6gd.ap-northeast-2.rds.amazonaws.com
~Raj(;7NRh8e.=sW
2
DB 접속용 시크릿 등록
envsubst 명령어는?
yaml 파일에서 환경 변수 대체해주는 역할을 한다.
21_db_config_k8s.yaml 파일
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: db-config
stringData:
db-url: ${DB_URL}
db-username: mywork
db-password: ${DB_PASSWORD}
cd $HOME
DB_URL=jdbc:postgresql://$RDSEP/myworkdb DB_PASSWORD=$AppDbPw envsubst < $HOME/k8s-aws-book/eks-env/21_db_config_k8s.yaml.template | kubectl apply -f -
secret/db-config created
3
kubectl get secret db-config
NAME TYPE DATA AGE
db-config Opaque 3 13s
kubectl get secret db-config -o yaml
apiVersion: v1
data:
db-password: QzpO
4
변수 확인
ACCOUNT_ID=`aws sts get-caller-identity --query 'Account' --output text`
echo $ACCOUNT_ID
5
배포
cd $HOME
ECR_HOST=$ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com envsubst < $HOME/k8s-aws-book/eks-env/22_deployment_backend-app_k8s.yaml.template | kubectl apply -f -
deployment.apps/backend-app created
6
kubectl get all
pod 2개가 보임
0/1 -> 1/1 변경됨.
kubectl get pod -o wide
watch -d kubectl get pod -o wide
7
디플로이먼트라 스케일 조정해 확인 가능하다.
kubectl scale deployment backend-app --replicas=5
kubectl scale deployment backend-app --replicas=24
kubectl scale deployment backend-app --replicas=0
1
서비스 생성하자.
ELB 포트 8080
노드 포트 32760
파드포트 8080
CLB 8080으로 접속하면 내부 Pod 에 접속하는 과정이다.
2
서비스 생성
cat <<EOF | kubectl create -f -
apiVersion: v1
kind: Service
metadata:
name: backend-app-service
spec:
type: LoadBalancer
selector:
app: backend-app
ports:
- protocol: TCP
port: 8080
targetPort: 8080
EOF
첨부
3
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
backend-app-service LoadBalancer 10.100.11.107 a834b556bb8b449c0a0d1fa0e8cf8952-863335935.ap-northeast-2.elb.amazonaws.com 8080:32758/TCP 26s
ab300c3df4812423584faf50caa6a5d7-693573332.ap-northeast-2.elb.amazonaws.com
4
LB 도메인 접속 주소 확인 ?
APIEXIP=`kubectl get svc backend-app-service -o jsonpath='{.status.loadBalancer.ingress[*].hostname}'`
echo $APIEXIP
5
AWS 웹 콘솔 > ELB 가면 LB가 만들어져 있다.
curl -s http://$APIEXIP:8080/health
{"status":"OK"}
웹브라우저로 접속
xxxxxxxxxxxxxxxxxxxxx.ap-northeast-1.elb.amazonaws.com:8080/health
6
while true; do curl -s http://$APIEXIP:8080/health; echo; date "+%Y-%m-%d %H:%M:%S"; sleep 1; done
{"status":"OK"}
2021-08-23 18:06:38
{"status":"OK"}
2021-08-23 18:06:39
7
pod log 확인
kubectl logs -l app=backend-app -f --max-log-requests 8
2021-08-23 18:04:39.029 [http-nio-8080-exec-7] INFO k.s.presentation.api.HealthApi - Health GET API called.
2021-08-23 18:05:09.029 [http-nio-8080-exec-10] INFO k.s.presentation.api.HealthApi - Health GET API called.
8
콘솔에서 LB 확인
9
서비스 확인
kubectl get svc backend-app-service -o jsonpath='{.status}'
{"loadBalancer":{"ingress":[{"hostname":"ab300c3df4812423584faf50caa6a5d7-693573332.ap-northeast-2.elb.amazonaws.com"}]}}[
10
APIEXIP=`kubectl get svc backend-app-service -o jsonpath='{.status.loadBalancer.ingress[*].hostname}'`
echo $APIEXIP
1
순서?
EC2에서 소스 빌드
S3버킷 생성
S3에 소스 업로드
CloudFront를 통해 확인
2
yum install -y gcc-c++ make
curl -sL https://rpm.nodesource.com/setup_14.x | sudo -E bash -
yum install -y nodejs
라이블러리 다운로드
cd $HOME/k8s-aws-book/frontend-app/
npm install
업데이트
npm audit fix
3
빌드하기 위해 LB 다시 확인한다.
APIEXIP=`kubectl get svc backend-app-service -o jsonpath='{.status.loadBalancer.ingress[*].hostname}'`
echo $APIEXIP
4
빌드 실행
BASE_URL=http://$APIEXIP:8080 npm run build
N
순서?
프런트엔드는 S3로 만든다.
EC2와 Sync시켜 홈페이지를 유지한다.
S3를 오리진으로하는 CDN을 연결시켜 서비스한다.
1
// 버킷 이름은 유일해야 한다. s3 이름을 본인 이름으로 해라.
S3suffix=masterseo0923
echo $S3suffix
2
Cloudformation으로 S3버킷 , CloudFront 배포 (15분 소요) (서울 리전 사용시)
aws cloudformation deploy --template-file $HOME/k8s-aws-book/eks-env/30_s3_cloudfront_cfn.yaml --stack-name eks-work-frontend --parameter-overrides BucketSuffix=$S3suffix
// 만들다 실패한 경우는 콘솔에서 Cloudformation 스택을 삭제하고 다시 만들자.
기존 실패 스택이 있으면 아래 처럼 오류가 난다.
An error occurred (ValidationError) when calling the CreateChangeSet operation: Stack:arn:aws:cloudformation:ap-northeast-2:451032684083:stack/eks-work-frontend/24da1110-03f3-11ec-97bd-0a6a7510121c is in ROLLBACK_COMPLETE state and can not be updated.
echo $S3suffix
3
# CloudFormation 으로 S3 CloudFront 배포 (도쿄 리전 사용 시)
sed -i 's/ap-northeast-2/ap-northeast-1/g' $HOME/k8s-aws-book/eks-env/30_s3_cloudfront_cfn.yaml
aws cloudformation deploy --template-file $HOME/k8s-aws-book/eks-env/30_s3_cloudfront_cfn.yaml --stack-name eks-work-frontend --parameter-overrides BucketSuffix=$S3suffix
4
# CloudFormation 으로 S3 CloudFront 배포 (싱가포르 리전 사용 시)
sed -i 's/ap-northeast-2/ap-southeast-1/g' $HOME/k8s-aws-book/eks-env/30_s3_cloudfront_cfn.yaml
aws cloudformation deploy --template-file $HOME/k8s-aws-book/eks-env/30_s3_cloudfront_cfn.yaml --stack-name eks-work-frontend --parameter-overrides BucketSuffix=$S3suffix
5
S3 버킷 확인
aws s3 ls
2021-08-23 18:28:36 eks-work-frontend-masterseo08231
6
s3와 동기화
aws s3 sync $HOME/k8s-aws-book/frontend-app/dist s3://eks-work-frontend-$S3suffix --delete --include "*" --acl public-read
7
업로드 확인
aws s3 ls s3://eks-work-frontend-$S3suffix --recursive
2021-08-23 18:34:06 3017 200.html
8
서비스 동작 ?
사용자가 CloudFront 접속해 사용, S3가 원본
LB > 컨테이너 > PostgreSQL DB에서 정보 가져옴
9
cloudfront 확인
aws cloudformation describe-stacks --stack-name eks-work-frontend --query 'Stacks[*].Outputs[1].OutputValue' --output text
http://d3fop4nghz24dz.cloudfront.net
10
웹 브라우저로 접속
참고
https://brunch.co.kr/@topasvga/746
db , cloudfront , s3 삭제 한다.
cloud formation 스택 삭제 한다.
1
kubectl delete deploy,svc,cronjob --all
2
DB 삭제
aws cloudformation delete-stack --stack-name eks-work-rds
3
프론트 삭제
aws cloudformation delete-stack --stack-name eks-work-frontend
4
클러스터 삭제 (10분)
eksctl delete cluster --name $CLUSTER_NAME
5
s3 삭제
aws s3 rm s3://eks-work-frontend-$S3suffix --recursive
aws s3 rm s3://eks-work-batch-$S3suffix --recursive
6
배치 삭제
aws cloudformation delete-stack --stack-name eks-work-batch
7
ecr 삭제
aws ecr delete-repository --repository-name k8sbook/backend-app --force
aws ecr delete-repository --repository-name k8sbook/batch-app --force
8
콘솔에서 로드 밸런서 삭제
9
스택 삭제
1번째 생성한 EC2 와 Public Subnet
aws cloudformation delete-stack --stack-name eks-work-base
10
Cloudformation 콘솔에서 스택 삭제
삭제 불가 이유 확인
리소스 삭제후 스택 삭제
1
aws-node 파드에 매핑된 AWS IAM Role(AmazonEKS_CNI_Policy 정책)을 사용
role/eksctl-first-eks-addon-iamserviceaccount-kub-Role1-G
AmazonEKS_CNI_Policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:AssignPrivateIpAddresses",
"ec2:AttachNetworkInterface",
"ec2:CreateNetworkInterface",
"ec2:DeleteNetworkInterface",
"ec2:DescribeInstances",
"ec2:DescribeTags",
"ec2:DescribeNetworkInterfaces",
"ec2:DescribeInstanceTypes",
"ec2:DetachNetworkInterface",
"ec2:ModifyNetworkInterfaceAttribute",
"ec2:UnassignPrivateIpAddresses"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ec2:CreateTags"
],
"Resource": [
"arn:aws:ec2:*:*:network-interface/*"
]
}
]
https://brunch.co.kr/@topasvga/1819
감사합니다.