팀프로젝트
- 기가막힌 주제를 가지고, 기승전결을 가진 스토리, 프로젝트로 진행해야한다.
중간 SAA 퀴즈
문제
- AWS EC2 인스턴스 집합에서 애플리케이션을 실행한다. 이 프로그램은 Amazon SQS 대기열에서 데이터를 가져와 동시네 메시지를 처리한다. 메세지 볼륨은 가변적이며 트래픽이 자주 중단된다. 무중단 서비스를 제공해야한다.
- A : 스팟 인스턴스만 사용하여 필요한 최대 용량 처리
- B : 필요한 최대 용량을 처리하기 위해 독점적으로 예약 인스턴스를 사용한다.
- C : 기준 용량으로 예약 인스턴스를 사용하고 추가 용량을 처리하려면 스팟 인스턴스를 사용한다.
- D : 기준 용량으로 예약 인스턴스를 사용하고 추가용량을 처리하기 위해 온디맨드 인스턴스를 사용한다.
답
- 비용효율적인 면은 SPOT 인스턴스를 사용하겠지만, 문제에는 자주 중단되며, 중단없이 지속적으로 메세지를 처리해야 하기 때문에 온디맨스를 사용한다고 생각한다.
EKS 생성
인스턴스 생성
- 이름: docker
- Amazon Linux 2
- t2.micro
- Docker0key
- NEW-VPC, NEW-PUBLIC-SUBNET-2A
- 보안그룹: dockcer-SG
사용자 데이터
timedatectl set-timezone Asiz/Seoul
cd /tmp
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
./aws/install
amazon-linux-extras install docker -y
systemctl enable --now docker
curl https://raw.githubusercontent.com/docker/docker-ce/master/components/cli/contrib/completion/bash/docker -o /etc/bash_completion.d/docker.sh
usermod -a -G docker ec2-user
docker run -d -p 80:80 --name=test-site halilinux/web-site:v2.0
Route53에 등록
- docker.[도메인주소]로 등록해주었다.
- 도메인주소로 잘 들어가진다.
EKS 생성
ECR 생성
- docker 계정의 credential을 이용하여 aws configure로 로그인해준다.
- aws s3 ls 명령어로 확인한다.
- 에러가 출력되지 않으면 로그인에 성공한 것이다.
docker image tag
- 현재 사용자데이터로 가져온 halilinux 이미지가 하나존재한다.
- 이것을 web-site에 대한 이미지로 tag해서 push해본다.
- push할 때
denied: Not Authorized
에러가 출력되었다.
- 인증 토큰으로 docker 클라이언트를 인증하지 않았다.
Docker 클라이언트 인증
- 위 AWSCLI로 인증을 해준다.
- PUSH가 잘 됬다.
EKS 클러스터 생성
요금
- 마스터노드, Control Plane은 EKS요금이 나가고, WorkerNode는 EC2요금이 나오게 된다.
- Fargate는 serverless 데이터베이스이다.
클러스터 생성
클러스터 구성
- 이름 : MY-CLUSTER
- 버전 1.22
- 클러스터서비스 역할 : 이전에 생성한 eksClusterRole사용
네트워킹 지정
- NEW-VPC, 2A, 2C
- 보안그룸 : MY-SG-WEB
로깅 구성
노드그룹 생성
노드 그룹 구성
- 이름: NDOEGROUP
- 노드IAM역할 : nodeGroupRole
컴퓨팅 및 조정 구성 설정
- 용량 유형에서 Spot방식은 경매방식으로 저렴하게 컴퓨팅자원을 구할 수있다. 그러나 Spot방식은 언제 컴퓨팅자원을 뺏길지 모른다. 그래서 실무에서는 사용용도에 따라 On-Demand와 Spot을 고려해야한다.
- 실습에서는 FreeTier적용을 받는 On-Demand를 사용한다.
- DesireState는 5개로 해주고, 최대크기는 보통 2배, 즉 10개로 해준다.
네트워킹 지정
- 서브넷을 확인해부고, SSH로 접글할 때의 키페어와 허용대상을 설정한다.
검토 및 생성
- 검토 후 생성해준다.
- 노드 5개가 잘 생성되었다.
EKS 자격증명
kubeconfig생성
aws eks --region ap-northeast-2 update-kubeconfig --name [클러스터이름]
EKS 1.22 kubectl 설치
curl -o kubectl https://s3.us-west-2.amazonaws.com/amazon-eks/1.22.6/2022-03-09/bin/linux/amd64/kubectl
실행파일 bin폴더로 옮기기 및 completaion설정
chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc
설치 확인
kubectl version --short --client
kubectl get svc
- ?????
계속 깜빡하는 docker계정
doker계정으로 들어가서 클러스터를 생성한다.
- 현재 kubectl에 로그인하는 계정은 docker이다.
- 그런데 root계정으로 클러스터를 만들면 권한문제가 생긴다.
- docker계정으로 들어가면 노드그룹의 노드들을 볼 수 없다.
- 생성되지 않았거나 권한이 없다는 출력을 볼 수 있다.
- docker계정으로 생성하니 잘 나온다.
AWS 볼륨 생성
aws ec2 create-volume --availability-zone=ap-northeast-2a --size=1 --volume-type=gp2
- 가용영역에 size 1(gb)인 볼륨을 만들어준다. gp2를 사용한다.
- VolumeId를 따로 기록해 놓는다.
현재 노드 상황
- 현재 5개의 노드가 잘 생성되었다.
- 노드는 2a 에 2개, 2c에 3개가 running중이고,
- 0~16의 internalIP를 가진것이 a, 나머지가 c에 있을 것이다.
vi aws-vol.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-aws
labels:
type: local
spec:
capacity:
storage: 1Gi
persistentVolumeReclaimPolicy: Retain
accessModes:
- ReadWriteOnce
awsElasticBlockStore:
fsType: ext4
volumeID: vol-05323fe05d69ee97b
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-aws
namespace: default
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
selector:
matchLabels:
type: local
---
apiVersion: v1
kind: Pod
metadata:
name: pod-aws
namespace: default
spec:
containers:
- name: test
image: nginx
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: pvc
nodeName: ip-192-168-7-153.ap-northeast-2.compute.internal
volumes:
- name: pvc
persistentVolumeClaim:
claimName: pvc-aws
- 생성중이다.
pod 생성 에러
- 137분째 생성중이다.
- 에러가 있다.
- EC2의 볼륨을 확인해본다.
- 각 인스턴스마다 가지고있는 볼륨(8-20Gb)과 우리가 생성한 볼륨(1Gb)가 보인다.
- 유형 gp2는 FreeTier에서 사용할 수 있는 보통 성능을 가지고 있는 볼륨 유형이다.
- 가장 빠른 유형은 IO2 라는 유형이다.
vi aws-sc.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: gp2
annotations:
storageclass.kubernetes.io/is-default-class: "true"
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp2
fsType: ext4
kubectl delete -f aws-vol.yaml
kubectl apply -f aws.sc.yaml
- 새로 StorageClass를 생성해준다.
- 잘 실행되고 있다.
확인
- 우리가 볼륨을 사용하기위해 넣은 2a의 인스턴스(worker1)의 퍼블릭 IP로 접속해본다.
- df -h 명령어로보면 안보이지만, lsblk명령어로보면 1Gb가 잡혀있는 것을 볼 수 있다.
- 그러나 아직 mount된것이 아니다/
- df -h에 나와야한다.
- 즉, mount 해줘야 한다.
sudo mount /dev/xvdbb /mnt
볼륨 또 만들어보기
볼륨 생성
aws ec2 create-volume --availability-zone=ap-northeast-2c --size=1 --volume-type=gp2
- size 1(gb)로 또다시 만들어본다.
- 이번엔 2C가용영역의 worker를 사용할 것이기 때문에 availability zone을 2C로 해줘야한다.
- 이번에도 볼륨ID를 기록한다.
vi test-ebs.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-ebs
labels:
app: test-ebs
spec:
containers:
- image: nginx
name: test-container
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: test-volume
nodeName: ip-192-168-38-243.ap-northeast-2.compute.internal
volumes:
- name: test-volume
awsElasticBlockStore:
volumeID: "vol-08c7609ed59ad51bd"
fsType: ext4
---
apiVersion: v1
kind: Service
metadata:
name: test-ebs-svc
spec:
type: NodePort
selector:
app: test-ebs
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30080
- 잘 실행되고 있다.
- 역시 lsblk에 잡히고 이번엔
xvdce
로 되어있다.
sudo mount /dev/xvdce /mnt
Configmap
vi configmap-wordpress.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: config-wordpress
namespace: default
data:
MYSQL_ROOT_HOST: '%'
MYSQL_ROOT_PASSWORD: mode1752
MYSQL_DATABASE: wordpress
MYSQL_USER: wpuser
MYSQL_PASSWORD: wppass
kubectl describe configmaps config-wordpress
- config-wordpress의 저장된 env들을 살펴본다.
vi mysql-pod-svc.yaml
apiVersion: v1
kind: Pod
metadata:
name: mysql-pod
labels:
app: mysql-pod
spec:
containers:
- name: mysql-container
image: mysql:5.7
envFrom:
- configMapRef:
name: config-wordpress
ports:
- containerPort: 3306
---
apiVersion: v1
kind: Service
metadata:
name: mysql-svc
spec:
type: ClusterIP
selector:
app: mysql-pod
ports:
- protocol: TCP
port: 3306
targetPort: 3306
vi wordpress-pod-svc.yaml
apiVersion: v1
kind: Pod
metadata:
name: wordpress-pod
labels:
app: wordpress-pod
spec:
containers:
- name: wordpress-container
image: wordpress
env:
- name: WORDPRESS_DB_HOST
value: mysql-svc:3306
- name: WORDPRESS_DB_USER
valueFrom:
configMapKeyRef:
name: config-wordpress
key: MYSQL_USER
- name: WORDPRESS_DB_PASSWORD
valueFrom:
configMapKeyRef:
name: config-wordpress
key: MYSQL_PASSWORD
- name: WORDPRESS_DB_NAME
valueFrom:
configMapKeyRef:
name: config-wordpress
key: MYSQL_DATABASE
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: wordpress-svc
spec:
type: LoadBalancer
externalIPs:
- 192.168.2.0
selector:
app: wordpress-pod
ports:
- protocol: TCP
port: 80
targetPort: 80
kubectl get all
- pod와 svc 모두 잘 만들어졌다.
- 워드프레스가 잘 생성되었다.
로드밸런서 인증(ACM)
- 현재 로드밸런서와, 5개의 노드가 잘 서비스 되고있다.
- 전 강의에서 생성했던 SSL인증서를 그대로 사용하겠다.
- 리스너를 다음과같이 설정해준다.
- 보안그룹을 클릭해주고 이름을 기억해준다.
- 인바운드 규칙으로 HTTPS를 열어준다.
Route53
- 레코드 이름: blog
- 트래픽 라우팅 대상: 별칭
- App/Classic Load Balancer로 해서 우리가 생성한 로드밸런서를 지정해서 레코드를 생성한다.
- CNAME을 이용하는 방법 보다
- 이 호스팅 영역의 다른 레코드에 대한 별칭으로 작성하는것이 더 저렴하다고 한다.
SSL 플러그인 설치하기
- 플러그인을 새로 추가한다.
- Really Simple SSL 을 설치해주고 활성화 눌러준다.
- 만약 ACM인증서와 그 리스너가 세팅이 안됬다면 오른쪽 파란색 공간에 Override 버튼이 생긴다.
- 그 버튼이 없이 그냥 Acivate SSL 버튼만 잇어야한다.
정리
cd /home/ec2-user/volume
cd /home/ec2-user/wordpress
delete -f .
명령어로 파일단위로 지워준다.
RDS
데이터베이스 생성
- 프리티어를 사용한다.
- 마스터 사용자의 이름은 왠만하면 root, master로 하지 말자.
- db.t2.micro
- t2.micro를 사용하기 때문에 다중AZ배포를 사용하지 못하지만, 사용한다면 데이터 중복을 이용해 하나가 지워져도 복구할 수 있는 가용성을 제공해준다.
- 가용영역에 평소에는 사용하지못하는 2b가 있으니 사용해보자
- 초기 데이터베이스이름: wordpress
- 로그 내보내기를 전부 사용해본다.
wordpress를 위한 configmap만들기
vi configmap-mysql.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: config-mysql
namespace: default
data:
MYSQL_ROOT_HOST: '%'
MYSQL_ROOT_PASSWORD: mode1752
MYSQL_DATABASE: wordpress
MYSQL_USER: wpuser
MYSQL_PASSWORD: wppass
vi mysql-deploy-svc.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-deploy
labels:
app: mysql-deploy
spec:
replicas: 1
selector:
matchLabels:
app: mysql-deploy
template:
metadata:
labels:
app: mysql-deploy
spec:
containers:
- name: mysql-container
image: mysql:5.7
envFrom:
- configMapRef:
name: config-wordpress
ports:
- containerPort: 3306
---
apiVersion: v1
kind: Service
metadata:
name: mysql-svc
spec:
type: ClusterIP
selector:
app: mysql-deploy
ports:
- protocol: TCP
port: 3306
targetPort: 3306
vi configmap-wordpress.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: config-wordpress
namespace: default
data:
WORDPRESS_DB_HOST: 'database-1.cidsblwezpmk.ap-northeast-2.rds.amazonaws.com'
WORDPRESS_DB_USER: cocudeny
WORDPRESS_DB_PASSWORD: Kosa0401!
WORDPRESS_DB_NAME: wordpress
vi wordpress-doploy-service.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress-deploy
labels:
app: wordpress-deploy
spec:
replicas: 1
selector:
matchLabels:
app: wordpress-deploy
template:
metadata:
labels:
app: wordpress-deploy
spec:
containers:
- name: wordpress-container
image: wordpress
envFrom:
- configMapRef:
name: config-wordpress
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: wordpress-svc
spec:
type: LoadBalancer
selector:
app: wordpress-deploy
ports:
- protocol: TCP
port: 80
targetPort: 80
- 잘 생성되고 있다.
- configmap도 잘 저장되어있다.
Route53
- 아까 생성한 blog는 지우고, 새로 만들어준다.
ACM
- 리스터를 편집해 ACM을 넣어준다.
- 보안그룹도 잊지말고 세팅해줘야한다.
프로젝트
- 4개의 worker 노드들이 하나의 볼륨공간으로 공유하는 방법
- PV를 사용한다.
- pod들이 PVC를 통해 PV로 세팅되어있는 EFS와 연결되어야한다.
정리
- 노드그룹을 정리한다.
- RDS 정리
- 생성한 볼륨을 정리한다.
- 클러스터를 삭제해준다.
- ECR도 정리해준다.