본 포스팅은 Udemy Certificated Kubernetes Administrator 강좌를 공부한 내용입니다.

 

Certified Kubernetes Administrator (CKA) Practice Exam Tests

Prepare for the Certified Kubernetes Administrators Certification with live practice tests right in your browser - CKA

www.udemy.com

 

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 기능에 대해 정리할 수 있었다

+ Recent posts