Pod


  • ๊ฐ€์žฅ ์ž‘์€ ๋ฐฐํฌ ๋‹จ์œ„
  • ์ „์ฒด ํด๋Ÿฌ์Šคํ„ฐ์—์„œ ๊ณ ์œ ํ•œ IP ํ• ๋‹น
  • 1~N ๊ฐœ์˜ Container ๋ฅผ ํฌํ•จ
    • Pods usually have a one-to-one relationship with containers running the app.
    • A single pod can have multiple containers, not the same kind of container but helper containers instead.
  • host ํด๋” ๊ณต์œ , localhost ๋„คํŠธ์›Œํฌ ๊ณต์œ 
    • This means the app container and the helper container can communicate through localhost.

How to deploy pods

kubectl run nginx --image nginx
kubectl get pods
  • The first line of command will pull the image from wherever K8s is configured to pull the image from such as public Docker Hub or private registries.

YAML in K8s

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
    type: front-end
spec:
  containers:
    - name: nginx-container
      image: nginx
  • K8s uses YAML files as inputs for creating objects and all objects contain 4 top-level fields.
    • apiVersion
      • The version of K8s API that is used for creating the object.
      • e.g. v1, apps/v1, etc
    • kind
      • The type of the object to be created.
      • e.g. Pod, Service, ReplicaSet, Deployment, etc
    • metadata
      • A dictionary for metadata describing the object.
      • e.g. name, labels, etc
    • spec
      • A specification of the object to be created.
      • For the above example, containers section is a list that can be listed with - character.

A pod can be created with the command below:

kubectl run nginx --image=nginx

or using a YAML file:

kubectl create -f pod-definition.yaml
kubectl get pods
kubectl describe pod myapp-pod
kubectl run redis --image=redis --dry-run=client -o yaml > redis.yaml

kubectl ๋ช…๋ น์–ด๋กœ template yaml file ์„ ์ƒ์„ฑํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ --dry-run ๊ณผ -o yaml ์˜ต์…˜์„ ํ†ตํ•ด yaml file ์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

ReplicaSet


  • Replication Controller & ReplicaSet is similar but different. The Replication Controller is the older technology that ReplicaSet replaces.
  • The ReplicaSet helps to run and maintain the desired number of pods in the K8s cluster by creating and deleting pods based on the configuration. This allows the K8s cluster to achieve high availability.
  • It also provides load-balancing & scaling capability by deploying additional pods in existing or additional nodes. This means the ReplicaSet spans across multiple nodes in the cluster.

Creating Replication Controller with YAML

apiVersion: v1
kind: ReplicationController
metadata:
  name: myapp-rc
  labels:
    app: myapp
    type: front-end
spec:
  template:
    metadata:
      name: myapp-pod
      labels:
        app: myapp
        type: front-end
    spec:
      containers:
      - name: nginx-container
        image: nginx
  replicas: 3
  • template
    • A template of the pod definition.
  • replicas
    • Number of replicas of the template.

Then run the below commands to create and see the objects created.

kubectl create -f rc-definition.yaml
kubectl get replicationcontroller
kubectl get pods

Creating ReplicaSet with YAML

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: myapp-replicaset
  labels:
    app: myapp
    type: front-end
spec:
  template:
    metadata:
      name: myapp-pod
      labels:
        app: myapp
        type: front-end
    spec:
      containers:
      - name: nginx-container
        image: nginx
  replicas: 3
  selector:
    matchLabels:
      type: front-end
  • template
    • A template of the pod definition.
  • replicas
    • Number of replicas of the template.
  • selector
    • It helps identify pods that fall under it so that it can monitor the selected pods and maintain the number of replicas in the cluster.

Then run the below commands to create and see the objects created.

kubectl create -f replicaset-definition.yaml
kubectl get replicaset
kubectl get pods

To scale the number of replicas by file:

kubectl replace -f replicaset-definition.yaml

To scale the number of replicas by command:

kubectl scale --replicas=6 -f replicaset-definition.yaml

or

kubectl scale --replicas=6 replicaset myapp-replicaset
  • Note these two commands will not change the definition file.

Deployment


  • ๋‚ด๋ถ€์ ์œผ๋กœ ReplicaSet ์„ ์ด์šฉํ•˜์—ฌ ๋ฐฐํฌ ๋ฒ„์ „์„ ๊ด€๋ฆฌ
  • The Deployment provides the capability of upgrading underlying instances seamlessly using rolling updates, undo changes, pauses, and resume changes as required.

