반응형

이때까지 배운 내용을 한 번에 모아 실습하는 내용이다.
투표시스템(voting app)을 만드는데, 총 5개의 POD를 생성한다.
먼저 첫 번째 목표는
1. Deploy Containers, 2. Enable Connectivity, 3. External Access.

1. Deploy Containers
1) voting-app: user가 투표하는 앱
2) redis: user가 투표한 내역을 저장하는 db
3) worker: redis에 저장된 투표내역 + db 업데이트를 위해 전달하는 앱
4) PostGresSQL db: persistant DB, 최종 결과가 업데이트되는 db
5) result-app: 결과를 띄워주는 앱
Demo 영상에서 각 pod들의 yaml 파일을 작성하는데, 영상은 화면캡쳐가 막혀있어서 제외한다.

2. Enable Connectivity
각 pod는 다른 Node에 있을 수도 있는데, 서로간 통신을 어떻게 할까?
이전에 배웠던 Service를 통해 진행한다!
그럼, Pod뿐만 아니라, Service를 위한 YAML도 별도로 만들어야 한다.
여기서 사용하는 Service Type은, 내부 통신이므로 Cluster IP 타입이다.

3. External Access
그럼 외부에서 접근하기 위해서는?
외부에서 접근이 필요한 app은 두 가지. voting-app과 result-app.
따라서, 이 두 가지 pod를 위해 NodePort type의 Service를 생성한다.

즉, 여기까지 정리하자면 pod는 총 5개, Service는 4개가 생성된다.
* Service는 Cluster IP 타입이 2개(redis, PostGresSQL), NodePort 타입이 2개(voting-app, result-app)이다.

그런데, 위와 같이 생성하면 pod가 각 1개였기 때문에, 하나라도 죽는 경우 통신이 불가한 문제가 있다.
따라서, Deployment를 통해 여러 개의 pod를 띄워준다.

아래는 실습 중에 진행했던 pod, service, deploy YAML인데,
각 pod당 비슷한 내용들이므로 voting-app에 대해 필요한 yaml만 1개씩 작성해보았다.

* voting-app의 pod, deployments, service YAML 파일
1. voting-app-pod.yaml

apiVersion: v1
kind: Pod
metadata:  
name: voting-app-pod
labels:
name: voting-app-pod
app: demo-voting-app
spec:
containers:
- name: voting-app
image: kodekloud/examplevoteapp_vote:v1
port:
- containerPort: 80


2. voting-app-deploy.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
name: voting-app-deploy
labels:
name: voting-app-deploy
app: demo-voting-app
spec:
replicas: 3
selector:
matchLabels:
name: voting-app-pod
app: demo-voting-app
template:
metadata:  
name: voting-app-pod
labels:
name: voting-app-pod
app: demo-voting-app
spec:
containers:
- name: voting-app
image: kodekloud/examplevoteapp_vote:v1
port:
- containerPort: 80


3. voting-app-service.yaml

apiVersion: v1
kind: Service
metadata:
name: voting-service
labels:
name: voting-service
app: demo-voting-app
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
nodePort: 30005
selector:
name: voting-app-pod
app: demo-voting-app


강의의 끝이 보인다.
처음 이 강의를 시작하기 전에는, YAML파일을 많이 접하긴 했으나 어떤 구조로 되어 있는지 개념을 잘 몰랐다.
그런데, 이제는 아주 조금씩 보이기 시작한다... 오 예


출처)
자료의 기반은 모두 Udemy의 'Kubernetes for the Absolute Beginners - Hands-on' Course 입니다!

반응형
반응형

Kubernetes Services는 app의 내외 컴포넌트간 통신을 가능하게 해준다.  

예를 들어, app이 다양한 섹션에 속해있는 pod 그룹을 가지고 있을 때(ex. Frontend, Backend, external data),

이런 그룹들 간 통신을 가능하게 해준다. 

 

한 가지 예를 들어보자면, 유저가 10.244.0.2(Internal IP)를 가진 pod에 어떻게 접속할까?

