aws의 eks를 활용해 백엔드 서버 배포 파이프라인을 구축 하는 방법에 대해 정리 하고자 한다.
test용 서버 같은 경우엔 https가 필요 없을수도 있겠지만, 여기서는 http, https 프로토콜 통신이 가능한 배포를 가정하고 진행하도록 하겠다.(https때문에 많은게 복잡해짐)
<사전 준비사항 - 개발자PC>
1)aws cli 프로그램 설치
2)aws configure 명령을 통해 AWS CLI를 설정. AWS Access Key ID, AWS Secret Access Key, Default region name 등
3)kubectl 설치 및 helm설치
<절차>
1.eks 클러스터 생성
1)버전, 이름 등 선택
2)iam역할 : awseksclusterrole 선택
3)별도 암호화 선택 없이 진행
4)VPC, subnet, 보안그룹 생성 후 선택
5)클러스터 엔드포인트 엑세스는 퍼블릭 및 프라이빗 선택
6)그외 선택은 모두 default사항 진행
2.kubectl config 파일 업데이트
-aws eks update-kubeconfig --region [region-name] --name [cluster-name] 명령을 통해 kubectl의 클러스터 설정 파일을 다운로드
-해당 파일은 로컬에 저장되는 파일로서 해당 config를 통해 eks 클러스터를 컨트롤
-파일 저장 위치는 ~/.kube/config 로서 사용자 home 밑에 kube폴더 밑에 config라는 이름의 파일로 생성
-클러스터가 여러개 일 경우에 kubectl config use-context [context-name] 를 통해 특정 클러스터의 context선택. aws eks update-kubeconfig ~ 를 재실행 해도 동일.
3.노드생성(ec2생성)
-aws콘솔의 클러스터의 컴퓨팅에서 노드그룹 생성 및 노드 생성
-kubectl get nodes --show-labels : 노드 조회(+라벨링여부)
-kubectl label nodes <your-node-name> deployment=test-dev-node : 노드에 deployment키와 test-dev-node라는 이름의 value로 라벨링
4.POD생성
-서비스 파드 생성을 위한 ecr이미지는 사전배포되어있다고 가정하겠다.
-파드 생성을 위한 yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-dev-depl
spec:
replicas: 1 # 추가: 복제본 수를 정의합니다.
selector:
matchLabels: # 추가: 어떤 pod를 관리할지 결정하는 선택기를 정의합니다.
app: test-dev
template:
metadata:
labels:
app: test-dev
spec:
containers:
- name: test-dev
image: <ecr url>
imagePullPolicy: Always
ports:
- containerPort: 4000
nodeSelector: # 라벨링된 node select
deployment: test-dev-node
---
apiVersion: v1
kind: Service
metadata:
name: test-dev-srv
spec:
selector:
app: test-dev
ports:
- protocol: TCP
port: 4000
targetPort: 4000
type: ClusterIP
-yaml파일을 적용하기 위한 명령어 : kubectl apply -f test.yaml
-적용한 yaml파일 취소 명령어 : kubectl delete -f test.yaml
4.라우팅
위의 절차까지 실행했다면 서비스 노드가 생성되었다. 이제 해당 노드에 http통신을 통해 접근할 차례.
-아래 명령어를 통해 ingress-nginx-controller 간편 생성
-kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/aws/deploy.yaml
-조회시에는 kubectl get deployments -A 를 통해 조회하자(ingress-comtroller의 namespace가 자동으로 ingress-nginx로 생성되기때문에)
-아래 yaml을 적용함으로서 Ingress 생성이 되고, 서비스 노드에 라우팅이 된다.(pod Service의 name을 라우팅시켜야함에 유의)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: dev-ingress
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: <name-of-your-clusterissuer>
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
tls:
- hosts:
- "dev.test.com"
secretName: dev-test-com-tls
rules:
- host: "dev.test.com"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: test-dev-srv
port:
number: 4000
#- 위 패턴으로 host 추가 가능
여기까지 진행하게 되면 로드밸런서가 하나 자동생성이 됨을 알수 있을 것이다. aws의 로드밸런서와 연계되어 nginx가 웹훅으로 동작하게 된다.
-참고로 위의 코드는 https통신까지 가능하도록 설정 해놓은 코드이다. cert-manager를 통해 tls 인증서를 발급받아 spec.tls.secretName에 발급받은 인증서를 매핑했고, force-ssl-redirect: "true" 를 통해 http요청을 https로 redirecting 시켜놓았다.
-인증서 발급 절차
1)cert-manager 생성
# 네임스페이스 생성
kubectl create namespace cert-manager
# cert-manager를 설치하기 위해 Jetstack Helm 리포지토리를 추가
helm repo add jetstack https://charts.jetstack.io
# Helm 리포지토리 업데이트
helm repo update
# cert-manager 차트 설치
helm install \
cert-manager jetstack/cert-manager \
--namespace cert-manager \
--version v1.5.0 \
--create-namespace \
--set installCRDs=true
2)ClusterIssuer 생성
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
# ACME 서버의 URL입니다. 이 값은 Let's Encrypt의 실제 환경을 가리킵니다.
server: https://acme-v02.api.letsencrypt.org/directory
# 이메일 주소는 Let's Encrypt에서 인증서의 만료 알림을 보내는 데 사용됩니다.
email: your-email@example.com
# 비공개키는 Let's Encrypt 계정에 사용됩니다.
privateKeySecretRef:
# Secret의 이름입니다.
name: letsencrypt-prod
# ACME 도메인 확인을 위해 사용되는 챌린지 방법을 지정합니다.
solvers:
- http01:
ingress:
class: nginx
3)ClusterIssuer를 이용하여 Certificate생성
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: dev-test-com-tls
namespace: default
spec:
secretName: dev-test-com-tls
duration: 2160h # 90d
renewBefore: 360h # 15d
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
commonName: dev.test.com
dnsNames:
- dev.test.com
#- host 추가 가능 - www.example.com
*여기서 생성한 secretName과 위의 ingress생성시 지정한 tls명과 일치해야함을 유의하자.
5.외부도메인매핑
여기까지 진행했다면 aws에서의 작업은 마무리됐다. 이제 만들어둔 도메인에 cname으로 만들어진 로드밸런서의 주소를 매핑하면 끝나게 된다.
*그외 기존 인프라 구성 파악시 유용한 kubectl 명령어
-kubectl get deployments -A : 모든 namespace에 배포사항 확인. -A옵션이 없으면 default에서 찾게 되고, 특정 namespace를 지정시에는 -n <네임스페이스명> 옵션을 붙이면된다.
-kubectl get deployment <deployment name> -o yaml : 기존에 적용된 배포관련 yaml이 무엇인지 알수 있다. deployment외에 service, ingress, ClusterIssuers, Certificate, secret 등 종류별로 조회 가능
'프로그래밍 > devops' 카테고리의 다른 글
private VPC outbound 인터넷 사용을 위한 nat구성 (0) | 2023.02.28 |
---|---|
AWS NLB를 활용한 private VPC 구성 (0) | 2023.02.24 |
ecs를 통한 컨테이너 배포와 alb health check (0) | 2023.02.20 |
git conflict 해결 - 명령어와 github UI (0) | 2023.01.29 |
git merge, rebase, squash 차이 (0) | 2023.01.29 |