220722

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

EC2 생성

사용자 데이터

#!/bin/bash
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:v1.0

Route53

  • docker.cocudeny.shop도메인을 등록해준다.

ECR

  • ECR로 바로 들어가기 힘들다
    • EKS를 통해 들어가준다.
  • 리포지토리 생성
  • 퍼블릭 리포지토리를 생성할 것이다.
  • 리포지토리가 저장소지만, 여러개의 서로다른 이미지가 들어가는 것이 아니다.
  • 하나의 이미지와 그 여러 버전들만 저장할 수 있다.
  • 즉, 도커hub의 한 이미지를 push한것과 비슷하다.

리포지토리 생성

  • test-site이름으로 리포지토리를 생성해준다.

AWS EC2

  • aws configure를 진행해준다.
  • aws configure는 IAM을 생성하고 나온 Credential을 이용하는데, 7월21일에 생성한 것을 사용한다.

리포지토리 push하기


  • aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws/[계정이름]
    • 인증 토큰으로 Docker클라이언트를 인증한다.
  • docker tag jo1132/web-site:v2.0 public.ecr.aws/z0w8s2n0/test-site:eagle
    • 도커 태그로 PUSH용 이미리로 태그한다.
    • 버전 이름은 아무렇게 해도된다.
  • docker push public.ecr.aws/z0w8s2n0/test-site:eagle
  • 잘 push되었다.
  • ECR에서도 확인할 수 있다.

EKS 클러스터 생성

클러스터 구성

  • 이름을 넣고, Kubernetes버전을 1.22로 한다.
  • 클러스터 서비스 역할은 어제 생성한 eksClusterRole로 해준다.

네트워킹 구성

  • VPC와 서브넷을 구성해준다.
    • 서브넷은 2A, 2C만 프리티어로 사용할 수 있다.
  • 보안그룹은 HTTP, HTTPS, SSH, ICMP가 열려있는 보안그룹을 사용한다.
  • 클러스터 엔드포인트는 퍼블릭으로 할 것이다.
  • 이전 실습에서 flannel로 사용했던 네트워크 관련 기능을 여기서 설정하게 된다.

로깅 구성

  • 제어플레인(Control Plane, MasterNode)에서 로그를 전송하는 것이다.
  • 5Gb까지 무료라 실습해보자.

검토

  • 검토 후 생성해준다.

AWS kubectl 설치

  • https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/install-kubectl.html
  • curl -o kubectl https://s3.us-west-2.amazonaws.com/amazon-eks/1.22.6/2022-03-09/bin/linux/amd64/kubectl
    • 아래 curl명령어로 다운받을 수 있다.
  • chmod +x ./kubectl
    • 바이너리에 실행 권한을 적용한다.
  • mkdir -p $HOME/bin && cp ./kubectl $HOME/bin/kubectl && export PATH=$PATH:$HOME/bin
    • 바이너리를 PATH의 폴더에 복사한다.
  • source <(kubectl completion bash)
    • 자동완성 기능을 실행한다.
  • echo "source <(kubectl completion bash)" >> ~/.bashrc
    • 재부팅해도 자동실행되도록 저장한다.
  • kubectl version --short --client
    • 설치가 잘 됬는지 확인한다.
  • 설치가 잘 됬다.
  • 그러나 kubectl 명령어가 제대로 나오지 않는다.
    • 클러스터가 아직 연결되지 않았기 때문이다.
  • aws eks --region ap-northeast-2 update-kubeconfig --name MY_CLUSTER2
    • 클러스터 생성이 완료되면, 위와같이 연결을 해줘야 한다.

노드 그룹 추가

노드그룹 구성

  • 이름을 넣어주고, 어제 생성한 nodeGroupRole을 사용한다.
  • 노드그룹에 들어갈 권한에는
    • AmazonEKSWorkerNodePolicy
    • AmazonEC2ContainerRegistryReadOnly
    • AmazonEKS_CNI_Policy
      이 세가지가 있다.

컴퓨팅 및 조정 구성 설정

  • 이번엔 on-demend가 아닌 SPOT을 사용해 보도록한다.
    • SPOT은 인스턴스 경매방식으로 최대 90%까지 저렴하게 인스턴스를 사용할 수 있다.
  • Desired state는 2개, 최대크기 4개를 준다.

네트워킹 지정

  • 서브넷은 2A, 2C를 사용할 것이다.
  • 노드에 대한 SSH액세스 구성
    • 키페어 설정
    • SSH원격 액세스 권한 허용 대상에서 모두를 넣어줘본다.

