티스토리 뷰

<츨처>

https://kubernetes.io/docs/tutorials/stateful-application/cassandra/




이번 튜토리얼에서는 K8S 상에서 여러분이 어떻게 네이티브 클라우드 Cassandra 배포를 개발할 수 있는지 보여준다. 이 예시에서, 주문제작한(custom) Cassandra SeedProvider 는 새로운 Cassandra 노드들이 클러스터에 가입할 때,  Cassandra가 그것들을 발견할 수 있도록 해준다.

StatefulSets은 클러스터가 구성된 환경 속에서 stateful 한 애플리케이션을 배포하기 쉽도록 해준다. 이 튜토리얼에서 이용된, 그 특성에 관한 추가 정보는, StatefulSet 문서를 참조한다.


Docker 기반 Cassandra

이 튜토리얼 내 Pods는 구글 container registry에 있는 gcr.io/google-samples/cassandra:v13 이미지를 이용한다 . 위 도커 이미지는 debian-base를 토대로 하며 OpenJDK 8을 포함하고 있다. 

이 이미지는 Apache Debian repo의 표준 Cassandra 설치를 포함한다. 여러분은 환경변수를 이용하여 "cassandra.yaml" 내 삽입되어져 있는 value들을 변경할 수 있다.


ENV VAR
DEFAULT VALUE
CASSANDRA_CLUSTER_NAME'Test Cluster'
CASSANDRA_NUM_TOKENS32
CASSANDRA_RPC_ADDRESS0.0.0.0





Objectives





Before you begin


이번 튜토리얼을 완료하기 위해서,  여러분은 PodsServices, 그리고 StatefulSets에 대해 기본적인 익숙함이 있어야만 한다. 더불어,

주의: 만약 클러스터가 아직 없다면, 시작을 위한 가이드를 읽어보기 바란다.

Additional Minikube Setup Instructions


경고: Minikube는 기본적으로 1024MB 메모리에 1 CPU로 구동된다. 기본 자원 구성으로 Minikube를 동작하게 되면, 이 튜토리얼 내내 불충분 자원 에러를 초래하게 된다. 이러한 에러들을 피하기 위해서는, 다음 설정들로 Minikube를 구동시킨다.

minikube start --memory 5120 --cpus=4


실제 위에서 권장한 리소스 뿐만 아니라 추가의 리소스(8G RAM/4 CPU)를 할당해봐도 메모리 에러는 피할 수 없었다. 여러분이 Minikube를 이용해 실습하고자 할 경우, 재확인 해보길 바란다. 아마도 동일한 결과가 나타날 것이다. 시험삼아 한번정도 시도해 보고, 가급적 구글 클라우드 환경에서 진행할 것을 권장한다.

그러나 구글 클라우드의 경우에도, 원문에서 제시하는 방식으로는 불충분 CPU 에러가 발생하였다. 일단 튜토리얼을 무난히 마치고 결과를 보는게 목적인지라 임시방편으로 처리(하기에 방편 제시)하도록 하였으나, 여하튼 실습들이 점점 어려워 지고 있음을 느낀다. 하고픈 것도, 해야 할 것도 점점 많아진다. 잼난다~~~^


Minikube 상에 추가 리소스 할당하여 진행하지만, 메모리 이슈 발생

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
root@zerobig-vm_u:~# minikube start --memory 8192 --cpus 4
Starting local Kubernetes v1.10.0 cluster...
Starting VM...
Getting VM IP address...
Moving files into cluster...
Setting up certs...
Connecting to cluster...
Setting up kubeconfig...
Starting cluster components...
Kubectl is now configured to use the cluster.
Loading cached images from config file.
root@zerobig-vm_u:~# minikube status
minikube: Running
cluster: Running
kubectl: Correctly Configured: pointing to minikube-vm at 192.168.99.100
cs


메모리 부족 에러 예시

