수들의 합 5

시간 제한 메모리 제한
2초 32MB

 

문제

어떠한 자연수 N은, 몇 개의 연속된 자연수의 합으로 나타낼 수 있다. 당신은 어떤 자연수 N(1 ≤ N ≤ 10,000,000)에 대해서, 이 N을 몇 개의 연속된 자연수의 합으로 나타내는 가지수를 알고 싶어한다. 이때, 사용하는 자연수는 N이하여야 한다.

예를 들어, 15를 나타내는 방법은 15, 7+8, 4+5+6, 1+2+3+4+5의 4가지가 있다. 반면에 10을 나타내는 방법은 10, 1+2+3+4의 2가지가 있다.

N을 입력받아 가지수를 출력하는 프로그램을 작성하시오.

입력

첫 줄에 정수 N이 주어진다.

출력

입력된 자연수 N을 몇 개의 연속된 자연수의 합으로 나타내는 가지수를 출력하시오

 

예제 입력 1

15

예제 출력 1

4

 


public class Main {
	private int N;
	private int ans = 0;

	public static void main(String[] args) throws Exception {
		Main main = new Main();
		main.start();
	}

	private void start() throws Exception {
		//System.setIn(new FileInputStream("src/test/input.txt"));
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
		N = Integer.parseInt(br.readLine());
		twoPointer();
		bw.write(ans + "\n");
		bw.close();
		br.close();
		return;
	}

	
	private void basic() {
		for (int first = 1; first <= N; first++) {
			int s = 0;
			for (int until = first; until <= N; until++) {
				if(first == until) s = until;
				else s += until;
				
				if(s == N) ans++;
				else if(s > N) break;
			}
		}
	}
	
	private void twoPointer() {
		int start = 1;
		int end = 1;
		int sum = 1;
		while(start<=end) {
			if(sum == N) ans++;
			if(sum < N) {
				end++;
				sum += end;
			} else if(sum >= N) {
				sum -= start;
				start++;
			}
		}
	}

	private void arithmeticSequence() {
		for (int first = 1; first <= N; first++) {
			int s = 0;
			for (int end = first; end <= N; end++) {
				if (first == end)
					s = end;
				else
					s = (end - first + 1) * (first + end) / 2; // 등차수열의 합

				if (s == N)
					ans++;
				else if (s > N)
					break;
			}
		}
	}
}

 

알고리즘 메모리 시간
기본 반복문 15812 kb 216ms
등차수열 14660 kb 268ms
투포인터 알고리즘 14632 kb 164ms

 

 


출처

백준 2018번

 https://www.acmicpc.net/problem/2018

프로메테우스(Prometheus)는 CNCF가 호스트하는 오픈 소스 소프트웨어 모니터링 도구다.

 

프로메테우스 구성요소

- prometheus-alertmanager : 규칙에 위반하는 사항에 대해서 알람을 전송(메일, 슬랙 등).

- prometheus-kube-state-metrics : 메트릭 수집을 위한 /metrics 엔드포인트를 제공

- prometheus-pushgateway : application이 push gateway에 메트릭을 push 한 후, prometheus server가 pushgateway에 접근해 metric을 pull하는 방식. 프록싱으로 접근할 수 없는 곳에 데이터가 존재하는 경우 사용.

- prometheus-server : 저장소.

- prometheus-node-exporter : prometheus에게 메트릭 정보를 제공.

 

프로메테우스 서버가 수집하는 메트릭은 데이터 소스에서 수집하는 풀방식 아키텍처를 채용하고 있으므로 프로메테우스 서버가 데이터를 수집하러 가는 형태가 된다. 

출처 : https://prometheus.io/docs/introduction/overview/
출처 : https://medium.com/finda-tech/kube-state-metrics%EC%97%90-%EB%8C%80%ED%95%B4%EC%84%9C-1303b10fb8f8

Helm을 이용한 설치

- 옵션 확인

helm inspect values stable/prometheus

- 설치

helm install prometheus stable/prometheus
--set alertmanager.persistentVolume.storageClass="xx"
--set server.persistentVolume.storageClass="xx"
--set pushgateway.persistentVolume.storageClass="xx"

--set nodeExporter.tolerations[0].key=xxx \
--set nodeExporter.tolerations[0].operator=Exists \
--set nodeExporter.tolerations[0].effect=NoSchedule

- 업데이트

helm upgrade prometheus -f values.yaml stable/prometheus

- 삭제

helm uninstall prometheus

- Grafana 설치

