1. Resource Management
- Pod를 배포할 때 CPU / Memory / Network Bandwidth(Not supported yet)를 어떻게 할당할지 결정
- Memory는 MegaByte, CPU는 millisecond의 단위 사용 (1,000ms = 1vCore)
- limits는 Pod의 Max Resource, requests는 Min Resource이다
apiVersion: v1
kind: Pod
metadata:
name: frontend
spec:
containers:
- name: db
image: mysql
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
- name: wp
image: wordpress
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
# kubectl describe
# kubectl top {nodes or pods}
- ResourceQuota : Namespace 내 정의되는 CPU와 Memory 전체의 상한
apiVersion: v1
kind: ResourceQuota
metadata:
name: demo
spec:
hard:
requests.cpu: 500m
requests.memory: 100Mib
limits.cpu: 700m
limits.memory: 500Mib
- LimitRange : 각 컨테이너에 적용되는 Quota의 범위
apiVersion: v1
kind: LimitRange
metadata:
name: demo
spec:
limits:
- default:
cpu: 600m
memory: 100Mib
defaultRequest:
cpu: 100m
memory: 50Mib
max:
cpu: 1000m
memory: 200Mib
min:
cpu: 10m
memory: 10Mib
type: Container
* Overcommitted State : 컨테이너의 limit의 총합이 물리적인 리소스를 넘어서는 상태(Resource Starving)이다. 이런 상태를 해결하기위해서 K8s에서는 CPU Throttling으로 할당된 CPU를 줄이거나 컨테이너를 Restart 시킨다.
2. Scheduling
- Taint : Pod가 특정 노드로 배포되지 않도록 하는 마킹 기능으로 <key>=<value>:<effect>의 형식으로 사용된다.
ex) Master Node에 Admin 기능의 Pod만 배포되도록 하는 경우
- Toleration : key와 value가 일치할 때 Taint 처리된 Node로 배포가 가능하도록 하는 기능
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
tolerations:
- key: "example-key"
operator: "Exists"
effect: "NoSchedule"
* key가 없으면 그냥 toleration 처리한다.
...
tolerations:
- operator: "Exists"
- NoSchedule : Taint에 대해서 Tolerate 하지 않음. (Taint 처리 전에 배포된 Pod는 영향을 받지 않는다)
- PerferNoSchedule : Resource 부족 등의 이유로 다른 Node에 배포가 불가능한 경우에 Toleration
- NoExecute : Taint에 대해 Torerate 하지 않으며, 기존에 배포된 Pod도 제거하여 다른 Node로 Migration한다. Node를 Upgrade 또는 Restart하기 위해 Pod를 제거할 때 주로 사용
* tolerationSeconds : Toleration을 적용 받는 기간으로, 이 기간이 지나면 toleration이 사라지고 해당 Pod는 제거
# kubectl taint nodes [NODE_NAME] [Key]=[Value]:[Effect]
# kubectl taint nodes node1 key=value:NoSchedule
# kubectl taint node -l myLabel=X dedicated=foo:PreferNoSchedule
* Toleration이 있다고해서 Taint처리된 Node로 반드시 배포되는 것은 아니다.
- Node Affiniy
- Hard affinity : nodeSelector와 같다.
- Soft affinity : 되도록이면 조건에 맞는 Node로 가중치에 따라 Pod를 배포
pod-with-node-affinity.yaml docs/concepts/configuration
apiVersion: v1
kind: Pod
metadata:
name: with-node-affinity
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution: ### Hard affinity
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/e2e-az-name
operator: In
values:
- e2e-az1
- e2e-az2
preferredDuringSchedulingIgnoredDuringExecution: ### Soft affinity
- weight: 1
preference:
matchExpressions:
- key: another-node-label-key
operatior: In
values:
- another-node-label-value
containers:
- name: with-node-affinity
image: k8s.gcr.io/pauser:2.0
- Pod Affinity
스케쥴러가 Affinity설정을 기반으로 새로운 Pod를 배포할 때, 이미 배포된 Pod의 Label(app=mongodb)과 일치하는 Node를 찾는다. 그리고 해당 Node의 topologyKey(zone:z1)를 받은 뒤, 그 값과 일치하는 Node로 새로운 Pod를 배포한다.
* topologyKey(Node Label) : Node, Rack, Zone, Region과 같은 Place 개념
→ Node-2의 Label(zone:z1)과 일치하는 Node들이 배포 타겟이 된다.
Pod Affinity는 주로, 아래와 같이 사용하기 위해 설정한다.
- DB Pod를 Backend Server가 있는 Rack의 Node에 배포하는 경우
- Front Server를 Backend Server와 동일한 Zone에 배포하는 경우
- 한 Cluster를 여러 다른 Node들에 분산시켜 배포하는 경우
ex1)
apiVersion: v1
kind: Pod
metadata:
name: with-pod-affinity
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: security
operator: In
values:
- S1
topologyKey: cloud/zone
containers:
- name: with-pd-affinity
image: k8s.gcr.io/pause:2.0
ex2) 하나의 Node에 Redis-cache가 2개 이상 중첩되어 배포되지 않도록 하는 경우
kind: Deployment
metadata:
name: redis-cache
spec:
selector:
matchLabels:
app: store
replicas: 3
template:
metadata:
labels:
app: store
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- store
topologyKey: "kubernetes.io/hostname"
containers:
- name: redis-server
iamge: redis:3.2-alpine
→ redis가 배포된 Node의 hostname과 같지 않은 Node에만 해당 Pod를 배포
ex3) Nginx가 한 Node에 하나씩 Redis와 같이 Pair로 배포되는 경우
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-server
spec:
selector:
matchLabels:
app: web-store
replicas: 3
template:
metadata:
labels:
app: web-store
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExpression:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- web-store
topologyKey: "kubernetes.io/hostname"
podAffinity:
requiredDuringSchedulingIgnoredDuringExpression:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- store
topologyKey: "kubernetes.io/hostname"
containers:
- name: web-app
iamge: nginx:1.12-alpine
- Anti-affinity
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: frontend
spec:
replicas: 5
template:
...
spec:
Affinity:
podAntiAffinty:
requiredDuringSchedulingIgnoredDuringExecution:
- topologyKey: kubernetes.io/hostname
labelSelector:
matchLabels:
app: backend
3. Reference
Kubernetes Advanced Workshop
조대협의 블로그
'System Engineering > Kubernetes' 카테고리의 다른 글
Kubernetes Lease (Node Heartbeat) (0) | 2022.01.10 |
---|---|
8. K8s AutoScaling (0) | 2021.04.11 |
6. K8s Volume (0) | 2021.04.05 |
5. K8s Lifecycle / Configmap (0) | 2021.04.02 |
4. K8s Service / Ingress (0) | 2021.03.30 |