Creating Deployment with YAML

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-replicaset
  labels:
    app: myapp
    type: front-end
spec:
  template:
    metadata:
      name: myapp-pod
      labels:
        app: myapp
        type: front-end
    spec:
      containers:
      - name: nginx-container
        image: nginx
  replicas: 3
  selector:
    matchLabels:
      type: front-end
  • All contents of the Deployment are exactly similar to the ReplicaSet definition file.

Run the below commands to create and find the objects created:

kubectl create -f deployment-definition.yaml
kubectl get deployments
kubectl get replicaset
kubectl get pods

or

kubectl get all

Service


NodePort

apiVersion: v1
kind: Service
metadata:
  name: myapp-service
spec:
  type: NodePort
  ports:
   - targetPort: 80
   - port: 80
   - nodePort: 30008
  selector:
    app: myapp
    type: front-end
  • Node(host) ์— ๋…ธ์ถœ๋˜์–ด ์™ธ๋ถ€์—์„œ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ์„œ๋น„์Šค
  • ๋ชจ๋“  Node ์— ๋™์ผํ•œ ํฌํŠธ๋กœ ์ƒ์„ฑ
  • targetPort ๋Š” target pod ์˜ port ๋ฅผ ์ง€์ •, ์ง€์ •ํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ port ์™€ ๊ฐ™์€ ๊ฐ’์„ ๊ฐ€์ง
  • port ๋Š” Service Object ์˜ port ๋ฅผ ์ง€์ • (required)
  • nodePort ๋Š” 30,000 ~ 32,767 ๊นŒ์ง€์˜ ๋ฒ”์œ„ ์•ˆ์— ์†ํ•ด์•ผ ํ•˜๋ฉฐ ์ง€์ •ํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ ์ž๋™์œผ๋กœ ํ• ๋‹น๋จ
  • selector ๋ฅผ ํ†ตํ•ด target pod ๋ฅผ ์ง€์ •
  • ํ•˜๋‚˜์˜ Node ์— ๊ฐ™์€ ์ข…๋ฅ˜์˜ Pod ๊ฐ€ ์—ฌ๋Ÿฌ๊ฐœ ์žˆ์„ ๊ฒฝ์šฐ Service ๊ฐ€ ์•Œ์•„์„œ selector ์— ํ•ด๋‹นํ•˜๋Š” Pod ๋ฅผ ์ฐพ๊ณ  ๋ถ€ํ•˜๋ฅผ ๋ถ„์‚ฐํ•˜์—ฌ ๊ฐ๊ฐ Pod ์— Random ํ•˜๊ฒŒ ๋ณด๋‚ด์คŒ.
  • ์—ฌ๋Ÿฌ Node ์— Pod ๊ฐ€ ๋ฐฐํฌ๋˜์–ด ์žˆ์„ ๊ฒฝ์šฐ์—๋„ Service ๋Š” ๋ชจ๋“  Node ์— ๊ฑธ์ณ ์ ์šฉ๋˜์–ด ์•„๋ฌด Node ์— ์š”์ฒญ์„ ๋ณด๋‚ด๋„ ์•Œ์•„์„œ ์•„๋ฌด Node ์— ๋ฐฐํฌ๋œ Pod ์— ํŠธ๋ž˜ํ”ฝ์„ ๋ณด๋ƒ„.

ClusterIP

apiVersion: v1
kind: Service
metadata:
  name: back-end
spec:
  type: ClusterIP
  ports:
   - targetPort: 80
   - port: 80
  selector:
    app: myapp
    type: back-end
  • ํด๋Ÿฌ์Šคํ„ฐ ๋‚ด๋ถ€์—์„œ ์‚ฌ์šฉํ•˜๋Š” ํ”„๋ก์‹œ
  • Pod ์€ ๋™์ ์ด์ง€๋งŒ ์„œ๋น„์Šค๋Š” ๊ณ ์œ  IP ๋ฅผ ๊ฐ€์ง
  • ํด๋Ÿฌ์Šคํ„ฐ ๋‚ด๋ถ€์—์„œ ์„œ๋น„์Šค ์—ฐ๊ฒฐ์€ DNS ๋ฅผ ์ด์šฉ
  • ๊ฐ€๋ น 3-tier-architecture ์—์„œ backend app ์— ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ  ์‹ถ์„ ๋•Œ backend ๋ฅผ ๋‹ด๋‹นํ•˜๋Š” ์—ฌ๋Ÿฌ Pod ๊ฐ€ cluster ์ „์ฒด์— ํผ์ ธ์žˆ์œผ๋‹ˆ ClusterIP ๋ฅผ ํ†ตํ•ด ์›ํ•˜๋Š” layer ๋ฅผ ์ง€์ •