helm install grafana stable/grafana \
--set datasources."datasources\.yaml".apiVersion=1 \
--set datasources."datasources\.yaml".datasources[0].name=Prometheus \
--set datasources."datasources\.yaml".datasources[0].type=prometheus \
--set datasources."datasources\.yaml".datasources[0].url=http://prometheus-server.default.svc.cluster.local \
--set datasources."datasources\.yaml".datasources[0].access=proxy \
--set datasources."datasources\.yaml".datasources[0].isDefault=true \

--set adminPassword='password' \

--set plugins=grafana-kubernetes-app

출처

- [Helm prometheus]

https://gruuuuu.github.io/cloud/l-helm-basic/

- [Grafana] 

https://grafana.com/grafana/dashboards/315

- [prometheus arch]

https://medium.com/finda-tech/kube-state-metrics%EC%97%90-%EB%8C%80%ED%95%B4%EC%84%9C-1303b10fb8f8

https://prometheus.io/docs/introduction/overview/

- [container restart] : https://stackoverflow.com/questions/41452930/how-can-i-alert-for-container-restarted

헬름(Helm)은 쿠버네티스의 패키지 관리자이다. 헬름은 오픈 소스 소프트웨어로 공개되어 있으며, 이미 많은 패키지(Chart)가 있다. 예를들어 레디스 클러스터나 워드프레스 환경 등의 소프트웨어를 하나의 명령어로 쿠버네티스 클러스터에 배포할 수 있다.

 

또한, 롤링 업데이트 등에도 지원하는 것들이 많아 쿠버네티스에서 최적화된 설정으로 사용할 수 있는 장점이 있다.

 

헬름은 클라이언트 측에서 처리하기 때문에 kubectl과 같은 인증 정보를 사용한다.

 

기본적으로 ~/.kube/config를 사용한다.

 

시스템이 대규모로 바뀔수록 비슷한 매니페스트를 대량으로 만들어야 하므로 재사용이나 일괄 변경 작업이 어려워진다. 그래서 필요한 것이 매니페스트 범용화라는 개념이다. 매니페스트를 범용화하고 관리하는 방법을 알아보자.

 

기본적인 헬름 설치 및 사용법을 살펴보자.

헬름 설치

$ curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
$ chmod 700 get_helm.sh
$ ./get_helm.sh

헬름 저장소 추가

# 저장소 추가
$ helm repo add stable https://charts.helm.sh/stable
"stable" has been added to your repositories

$ helm repo add bitnami https://charts.bitnami.com/bitnami
"bitnami" has been added to your repositories

# 등록된 저장소 표시
$ helm repo list
NAME   	URL                               
stable 	https://charts.helm.sh/stable     
bitnami	https://charts.bitnami.com/bitnami

# 저장소 업데이트
$ helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "stable" chart repository
...Successfully got an update from the "bitnami" chart repository
Update Complete. ⎈Happy Helming!⎈

차트 검색

- 차트 버전 : 템플릿 내용이나 초기 설정값이 변경될 때 업데이트 됨

- 앱 버전 : 실제 애플리케이션 버전

- 아티팩트 허브 : https://artifacthub.io/

# 저장소에서 차트 검색
$ helm search repo wordpress
NAME             	CHART VERSION	APP VERSION	DESCRIPTION                                       
bitnami/wordpress	12.1.24      	5.8.1      	Web publishing platform for building blogs and ...
stable/wordpress 	9.0.3        	5.3.2      	DEPRECATED Web publishing platform for building...

