기본적으로 택배 운송장에 택배서비스를 이용하는 고객의 주소와 택배 물품의 운송장 번호가 기재되어 있으며 일부 택배는 이름이 가려져 있으나 택배회사마다 가려진 이름의 위치가 달라 택배서비스 이용자의 이름도 추측이 가능할 수 있으며, 일부 운송장에는 택배서비스 이용자의 전화번호 일부가 기재되어 있다.
위와 같은 사례들과 택배 운송장 사진과 같이 택배 서비스를 이용하는 고객들은 개인정보 노출에 대한 문제를 제기하고 택배 운송장 폐기 방법에 대한 관심도 또한 증가하고 있다. 하지만 현재의 택배 운송장들은 일부 정보만 가려지고 모든 정보들이 완벽하게 가려지지는 않는다.
이와 같은 문제 인식을 통해 택배운송장의 개인정보 노출을 차단하기 위해 QR코드로 이루어진 택배운송장을 개발해 인가된 사용자인 고객, 택배 기사, 관리자에게만 QR코드를 인식할 수 있는 권한을 부여해서 개인 정보노출을 막을 수 있는 택배운송장을 구현하고 여러 택배회사들의 택배서비스를 일괄적으로 관리, 운용해 편의성을 증진하려고 한다.
이전에 사용해봤었던 AWS EKS를 사용하여 쿠버네티스로 서비스를 배포
백엔드 서버 파드에 PVC를 부착하여 스토리지 클래스에 의해 동적으로 PV를 생성해 EBS스토리지에 연결시킨다. EBS 스토리지는 직접 연결 스토리지에 액세스하는 단일 EC2 인스턴스용으로 설계되었기 때문에 백엔드 파드들은 모든 같은 노드에 위치시킬 필요가 있다.
따라서 affinity를 사용하여 백엔드 파드들이 모든 같은 노드에 있도록 설정할 것이다.
user와 deeliver 웹/앱의 도메인을 각각 생성하여 도메인 이름에 맞는 서비스로 라우팅 되도록 설계
백엔드의 경우 로드밸런싱을 통해 프론트엔드에서 받아온 트래픽을 이중화가 된 백엔드 서버로 트래픽을 분산시킨다.
장애 대비를 위해서 eks node그룹에 Auto Scaling Group을 지정하여 CPU 사용률 70%가 넘으면 Backend 서버를 자동 증설 및 삭제하도록 설정
백엔드의 경우 user, admin, deliver 의 3가지 서비스를 독립적으로 개발할 것이고 내부적으로 통신이 가능하도록 설계할 것이다.
DBMS의 데이터베이스도 기능별로 분리해서 구축한 후 필요한 내용을 공유할때 kafka를 사용하여 실시간 통신에 이용
고가용성을 위해 RDS 데이터베이스 사용, 인스턴스와 RDS는 보안을 위해 각각 프라이빗 서브넷에 배치
이후 Github Action을 이용하여 각 서비스의 코드를 자동으로 빌드하는 CI/CD 구축
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: exqress
region: ap-northeast-2
version: "1.24"
# AZ
availabilityZones: ["ap-northeast-2a", "ap-northeast-2b", "ap-northeast-2c"]
# IAM OIDC & Service Account
iam:
withOIDC: true
serviceAccounts:
- metadata:
name: aws-load-balancer-controller
namespace: kube-system
wellKnownPolicies:
awsLoadBalancerController: true
- metadata:
name: ebs-csi-controller-sa
namespace: kube-system
wellKnownPolicies:
ebsCSIController: true
- metadata:
name: cluster-autoscaler
namespace: kube-system
wellKnownPolicies:
autoScaler: true
# Managed Node Groups
managedNodeGroups:
# On-Demand Instance
- name: mynodes
instanceType: t3.medium
minSize: 2
desiredCapacity: 2
maxSize: 3
privateNetworking: true
#ssh:
#allow: true
#publicKeyPath: ./keypair/myeks.pub
availabilityZones: ["ap-northeast-2a", "ap-northeast-2b", "ap-northeast-2c"]
iam:
withAddonPolicies:
imageBuilder: true # AWS ECR에 대한 권한 추가
autoScaler: true
albIngress: true
cloudWatch: true
ebs: true
# CloudWatch Logging
cloudWatch:
clusterLogging:
enableTypes: ["*"]
apiVersion: apps/v1
kind: Deployment
metadata:
name: front-user-deploy
spec:
selector:
matchLabels:
tier: front-user
replicas: 1
template:
metadata:
labels:
tier: front-user
spec:
containers:
- name: front-user
image: <사용자 ID>.dkr.ecr.ap-northeast-2.amazonaws.com/front-user:27
ports:
- containerPort: 80
protocol: TCP
현재 적용되어 있는 이미지는 개발한 코드를 도커 이미지로 만들어 ECR에 저장시켜둔 파일을 가져온 것이다.
이미지를 만드는 방법은 나중에 적어두겠다.
apiVersion: v1
kind: Service
metadata:
name: front-user-svc
spec:
selector:
tier: front-user
type: NodePort
ports:
- port: 80
targetPort: 80
nodePort: 31113
apiVersion: apps/v1
kind: Deployment
metadata:
name: front-delivery-deploy
spec:
selector:
matchLabels:
tier: front-delivery
replicas: 1
template:
metadata:
labels:
tier: front-delivery
spec:
containers:
- name: front-delivery
image: <사용자 ID>.dkr.ecr.ap-northeast-2.amazonaws.com/front-delivery:53
ports:
- containerPort: 80
protocol: TCP
apiVersion: v1
kind: Service
metadata:
name: front-delivery-svc
spec:
selector:
tier: front-delivery
type: NodePort
ports:
- port: 80
targetPort: 80
nodePort: 31112
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: front-ing
annotations: # AWS에서 ALB로 사용할수 있게 함
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: instance
alb.ingress.kubernetes.io/certificate-arn: <exqress.com 용 인증값>, <exqress-deliver.com 용 인증값>
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
alb.ingress.kubernetes.io/ssl-redirect: "443"
spec:
rules:
- host: exqress-deliver.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: front-delivery-svc
port:
number: 80
- host: exqress.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: front-user-svc
port:
number: 80
각 호스트마다 인그레스를 설정해두어서 exqress.com은 front-user-svc로 포워딩 시켜두었고 exqress-deliver.com은 front-deliver-svc로 포워딩하도록 설정해두었다.
또한 이전에 https 리다이렉트를 진행할 때 tls-redirect를 사용했었는데 이 방식으로 진행했을때는 웹에서 접속했을 땐 https가 제대로 적용이 되었다. 하지만 우리 프로젝트는 PWA 이기때문에 핸드폰으로 모바일 접속을 했을 경우에도 https로 리다이렉트가 되어야 하지만 적용되지 않았다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: back-user-deploy
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 0
selector:
matchLabels:
tier: back-user
replicas: 1
template:
metadata:
labels:
tier: back-user
spec:
containers:
- name: back-user
image: <사용자 ID>.dkr.ecr.ap-northeast-2.amazonaws.com/back-user:26
ports:
- containerPort: 4002
protocol: TCP
volumeMounts:
- name: ebs-volume
mountPath: /data
resources:
requests:
cpu: 200m
memory: 200M
volumes:
- name: ebs-volume
persistentVolumeClaim:
claimName: ebs-pvc
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: tier
operator: In
values:
- back-delivery
topologyKey: "kubernetes.io/hostname"
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: tier
operator: In
values:
- back-user
topologyKey: "kubernetes.io/hostname"
apiVersion: v1
kind: Service
metadata:
name: back-user-svc
spec:
selector:
tier: back-user
type: NodePort
ports:
- port: 80
targetPort: 4002
nodePort: 31118
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: back-user-ing
annotations: # AWS에서 ALB로 사용할수 있게 함
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: instance
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: back-user-svc
port:
number: 80
apiVersion: apps/v1
kind: Deployment
metadata:
name: back-delivery-deploy
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 0
selector:
matchLabels:
tier: back-delivery
replicas: 1
template:
metadata:
labels:
tier: back-delivery
spec:
containers:
- name: back-delivery
image: <사용자 ID>.dkr.ecr.ap-northeast-2.amazonaws.com/back-delivery:34
ports:
- containerPort: 4001
protocol: TCP
volumeMounts:
- name: ebs-volume
mountPath: /data
resources:
requests:
cpu: 200m
memory: 200M
volumes:
- name: ebs-volume
persistentVolumeClaim:
claimName: ebs-pvc
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: tier
operator: In
values:
- back-delivery
topologyKey: "kubernetes.io/hostname"
apiVersion: v1
kind: Service
metadata:
name: back-delivery-svc
spec:
selector:
tier: back-delivery
type: NodePort
ports:
- port: 80
targetPort: 4001
nodePort: 31117
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: back-delivery-ing
annotations: # AWS에서 ALB로 사용할수 있게 함
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: instance
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: back-delivery-svc
port:
number: 80
apiVersion: apps/v1
kind: Deployment
metadata:
name: back-admin-deploy
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 0
selector:
matchLabels:
tier: back-admin
replicas: 1
template:
metadata:
labels:
tier: back-admin
spec:
containers:
- name: back-admin
image: <사용자 ID>.dkr.ecr.ap-northeast-2.amazonaws.com/back-admin:4
ports:
- containerPort: 8000
protocol: TCP
volumeMounts:
- name: ebs-volume
mountPath: /data
resources:
requests:
cpu: 200m
memory: 200M
volumes:
- name: ebs-volume
persistentVolumeClaim:
claimName: ebs-pvc
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: tier
operator: In
values:
- back-delivery
topologyKey: "kubernetes.io/hostname"
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: tier
operator: In
values:
- back-admin
topologyKey: "kubernetes.io/hostname"
apiVersion: v1
kind: Service
metadata:
name: back-admin-svc
spec:
selector:
tier: back-admin
type: NodePort
ports:
- port: 80
targetPort: 8000
nodePort: 31115
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: back-admin-ing
annotations: # AWS에서 ALB로 사용할수 있게 함
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: instance
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: back-admin-svc
port:
number: 80
온프레미스에서 사용했던 내용들을 AWS에서도 똑같이 사용할 수 있도록 구성하기 위해
Amazon EKS의 애플리케이션 로드 밸런싱, EBS CSI Provisioner, Metric-Server 설치, Cluster AutoscalerController, CloudWatch & Container Insights 의 애드온을 설치해준다. 이를 안해주면 ingress 나 ebs 볼륨등을 사용할 수 없기에 다음 내용을 참조하여 설치해주면 된다. 📢 eks 애드온 설치
원래는 efs 스토리지를 사용하여 여러 가용영역에 거쳐 활용하려고 하였는데 우리가 하는 프로젝트에서 딱히 efs 스토리지를 사용하는 이점이 없었다. 그래서 ebs 스토리지를 사용하기로 결정하였는데 이는 하나의 노드에서 사용이 가능하기 때문에 위에서 파드들의 위치를 모두 한곳으로 모아두었다.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: gp3
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Delete
parameters:
type: gp3
csi.storage.k8s.io/fstype: ext4
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ebs-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: gp3
만들어둔 yaml파일들을 git 저장소에 저장시키고 이 저장소의 url를 argocd와 연결시켜 자동으로 쿠버네티스 manifest파일들을 배포하도록 설정할 것이다.
# Argo CD 설치
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# 로드밸런서로 바꿈
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'
# 패스워드 찾기
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo
argocd에 접속하여 비밀번호는 내가 원하는 값으로 변경하고 새로운 app을 만든다.
앱생성시에 default 위치에 만들고 원격 저장소의 url로 쿠버네티스 manifest 파일들이 저장되어있는 git 저장소의 url을 입력하고 밑의 값들을 main / . 으로 바꿔준다. 그후 생성하면 자동으로 서비스들이 배포되는 것을 볼 수 있다.