다른 사람 IAM으로 접속
kubectl 설치
https://kubernetes.io/ko/docs/tasks/tools/install-kubectl-windows/
winget install -e --id Kubernetes.kubectl
kubectl version --client
IAM 역할 생성
VPC - 보안 - 보안 그룹
eks 클러스터 생성
생성한 보안그룹으로 지정하고 나머지는 기본값 세팅
=> 요 친구가 마스터 노드다 !!!!!!
워커 노드들을 연결해보자
aws eks update-kubeconfig --region ap-northeast-2 --name 1team-cluster
연결은 됐지만 자원을 찾지 못한다. 추가 설정이 필요하다.
원하는 크기만큼 생성된 워커 노드들을 볼 수 있다.
Deplyment로 워커노드 2개 만들자.
CMD 창에서 간단한 명령어를 통해 AWS에 워커 노드가 생긴다.
이러한 과정은 IAM 사용자 권한을 지정하고, 나와 마스터 노드 간 연결이 생겼기 때문에 가능한 것을 알고 있자.
워커 노드에 네트워크 설정을 해주자.
접근할 수 있는 외부 포트 30007을 설정해주었다.
service도 잘 실행됐다.
kubectl get pods -o wid 명령어를 통해 생성한 pods들의 IP와 NODE 정보를 확인할 수 있다.
떠 있는 ip 포트 아무거나 잡아서 EC2에서 검색
eks가 알아서 보안 그룹을 잡아준다.
내가 만든 보안 그룹(아래)와 eks가 방금 만들어준 보안 그룹(위)을 볼 수 있다.
eks가 방금 만들어준 보안 그룹에서 접속하고자하는 포트를 열어준다. 팀원들 것까지 모두 열어줬음 !
접속 테스트 할 때는 EC2 퍼블릭 DNS 주소 : 열어준 포트 로 접속하면 된다.
nginx가 두 대의 ec2에 잘 올라간 것을 확인할 수 있다 !
로드밸런서 적용
[ nginx-service-http-only.yml ]
Deploymeny 코드에서 type을 LoadBalancer로 바꾸고, nodePort를 삭제해줬다.
nodePort가 필요없는 이유는, LB가 연결된 ec2들 중에 적절한 곳으로 알아서 보내기 때문이다.
apiVersion: v1
kind: Service
metadata:
name: yujeong-nginx-service
spec:
type: LoadBalancer
ports:
- name: http # nodePort가 필요 없음
port: 80
targetPort: 80
selector:
app: yujeong-nginx # depl.yml의 spec.app과 동일
kubectl apply -f .\nginx-service-http-only.yml
각자의 LB가 생성됐고, pod와 연결되는 외부 포트도 각각 생겼다.
EC2 > 로드밸런서가 만들어졌다.
만들어지면서 보안그룹과 타겟그룹(target Port) 생성 등 로드밸런서 호출에 필요한 작업을 모두 해준다.
알아서 80포트를 연 보안 그룹을 하나 만들어서 배정해줬다. 타겟 그룹에 ec2 두 대도 넣어주는 것 같다.
로드밸런서 목록에서 kubectl get services 명령어를 쳤을 때 볼 수 있는 EXTERNAL-IP를 검색하면 해당 로드밸런서를 찾을 수 있는데, DNS 주소로 들어가보면 nginx를 만날 수 있다.
https도 걸어준다
apiVersion: v1
kind: Service
metadata:
name: yujeong-nginx-service
spec:
type: LoadBalancer
ports:
- name: http
port: 80
targetPort: 80
- name: https
port: 443
targetPort: 80
selector:
app: yujeong-nginx # depl.yml의 spec.app과 동일
로드 밸런서에도 HTTPS 인증서 적용을 해줘야 함 !!
HTTPS -> 인증서 선택 -> ROUTE 53에서 라우팅 대상 로드밸런서 지정 -> https://server.yujeong.shop으로 테스트
서비스 라우팅 기능 ! 인그래쓰 !!
각 LB마다 한 Service로, 각 Service는 pod로 라우팅된다.
각 pod에 item, order, member가 있을 때 총 3개의 LB를 만들고, 각각 연결해야한다.
하지만 이 방식은 자원 낭비가 심하고, 플랫폼 종속적(애저같은 다른 배포 서비스로 이전 어려움)이라는 문제가 있다.
=> 인그래쓰 !
Lb와 Service 사이에 위치하며, 요청이 들어오면 적절한 Service로 라우팅해준다.
격리되어있는 IP 타입으로 인해, 외부 포트가 생성되지 않기 때문에 클러스터 외부에서 접근이 안된다.
=> 인그래쓰 연결 !
API Gateway같은 친구다. 얘는 여러 서비스가 있으면 각 url(/item-service/, ..)에 맞게 보내준다.
로드밸런서 -> ingress -> service로 아키텍처 구성
deployment와 service를 한 번에 작성 !
-> pod 생성 및 네트워크 연결
[ nginx-depl-serv.yml ]
apiVersion: apps/v1
kind: Deployment
metadata:
name: yujeong-nginx-depl
spec:
replicas: 2
selector:
matchLabels:
app: yujeong-nginx
template:
metadata:
labels:
app: yujeong-nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: yujeong-nginx-service
spec:
# ClusterIP : 클러스터 내부에서만 접근 가능한 Service를 생성
# 외부에서 접근 가능하도록 ingress라는 중간 layer를 둠.
type: ClusterIP
ports:
- name: http
port: 80
targetPort: 80
selector:
app: yujeong-nginx
폴더 이동 후 서비스 조회
디플로이 섭섭할까봐 같이 조회해줌
인그래쓰 진짜 적용해보자구 !
- ingress controller 설치
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/aws/deploy.yaml
[ ingress.yml ]
# ingress-controller 설치 명령어
# kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/aws/deploy.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: yujeong-nginx-ingress
annotations:
kubernetes.io/ingress.class: nginx
spec:
rules:
- http:
paths:
- path: /yujeong/ #모든 url 요청을 nginx-service로 라우팅
pathType: Prefix
backend:
service:
name: yujeong-nginx-service
port:
number: 80
- ingress controller 설치 및 ingress yml 실행
ingress를 실행했을 뿐인데 로드밸런서가 자동으로 생성됐다.
그리고 로드밸런서에 ec2, 타겟 그룹 등을 모두 자동으로 설정됐다 !!!!!!
대단한 녀석이군
kubectl get ingress -A 명령어 혹은 describe 명령어로 얻을 수 있는 Address는 로드밸런서의 DNS 이름이다.
ADDRESS 주소가 같은걸로 봐서는 팀원들과 같은 인그래쓰, 로드 밸런서를 공유하고 있는 것 같다.
이제 ec2(pods)로 로드밸런싱이 되고 있는지 확인해보자.
내꺼는 1번 yujeong-nginx-depl-6646987b84-gvlxb, 2번 yujeong-nginx-depl-6646987b84-rwjmt 두 대가 있다.
1번의 로그를 확인해보자.
2번의 로그를 확인해보자.
GET 요청이 적절하게 분산된 로그를 확인할 수 있다.
로드밸런서가 RR으로 공평하게 잘 분배하고 있는 것 같다.
https 인증서 적용 ! ingress helm !!
기존의 방식처럼 AWS에서 인증서를 받아 적용하게 되면,
aws 의존성이 커지기 때문에(독립성이 낮아짐) ingress에 인증서를 받아두는 방식을 채택했다.
아키텍처를 설계할 때, 너무 한 플랫폼에 독립적이게 설계하면 안 된다.
다른 플랫폼으로 옮기더라도 쉽게 옮길 수 있는 설계가 좋은 설계이다.
아무튼 ingress 내부 인증서 기능을 도와주는 친구는 helm
- helm 설치
https://sseokseok.tistory.com/7
윈도우는 껐다 켜야됨
[ ingress_cert.yml ]
# https 인증서 적용 절차
# cert-manager 생성
# cert-manager 생성을 위한 cert-manager namespace 생성
# 1-1) kubectl create namespace cert-manager
# 1-2) Helm 설치
# 1-3) cert-manager를 설치하기 위한 Jetstack Helm 레포지토리 추가
# 명령어 : helm repo add jetstack https://charts.jetstack.io
# 1-4) helm repository 업데이트
# 명령어 : helm repo update
# 1-5) cert-manager 차트 설치
# 명령어 : helm install cert-manager jetstack/cert-manager --namespace cert-manager --version v1.5.0 --create-namespace --set installCRDs=true
# 2. ClusterIssuer 생성
# ClusterIssuer 자원이 있어야 인증서가 생성됨
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
# 인증서 서버 주소. 해당 서버의 리소스를 통해 인증서 발행
server: https://acme-v01.api.letsencrypt.org/directory
# 인증서 만료 또는 갱신 필요시 알람 email
email: vouobb@naver.com
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx
---
# 3. ClusterIssuer를 사용하여 Certificate 리소스 생성 : Certificate 리소스 생성시에 인증서 발급됨
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: nginx-yujeong-com-tls
namespace: default
spec:
secretName: nginx-yujeong-com-tls
duration: 2160h # 90day
renewBefore: 360h # 15day before
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
commonName: server.yujeong.shop
dnsNames:
- server.yujeong.shop
[ ingress.yml ]
# ingress-controller 설치 명령어
# kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/aws/deploy.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: yujeong-nginx-ingress
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /$1 #첫번째 prefix제거
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- hosts:
- "server.yujeong.shop"
secretName: nginx-yujeong-com-tls
rules:
- host: server.yujeong.shop
http:
paths:
- path: /yujeong/ #모든 url 요청을 nginx-service로 라우팅
pathType: Prefix
backend:
service:
name: yujeong-nginx-service
port:
number: 80
apply 명령어로 ingress, ingress_cert 모두 적용해주고 ~
내 AWS ROUTE53에 LB경로를 생성된 LB 경로로 수정해주면 ~
아래 두 줄의 코드로 인해 테스트할 때 url에 이름을 포함해서 테스트 해야한다.
로드 밸런서로 server.yujeong.shop/yujeong/ 요청 받음 -> ingress가 yujeong-nginx-service로 서비스 라우팅이 되는 것.
성공ㅋ
이제 Ordering 프로젝트로 실습
[ order-backend-depl-serv.yml ]
백엔드 파일의 이미지를 docker에 올리고, service로 포트를 80으로 잡아줬다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: yujeong-order-backend-depl
spec:
replicas: 2
selector:
matchLabels:
app: yujeong-order-backend
template:
metadata:
labels:
app: yujeong-order-backend
spec:
containers:
- name: order-backend
image: yujeongg22/order-backend:v1 # dockerhub에 push할 image명
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: yujeong-order-backend-service
spec:
type: ClusterIP
ports:
- name: http
port: 80
targetPort: 80
selector:
app: yujeong-order-backend
[ ingress.yml ]
# ingress-controller 설치 명령어
# kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/aws/deploy.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: yujeong-nginx-ingress
annotations:
kubernetes.io/ingress.class: nginx # ingress controller의 내부 router는 nginx로 구성
nginx.ingress.kubernetes.io/rewrite-target: /$1 #첫번째 prefix제거
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- hosts:
- "server.yujeong.shop"
secretName: nginx-yujeong-com-tls
rules:
- host: server.yujeong.shop
http:
paths:
- path: /yujeong/ #모든 url 요청을 nginx-service로 라우팅
pathType: Prefix
backend:
service:
name: yujeong-order-backend-service # order-backend-depl-serv.yml에서 생성되는 service로 라우팅
port:
number: 80
git action으로 push될 때마다 docker hub에 이미지 업로드 -> git action에서 EKS(마스터 노드)에 명령어 날림 : dockerhub에서 변경된 이미지를 pod에 다운받아, 변경사항을 적용 -> 하려고 했지만~
--> RDS 비밀번호 문제 때문에 바로 ECR에 이미지 업로드
ECR
aws에서 제공해주는 저장 공간. 여기에 이미지를 저장할거임
초간단 생성
개발자 -> push될 때마다 github action으로 새로운 이미지 ECR에 업로드 -> git action에서 EKS에게 변경된 이미지를 각 pod에 적용하라고 명령 내림, 이때 git action에서 EKS 접근할 수 있는 권한 설정 필요 -> EKS는 변경된 이미지를 찾아 알맞은 pod 내용을 변경
2024.03.08
- 배포 전, 이미지만 ECR에 업로드하는 실습
[ order-backend-deply.yml ]
[ Dockerfile ]
[ order-backend-depl-serv.yml ]
위에서 했던 것처럼 EKS 만들고, 노드 그룹 구성 해주고 ~
이때 클러스터 이름좀 신경써서 맞춰주고 ~
DB 정보를 감추고 싶다 !
쿠버네틱스 내부 저장소에 DB 정보를 저장한다 ⭐
k8s tls 인증서처럼 AWS 플랫폼에 독립적이기 위한 과정이기도 하다.
RDS 정보들을 DB_HOST, USERNAME, PASSWORD에 각각 넣어준다.
kubectl create secret generic db-infos --from-literal=DB_HOST=my-db.c56o88ycqdyj.us-east-1.rds.amazonaws.commy-db.c56o88ycqdyj.us-east-1.rds.amazonaws.com --from-literal=DB_USERNAME=admin --from-literal=DB_PASSWORD=gksghk12!
DB정보들은 자동으로 base64로 인코드.
설정해준 [db-infos]이름으로 get secret -o yaml 명령어를 통해 인코딩된 내용을 확인할 수 있다.
이제 찐 배포를 시작하지
order-backend-deply.yml에서주석처리 한 EKS kubectl apply 부분을 살려준다.
강사님 EKS -> 리소스 -> 보안 정보 -> db-infos -> DB정보들을 디코딩해서 DB Connection 생성
spring_roder_team1이름으로 mariaDB에 스키마 만들어주고
url: jdbc:mariadb://${DB_HOST}:3306/spring_order_team1
[ ingress.yml ]
로드밸런서 및 타겟그룹 자동 생성 및 설정
[ ingress_cert.yml ]
https를 위한 k8s 인증서 적용
아래오류가 발생했다.
그래서 두 줄을 추가해줘서 해결했다.
[ order-backend-depl-serv.yml ]
스프링 백엔드 서버로 설정한 포트인 8080으로 containerPort와 targetPort를 변경해주어야 한다.
모두 정상 적용되고 certificate도 무사히 적용됐다.
True가 떠야 된다...... 훈쓰 옆에서 False나서 고생 중이다ㅠㅠ. 맥북 왜구랭..
rollout restart 명령어를 통해 현재 올라와 있는 컨테이너(pod, ..)를 업데이트 해줌.
업데이트한 pods를 한 번 들여다 봐주고 ~
ingress 확인해서 붙은 로드밸런서 이름 확인해주고 ~
강사님 계정으로 로드 밸런서 찾아서
내 Route 53에서 로드밸런서 경로 잡아주기
접속 테스트
server.yujeong.shop/yujeong/items로 테스트 했을 때,
스프링 서버의 결과를 잘 가져오는 것을 확인했다 !!!!!!
'Back-End 공부 > AWS' 카테고리의 다른 글
Devops (0) | 2024.02.26 |
---|