새소식

Kubernetes

[Cloud Compute] Kubernetes 구축하기 - 4. nginx 서버 배포하기

  • -

지난 글에서 간단하게 어플리케이션을 배포하는 과정을 진행해보았다.

 

이번에는 nginx와 html을 배포해서 간단한 웹서버를 구축해보려고 한다.

 

어떻게 보면 지난글보다 이번글이 더 중요할 수 있겠다.

 

저번처럼 Pod를 배포하는 것이 아니라 Deployment와 Service를 배포할 것이고, 이것은 실제환경과 유사할 것이다.

 

진행에 앞서 Deployment와 Service에 대해 공부를 할 것을 추천한다.

 

1. Deployment 배포하기

둘 중에 뭘 먼저 배포하던지 Port만 일치시켜준다면 문제는 없지만 실습환경이니 먼저 Deployment를 배포해보자.

 

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-server
  labels:
    app: server
spec:
  replicas: 1
  selector:
    matchLabels:
      app: server
  template:
    metadata:
      name: nginx-server
      labels:
        app: server
    spec:
      containers:
        - name: server
          image: nginx:1.23.3
          ports:
            - containerPort: 80

 

busybox를 배포했을 때와는 뭔가 내용이 더 추가된 것을 확인할 수 있다.

 

Deployment는 ReplicaSet을 이용해 Pod를 관리하기 때문에 replicas라는 속성으로 몇개를 배포할지 정한다.

그리고 matchLabels라는 속성은 Deployment가 관리하는 Pod을 유일하게 식별하기 위한 것으로 관리대상을 명확히 하는 것이다. labels속성은 임의로 바뀔 수 있기 때문에.

 

가장 밑에 ports라는 속성이 실습에서 가장 중요한 부분이다.

name=server라는 컨테이너에서 노출할 port 번호를 가리킨다.

컨테이너의 포트와 내부 어플리케이션의 포트는 다르다는 것을 알면 이해가 쉽다.

내부 어플리케이션에서 80포트를 열어도 컨테이너 포트에서 80포트를 열지않으면 접근할 수 없다.

여기서는 80포트를 열었고 내부 어플리케이션인 nginx도 기본포트로 80포트를 열기 때문에 통로가 연결된 것이다.

만약 nginx에 listen 설정을 변경해서 x포트를 열었다면 컨테이너도 x포트를 열어야 한다.

 

이제 위 설정으로 배포해보자.

 

kubectl create -f nginx-deployment.yaml

 

replicas속성을 1이 아니라 3를 넣어보는 건 어떨까?

 

이렇게 해서 nginx서버가 배포되었다!

물론 여기에 접근할 수 있는 경로는 아예 없는 상황이니 다음단계로 넘어가자.

 

2. Service 배포하기

이제 pod에 접근할 수 있는 경로를 만들어보자

 

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  labels:
    app: server
spec:
  selector:
    app: server
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

 

spec.selector 속성은 간단하게 말하면 pod의 labels를 체크하여 일치하는 pod에 spec.ports 의 프로토콜을 연결해주는 것이다.

여기서는 app=server인 pod에 TCP로 80포트를 연결해주고 있다.

port와 targetPort는 복잡하게 생각하지 않아도 된다.

 

port = 외부에서 Service에 접근하는 포트
targetPort = Service와 연결된 pod의  포트

 

이제 Service도 배포해보자

 

kubectl create -f nginx-service.yaml

 

이번에는 좀 다르게 Resources를 확인해보자

 

kubectl get deploy,pod,svc,ep

 

ResouceType를 공백없이 쉼표로 나열함으로써 여러개의 ResouceType에 대한 정보를 볼 수 있다.

 

직관적으로 알아보기 쉽다!

 

service와 endpoints 부분을 살펴보자

service/nginx-service라는 항목이 있는데 TYPE=ClusterIP 라고 되어있다.

service의 Type에는 여러 종류가 있는데 공식문서 내용을 가져와봤다.

 

쿠버네티스 ServiceTypes는 원하는 서비스 종류를 지정할 수 있도록 해준다. 기본 값은 ClusterIP이다.

Type 값과 그 동작은 다음과 같다.

 

  • ClusterIP: 서비스를 클러스터-내부 IP에 노출시킨다. 이 값을 선택하면 클러스터 내에서만 서비스에 도달할 수 있다. 이것은 ServiceTypes의 기본 값이다.
  • NodePort: 고정 포트 (NodePort)로 각 노드의 IP에 서비스를 노출시킨다. NodePort 서비스가 라우팅되는 ClusterIP 서비스가 자동으로 생성된다. <NodeIP>:<NodePort>를 요청하여, 클러스터 외부에서 NodePort 서비스에 접속할 수 있다.
  • LoadBalancer: 클라우드 공급자의 로드 밸런서를 사용하여 서비스를 외부에 노출시킨다. 외부 로드 밸런서가 라우팅되는 NodePort와 ClusterIP 서비스가 자동으로 생성된다.
  • ExternalName: 값과 함께 CNAME 레코드를 리턴하여, 서비스를 externalName 필드의 콘텐츠 (예:foo.bar.example.com)에 매핑한다. 어떤 종류의 프록시도 설정되어 있지 않다.

 

3. NodePort로 외부에 포트 노출시키기

우리가 배포한 Service는 어떤 타입도 지정하지 않았기 때문에 ClusterIP 로 지정된 것이다.

설명에도 적혀있듯이 내부에만 노출되어 있기 때문에 외부에서 접근할 수 없는 유형이다.

