220725

HyeonKi Jo·2022년 7월 25일
0
post-thumbnail

팀프로젝트

  • 기가막힌 주제를 가지고, 기승전결을 가진 스토리, 프로젝트로 진행해야한다.

중간 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

사용자 데이터

#!bin/bash
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 생성


  • web-site 이름으로 생성해준다.

EC2 aws configure

  • 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)
    • 이 completion bash 명령어는 쿠버네티스 시험을 볼 떄 반드시 필요한 항목이다.
    • kubectl 치트시트를 검색하면 각종 쿠버네티스 편리 기능정보가 모두 담겨있다.
    • 이 편의 기능을 시험볼때 처음에 설정할 수 있다.
    • 예를들어 alias kube=kubectl 명령어로 kubectl명령어를 kube로 줄여사용할 수 있다.
    • https://kubernetes.io/ko/docs/reference/kubectl/cheatsheet/
  • 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				# persistent volume
  labels:
    type: local
spec:
  capacity:
    storage: 1Gi
  persistentVolumeReclaimPolicy: Retain	# pdd가 삭제되도 유지
  accessModes:
    - ReadWriteOnce
  awsElasticBlockStore:		# EBS를 사용한다.
    fsType: ext4			# ext4타입으로 포맷한다.
    volumeID: vol-05323fe05d69ee97b	# 아까 기록해놓은 volumeID를 여기 입력한다.
    						# 볼륨이 현재 2a에 생성되어있다.
---
apiVersion: v1
kind: PersistentVolumeClaim		
metadata:
  name: pvc-aws
  namespace: default
spec:
  accessModes:
    - ReadWriteOnce
  resources:			# 라벨이 없어도, PVC와 PV의 용량에 맞춰 연결될 것이다.
    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
          						# 볼륨이 2a에 생성되어있으니, 노드도 2a에 존재하는 인스턴스를 골라야한다.
                                # 이것은 내부IP를 보면 0~16까지가 a이니 내부IP를 보고 구별할 수있다.
  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					# 기존 api버전부터 나오던것과 달리 kind먼저 작성했다.
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
    • df -h로 확인해보니 잘 나온다.

볼륨 또 만들어보기

볼륨 생성

  • 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
    # This AWS EBS volume must already exist.
    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
    • 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:				# env를 다 가져온다.
    - configMapRef:			
        name: config-wordpress	# config-wordpress라는 이름의 configmap을 전부 가져와서 사용할 것이다.
       							# 결국 mysql설정이 전부 완료되서 pod가 생성될 것이다.
    ports:
    - containerPort: 3306
---
apiVersion: v1
kind: Service
metadata:
  name: mysql-svc
spec:
  type: ClusterIP				# mysql은 내부에서만 사용할 것이기 때문에 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	# 방금전 mysql-svc에 3306포트로 연결한다.
      value: mysql-svc:3306
    - name: WORDPRESS_DB_USER
      valueFrom:				# 값을 가져온다.
        configMapKeyRef:			# configmap에서 값을 가져오는데, 
          name: config-wordpress	# config-wordpress에서
          key: MYSQL_USER			# 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
    • kubectl delete -f .
  • cd /home/ec2-user/wordpress
    • kubectl delete -f .
  • 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'	# AWS RDS의 엔트포인트를 넣는다.
  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:			# 이전의 wordpress-deploy-svc와의 다른점이 여기다.
        					# 이전에는 하나하나 가져왔지만 이번엔 한번에 가져올 것이다.
        - configMapRef:
            name: config-wordpress
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: wordpress-svc
spec:
  type: LoadBalancer
#  externalIPs:
#  - 192.168.2.0
  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도 정리해준다.
profile
Talking Potato

0개의 댓글