- 일단 Node IP인 192.168.1.2 까진 ssh로 접속할 수 있다. 근데 그걸 타고가서 또 다른 걸로 접속하기엔 번거롭다.

그래서, Service라는 개념이 나왔는데, Service는 pod, deployments와 같은 object이다.

Service는 크게 3가지 타입으로 구성되어 있는데, 하나씩 봐보도록 하자.

 

 

1. NodePort

 : Node에서 port를 통해 internal POD로 접근가능하게 한다.

 

2. ClusterIP

 : 다른 서비스(Frontend, backend 등)간 통신을 가능하게 하는 내부 virtual IP

 

3. LoadBalancer

 : 말그대로 LB인데, 지원되는 cloud providers(ex. GCP 등) 에서 사용할 수 있다. 

 

하나씩 더 자세히 알아보자.

1. NodePort

 : NodePort는 Node에서 pod port까지 port를 mapping 해준다. 

   예를 들어, Node안에는 아래와 같이 3개의 ports가 포함되어 있다.

   1) TargetPort: 실제 앱이 돌아가는 pod의 포트

   2) Port: Service itself

   3) NodePort: Node itself (외부에서 접근 가능한)

  그래서 이런 Port들을 service definition yaml에 정의해주는데, high level structure는 기존 오브젝트들과 거의 같다.

  다만, spec아래에 type, ports라는 부분이 추가되었으며 type의 default는 cluster IP이고, 

  nodePort는 service에서 30000~32767 범위로 자동 할당한다.

 

 

근데 pod가 많다면? (=multi pods)

이전에 사용했던 selector라는 key를 사용한다.

selector는 pod를 identify하는 label list를 제공하므로, 이걸 통해 multi-pods를 관리할 수 있다.

(label은 이전에 pod생성 시 사용했던 pod-definition file을 참고하자)

그리고, Service는 LB로서, 다른 pod들에게 random algorithm을 사용하여 load를 분산시켜준다.

 

service definition YAML 작성이 끝났으면, 아래 create명령어로 service를 만들고,

실제로 pod까지 접속이 되는지 curl 명령어로 확인해본다.

# kubectl create -f service-definition.yaml

 

 

2. Cluster IP

보통 cluster 구성은 위와 같이 다양한 group으로 구성되는데, 서로간 연결이 어떻게 될까?

심지어, pod는 재생성되면서 IP가 바뀌기도 하는데, 관리하기가 쉽지 않다.

 

그래서, ClusterIP는 각 Pod들이 속한 label마다 group을 만들어서 관리한다. 

예를 들어, 위 그림의 redis는 'redis'라는 service로 다른 pods들이 각 pod로 접근할 수 있게 한다. (정확히는 service)

그리고, service를 통해 pkt이 들어오면, service에서 랜덤적으로 각 pod에 분산을 해줘서 효율적인 microservice deploy가 가능하게 해준다. 

 

Cluster IP의 service definition YAML은 위와 같다. 

전반적으로 NodePort와 비슷하지만, 'NodePort'가 있을 필요가 없으니 이 부분이 없고,

type이 ClusterIP이다. type에 아무것도 쓰지 않더라도, ClusterIP가 default 값이라 비워놔도 된다.

 

 

3. Load Balancer

app이 2 tier를 갖고 있고, 외부에서 접근 가능하도록 Node Port를 구성했다.

그럼 end user에는 어떤 ip를 줘야할까? 깔끔하게 하나 IP를 주는 게 좋을텐데..

Single Node일 경우 NodePort를 주면 되겠지만, multi Node의 경우, Node마다 IP가 다르다.

 

그래서, LB VM을 새로 구성하고, DNS 설정을 해서 user hosts를 만든다. 

근데 이 작업이 너무 귀찮은데, GCP와 같은 플랫폼에서는 native load balancing fuction들을 제공한다. 

따라서, 우리가 굳이 하나씩 setup할 필요가 없고, K8s가 스스로 셋업하도록 보고만 있으면 된다 ㅋ_ㅋ 

(교육자료가 과거내용인 것 같다. 요즘엔 다 되더라...)

 

