kubernetes

쿠버네티스 시작하기

최근에는 컨테이너 기술인 도커 등을 이용하여 어플리케이션을 컨테이너 형태로 배포하는 추세이다.

kubernetes는 이렇게 많은 컨테이너들의 배포 프로세스를 관리하고 컨테이너 들을 클러스터링 하여 체계적이로 관리, 배포할 수 있게 해주는 툴이다.

클러스터를 생성하고 각 어플리케이션을 노드 단위가 아니라 클러스터 단위로 배포함으로써 특정 컨테이너에 문제가 생기면 kubernetes가 컨테이너를 재시작 하는 등 다양한 기능을 제공하여 보다 안정적으로 서비스를 운영할 수 있게 해준다.

또한 여러 컨테이너들 사이에서 Load Balancing 등을 활용한 라우팅 기능을 사용하여 분산처리도 가능하게 해주는 장점이 있다.

Kind of Objects in kubernetes

Kubernetes에는 다음과 같이 크게 4가지 종류의 Object 가 존재한다.

  1. Cluster
  2. Service
  3. Pod

Create kubernetes cluster

먼저 쿠버네티스를 시작하기 위해서는 클러스터를 생성하여 그 위에 컨테이너화된 어플리케이션을 배포할 수 있다.

쿠버네티스 디플로이먼트 설정을 만들어야 한다. 디플로이먼트는 쿠버네티스가 애플리케이션의 인스턴스를 어떻게 생성하고 업데이트해야 하는지를 지시한다.

디플로이먼트가 만들어지면, 쿠버네티스 마스터가 해당 애플리케이션 인스턴스를 클러스터의 개별 노드에 스케줄한다.

디플로이먼트는 애플리케이션 인스턴스를 생성하고 업데이트하는 역할을 담당한다.

미니쿠베를 통해 로컬에서 간단하게 쿠버네티스를 실행시킬 수 있다.

1
2
minikube start
minikube stop

새로운 deployment를 실행한다.

아래 명령어에서 deployment의 이름과 app의 이미지 주소를 입력해 준다.

We want to run the app on a specific port so we add the –port parameter:

