## NodeLabels
우리는 pod에 라벨링을 해서 service나, deployment 또는 cli 커맨드상에서 selector조건에 맞는 라벨링을 가진 pod들에 대해서 컨트롤하는걸 배웠다. Nodelabels는 이런 pod뿐 아니라, 노드 자체에 라벨링을 하는 기능이다.
바로 예시를 들어보자면, 마스터노드가 pod를 생성하려고 할때, 이 pod가 생성될 노드를 골라야 하는 상황이 생겼다고 하자.
물론 우리는 예전에 pod yaml에서 resource로 cpu나 ram을 지정해줘서 알아서 선택적으로 배치 혹은 펜딩상태가 되도록 조절할 수 있었다. 하지만 nodelabel은 아예 리소스분량뿐 아니라, 여러가지 방향으로 라벨링만으로 리소스들을 배치시킬 수 있다.
worker node1는 아주 좋은 컴퓨터로 돌아가고 있는 노드라 computer: supercomputer이라는 라벨링이 되어있고, worker node2는 개똥컴이라서 computer: ddongcomputer이라는 라벨링이 되어있다고 하자.
만약 엄청 무거운 작업을 하는 이미지로 만든 컨테이너가 있는 pod를 생성하려고 할때 똥컴인 worker node2에 생성이 된다고 한다면, 이 노드는 이 pod를 띄우고 돌리는 순간 노드가 터져버리게 될거다.
만약 이 생성하려는 pod의 yaml파일에서 computer: supercomputer이라는 노드셀렉터를 설정해둔다면, 이 pod를 create하는 순간, 알아서 worker node1을 선택해서 생성되게 될거다.
# node에 라벨링하기 cli 명령어
kubectl label nodes <노드이름> <라벨링키>=<라벨링값>
이게 노드에다가 라벨링하는 양식이다. 물론 마스터노드에서 치삼
위에 그림대로 worker1노드에는 슈퍼컴, worker2노드에는 똥컴이라는 라벨링을 해줄것이다.
kubectl label nodes worker1 computer=supercomputer
kubectl label nodes worker2 computer=ddongcomputer
# node에 라벨링 확인하는 명령어
기본적인 라벨링 확인 명령어는
kubectl get nodes --show-labels
이렇게 된다.
결과가 복잡한데 빨간줄 쳐놓은것처럼 우리가 아까 worker1, worker2노드에 각각 해줬던 슈퍼컴, 똥컴 라벨링이 잘 되어있는것을 확인할 수 있다.
그 외에 복잡한 라벨링들이 더 있는데, 이건 쿠버네티스가 기본적으로 해준 노드라벨링이다.
조금 더 깔끔하게 우리가 원하는 라벨링만 보려면,
kubectl get nodes -L <라벨링키>
이런데, 우리는 computer이라는 노드라벨링을 보고 싶으니까..
kubectl get nodes -L computer
붙여준 슈퍼컴, 똥컴 라벨링이 computer 라벨링키에 잘 나와있다.
-L 라벨링키 를 쓰면 일반적인 node테이블 나오는데서 라벨링키의 컬럼이 추가되서 보이게 된다.
# nodeSelector을 가진 pod의 yaml양식
apiVersion: v1
kind: Pod
metadata:
name: super-heavy-pod
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
nodeSelector:
computer: supercomputer
저기 보면 nodeSelector에 computer: supercomputer이라는 라벨링을 볼 수 있는데, 이 파드는 해당 노드라벨링이 있는 node에 만들겠다는 거다. containers필드와 같은레벨에 nodeSelector필드를 만들어준다.
pod를 생성해보면,
kubectl create -f test-nodesel-pod1.yaml
pod가 supercomputer이라는 라벨링을 가진 worker1노드에 잘 생성된걸 알 수 있다.
그냥 우연찮게 순서대로 worker1노드에 생성되었다고 생각하면 라벨링을 서로 바꾸고 테스트 해보면 된다.
# nodeselector에 expression사용하기
controller/ replicaSet & deployment
하씨발 이틀동안 적어놓은 포스팅 임시저장 싹다 사라져서 다시 적어야 한다 ㅈ같은씨발 # replicaSet replicaSet은 replication controller와 거의 비슷하다고 봐도 될것같다. 그냥 파드 수를 보장하는기능
jacobowl.tistory.com
이전 replicaSet 포스팅에서 replication controller타입 컨트롤러와 replicaSet타입의 컨트롤러의 차이를 포스팅했었는데 이 둘의 차이는 셀렉터가 더 업그레이드 됐냐 차이이다. 이게 expression이다.
자세한 설명은 직접 포스팅을 읽어보면 되니까 생략하고 이제 nodeSelector에 expression을 사용하는 방법은 이렇다.
apiVersion: v1
kind: Pod
metadata:
name: super-super-heavy-pod
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: computer
operator: NotIn
values:
- ddongcomputer
바로 nodeSelector로 들어간게 아니라 affinity라고 필드에다가 이것저것 깊이 더 만들어서 matchExpressions라는 필드부터 우리가 아는 expression을 사용할 수 있다.
matchExpressions에서 computer이란 라벨링키에 ddongcomputer라는 값이 없는 node에만 super-super-heavy-pod를 만들겠다는 양식이다.
강의에는 없는데 공식문서에서 찾아온거다.
Assigning Pods to Nodes
You can constrain a Pod so that it is restricted to run on particular node(s), or to prefer to run on particular nodes. There are several ways to do this and the recommended approaches all use label selectors to facilitate the selection. Often, you do not
kubernetes.io
암튼 이걸로 pod를 생성해보면,
kubectl create -f test-nodesel-pod.yaml
똥컴인 worker2노드가 아닌 슈퍼컴인 worker1노드에 pod가 생성된것을 확인할 수 있다.
# 만약 해당 노드 라벨링이 없는 pod를 생성하려 한다면?
apiVersion: v1
kind: Pod
metadata:
name: normal-pod
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
nodeSelector:
computer: normalcomputer
우리는 아까 supercomputer와 ddongcomputer이라는 라벨링만 만들었고 현재 클러스터에는 normalcomputer이라는 라벨링을 가진 노드는 없다.
이 pod를 생성해보려 한다면?
kubectl create -f test-nodesel-pod1.yaml
kubectl get pods -o wide
pod가 생성되지 않고 pending상태로 머물게 된다.
# 노드셀렉터는..
저렇게 computer가 똥컴이냐 슈퍼컴이냐 장난식으로 라벨링하지는 않고, cpu가 있냐, 몇코어냐, gpu가 있냐 없냐 등등으로 조절을 한다. 사실 hdd쪽도 1gp이상 이하 등등 옵션도 지원해줌 좋겠는데 그건 모르겠다.
# 기타 노드 셀렉터 명령어
kubectl label node <노드이름> <라벨링키>=<라벨링값> --overwrite
만약 computer라는 라벨링에 supercomputer이라는 라벨링값이 있다고 할때 만약 normalcomputer이라는 값으로 바꾸고 싶다면, --overwrite이라는 옵션으로 덮어쓰기를 하면 된다.
kubectl label node worker1 computer=normalcomputer --overwrite
이러면 덮어써진다.
kubectl label node <노드이름> <라벨링키>-
이건 라벨 삭제하는 cli명령어인데 라벨링키에 - 마이너스를 붙여주면 해당 노드라벨은 사라진다.
## annotations
# 개념
파드 실행하는 관리자한테 정보를 전해주는 목적
관리를 위해 필요한 정보를 기록할 용도로 사용
# k8s한테 설정 해달라는 용도로 쓸때
예전에 deployment에서 롤링업데이트 할때 쓴 내용이지만 복습겸 사용해본다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: babo-dep
spec:
replicas: 3
selector:
matchLabels:
name: muzzipage
template:
metadata:
labels:
name: muzzipage
spec:
containers:
- image: nginx:1.14
name: nginx
이렇게 기본적인 deployment양식이 있다.
여기에 annotations필드를 만들어서 롤링업데이트에 남는 히스토리를 직접 적어보겠다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: babo-dep
annotations:
kubernetes.io/change-cause: nginx1.14
spec:
replicas: 3
selector:
matchLabels:
name: muzzipage
template:
metadata:
labels:
name: muzzipage
spec:
containers:
- image: nginx:1.14
name: nginx
annotations필드에 kubernetes.io/change-cause: nginx1.14라는 키값을 적어넣어주면 쿠버네티스 엔진이 rolling update & roll back시에 nginx.1.14라는 이름으로 적용시켜 줄 거다.
이렇게 deployment를 생성해주면,
kubectl create -f test-deploy.yaml
kubectl rollout history delpoyment babo-dep
아까 annotations필드에 설정된 값이 적용되어서 pod가 생성되었다.
여기서 만약 rolling update를 하고 싶다면
이렇게 set명령어로 업데이트를 해줄 수 있지만,
kubectl set image deployment babo-dep nginx=nginx:latest --record
rollout history가 명령어로 드럽게 남기때문에,
직접 yaml파일을 수정 후, apply로 적용시켜주면 된다.
vi test-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: babo-dep
annotations:
kubernetes.io/change-cause: nginx-1.14
spec:
replicas: 3
selector:
matchLabels:
name: muzzipage
template:
metadata:
labels:
name: muzzipage
spec:
containers:
- image: nginx:1.14
name: nginx
kubectl apply -f test-deploy.yaml
kubectl rollout history deployment babo-dep
원하는 양식으로 남게된다.
참고로 ingress.yaml을 생성할때도 annotations을 설정해줬었다. 설정 안했을땐 ingress가 생성되지 않았던걸로 기억함..
ingress/ test
실제로 ingress 컨트롤러로 dog.com이라는 사이트를 만들어 볼 예정이다. # 먼저 기본 namespace를 바꾸자. 쿠버네티스 namespace # 기본 개념 네임스페이스는 리소스들을 분리하고 관리하는거다. 그냥 컴
jacobowl.tistory.com
# 관리용으로 기록하려고 할때.
apiVersion: apps/v1
kind: Deployment
metadata:
name: babo-dep
annotations:
kubernetes.io/change-cause: nginx-1.14
owner: muzzi
spec:
replicas: 3
selector:
matchLabels:
name: muzzipage
template:
metadata:
labels:
name: muzzipage
spec:
containers:
- image: nginx:1.14
name: nginx
annotations필드에 이 deployment의 주인은 muzzi라고 설정해주었다.
그리고 deployment를 생성해주면,
kubectl create -f test-deploy.yaml
그리고 describe명령어로 확인을 해보자
kubectl describe deployment babo-dep
이 deployment의 주인은 muzzi라는 annotation키값이 잘 들어간걸 확인 할 수 있다.
# 자주쓰이는 annotations
사실 관리용도로 owner가 muzzi라는 키값은 뭐.. 사실 주석달기용정도로밖에 생각안들지만, 중요한건 k8s에 직접 이 resource를 어떻게 관리해달라는 annotations가 많이 중요할것 같다. 인그레스도 이거 잘못적었더니 생성안되고 에러띄우고.. 암튼 gpt한테 자주쓰이는거 물어봤더니
Kubernetes에서 사용되는 annotation은 매우 다양하며, 어플리케이션 및 운영 환경에 따라 다를 수 있습니다. 그러나 몇 가지 일반적인 annotation이 있습니다. 여기서는 일반적으로 사용되는 몇 가지 annotation을 소개하겠습니다:
- kubectl.kubernetes.io/last-applied-configuration:
- 리소스가 마지막으로 어떤 설정으로 생성되었는지를 나타냅니다. kubectl apply 명령으로 리소스를 생성할 때 이 annotation이 자동으로 추가됩니다.
- prometheus.io/scrape 및 prometheus.io/port:
- Prometheus 모니터링 시스템과 통합할 때 사용되는 annotation입니다. prometheus.io/scrape: "true"로 설정하면 해당 서비스가 스크랩되어 모니터링됩니다.
- ingress.kubernetes.io/rewrite-target:
- Ingress 리소스에서 사용되며, 요청 경로를 재작성할 때 사용됩니다. 클라이언트의 요청 경로를 다른 경로로 재작성하는 데 유용합니다.
- nginx.ingress.kubernetes.io/affinity:
- Nginx Ingress 컨트롤러에서 사용되는 annotation으로, 세션 지속성과 관련된 설정을 지정합니다.
- scheduler.alpha.kubernetes.io/critical-pod:
- 크리티컬 파드(예: kube-system 내의 파드)를 특별히 스케줄링하는 데 사용되는 annotation입니다.
- helm.sh/hook:
- Helm 차트에서 사용되며, 특정 이벤트에서 실행되어야 하는 훅을 지정합니다. 예를 들어, pre-install, post-install, pre-delete, post-delete 등이 있습니다.
- cert-manager.io/issuer:
- Cert-Manager와 통합할 때 사용되는 annotation으로, SSL 인증서의 발급자(issuer)를 지정합니다.
- sidecar.istio.io/inject:
- Istio 서비스 매쉬에서 사용되며, sidecar 컨테이너를 자동으로 주입하도록 하는 annotation입니다.
이는 일부 예시일 뿐이며, 각 애플리케이션 및 도구에 따라 다양한 annotation이 있을 수 있습니다. 사용 중인 리소스와 툴에 따라서 필요한 annotation을 확인하시기 바랍니다.
뭐 이렇다는데 난 아직 쿠찔이라 잘 모르겠고.. 아래 공식문서를 좀 더 배우고 자세히 살펴보아야 겠다.
Well-Known Labels, Annotations and Taints
Production-Grade Container Orchestration
kubernetes.io
'k8s > concept' 카테고리의 다른 글
configMap (0) | 2023.12.21 |
---|---|
deployment strategy - blue&green / rolling / canary (0) | 2023.12.18 |
labels (0) | 2023.12.12 |
ingress/ test (0) | 2023.12.11 |
ingress/ 설치 & 개념 (0) | 2023.12.11 |