✔️ Workload Resource(Controller)
워크로드 리소스는 컨트롤러라고도 불린다.
파드는 컨테이너의 집합이며 컨트롤러는 파드의 집합이다.
컨테이너 ⊂ 파드 ⊂ 컨트롤러 관계를 가진다.
워크로드는 쿠버네티스에서 구동되는 애플리케이션이다. 워크로드가 단일 컴포넌트이거나 함께 작동하는 여러 컴포넌트이든 관계없이, 쿠버네티스에서는 워크로드를 일련의 파드 집합 내에서 실행한다.
컨트롤러라는 것은 파드의 집합이다. 컨트롤러는 하나 이상의 파드로 구성되어 있다. 파드에는 여러개의 컨테이너가 있을 수 있다.
싱글톤 파드를 만드는 경우는 거의 없으며 컨트롤러를 만들고 컨트롤러가 파드를 만들고 파드가 컨테이너를 만드는 형태로 사용한다.
컨트롤러를 파드를 3개를 복제해서 만들어라
라고 선언하면
컨트롤러는 알아서 파드에 세개의 컨테이너를 만들게 되며 컨테이너가 죽으면 컨트롤러가 알아서 파드에 3개의 컨테이너를 만든다.이것을 쿠버네티스의 핵심 기능 중 하나인 Self-Healing
이라고 한다.
쿠버네티스는 다음과 같이 여러 가지 빌트인(built-in) 워크로드 리소스를 제공한다.
✔️ ReplicationController
vagrant@k8s-node1:~/cont/rc$ kubectl api-resources | more
replicationcontrollers rc v1 true ReplicationController
v1 을 사용하며 모든 파드와 모든 컨트롤러는 NS를 사용한다.
KIND는 ReplicationController이다.
ReplicationController
목록을 확인하는 방법
kubectl get replicationcontrollers
kubectl get replicationcontroller
kubectl get rc
✔️ 레플리케이션 컨트롤러의 동작방식
파드가 너무 많으면 레플리케이션 컨트롤러가 추가적인 파드를 제거한다.
파드를 관리한다. 파드의 복제본 개수를 몇개로 관리할 것인지 선언할 수 있다.Replicas : 3
으로 선언하면 3개의 파드를 유지한다.
특정 조건에서 파드가 3개 이상으로 생성될 때가 있는데 선언한 개수에 맞춰 자동으로 파드를 삭제한다.
파드가 실행되는 노드에 장애가 나서 죽으면 파드가 죽는 경우에는 선언한 개수에 맞춰 파드를 생성한다.
즉, 선언한 값보다 너무 적거나 너무 많으면 파드 수를 조정한다.
컨트롤러가 파드를 3개를 만들어서 운영하고 있고 node1, 2, 3에 각각 하나씩 배치되어 있다고 하자
node3가 죽어버리면 하나의 파드를 더 만들어야 하는데 스케줄러에의해 node3 에 배치할 수 없으면 node 1, 2 에 배치해야한다.
만약 node 1, 2에서 cpu, memory를 너무 많이 쓰고 있어서 새롭게 하나를 더 만들어서 배치하려고 하면 실패할 때는 레플리케이션 컨트롤러 선에서 해결할 수 없다.
그럼에도 레플리케이션 컨트롤러는 우리가 선언한 형태로 유지하기 위해 노력한다.
레플리케이션 컨트롤러가 유지 관리하는 파드는 실패하거나 삭제되거나 종료되는 경우 자동으로 교체된다.
📌 교체의 의미 ?
RC(ReplicationController)가 있고 3개의 파드가 있을 때 하나의 파드를 지운다고해서 기존의 것과 완전 같은 파드가 다시 새롭게 만들어지는 것이 아니다.
전혀 새로운 파드를 만든다.
✔️ 레플리케이션 컨트롤러의 Spec 작성
✔️ replicas
replicas
는 Integer
값이며 원하는 복제 개수이다.
설정한 숫자만큼의 파드가 만들어진다. 따로 설정하지 않으면 기본값은 1이다.
✔️ template
vagrant@k8s-node1:~/cont/rc$ kubectl explain rc.spec.template
FIELDS:
metadata <Object>
Standard object's metadata. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
spec <Object>
Specification of the desired behavior of the pod. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
컨트롤러가 파드를 만들기 위한 정보가 필요하다.
어떤 이미지로 만들 것인지, 포트는 몇번인지 등등을 Pod template
라고 한다.
파드의 metadata
와 spec
이 있다.
metadata
에는 파드의 이름, 레이블, 어노테이션 등이 들어간다.spec
에는 파드의 스펙이 들어간다.
pod.metadata == rc.spec.metadata
pod.spec.* == rc.spec.template.spec.*
물론 여기에는 apiversion은 없다.
어차피 파드를 만들것이고 파드는 v1을 쓰므로 별도로 kind와 apiversion을 따로 지정하지 않는다.
✔️ selector
labelSelector
는 리소스 간 연결을 제공한다.
RC가 있고 파드를 만들 것인데 운영 과정에서 싱글톤 파드가 있을 수도 있고 다른 RC에 의해 관리되는 파드들도 있을 것이다.
많은 파드들 중 내가 관리하는 파드가 도대체 어떤 파드인지를 선택하느냐와 관련된 것이다.
모든 파드에는 레이블이 붙어 있어야 한다.
싱글톤 파드를 만들때는 레이블이 반드시 필요한 요소는 아니다.
하지만 컨트롤러에 의해 관리되는 파드는 반드시 레이블이 붙어 있어야 한다.
같은 RC에 의해 관리되는 파드들은 동일한 레이블이 붙어 있어야 하며 RC는 수많은 파드 중에서 해당되는 레이블을 선택해야 한다.
vagrant@k8s-node1:~/cont/rc$ kubectl explain rc.spec.selector
KIND: ReplicationController
VERSION: v1
FIELD: selector <map[string]string>
셀렉팅할 레이블의 key, value를 지정해준다.
myweb-rc.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: myweb-rc
spec:
replicas: 3
selector:
app: web # 1) 해당 값은
# Pod Configure
template:
metadata:
# name: # 똑같은 이름의 파드를 만들 것이 아니므로 이름을 지정하지 않는다.
labels:
app: web # 2) 이 값과 같아야 한다.
spec:
containers:
- name: myweb
image: ghcr.io/c1t1d0s7/go-myweb
ports:
- containerPort: 8080
protocol: TCP
파드의 이름은 나중에 컨트롤러의 이름 뒤에 -
랜덤하게 붙는다.
파드의 이름을 직접 지정하지 않는다.
우리가 만들 파드의 템플릿은 다음과 같고 파드에는 레이블이 붙는다.
셀렉팅 할 레이블의 값은 템플릿의 레이블의 값과 같아야만 한다.
vagrant@k8s-node1:~/cont/rc$ kubectl create -f myweb-rc.yaml
replicationcontroller/myweb-rc created
vagrant@k8s-node1:~/cont/rc$ kubectl get rc
NAME DESIRED CURRENT READY AGE
myweb-rc 3 3 3 21s
RC의 이름, 정의한 개수, 현재 개수, 준비된 파드의 개수를 확인할 수 있다.
vagrant@k8s-node1:~/cont/rc$ kubectl get pods
NAME READY STATUS RESTARTS AGE
myweb-rc-67vsp 1/1 Running 0 100s
myweb-rc-fpnht 1/1 Running 0 100s
myweb-rc-nndfk 1/1 Running 0 100s
컨트롤러의 이름 - 랜덤한 값 (지정 불가함)
같은 NS에서 같은 이름의 리소스는 존재할 수 없다.
상세하게 보자
vagrant@k8s-node1:~/cont/rc$ kubectl get rc,pods
NAME DESIRED CURRENT READY AGE
replicationcontroller/myweb-rc 3 3 3 2m45s
NAME READY STATUS RESTARTS AGE
pod/myweb-rc-67vsp 1/1 Running 0 2m45s
pod/myweb-rc-fpnht 1/1 Running 0 2m45s
pod/myweb-rc-nndfk 1/1 Running 0 2m45s
vagrant@k8s-node1:~/cont/rc$ kubectl get rc -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
myweb-rc 3 3 3 3m45s myweb ghcr.io/c1t1d0s7/go-myweb app=web
vagrant@k8s-node1:~/cont/rc$ kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
myweb-rc-67vsp 1/1 Running 0 3m52s app=web
myweb-rc-fpnht 1/1 Running 0 3m52s app=web
myweb-rc-nndfk 1/1 Running 0 3m52s app=web
이 컨트롤러는 app: web
레이블을 셀렉팅하고 있다는 의미이다.
파드에는 app: web
레이블이 붙어있고 이 컨트롤러는 app: web
레이블을 갖고 있는 것들을 셀렉팅하고 관리한다.
watch
명령으로 파드의 목록을 띄워놓은 상태에서 임의의 파드 중 하나의 label을 변경해보자
우선 watch
로 변경 전 상태의 파드의 레이블을 확인한다.
Every 1.0s: kubectl get pods --show-labels k8s-node1: Wed May 18 08:48:39 2022
NAME READY STATUS RESTARTS AGE LABELS
myweb-rc-67vsp 1/1 Running 0 7m18s app=web
myweb-rc-fpnht 1/1 Running 0 7m18s app=web
myweb-rc-fwlc8 1/1 Running 0 7m18s app=web
vagrant@k8s-node1:~$ kubectl label pods myweb-rc-nndfk app=database --overwrite
pod/myweb-rc-nndfk labeled
다음 명령을 실행하는 순간
Every 1.0s: kubectl get pods --show-labels k8s-node1: Wed May 18 08:49:21 2022
NAME READY STATUS RESTARTS AGE LABELS
myweb-rc-67vsp 1/1 Running 0 8m app=web
myweb-rc-fpnht 1/1 Running 0 8m app=web
myweb-rc-fwlc8 1/1 Running 0 67s app=web
myweb-rc-nndfk 1/1 Running 0 8m app=database
출력창이 다음과 같이 변한다.
RC 입장에서는 관리할 파드가 2개로 줄었으므로 선언한 수를 맞추기 위해 새롭게 파드를 생성한다.
반대의 상황을 보자
vagrant@k8s-node1:~$ kubectl label pods myweb-rc-nndfk app=web --overwrite
pod/myweb-rc-nndfk labeled
해당 명령을 입력하는 순간 파드가 하나 삭제된다.
Every 1.0s: kubectl get rc,pods --show-labels k8s-node1: Wed May 18 08:52:54 2022
NAME DESIRED CURRENT READY AGE LABELS
replicationcontroller/myweb-rc 3 3 3 11m app=web
NAME READY STATUS RESTARTS AGE LABELS
pod/myweb-rc-67vsp 1/1 Running 0 11m app=web
pod/myweb-rc-fpnht 1/1 Running 0 11m app=web
pod/myweb-rc-nndfk 1/1 Running 0 11m app=web
원칙은 가장 최근에 만들어진 것이 삭제된다.
🔍 추가적인 상황을 생각해보자
만약 셀렉팅할 레이블과 파드 템플릿의 레이블이 다르면 어떻게 될까 ?
셀렉팅을 할 수 없으므로 파드가 생성조차 되지 않는다.
만약 app: web
외에 env: deb
레이블을 추가로 붙이면 어떻게 될까 ?
정상적으로 생성된다.
컨트롤러 입장에서 해당되는 파드를 셀렉팅할 수 있기만 하면 상관없다.
셀렉팅만 되면 셀렉팅 레이블과 파드 템플릿의 레이블의 목록이 완전 일치할 필요는 없다.
다음과 같이 수정하고 실행하면 어떻게 될까 ?
apiVersion: v1
kind: ReplicationController
metadata:
name: myweb-rc
spec:
replicas: 3
selector:
app: web
env: dev
# Pod Configure
template:
metadata:
# name:
labels:
app: web
env: dev
spec:
containers:
- name: myweb
image: ghcr.io/c1t1d0s7/go-myweb
ports:
- containerPort: 8080
protocol: TCP
정상적으로 생성된다.
마찬가지로 해당되는 파드를 셀렉팅할 수 있기 때문에 문제가 없다.
✔️ ReplicationController 스케일링
vagrant@k8s-node1:~$ kubectl scale -help
Examples:
# Scale a replica set named 'foo' to 3
kubectl scale --replicas=3 rs/foo
# Scale a resource identified by type and name specified in "foo.yaml" to 3
kubectl scale --replicas=3 -f foo.yaml
# If the deployment named mysql's current size is 2, scale mysql to 3
kubectl scale --current-replicas=2 --replicas=3 deployment/mysql
# Scale multiple replication controllers
kubectl scale --replicas=5 rc/foo rc/bar rc/baz
# Scale stateful set named 'web' to 3
kubectl scale --replicas=3 statefulset/web
✔️ ReplicationController 명령어
kubectl scale rc myweb-rc --replicas=5
kubectl scale rc/myweb-rc --replicas=5
--replicas
옵션 뒤에 원하는 복제본 개수를 선언하여 사용한다.
Every 1.0s: kubectl get rc,pods --show-labels -o wide k8s-node1: Wed May 18 09:07:00 2022
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR LABELS
replicationcontroller/myweb-rc 5 5 5 2m26s myweb ghcr.io/c1t1d0s7/go-myweb app=web,env=dev app=web,env=dev
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELS
pod/myweb-rc-4k8x7 1/1 Running 0 11s 10.233.92.22 node3 <none> <none> app=web,env=dev
pod/myweb-rc-d7g8v 1/1 Running 0 2m26s 10.233.92.21 node3 <none> <none> app=web,env=dev
pod/myweb-rc-gdgnc 1/1 Running 0 11s 10.233.96.20 node2 <none> <none> app=web,env=dev
pod/myweb-rc-px69s 1/1 Running 0 2m26s 10.233.96.19 node2 <none> <none> app=web,env=dev
pod/myweb-rc-v9scp 1/1 Running 0 2m26s 10.233.90.15 node1 <none> <none> app=web,env=dev
명령을 실행하면 다음과 같이 5개의 파드가 생성된다.
Every 1.0s: kubectl get rc,pods... k8s-node1: Wed May 18 09:08:53 2022
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR LABELS
replicationcontroller/myweb-rc 3 3 3 4m19s myweb ghcr.io/c1t1d0s7/go-myweb app=web,env=dev app=web,env=dev
NAME READY STATUS RESTARTS AGE IP
NODE NOMINATED NODE READINESS GATES LABELS
pod/myweb-rc-d7g8v 1/1 Running 0 4m19s 10.233.92.21
node3 <none> <none> app=web,env=dev
pod/myweb-rc-px69s 1/1 Running 0 4m19s 10.233.96.19
node2 <none> <none> app=web,env=dev
pod/myweb-rc-v9scp 1/1 Running 0 4m19s 10.233.90.15
node1 <none> <none> app=web,env=dev
--replicas: 3
으로 조정시 가장 최근에 만들어졌던 것들이 Terminating된다.
✔️ replace
yaml 파일을 수정하고 kubectl create
명령을 수행하면 에러가 발생한다.
kubectl replace -f myweb-rc.yaml
그럴 때는 replace
명령을 사용한다.
vagrant@k8s-node1:~/cont/rc$ kubectl replace -f myweb-rc.yaml
replicationcontroller/myweb-rc replaced
Every 1.0s: kubectl get rc,pods k8s-node1: Wed May 18 09:13:05 2022
NAME DESIRED CURRENT READY AGE
replicationcontroller/myweb-rc 2 2 2 8m31s
NAME READY STATUS RESTARTS AGE
pod/myweb-rc-px69s 1/1 Running 0 8m31s
pod/myweb-rc-v9scp 1/1 Running 0 8m31s
myweb-rc.yaml
의 replicas: 2
로 고치고 replace
실행한다.
정상적으로 반영된다.
vagrant@k8s-node1:~/cont/rc$ kubectl replace -f myweb-rc.yaml
replicationcontroller/myweb-rc replaced
Every 1.0s: kubectl get rc,pods k8s-node1: Wed May 18 09:13:35 2022
NAME DESIRED CURRENT READY AGE
replicationcontroller/myweb-rc 4 4 4 9m1s
NAME READY STATUS RESTARTS AGE
pod/myweb-rc-6pj7d 1/1 Running 0 11s
pod/myweb-rc-c8vm2 1/1 Running 0 11s
pod/myweb-rc-px69s 1/1 Running 0 9m1s
pod/myweb-rc-v9scp 1/1 Running 0 9m1s
replicas: 4
로 고치고 replace
실행한다.
정상적으로 반영된다.
myweb-rc.yaml
template:
metadata:
# name:
labels:
app: web
env: dev
tier: fe
다음과 같이 tier: fe
레이블을 추가하고 replace
를 실행해보자
vagrant@k8s-node1:~/cont/rc$ kubectl replace -f myweb-rc.yaml
replicationcontroller/myweb-rc replaced
vagrant@k8s-node1:~/cont/rc$ kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
myweb-rc-6pj7d 1/1 Running 0 2m54s app=web,env=dev
myweb-rc-c8vm2 1/1 Running 0 2m54s app=web,env=dev
myweb-rc-px69s 1/1 Running 0 11m app=web,env=dev
myweb-rc-v9scp 1/1 Running 0 11m app=web,env=dev
? 반영되지 않았다.
📌 여기서 주의할점 !
우리가 변경한 것은 템플릿의 label이다. 템플릿의 label은 파드를 만들 때 적용된다.
이미 만들어져 있는 것을 replace
한 것이므로 템플릿이 적용되지 않는다.
템플릿을 적용시키고 싶다면 파드를 새로 생성해야 한다.
마찬가지로 이미 실행 중인 파드가 있고 해당 파드를 만들 때 사용한 템플릿의 이미지를 변경한후 replace
한다면 실제로 반영되지 않는다.
만약 템플릿을 변경했고 적용하고 싶다면 파드를 고의적으로 지워준다.
myweb-rc.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: myweb-rc
spec:
replicas: 4
selector:
app: web
env: dev
# Pod Configure
template:
metadata:
labels:
app: web
env: dev
tier: fe
spec:
containers:
- name: myweb
#image: ghcr.io/c1t1d0s7/go-myweb
image: nginx
ports:
- containerPort: 8080
protocol: TCP
vagrant@k8s-node1:~/cont/rc$ kubectl replace -f myweb-rc.yaml
replicationcontroller/myweb-rc replaced
vagrant@k8s-node1:~/cont/rc$ kubectl delete po myweb-rc-v9scp
pod "myweb-rc-v9scp" deleted
Every 1.0s: kubectl get rc,pods k8s-node1: Wed May 18 09:22:25 2022
NAME DESIRED CURRENT READY AGE
replicationcontroller/myweb-rc 4 4 3 17m
NAME READY STATUS RESTARTS AGE
pod/myweb-rc-5wz87 0/1 ContainerCreating 0 5s
pod/myweb-rc-6pj7d 1/1 Running 0 9m1s
pod/myweb-rc-c8vm2 1/1 Running 0 9m1s
pod/myweb-rc-px69s 1/1 Running 0 17m
새로운 파드인 myweb-rc-5wz87
가 생성되었음을 확인할 수 있다.
확실히 적용됐는지 확인해보자
vagrant@k8s-node1:~/cont/rc$ kubectl describe pod myweb-rc-5wz87
Labels: app=web
env=dev
tier=fe
Containers:
myweb:
Container ID: containerd://c6915712f9aee05744412454c7fbe9aa163a9dc8050e6f7e2c926f6930d3dd7c
Image: nginx
tier: fe
레이블이 추가되었고 nginx 이미지로 변경된 것을 확인할 수 있다.
vagrant@k8s-node1:~/cont/rc$ kubectl delete pods -l app=web
pod "myweb-rc-5wz87" deleted
pod "myweb-rc-6pj7d" deleted
pod "myweb-rc-c8vm2" deleted
pod "myweb-rc-px69s" deleted
Every 1.0s: kubectl get rc,pods k8s-node1: Wed May 18 09:26:46 2022
NAME DESIRED CURRENT READY AGE
replicationcontroller/myweb-rc 4 4 4 22m
NAME READY STATUS RESTARTS AGE
pod/myweb-rc-529g6 1/1 Running 0 68s
pod/myweb-rc-dl2n5 1/1 Running 0 68s
pod/myweb-rc-fqf9d 1/1 Running 0 68s
pod/myweb-rc-zqn88 1/1 Running 0 68s
레이블을 지정해서 리소스를 모두 지우면 변경한 yaml 파일이 적용된 새로운 파드가 생성된다.
vagrant@k8s-node1:~/cont/rc$ kubectl delete pods --all
--all
옵션을 사용하면 한번에 지울 수 있다.
vagrant@k8s-node1:~/cont/rc$ cat myweb-rc.yaml
metadata:
name: myweb-rc-v1
vagrant@k8s-node1:~/cont/rc$ kubectl replace -f myweb-rc.yaml
Error from server (NotFound): error when replacing "myweb-rc.yaml": replicationcontrollers "myweb-rc-v1" not found
yaml 파일에서 metadata의 이름은 변경할 수 없다.
리소스의 속성 중에 변경이 가능한 속성 불가한 속성이 있다.
vagrant@k8s-node1:~/cont/rc$ kubectl explain rc.metadata.name
KIND: ReplicationController
VERSION: v1
FIELD: name <string>
DESCRIPTION:
Name must be unique within a namespace. Is required when creating
resources, although some resources may allow a client to request the
generation of an appropriate name automatically. Name is primarily intended
for creation idempotence and configuration definition. Cannot be updated.
More info: http://kubernetes.io/docs/user-guide/identifiers#names
rc.metadata.name
은 YAML 파일에서 수정 후 replace
할 수 없다.
✔️ patch
kubectl patch -f myweb-rc.yaml -p '{"spec": {"replicas": 3}}'
kubectl patch rc myweb-rc -p '{"spec": {"replicas": 3}}'
json
형식을 이용해 patch
할 부분을 지정하고 변경할 수 있다.
vagrant@k8s-node1:~/cont/rc$ kubectl patch -f myweb-rc.yaml -p '{"spec": {"replicas":2 }}'
replicationcontroller/myweb-rc patched
Every 1.0s: kubectl get rc,pods k8s-node1: Wed May 18 09:42:45 2022
NAME DESIRED CURRENT READY AGE
replicationcontroller/myweb-rc 2 2 2 38m
NAME READY STATUS RESTARTS AGE
pod/myweb-rc-fqf9d 1/1 Running 0 17m
pod/myweb-rc-zqn88 1/1 Running 0 17m
-f
의미는 내가 어떤 리소스를 패치할 것인지 선택하는 것 뿐이다.
vagrant@k8s-node1:~/cont/rc$ kubectl patch myweb-rc -p '{"spec": {"replicas":2 }}'
다음과 같이 실행해도 동일하다.
-p
가 중요한 부분인데 우리가 패치할 부분을 yaml이 아닌 json형식으로 저장한다.
replace | patch |
파일을 수정하고 교체하는 것, 수정하고자 하는 완전한 오브젝트를 제공해야 한다. | 변경하고자 하는 일부분만을 제공하면 된다. |
replace하기 위해서는 코드를 만들어야 한다. | 명령형 커맨드로 일부분만을 수정할 수 있다. |
myweb-rc.yaml
파일 은 오브젝트를 리소스로 만들기 위한 완전한 구조를 가지고 있다.
다시 말하면 -f
의미는 내가 어떤 리소스를 패치할 것인지 지칭하는 용도로 사용하는것 뿐이며 수정된 값은 -p '{"spec": {"replicas":2}}'
이부분이다.
replicas.json
{
"spec":
{"replicas": 2}
}
vagrant@k8s-node1:~/cont/rc$ kubectl patch rc myweb-rc --patch-file replicas.json
replicationcontroller/myweb-rc patched
--patch-file
이라는 옵션을 사용해 json
파일로 패치할 수도 있다.
하지만 json 형식은 길어지면 포맷 맞추기가 헷갈리기 때문에 웬만하면 인라인 형태로 사용하는 것이 편하다.
✔️ edit
kubectl edit -f myweb-rc.yaml
kubectl edit rc/myweb-rc
kubectl edit rc myweb-rc
etcd
에 저장된 리소스의 raw data
를 vi 에디터에서 실시간으로 수정할 수 있다.
vagrant@k8s-node1:~/cont/rc$ kubectl edit -f myweb-rc.yaml
replicationcontroller/myweb-rc edited
Every 1.0s: kubectl get rc,pods k8s-node1: Wed May 18 12:44:15 2022
NAME DESIRED CURRENT READY AGE
replicationcontroller/myweb-rc 3 3 3 3h39m
NAME READY STATUS RESTARTS AGE
pod/myweb-rc-9929q 1/1 Running 0 11s
pod/myweb-rc-fqf9d 1/1 Running 0 3h18m
pod/myweb-rc-zqn88 1/1 Running 0 3h18m
수정 후 저장하면 edited
되었다고 출력된다.
하지만 여전히 rc.metadata.name
은 변경할 수 없다.
만약 적용할 수 없는 예를 들어 replicas : two
같은 내용을 썼다면 에러 로그가 출력되며 다시 vi 에디터를 실행한다.
✔️ apply
kubectl apply -f myweb-rc.yaml
가장 강력한 명령어이다. apply
는 없으면 만들어주고 변경됐으면 변경 사항을 반영한다.
우선 myweb-rc.yaml
에서 replicas: 4 -> 2로 수정한뒤 apply를 실행한다.
vagrant@k8s-node1:~/cont/rc$ kubectl apply -f myweb-rc.yaml
replicationcontroller/myweb-rc created
다시 replicas: 2 -> 3 으로 변경하면
vagrant@k8s-node1:~/cont/rc$ kubectl apply -f myweb-rc.yaml
replicationcontroller/myweb-rc configured
Every 1.0s: kubectl get rc,pods k8s-node1: Wed May 18 12:53:07 2022
NAME DESIRED CURRENT READY AGE
replicationcontroller/myweb-rc 3 3 3 2m35s
NAME READY STATUS RESTARTS AGE
pod/myweb-rc-4k56n 1/1 Running 0 2m35s
pod/myweb-rc-9j8mm 1/1 Running 0 2m35s
pod/myweb-rc-pwgs7 1/1 Running 0 58s
configured
라고 뜬다.
✔️ log
kubectl logs rc/myweb-rc
로그를 볼 수 있다. 로그를 확인할 때는 오브젝트가 아닌 리소스의 이름을 지정해줘야 한다.
✔️ delete
vagrant@k8s-node1:~/cont/rc$ kubectl get rc
NAME DESIRED CURRENT READY AGE
myweb-rc 3 3 3 7m40s
vagrant@k8s-node1:~/cont/rc$ kubectl delete rc myweb-rc
replicationcontroller "myweb-rc" deleted
vagrant@k8s-node1:~/cont/rc$ kubectl get pods
No resources found in default namespace.
컨트롤러를 지우면 파드도 같이 지워진다.
만약 --cascade=orphan
옵션을 지정하면 컨트롤러만 지워지고 파드는 그대로 남는다.
레플리케이션 컨트롤러는 더 이상 사용하지 않을 것을 권장하며 레플리카셋이나 디플로이먼트로 대체하는 것을 권장한다.
✔️ ReplicaSets
ReplicationController → ReplicaSets 으로 대체되어 사용된다.
vagrant@k8s-node1:~/cont/rs$ kubectl api-resources | grep replicasets
replicasets rs apps/v1 true ReplicaSet
레플리카셋은 rs 이며 apps 그룹에 속한다.
vagrant@k8s-node1:~/cont/rs$ kubectl api-resources | grep apps/v1
참고로 apps 그룹에 속해있는 것은 전부 다 워크로드이다.
ReplicationController와 다른 점은 selector
부분이다.
vagrant@k8s-node1:~$ kubectl explain rs.spec.selector
KIND: ReplicaSet
VERSION: apps/v1
RESOURCE: selector <Object>
FIELDS:
matchExpressions <[]Object>
matchExpressions is a list of label selector requirements. The requirements
are ANDed.
matchLabels <map[string]string>
matchLabels is a map of {key,value} pairs. A single {key,value} in the
matchLabels map is equivalent to an element of matchExpressions, whose key
field is "key", the operator is "In", and the values array contains only
"value". The requirements are ANDed.
RC의 selector 하위는 더 이상 없지만 RS의 경우 추가 FIELDS
가 존재한다.
✔️ matchLabels
vagrant@k8s-node1:~/cont/rs$ kubectl explain rs.spec.selector.matchLabels
KIND: ReplicaSet
VERSION: apps/v1
FIELD: matchLabels <map[string]string>
DESCRIPTION:
matchLabels is a map of {key,value} pairs. A single {key,value} in the
matchLabels map is equivalent to an element of matchExpressions, whose key
field is "key", the operator is "In", and the values array contains only
"value". The requirements are ANDed.
myweb-rs.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: myweb-rs
spec:
replicas: 3
selector:
matchLabels: # 달라지는 부분
app: web
env: dev
template:
metadata:
labels:
app: web
env: dev
spec:
containers:
- name: myweb
image: ghcr.io/c1t1d0s7/go-myweb
ports:
- containerPort: 8080
protocol: TCP
RC와 RS는 작동원리가 100% 같다.
셀렉터를 지정할 때 matchLabels
라는 필드만 추가되었을 뿐이다.
vagrant@k8s-node1:~/cont/rs$ kubectl create -f myweb-rs.yaml
replicaset.apps/myweb-rs created
vagrant@k8s-node1:~/cont/rs$ kubectl get rs -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
myweb-rs 3 3 3 17s myweb ghcr.io/c1t1d0s7/go-myweb app=web,env=dev
vagrant@k8s-node1:~/cont/rs$ kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
myweb-rs-5vncl 1/1 Running 0 28s app=web,env=dev
myweb-rs-d7pvx 1/1 Running 0 28s app=web,env=dev
myweb-rs-fxsx2 1/1 Running 0 28s app=web,env=dev
vagrant@k8s-node1:~/cont/rs$ kubectl describe rs myweb-rs
Name: myweb-rs
Namespace: default
Selector: app=web,env=dev
Labels: <none>
Annotations: <none>
Replicas: 3 current / 3 desired
Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
Labels: app=web
env=dev
Containers:
myweb:
Image: ghcr.io/c1t1d0s7/go-myweb
Port: 8080/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 37s replicaset-controller Created pod: myweb-rs-5vncl
Normal SuccessfulCreate 37s replicaset-controller Created pod: myweb-rs-fxsx2
Normal SuccessfulCreate 37s replicaset-controller Created pod: myweb-rs-d7pvx
vagrant@k8s-node1:~/cont/rs$ kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
myweb-rs-5vncl 1/1 Running 0 3m56s app=web,env=dev
myweb-rs-d7pvx 1/1 Running 0 3m56s app=web,env=dev
myweb-rs-fxsx2 1/1 Running 0 3m56s app=web,env=dev
vagrant@k8s-node1:~/cont/rs$ kubectl label po myweb-rs-fxsx2 app-
pod/myweb-rs-fxsx2 labeled
vagrant@k8s-node1:~/cont/rs$ kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
myweb-rs-5vncl 1/1 Running 0 5m1s app=web,env=dev
myweb-rs-d7pvx 1/1 Running 0 5m1s app=web,env=dev
myweb-rs-fxsx2 1/1 Running 0 5m1s env=dev
myweb-rs-vqs98 1/1 Running 0 7s app=web,env=dev
app: web
레이블을 제거하면 RS가 새로운 파드를 만든다.
app 레이블이 지워진 파드는 더 이상 관리 대상이 아니다.
vagrant@k8s-node1:~/cont/rs$ kubectl label po myweb-rs-fxsx2 app=web
pod/myweb-rs-fxsx2 labeled
vagrant@k8s-node1:~/cont/rs$ kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
myweb-rs-5vncl 1/1 Running 0 7m34s app=web,env=dev
myweb-rs-d7pvx 1/1 Running 0 7m34s app=web,env=dev
myweb-rs-fxsx2 1/1 Running 0 7m34s app=web,env=dev
myweb-rs-vqs98 1/1 Terminating 0 2m40s app=web,env=dev
마찬가지로 myweb-rs-fxsx2
에 다시 app: web
레이블을 추가하면 가장 최근에 만들었던 myweb-rs-vqs98
파드가 삭제되는 것을 볼 수 있다.
vagrant@k8s-node1:~/cont/rs$ kubectl scale rs myweb-rs --replicas=2
replicaset.apps/myweb-rs scaled
vagrant@k8s-node1:~/cont/rs$ kubectl get pods
NAME READY STATUS RESTARTS AGE
myweb-rs-d7pvx 1/1 Running 0 8m52s
myweb-rs-fxsx2 1/1 Running 0 8m52s
✔️ matchExpressions
이제 RC와 RS가 다른점을 보자
결론부터 말하면 matchExpressions
의 유무가 RC와 RS를 구분한다.
key
- 레이블의 키를 지정한다.operator
- 해당되는 키의 value를 지정한다.values
-
일치성은 key
만 매칭할 수 있는 방법이 없다. 반드시 key
와 value
가 매칭되어야 한다.
집합성의 exists
와 doesnotexists
는 키만 매칭시킬 수 있다.
RS는 RC와 다르게 키만 매칭시킬 수 있는 집합성 기준을 제공한다.
myweb-rs-set.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: myweb-rs-set
spec:
replicas: 3
selector:
matchExpressions: # 달라지는 부분
- key: app
operator: In
values:
- web
- key: env
operator: Exists
template:
metadata:
labels:
app: web
env: dev
spec:
containers:
- name: myweb
image: ghcr.io/c1t1d0s7/go-myweb
ports:
- containerPort: 8080
protocol: TCP
vagrant@k8s-node1:~/cont/rs$ kubectl create -f myweb-rs-set.yaml
replicaset.apps/myweb-rs-set created
vagrant@k8s-node1:~/cont/rs$ kubectl get po --show-labels
NAME READY STATUS RESTARTS AGE LABELS
myweb-rs-d7pvx 1/1 Running 0 18m app=web,env=dev
myweb-rs-fxsx2 1/1 Running 0 18m app=web,env=dev
myweb-rs-set-fbl5c 1/1 Running 0 6s app=web,env=dev
myweb-rs-set-gxnnm 1/1 Running 0 6s app=web,env=dev
myweb-rs-set-vtjk6 1/1 Running 0 6s app=web,env=dev
vagrant@k8s-node1:~/cont/rs$ kubectl get rs
NAME DESIRED CURRENT READY AGE
myweb-rs 2 2 2 18m
myweb-rs-set 3 3 3 24s
vagrant@k8s-node1:~/cont/rs$ kubectl get rs -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
myweb-rs 2 2 2 18m myweb ghcr.io/c1t1d0s7/go-myweb app=web,env=dev
myweb-rs-set 3 3 3 30s myweb ghcr.io/c1t1d0s7/go-myweb app in (web),env
vagrant@k8s-node1:~/cont/rs$ kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
myweb-rs-d7pvx 1/1 Running 0 18m app=web,env=dev
myweb-rs-fxsx2 1/1 Running 0 18m app=web,env=dev
myweb-rs-set-fbl5c 1/1 Running 0 45s app=web,env=dev
myweb-rs-set-gxnnm 1/1 Running 0 45s app=web,env=dev
myweb-rs-set-vtjk6 1/1 Running 0 45s app=web,env=dev
사실 동일하게 선언한 같은 레이블이지만 리소스에 따라 정교하게 셀렉팅하고 있다.
vagrant@k8s-node1:~/cont/rs$ kubectl scale rs myweb-rs --replicas=3
replicaset.apps/myweb-rs scaled
vagrant@k8s-node1:~/cont/rs$ kubectl get po
NAME READY STATUS RESTARTS AGE
myweb-rs-9r5ls 1/1 Running 0 4s
myweb-rs-d7pvx 1/1 Running 0 20m
myweb-rs-fxsx2 1/1 Running 0 20m
myweb-rs-set-fbl5c 1/1 Running 0 2m37s
myweb-rs-set-gxnnm 1/1 Running 0 2m37s
myweb-rs-set-vtjk6 1/1 Running 0 2m37s
정확하게 잘 만들어낼 수 있고 이름으로 구분 가능하다.
vagrant@k8s-node1:~/cont/rs$ kubectl get pod/myweb-rs-set-vtjk6 -o yaml
ownerReferences:
- apiVersion: apps/v1
blockOwnerDeletion: true
controller: true
kind: ReplicaSet
name: myweb-rs-set
uid: 56afea1c-60e1-44c1-9c54-18274df7703b
resourceVersion: "256484"
uid: 40a1c661-1b77-457d-a97c-4bcfa7d59eac
metadata에 ownerReferences
라는 속성이 있다. 파드에 어떤 컨트롤러에 의해서 제어되는 지 정보가 추가된다.
예전에는 파드에 이 정보가 없었다.
만약 RC가 있고 파드를 3개를 셀렉팅해서 관리하고 있었다고 하면, 다른 RS가 RC의 파드를 셀렉팅하는 오류가 있었다.
궁극적으로 우리가 정의할 때는 셀렉터를 이용해서 파드를 지정하고 거기에 의해 만들어진 파드는 어떤 컨트롤러에의해 제어받는지 소유권을 세팅한다. 그래서 오류가 발생하지 않는다.
vagrant@k8s-node1:~/cont/rs$ kubectl get all
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.233.0.1 <none> 443/TCP 2d6h
모든 타입을 볼 수 있다. api-resources
의 모든 종류를 커버하는 것은 아니다.
vagrant@k8s-node1:~/cont/rs$ kubectl get -n kube-system rs
NAME DESIRED CURRENT READY AGE
calico-kube-controllers-5788f6558 1 1 1 2d6h
coredns-8474476ff8 2 2 2 2d6h
dns-autoscaler-5ffdc7f89d 1 1 1 2d6h
kube-system
에도 레플리카셋이 존재한다.
레플리카셋의 이름이 calico-kube-controllers-5788f6558
랜덤하게 붙는 것인데 역시 이 레플리카셋도 다른 컨트롤러(디플로이먼트)에 의해 만들어진것이다.
vagrant@k8s-node1:~/cont/rs$ kubectl get -n kube-system rs coredns-8474476ff8 -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
coredns-8474476ff8 2 2 2 2d6h coredns k8s.gcr.io/coredns/coredns:v1.8.0 k8s-app=kube-dns,pod-template-hash=8474476ff8
셀렉터를 볼 수 있다.
vagrant@k8s-node1:~/cont/rs$ kubectl get po -n kube-system -l k8s-app=kube-dns
NAME READY STATUS RESTARTS AGE
coredns-8474476ff8-4bmms 1/1 Running 3 (13h ago) 2d6h
coredns-8474476ff8-q7svm 1/1 Running 4 (13h ago) 2d6h
파드가 더 많아지면 셀렉터를 이용해 확인할 수 있다.
vagrant@k8s-node1:~/cont/rs$ kubectl get po -n kube-system -l pod-template-hash=8474476ff8
NAME READY STATUS RESTARTS AGE
coredns-8474476ff8-4bmms 1/1 Running 3 (13h ago) 2d6h
coredns-8474476ff8-q7svm 1/1 Running 4 (13h ago) 2d6h
vagrant@k8s-node1:~/cont/rs$ kubectl get rc -n kube-system
No resources found in kube-system namespace.
RS이라고 하는 컨트롤러가 우리가 k8s에서 사용하는 대부분의 컨트롤러이다.
로드 밸런서 서비스를 추가할 것이라면 무조건 레플리카셋을 사용해야 한다.
'DevOps > Kubernetes' 카테고리의 다른 글
[Kubernetes] Kubespray로 노드 추가/삭제하기 (0) | 2022.05.20 |
---|---|
[Kubernetes] DaemonSet (데몬셋) (0) | 2022.05.20 |
[Kubernetes] Pod의 LifeCycle (파드의 생명주기) (0) | 2022.05.19 |
[Kubernetes] Annotation (어노테이션) (0) | 2022.05.18 |
[Kubernetes] Label, LabelSelector (레이블, 레이블셀렉터) (0) | 2022.05.18 |
영차영차 성장 블로그
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!