# 헬름 허브에서 차트 검색
$ helm search hub wordpress
URL                                               	CHART VERSION 	APP VERSION        	DESCRIPTION                                       
https://artifacthub.io/packages/helm/kube-wordp...	0.1.0         	1.1                	this is my wordpress package                      
https://artifacthub.io/packages/helm/bitnami/wo...	12.1.24       	5.8.1              	Web publishing platform for building blogs and ...
https://artifacthub.io/packages/helm/groundhog2...	0.4.2         	5.8.1-apache       	A Helm chart for Wordpress on Kubernetes          
https://artifacthub.io/packages/helm/riftbit/wo...	12.1.16       	5.8.1              	Web publishing platform for building blogs and ...
https://artifacthub.io/packages/helm/bitnami-ak...	12.1.18       	5.8.1              	Web publishing platform for building blogs and ...
https://artifacthub.io/packages/helm/mcouliba/w...	0.1.0         	1.16.0             	A Helm chart for Kubernetes                       
https://artifacthub.io/packages/helm/homeenterp...	0.1.0         	5.8.0-php8.0-apache	Blog server                                       
https://artifacthub.io/packages/helm/securecode...	3.3.0         	4.0                	Insecure & Outdated Wordpress Instance: Never e...
https://artifacthub.io/packages/helm/wordpressm...	1.0.0         	                   	This is the Helm Chart that creates the Wordpre...
https://artifacthub.io/packages/helm/bitpoke/wo...	0.11.0-rc.2   	0.11.0-rc.2        	Bitpoke WordPress Operator Helm Chart             
https://artifacthub.io/packages/helm/presslabs/...	0.11.0-alpha.3	0.11.0-alpha.3     	Presslabs WordPress Operator Helm Chart           
https://artifacthub.io/packages/helm/presslabs/...	0.11.1        	v0.11.1            	A Helm chart for deploying a WordPress site on ...
https://artifacthub.io/packages/helm/phntom/bin...	0.0.3         	0.0.3              	www.binaryvision.co.il static wordpress           
https://artifacthub.io/packages/helm/gh-shessel...	1.0.34        	5.8.0              	Web publishing platform for building blogs and ...
https://artifacthub.io/packages/helm/sonu-wordp...	1.0.0         	2                  	This is my custom chart to deploy wordpress and...
https://artifacthub.io/packages/helm/uvaise-wor...	0.2.0         	1.1.0              	Wordpress for Kubernetes                          
https://artifacthub.io/packages/helm/wordpress/...	0.2.0         	1.1.0              	Wordpress for Kubernetes                          
https://artifacthub.io/packages/helm/wordpress-...	1.0.0         	2                  	This is my custom chart to deploy wordpress and...
https://artifacthub.io/packages/helm/securecode...	3.3.0         	v3.8.19            	A Helm chart for the WordPress security scanner...
https://artifacthub.io/packages/helm/viveksahu2...	1.0.0         	2                  	This is my custom chart to deploy wordpress and...
https://artifacthub.io/packages/helm/presslabs/...	0.11.0-rc.2   	v0.11.0-rc.2       	Open-Source WordPress Infrastructure on Kubernetes
https://artifacthub.io/packages/helm/presslabs/...	0.11.1        	v0.11.1            	Open-Source WordPress Infrastructure on Kubernetes
https://artifacthub.io/packages/helm/six/wordress 	0.2.0         	1.1.0              	Wordpress for Kubernetes                          
https://artifacthub.io/packages/helm/wordpressm...	0.1.0         	1.1                	                                                  
https://artifacthub.io/packages/helm/presslabs/...	0.11.3        	0.11.3             	Presslabs WordPress Operator Helm Chart

차트 설치

- 각 차트마다 설정가능한 values 들이 있고, 이를 커스터마이징 하는 것이 아주 중요하다.

- 헬름 클라이언트는 헬름 저장소에서 다운로드한 차트와 values의 조합을 릴리스로 관리하고 쿠버네티스의 시크릿으로 데이터를 저장한다. 따라서 별도의 데이터베이스가 필요하지 않다.

# 설정 가능한 파라미터 표시
$ helm show values bitnami/wordpress

# README
$ helm show readme bitnami/wordpress

# 설치 명령어에 파라미터를 지정하여 설치
$ helm install sample-wordpress bitnami/wordpress --version 10.9.1 \
--set wordpressUsername=sample-user \
--set wordpressPassword=sample-pass \
--set wordpressBlogName="sample blog" \
--set persistence.size=5Gi

# values 파일을 생성하여 설치
$ helm install sample-wordpress bitnami/wordpress --version 10.9.1 \
--values values.yaml

# 테스트
$ helm test sample-wordpress

 

다음으로 개인적으로 아주 유용하다고 생각되는 템플릿 기능이다. 매니페스트의 특정 부분을 수정할 때 템플릿에서 해당하는 변수만을 수정하면 작업이 끝나기 때문에 sed 등을 사용한 매니페스트 수정 작업에 비해 실수를 방지하기가 더 유리하다. 즉, 자주 사용되는 템플릿을 기반으로 커스텀 차트를 생성하고, 파라미터 혹은 values 파일을 통해 유용한 매니페스트를 생성해낼 수 있다.

템플릿으로 매니페스트 생성

# 설치 명령어에 파라미터를 지정하여 매니페스트 생성
$ helm template sample-wordpress bitnami/wordpress --version 10.9.1 \
--set wordpressUsername=sample-user \
--set wordpressPassword=sample-pass \
--set wordpressBlogName="sample blog" \
--set persistence.size=5Gi

# values 파일을 생성하여 매니페스트 생성
$ helm template sample-wordpress bitnami/wordpress --version 10.9.1 \
--values values.yaml

 

