본 포스팅은 Udemy Certificated Kubernetes Administrator 강좌를 공부한 내용입니다.
Kubernetes는 어플리케이션 사이의 isolation을 위해 namespace라는 리소스 제공하고 있다.
여기서 isolation은 실제 리소스를 물리적으로 격리시키는 것이 아니라 논리적인 단위이다.
또한 POD를 외부에서 접근할 수 있는 endpoint를 제공하기 위해 service라는 리소스를 제공한다.
이 둘에 대해 알아보자.
namespace
하나의 kubernetes cluster에서 dev application과 prod application을 같이 운영한다고 가정해보자.
개발자는 dev application을 수시로 업데이트 할 것이고 prod application은 정기 점검이나 새로운 버전을 release할 때 접근할 것이다.
그런데 dev와 prod의 POD가 같은 cli로 보이게 된다면 POD 설정에 실수를 범할 가능성이 높아진다.
이뿐 아니라 kubernetes의 control plane의 역할을 하는 POD 역시 같이 보인다면 위험성이 더 높아진다.
namespace는 이러한 문제를 해결할 수 있다.
namespace 역시 kubernetes의 리소스로 관리되기 때문에 kubectl 명령어를 통해 생성/삭제를 할 수 있다.
kubernetes의 control plane POD는 kube-system namespace에 존재하고 해당 namespace의 POD를 조회할 때는
-n kube-system option을 사용하면 된다.
$ kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-66bff467f8-8wk9d 1/1 Running 0 49m
coredns-66bff467f8-hwqm2 1/1 Running 0 49m
etcd-master 1/1 Running 0 49m
katacoda-cloud-provider-58f89f7d9-v79q2 1/1 Running 0 49m
kube-apiserver-master 1/1 Running 0 49m
kube-controller-manager-master 1/1 Running 0 49m
kube-flannel-ds-amd64-9f4js 1/1 Running 0 48m
kube-flannel-ds-amd64-9v7l9 1/1 Running 0 49m
kube-keepalived-vip-7fn2r 1/1 Running 0 48m
kube-proxy-ccm7p 1/1 Running 0 49m
kube-proxy-ttfhw 1/1 Running 0 48m
kube-scheduler-master 1/1 Running 0 49m
namespace 생성
$ kubectl create namespace dev
namespace/dev created
namespace 삭제
$ kubectl delete namespace dev
namespace "dev" deleted
namespace 조회
$ kubectl get namespace
NAME STATUS AGE
default Active 54m
kube-node-lease Active 54m
kube-public Active 54m
kube-system Active 54m
cluster context
유저가 kubectl을 사용하기 위한 kubernetes의 정보는 ~/.kube/config에 있는데 해당 configuration을 통해 여러 k8s cluster와 namespace를 조회/변경할 수 있다.
context 조회
$ kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* kubernetes-admin@kubernetes kubernetes kubernetes-admin
context 추가
$ kubectl config set-context cluster1_kube-system --cluster=cluster1 --namespace=kube-system --user=cluster1
Context "cluster1_kube-system" created.
$ kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
cluster1_kube-system cluster1 cluster1 kube-system
* kubernetes-admin@kubernetes kubernetes kubernetes-admin
현재 context 변경
$ kubectl config use-context cluster1_kube-system
Switched to context "cluster1_kube-system".
$ kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* cluster1_kube-system cluster1 cluster1 kube-system
kubernetes-admin@kubernetes kubernetes kubernetes-admin
앞에서 namespace는 논리적 단위의 isolation이라고 했는데 이 뜻은 dev와 prod namespace에 있는 POD가 실제로 다른 worker node에 존재하지 않고 같은 node에 있을 수 있다는 의미다.
실제 물리적으로 다른 worker node에 배치하고 싶다면 뒤에서 배울 taint and toleration 과 node affinity 등을 사용하면 된다.
추가로 namespace에는 resource quota를 지정할 수 있다.
resource quota는 CPU/Memeory/Storage 등 컴퓨팅/스토리지 리소스를 나타내는데 각 namespace에 resource quota를 지정해 namespace 별로 최대 사용할 수 있는 컴퓨팅/스토리지 리소스 량을 제한할 수 있다.
service
kubernetes에서 POD를 생성하면 POD는 k8s cluster 내부 IP를 가진다.
이 내부 IP를 이용하면 POD 간의 통신에는 문제가 없다.
하지만 웹페이지와 같이 외부에서 브라우저를 통해 접근해야 하는 POD는 어떻게 제공해줄 수 있을까?
그리고 Deployment, ReplicaSet등을 통해 POD의 replicas를 2개 이상 만들었을 때,
이들을 load balacing을 어떻게 제공해줄 수 있을까?
POD를 사용하는 client에서 다수 POD의 IP를 모두 알고 load balancing 로직을 직접 구현해야할까?
이러한 문제를 해결할 수 있는 방법을 kubernetes는 service를 통해 제공하고 있다.
위의 예시는 Service의 타입 중 NodePort를 이용한 예시다.
POD는 kubernetes node 중 IP 192.168.1.2를 사용하는 Worker Node에서 실행 중이다.
그리고 Service는 Worker Node의 30008번 포트를 통해 listen을 하고 있고 10.244.0.2 IP를 사용하는 POD에 연결되어 있다.
개발자는 Desktop(192.168.1.5)에서 192.168.1.2:30008를 통해 해당 POD에 접근할 수 있게된다.
참고로 NodePort는 Node의 30000~32767 사이의 포트 중 하나를 배정받아 Service를 외부로 노출시킬 수 있게 해준다.
Deployment 또는 ReplicaSet을 통해 배포된 POD는 Label과 Selector를 통해 Service가 연결할 수 있고 이를 통해 Loadbalancing을 할 수 있게 된다.
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 8080
위와 같이 selector를 사용해 POD의 Label을 지정할 수 있다.
Service Type
Service의 Type은 아래와 같이 3가지 방식이 있다.
Type | 내용 |
ClusterIP | Cluster 내부 IP만 배정받음, 외부로 노출 X Default Service Type |
NodePort | Node의 Port를 배정받음, 외부로 노출 |
LoadBalancing | Cloud Provider의 리소스를 제공받음(eg,. AWS ELB) |
POD에서 Service를 통해 다른 POD에 요청할 때는 Service name을 DNS 네임으로 이용할 수 있다.
동일 namespace의 Service port에 접근 : {SERVICE_NAME}:{PORT} (eg,. nginx:80)
다른 namespace의 Service port에 접근 : {SERVICE_NAME}.{namespace}.svc.cluster.local:{PORT}
(eg,. nginx.dev.svc.cluster.local:80)
정리
kubernetes의 service 기능에 대해 정리할 수 있었다
'Kubernetes > CKA' 카테고리의 다른 글
CKA 준비 (7) - Scheduling 2 (Node Selector, Node Affinity) (0) | 2020.06.09 |
---|---|
CKA 준비 (6) - Scheduling 1 (Manual, taint and toleration) (0) | 2020.06.07 |
CKA 준비 (4) - Pod, ReplicaSet, Deployment (0) | 2020.06.05 |
CKA 준비 (3) - Basic Data Plane Components (kubelet, kube-proxy) (0) | 2020.06.05 |
CKA 준비 (2) - Basic Control Plane Components (api-server, controller-manager, scheduler) (0) | 2020.06.04 |