강의의 끝이 보인다.

 

 

출처)

자료의 기반은 모두 Udemy의 'Kubernetes for the Absolute Beginners - Hands-on' Course 입니다!

반응형
반응형

Single Node로 K8s가 구성되어 있다고 생각해보자.

그럼 Node는 192.168.1.2 IP를 가지고 있고, Pod는 내부적으로 10.244.0.0/16 대역을 가지고 있다.

Node의 192.168.1.2 ip의 경우, ssh를 통해 접속이 가능하지만, Pod의 경우 내부 10.244.0.0/16 대역은 외부에서 접근할 수 없다. 

 

 

그럼 Multi-Node로 구성되어 있을 때는?

동일한 Cluster 내에서 각 Node가 동일한 대역을 갖고있으면 IP 충돌이 일어난다. 

그런데, K8s cluster가 setup될 때, k8s는 이런 이슈를 해결하기 위한 networking 종류를 자동으로 셋업하지 않는다.

그럼 All nodes가 NAT 없이 통신할 수 없는 방법은 무엇일까? 

 

 

Calico, cisco ACI networks, Cilium 등 pre-built solutions을 사용할 수 있다.

이건 각 플랫폼의 환경에 따라 달라지는 부분으로 (ex. VMware를 쓴다면 NSX-T가 good option)

각자 환경에 맞춰 맞는 networking solution을 선택하면 된다.

 

 

위는 Calico networking setup을 한 것인데, Node간 다른 network 를 할당했다. 

이런 Networking은 모든 pod 및 노드의 가상 network가 유니크한 ip를 할당받게 만든다. 

그리고, 다른 노드에 있다고 해도, 할당된 ip로 서로간 통신 할 수 있다. 

 

출처)

자료의 기반은 모두 Udemy의 'Kubernetes for the Absolute Beginners - Hands-on' Course 입니다!

 

반응형
반응형

* Deployment: ReplicaSet, pod보다 상위에 있는 K8s object.

                               seamless upgarde (using rolling updates) / undo changes / pause / resume changes 제공

 

1. 생성 배경 

1) 한 번에 여러 개의 instance를 deploy하고 싶음

2) pkg upgrade/rollback시 한 번에 모든 pod를 죽여버리고 살리면, 서비스 단절이 발생.

   seamless한 업그레이드를 원함. 

3) 다수의 환경 변경(scaling, upgrading, modifying resource)을 원함

 

 

 

2. Deployment 생성: ReplicaSet과 하나를 제외하고 모두 동일함.

    - 다른 것: "Kind" (ReplicaSet: ReplicaSet, Deployment: Deployment)

   Deployment는 ReplicaSet, pod의 상위 개념으로서, Deployment를 생성하면 Replicaset도 동시에 생성됨 

  (왼쪽 kubect get replicaset 참고)

 

 

3. Updates and Rollback in Deployment

* Rollout: 새로운 deployment 를 생성하거나 image를 업그레이드할 때, Rollout이 trigger되는데

이것은 점진적으로 컨테이너를 deploy하거나 upgrade함. 

예를 들어, deployment를 처음 생성하면 rollout이 trigger되는데, 이걸 revision 1이라 부름. 

이후에 해당 app이 upgrade되면 new rollout이 trigger되고, new deployment revision 2가 생성됨.

이렇게 하면 앞으로 롤백이나 history 관리 차원에서도 도움이 됨.

 

 

 

4. Deployment Strategy

2가지 type의 deployment strategies가 있음.

예를 들어, 5개의 replica가 있다고 가정한다면, 이를 새 버전으로 upgrade하는 방법은,

1) Recreate Strategy: 전체를 삭제 후 새 인스턴스를 생성하는 방법 (끊김O) 

2) Rolling Update: one by one으로 old version을 하나씩 down 후 새 버전으로 생성하는 방법 (끊김X)

   => Rolling Update가 default Deployment Strategy임.

 

5-1. kubectl apply: 실제로 어떻게 적용할까?

1) YAML파일에서 직접 수정: kubectl apply -f deplyment-definition.yaml 

