Table of Contents |
---|
minLevel | 1 |
---|
maxLevel | 6 |
---|
outline | false |
---|
type | list |
---|
printable | false |
---|
|
Github
아래 예제들에 대한 전체 helm chart는 https://github.com/snetsystems/K8s-Objects/tree/master/helm-charts 에서 볼 수 있다.
Walkthrough overview
Code Block |
---|
|
[Telegraf] ---8086--> [InfluxDB] <---8086--- [CH Srv] <---443--- [External]
/\ /\
8086| |
|9094 |2379
\/ \/
[Kapacitor] [ETCD Cluster] |
이번 장에서는 보다 더 다양한 production 환경에 근접한 실습이 될 수 있도록 위 서비스를 배포하여 본다.
또한, K8s application package 관리의 편의성을 위해 Helm Chart를 사용하기로 한다.
기본적인 사용법은 Quickstart Helm 을 참고하고, 아래 컴포넌트들을 하나씩 배포하여 보자.
Deploy InfluxDB
CloudHub와 호환되는 InfluxDB의 버전은 1.18이므로, InfluxDB:1.18로 배포하기 위해 아래 influxdata의 repo를 추가한다.
Add Helm Repo
만일 아래 influxdata의 repo가 추가되어 있지 않다면, 아래 명령어로 추가하여 준다.
Code Block |
---|
|
$ helm repo add influxdata https://helm.influxdata.com/
$ helm search repo influxdb
NAME CHART VERSION APP VERSION DESCRIPTION
bitnami/influxdb 5.7.0 2.7.1 InfluxDB(TM) is an open source time-series data...
influxdata/influxdb 4.12.3 1.8.10 Scalable datastore for metrics, events, and rea...
influxdata/influxdb-enterprise 0.1.22 1.10.0 Run InfluxDB Enterprise on Kubernetes
influxdata/influxdb2 2.1.1 2.3.0 A Helm chart for InfluxDB v2
influxdata/kapacitor 1.4.6 1.6.4 InfluxDB's native data processing engine. It ca...
influxdata/chronograf 1.2.5 1.9.4 Open-source web application written in Go and R...
influxdata/telegraf 1.8.28 1.26.3 Telegraf is an agent written in Go for collecti...
influxdata/telegraf-operator 1.3.11 v1.3.10 A Helm chart for Kubernetes to deploy telegraf-... |
Installation
설치 명령어
위의 여러 버전들 중에 influxdata/influxdb 4.12.3 1.8.10
을 목표 버전으로 하고, Helm chart를 통해 설치하는 방법은 아래 두 가지(세부적으로는 세 가지) 정도가 있다.
helm pull influxdata/influxdb
를 통해 로컬에 다운로드 후, 아래 명령 중 하나로 설치.
-g
: Deploy 이름 자동 생성 모드helm install -n helm-test -g influxdb-4.12.3.tgz
tar xzf influxdb-4.12.3.tgz && helm install -n helm-test -g ./influxdb
Helm repo를 통해 설치.
helm install -n helm-test -g influxdata/influxdb
필자 생각에는 참고 삼아 배포하거나 show values
등의 명령을 사용하여 리서치할 용도가 아니라, 본인의 K8s에 배포를 목적으로 한다면, 위 1번이 버전을 따로 관리하기에도 편하고 charts 구조 및 내용을 탐색하기에도 편한 듯 하다.
캐바캐이니, 편한대로 하여도 좋으나, 여기서는 1번 방식으로 배포하도록 하겠다.
Values override
influxdata/influxdb
내부의 values를 상황에 맞게 override 하자.
사용 가능한 values는 위 influxdb-4.12.3.tgz
를 압축 해제한 폴더의 values.yaml
을 보면 되며,helm show values influxdata/influxdb
명령을 통해서도 볼 수 있다.--set
옵션을 통해 override 할 수 있으나, 항목이 여러 개일 경우 번거로우므로 influxdb_override.yaml
내에 oerride할 내용을 기입하여 create 혹은 upgrade 시 반영하도록 한다.
object 키워드 및 형식은 대부분 k8s object yaml과 동일하다.
Code Block |
---|
| # 편의상 "helm-test" namespace 생성.
$ kubectl create ns helm-test
# helm-test ns에 chart name은 자동 생성 모드(-g)로 생성.
$ helm install |
$ vim influxdb_override.yaml
persistence:
enabled: false
service:
type: ClusterIP
ports:
- port: 8086
externalIPs:
- 10.20.2.235
- 10.20.2.236
nodeSelector:
kubernetes.io/os: linux
kubernetes.io/hostname: test-k8s-worker01-centos8.snetsystems.com |
Influxdb는 데이터베이스 이므로 당연히 상태를 가지는 pod(kind: StatefulSet)가 생성되어야 한다.
하지만 현재 persistence volume을 생성해두지 않았으므로, 일단 persistence.enabled = false
로 하여 생성하여 pod 생성이 잘 되는 지 등, 그 밖에 기능들이 생각한 대로 워킹하는지 확인한다.
차후, persistence volume으로 대체하기로 한다.
helm show values influxdata/influxdb
결과의 values.config.http.bind-address: ":8086"
이므로 서비스 포트를 8086으로 지정하였다.
또한, 외부 접근을 위해 externalIPs
도 추가하였다.
1과 같이 공유 persistence volume을 사용하지 않기 때문에 pod가 업그레이드 되거나 혹은 재 생성되거나 할 때, 데이터 유지를 위해서는 반드시 같은 노드에 생성되어야 한다.
따라서 nodeSelector
를 통해 worker01
노드에만 생성되도록 하였다.
Install influxdb
그럼 위의 influxdb_override.yaml
와 함께 배포해본다.
필자의 경우에는 이미 helm install -n helm-test -g ./influxdb
명령어를 통해 불완전하게나마 생성을 한 상태이다.
따라서, 아래와 같이 upgrade
를 통해 influxdb_override.yaml
의 내용을 적용하도록 하겠다.
Code Block |
---|
|
# helm upgrade -n helm-test influxdb-1688227557 -g influxdataf influxdb_override.yaml ./influxdb
--set persistence.enabled=falseRelease "influxdb-1688227557" has been upgraded. Happy Helming!
NAME: influxdb-1688227557
LAST DEPLOYED: SunMon Jul 23 0113:0650:0543 2023
NAMESPACE: helm-test
STATUS: deployed
REVISION: 16
TEST SUITE: None
NOTES:
InfluxDB can be accessed via port 8086 on the following DNS name from within your cluster:
http://influxdb-1688227557.helm-test:8086
You can connect to the remote instance with the influx CLI. To forward the API port to localhost:8086, run the following:
kubectl port-forward --namespace helm-test $(kubectl get pods --namespace helm-test -l app=influxdb-1688227557 -o jsonpath='{ .items[0].metadata.name }') 8086:8086
You can also connect to the influx CLI from inside the container. To open a shell session in the InfluxDB pod, run the following:
kubectl exec -i -t --namespace helm-test $(kubectl get pods --namespace helm-test -l app=influxdb-1688227557 -o jsonpath='{.items[0].metadata.name}') /bin/sh
To view the logs for the InfluxDB pod, run the following:
kubectl logs -f --namespace helm-test $(kubectl get pods --namespace helm-test -l app=influxdb-1688227557 -o jsonpath='{ .items[0].metadata.name }')
[root@test-k8s-master-centos8 helm]# kubectl get svc -n helm-test
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
influxdb-1688227557 ClusterIP 10.97.73.25 10.20.2.235,10.20.2.236 8086/TCP,8088/TCP 36h
nginx-1688100975 NodePort 10.106.11.197 <none> 80:30117/TCP 2d23h |
Override된 내용은 아래 명령을 통해서 변경된 내용만 확인도 가능하다.
Code Block |
---|
|
$ helm get values -n helm-test influxdb-1688227557
USER-SUPPLIED VALUES:
nodeSelector:
kubernetes.io/hostname: test-k8s-worker01-centos8.snetsystems.com
kubernetes.io/os: linux
persistence:
enabled: false
service:
externalIPs:
- 10.20.2.235
ports:
- port: 8086
type: ClusterIP |
여기까지 성공적으로 수행이 되었다면, http://10.20.2.235:8086 으로 CloudHub의 data source로 추가도 가능할 것이다.
...
To do
위에서 언급한 것처럼 StatefulSet을 위한 persistence volume claim을 생성하여 production 환경과 유사한 배포를 해볼 것이다.
Deploy Kapacitor
Info |
---|
여기에서는 편의상 Headless Service로 생성하지 않을 것이나, 사실 kapacitor의 경우 stateless하며 k8s 클러스터 내부 통신만 허용하면 되고, 더구나 CloudHub에서는 굳이 로드밸런싱할 이유가 (현재까지 상황으로는) 별로 없기 때문에 Headless Service가 더 적합하다. https://seversky.atlassian.net/wiki/spaces/CHT/pages/2114289730/Service+Discovery#Headless-Service 참조. 만일 외부의 telegraf 등에서 직접 kapacitor로 데이터를 전송해야 한다면, Headless Service를 사용하면 곤란해 질 것이다. |
InfluxDB의 배포가 정상 가동되면, 이제 Kapacitor를 배포하여 보자.
CloudHub latest 버전인 v1.4.4에서는 Kapacitor 호환 버전 KAPACITOR_TAG=1.5.4
를 사용하고 있다.
그런데, 현재 Helm artifacthub의 공식 influxdata/kapacitor
는 아래와 같이 APP VERSION = 1.6.4
만 업로드 되어 있다.
Code Block |
---|
|
$ helm search repo kapacitor
NAME CHART VERSION APP VERSION DESCRIPTION
influxdata/kapacitor 1.4.6 1.6.4 InfluxDB's native data processing engine. It ca... |
물론, github에는 여러 버전의 chart들이 업로드 되어 있고, Docker hub에도 다양한 버전으로 tag된 image들이 있으므로 version skew를 최소화 할 수 있으나, Kapacitor 공식 문서나 Github CHANGELOG.md를 봐도 호환이 가능할 것 같다는 생각이 들어, 일단 APP VERSION = 1.6.4
으로 배포하여 테스트를 진행하기로 한다.
Code Block |
---|
|
$ helm pull influxdata/kapacitor |
Values override
Kapacitor는 특별히 상태를 가지지 않아도 되므로 Deployment로 배포된다.
따라서 nodeSeletor
는 따로 지정하지 않는다.
Code Block |
---|
|
$ vim kapacitor_override.yaml
persistence:
enabled: false
service:
type: ClusterIP
ports:
- port: 9094
targetPort: 9092
externalIPs:
- 10.20.2.236
influxURL: http://influxdb-1688227557:8086 |
위의 yaml로 helm install -n helm-test -g -f kapacitor_override.yaml ./kapacitor
를 하면 실제 서비스 포트는 9092, externalIPs
는 잡히지 않는다. Code Block |
---|
|
$ kubectl get svc -n helm-test
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
influxdb-1688227557 ClusterIP 10.97.73.25 10.20.2.235,10.20.2.236 8086/TCP,8088/TCP 2d16h
kapacitor-1-1688391149-kapacitor ClusterIP 10.100.185.40 <none> 9092/TCP 19h |
kapacitor/templates/service.yaml을 보게되면, Code Block |
---|
|
spec:
type: {{ .Values.service.type }}
ports:
- port: 9092
targetPort: 9092
name: api
selector:
app: {{ template "kapacitor.fullname" . }} |
spec.type과 selector.app을 제외하면 모두 변수가 아니라 상수로 지정되어 있다.
따라서, kapacitor/templates/service.yaml과 kapacitor/values.yaml을 적절히 수정한다. Code Block |
---|
|
$ vim kapacitor/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: {{ template "kapacitor.fullname" . }}
labels:
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
release: "{{ .Release.Name }}"
heritage: "{{ .Release.Service }}"
app: {{ template "kapacitor.fullname" . }}
spec:
type: {{ .Values.service.type }}
{{- if .Values.service.ports }}
ports:
{{ toYaml .Values.service.ports | indent 4 }}
{{- end }}
selector:
app: {{ template "kapacitor.fullname" . }}
{{- if .Values.service.externalIPs }}
externalIPs:
{{ toYaml .Values.service.externalIPs | indent 4 }}
{{- end }} |
Values override를 하지 않으면 default 값이 템플릿으로 넘어 갈 수 있도록 아래와 같이 values.yaml도 수정해준다.
Code Block |
---|
|
$ vim kapacitor/values.yaml
...
## Specify a service type, defaults to NodePort
## ref: http://kubernetes.io/docs/user-guide/services/
##
service:
type: ClusterIP
ports:
- port: 9092
- targetPort: 9092
#externalIPs:
... |
Install kapacitor
이제 위에 만들어둔 kapacitor_override.yaml와 함께 설치(이미 설치되어 있으므로 upgrade)해 본다.
Code Block |
---|
|
$ helm upgrade -n helm-test kapacitor-1-1688391149 -f kapacitor_override.yaml ./kapacitor
Release "kapacitor-1-1688391149" has been upgraded. Happy Helming!
NAME: kapacitor-1-1688391149
LAST DEPLOYED: Wed Jul 5 15:03:32 2023
NAMESPACE: helm-test
STATUS: deployed
REVISION: 18
TEST SUITE: None
NOTES:
Kapacitor can be accessed via port 9092 on the following DNS name from within your cluster:
http://kapacitor-1-1688391149-kapacitor.helm-test:9092
You can connect to the remote instance from a local Kapacitor CLI. Forward the API port to localhost:9092:
kubectl port-forward --namespace helm-test $(kubectl get pods --namespace helm-test -l app=kapacitor-1-1688391149-kapacitor -o jsonpath='{ .items[0].metadata.name }') 9092:9092
You can also connect to the container running Kapacitor. To open a shell session in the pod, run the following:
kubectl exec -i -t --namespace helm-test $(kubectl get pods --namespace helm-test -l app=kapacitor-1-1688391149-kapacitor -o jsonpath='{.items[0].metadata.name}') /bin/sh
To view the logs for the Kapacitor pod, run the following: |
필자의 try & error로 인해 벌써 REVISION: 18
까지 올라간 것을 볼 수 있다.
이제, 앞서 연결한 InfluxDB data source에 위 kapacitor를 연결하면 정상 작동 할 것이다.
...
Deploy ETCD
일단 모든 공개 허브에서 etcd를 검색해보면, 아래와 같이 여러 APP VERSION
의 Repo가 출력된다.
Code Block |
---|
|
$ helm search hub etcd
URL CHART VERSION APP VERSION DESCRIPTION
https://artifacthub.io/packages/helm/wenerme/etcd 9.0.4 3.5.9 etcd is a distributed key-value store designed ...
https://artifacthub.io/packages/helm/bitnami/etcd 9.0.4 3.5.9 etcd is a distributed key-value store designed ...
https://artifacthub.io/packages/helm/wener/etcd 9.0.4 3.5.9 etcd is a distributed key-value store designed ...
https://artifacthub.io/packages/helm/bitnami-ak... 8.5.8 3.5.5 etcd is a distributed key-value store designed ...
https://artifacthub.io/packages/helm/riftbit/etcd 6.8.4 3.5.0 etcd is a distributed key value store that prov...
https://artifacthub.io/packages/helm/cloudnativ... 2.2.3 3.3.13 etcd is a distributed key value store that prov...
https://artifacthub.io/packages/helm/gardener-c... 5.3.1 v3.5.2 Helm chart for etcd
https://artifacthub.io/packages/helm/groundhog2... 0.1.5 v3.5.9 A Helm chart for etcd on Kubernetes
https://artifacthub.io/packages/helm/kubesphere... 0.1.3 3.3.12 etcd is a distributed reliable key-value store ...
... |
Kapacitor와 마찬가지로, CloudHub에서 현재까지 공식 호환 Etcd 버전은 3.3.11이지만, 최신 버전도 호환되는 지 여부 등을 테스트 해보기 위해 APP VERSION=3.5.9
로 설치할텐데, 이는 이미 이전에 bitnami repo가 추가된 상태이므로 바로 repo를 다운로드할 수 있다.
Code Block |
---|
|
$ helm search repo etcd
NAME CHART VERSION APP VERSION DESCRIPTION
bitnami/etcd 9.0.2 3.5.9 etcd is a distributed key-value store designed ...
$ helm pull bitnami/etcd && tar xzf etcd-9.0.2.tgz |
etcd helm chart를 보면 매우 복잡한 구조로 되어 있음을 볼 수 있다.
일단, ./etcd/templates/statefulset.yaml
과 ./etcd/values.yaml
을 살펴보고 필요한 항목을 override한다.
필자가 추가한 내용은 다음과 같다.
Code Block |
---|
|
$ etcd_override.yaml
replicaCount: 3
persistence:
## @param persistence.enabled If true, use a Persistent Volume Claim. If false, use emptyDir.
##
enabled: false
tolerations:
- operator: Exists
disasterRecovery:
cronjob:
tolerations:
- operator: Exists |
Etcd cluster 개수의 최소 요구 조건은 3개 이므로, replicaCount
는 3개로 주었다.
persistence
는 InfluxDB와 마찬가지로 PersistentVolume 부터 따로 다룬 후 적용할 것이다.
지금은 enabled: false
.
현재 테스트 베드 구성 상, worker 노드를 2개만 생성하였다. 1번의 제약으로 인해 control plane에도 생성되게 하기 위해 tolerations
를 적용하였다.
물론 Production에서는 worker node에만 생성되게 하는 것을 권장한다.
Sevice는 Etcd의 경우 CloudHub 서버에서만 접속 가능하면 되므로, 별도 외부에서 접속할 일이 없을 듯 하여 override하지 않았다.
아래와 같이 배포한 후, 정상 배포되면 접속 방법 등의 간략한 가이드가 출력될텐데, 어떤 것들이 있는지 눈여겨 봐두면 이후 작업(CloudHub 설정 작업 등)에 도움이 될 수 있을 것이다.
Code Block |
---|
|
# helm install -n helm-test -g -f etcd_override.yaml ./etcd
NAME: etcd-1688819715
LAST DEPLOYED: Sat Jul 8 21:35:15 2023
NAMESPACE: helm-test
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
CHART NAME: etcd
CHART VERSION: 9.0.2
APP VERSION: 3.5.9
** Please be patient while the chart is being deployed **
etcd can be accessed via port 2379 on the following DNS name from within your cluster:
etcd-1688819715.helm-test.svc.cluster.local
To create a pod that you can use as a etcd client run the following command:
kubectl run etcd-1688819715-client --restart='Never' --image docker.io/bitnami/etcd:3.5.9-debian-11-r18 --env ROOT_PASSWORD=$(kubectl get secret --namespace helm-test etcd-1688819715 -o jsonpath="{.data.etcd-root-password}" | base64 -d) --env ETCDCTL_ENDPOINTS="etcd-1688819715.helm-test.svc.cluster.local:2379" --namespace helm-test --command -- sleep infinity
Then, you can set/get a key using the commands below:
kubectl exec --namespace helm-test -it etcd-1688819715-client -- bash
etcdctl --user root:$ROOT_PASSWORD put /message Hello
etcdctl --user root:$ROOT_PASSWORD get /message
To connect to your etcd server from outside the cluster execute the following commands:
kubectl port-forward --namespace helm-test svc/etcd-1688819715 2379:2379 &
echo "etcd URL: http://127.0.0.1:2379"
* As rbac is enabled you should add the flag `--user root:$ETCD_ROOT_PASSWORD` to the etcdctl commands. Use the command below to export the password:
export ETCD_ROOT_PASSWORD=$(kubectl get secret --namespace helm-test etcd-1688819715 -o jsonpath="{.data.etcd-root-password}" | base64 -d) |
Deploy CloudHub
위의 예제들과 기본적 개념은 유사하므로, https://github.com/snetsystems/K8s-Objects/tree/master/helm-charts 를 참고하도록 한다.