인그레스
- 외부에서 접속가능한 URL 사용
- 트래픽 로드밸런싱
- SSL 인증서 처리
- 도메인 기반 가상 호스팅 제공
인그레스는 위와 같은 기능들에 대해 정의해둔 규칙들을 정의해둔 리소스이고,
이를 동작하기 위해서는 인그레스 컨트롤러가 필요하다.
이 전글에서는 Depl (pod) 와, service를 따로 해줬지만 여기서는 한 yml로 만든다.
Ingress 중간에서 라우팅을 해주는 역할이다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: boseok-nginx-depl
spec:
replicas: 2
selector:
matchLabels:
app: boseok-nginx
template:
metadata:
labels: # nodeport와 매핑
app: boseok-nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: boseok-nginx-service
spec:
# ClustreIP는 클러스터 내부에서만 접근가능한 service를 생성
type: ClusterIP
ports:
- name: http
port: 80
targetPort: 80
selector:
app: boseok-nginx
apply 해주면 두 개 pods와 service가 생성된다.
하지만 라우팅이 끊겨 있고 격리되어 있는 상태이다.
내부포트는 80이지만 외부포트가 없다. Service에 접근이 안돼서 라우팅이안된다.
해결 방법은 Ingress를 두어야한다.
1. controller 먼저 적용해준다.
직접적으로 LoadBalancer를 이용하는 것보다, 하나의 Ingress Controller를 통해 여러 서비스로 트래픽을 분산할 수 있으므로, 여러 LoadBalancer 서비스를 생성하는 것보다 경제적이다.
# ingress controller 설치 명령어
# kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/aws/deploy.yaml
2. ingress 적용
# 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: boseok-nginx-ingress
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /$1 # 첫번째 prefix제거
spec:
rules:
- http:
paths:
- path: /boseok/ # 모든 url 요청을 nginx-service로 라우팅 한다.
pathType: Prefix
backend:
service:
name: boseok-nginx-service
port:
number: 80
내 이름으로 접속하면 웰컴이 뜬다.
나 말고 내 팀원들도 가능하다.
로드밸런스에서 ingress controller로 넘겨줘 controller에서 라우팅을 해준다.
https 설정하기 ingress.yml
1. cert-manager 설정
2. ClusterIssuer 생성,
3. certification 리소스 생성
- 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: boseok-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.songboseok.shop"
secretName: nginx-songboseok-com-tls
rules:
- host: server.songboseok.shop
http:
paths:
- path: /boseok/ # 모든 url 요청을 nginx-service로 라우팅 한다.
pathType: Prefix
backend:
service:
name: boseok-nginx-service
port:
number: 80
-ingress.cert.yml
Https로도 접속 할 수 있게 만들기위한 것이다.
# https 인증서 적용 절차
# 1. cert-manager 생성
# cert-manager 생성을 위한 cert-manager namespace 생성
# 1-1) kubectl create namespace cert-manager
# 1-2) Helm 설치
# brew update
# brew install Helm
# 1-3) cert-manager 를 설치하기 위한 Jetstack Helm 레포지토리 추가
# helm repo add jetstack https://charts.jetstack.io
# 1-4) Helm repositroy 업데이트
# 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 생성
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
# 인증서 서버 주소, 해당 서버에서 인증서 발행
server: https://acme-v02.api.letsencrypt.org/directory
# 인증서 만료 또는 갱신 필요시 알람이 갈 email 설정
email: fa7271@naver.com
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx
---
# 3. ClussterIssue 를 사용하여 Certificate 리소스 생성하기. : Certificate 리소스 생성시에 인증서 발급
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: nginx-boseok-com-tls
namespace: default
spec:
secretName: nginx-boseok-com-tls
duration: 2160h # 90d
renewBefore: 360h
issureRef:
name: letsencrypt-prod
kind: ClusterIssuer
commonName: server.songboseok.shop
dnsNames:
- server.songboseok.shop
router53에 등록하면
server.songboseok.shop/boseok/ 에 들어가도 정상적으로 홈페이지가 나온다.
ordering System k8s 무중단 배포
개발자 -> github,git action 을 해준다. eks를 통해 명령어를 실행해야하므로 git action에서 eks에 접근할 수 있게 권한을 열어 줘야한다.
시스템에 host 정보 저장해놓고 가져다 쓴다.
-> 밖으로 노출이 안된다.
kubectl create secret generic db-infos --from-literal=DB_HOST="db이름" --from-literal=DB_USERNAME=admin --from-literal=DB_PASSWORD=gksghk12!
kubectl로 조회해 보면 비밀번호가 들어가게 된다.
k8s secret에 db정보가 들어있어 거기서 뽑아서 바인딩 해준다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: boseok-order-backend-depl
spec:
replicas: 2
selector:
matchLabels:
app: boseok-order-backend
template:
metadata:
labels: # nodeport와 매핑
app: boseok-order-backend
spec:
containers:
- name: order-backend
image: 346903264902.dkr.ecr.ap-northeast-2.amazonaws.com/team6-order:latest
ports:
- containerPort: 80
resources:
# container가 사용할 수 있는 리소스의 최대치
limits:
cpu: "1"
memory: "500Mi"
# container가 시작될때 보장받아야 하는 최소 자원
requests:
cpu: "0.5"
memory: "250Mi"
# 런타임이라 db주입, github에 sercrets key에서 넣어주는게 아니라
# 비밀번호를 내장 저장해서 사용한다.
env:
- name: DB_HOST
valueFrom:
secretKeyRef:
name: db-infos
key: DB_HOST
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: db-infos
key: DB_USERNAME
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-infos
key: DB_PASSWORD
---
apiVersion: v1
kind: Service
metadata:
name: boseok-order-backend-service
spec:
# ClustreIP는 클러스터 내부에서만 접근가능한 service를 생성
type: ClusterIP
ports:
- name: http
port: 80
targetPort: 80
selector:
app: boseok-order-backend
container 안에 image 에는
docker images에 있는 repository를 넣어야한다. 근데 지금 private로 되어 있지만
ECR을 사용해서 배포를 해보려고한다. hub에서 public으로 바꾸면 설정을 여러가지 해줘야하고, 비밀번호들이 있기 때문에 불안하고 private로 하면 설정하는데 번거롭기 때문에 더 간편하고 무조건 private인
ECR을 사용한다.
ingress.yml 에는 service: name 부분만 바꿔주면 된다.
ingress-controller 에서 원래는 nginx-service를 바라보고 있었는데 그것을 order-backend-service로 바꿔주는것이다.
즉 A->B 로 가는것을 A-> C 로 바꿔주는 것이다.
1. ingress apply
kubectl apply -f ingress.yml
2. DockerHub 대신 ECR
레포 생성해주고 DNS를 images에 넣어주면 된다.
권한이 있어야지 땡겨올 수 있기 때문에 권한 관련 설정을 해줘야한다.
name: deploy order backend-system
on:
push:
branches:
- main
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: checkout github
uses: actions/checkout@v2
- name: install kubectl
uses: azure/setup-kubectl@v3
with:
version: "v1.25.9"
id: install
- name: configure aws
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{secrets.AWS_ACCESS_KEY_ID}}
aws-secret-access-key: ${{secrets.AWS_SECRETE_ACCESS_KEY}}
aws-region: ap-northeast-2
- name: update cluster infomation
run: aws eks update-kubeconfig --name 6team-cluster --region ap-northeast-2
- name: login to ECR
id: login-cer
uses: aws-actions/amazon-ecr-login@v1
- name: build and push docker image to ecr
env:
REGISTRY: 346903264902.dkr.ecr.ap-northeast-2.amazonaws.com
REPOSITORY: team6-order
IMAGE_TAG: latest
run: |
docker build \
-t $REGISTRY/$REPOSITORY:$IMAGE_TAG \
-f ./ordering/Dockerfile ./ordering
docker push $REGISTRY/$REPOSITORY:$IMAGE_TAG
AWS 에 접근을 해서 클러스터에 들어가고. ECR에 로그인해서 이미지를 업로드한다.
기존에 도커 허브에 이미지를 올리는 것을 ecr로 올리는 것이다.
마지막에 run할때 도커이미지를 ecr에 올리는것이다.
DB도 yml에서 받아준다.
spring:
security:
user:
name: user
password: 1234
datasource:
driver-class-name: org.mariadb.jdbc.Driver
url: jdbc:mariadb://%{DB_HOST}:3306/spring_order
username: ${DB_USERNAME}
password: ${DB_PASSWORD}
jpa:
database: mysql
database-platform: org.hibernate.dialect.MariaDBDialect
generate-ddl: true
hibernate:
ddl-auto: update
show-sql: true
jwt:
expiration: 30 # 30?
secretKey: mysecret # ??? ?
돌리면 결과.
git action script => docker. build 할때 build.arg -> docker파일에 전달 ,
arg 통해서 전달 받고 빌드 => run을 할때 env를통해 spring에서 yml에 전달한다.
DB까지 추가하고 전달해주면 다시 add 해주면 성공한다.
내 서버에 등록을 하기 위해
router 53에 로드밸런서에 나온 Dname을 추가해줬다
그럼 성공
다음엔 msa구조를 한 번 해보도록 하겠다.
msa 구조 ingress랑 ,certificate는 1개씩필요하고,
serve랑 service는 다 필요
댓글