우리는 NodePort를 써서 포트를 노출시켜서 접근할 수 있도록 테스트해볼 것이다.

 

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  labels:
    app: server
spec:
  selector:
    app: server
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service-node
  labels:
    app: server
spec:
  selector:
    app: server
  type: NodePort
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30080

 

설정파일에서 뭔가 중복된 내용이 추가된 것처럼 보이는데 그렇지 않으니 살펴보자

yaml은 "---" 를 이용하면 한 파일에 여러 문서를 작성할 수 있다.

 

위에 항목은 그대로니 아래항목을 보면 spec.type이 추가되었고, ports.nodePort도 생겼다.

nodePort로 외부에 직접 노출시킨 것은 알겠는데 포트넘버가 30080 이다.

왜 이렇게 한 것일까? 공식문서를 살펴볼 필요가 있다.

 

Worker node(s)의 항목을 보면 NodePort Services를 위한 Port Range가 기본값 30000-32767 로 되어있다.

 

특별히 설정을 바꾸진 않았으니 우리가 사용하는 Port Range도 바뀌지 않았을 테니 nodePort는 30000-32767 내로 지정되어야 한다.

 

이제 다시 적용해보자.

 

kubectl apply -f nginx-service.yaml

 

 

apply command로 기존 Service를 교체하고 새로운 Service를 추가했더니 Warning문구가 뜬다!

기존 파일에 새로운 내용이 추가되었기 때문에 kubernetes에서 기록했던 기존 파일의 상태가 변경되었다는 것을 알려주는 것이니 걱정하지 말자. annotation을 이용해 이전 상태를 보고 변경점을 추적해서 문제를 해결하는 데 도움이 된다.

 

service/nginx-service-node를 보면 PORT(S) 에 80:30080/TCP로 적혀있는데 servicePort : nodePort / Protocol 형태다.

 

30080포트로 접속을 해보면 어떻게 될까?

 

현재는 MasterNode가 아닌 SubNode에 배포되어 있기때문에 SubNodeIP:30080으로 접속해보면 된다.

 

이제 서버를 배포한 경험을 얻었다!

 

접속에 성공했다!

 

4. File Mount 해보기

이번에는 타임존을 변경하는 방법을 kubernetes의 기능을 이용해서 적용해보자.

환경변수로 넘겨주거나 Image에서 적용할 수도 있지만 이번에 해볼 방식은 volume mount 이다.

 

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-server
  labels:
    app: server
spec:
  replicas: 1
  selector:
    matchLabels:
      app: server
  template:
    metadata:
      name: nginx-server
      labels:
        app: server
    spec:
      containers:
        - name: server
          image: nginx:1.23.3
          ports:
            - containerPort: 80
          volumeMounts:
            - name: time-zone
              mountPath: /etc/localtime
      volumes:
        - name: time-zone
          hostPath:
            path: /usr/share/zoneinfo/Asia/Seoul

 

기존 nginx-deployment.yaml 에서 밑에 7줄이 추가되었다.

우선 containers와 동급에 위치한 volumes를 봐야한다.

time-zone 이라는 이름으로 volume을 생성했다. 그리고 volume에는 pod가 위치한 Node로부터 path가 연결되어있다.

이렇게 정의된 time-zone이라는 volume을 volumeMounts 라는 속성에서 pod에 연결시킨다.

time-zone이라는 volume을 mountPath 값으로 mount 하는 것이다.

 

주의할 건 volumes.name 과 volumeMounts.name 이 일치하는 것이다.

 

이제 확인해볼 시간이다.

 

1. 재배포

kubectl apply -f nginx-deployment.yaml

 

2. Pod 이름 확인

kubectl get pod

 

3. 날짜 확인

kubectl exec -it {POD_NAME} -- date

 

작성하는 시간으로 "Sun Mar  5 14:43:31 KST 2023" 라는 결과를 받을 수 있었다. 정확했다.

 

# 부록

위에서 사용한 exec 명령어는 Pod 내부에서 명령어를 실행하기 위한 것이다.

-i 는 "인터랙티브 모드"를 활성화하며, 컨테이너에 명령어를 전달할 수 있게 STDIN을 연다
-t 는 "터미널 모드"를 활성화하며, TTY를 할당하여 컨테이너의 쉘에 연결한다

그리고 " -- " 로 명령어부분을 구분한다.

만약 

 

kubectl exec -it {POD_NAME} -- /bin/bash

 

라고 입력한다면 Pod의 컨테이너에서 bash를 계속해서 사용할 수 있다.

 

 

 

이제 웹서버를 구축해보는 건 끝이났다.

다음에는 데이터베이스 목적으로 mysql과 백업용 xtrabackup을 배포해보자

 

이전글

 

 

[Cloud Compute] Kubernetes 구축하기 - 3. 어플리케이션 배포하기

지난 글에서 구축까지 진행해보았다. 이제는 어떻게 어플리케이션을 배포하고 통신을 할 수 있는지 알아보자. 0. 시작하기에 앞서 명령어 알아보기 지금까지는 그냥 따라왔다면 이제는 명령어

bateaux.tistory.com

 

다음글

 

[Cloud Compute] Kubernetes 구축하기 - 5. mysql + xtrabackup 배포하기

지난 글에서 nginx 서버를 배포해보았으니 이번에는 데이터베이스를 배포해자. nginx 같은 경우에는 stateless인 Deployment로 배포했는데 이번엔 다르게 진행되어야 한다. 기본적으로 데이터베이스는

bateaux.tistory.com

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.