Kubectl
kubectl은 Kubernetes Cluster를 관리하기 위한 도구임
리소스 생성 (create), Update (apply)
- create -> 최초 생성할 때 사용함
- apply -> 최초든, 중간에 값이 변경된 정보든 다 사용가능
리소스 삭제 (delete)
리소스 생성, 삭제에서는 -f로 Manifest File의 경로를 지정
=> 경로의 Local Directory가 될 수 있고, http 경로도 가능함
리소스 상태 조회 (get)
kubectl get {Resource Type} [Resource Name] [-Aw] [-n <namespace name>]
- -A : 모든 namespace에 대해서 조회
- -w : watch
- Resource Type
- pod
- ing (ingress)
- deployment
- svc (service)
- node
- etc...
리소스 정보 확인 (describe)
kubectl describe {Resource Type} [Resource Name] [-Aw] [-n <namespace name>]
Pod의 Log 확인 (logs)
kubectl logs -n <namespace> <podname> [-f] [container name]
Pod에서 명령어 실행 (exec)
kubectl exec -n <namespace> {-it | -d} <podname> [containername] -- <command>
Deployment 재시작 (rollout)
kubectl rollout restart [-n] deployment/abc
Replica 개수 Scale (scale)
kubectl scale [--resource-version=version] [--current-replicas=count] -- replicas=COUNT (-f FILENAME | TYPENAME)
Cloud Controller Manager를 통해서 Kubernetes가 Public Cloud와 통신 (API 요청 전달)을 할 수 있음
=> Cloud Controller Manager는 Kubelet 설정을 진행해야 가능하고, Kubernetes Cluster를 만들 때, Cloud Controller Manager를 사용할 것이라고 지정해줘야함
Ingress, Service, Deployment, Pod ...
CNI는 Container Network Interface로 컨테이너 간의 네트워킹을 제어할 수 있는 플러그인이 지켜야 하는 표준임
=> 이런 CNI가 있어야지만 Kubernetes Cluster 내부 Networking을 처리할 수 있음
Service
docs에 의하면 정의는 이러함
파드 집합에서 실행중인 애플리케이션을 네트워크 서비스로 노출하는 추상화 방법
서비스의 대상이 되는 파드 집합은 (보통) 셀렉터로 결정된다. 많은 파드가 추가되거나 제거되면, 셀렉터와 일치하는 파드의 집합도 변경된다. 서비스는 네트워크 트래픽을 현재 워크로드를 위한 파드 집합으로 보낼 수 있는지 확인한다.
Selector
잠깐 Selector를 보고 넘어가자면
셀렉터는 Service가 어떤 Pod를 대상으로 트래픽을 보낼지 결정하는 조건이라고 생각하면됨
=> Lable을 기반으로 조건을 정의
apiVersion: v1
kind: Pod
metadata:
name: example-pod
labels:
app: my-app
env: production
위와 같이 Kubernetes의 Pod들은 보통 레이블(키-값 쌍)로 태그가 되어 있음
(app: my-app 과 env: production)
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app # 이 Selector가 "app=my-app" 레이블이 있는 Pod를 찾음
ports:
- protocol: TCP
port: 80 # Service의 포트
targetPort: 8080 # Pod의 포트
type: ClusterIP # 기본값: 내부에서만 접근 가능한 서비스
Service는 spec.selector 필드를 사용해서 Pod를 선택함
=> Selector에 명시된 레이블과 일치하는 Pod들을 대상으로 트래픽을 전달
다시 돌아와서 Service를 정리해보면
- Pod로 향하는 Traffic을 Routing 할 수 있는 Object
- Service와 Pod를 연결해두면, 여러 Pod에 대해서 내부적으로 Load Balancing을 수행함
- Service의 Type은 크게 3가지가 존재
- ClusterIP
=> Cluster 내부에서 접근할 수 있도록 Network를 open
(Round-Robin 방식으로 요청을 Pod들에 분산) - NodePort
=> 해당 노드의 실제 IP:Port를 통해 내부 Pod에 접근할 수 있도록 Network를 open - LoadBalancer
=> 외부 리소스로부터 Traffic을 받아들이고, 내부의 도착점으로 전달해주는 역할
- 외부 리소스
- ELB와 같은 외부 Load Balancer가 필요함
- 외부 Load Balancer는각 Node에 배치된 부하를 처리할 Service로 전달
- ELB와 같은 외부 Load Balancer가 필요함
- Type이 Load Balancer면, Kubernetes에 배포된 LoadBalancer나, Ingress Controller의 정책에 따라서 별도 자원을 생성할 수 있음
- 외부 리소스
- ClusterIP
결론은 Service는 Selector를 통해 Routing할 Pod를 결정
클러스터 내부의 ClusterIP는 가상 IP라 모든 노드에서 접근할 수 있기 때문에 이를 통해 Pod들로 트래픽을 라우팅함
이때 각 노드에 있는 kube-proxy가 Service의 라우팅 정보를 유지함
=> 요청이 Service의 ClusterIP로 오면, kube-proxy가 연결된 Pod 목록에서 적절한 Pod로 트래픽을 전달
Deployment
docs에 의하면 정의는 이러함
일반적으로 로컬 상태가 없는 파드를 실행하여 복제된 애플리케이션을 관리하는 API 오브젝트.
각 레플리카는 파드로 표현되며, 파드는 클러스터의 노드에 분산된다. 로컬 상태가 필요한 워크로드의 경우 스테이트풀셋(StatefulSet)의 사용을 고려한다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deployment
spec:
replicas: 3 # 복제본 개수
selector:
matchLabels:
app: my-app # 파드를 선택할 레이블
template: # Replica의 Template
metadata:
labels:
app: my-app # 파드에 지정할 레이블
spec:
containers:
- name: my-container
image: nginx:latest # 컨테이너 이미지
ports:
- containerPort: 80
- Deployment에서는 Stateless한 Application을 배포
- Deployment는 Replica를 활용해서 손쉽게 scale할 수 있음
- Deployment에서는 Replica의 Template을 지정해주어야함
=> nginx:latest 이미지를 기반으로 컨테이너 실행
Ingress
외부 Traffic을 내부 Service로 전달할 수 있게 해주는 Object
(여러 서비스에 대해 하나의 외부 IP를 사용할 수 있도록 트래픽 관리)
Ingress를 통해서 Cluster 외부에서 온 요청을 배포한 Ingress Controller에서 처리할 수 있게 해줌
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
spec:
rules:
- host: "example.com"
http:
paths:
- path: "/api"
pathType: Prefix
backend:
service:
name: backend-service
port:
number: 80
- path: "/"
pathType: Prefix
backend:
service:
name: frontend-service
port:
number: 80
=> Ingress를 활용한 경로 기반 라우팅
Ingress Controller
Ingress 리소스를 감시하고 규칙에 따라 라우팅 설정을 적용함
(외부 HTTP/HTTPS 트래픽을 적절한 서비스로 전달, SSL/TLS 설정도 처리함)
Ingress Controller 종류로는
- AWS Load Balancer Controller -> L4, L7
- Nginx Ingress Controller -> L4
- Istio Ingress Controller -> L4
Ingress만 정의하면 아무 일도 일어나지 않으며, 반드시 Ingress Controller가 클러스터에 설치되어 있어야함
트래픽 흐름 요약
1. 외부 사용자가 HTTP/HTTPS 요청을 보내면 Ingress Controller가 먼저 받음
2. Ingress Controller는 라우팅 규칙에 따라 Service로 요청을 전달함
=> Ingress 리소스에서 설정한 도메인이나 경로 규칙에 따라 처리
3. Service는 요청을 파드 집합으로 전달하고 트래픽을 로드밸런싱함
4. 파드가 요청을 처리하고 응답을 반환함
만약 Ingress를 사용하지 않고 LoadBalancer Service만 사용할 경우?
1. 외부 로드 밸런서 (ex. AWS ELB)가 Service에 트래픽을 전달
2. Service는 트래픽을 선택된 파드로 라우팅
3. 파드가 요청을 처리하고 응답을 반환
Service는 Pod로 트래픽을 라우팅
(진입점이 클러스터 내부 트래픽 or 외부 로드밸런서)
vs
Ingress는 HTTP/HTTPS 트래픽을 여러 Service로 라우팅
(Ingress Controller를 통한 외부 트래픽의 진입점)
'Infra > Kubernetes' 카테고리의 다른 글
Kubernetes Components (0) | 2024.11.26 |
---|