kubectl create -f deployment-definition.yaml
kubectl get deployments
kubectl get replicaset
kubectl get pods
또는
kubectl get all
Service
Service 는 여러 개의 Pod 로 구성된 애플리케이션을 하나의 네트워크 엔드포인트로 외부에 노출시키는 리소스이다.
Pod 는 언제든지 재시작되거나 재배포될 수 있기 때문에 IP 가 항상 바뀔 수 있다.
Service 는 클러스터 내부에 고정된 가상 IP 를 외부에 노출시켜 클라이언트가 항상 같은 IP 주소로 파드에 접근할 수 있도록 한다.
Label Selector 를 이용해 트래픽을 전달해야할 Pod 를 지정할 수 있다.
내부적으로 각 노드에서 실행되는 kube-proxy 가 Service 의 가상 IP 로 들어온 요청을 Label Selector 조건에 해당하는 Pod 중 하나로 전달한다.
여러가지 Service Type 을 가지고 있다.
ClusterIP
NodePort
LoadBalancer 등
Service 흐름
클러스터 내부에서 Service 를 호출할 때:
클라이언트가 Service 의 ClusterIP:Port 로 요청을 보낸다.
kube-proxy 가 이 요청을 가로챈다.
EndpointSlice 를 참조해 적절한 Pod IP 로 라우팅한다.
Pod 는 targetPort 에서 요청을 받는다.
아래 ClusterIP 예시로 들면, back-end:8080 으로 들어온 요청이 label 이 app=myapp, type=back-end 인 Pod 의 80 포트로 전달된다.
ClusterIP
apiVersion: v1kind: Servicemetadata: name: back-endspec: type: ClusterIP # default 값 selector: # label 기준으로 트래픽을 보낼 pod 결정 app: myapp type: back-end ports: - port: 8080 # (required) 클라이언트가 Service 에 요청을 보낼 port targetPort: 80 # 실제 pod 에서 리스닝하는 port, 지정하지 않으면 port 값을 따름
ClusterIP 는 클러스터 내부에서만 접근 가능한 IP 로 기본값으로 적용된다.
클러스터 내부에서 서비스 연결은 DNS 를 이용
가령 3-tier-architecture 에서 backend app 에 요청을 보내고 싶을 때 backend 를 담당하는 여러 Pod 가 cluster 전체에 퍼져있으니 ClusterIP 를 통해 원하는 layer 를 지정
NodePort
apiVersion: v1kind: Servicemetadata: name: myapp-servicespec: type: NodePort selector: # label 기준으로 트래픽을 보낼 pod 결정 app: myapp type: front-end ports: - port: 80 # (required) 클라이언트가 Service 에 요청을 보낼 port targetPort: 80 # 실제 pod 에서 리스닝하는 port, 지정하지 않으면 port 값을 따름 nodePort: 30008 # 30000-32767 범위, 지정하지 않을 경우 자동으로 할당됨
모든 노드에 동일한 고정 포트(30000-32767)를 생성하여 외부에 노출한다.
외부에서 {Node IP}:{nodePort} 형식으로 접근할 수 있다.
NodePort 역시 ClusterIP 를 가지기 때문에 내부적으로는 ClusterIP 를 통해 Pod 에 접근한다.
kubectl run httpd --image=httpd --port=80 --expose
kubectl run 으로 Pod 를 생성할 때 —expose 옵션을 주면 Pod 에 연결되는 ClusterIP 를 자동으로 생성해준다. ClusterIP 와 연결되어야 하기 때문에 —port 옵션이 필수적으로 포함되어야 한다.
K8s Cluster 를 구축하게되면 기본적으로 Default, kube-system, kube-public Namespace 들이 자동으로 생성된다. 사용자가 생성한 Pod, Deployment, Service 등 K8s Object 들은 기본적으로 Default Namespace 에 속하게 된다.
kubectl get pods --namespace=kube-system
kube-system Namespace 의 경우, coredns, etcd-master, kube-apiserver-master, kube-controller-manager-master 등 K8s 의 기본적인 Component 들을 확인할 수 있다.
K8s configuration file 을 통해 Object 를 생성한 경우 선언형 방식으로 구축했다고 생각할 수 있지만, edit 명령어를 통해 접근한 file 은 K8s memory 에 동적으로 생성된 yaml 인 것을 확인할 수 있다. 때문에 edit 으로 설정을 바꾼다고 기존에 작성한 nginx.yaml 은 수정되지 않기 때문에 추후에 replace 등을 할 경우 예상하지 못한 변경이 생길 수 있다. 이를 방지하기 위해선 edit 대신 configuration file 자체를 변경한 후 replace 를 실행하는 것이 바람직하다.
kubectl apply -f nginx.yaml
K8s 는 apply 를 통해 선언형 방식으로 Object 를 제어할 수 있다. apply 는 이미 만들어진 Object 를 파악하며 부분적으로 설정이 수정된 경우 해당 부분만 적용하는 기능 역시 지원한다.
kubectl apply 를 실행하면 K8s 는 사용자가 작성한 yaml file 과 K8s memory 에 저장된 Live object configuration 과 kubectl.kubernetes.io/last-applied-configuration 필드를 비교하여 변경된 사항만 부분적으로 확인하고 적용이 가능하다.