2) Temperary 수정: kubectl set image deplyment/myapp-deplyment \nginx=nginx:1.9.1

 

 

 

5-2. 수행 결과

1) Recreate 방식: old replicaset은 0으로 전체 Scale down 후 5로 전체 Scale up이 됨

2) Rolling Update 방식: one by one으로, 하나씩 Scale Up/Down이 진행됨

 

 

 

5-3. Rollback

왼쪽 그림과 같이 replicaset 이 생성되었는데, pod가 0, 0, 0 상태로 무언가 잘못되어 보인다.

이때, 'rollout undo' 명령어를 통해, 이전 버전으로 복구할 수 있다.

 #kubectl rollout undo deployment/myapp-deployment

 

* Note: POD 생성 시 'deployment "nginx" created'가 출력되었던 이유!

사실 해당 명령어는 deployment를 먼저 생성 후, 자동으로 replicaset과 pod가 생성되었던 것이다. 

 

 

6. Deployment에서 배운 command 정리

- Deployment Create

  # kubectl create -f deplyment-definition.yaml

- Deployment 조회(get)

  # kubectl get deployments

- Update

  # kubectl apply -f deplyment-definition.yaml

  # kubectl set image deployment/myapp-deployment nginx=nginx:1.9.1

- Status

  # kubectl rollout status deployment/myapp-deployment

  # kubectl rollout history deployment/myapp-deployment

- Rollback

  # kubectl rollout undo deployment/myapp-deployment

 

Recreate strategy
https://joont92.github.io/kubernetes/%EB%B0%B0%ED%8F%AC-%EC%A0%84%EB%9E%B5/

출처)

자료의 기반은 모두 Udemy의 'Kubernetes for the Absolute Beginners - Hands-on' Course 입니다!

https://joont92.github.io/kubernetes/%EB%B0%B0%ED%8F%AC-%EC%A0%84%EB%9E%B5/

https://www.cncf.io/wp-content/uploads/2020/08/CNCF-Presentation-Template-K8s-Deployment.pdf

반응형
반응형

 

* Controller: K8s object들을 모니터링하는, K8s의 뇌

그 중에서도, 오늘은 Replication Controller에 대해 정리할 예정이다.

 

1. Replication이란?

Replica가 무엇이고, 왜 replication controller가 필요할까?

 1) High Availability

이전 공부했던 것 처럼, 우리 app이 single로 돌아가고 있는데, 문제가 발생하면 access가 중단된다.

그래서 하나 이상의 instance or POD를 구성하는데,

이때 Replication controller가 multiple한 instance의 구동(running)을 돕는다. 

 

 - 그럼, multiple한 instance 구성이 아니면 Replica는 필요 없을까?

  => No. single pod가 fail되면, replication controller는 자동으로 new pod를 생성한다.

        따라서, replicaion controller는 항상 pod가 예상했던 수 만큼 running 되고 있는지 감시하고 있다.

 

 2) Load Balancing & Scaling 

  - 또다른 목적은, load 분산을 위한 multiple POD를 생성할 때 필요하다.

    유저 수가 늘거나 리소스가 부족할 때, pod를 동일 클러스터 내 다른 노드로까지 확장한다.

    수요가 떨어질 때는 pod 또한 감설한다.

 

 

2. Replication Controller VS Replica Set

둘 다 동일한 목적을 갖고 있으나, 같은 것은 아니다. 

Replication Controller는 과거 기술 버전으로, 현재는 Replicat Set에 대체됐다.

현재로서는 Replica Set이 replication setup을 위한 방법으로 추천된다!

 

1) ReplicationController YAML

 : 현재는 사용하지 않으니 패스하도록 하자.

   크게 달라지는 것은, spec 밑에 "template", "replicas" 라는 key가 생긴다.

 

2) ReplicaSet YAML

Replication controller와 구성은 거의 비슷하지만, 아래와 같이 변경된 사항들이 있다.

- apiVersion: v1 -> apps/v1 으로 변경

- kind: Replication controller -> ReplicaSet 으로 변경