검토 및 생성

  • 검토 후 생성해준다.

AutoScaling그룹

  • 클러스터 생성 후, 자동으로 AutoScaling그룹이 생성되었다.
  • 이 AutoScaling그룹은 지정된 Node수만큼 지워지면 다시 정해진 개수만큼 생성되는 방법으로 node개수를 유지하는 용도의 그룹이다.

pod 및 로드밸런서 생성

  • kubectl run nginx-pod --image=public.ecr.aws/z0w8s2n0/test-site:eagle
  • ECR에 업로드한 이미지로 pod을 생성해준다.
  • 47 kubectl expose pod pod --name loadbalancer --type LoadBalancer --external-ip [masterIP] --port 80
    • 또, 로드밸런서를 생성해준다.

로드밸런서

  • 로드밸런서 서비스를 생성하여 AWS 로드밸런서가 만들어졌다.
  • 여기서 리스너 -> 편집을 눌러준다.
  • 인증서에서 ACM 인증서 생성하여 리스너를 SSL로 만들어준다.
  • 인증서가 잘 로드되면 저장해준다.
    • 인증서 생성에 꽤 오랜시간이 걸린다.
  • 이제 HTTPS으로 접속해야 될 것이다.

노드그룹 정리

  • 노드그룹을 삭제하고 다시 만들어본다.

오후강의

노드그룹 생성

노드 그룹 구성

  • 이름 : NODEGROUP
  • 역할도 설정해준다. 위에서 언급한 역할 3개가 들어가야한다.

컴퓨팅 및 조정 구성 설정

  • 이번에는 ON-Demand로 구성해준다.
  • 최소크기 4, 최대 8개의 인스턴스를 만들어본다.

네트워킹 지정

생성

노드그룹을 생성할 때, 역할을 주는 이유

  • 역할을 줌으로써 AWS 서비스를 생성할 수 있게된다.
  • EC2를 생성하는등의 권한이 필요하다.

Route53 이용

  • worker1~4까지 도메인을 생성해서 사용한다.

노드 확인

  • 4개의 노드가 Ready로 대기하고있다.

실습

vi replica-loadbalancer.yaml

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: nginx-replicaset
spec:
  replicas: 3 # desired state (kube-controller-manager)
  selector:
    matchLabels:
      app: nginx-replicaset

  template:
    metadata:
      name: nginx-replicaset
      labels:
        app: nginx-replicaset
    spec:
      containers:
      - name: nginx-replicaset-container
        image: nginx
        ports:
        - containerPort: 80

---

apiVersion: v1
kind: Service
metadata:
  name: loadbalancer-service-replicaset
spec:
  type: LoadBalancer
    #  externalIPs:
    #    -
  selector:
    app: nginx-replicaset
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

  • 로드밸런싱 DNS주소로 접속해본다.
  • 잘 나온다.
  • 현재 replicas가 3으로 되어있어 3개만 들어가있다.
  • 4개로 수정해본다.
  • kubectl edit replicaset nginx-replicaset
    • kubectl edit rs nginx-replicaset
      - rs로 줄이는 방법이 있다.
  • replicas를 4로 수정한다.
  • 빠르게 4개로 수정되었다.

각 4개의 노드마다 html을 구별해본다.

  • kubectl exec nginx-replicaset-7hsln -- sh -c "echo 'web01' > /usr/share/nginx/html/index.html"
  • kubectl exec nginx-replicaset-kl5gk -- sh -c "echo 'web02' > /usr/share/nginx/html/index.html"
  • kubectl exec nginx-replicaset-m48bx -- sh -c "echo 'web03' > /usr/share/nginx/html/index.html"
  • kubectl exec nginx-replicaset-vqhqx -- sh -c "echo 'web04' > /usr/share/nginx/html/index.html"
  • 새로고침해도 바뀌지 않는것을 보니 라운드로빈은 아닌 것 같다.

replicaset의 자가치유 기능

  • kubectl delete pod nginx-replicaset-m45bx
    • pod하나를 지워본다.
  • 하나를 삭제했더니 하나가 바로 생겼다.
    • 자가치유 기능을 하고있다.
  • 각 pod이 골고루 node에 퍼져서 작동중이다.

Cluster IP

vi deployment-clusterip.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 4
  selector:
    matchLabels:
      app: nginx-deployment
  template:
    metadata:
      name: nginx-deployment
      labels:
        app: nginx-deployment
    spec:
      containers:
      - name: nginx-deployment-container
        image: nginx
        ports:
        - containerPort: 80

