Kubernetes
- ์ฟ ๋ฒ๋คํฐ์ค๋ docker-compose์ ๋น์ทํ ์ญํ ์ ์ํํฉ๋๋ค(์๋ฒ์ ์๋์ฌ์คํ, ์๊ฒฉ ํธ๋ค๋ง, etc.). ์ฐจ์ด์ ์ docker-compose๋ single host ํ๊ฒฝ์์ ์ํ๋๋ฉฐ, ์ฟ ๋ฒ๋คํฐ์ค๋ multi-host ํ๊ฒฝ์์ ์ํ๋ฉ๋๋ค.
1. Components
Cluster
:Controll Plane
๊ณผ 1๊ฐ ์ด์์Worker Node
์ ์งํฉ์ ๋๋ค.Controll Plane
:Master Node
๋ก๋ ๋ถ๋ฆฝ๋๋ค. ์ด ๋ ธ๋๋Worker Node
๋ค๊ณผPod
๋ค์ ๊ด๋ฆฌํ๋ ์ญํ ์ ์ํํฉ๋๋ค.API server
: ์ฟ ๋ฒ๋คํฐ์ค๋ฅผ RESTAPI๋ฅผ ํตํด ๊ด๋ฆฌํ ์ ์๊ฒ ๋ง๋ค์ด์ฃผ๋ ์๋ฒ์ ๋๋ค.Scheduler
:Worker Node
๋ด๋ถPod
๋ค์ ์ค์ผ์ฅด๋ง์ ๋ด๋นํฉ๋๋ค.Controll Manager
: ์ค์ง์ ์ผ๋กWorker Node
,Pod
๋ฅผ ๊ด๋ฆฌํ๋ฉฐ ํ์ฌ ์ํ๋ฅผ ์ฒดํฌํฉ๋๋ค.etcd
(key-value store) : ์ฌ๋ฌ๊ฐ์ง configuration ํ์ผ๋ค์ด ์ ์ฅ๋์ด์๋ ๊ณณ์ ๋๋ค.
Worker Node
: ์๋น์ค๋ฅผ ์ํํ๋Pod
๊ฐ ์คํ๋๋ ๋ ธ๋์ ๋๋ค.kubelet
:Master Node
์Worker Node
์ฌ์ด ๋งค๊ฐ์ฒด์ด๋ฉฐ, ํ๋ ๋ณ ํฌ์ค์ฒดํฌ๋ฅผ ์ํํฉ๋๋ค.kube-proxy
: IP ๋ณํ๊ณผ ๋ผ์ฐํ ์ ๋ด๋นํฉ๋๋ค. ์ฌ๊ธฐ์ load-balancing์ ์ค์ ํ ์ ์์ต๋๋ค.Container runtime
:Container Registry
๋ก๋ถํฐ ๋์ปค ์ด๋ฏธ์ง๋ฅผ ๊ฐ์ ธ์ค๊ณ , ์ปจํ ์ด๋๋ฅผ ์์/์ข ๋ฃํ ์ ์์ต๋๋ค.Container Registry
:Docker Hub
,Amazon Elastic Container Registry(ECR)
,Google Container Registry(GCR)
2. Types of yaml used in Kubernetes
์ค์ง์ ์ผ๋ก ์๋ฒ๋ค์ Pod
๋ผ๋ ๋จ์๋ก ์๋น์ค๋ฉ๋๋ค. ์ด๋ฌํ Pod๋ฅผ ๋ง๋ค๊ธฐ ์ํด์๋ ๋ค์ํ ํ์
์ configuration ํ์ผ๋ค์ด ํ์ํฉ๋๋ค. ์ด๋ฌํ ํ์ผ ํ์์ ์ฃผ๋ก yaml์ด๋ผ๋ ํ์์ ์ฌ์ฉํ๊ฒ ๋๋๋ฐ์. Deployment
, Service
, Ingress
, ClusterIssuer
, ๋ฑ์ ํ์
์ด ์กด์ฌํฉ๋๋ค. ์ด์ ๋ถํฐ ๊ฐ๊ฐ์ yamlํ์ผ๋ค์ ์์๋ณด๊ฒ ์ต๋๋ค.
2-1. Deployment
Deployment
๋ Pod์ ์ฌ์ฉ๋๋ ๋์ปค ์ด๋ฏธ์ง๋ฅผ ๋ถ๋ฌ์์, ๋ช๊ฐ์ ๋์ผํ Pod
๋ฅผ ์์ฑํ ๊ฒ์ธ์ง ์ค์ ํ๋ ํ์ผ์
๋๋ค. ์๋๋ ๋ฑ
ํน ์๋ฒ์ ์ฌ์ฉํ deployment.yaml ํ์ผ์
๋๋ค.
apiVersion: apps/v1
kind: Deployment
metadata:
name: golang-backend-api-deployment
spec:
replicas: 2
selector:
matchLabels:
app: golang-backend-api
template:
metadata:
labels:
app: golang-backend-api
spec:
containers:
- name: golang-backend-api
image: ghkdqhrbals/simplebank:latest
imagePullPolicy: Always
ports:
- containerPort: 8080
env:
- name: DB_SOURCE
value: postgresql://root:secret@postgres:5432/simple_bank?sslmode=disable
- apiVersion : ์ฟ ๋ฒ๋คํฐ์ค๊ฐ ์ ๊ณตํ๋ ๊ธฐ๋ฅ๋ค์ ๋ฒ์ ์ ๋๋ค. ์ ๋ง ๋ค์ํ ๋ฒ์ ์ด ์กด์ฌํ๊ณ ๊ฐ๊ฐ์ ๋ฒ์ ์ ์ง์ํ๋ ๋ฐ๊ฐ ์ ๋ถ ๋ค๋ฆ ๋๋ค. ๋ค์ํ ๋ฒ์ ๋ค๊ณผ ๊ฐ๊ฐ์ ๋ด์ฉ์ https://matthewpalmer.net/kubernetes-app-developer/articles/kubernetes-apiversion-definition-guide.html์์ ํ์ธ๊ฐ๋ฅํฉ๋๋ค.
- kind : ํ์ ์ ๋๋ค. ์ฃผ๋ก ์ฐ๋ฆฌ๋ Service, PersistanceVolume, PersistanceVolumeClaim, Deployment, Ingress ๋ฑ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
- metadata : ์ฌ๋ฌ ๋ฉํ๋ฐ์ดํฐ๋ค์ ์ ๋ ฅํ ์ ์์ต๋๋ค. ๋ผ๋ฒจ์ ๋ถ์ด๊ณ ์ ์ฅํ๋ ์ญํ ์ ์ํํฉ๋๋ค.
metadata ํ๋์ ์ ๋ ฅํ ์ ์๋ ์ฃผ์ ์์ฑ๋ค
- name (ํ์):
- ๋ฆฌ์์ค์ ์ด๋ฆ์ ์ง์ ํฉ๋๋ค. ์ด๋ฆ์ ๋ฆฌ์์ค์ ๊ณ ์ ์๋ณ์์ด์ด์ผ ํฉ๋๋ค.
- ์:
name: my-pod
- namespace:
- ๋ฆฌ์์ค๊ฐ ์ํ๋ ๋ค์์คํ์ด์ค(namespace)๋ฅผ ์ง์ ํฉ๋๋ค. ๋ค์์คํ์ด์ค๋ฅผ ์ง์ ํ์ง ์์ผ๋ฉด ๊ธฐ๋ณธ ๋ค์์คํ์ด์ค์ธ โdefaultโ๊ฐ ์ฌ์ฉ๋ฉ๋๋ค.
- ์:
namespace: my-namespace
- labels:
- ๋ฆฌ์์ค์ ๋ถ์ฌํ ๋ผ๋ฒจ(Label)์ ์ง์ ํฉ๋๋ค. ๋ผ๋ฒจ์ ๋ฆฌ์์ค๋ฅผ ์๋ณํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
- ์:
labels: app: my-app environment: production
- annotations:
- ๋ฆฌ์์ค์ ์ถ๊ฐ ์ ๋ณด๋ฅผ ์ ๊ณตํ๋ ์ด๋ ธํ ์ด์ (Annotation)์ ์ง์ ํฉ๋๋ค. ์ด๋ ธํ ์ด์ ์ ๋ผ๋ฒจ๊ณผ ์ ์ฌํ์ง๋ง ๋ ์์ธํ ๋ฉํ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
- ์:
annotations: description: This is my application. owner: John Doe
- resourceVersion:
- ๋ฆฌ์์ค์ ๋ฒ์ ์ ๋ณด๋ฅผ ๋ํ๋ด๋ ๊ฐ์ ๋๋ค. ์ฃผ๋ก ํด๋ฌ์คํฐ ๋ด์์ ๋ฆฌ์์ค์ ๋ณ๊ฒฝ์ ์ถ์ ํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
- generateName:
- ์ด๋ฆ์ ์๋์ผ๋ก ์์ฑํ ๋ ์ฌ์ฉํ๋ ์ ๋์ฌ(prefix)์ ๋๋ค. ์ฃผ๋ก ๋ฆฌ์์ค๋ฅผ ๋์ ์ผ๋ก ์์ฑํ ๋ ์ฌ์ฉ๋ฉ๋๋ค.
- finalizers:
- ๋ฆฌ์์ค๊ฐ ์ญ์ ๋ ๋ ์คํ๋์ด์ผ ํ๋ ์ข ๋ฃ ์ฒ๋ฆฌ(finalization) ํธ๋ค๋ฌ๋ฅผ ์ง์ ํฉ๋๋ค.
- clusterName:
- ๋ฆฌ์์ค๊ฐ ์ํ ํด๋ฌ์คํฐ์ ์ด๋ฆ์ ์ง์ ํฉ๋๋ค.
- selfLink:
- ๋ฆฌ์์ค์ ์์ฒด ๋งํฌ๋ฅผ ์ง์ ํฉ๋๋ค.
- uid:
- ๋ฆฌ์์ค์ ๊ณ ์ ์๋ณ์์ธ UID๋ฅผ ์ง์ ํฉ๋๋ค.
- ownerReferences:
- ๋ค๋ฅธ ๋ฆฌ์์ค๊ฐ ํด๋น ๋ฆฌ์์ค๋ฅผ ์์ ํ๋ ๊ฒฝ์ฐ ์ฐ๊ด๋ ๋ฆฌ์์ค ์ ๋ณด๋ฅผ ์ง์ ํฉ๋๋ค.
- creationTimestamp:
- ๋ฆฌ์์ค๊ฐ ์์ฑ๋ ์๊ฐ์ ๋ํ๋ด๋ ํ์์คํฌํ๋ฅผ ํฌํจํฉ๋๋ค.
- deletionTimestamp:
- ๋ฆฌ์์ค๊ฐ ์ญ์ ๋ ์์ ์ธ ๊ฒฝ์ฐ, ์ญ์ ์์ ์ธ ์๊ฐ์ ๋ํ๋ด๋ ํ์์คํฌํ๋ฅผ ํฌํจํฉ๋๋ค.
- deletionGracePeriodSeconds:
- ๋ฆฌ์์ค๊ฐ ์ญ์ ๋ ๋ Graceful Delete๋ฅผ ์ํ ๋๊ธฐ ์๊ฐ์ ์ง์ ํฉ๋๋ค.
- initializers:
- ์ด๊ธฐํ๋ฅผ ์ ์ดํ๊ธฐ ์ํ ์ค์ ์ ๋ณด๋ฅผ ํฌํจํฉ๋๋ค.
- managedFields:
- ๋ฆฌ์์ค์ ๊ด๋ฆฌ ํ๋ ์ ๋ณด๋ฅผ ํฌํจํฉ๋๋ค.
- ownerReference:
- ๋ค๋ฅธ ๋ฆฌ์์ค๊ฐ ํด๋น ๋ฆฌ์์ค๋ฅผ ์์ ํ๋ ๊ฒฝ์ฐ์ ๋ํ ์ฐ๊ฒฐ ์ ๋ณด๋ฅผ ํฌํจํฉ๋๋ค.
์์์ ์ค๋ช ํ ๋ฉํ๋ฐ์ดํฐ ์์ฑ ์ค ์ผ๋ถ๋ ํ์์ด๋ฉฐ, ๋ค๋ฅธ ์ผ๋ถ๋ ์ ํ ์ฌํญ์ ๋๋ค. ๋ฆฌ์์ค์ ์ ํ ๋ฐ ์ฌ์ฉ ์ฌ๋ก์ ๋ฐ๋ผ ์ด๋ค ๋ฉํ๋ฐ์ดํฐ๋ฅผ ์ค์ ํ ์ง๋ฅผ ๊ฒฐ์ ํด์ผ ํฉ๋๋ค.
- spec : ์ค์ ๋ก ๋ฆฌ์์ค๋ฅผ ์์ฑํ ๋ ํ์ํ ์ ๋ณด๋ค์ ์
๋ ฅํฉ๋๋ค.
- replicas :
pod
์ ๊ฐ์๋ฅผ ์ค์ ํฉ๋๋ค. - selector : ๋ณต์ ๋ณธ์ ์์ฑํ ํ
ํ๋ฆฟ ์ด๋ฆ์ ์ ํํฉ๋๋ค. Service์ metadata.label ๊ณผ ๋์ผํ ๊ฐ์ ๊ฐ์ ธ์ผํฉ๋๋ค. ๋ง์ผ Service ์
metadata.label.{key:value}
๊ฐ app: golang-backend-api ๋ผ๋ฉด, ์ฌ๊ธฐ์๋ app: golang-backend-api ๋ฅผ ๊ฐ์ ธ์ผํฉ๋๋ค. - template.metadata : ์ด deployment ๋ก ์ธํด ๋ณต์ ๋๋ ์ฌ๋ฌ ํ๋๋ค์๊ฒ ๊ณตํต์ผ๋ก ์ ์ฉํ ๋ฉํ๋ฐ์ดํฐ๋ฅผ ์ ๋ ฅํ ์ ์์ต๋๋ค.
- template.spec : ๊ฐ ํ
ํ๋ฆฟ์ ์ด๋ค ๋์ปค ์ด๋ฏธ์ง๊ฐ ์ฌ์ฉ๋ ๊ฒ์ธ์ง, ํฌํธ ๋ฐ ๊ธฐํ ์ค์ ์ ์ํํฉ๋๋ค(Docker์ค์ ๊ณผ ๋์ผํฉ๋๋ค).
- Docker Hub ์์
ghkdqhrbals/simplebank:latest
์ด๋ฏธ์ง๋ฅผ ๊ฐ์ ธ์ต๋๋ค. golang-backend-api
๋ผ๋ ์ด๋ฆ์ผ๋ก ์ปจํ ์ด๋๋ฅผ ์์ฑํฉ๋๋ค.8080
ํฌํธ๋ฅผ ๋คํธ์ํฌ ๋ด๋ถ์ ๋ ธ์ถ์ํต๋๋ค.
- Docker Hub ์์
- replicas :
2-2. Service
์์ ์ฐ๋ฆฌ๋ deployment.yaml๋ฅผ ํตํด Pod
๋ฅผ 2๊ฐ ์์ฑํ์ต๋๋ค. Service
ํ์
์ ์ด Pod๋ค์ ํตํฉ entryํฌ์ธํธ๋ฅผ ์ ๊ณตํ๋ฉฐ, ์ด๋ค ๋ฐฉ์์ผ๋ก ์ธ๋ถ์์ ์ ์ํ ์ง ๋คํธ์ํฌ๋ฅผ ์ค์ ํ๋ ํ์
์
๋๋ค. ์๋๋ service.yaml ํ์ผ์
๋๋ค.
apiVersion: v1
kind: Service
metadata:
name: golang-backend-api-service
spec:
type: ClusterIP #diff. LoadBalancer, etc.
selector:
app: golang-backend-api
ports:
- protocol: TCP
# nodePort is external access port outside the cluster. But, as we set type as clusterIP, this setting isn't needed
# nodePort: 30131
port: 80 # internal port
targetPort: 8080 # forward port
reference from https://matthewpalmer.net/kubernetes-app-developer/articles/service-kubernetes-example-tutorial.html
- spec.type :
ClusterIP
,LoadBalancer
,NodePort
์ค ํ๋๋ฅผ ์ ํํ ์ ์์ต๋๋ค.- ClusterIP : ์ด ์ค์ ์ ์ฟ ๋ฒ๋คํฐ์ค ํด๋ฌ์คํฐ ๋ด๋ถ์์๋ง
Pod
์ ์ ์ํ ์ ์๋๋ก ์ค์ ํด์ค๋๋ค. - NodePort : ํด๋ฌ์คํฐ ์ธ๋ถ์์๋
Pod
์ ์ ์ ๊ฐ๋ฅํ๋๋ก ์ค์ ํด์ค๋๋ค. ๋ง์ฝ 2๊ฐ์ ํ๋์ ์ฐ๊ฒฐ๋ ์๋น์ค๊ฐ NodePort ๋ก ๋์ด์๋ค๋ฉด, ๋ผ์ด๋๋ก๋น ๋ฐฉ์์ผ๋ก ์์๋๋ก ์์ฒญ์ด ๊ฐ ํ๋์ ์ ๋ฌ๋ฉ๋๋ค. - LoadBalancer : ํด๋ผ์ฐ๋์์ ์ ๊ณตํ๋ ๋ก๋๋ฐธ๋ฐ์ฑ์ ์ฌ์ฉํ๊ธฐ ์ํ ํ์ ์ ๋๋ค.
- ClusterIP : ์ด ์ค์ ์ ์ฟ ๋ฒ๋คํฐ์ค ํด๋ฌ์คํฐ ๋ด๋ถ์์๋ง
์, ์ง๊ธ๊น์ง deployment์ service๋ฅผ ์ ์ํ์ต๋๋ค.
ํ๋ฒ ์ ๋ฆฌํด๋ณผ๊น์?
์ฐ๋ฆฌ๋ Deployment๋ฅผ ํตํด (1) ๋์ปค์ด๋ฏธ์ง๋ฅผ ๋ถ๋ฌ์์, (2) ๋ ๊ฐ์ ์๋น์ค(Pod)๋ฅผ ์์ฑํ์ต๋๋ค. (3) ๊ทธ๋ฆฌ๊ณ ์ด ์๋น์ค๋ค์ ๊ฐ๊ธฐ ๋ค๋ฅธ IP๋ฅผ ๊ฐ์ง๊ณ ํฌํธ 8080๋ฅผ ๋ด๋ถ๋ ธ์ถ์ํต๋๋ค.
๊ทธ๋ฆฌ๊ณ Service๋ฅผ ํตํด (1) ์ฎ๊ธด Pod ์งํฉ์ ๋ถ๋ฌ์ค๊ณ , (2) ํตํฉ ์ํธ๋ฆฌ ํฌ์ธํธ์ธ ํฌํธ 80๋ฅผ ์ ๊ณตํ๊ณ , (3) ๊ฐ๊ฐ์
Pod
:8080์ผ๋ก ๋ผ์ด๋๋ก๋น ํฌํธํฌ์๋ฉํ์์ต๋๋ค(๊ธฐ๋ณธ์ ์ผ๋ก ๋ผ์ด๋๋ก๋น์ผ๋ก ์ค์ ๋ฉ๋๋ค).ํ์ง๋ง ์์ง๊น์ง๋, ์ธ๋ถ๋ก ํฌํธ๊ฐ ๋ ธ์ถ๋์ง ์์์ต๋๋ค.
์ด์ ๋ถํฐ ์ด๊ฑธ ์ค์ ํ๊ธฐ ์ํด์ ์ฐ๋ฆฌ๋ Ingress ๋ฅผ ์์ฑํด์ฃผ์ด์ผํฉ๋๋ค!(๋ฌผ๋ก NodePort ๋ก ์ง์ ์ธ๋ถ๋ ธ์ถํ ์ ์์ต๋๋ค.)
2-3. Ingress
Ingress๋ ์ธ๋ถ์ ํฌํธ๋ฅผ ๋ ธ์ถ์์ผ์ค๊ณผ ๋์์ ๋ก๋๋ฐธ๋ฐ์ฑ์ ์ค์ ํด์ฃผ๋ ์ญํ ์ ์ํํฉ๋๋ค. ์๋๋ ingress.yaml ํ์ผ์ ๋๋ค.
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: nginx
spec:
controller: k8s.io/ingress-nginx
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: golang-backend-api-ingress
annotations:
cert-manager.io/cluster-issuer: letsencrypt
spec:
ingressClassName: nginx
rules:
- host: "api.hwangbogyumin.com"
http:
paths:
- pathType: Prefix # 443, 80 etc. -> 80 if "/" prefix
path: "/"
backend:
service:
name: golang-backend-api-service
port:
number: 80
tls:
- hosts:
- api.hwangbogyumin.com
secretName: hwangbogyumin-api.cert
์ฌ๊ธฐ์๋ ์ฌ๋ฌ๊ฐ์ง ์ญํ ์ ์ํํ๊ฒ ๋ฉ๋๋ค.
- TLS ์ธ์ฆ์ ์ ์ฉ
- TLS ์ธ์ฆ์๋ ์์ ์ด ๊ฐ์ง๊ณ ์๋ ๋๋ฉ์ธ์ letsencrypt ์ ์ฐ๋ํ๋ฉฐ ๋ฌด๋ฃ๋ก! ๋ฐ๊ธ๋ฐ์ ์ ์์ต๋๋ค.
- ์ ๋ ๋๋ฉ์ธ์ AWS-Route-53์ ํตํด ์์ต๋๋ค.
- ๋๋ฉ์ธ ์ฐ๊ฒฐ
- spec.rules.host : ์ฌ๊ธฐ์ ์์ ์ด ๊ฐ์ง๊ณ ์๋ ๋๋ฉ์ธ์ ์ ๊ณ , http.path ์ ์ถ๊ฐ์ ์ธ ๋ผ์ฐํ ์ ์ ์ผ์๋ฉด ๋ฉ๋๋ค.
- ์ธ๋ถ ํฌํธ ๋
ธ์ถ
- backend.service.name : ์์ ์ฐ๋ฆฌ๊ฐ ์ค์ ํ๋ service๋ ๋ฌถ๊ธด Pod๋ค์ ๊ฐ์ง๊ณ ์์ต๋๋ค. ์ฌ๊ธฐ์ ์ธ๋ถ ํฌํธ๋ฅผ ๋งคํ์์ผ์ฃผ๋ ์ญํ ์ ์ํํฉ๋๋ค(์ด ๋ถ๋ถ์ nginx์ location์ ์ ์ํ๋ ๋ถ๋ถ๊ณผ ๊ฐ์ฃ ).
์ด ์ ๊ฐ์ด ์ฐ๋ฆฌ๋ ์ฟ ๋ฒ๋คํฐ์ค๋ฅผ ์ฑ๊ณต์ ์ผ๋ก ์คํํ ์ ์๊ฒ ๋ฉ๋๋ค!
References
- https://www.upguard.com/blog/docker-vs-vmware-how-do-they-stack-up
- https://stackoverflow.com/questions/47536536/whats-the-difference-between-docker-compose-and-kubernetes
- https://github.com/compose-spec/compose-spec/blob/master/spec.md
- https://www.theserverside.com/blog/Coffee-Talk-Java-News-Stories-and-Opinions/What-is-Kubernetes-vs-Docker-Compose-How-these-DevOps-tools-compare
- https://medium.com/devops-mojo/kubernetes-architecture-overview-introduction-to-k8s-architecture-and-understanding-k8s-cluster-components-90e11eb34ccd
- https://matthewpalmer.net/kubernetes-app-developer/articles/service-kubernetes-example-tutorial.html
- https://kubernetes.io/docs/concepts/services-networking/ingress/