구글 클라우드 작업환경 설정

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@docker-registry ~]# gcloud container clusters get-credentials zerobig-cluster-1 --zone asia-east1-c --project zerobig-k8s-tutorial
Fetching cluster endpoint and auth data.
kubeconfig entry generated for zerobig-cluster-1.
 
 
Updates are available for some Cloud SDK components.  To install them,
please run:
  $ gcloud components update
 
[root@docker-registry ~]# kubectl get nodes
NAME                                               STATUS    ROLES     AGE       VERSION
gke-zerobig-cluster-1-default-pool-d22ac19b-4c42   Ready     <none>    4d        v1.9.7-gke.6
gke-zerobig-cluster-1-default-pool-d22ac19b-7gc1   Ready     <none>    4d        v1.9.7-gke.6
gke-zerobig-cluster-1-default-pool-d22ac19b-fc6x   Ready     <none>    4d        v1.9.7-gke.6
cs





Creating a Cassandra Headless Service


K8S Service는 동일한 작업을 수행하는 Pods 세트를 기술한다.

다음의 "Service"는 K8S 클러스터 이내의 Cassandra Pods와 클라이언트들 사이에서 DNS lookup 을 위해 이용된다.


application/cassandra/cassandra-service.yaml

1
2
3
4
5
6
7
8
9
10
11
12
apiVersion: v1
kind: Service
metadata:
  labels:
    app: cassandra
  name: cassandra
spec:
  clusterIP: None
  ports:
  - port: 9042
  selector:
    app: cassandra
cs



1. manifest 파일들을 다운로드했던 디렉토리에서 터미널 창을 구동시킨다. 

2. "cassandra-service.yaml" 파일로부터 모든 Cassandra StatefulSet 노드를 추적하기 위해 Service를 생성한다 :

1
2
3
[root@docker-registry ~]# kubectl create -f https://k8s.io/examples/application/cassandra/cassandra-service.yaml
service/cassandra createdroot@zerobig-vm_u:~# kubectl create -f https://k8s.io/examples/application/cassandra/cassandra-service.yaml
service/cassandra created
cs


Validating (optional)


Cassandra Service를 확인해 본다.

1
[root@docker-registry ~]# kubectl get svc cassandra
cs


그 응답은

1
2
3
[root@docker-registry ~]# kubectl get svc cassandra
NAME        TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
cassandra   ClusterIP   None         <none>        9042/TCP   22s
cs


아무런 반응결과 없이 Service 생성이 실패가 나면, 일반적인 이슈들에 대한 Debug Services을 읽어본다.





Using a StatefulSet to Create a Cassandra Ring


아래 포함된, StatefulSet manifest은 3개의 Pod로 구성된 Cassandra 링을 생성한다.


주의: 이 예제는 Minikube를 위해 기본 공급자를 이용한다. 여러분이 작업하고 있는 클라우드를 위해서는 다음의 StatefulSet을 업데이트 하길 바란다.



<참고>

필자는 다음 YAML 파일에서 3,4,100 라인을 4,5,101로 수정하여 진행하였다. 3,4라인은 CPU 에러를 피하기 위함이고, 100라인은 현재 실습환경이 Minikube 환경이 아니기 때문이다.



application/cassandra/cassandra-statefulset.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: cassandra
  labels:
    app: cassandra
spec:
  serviceName: cassandra
  replicas: 3
  selector:
    matchLabels:
      app: cassandra
  template:
    metadata:
      labels:
        app: cassandra
    spec:
      terminationGracePeriodSeconds: 1800
      containers:
      - name: cassandra
        image: gcr.io/google-samples/cassandra:v13
        imagePullPolicy: Always
        ports:
        - containerPort: 7000
          name: intra-node
        - containerPort: 7001
          name: tls-intra-node
        - containerPort: 7199
          name: jmx
        - containerPort: 9042
          name: cql
        resources:
          limits:
#            cpu: "500m"
            cpu: "200m"
            memory: 1Gi
          requests:
