#!/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
- docker.cocudeny.shop도메인을 등록해준다.
- 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에서도 확인할 수 있다.
클러스터 구성
- 이름을 넣고, Kubernetes버전을 1.22로 한다.
- 클러스터 서비스 역할은 어제 생성한 eksClusterRole로 해준다.
네트워킹 구성
- VPC와 서브넷을 구성해준다.
- 서브넷은 2A, 2C만 프리티어로 사용할 수 있다.
- 보안그룹은 HTTP, HTTPS, SSH, ICMP가 열려있는 보안그룹을 사용한다.
- 클러스터 엔드포인트는 퍼블릭으로 할 것이다.
- 이전 실습에서 flannel로 사용했던 네트워크 관련 기능을 여기서 설정하게 된다.
로깅 구성
- 제어플레인(Control Plane, MasterNode)에서 로그를 전송하는 것이다.
- 5Gb까지 무료라 실습해보자.
검토
- 검토 후 생성해준다.
- 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개수를 유지하는 용도의 그룹이다.
kubectl run nginx-pod --image=public.ecr.aws/z0w8s2n0/test-site:eagle
47 kubectl expose pod pod --name loadbalancer --type LoadBalancer --external-ip [masterIP] --port 80
노드 그룹 구성
- 이름 : 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를 사용했을 때, 잘 연결 됬다.
kubectl set image deployment.apps/nginx-deployment nginx-deployment-container=public.ecr.aws/z0w8s2n0/test-site:eagle
- 이미지를 nginx에서 ECR의 이미지로 업데이트를 진행한다.
- pod들이 한번에 업데이트 되는것이 아니라 조금(25%)씩 업데이트를 진행한다.
- 업데이트로인한 고객의 불편함 없이 무중단 서비스를 이어가기 위함이다.
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개까지 늘려본다.
- 저장해보니 에러메세지가 출력되지 않고 성공적으로 저장되었다.
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
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는 다음주에 하도록 한다.
회사는 사용자가 자체 설문지를 통해 ~~ 조사를 완료할 수 있도록 새로운 웹 애플리케이션을 만들었습니다. 회사는 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 이동, 일종의 규약, 프로토콜이다.
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