- spec: 에 "selector" 개념 추가

  . selector: 어떤 레이블에 속한 파드를 관리할지에 대한 설정

    -> 이걸 왜 설정해야 하냐면, ReplicaSet은, ReplicaSet이 생성하지 않은 pod에 대해서도 관리하기 때문이다. 

 

이전에 생성했던 pod(우측 yaml) YAML에서는 labels에 tier:Front-end를 정의해줬었다.

따라서, ReplicaSet에 selector로 해당 labels를 정의해주면,

이 pods에 대해 모니터링이 되면서 pod가 죽었는지, 수(replicas: 3)가 제대로 떠 있는지 모니터링 가능하다.

 

 

3) 'template' key는 왜 필요할까?

현재 관리되고 있는 pod 중에 한 개가 죽어서 'replicas=3'을 만족시키지 못할 경우,

동일한 pod를 띄워주기 위함이다. Replicaset은 항상 pod들을 감시하고, desired number of PODs가 유지되게 해주며, 'template' 섹션은 필수다. 

 

4) Replicaset을 Scale하는 방법

 : 기존 replicas 값을 3 -> 6으로 변경하고 싶다면?

 4-1) replicaset-definition.yaml에서 값을 수정한다.

        # kubectl replace -f replicaset-definition.yaml

 4-2) kubectl scale 명령을 사용한다. *단, 파일이 변경되진 않고 임시로 변경되는 것임!

        # kubectl scale --replicas=6 -f replicaset-definition.yaml

        # kubectl scale --replicas=6 [TYPE] [NAME] // ex. kubectl scale --replicas=6 replicaset myapp-replicaset

 

 

3. Command 정리

# kubectl create -f replicaset-definition.yaml // 생성

# kubectl get replicaset // 조회

# kubectl delete replicaset myapp-relicaset (이와 연관된 모든 pod도 삭제됨)

# kubectl replace -f replicaset-definition.yaml // replace/update를 위한 cmd

# kubectl scale -replicas=6 -f replicaset-definition.yaml  // 파일을 수정하지않고 설정 변경

 

 

출처)

자료의 기반은 모두 Udemy의 'Kubernetes for the Absolute Beginners - Hands-on' Course 입니다!

반응형
반응형

 

Kubernetes를 setup하는 방법은 여러 가지가 있다. 

1) Minikube / Kubeadm 툴을 사용하여 랩탑 or VM에 setup을 할 수 있다.

 - Minikube: All-in-one으로 single instance 셋업을 위해 사용되는 툴

 - Kubeadm: multi-node setup에 사용되는 툴

 

2) Hosted solutions in a cloud environment (ex. GCP, AWS)

3) play-with-k8s.com에 checkout

 - 리소스가 없거나, 복잡한 셋업 과정을 거치고 싶지 않은 경우

 

다시 하나씩 보자. Minikube부터.

Minikube는 위 그림에서보면, master/worker node가 분리된 것처럼 보이지만,

ppt 효과가 들어가 있어서 분리되어 있는 것이고

실제론 Master와 Worker Node가 하나로 All-in-one 버전이다.

 

Minikube는 아래 링크에서 Minikube와 VirtualBox를 다운 받아서 셋업하면 된다.

Install MiniKube: https://kubernetes.io/docs/tasks/tools/install-minikube/

VirtualBox: https://www.virtualbox.org/wiki/Downloads

MiniKube Download page for  Windows: https://github.com/kubernetes/minikube/releases

 

More about it here: https://kubernetes.io/docs/setup/learning-environment/minikube/#specifying-the-vm-driver

 

 

이 외는 데모하는 부분이라 여기서 마무리 :)

퀴즈는 3개 중 2개를 맞췄는데, 틀린 부분 역시.. 지금 티스토리에 정리를 하다보니 답이 바로 보인다.

앞으로도 열심히 정리해봐야겠다.

 

출처)

자료의 기반은 모두 Udemy의 'Kubernetes for the Absolute Beginners - Hands-on' Course 입니다!

반응형

+ Recent posts