1
2
3
kubectl run kubernetes-bootcamp --image=[gcr.io/google-samples/kubernetes-bootcamp:v1](<http://gcr.io/google-samples/kubernetes-bootcamp:v1>) --port=8080

kubectl get deployments

기본적으로 쿠버네티스의 팟들은 해당 클러스터 내에서 서로 ip를 알고 있지만 클러스터 밖은 클러스터 내의 팟의 아이피를 알지 못한다.

The kubectl command can create a proxy that will forward communications into the cluster-wide, private network.

이러한 클러스터에 접근하기 위해 proxy 서버를 돌릴 수 있는데, 다음과 같다.

undefined

위처럼 환경변수를 설정하면 다음과 같이 접근이 가능하다.

1
curl [<http://localhost:8001/api/v1/namespaces/default/pods/$POD_NAME/proxy/>](<http://localhost:8001/api/v1/namespaces/default/pods/$POD_NAME/proxy/>)

파드는 쿠버네티스 플랫폼 상에서 최소 단위가 된다. 우리가 쿠버네티스에서 배포를 생성할 때, 그 배포는 컨테이너 내부에서 컨테이너와 함께 파드를 생성한다

파드는 하나 또는 그 이상의 애플리케이션 컨테이너 (도커 또는 rkt와 같은)들의 그룹이고 공유 스토리지 (볼륨), IP 주소 그리고 그것을 동작시키는 방식에 대한 정보를 포함하고 있다.

  • kubectl get - 자원을 나열한다
  • kubectl describe - 자원에 대해 상세한 정보를 보여준다.
  • kubectl logs - 파드 내 컨테이너의 로그들을 출력한다
  • kubectl exec - 파드 내 컨테이너에 대한 명령을 실행한다.

노드는 쿠버네티스에 있어서 워커 머신이며 클러스터에 따라 VM 또는 물리 머신이 될 수 있다. 여러개의 파드는 하나의 노드 위에서 동작할 수 있다.

We can execute commands directly on the container once the Pod is up and running. For this, we use the exec command and use the name of the Pod as a parameter. Let’s list the environment variables:

특정 팟에서 명령어를 실행할 수 있따.

가령 kubectl exec -it \$POD_NAME bash

cat server.js

Service

쿠버네티스에서 서비스는 하나의 논리적인 파드 셋과 그 파드들에 접근할 수 있는 정책을 정의하는 추상적 개념이다

서비스는 종속적인 파드들 사이를 느슨하게 결합되도록 해준다. 서비스는 모든 쿠버네티스 오브젝트들과 같이 YAML 또는 JSON을 이용하여 정의된다.

쿠버네티스 클러스터 내 각 파드는 유일한 IP 주소를 가지며, 여러분의 애플리케이션들이 지속적으로 기능할 수 있도록 파드들 속에서 발생하는 변화에 대해 자동으로 조정해 줄 방법이 있어야 한다.

비록 각 파드들이 고유의 IP를 갖고 있기는 하지만, 그 IP들은 서비스의 도움없이 클러스터 외부로 노출되어질 수 없다. 서비스들은 여러분의 애플리케이션들에게 트래픽이 실릴 수 있도록 허용해준다. 서비스들은 ServiceSpec에서 type을 지정함으로써 다양한 방식들로 노출시킬 수 있다:

서비스는 쿠버네티스의 객체들에 대해 논리 연산을 허용해주는 기본 그룹핑 단위인, 레이블과 셀렉터를 이용하여 파드 셋과 매치시킨다. 레이블은 오브젝트들에 붙여진 키/밸류 쌍으로 다양한 방식으로 이용 가능하다:

  • 개발, 테스트, 그리고 상용환경에 대한 객체들의 지정
  • 임베디드된 버전 태그들
  • 태그들을 이용하는 객체들에 대한 분류

여러분은 kubectl 명령에--expose 옵션을 사용함으로써 디플로이먼트 생성과 동일 시점에 서비스를 생성할 수 있다.

how to expose Kubernetes applications outside the cluster using the kubectl expose command

1
2
노드 포트 타입으로 클러스터를 외부로 노출시킴
kubectl expose deployment/kubernetes-bootcamp --type="NodePort" --port 8080

열린 포트를 확인하기 위해 다음 명령어를 실행시킴

kubectl describe services/kubernetes-bootcamp

curl $(minikube ip):$NODE_PORT

라벨 사용하기

1
2
아래 커맨드의 -l 은 라벨을 의미한다.
kubectl get pods -l run=kubernetes-bootcamp

다음과 같이 라벨링을 한다.

kubectl label pod \$POD_NAME app=v1

kubectl describe pods \$POD_NAME

를 실행시켜 보면 라벨링이 바뀐 것을 볼 수 있다.

다음과 같이 새로운 라벨로 쿼링을 할 수 있다

kubectl get pods -l app=v1

다음과 같이 서비스를 삭제하면 요청이 오지 않는데 그것은 외부로 열려있지 않기 때문이다.

kubectl delete service -l run=kubernetes-bootcamp

드플로이먼트의 복제수를 변경하면 스케일링이 수행된다.

스케일링 명령어

1
kubectl scale deployments/kubernetes-bootcamp --replicas=4

다음 명령어로 확인하면 서로 다른 ip를 가진 여러 개의 팟이 생긴것을 볼 수 있다.

1
kubectl describe deployments/kubernetes-bootcamp

앱 업데이트 하기

1
kubectl set image deployments/kubernetes-bootcamp kubernetes-bootcamp=jocatalin/kubernetes-bootcamp:v2

위 명령어는 특정 deployment의 팟의 이미지를 교체해준다.

kubectl get pods

를 통해 확인해 본다.

롤아웃

kubectl rollout status deployments/kubernetes-bootcamp

롤백

kubectl rollout undo deployments/kubernetes-bootcamp

클러스터 밖에서 팟을 바라보기

The hostNetwork setting applies to the Kubernetes pods. When a pod is configured with hostNetwork: true, the applications running in such a pod can directly see the network interfaces of the host machine where the pod was started.

1
2
3
4
5
6
7
8
9
apiVersion: v1
kind: Pod
metadata:
name: influxdb
spec:
hostNetwork: true
containers:
- name: influxdb
image: influxdb

컨테이너에 hostPort 옵션

The hostPort feature allows to expose a single container port on the host IP.

1
2
3
4
5
6
7
8
9
10
11
apiVersion: v1
kind: Pod
metadata:
name: influxdb
spec:
containers:
- name: influxdb
image: influxdb
ports:
- containerPort: 8086
hostPort: 8086

To make the service accessible from outside of the cluster a user can create a service of type NodePort.

each Kubernetes node will proxy that port to the pods selected by the service.

1
2
3
4
5
6
7
8
9
10
11
kind: Service
apiVersion: v1
metadata:
name: influxdb
spec:
type: NodePort
ports:
- port: 8086
nodePort: 30000
selector:
name: influxdb

kubernetes DNS

Services

A records

“Normal” (not headless) Services are assigned a DNS A record for a name of the form my-svc.my-namespace.svc.cluster.local. This resolves to the cluster IP of the Service.

“Headless” (without a cluster IP) Services are also assigned a DNS A record for a name of the form my-svc.my-namespace.svc.cluster.local. Unlike normal Services, this resolves to the set of IPs of the pods selected by the Service. Clients are expected to consume the set or else use standard round-robin selection from the set.

SRV records

SRV Records are created for named ports that are part of normal or Headless Services. For each named port, the SRV record would have the form _my-port-name._my-port-protocol.my-svc.my-namespace.svc.cluster.local. For a regular service, this resolves to the port number and the domain name: my-svc.my-namespace.svc.cluster.local. For a headless service, this resolves to multiple answers, one for each pod that is backing the service, and contains the port number and the domain name of the pod of the form auto-generated-name.my-svc.my-namespace.svc.cluster.local.

Kube dns

https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/

minikube start

kubectl cluster-info

kubectl get nodes

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×