---

apiVersion: v1
kind: Service
metadata:
  name: clusterip-service-deployment
spec:
  type: ClusterIP
  externalIPs:		# ClusterIP지만 외부 IP를 넣어본다.
  - [worker1IP]
  selector:
    app: nginx-deployment
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  • 위 yaml파일은 ClusterIP 서비스지만 중간에 externalIP 옵션을 넣어줬다.
  • 과연 들어가질까?
  • 안된다.
  • worker1 보안그룹에 80번 포트를 열어준다.
  • 안된다....
  • ClusterIP는 내부에서 사용하는 IP이다.
  • externalIP는 외부에서 대문처럼 있는 IP이며, 내부의 IP와 NAT로 연결되어있다. 그래서 externalIP에 worker1의 외부IP가 아닌 내부 IP를 넣어주면 1:1NAT로 인해 통신이 될 것이다.
  • worker1의 내부IP를 externalIP에 넣어본다.
  • 된다!
  • worker모두의 IP를 넣어본다.
  • DNS주소로 들어가니 잘 나온다.

LoadBalancer

loadbalancer-deployment.yaml

apiVersion: v1
kind: Service
metadata:
  name: loadbalancer-service-deployment
spec:
  type: LoadBalancer
  externalIPs:		# AWS EKS의 Worker들의 내부 IP를  externalIPs로 넣었다.
  - 192.168.13.11
  - 192.168.41.238
  - 192.168.9.157
  - 192.168.32.34

  selector:
    app: nginx-deployment
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

  • 주소가 잘 들어왔다.
  • 여기서 생성된 로드밸런서 주소로 들어가본다.
  • 잘 연결되었다.

정리

  • 결국 ClusterIP를 사용하는 것이 아니라, Node의 내부 IP를 사용했을 때, 잘 연결 됬다.

Deployment 롤링 업데이트 제어

  • kubectl set image deployment.apps/nginx-deployment nginx-deployment-container=public.ecr.aws/z0w8s2n0/test-site:eagle
    • 이미지를 nginx에서 ECR의 이미지로 업데이트를 진행한다.
    • pod들이 한번에 업데이트 되는것이 아니라 조금(25%)씩 업데이트를 진행한다.
    • 업데이트로인한 고객의 불편함 없이 무중단 서비스를 이어가기 위함이다.

revision

  • kubectl rollout history deployment nginx-deployment
    • 이전 버전의 기록인 revision을 살펴본다.
  • revision 2 정보 확인
  • kubectl set image deployment.apps/nginx-deployment nginx-deployment-container=[이미지경로]
  • 반복작업으로 버전을 막 쌓았다.

롤백

  • kubectl rollout history deployment nginx-deployment
    • 이전 버전으로 롤 백하기
  • kubectl rollout history deployment nginx-deployment --to-revision=2
    • revision 2 버전으로 롤백하기

리비전 최대개수

  • kubectl edit deployments.apps nginx-deployment
    • 리비전 최대 기록 개수가 10개로 저장되어 있다.
    • edit명령어로 20개까지 늘려본다.
    • 저장해보니 에러메세지가 출력되지 않고 성공적으로 저장되었다.

WordPress

vi wordpress-pod-svc.yaml

apiVersion: v1
kind: Pod
metadata:
  name: wordpress-pod		# 이 코드는 한 pod에 두개의 컨테이너를 넣는 예제이다. 
  							# 그러나 이 방식은 요즘방식이 아니다.
                            # pod하나에 여러 컨테이너가 들어갈 수 있다는 실습이다.
  labels:
    app: wordpress-pod
spec:
  containers:
  - name: mysql-container
    image: mysql:5.7
    env:
    - name: MYSQL_ROOT_HOST
      value: '%' # wpuser@%
    - name: MYSQL_ROOT_PASSWORD
      value: kosa0401
    - name: MYSQL_DATABASE
      value: wordpress
    - name: MYSQL_USER
      value: wpuser
    - name: MYSQL_PASSWORD
      value: wppass
    ports:
    - containerPort: 3306
    command:
>
  - name: wordpress-container
    image: wordpress
    env:
    - name: WORDPRESS_DB_HOST
      value: wordpress-pod:3306		# wordpress-pod, 자기스스로의 3306포트를 DB-HOST로 넣는다.
    - name: WORDPRESS_DB_USER
      value: wpuser
    - name: WORDPRESS_DB_PASSWORD
      value: wppass 
    - name: WORDPRESS_DB_NAME
      value: wordpress
    ports:
    - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: loadbalancer-service-deployment-wordpress
