지난 글에서 EKS
에 Wordpress
를 배포하기 위해 네트워크 및 보안그룹
설정, bastion server
구성, EKS Cluster
생성을 완료했습니다.
이번에는 생성한 EKS Cluster
에 실제로 Worker Node
를 구성하고 Wordpress를 배포해보겠습니다.
EKS
에 애플리케이션을 배포하기 위해서는 Worker Node
가 필요합니다.
Node Group
을 통해 Worker Node
를 생성하겠습니다.
EKS-Cluster
-> 구성 -> 컴퓨팅에서 노드 그룹 추가 버튼을 선택해줍니다.
이름을 설정하고 이전글에서 생성한 eks-worker-role
을 적용해줍니다.
레이블과 테인트는 설정하지 않고 다음으로 넘어가겠습니다.
Node
의 타입 및 디스크는 기본값을 사용하겠습니다.
노드그룹 조정은 최소 크기 2, 최대 크기 3, 원하는 크기 2로 하겠습니다.
이제 네트워킹을 설정하겠습니다.
Subnet
: EKS-Subnet-01, 02
을 설정하고, SSH 구성을 활성화 한 뒤 키페어
를 설정해 줍시다. 그리고 원격 허용 대상을 선택한 보안 그룹
으로 설정하고 대상 보안 그룹
을 Bastion-SG
로 설정해주겠습니다.
이렇게하면 bastion server
에서 Worker Node
에 ssh로 접속하여 상태를 확인할 수 있습니다.
만약 Node Group
구성 과정에서 위와 같은 에러가 발생했을 경우 NAT Gateway
가 정상적으로 라우팅 테이블에 설정되어 있는지 확인해봅시다.
이제 EKS Cluster
도 있고 애플리케이션을 배포할 Worker Node
도 있습니다.
그럼 어떻게해야 애플리케이션을 배포할 수 있을까요?
이전글에서 설명드렷던 것 처럼 bastion server
를 통해 EKS Cluster
에 명령어를 전달하면 됩니다.
그럼 이를 위한 bastion server
를 세팅하겠습니다.
이전글에서 bastion server
에 kubectl
을 설치하였습니다.
kubectl
은 ~/.kube/config
파일을 이용해 자신이 접근할 Kubernetes Control Plane
을 식별하는데요, 이전글에서는 .kube
폴더만 만들고 config 파일은 존재하지 않습니다.
이제 config 파일을 만들어 보겠습니다.
먼저 bastion server
에 설치된 aws cli
에 AWS IAM
계정을 통해 로그인 해야합니다.
bastion server
에 ssh로 접속한뒤 aws configure
명령을 수행합니다.
EC2
를 Amazon Linux 2로 생성했다면 aws cli
가 설치되어 있지만 그렇지 안하면 설치해 주어야 합니다.
다음은 Admin
권한을 가진 IAM
사용자의 보안 자격 증명
탭에서 액세스 키
를 만듭니다.
$ aws configure
AWS Access Key ID [None]: {액세스 키}
AWS Secret Access Key [None]: {비밀 액세스 키}
Default region name [None]: {지금까지 작업을 진행한 region}
Default output format [None]: json
이제 액세스 키
정보와 region
정보를 입력해줍니다.
# 자동으로 kubeconfig 파일 생성
$ aws eks update-kubeconfig --region {리전명} --name {EKS 클러스터 명}
다음으로 위의 명령어를 수행해줍니다.
이제 ~/.kube/config
파일이 생성되었습니다.
해당 파일을 열어보면 5번째줄에 자동으로 EKS Cluster
의 Endoint
정보가 입력되었습니다.
이제 kubectl
을 이용해 EKS Cluster
에 명령어를 전달해 보겠습니다.
# pod 조회
$ kubectl get pod --all-namespaces
정상적으로 bastion server
를 이용해 EKS Cluster
에 명령을 전달했습니다!
이제 EKS Cluster
에 Wordpress 애플리케이션을 배포해보겠습니다.
이전글에서 설명드렸듯이 Wordpress Pod
는 EFS
를 공유하고, DB로는 RDS
를 사용할 예정입니다.
EKS
에서EFS
를 사용하는 방법과 RDS
에 대해서는 아래의 글을 참고해서 진행해주세요.
이번에는 EFS
및 RDS
의 생성이 완료되었다고 가정하고 진행하겠습니다.
fs-0df4d517e6be023fc
라는 EFS
가 생성되었고, RDS
에 Wordpress
라는 스키마를 생성했습니다.
EFS
의 네트워크
에 적용된 Subnet
별 Endpoint
에 적용된 보안그룹에 Worker Node
가 가지고 있는 보안그룹도 추가해 주었습니다.
이제 yaml 파일을 작성하겠습니다.
# pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: efs-pv
spec:
capacity:
storage: 5Gi
volumeMode: Filesystem
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
storageClassName: efs-sc
csi:
driver: efs.csi.aws.com
volumeHandle: 여기에 EFS id 입력
먼저 실제 EFS
인 PV
에 대한 yaml 파일입니다.
# pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: efs-claim
spec:
accessModes:
- ReadWriteMany
storageClassName: efs-sc
resources:
requests:
storage: 5Gi
다음은 PV
와 연결할 PVC
에 대한 yaml 파일입니다.
# storageclass.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: efs-sc
provisioner: efs.csi.aws.com
다음은 StorageClass
에 대한 yaml 파일입니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
labels:
app: wordpress
spec:
replicas: 5
selector:
matchLabels:
app: wordpress
tier: frontend
strategy:
type: Recreate
template:
metadata:
labels:
app: wordpress
tier: frontend
spec:
containers:
- image: wordpress:4.8-apache
name: wordpress
env:
- name: WORDPRESS_DB_HOST
value: RDS 엔드포인트 입력
- name: WORDPRESS_DB_PASSWORD
value: RDS 비밀번호 입력
- name: WORDPRESS_DB_USER
value: RDS 계정 입력
- name: WORDPRESS_DB_NAME
value: 위에서 생성한 Wordpress 스키마 입력
ports:
- containerPort: 80
name: wordpress
volumeMounts:
- name: wordpress-persistent-storage
mountPath: /var/www/html
volumes:
- name: wordpress-persistent-storage
persistentVolumeClaim:
claimName: efs-claim
마지막으로 Wordpress에 대한 yaml입니다.
EFS
를 VolumeMount해 사용하고, DB로는 RDS
를 사용하는 환경변수를 전달했습니다.
이제 위의 yaml파일 4개를 한 디렉토리에 모으고 명령어를 수행하겠습니다.
$ kubectl apply -f .
persistentvolume/efs-pv created
persistentvolumeclaim/efs-claim created
storageclass.storage.k8s.io/efs-sc created
deployment.apps/wordpress created
Pod
가 정상적으로 배포 되었습니다.
이제 해당 애플리케이션을 LoadBalancer
를 통해 외부로 노출시키겠습니다.
# lb.yaml
apiVersion: v1
kind: Service
metadata:
name: wordpress
labels:
app: wordpress
spec:
ports:
- port: 80
targetPort: 80
selector:
app: wordpress
tier: frontend
type: LoadBalancer
LoadBalancer
Type Serivce
의 yaml 파일입니다.
Serivce
를 배포해 주겠습니다.
# lb 배포
$ kubectl apply -f lb.yaml
# lb 확인
$ kubctl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 172.20.0.1 <none> 443/TCP 103m
wordpress LoadBalancer 172.20.125.206 a64e3b055f9ec4b71945c5244fb09852-847660875.ap-northeast-1.elb.amazonaws.com 80:32655/TCP 6s
Service
조회시 LoadBalancer
Type이 보입니다.
실제로 AWS
에 ELB
가 생성된것도 확인할 수 있습니다.
이제 해당 ELB
를 통해 배포한 Wordpress 애플리케이션에 접근하겠습니다.
DNS 이름
을 복사해서 http://{DNS이름}으로 접속합니다.
http://a64e3b055f9ec4b71945c5244fb09852-847660875.ap-northeast-1.elb.amazonaws.com/
저의 경우 위와 같은 주소로 접속합니다.
Wordpress가 정상적으로 배포되었습니다!
이제 언어를 선택하고 다음으로 넘어가겠습니다.
그 다음 사이트 정보를 입력하겠습니다.
이제 설치가 끝났으니 로그인을 해보겠습니다.
로그인도 정상적으로 수행되는걸 확인할 수 있습니다!
이제 트래픽이 정상적으로 분배되는지 확인해 보겠습니다.
먼저 bastion
에서 ssh를 통해 각 Worker Node
에 접속하겠습니다.
# LoadBalancer가 트래픽을 분배해주는 Worker Node의 포트 확인 = 32655/TCP
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 172.20.0.1 <none> 443/TCP 121m
wordpress LoadBalancer 172.20.125.206 a64e3b055f9ec4b71945c5244fb09852-847660875.ap-northeast-1.elb.amazonaws.com 80:32655/TCP 17m
# Node 검색하여 ip 확인
$ kubectl get node
NAME STATUS ROLES AGE VERSION
ip-10-0-2-62.ap-northeast-1.compute.internal Ready <none> 73m v1.21.5-eks-9017834
ip-10-0-3-243.ap-northeast-1.compute.internal Ready <none> 73m v1.21.5-eks-9017834
# 각 Node에 원격 연결
$ ssh -i "keypairt" ec2-user@10.0.2.62
$ ssh -i "keypairt" ec2-user@10.0.3.243
각 Worker Node
에 tcpdump
를 설치하겠습니다.
그 다음 LB
에서 80번을 수신해 Worker Node
로 전파해주는 포트인 32655/TCP
에 대해 패킷을 캡쳐해 보겠습니다.
# 32655번 포트에 대해 캡쳐
$ tcpdump dst port 32655
그 다음 LB
를 통해 접속한 Wordpress를 새로고침해보겠습니다.
패킷이 분산되고 있는것을 확인할 수 있습니다.
만약 하나의 Worker Node
에만 계속해서 트래픽이 전달되는 것 같다면 ELB
의 교차 영역 로드 밸런싱
이 활성화 상태인지 확인해 주세요.
해당 옵션이 비활성화 상태일 경우 같은 브라우저, 같은 IP에서 접근시 로드밸런싱 알고리즘에 따라 계속 같은 Worker Node
에만 요청을 보낼 수 있습니다.