kubectl run httpd --image=httpd --port=80 --expose
  • kubectl run ์œผ๋กœ Pod ๋ฅผ ์ƒ์„ฑํ•  ๋•Œ โ€”expose ์˜ต์…˜์„ ์ฃผ๋ฉด Pod ์— ์—ฐ๊ฒฐ๋˜๋Š” ClusterIP ๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•ด์ค€๋‹ค. ClusterIP ์™€ ์—ฐ๊ฒฐ๋˜์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— โ€”port ์˜ต์…˜์ด ํ•„์ˆ˜์ ์œผ๋กœ ํฌํ•จ๋˜์–ด์•ผ ํ•œ๋‹ค.

LoadBalancer

apiVersion: v1
kind: Service
metadata:
  name: myapp-service
spec:
  type: LoadBalancer
  ports:
   - targetPort: 80
   - port: 80
   - nodePort: 30008
  • ํ•˜๋‚˜์˜ IP ์ฃผ์†Œ๋ฅผ ์™ธ๋ถ€์— ๋…ธ์ถœํ•˜์—ฌ ์ง€์ •๋œ Pod ์— ์š”์ฒญ์ด ๋„๋‹ฌํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์คŒ
  • NodePort ๋Œ€์‹  AWS, Azure, GCP ๋“ฑ์—์„œ ์ œ๊ณตํ•˜๋Š” Native Load Balancer ๋กœ ๋ถ€ํ•˜๋ฅผ ๋ถ„์‚ฐํ•˜์—ฌ ๋ณด๋‚ด๋Š” ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•จ

Namespaces


K8s Cluster ๋ฅผ ๊ตฌ์ถ•ํ•˜๊ฒŒ๋˜๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœ Default, kube-system, kube-public Namespace ๋“ค์ด ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋œ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ์ƒ์„ฑํ•œ Pod, Deployment, Service ๋“ฑ K8s Object ๋“ค์€ ๊ธฐ๋ณธ์ ์œผ๋กœ Default Namespace ์— ์†ํ•˜๊ฒŒ ๋œ๋‹ค.

kubectl get pods --namespace=kube-system

kube-system Namespace ์˜ ๊ฒฝ์šฐ, coredns, etcd-master, kube-apiserver-master, kube-controller-manager-master ๋“ฑ K8s ์˜ ๊ธฐ๋ณธ์ ์ธ Component ๋“ค์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

kubectl create -f pod-definition.yml --namespace=dev

K8s Object ๋ฅผ ํŠน์ • Namespace ์— ๋ฐฐํฌํ•˜๊ณ  ์‹ถ์„ ๊ฒฝ์šฐ์—” ์˜ต์…˜์œผ๋กœ namespace ๋ฅผ ์ง€์ •ํ•ด์ฃผ๊ฑฐ๋‚˜,

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  namespace: dev
  labels:
    app: myapp
    type: front-end
spec:
  containers:
    - name: nginx-container
      image: nginx

์œ„ ์ฒ˜๋Ÿผ metadata ํ•„๋“œ์— namespace ๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ๋ฉด๋œ๋‹ค.

apiVersion: v1
kind: Namespace
metadata:
  name: dev

Namespace ๋ฅผ ์ƒ์„ฑํ•  ๋• ์œ„์ฒ˜๋Ÿผ Namespace yaml ์„ ์ƒ์„ฑํ•œ ๋’ค,

kubectl create -f namespace-dev.yml

์œ„ ๋ช…๋ น์–ด๋กœ ์ƒ์„ฑํ•˜๊ฑฐ๋‚˜,

kubectl create namespace dev

yaml ํŒŒ์ผ ์—†์ด ๋ช…๋ น์–ด๋กœ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

kubectl config set-context $(kubectl config current-context) --namespace=dev

์œ„ ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด cli ์ž‘์—… ์œ„์น˜๋ฅผ ํŠน์ • Namespace ๋กœ ์ด๋™์‹œํ‚ฌ ์ˆ˜๋„ ์žˆ๋‹ค.

apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-quota
  namespace: dev
spec:
  hard:
    pods: "10"
    requests.cpu: "4"
    requests.memory: 5Gi
    limits.cpu: "10"
    limits.memory: 10Gi