#           cpu: "500m"
           cpu: "200m"
           memory: 1Gi
        securityContext:
          capabilities:
            add:
              - IPC_LOCK
        lifecycle:
          preStop:
            exec:
              command:
              - /bin/sh
              - -c
              - nodetool drain
        env:
          - name: MAX_HEAP_SIZE
            value: 512M
          - name: HEAP_NEWSIZE
            value: 100M
          - name: CASSANDRA_SEEDS
            value: "cassandra-0.cassandra.default.svc.cluster.local"
          - name: CASSANDRA_CLUSTER_NAME
            value: "K8Demo"
          - name: CASSANDRA_DC
            value: "DC1-K8Demo"
          - name: CASSANDRA_RACK
            value: "Rack1-K8Demo"
          - name: POD_IP
            valueFrom:
              fieldRef:
                fieldPath: status.podIP
        readinessProbe:
          exec:
            command:
            - /bin/bash
            - -c
            - /ready-probe.sh
          initialDelaySeconds: 15
          timeoutSeconds: 5
        # These volume mounts are persistent. They are like inline claims,
        # but not exactly because the names need to match exactly one of
        # the stateful pod volumes.
        volumeMounts:
        - name: cassandra-data
          mountPath: /cassandra_data
  # These are converted to volume claims by the controller
  # and mounted at the paths mentioned above.
  # do not use these in production until ssd GCEPersistentDisk or other ssd pd
  volumeClaimTemplates:
  - metadata:
      name: cassandra-data
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: fast
      resources:
        requests:
          storage: 1Gi
---
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: fast
# provisioner: k8s.io/minikube-hostpath
provisioner: kubernetes.io/gce-pd
parameters:
  type: pd-ssd
cs


1. 필요하다면, StatefulSet을 업데이트한다.

2. "cassandra-statefulset.yaml 파일로부터 Cassandra StatefulSet을 생성한다:

1
2
3
[root@docker-registry ~]# kubectl create -f /home/study/k8s/application/cassandra/cassandra-statefulset.yaml
statefulset.apps/cassandra created
storageclass.storage.k8s.io/fast created
cs




Validating The Cassandra StatefulSet


1. Cassandra Service를 확인해 본다.

1
[root@docker-registry ~]# kubectl get statefulset cassandra
cs

그 응답은 다음과 같아야 한다.
1
2
3
[root@docker-registry ~]# kubectl get statefulset cassandra
NAME        DESIRED   CURRENT   AGE
cassandra   3         1         17s
cs

"StatefulSet 자원은 순차적으로 Pod를 배포한다.


2. 정렬된 생성 상태를 확인하기 위해 Pod를 확인해 본다.

1
[root@docker-registry ~]# kubectl get pods -l="app=cassandra"
cs

그 응답은 다음과 같아야 한다.
1
2
3
4
[root@docker-registry ~]# kubectl get pods -l="app=cassandra"
NAME          READY     STATUS    RESTARTS   AGE
cassandra-0   1/1       Running   0          3m
cassandra-1   0/1       Running   0          1m
cs

3개의 Pod가 모두 배포되는데 수분의 시간이 소요될 수 있다. 배포가 이루어지면, 동일 명령이 반환된다:

1
2
3
4
5
[root@docker-registry ~]# kubectl get pods -l="app=cassandra"
NAME          READY     STATUS    RESTARTS   AGE
cassandra-0   1/1       Running   0          7m
cassandra-1   1/1       Running   0          5m
cassandra-2   1/1       Running   0          2m
cs


(참고로 GCP 상에서 다음과 같이 보다 직관적으로 상세한 상태를 확인 할 수 있다.)



3. 링의 상태를 전시해주는 Casandra nodetool을 구동한다. 

1
[root@docker-registry ~]# kubectl exec -it cassandra-0 -- nodetool status
cs

그 응답은 다음과 같은 식으로 보여야만 한다.

