์ค์
aws ์ค์
aws configureaws cli๊ฐ ์๋ค๋ฉด ๋ค์ด๋ก๋
Access Key ID, Secret Access Key ์
๋ ฅ์์ EKS ์ค์ KEY ๋ฃ๊ธฐ
๋ฃ๊ณ ๋๋ฉด ~/.aws/credentials ํ์ผ์ ์์ ๊ฐ์ด ๋ค์ด๊ฐ๊ฒ์ ๋ณผ ์ ์์.
ย
EKS context ๋ง๋ค๊ธฐ
aws eks --region ap-northeast-2 update-kubeconfig --name DATEPOP๊ฒฐ๊ณผ โฌ
Added new context arn:aws:eks:ap-northeast-2:<APPID>:cluster/<CLUSTER_NAME> to /Users/<USERNAME>/.kube/config
ย
service namespace ์กฐํ
kubectl ๋ช
๋ น์ด๊ฐ ์๋ค๋ฉด kubernetes ๋ค์ด๋ก๋
kubectl get services --all-namespaces
ย
ย
ย
Kubernetes ์ฐ๊ฒฐํ๋ ๋ฐฉ๋ฒ๋ค
ย
/Users/<USERNAME>/.kube/config ์ฌ๊ธฐ์ ํ์ผ์ด ์๋ค๋ฉด ์๋ ๋ฐฉ์์ผ๋ก ํ ๋ ์๋์ผ๋ก ์ค์ ํ์ผ ์ฝ์ด์ ํด๋ฌ์คํฐ ์ด๋ฆผ.
- Kubernetes Dashboard
- Lens
- VS Code Extensions
ย
ย
ย
ย
์๋ก์ด ์ปจํ ์ด๋ ์ค์ ์์ฑํ๊ธฐ
Deployment
- ํ์) ๋ฐฐํฌ๋ฅผ ์ํด ๊ฐ์ฅ ํ์ํ ํ์ผ
- ์ฃผ์* Secret.yaml ํ์ผ์ ์๋ ์ํฌ๋ฆฟ๊ฐ๊ณผ ์ฌ๊ธฐ env์ ์๋ ๋ณ์๋ช ๊ณผ 1๋1 ๋์๋๊ฒ ๋ชจ๋ ๋ฃ์ด์ค์ผํ๋ค.
ย
์๋์์ <DEPLOYMENT_NAME>๊ณผ <NAMESPACE>๋ฅผ ์๋ง๊ฒ ๋ฃ๋๋ค. (์๋ ์ค์ yaml์์ ๊ณ์ ๋์ผ)
ํ์ผ์์ ์ํฌ๋ฆฟํค๋ฅผ ๊ฐ์ ธ์ ๋ฃ๋ ๊ฒฝ์ฐ๋ Volume ๋ง์ดํธ๋ฅผ ํด์ผํ๊ณ ๊ทธ๊ฒ ์๋๋ฉด ํ์๋ ์๋ค.
ํด๋น ๋ณผ๋ฅจ๊ด๋ จ๋ ํ์ ์์ ์ ์๋ ๋ถ๋ถ์ ํ์์ผ๋ก ํ์.
apiVersion: apps/v1 kind: Deployment metadata: name: <DEPLOYMENT_NAME> namespace: <NAMESPACE> labels: app: <DEPLOYMENT_NAME> spec: replicas: 3 revisionHistoryLimit: 2 selector: matchLabels: app: <DEPLOYMENT_NAME> template: metadata: labels: app: <DEPLOYMENT_NAME> spec: volumes: - name: <VOLUME_NAME> secret: secretName: gcp defaultMode: 420 containers: - name: <DEPLOYMENT_NAME> image: ports: - name: inbound containerPort: 8000 protocol: TCP env: - name: DEBUG valueFrom: secretKeyRef: name: <DEPLOYMENT_NAME> key: DEBUG - name: GOOGLE_APPLICATION_CREDENTIALS value: <VOLUME_FOLDER_PATH>/<FILE_NAME> volumeMounts: - name: <VOLUME_NAME> readOnly: true mountPath: <VOLUME_FOLDER_PATH>
ย
Deployment์์์ ๊ถ๊ณ ์ฌํญ
- readiness ์ค์ ํ๊ธฐ (/ping ์ค์ )
Service
- ํ์
- Web ๊ธฐ๋ฐ์ ๊ฒฝ์ฐ ๋๋ถ๋ถ TCP์ port์ targetPort๋ฅผ ์ค์ ํ๋ฉด ๋
- ์น์ด๋ฉด ๋๋ถ๋ถ port 80์ด๋ ๋์ปค์์ ์ค์ ํ ๋ด๋ถ ํฌํธ๋ฒํธ๋ง targetPort์ ๋ฃ์ผ๋ฉด ๋๋ค.
apiVersion: v1 kind: Service metadata: name: <DEPLOYMENT_NAME> namespace: <NAMESPACE> spec: ports: - protocol: TCP name: inbound port: 80 targetPort: 8000 selector: app: <DEPLOYMENT_NAME>
ย
Secret
- ํ์ ์๋. ํ๊ฒฝ ๋ณ์๊ฐ ์๋ ๊ฒฝ์ฐ์๋ง ํ์ํจ.
- Deployment.yaml env ์ํฌ๋ฆฟ๊ณผ ์ฌ๊ธฐ data ์๋ ์ํฌ๋ฆฟ์ ๋์ผํ๊ฒ
apiVersion: v1 kind: Secret type: Opaque metadata: name: <DEPLOYMENT_NAME> namespace: <NAMESPACE> data: DEBUG: SECRET_VALUE SECRET_KEY: SECRET_VALUE
ย
ย
์ ์ปจํ ์ด๋ ๋์ฐ๊ธฐ
๊ธฐ๋ณธ ๋ช ๋ น์ด
kubectl apply -f <YAML_FILE>
ย
์ ์ฉ ์์
์์๋ ํฌ๊ฒ ์๊ด์์ง๋ง ๋ฐฐํฌํ์๋ง์ ๋ฐ๋ก ๋ณด๊ณ ์ถ๋ค๋ฉด
Secret โ Service โ Deployment
or
Service โ Secret โ Deployment ๋ก ํ๋ฉด ๋๋ค.
ย
๊ทธ๋ผ Deployment๊ฐ ๋จ๋ ์์ ์ ํ์ํ Secret์ด ์ ์ฉ๋์ด ์๊ธฐ ๋๋ฌธ์ ๋ฐ๋ก ๋ฌ๋ค.
ย
Deployment๊น์ง ์ ์ฉํ๋ค๋ฉด Pod์ ๋ค์ด๊ฐ์ ์ ์์ ์ผ๋ก ์ด๋ ธ๋์ง ํ์ธํ๋ค.
ย
Deployment ์ ์ฉํ ๋ image ๊ฐ์ ์ด๋ฏธ์ง ์ฃผ์๋ฅผ ๊ผญ ๋ฃ์ด์ค์ผํ๋ค!
ย
+) Lens์์ ํธ์งํ๊ณ ์ ์ฅํ๋ฉด ๊ทธ ์๊ฐ๋ kubectl apply -f ๊ฐ ๋๋๊ฒ์ด๋ค.
ย
ย
Ingress ์ค์
ย
์์ ๊ฐ์ดํ๋๋ผ๋ Pod๋ง ์ ์์ ์ผ๋ก ๋ฌ๊ฑฐ๊ณ ์ค์ ๋ก URL์ ํตํด ์ ๊ทผ ํ ์๋ ์๋ค.
ย
์ด ์ค์ ์ 3rd party traefik ingress๋ฅผ ํตํด ์งํํ๋๋ฐ ์๋์ ๊ฐ์ด yaml ๋ง๋ค๊ณ ์ ์ฉํ๋ฉด ๋๋ค.
ย
apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: <TRAEFIK_NAME> namespace: <TRAEFIK_NAMESPACE> spec: entryPoints: - web routes: - match: Host(`api.datepop.co.kr`) && PathPrefix(`/api/v1/test`) kind: Rule services: - namespace: <NAMESPACE> name: <DEPLOYMENT_NAME> port: 80
์ฌ๊ธฐ์ ์ฃผ์ํ ์ ์
- metadata์ ์๋ name๊ณผ namespace๋ traefik์ธ๊ฒ. ์ด๋ฏธ์ง ๋ฐฐํฌํ ๊ทธ name๊ณผ namespace์๋ ๋ค๋ฅด๋ค! ๊ทธ๋์ ๋ณ์๋ช ๋ ํ์ผ๋ด์์ ๋ค๋ฅด๊ฒ ํ์.
- ๊ฐ์ TRAEFIK_NAME์ผ๋ก kubectl apply -f ๋ฅผ ํ๋ฉด ๊ธฐ์กด routes ์์ฑํ๊ฑด ์๋ก์ด routes๋ก ๋ฎ์ด์ฐ๊ธฐ๊ฐ ๋๋ค.
- ์ด๋ฐ ์ค์ํ๋ ์ผ์ด์ค
- ๊ธฐ์กด ๋ด์ฉ์ ๋ณต๋ถํ๊ณ name์ ์์ ํ์ง ์๊ณ ๋ค๋ฅธ routing rules ๋ฐฐํฌ
(๋ณธ์ธ ๊ฒฝํ)
ย
traefik์์ ์ค์ ํ๋๊ฒ์ Host์ PathPrefix๋ฅผ ํตํด ์ด๋ค ๋๋ฉ์ธ์ ์ด๋ค path์ผ๋ ์ด๋ค namespace์ name์ผ๋ก ์ด๋ํ๋์ง๋ฅผ ์ค์ ํ ์ ์๋ค.
*.datepop.co.kr์ผ๋ก ๋ค ๊ฐ๋ฅํ ์ด์ ๋ AWS Route53์์ ์ค์ ํ๊ธฐ ๋๋ฌธ
ย
Ingress๋ฅผ ์ค์ ํ๋ ์ผ์ด์ค
- ์๋ก์ด ์๋น์ค ์ถ์
- ์๋ฅผ๋ค์ด ๋ธ๋ก๊ทธ ์ฌ์ดํธ๋ฅผ ๋ฐฐํฌํ๋ค๋ฉด blog.datepop.co.kr์ ์ฌ๋ฆฌ๊ณ ์ถ์ ๊ฒ
- ๊ทธ๋ผ ingress์ Host๋ฅผ blog.datepop.co.kr์ ๋ฃ๊ณ namespace, name์ ์ ๊ฐ๋ฅดํค๊ฒ ์ค์ ํ๋ฉด ๋
- ๊ธฐ์กด ์๋น์ค ๋ฎ์ด์ฐ๊ธฐ
- A๋ผ๋ Deployment์ B๋ผ๋ Deployment๊ฐ ์๋๋ฐ A๋ ๊ธฐ์กด ์๋น์ค๊ณ B๋ ์๋ก์ด ๊ฒ
- ๋์ผํ API์ด์ง๋ง ๋ ๊ฐ์ ํด์ B๋ฅผ ๋ง๋ค์๋ค๋ฉด API spec์ ๋์ผํ๋ B๋ก ๋ณ๊ฒฝํด๋ ๋๋ค.
- ๊ทธ๋ฐ ๊ฒฝ์ฐ ๋์ผํ route์ name, namespace๋ง A โ B๋ก ์์ ํ๋ฉด ๋๋ค.
ย
ย
์ฝ๋์์ Kubernetes๋ก ๋ฐฐํฌ
1๋จ๊ณ. ๋์ปค ๋น๋
๋์ปค ํ์ผ ๋ง๋ค๊ณ ๋น๋ํ๋ ์์ธํ ๊ณผ์ ์ ์ฌ๊ธฐ์ ์๋ต.
docker build -t <name> .
ย
2๋จ๊ณ. ๋์ปค ์ ๋ก๋
์์ ๋น๋ํ ์ด๋ฆ์ผ๋ก AWS ECR์ ์
๋ก๋๋ฅผ ํด์ผํ๋ค.
ย
์ฌ๊ธฐ์ ์ฃผ์ํ ์ ์ AWS ECR์ ๋ค์ด๊ฐ์ ๋ฏธ๋ฆฌ private์ผ๋ก ๋น๋ํ ์ด๋ฆ์ ๋ํ ๋ ํฌ์งํ ๋ฆฌ๋ฅผ ์์ฑํด์ผํ๋ค. (๊ทธ๋ฅ ์
๋ก๋ ์๋ํ๋ฉด ์๋ก์ด๊ฒ์ด๋ฉด ์๋์ผ๋ก ์์์ ๋ฐ์๋ ์ง ์์์ผ๋ ๋น์ด์๋ ๊ฒ์ ๋ฏธ๋ฆฌ ์์ฑํด๋์ผํ๋ค)
ย
์
๋ก๋ํ๊ธฐ์ ์ ECR์ ๋ก๊ทธ์ธ์ด ๋์ด ์์ด์ผํ๋ค. ์๋์์ AWS_DEFAULT_REGION ์ด๊ฒ๋ง ๋ฐ๊ฟ์ฃผ๋ฉด ๋๋ค.
aws ecr get-login-password | docker login --username AWS --password-stdin "$(aws sts get-caller-identity --query Account --output text).dkr.ecr.<AWS_DEFAULT_REGION>.amazonaws.com"
ย
๋น๋ํ ๋์ปค์ ํ๊ทธ ๋ถ์ด๊ธฐ
docker tag <IMAGE_NAME>:<VERSION> <AWS_ACCOUNT_ID>.dkr.ecr.<AWS_DEFAULT_REGION>.amazonaws.com/<IMAGE_NAME>
ย
๋ง์ง๋ง์ผ๋ก ์ฌ๋ฆฌ๊ธฐ
docker push <AWS_ACCOUNT_ID>.dkr.ecr.<AWS_DEFAULT_REGION>.amazonaws.com/<IMAGE_NAME>
ย
3๋จ๊ณ. ์ฟ ๋ฒ๋คํฐ์ค ์ ์ฉ
2๋จ๊ณ์์ ECR์ ์ฌ๋ฆฌ๋ฉด ECR์ ๊ทธ ์ด๋ฏธ์ง์ ๋ํ ์ฃผ์๊ฐ ์๊ธด๋ค.
ย
๊ทธ ์ฃผ์๋ฅผ Deployment YAMLํ์ผ ๋ด image์ ๊ฐ์ผ๋ก ๋ฃ๊ณ ์ ์ฅํ๋ฉด ๋๋ค.
ย
ย
์ ๊ณผ์ ์ ์๋ํ๋ 1, 2, 3๋จ๊ณ๋ฅผ CI/CD ํด์ ํตํด ๊ตฌํํด์ ์งํํ๋ฉด ๋๋ค.
ย