ํŠน์ • Namespace ์— ํ•˜๋“œ์›จ์–ด ๋ฆฌ์†Œ์Šค๋ฅผ ํ• ๋‹นํ•  ๋•Œ์—” ResourceQuota yaml ์„ ์ƒ์„ฑํ•œ ๋’ค,

kubectl create -f compute-quota.yml

์ƒ์„ฑํ•˜์—ฌ ์ž์›์„ ํ• ๋‹นํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค.

Imperative vs Declarative


IaC ์—์„  ๋ช…๋ นํ˜•๊ณผ ์„ ์–ธํ˜• ๋ฐฉ์‹์œผ๋กœ ์ธํ”„๋ผ๋ฅผ ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ,

kubectl run --image=nginx nginx
kubectl create deployment --image=nginx nginx
kubectl expose deployment nginx --port 80

์œ„ ๊ฐ™์€ ๋ช…๋ น์–ด๋“ค์„ ํ†ตํ•ด Object ๋ฅผ ์ƒ์„ฑํ•˜๊ณ ,

kubectl edit deployment nginx
kubectl scale deployment nginx --replicas=5
kubectl set image deployment nginx nginx=nginx:1.18

์ƒ์„ฑ๋œ Object ๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Š” ๋ช…๋ นํ˜• ๋ฐฉ์‹์œผ๋กœ K8s ๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

kubectl create -f nginx.yaml
kubectl edit deployment nginx

K8s configuration file ์„ ํ†ตํ•ด Object ๋ฅผ ์ƒ์„ฑํ•œ ๊ฒฝ์šฐ ์„ ์–ธํ˜• ๋ฐฉ์‹์œผ๋กœ ๊ตฌ์ถ•ํ–ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, edit ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด ์ ‘๊ทผํ•œ file ์€ K8s memory ์— ๋™์ ์œผ๋กœ ์ƒ์„ฑ๋œ yaml ์ธ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ๋•Œ๋ฌธ์— edit ์œผ๋กœ ์„ค์ •์„ ๋ฐ”๊พผ๋‹ค๊ณ  ๊ธฐ์กด์— ์ž‘์„ฑํ•œ nginx.yaml ์€ ์ˆ˜์ •๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์ถ”ํ›„์— replace ๋“ฑ์„ ํ•  ๊ฒฝ์šฐ ์˜ˆ์ƒํ•˜์ง€ ๋ชปํ•œ ๋ณ€๊ฒฝ์ด ์ƒ๊ธธ ์ˆ˜ ์žˆ๋‹ค. ์ด๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด์„  edit ๋Œ€์‹  configuration file ์ž์ฒด๋ฅผ ๋ณ€๊ฒฝํ•œ ํ›„ replace ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์ด ๋ฐ”๋žŒ์งํ•˜๋‹ค.

kubectl apply -f nginx.yaml

K8s ๋Š” apply ๋ฅผ ํ†ตํ•ด ์„ ์–ธํ˜• ๋ฐฉ์‹์œผ๋กœ Object ๋ฅผ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋‹ค. apply ๋Š” ์ด๋ฏธ ๋งŒ๋“ค์–ด์ง„ Object ๋ฅผ ํŒŒ์•…ํ•˜๋ฉฐ ๋ถ€๋ถ„์ ์œผ๋กœ ์„ค์ •์ด ์ˆ˜์ •๋œ ๊ฒฝ์šฐ ํ•ด๋‹น ๋ถ€๋ถ„๋งŒ ์ ์šฉํ•˜๋Š” ๊ธฐ๋Šฅ ์—ญ์‹œ ์ง€์›ํ•œ๋‹ค.

# Live object configuration
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: {"apiVersion": "v1", ...}
  labels:
    app: myapp
    type: front-end
spec:
  containers:
  - name: nginx-container
    image: nginx
status:
  conditions:
  - lastProbeTime: null
    ...

kubectl apply ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด K8s ๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์ž‘์„ฑํ•œ yaml file ๊ณผ K8s memory ์— ์ €์žฅ๋œ Live object configuration ๊ณผ kubectl.kubernetes.io/last-applied-configuration ํ•„๋“œ๋ฅผ ๋น„๊ตํ•˜์—ฌ ๋ณ€๊ฒฝ๋œ ์‚ฌํ•ญ๋งŒ ๋ถ€๋ถ„์ ์œผ๋กœ ํ™•์ธํ•˜๊ณ  ์ ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

Ingress


  • ๋„๋ฉ”์ธ ๋˜๋Š” ๊ฒฝ๋กœ๋ณ„ ๋ผ์šฐํŒ…
    • Nginx, HAProxy, ALB, โ€ฆ

References