1
2
3
4
5
6
7
8
9
[root@docker-registry ~]# kubectl exec -it cassandra-0 -- nodetool status
Datacenter: DC1-K8Demo
======================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
--  Address     Load       Tokens       Owns (effective)  Host ID                               Rack
UN  10.52.1.22  104.54 KiB  32           70.5%             5e9d8331-f424-48ea-a488-18c8396961c5  Rack1-K8Demo
UN  10.52.2.16  108.9 KiB  32           74.3%             659cdbc5-a6b4-4c85-9fc4-dd2cb6449670  Rack1-K8Demo
UN  10.52.0.8   103.81 KiB  32           55.1%             41278014-195c-49cc-bc82-ed2314d10733  Rack1-K8Demo
cs






Modifying the Cassandra StatefulSet


Cassandra StatefulSet의 사이즈를 수정하기 위해 "kubectl edit" 을 이용한다.



1. 다음 명령을 수행한다:

1
[root@docker-registry ~]# kubectl edit statefulset cassandra
cs


이 명령은 여러분의 터미널에 편집기를 띄워준다. 변경하려는 라인은 "replicas" 필드이다. 다음 샘플은 StatefulSet 파일의 발췌본이다:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: StatefulSet
metadata:
  creationTimestamp: 2016-08-13T18:40:58Z
  generation: 1
  labels:
  app: cassandra
  name: cassandra
  namespace: default
  resourceVersion: "323"
  selfLink: /apis/apps/v1/namespaces/default/statefulsets/cassandra
  uid: 7a219483-6185-11e6-a910-42010a8a0fc0
spec:
  replicas: 3
cs



2. Change the number of replicas의 숫자를 4로 변경하고, manifest을 저장한다.



3. 검증을 위해 Cassandra StatefulSet 을 확인한다:

1
[root@docker-registry ~]# kubectl get statefulset cassandra
cs


그 응답은 다음과 같아야 한다.

1
2
3
[root@docker-registry ~]# kubectl get statefulset cassandra
NAME        DESIRED   CURRENT   AGE
cassandra   4         4         11m
cs







Cleaning up


StatefulSet의 삭제 또는 스케일 다운은 StatefulSet으로 연계된 볼륨들을 삭제하지 않는다. 모든 관련 StatefulSet 자원들을 자동으로 정리하는 것보다 여러분의 데이터가 더 가치 있기 때문에 이 설정은 여러분의 안전을 위한것이다.  


경고: 스토리지 등급과 반환요구 정책에 따라, PersistentVolumeClaims을 삭제하는 것은 연관된 볼륩들을 함께 지우는 결과를 초래할 수 있다. 볼륨 요구가 제거되어지면, 여러분이 데이터 접근을 할 수 있을거라는 가정은 절대하지 말자.



1. Cassandra "StatefulSet"에서 모든 것을 삭제하기 위해 다음 명령들(하나의 명령어 속에 함께 연결되어진)을 수행한다:

1
2
3
4
5
6
7
8
9
10
11
[root@docker-registry ~]# grace=$(kubectl get po cassandra-0 -o=jsonpath='{.spec.terminationGracePeriodSeconds}') \
>   && kubectl delete statefulset -l app=cassandra \
>   && echo "Sleeping $grace" \
>   && sleep $grace \
>   && kubectl delete pvc -l app=cassandra
statefulset.apps "cassandra" deleted
Sleeping 1800
persistentvolumeclaim "cassandra-data-cassandra-0" deleted
persistentvolumeclaim "cassandra-data-cassandra-1" deleted
persistentvolumeclaim "cassandra-data-cassandra-2" deleted
persistentvolumeclaim "cassandra-data-cassandra-3" deleted
cs



2. Cassandra Service를 삭제하기 위해 다음 명령을 수행한다:

1
2
[root@docker-registry ~]# kubectl delete service -l app=cassandra
service "cassandra" deleted
cs







What's next



댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함