차트

헬름에서는 차트라는 단위로 시스템을 패키징하고 차트 내용은 쿠버네티스 매니페스트 템플릿과 변수가 메인이다. 한번 생성한 차트는 쿠버네티스 버전에 맞추어 매니페스트 유지 보수를 별도로 해야한다.

# 커서틈 차트 양식 생성
$ helm create sample-charts
$ cd sample-charts
$ tree
├── Chart.yaml
├── charts
├── templates
│   ├── NOTES.txt
│   ├── _helpers.tpl
│   ├── deployment.yaml
│   ├── hpa.yaml
│   ├── ingress.yaml
│   ├── service.yaml
│   ├── serviceaccount.yaml
│   └── tests
│       └── test-connection.yaml
└── values.yaml

3 directories, 10 files

$ cd ..
$ helm install sample-helm sample-charts
NAME: sample-helm
LAST DEPLOYED: Tue Oct 26 23:06:13 2021
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
1. Get the application URL by running these commands:
  export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=sample-charts,app.kubernetes.io/instance=sample-helm" -o jsonpath="{.items[0].metadata.name}")
  export CONTAINER_PORT=$(kubectl get pod --namespace default $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
  echo "Visit http://127.0.0.1:8080 to use your application"
  kubectl --namespace default port-forward $POD_NAME 8080:$CONTAINER_PORT
파일명 용도
templates/*.yaml 설치하는 매니페스트 템플릿
templates/tests/*.yaml 설치한 차트가 정상적으로 동작하는지 테스트하는 매니페스트 템플릿
values.yaml 사용자가 나중에 덮어 쓸 수 있는 기본값 정의
templates/NOTES.txt helm install 시 출력되는 메시지
requirements.yaml 의존하는 차트와 해당 버전 기록
templates/_helpers.tpl 릴리스 이름으로 변수를 정의하는 등의 헬퍼 변수 정의
Chart.yaml 차트 메타데이터, 의존하는 다른 차트 명시

 

기타 명령

# 설치 후 릴리스 확인
$ helm list
NAME       	NAMESPACE	REVISION	UPDATED                             	STATUS  	CHART              	APP VERSION
sample-helm	default  	1       	2021-10-26 23:06:13.158183 +0900 KST	deployed	sample-charts-0.1.0	1.16.0    

# 릴리스 삭제
$ helm uninstall sample-wordpress

 

 


출처

- [Helm 설치] : https://helm.sh/docs/intro/install/

- [책] 쿠버네티스 완벽 가이드 마사야 아오야마 지음, 박상욱 옮김

'클라우드 컴퓨팅 > 쿠버네티스' 카테고리의 다른 글

Kubernetes TLS/PKI 살펴보기  (0) 2021.11.08
Kubernetes Monitoring with Prometheus  (0) 2021.10.27
Kubernetes 컨테이너 로그 집계  (0) 2021.10.26
Kubernetes Container Images  (0) 2021.10.24
AWS EKS 살펴보기  (0) 2021.10.23

쿠버네티스에서 기동하고 있는 컨테이너 로그를 중장기적으로 안정적으로 저장하려면 플루언트디(Fluentd)를 사용하여 클러스터 외부로 로그를 전송하는 것을 추천한다.

 

플루언트디를 쿠버네티스에 통합하여 사용할 때는 데몬셋을 사용하여 각 노드에 플루언트디 파드를 한 대씩 기동하는 방법으로 구현한다. 파드가 직접 플루언트디 파드에 로그를 전송하는 것처럼 보이지만, 실제로는 도커 컨테이너 표준 출력으로 출력된 로그가 노드의 /var/log/containers/ 아래에 저장되고, 그 로그 파일을 플루언트디 파드가 tail 플러그인을 사용하여 읽어들인다.

 

로그 저장소는 아래 그림과 같이 elasticsearch를 사용해도 되지만 그 밖에 AWS S3, GCP Cloud Logging 등을 사용해도 좋다.

출처 : https://blog.opstree.com/2019/12/17/collect-logs-with-fluentd-in-k8s-part-2/

 

쿠버네티스에서 로그를 집계할 경우에는 로그 중요도나 용량을 고려하면서 적절한 로그 전송 경로를 검토해보자. 경우에 따라서는 애그리게이션(aggregation)하는 역할을 중간에 넣어 집계 측 서버의 부하를 줄이는 것도 고려해보자.

 

RBAC

- ServiceAccount

apiVersion: v1
kind: ServiceAccount
metadata:
  name: fluentd
  namespace: kube-system

- ClusterRole

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: fluentd
rules:
- apiGroups:
  - ""
  resources:
  - pods
  - namespaces
  verbs:
  - get
  - list
  - watch

- ClusterRoleBinding

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: fluentd
roleRef:
  kind: ClusterRole
  name: fluentd
  apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
  name: fluentd
  namespace: kube-system

DaemonSet

- configMap을 통해 원하지 않는 로그는 필터링 할 수 있다.

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd
  namespace: kube-system
  labels:
    k8s-app: fluentd-logging
    version: v1
spec:
  selector:
    matchLabels:
      k8s-app: fluentd-logging
      version: v1
  template:
    metadata:
      labels:
        k8s-app: fluentd-logging
        version: v1
    spec:
      serviceAccount: fluentd
      serviceAccountName: fluentd
      tolerations:
      - key: node-role.kubernetes.io/master
        effect: NoSchedule
      containers:
      - name: fluentd
        image: fluent/fluentd-kubernetes-daemonset:v1-debian-elasticsearch
        env:
          - name:  FLUENT_ELASTICSEARCH_HOST
            value: "elasticsearch-logging"
          - name:  FLUENT_ELASTICSEARCH_PORT
            value: "9200"
          - name: FLUENT_ELASTICSEARCH_SCHEME
            value: "http"
          # Option to configure elasticsearch plugin with self signed certs
          # ================================================================
          - name: FLUENT_ELASTICSEARCH_SSL_VERIFY
            value: "true"
          # Option to configure elasticsearch plugin with tls
          # ================================================================
          - name: FLUENT_ELASTICSEARCH_SSL_VERSION
            value: "TLSv1_2"
          # X-Pack Authentication
          # =====================
          - name: FLUENT_ELASTICSEARCH_USER
            value: "elastic"
          - name: FLUENT_ELASTICSEARCH_PASSWORD
            value: "changeme"
        resources:
          limits:
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 200Mi
        volumeMounts:
        - name: config-volume
          mountPath: /fluentd/etc/kubernetes.conf
          subPath: kubernetes.conf
        - name: varlog
          mountPath: /var/log
        # When actual pod logs in /var/lib/docker/containers, the following lines should be used.
        # - name: dockercontainerlogdirectory
        #   mountPath: /var/lib/docker/containers
        #   readOnly: true
        # When actual pod logs in /var/log/pods, the following lines should be used.
        - name: dockercontainerlogdirectory
          mountPath: /var/log/pods
          readOnly: true
      terminationGracePeriodSeconds: 30
      volumes:
      - name: config-volume
        configMap:
          name: fluentd-conf
      - name: varlog
        hostPath:
          path: /var/log
      # When actual pod logs in /var/lib/docker/containers, the following lines should be used.
      # - name: dockercontainerlogdirectory
      #   hostPath:
      #     path: /var/lib/docker/containers
      # When actual pod logs in /var/log/pods, the following lines should be used.
      - name: dockercontainerlogdirectory
        hostPath:
          path: /var/log/pods

 

참고

로그 저장소의 부하가 많아지면 정상상태로 복구하는 것이 어려워질 수 있다. 이런 상황을 사전에 방지하기 위해서는 아래와 같이 fluentd filter를 추가하여 필요한 로그만 로그 저장소에 추가해야한다.

<filter kubernetes.**>
    @type grep
    <exclude>
        key $.kubernetes.labels.app
        pattern kibana|fluentd|elasticsearch
    </exclude>
</filter>
    
# this tells fluentd to not output its log on stdout  
<match fluent.**>
    @type null
</match>

# disable kube system log 
<match kubernetes.var.log.containers.**kube-system**.log>
    @type null
</match>

출처

- [책] 쿠버네티스 완벽 가이드 마사야 아오야마 지음, 박상욱 옮김

- [fluentd in k8s]

https://github.com/fluent/fluentd-kubernetes-daemonset/blob/master/fluentd-daemonset-elasticsearch-rbac.yaml

https://blog.opstree.com/2019/12/17/collect-logs-with-fluentd-in-k8s-part-2/

 

'클라우드 컴퓨팅 > 쿠버네티스' 카테고리의 다른 글

Kubernetes Monitoring with Prometheus  (0) 2021.10.27
Helm으로 매니페스트 범용화하기  (0) 2021.10.26
Kubernetes Container Images  (0) 2021.10.24
AWS EKS 살펴보기  (0) 2021.10.23
Kubernetes Cluster Maintenance  (0) 2021.10.16

+ Recent posts