블로그 이미지
평범하게 살고 싶은 월급쟁이 기술적인 토론 환영합니다.같이 이야기 하고 싶으시면 부담 말고 연락주세요:이메일-bwcho75골뱅이지메일 닷컴. 조대협


Archive»


 
 

[팁] 쿠버네티스 StatefulSet에서 Headless 서비스를 이용한 Pod discovery


조대협 (http://bcho.tistory.com)


statefulset에서 데이타베이스와 같이 master,slave 구조가 있는 서비스들의 경우에는 service를 통해서 로드밸런싱을 하지 않고, service 를 통해서 로드 밸런싱을 하는 것을 잘 사용하지 않고 개별 pod의 주소를 알고 접속해야 한다. 그래서 개별 Pod의 dns 이름이나 주소를 알아야 한다.


Pod들은 DNS이름을 가질 수 는 있으나, {pod name}.{service name}.{name space}.svc.cluster.local 식으로 이름을 가지기 때문에, pod 를 DNS를 이용해서 접근하려면 service name이 있어야 한다. 그러나 statefulset에 의한 서비스들은 앞에서 언급하였듯이 쿠버네티스 service를  이용해서 로드밸런싱을 하는 것이 아니기 때문에, 로드밸런서의 역할은 필요가 없고, 논리적으로, pod들을 묶어줄 수 있는 service만 있으면 되기 때문에 headless 서비스를 활용한다. Headless 서비스를 이용하면, service 가 로드 밸런서의 역할도 하지 않고, 단일 IP도 가지지 않지만, 아래 그림처럼 nslookup을 이용해서, headless 서비스에 의해서 묶여진 Pod들의 이름도 알 수 있고




{pod name}.{service name}.{name space}.svc.cluster.local  이름으로, 각 pod 에 대한 접근 주소 역시 얻을 수 있다.




본인은 구글 클라우드의 직원이며, 이 블로그에 있는 모든 글은 회사와 관계 없는 개인의 의견임을 알립니다.

댓글을 달아 주세요

StatefulSet을 이용하여 상태가 유지되는 Pod 관리하기

조대협 (http://bcho.tistory.com)

ReplicaSet으로 Stateful Pod 관리하기

앞에서 쿠버네티스의 Pod를 관리하기 위한 여러가지 컨트롤러 (Replica Set, ReplicationController,Job 등)에 대해서 알아보았다.

이런 컨트롤러들은 상태가 유지되지 않는 애플리케이션(Stateless application)을 관리하기 위해 사용된다. Pod가 수시로 리스타트되어도 되고, Pod 내의 디스크 내용이 리스타트되어 유실되는 경우라도 문제가 없는 워크로드 형태이다. 웹서버나 웹애플리케이션 서버 (WAS)등이 그에 해당한다. 그러나 RDBMS나 NoSQL과 같은  분산 데이타 베이스등과 같이 디스크에 데이타가 유지 되어야 하는 상태가 유지되는 애플리케이션 (Stateful application)은 기존의 컨트롤러로 지원하기가 어렵다.

ReplicaSet (이하 RS)를 이용하여 데이타 베이스 Pod를 관리하게 되면 여러가지 문제가 발생한다.

Pod의 이름

RS 등, Stateless Pod를 관리하는 컨트롤러에 의해서 관리되는 Pod들의 이름은 아래 그림과 같이 그 이름이 불 규칙적으로 지정된다.



마스터/슬레이브 구조를 가지는 데이타 베이스등에서 마스터 서버의 이름을 특정 이름으로 지정할 수 가 없다.

Pod의 기동 순서

RS에 의해서 관리되는 Pod들은 기동이 될때 병렬로 동시에 기동이 된다. 그러나 데이타베이스의 경우에는 마스터 노드가 기동된 다음에, 슬레이브 노드가 순차적으로 기동되어야 하는 순차성을 가지고 있는 경우가 있다.

볼륨 마운트

Pod에 볼륨을 마운트 하려면, Pod는 PersistentVolume (이하 PV)를 PersistentVolumeClaim(이하 PVC)로 연결해서 정의해야 한다.

RS등의 컨트롤러를 사용해서 Pod를 정의하게 되면, Pod 템플릿에 의해서 PVC와 PV를 정의하게 되기 때문에, 여러개의 Pod들에 대해서 아래 그림과 같이 하나의 PVC와 PV만 정의가 된다. RS의 Pod 템플릿에 의해 정의된 Pod들은 하나의 PVC와 연결을 시도 하는데, 맨 처음 생성된 Pod가 이 PVC와 PV에 연결이 되기 때문에 뒤에 생성되는 Pod들은 PVC를 얻지 못해서 디스크를 사용할 수 없게 된다.   


아래 YAML 파일은 위의 내용을 테스트 하기 위해서 작성한 파일이다.


apiVersion: v1

kind: PersistentVolumeClaim

metadata:

name: helloweb-disk

spec:

accessModes:

  - ReadWriteOnce

resources:

  requests:

    storage: 30Gi

---

apiVersion: v1

kind: ReplicationController

metadata:

name: nginx

spec:

replicas: 3

selector:

  app: nginx

template:

  metadata:

    name: nginx

    labels:

      app: nginx

  spec:

    containers:

    - name: nginx

      image: nginx:1.7.9

      volumeMounts:

      - name: nginx-data

        mountPath: /data/redis

      ports:

      - containerPort: 8090

    volumes:

    - name: nginx-data

      persistentVolumeClaim:

        claimName: helloweb-disk



nginx Pod를 RC를 이용하여 3개를 만들도록 하고, nginx-data 라는 볼륨을 helloweb-disk라는 PVC를 이용해서 마운트 하는 YAML 설정이다. 이 설정을 실행해보면 아래 그림과 같이 nginx-2784n Pod 하나만 생성된다.




%kubectl describe pod nginx-6w9xf

명령을 이용해서 다른 Pod가 기동되지 않는 이유를 조회해보면 다음과 같은 결과를 얻을 수 있다.



내용중에 중요한 내용을 보면 다음과 같다.


“Multi-Attach error for volume "pvc-d930bfcb-2ec0-11e9-8d43-42010a920009" Volume is already used by pod(s) nginx-2784n”


앞에서 설명한 대로, 볼륨(PV)이 다른 Pod (nginx-2784n)에 의해 이미 사용되고 있기 때문에 볼륨을 사용할 수 없고, 이로 인해서, Pod 생성이 되지 않고 있는 상황이다.


RS로 이를 해결 하려면 아래 그림과 같이 Pod 마다 각각 RS을 정의하고, Pod마다 각기 다른 PVC와 PV를 바인딩하도록 설정해야 한다.



그러나 이렇게 Pod 마다 별도로 RS와 PVC,PV를 정의하는 것은 편의성 면에서 쉽지 않다.

StatefulSet

그래서 상태를 유지하는 데이타베이스와 같은 애플리케이션을 관리하기 위한 컨트롤러가 StatefulSet 컨트롤러이다. (StatefulSet은 쿠버네티스 1.9 버전 부터 정식 적용 되었다. )

StatefulSet은 앞에서 설명한 RS등의 Stateless 애플리케이션이 관리하는 컨트롤러로 할 수 없는 기능들을 제공한다. 대표적인 기능들은 다음과 같다.

Pod 이름에 대한 규칙성 부여

StatefulSet에 의해서 생성되는 Pod들의 이름은 규칙성을 띈다. 생성된 Pod들은 {Pod 이름}-{순번} 식으로 이름이 정해진다. 예를 들어 Pod 이름을 mysql 이라고 정의했으면, 이 StatefulSet에 의해 생성되는 Pod 명들은 mysql-0, mysql-1,mysql-2 … 가 된다.

배포시 순차적인 기동과 업데이트

또한 StatefulSet에 의해서 Pod가 생성될때, 동시에 모든 Pod를 생성하지 않고, 0,1,2,.. 순서대로 하나씩 Pod를 생성한다. 이러한 순차기동은 데이타베이스에서 마스터 노드가 기동된 후에, 슬레이브 노드가 기동되어야 하는 조건등에 유용하게 사용될 수 있다.

개별 Pod에 대한 디스크 볼륨 관리

RS 기반의 디스크 볼륨 관리의 문제는 하나의 컨트롤러로 여러개의 Pod에 대한 디스크를 각각 지정해서 관리할 수 없는 문제가 있었는데, StatefulSet의 경우 PVC (Persistent Volume Claim)을 템플릿 형태로 정의하여, Pod 마다 각각 PVC와 PV를 생성하여 관리할 수 있도록 한다.


그럼 StatefulSet 예제를 보자


apiVersion: apps/v1

kind: StatefulSet

metadata:

name: nginx

spec:

selector:

  matchLabels:

    app: nginx

serviceName: "nginx"

replicas: 3

template:

  metadata:

    labels:

      app: nginx

  spec:

    terminationGracePeriodSeconds: 10

    containers:

    - name: nginx

      image: k8s.gcr.io/nginx-slim:0.8

      ports:

      - containerPort: 80

        name: web

      volumeMounts:

      - name: www

        mountPath: /usr/share/nginx/html

volumeClaimTemplates:

- metadata:

    name: www

  spec:

    accessModes: [ "ReadWriteOnce" ]

    storageClassName: "standard"

    resources:

      requests:

        storage: 1Gi


RS나 RC와 크게 다른 부분은 없다. 차이점은 PVC를 volumeClaimTemplate에서 지정해서 Pod마다 PVC와 PV를 생성하도록 하는 부분이다. 위의 볼드처리한 부분


이 스크립트를 실행하면 아래와 같이 Pod가 배포 된다.



pod의 이름은 nginx-0,1,2,... 식으로 순차적으로 이름이 부여되고 부팅 순서도 0번 pod가 기동되고 나면 1번이 기동되고 다음 2번이 기동되는 식으로 순차적으로 기동된다.


template에 의해서 PVC가 생성되는데, 아래는 생성된 PVC 목록이다. 이름은 {StatefulSet}-{Pod명} 식으로 PVC가 생성이 된것을 확인할 수 있다.


그리고 마지막으로 아래는 PVC에 의해서 생성된 PV(디스크 볼륨)이다.

기동 순서의 조작

위의 예제에 보는것과 같이, StatefulSet은 Pod를 생성할때 순차적으로 기동되고, 삭제할때도 순차적으로 (2→ 1 → 0 생성과 역순으로) 삭제한다. 그런데 만약 그런 요건이 필요 없이 전체가 같이 기동되도 된다면 .spec.podManagementPolicy 를 통해서 설정할 수 있다.

.spec.podManagementPolicy 는 디폴트로 OrderedReady 설정이 되어 있고, Pod가 순차적으로 기동되도록 설정이 되어 있고, 병렬로 동시에 모든 Pod를 기동하고자 하면  Parallel 을 사용하면 된다.

아래는 위의 예제에서 podManagementPolicy를 Parallel로 바꾼 예제이다.

apiVersion: apps/v1

kind: StatefulSet

metadata:

name: nginx

spec:

selector:

  matchLabels:

    app: nginx

serviceName: "nginx"

podManagementPolicy: Parallel

replicas: 3

template:

  metadata:

    labels:

      app: nginx

  spec:

    terminationGracePeriodSeconds: 10

    containers:

:

Pod Scale out and in

지금까지 StatefulSet에 대한 개념과 간단한 사용방법에 대해서 알아보았다. 그러면, StatefulSet에 의해 관리되는 Pod가 장애로 인하거나 스케일링 (In/out)으로 인해서 Pod의 수가 늘거나 줄면 그에 연결되는 디스크 볼륨은 어떻게 될까?


예를 들어 아래 그림과 같이 Pod-1,2,3 이 기동되고 있고, 이 Pod들은 StatefulSet에 의해서 관리되고 있다고 가정하자. Pod들은 각각 디스크 볼륨 PV-1,2,3 을 마운트해서 사용하고 있다고 하자.



이때, Pod-3가 스케일인이 되서, 없어지게 되면, Pod는 없어지지면, 디스크 볼륨을 관리하기 위한 PVC-3는 유지 된다. 이는 Pod 가 비정상적으로 종료되었을때 디스크 볼륨의 내용을 유실 없이 유지할 수 있게 해주고, 오토 스케일링이나 메뉴얼로 Pod를 삭제했을때도 동일하게 디스크 볼륨의 내용을 유지하도록 해준다.



그러면 없앴던 Pod가 다시 생성되면 어떻게 될까? Pod가 다시 생성되면, Pod 순서에 맞는 번호로 다시 생성이 되고, 그 번호에 맞는 PVC 볼륨이 그대로 붙게 되서, 다시 Pod 가 생성되어도 기존의 디스크 볼륨을 그대로 유지할 수 있다.



본인은 구글 클라우드의 직원이며, 이 블로그에 있는 모든 글은 회사와 관계 없는 개인의 의견임을 알립니다.

댓글을 달아 주세요

  1. 준티 2019.06.30 09:24 신고  댓글주소  수정/삭제  댓글쓰기

    잘 읽었습니다. 감사합니다!

구글 CloudSQL(MySQL) 접속하기

조대협 (http://bcho.tistory.com)


개요 


구글 클라우드에서는 MySQL의 매니지드 서비스 형태로 CloudSQL 서비스를 제공한다. 

이 글에서는 CloudSQL을 서버에서 접근하는 방법과, 일반적인 MySQL 클라이언트로 접근하는 방법에 대해서 설명하고자 한다.


몇가지 배경


CloudSQL은 매니지드 MySQL서비스이다. 아마존에 RDS서비스와 같다고 보면 되는데 현재는 1세대를 서비스하고 있고, 곧 2세대가 서비스 예정이다.

1세대는 500GB까지의 용량까지 지원하고 있지만 2세대는 10테라까지 지원을 한다.

현재 지원되는 MySQL버전은 5.5와 5.6 지원하고, 내부 엔진으로는  InnoDB만을 제공한다.


2 세대에 기대되는 기능으로는 On Prem(호스팅 센터에 있는) MySQL과 복제 구성이 가능하다. On Prem에 있는 서버를 마스터로 할 수 도 있고, 반대로 마스터를 CloudSQL로 사용하고 읽기 노드를 On Prem에 구성하는 등 다양한 하이브리드 구성이 가능하다. (기대되는 부분)


자동 백업, 확장을 위한 읽기 전용 노드 (Read replica)등 필수적인 기능을 제공하고 있다.


연결 방식


CloudSQL은 RDS와는 다르게 private ip (10.x.xx)를 아직 지원하지 않고 public ip만을 지원한다. 그래서 서버에 접근하려면 이 public ip를 통해서 접근하면 된다. 보안을 위한 접근 통제 방법으로 특정 IP 주소에서 들어오는 트래픽만을 받아드리도록 설정이 가능하다.


또는 PaaS서비스인 구글 앱앤진을 사용하는 경우에는 구글 앱앤진의 인스턴스나 그룹 단위로 접근 통제가 가능하다.

다음 그림은 콘솔상에서 접근이 가능한 IP 주소를 지정하는 화면이다.



MySQL 클라이언트를 이용하여 접속을 할때 mysqlclient를 이용하여 직접 ip등을 입력하고 접속을해도 되지만 이 경우에는 CloudSQL에서 Ip를 허용해줘야 하기 때문에 개발이나 기타 운영 환경등에서 IP 주소가 바뀌면 그때 마다 설정을 해줘야 하기 때문에 불편할 수 있다.

이를 조금 더 편하게 하려면 mysqlclient를 사용하지 않고 구글에서 제공하는 "gcloud" 라는 도구를 이용하면, 별도로 접속 IP를 열지 않더라도 접속이 가능하다.

접속 방법은 먼저 gcloud  명령어를 인스톨 한 후에 


$ gcloud config set project [클라우드 프로젝트 이름]

$ gcloud beta sql connect [CloudSQL 인스턴스이름] —user=root

(여기서 --user=root 에서 root 사용자는 MySQL 인스턴스내의 사용자이다)


으로 접속하면 MySQL 클라이언트와 동일한 툴로 접속이 된다.


gcloud 툴킷을 이용한 자세한 접속 방법은 https://cloud.google.com/sql/docs/mysql-client#connect-ssl 를 참고하기 바란다.


참고

  • Toad, MySQL Workbench 등에서 안전하게 연결하는 방법 https://cloud.google.com/sql/docs/admin-tools#squirrel


본인은 구글 클라우드의 직원이며, 이 블로그에 있는 모든 글은 회사와 관계 없는 개인의 의견임을 알립니다.

댓글을 달아 주세요