k8s/concept

service/ 개념 & test

부엉이사장 2023. 12. 4. 18:21

# deployment를 쓰는이유? 고가용성!

이렇게 deployment로 생성된 세개의 nginx pod들이 있다고 가정하자.

일단 우리가 deployment컨트롤러로 동일한 pod 세 개를 운영하는 목적은 뭐였니?

고가용성을 보장하기 위해서다. 고가용성이란 만약 노드 하나가 죽거나 한가지 pod가 죽거나 등등 뭐 ㅈ같은 일이 생겼을 경우 서비스가 죽게 될 것인데, 이거를 대비하려고 deployment컨트롤러로 동일한 pod들을 replicas 설정을 통해 만들어줬다.

 

 

# 헐

이렇게 세개의 동일한 pod들을 배포해줬고 deployment컨트롤러가 가용성을 보장해준다. 근데 이 세개의 pod들안에서 nginx컨테이너가 띄운 웹사이트들은 다 똑같지만 접속하려면 서로 다른 아이피로 접속을 해야한다. 그러면 의미가 없을텐데?

 

 

 

# 여기서 service가 생김

위 그림처럼 service를 만들게 되면 이 service에 cluster IP가 생기고 이 cluster IP로 접속하면 각각의 pod들에 같은확률로 균등하게 연결되는, 즉 로드벨런서 역할이 된다.

이 service의 아이피 대역은 pod가 생성되는 10.244.0.0/16대역대랑은 다르다. 충돌을 방지하기 위한거같기도한데 아직 내가 쿠버 엔진을 뜯어보진 못해서 모르겠다.

참고로 이 서비스는 컨트롤러가 생성한 pod들의 라벨을 따라서 로드벨런싱을 하게된다. 때문에 라벨링이 매~우 중요하다.

 

 

 

 

 

 

# yaml 양식

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app.kubernetes.io/name: MyApp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376

이렇게 생겼다. 공식문서에서 가져옴.

뭐 단순하게 생겼는데, 중요시 볼건 아래와 같다.

- selector : 이전에 컨트롤러를 공부할때 컨트롤러가 관리할 pod들에 라벨링을 붙여줬고, template에서 각 pod들이 이 라벨 키값쌍을 갖고 있었다. 서비스도 마찬가지로 이 서비스가 관리할 pod들을 연결지을 수 있도록 selector들과 pod들의 라벨링을 해줘야 한다. 

 

 

controller/ replicaSet & deployment

하씨발 이틀동안 적어놓은 포스팅 임시저장 싹다 사라져서 다시 적어야 한다 ㅈ같은씨발 # replicaSet replicaSet은 replication controller와 거의 비슷하다고 봐도 될것같다. 그냥 파드 수를 보장하는기능

jacobowl.tistory.com

- ports : 얘는 포트를 관리해주는거다.

여기엔 통신방법인 protocol과 port, targetPort이렇게 두 가지가 있는데 port는 clusterIP에 붙는 포트고, targetPort는 pod들에 붙는 포트이다. 만약 targetPort를 80으로 하고, 그냥 port를 1234으로 한다음 해당 서버들이 웹서버들일때, curl <clusterIP>:1234으로 커맨드를 치면 해당 pod들의 80포트로 연결되서 웹서버 동작을 확인 할 수 있다. 일반적으론 두 가지 port를 통일시켜주는데 다르게한다면 이걸 알고 쓰면 된다.

 

 

 

# 내가 직접 만든 service와 deployment yaml양식

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      pod-deployment: dori
  template:
    metadata:
      labels:
        pod-deployment: dori
        pod-service: muzzi
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    pod-service: muzzi
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

중간에 ---라고 해서 deployment yaml양식과, service yaml양식을 같이 써줬다.

그 이유는 deployment로 컨트롤러와 함께 이 컨트롤러가 관리할 pod들을 만들기 위함이고, 이 pod들을 로드벨런서 역할로써 단일진입점을 만들 service를 만들기 위함이다.

 

 

위에서 말한 selector를 자세히 설명하자면, 

아래쪽 service yaml양식에서 selector: pod-service: muzzi라고 해줬다.

pod-service: muzzi라고 한 키 값 쌍과 매치되는 pod들을 관리할건데, deployment양식에서 보면, template에 labels쪽에 pod-service: muzzi라고 해놨다. 이 deployment에서 생성된 pod들은 이 라벨링을 갖게 될 것이고, 서비스는 이 라벨링을 가진 pod들에 접속할 로드벨런서 역할을 할것이다.

 

또한 컨트롤러도 selector이 있다. 이전 포스팅에서 많이 설명했지만 위에 yaml양식에서 pod-deploymen: dori라는 라벨링으로써 delpoyment의 selector가 이 라벨링을 가진 pod들을 관리하게 될것이다.

 

 

 

 

# 실험해보자~

kubectl create -f test-service.yaml

일단 세 개의 pod들이 만들어졌다.

 

kubectl get service

서비스도 잘 만들어졌다.

저기 clusterIP컬럼이 아까 말한 로드벨런서역할을 하는 진입점 IP이다.

 

 

describe에서도 알 수 있다.

 

kubectl describe service my-service

저기 IP부분에 있는 아이피가 clusterIP이다.

또한 EndPoints에 어디로 갈건지 정보가 있다.

deployment로 생성된 pod들의 아이피와 같다 

 

 

# 그럼 clusterIP에 curl커맨드를 쳐보자.

 

curl 10.99.104.66

nginx가 뱉는 html이 잘 보인다. 

 

 

# 제대로 동작하는게 맞을까?

일단 웹서버가 동작하는지는 확인했지만 service가 로드벨런서 역할을 제대로 하고 있는지는 확인 못한다.

왜냐하면 세, 개의 pod들이 떳지만, 로드벨런서로써 각각 랜덤하게 http 요청을 하는지 현재로썬 알 수 없기 때문이다.

 

일단 curl 요청을 아까 한번 쳤고, 다섯 번 더 쳐보자. 총 여섯번 curl 요청했다.

curl 10.99.104.66

 

그리고 각각 pod들에 대해서 log를 확인해보면

kubectl logs 파드이름

각각 pod들에 다 쳐봤는데 8c로 시작하는 pod는 세번, vr로 시작하는 pod도 세번, xl로 시작하는 pod는 안받았다.

 

 

다른 방법도 있다.

kubectl exec -it 파드이름 -- /bin/bash

이렇게 exec로 각각 pod들에 커맨드로 진입해서 index.html파일을 수정해줄거다.

echo web1> /usr/share/nginx/html/index.html
exit

나오고 두번쨰 pod, 세번째 pod모드 web2 web3으로 바꿔준다.

kubectl exec -it nginx-deployment-7cbd7d4c87-vrhfj -- /bin/bash
echo web2> /usr/share/nginx/html/index.html
kubectl exec -it nginx-deployment-7cbd7d4c87-xlx2q -- /bin/bash
echo web3> /usr/share/nginx/html/index.html

 

이 상태에서 다시 clusterIP로 curl명령을 쳐보자.

요렇게 랜덤한 web이 뜬다.

service가 로드밸런서로써 잘 작동하고 있다는 증거이다.

 

'k8s > concept' 카테고리의 다른 글

service/ k8s의 dns구성, service type> externalName  (0) 2023.12.06
service/ service type > ClueterIP & NodePort & LoadBalancer  (0) 2023.12.05
controller/ cronJob  (0) 2023.12.03
controller/ job  (0) 2023.12.02
controller/ daemonSet & statefulSet  (0) 2023.12.01