spec:
  type: LoadBalancer
#  externalIPs:
#  - 192.168.56.101
  selector:
    app: wordpress-pod
  ports:
  - protocol: TCP
    port: 80

  • 로드밸런서까지 잘 생성되었다.
  • Route53으로 로드밸런서를 DNS로 등록하고 잘 접속된다.

보안그룹 편집

  • 위 보안그룹을 클릭해서 인바운드를 편집해준다.
  • HTTPS를 추가해주었다.
  • 워드프레스를 설치하고 로그인해서 플러그인 새로 추가를 눌러준다.
  • Really simple ssh를 설치 -> 활성화해준다.
  • 여기서 ssl을 설정해준다.
  • 이렇게 진행해본다
  • 그럼 이제 안된다. ㅎㅎ
  • 우리 로드밸런서의 리스너를 편집해야 한다.
  • 위와같이 SSL인증과 TCP 80번포트를 리스너로 등록해주고
  • 다시 pod을 생성한다.
  • 이러면 Override 체크박스 없이 ActiveSSL이 활성화된다.
  • HTTPS로 잘 접속할 수 있었다.
  • 이제부터는 Https까지 하는것으로 마무리 짓도록 하겟다.

metallb

기존 작업 정리

  • kubectl delete all --all
    • pod, svc, deploy등 이전 생성한 자워늘 모두 지워준다.
  • sudo yum install git -y
    • git을 설치해준다.
  • git clone https://github.com/hali-linux/_Book_k8sInfra.git
    • git으로 metallb를 다운로드 받는다.
  • kubectl apply -f ./_Book_k8sInfra/ch3/3.3.4/metallb.yaml
    • apply 해준다.
  • kubectl get pods -n metallb-system -o wide
    • 현재 자원이 꽉차서 하나의 pod이 pending상태로 대기하고있다.
    • pod개수의 자원이 부족하다.
    • 주륵 metallb는 다음주에 하도록 한다.

정리

  • 노드그룹 정리
  • 클러스터 삭제
  • ECR 삭제
  • EC2 삭제

추가, CNAME과 ALIAS

문제

회사는 사용자가 자체 설문지를 통해 ~~ 조사를 완료할 수 있도록 새로운 웹 애플리케이션을 만들었습니다. 회사는 Route53을 사용하여 도메인을 구입했습니다. 웹개발팀은 모든 트래픽이 들어오면 www으로 라우팅되도록 Route53으로 레코드를 생성하려고 합니다. 웹 개발팀에 추천할 가장 비용 효율적 솔루션은?

A

  • 트래픽을 www으로 라우팅하는 MX레코드를 작성
    -> MX레코드는 메일서버를 말한다.

B

  • 트래픽을 www으로 라우팅하는 NS 레코드를 생성
    -> nameserver를 작성하는것도 아니다.

C

  • CNAME레코드를 생성
    • www.virus-survey.com -> virus-survey.com 으로는 갈 수 있지만,
      반대로 virus -> www는 아예 갈 수 없다. 비용만 따지면 이게 저렴하지만 아예 가능하지 않다.
    • CNAME : Domain -> Domain 이동, 일종의 규약, 프로토콜이다.

D

  • 별칭 레코드를 생성
    • 이것만 가능하다. 별칭 레코드를 생성하여 논리적으로 virus -> www가 가능하다.
    • AWS 서비스간 이동 가능, AWS시험은 일종의 자기네 제품 홍보기능도 있다. 자기네 제품이 정담일 가능성이 많다.

추가

the difference between CNAME and Alias
CNAME:
– Points a hostname to any other hostname. (app.mydomain.com => blabla.anything.com) 
– ONLY FOR NON ROOT DOMAIN (aka. something.mydomain.com) 
Alias: 
– Points a hostname to an AWS Resource (app.mydomain.com => blabla.amazonaws.com) 
– Works for ROOT DOMAIN and NON ROOT DOMAIN (aka mydomain.com) 
– Free of charge 
– Native health check

  • 즉, CNAME은 루트도메인(cocudeny.shop)을 라우팅할 수 없다. (*.cocudeny.shop)처럼 앞에 다른 주소가 있어야 한다.
  • Alias는 자유롭게 설정할 수 있다.
profile
Talking Potato

0개의 댓글