Nginx 로그를 위한 Logstash Pipeline 설정하기

Logstash 를 이용해 로그를 프로세싱 해보자. Logstash 에 대한 기초적인 설정은 다음글에서 확인 가능하다.

또, 이 글은 Elastic 홈페이지에 내용을 기반으로 한다.

filebeat 설정 및 기동

먼저 파일 filebeat 설정을 다음과 한다.

Elastic 홈페이지에는 간단하게 설정하도록 나오지만 여기서는 몇가지 설정을 추가 하였다. tags 를 설정하였고 fields 도 추가 하였다. 다음과 같이 시작 한다.

logstash Nginx pipeline 설정

먼저 filebeat 으로부터 메시지가 잘 들어오는지 디버깅을 먼저 해보자. 다음과 같이 간단하게 설정을 해본다.

INPUT 에는 filebeat 으로부터 전송을 받기 위한 port 를 지정해준다. OUTPUT 에는 디버깅을 위한 화면출력을 설정해 준다.

테스트

filebeat 의 로그 파일에 한 줄 넣어준다.

이렇게 하고 난 후에 logstash 의 출력 로그를 보면 다음과 같이 나온다.

여기서 보아야 할 것은 filebeat 에서 설정한 tags 와 field 다. 이것이 logstash 로 전송될때에 그대로 전송이 된다. message 에는 log 파일에 내용을 담고 있는데 이것을, 이제 필드별로 구별을 해야 한다. 이를 위해서는 로그의 형식을 알아야 한다.

Nginx 로그 형식

Nginx 의 로그 형식은 nginx 설정 파일에 log_format 에 기록되어 있다.

이 형식은 필요에 따라서 변경 될 수 있다. 이 형식을 알아야 한다.

Logstash FILTER pipeline 설정

이제 Nginx Pipeline 에 FILTER 를 설정해야 한다. 일 FILTER 는 들어오는 메시지를 가공처리해주는데, grok 을 이용한다. 메시지를 가공처리하는데 미리 정의된 형식도 지원한다. 다음과 같이 해보자.

filebeat 는 한번 읽은 로그는 다시 읽지 않는다. filebeat 는 중지 시키고, 데이터 디렉토리에 registry 디렉토리를 삭제 한다.

이렇게 하면 파일을 다시 읽는다. 하지만 결과는 필드로 구분되지 않았다. 이것은 미리 정의된 FILTER 가 적용되지 않았음을 의미 한다.

FILTER 의 적용은 grok 을 사용하는데, 이것을 매번 해보는건 힘들다. 그래서 온라인으로 테스트를 할 수 있도록 도와주는 사이트가 있다.

여기에서 샘플데이터를 넣은 후에 패턴을 grok 패턴으로 적용하면 결과를 보여준다. 이 패턴을 이용하면 된다.

grok 의 사용법은 %{SYNTAX:SEMANTIC} 형식인데, SYNTAX 는 패턴이다. SEMANTIC 는 그 패턴을 담는 변수라고 보면 된다. 그런데, 이 패턴은 미리 정의되어 있는데, 다음에서 확인 가능하다.

Nginx 형식에 맞는 grok 패턴을 다음과 같이 입력 해줬다.

이렇게 한 후에 로그를 전송하면 다음과 같이 잘 파싱된다.

Elasticsearch 보안

Elasticsearch 가 버전이 높아지면서 보안이 강화 됐다. 더군다나 Security 플러그인을 활성화할 경우에 각종 Rules와 Roles 들이 생성된다. 뭔가를 하기 위해서는 인증을 거쳐야 한다는 뜻이다.

Logstash 는 최종적으로 Elasticsearch 로 데이터를 보내야 한다. 이에 대한 보안 설정이 필요한데, 이에 대한 자세한 설명은 다음에 잘 나와 있다.

CA 인증서 설정

Elasticsearch 8.1 을 설치할때에 CA 인증서가 config/certs 디렉토리에 생성 되었다. RPM 으로 설치하였을 경우에 /etc/elasticsearch/certs 디렉토리인데, 여기에 http_ca.crt 파일로 존재 한다. 이것을 Logstash 에 OUTPUT 필터에서 사용해야 한다.

Logstash 를 위한 자격증명 만들기

자격증명을 만들기 위해서는 권한을 부여한 역할(Role) 를 만들어야 한다. Kibana 를 설치했다면 Management > Roles 에서 생성할 수 있다. 다음과 같이 만든다.

  • Role 이름: logstash_writer
  • Cluster Privileges: manage_index_templates, monitor, manage_ilm
  • Indices Name: nginx-access-*
  • Indices Privileges: write, create, create_index, manage, manage_ilm
Logstash 를 위한 Role 생성

이것은 다음과 같이 curl 을 이용할 수도 있다. 먼저 Role 을 위한 JSON 파일을 작성한다.

그리고 이제 다음과 같이 curl 명령어를 작성해 실행하면 된다.

이제 사용자를 만들어야 한다. 사용자를 만들때에는 패스워드도 함께 생성하고 앞에서 만든 logstash_writer 롤을 할당해 준다.

Logstash 를 위한 계정생성

역시 이것도 다음과 같이 JSON 형식으로 생성이 가능하다.

logstash OUTPUT 파이프라인 설정

이제 Logstash 의 OUTPUT 파이프라인을 설정해야 한다. 다음과 같다.

결론

logstash OUTPUT 파이프라인 설정이 되면 logstash 와 filebeat 을 재시작 하고 nginx 로그를 넣게 되면 이제 Elasticsearch 에 nginx-access-날짜 로 인덱스가 생성되면서 데이터가 적재된다.

Logstash 살펴보기

ELK 스택에서 로그를 프로세싱하고 저장소에 실시간으로 적재해주는 프로그램인 Logstash 에 대해서 살펴본다.

자바 프로그램

Logstash 는 자바 프로그램이다. 그래서 Java Runtime 이 필요하다. 그런데, Logstash 에는 Java Runtime 이 내장되어 있어서 별도로 설치하지 않아도 된다.

하지만 이 자바 때문에 프로그램이 무겁다.

Logstash 정의

다음과 같이 정의가 머리속에 담아 두기 좋다.

실시간 파이프라인(Pipeline) 기능을 가진 데이터 수집 엔진을 가진 오픈 소스 소프트웨어다.

파이프라인(Pipeline)

Logstash 는 파이프라인(Pipeline) 형식으로 데이터를 처리 한다.

INPUTS 은 데이터를 입력받는 부분에 대한 설정이다. OUTPUTS 은 어디로 데이터를 보낼 것인지 하는 부분인데, 대부분 데이터 저장소를 지정한다. FILTERS 부분은 입력받은 데이터를 가공처리하는 부분을 말하는데, Logstash 의 핵심부분이라고 할 수 있다.

logstash 플러그인

logstash 는 자체 플러그인을 가지고 있다. 이 플러그인을 활용하면 미리 설정된 FILTERS 에 맞게 로그를 처리하고 OUTPUT 을 해준다.

logstash 를 설치했다면 다음과 같이 지원되는 리스트를 확인해 볼 수 있다.

OUTPUT 플러그인 중에 Elasticsearch 를 설치해 보자.

logstash.yml

이 파일은 Logstash 실행을 제어하기 위한 것이다. 파이프라인 세팅, 설정 파일 위치 지정, 로깅 옵션등을 지정할 수 있다. 이 파일에 적은 옵션은 커맨드 라인으로 지정해도 된다.

주요한 설정은 다음과 같다.

logstash.yml 파일에 pipeline 관련 설정도 있다. 이것 때문에 헷깔리는 사람들이 많은데, 여기서 pipeline 설정을 하지 않아도 된다. 각각의 pipeline 설정은 pipeline.yml 에서 설정하는데, 여기서 설정하지 않은 값은 logstash.yml 파일에서 읽어 들인다. 쉽게 말해서 Default 값을 지정하는 것이라고 보면 된다.

pipeline.yml

pipeline 에 대한 설정을 하는 것이다. 대략 다음과 같다.

path.config 에서 디렉토리에 .conf 확장자 파일을 모두 읽어 들이도록 한다.

-f 옵션 없이 실행

보통 -f 옵션을 주고 실행하는 이유는 pipeline 설정파일을 지정하기 위해서다. 하지만 logstash.yml 과 pipeline.yml 파일을 작성했다면 -f 옵션 없이 실행할 수 있다.

위에 두가지 설정을 한 이유다.

로그 저장과 트래킹

로그(log) 는 각종 시스템과 소프트웨어 프로그램의 정보를 담고 있다. 한 사람이 하나의 시스템, 하나의 소프트웨어 프로그램을 다루거나 관리를 한다면 별 문제가 없겠지만 요즘 처럼 분산형 시스템과 소프트웨어를 사용하는 시대에 로그를 하나씩 다 들여다 본다는 건 불가능이다.

거기다 로그를 본다는 것도 여간 쉬운일이 아니다. 매우 지루하고 많은 시간을 허비해야 하는데, 수 많은 로그속에서 내가 필요로하는 정보를 찾기란 매우 어렵다.

그래서 이것을 손쉽게 처리할 수 있도록 도와주는 프로그램 그룹이 만들어졌는데, 다음과 같은 것이다.

Splunk

스플렁크(Splunk) 는 사용 소프트웨어다. 대량으로 로그를 저장하고 분석하도록 해주는 소프트웨어를 판매하는 회사다. 상용제품이다 보니까 이 제품을 익히는게 중요하다. Splunk Search Processing Language, 줄여서 SPL 을 이용해서 로그에서 필요한 정보를 뽑아 낼 수 있다.

ELK(Elasticsearch, Logstash, Kibana)

Elastic 제품군이다. 엘라스틱서치(Elasticsearch) 검색 소프트웨어로 유명한 Elastic 에서 만드는 것인데, 로그스태쉬(Logstash) 는 실시간으로 로그를 전달 받아서 처리하고 이것을 엘라스틱서치에 저장한다. 키바나(Kibana) 는 엘라스틱서치에 저장한 로그들을 특저한 쿼리를 이용해 시각화 해준다.

로그스태쉬(Logstasch) 대신 플로언트디(FluentD) 를 사용하기도 한다. 로그스태쉬로그스태쉬(Logstasch)보다 메모리를 덜 먹으면서도 가용성이 좋다.

로그 처리를 위한 ELK 를 스택(Stack) 이라고 명명하고 ELK Stack, EFK Stack 이라고 부른다.

ELK stack components

TICK(Telegraf, InfluxDB, Chronograf, Kapacitor)

InfluxDB 와 Telegraf 로 유명한 InfluxData 에서 만든 것이다. Kapacitor 는 ELK 에서 로그스태쉬에 해당한다. Chronograf 는 ELK 의 키바나에 해당된다.

개인적으로 Telegraf, InfluxDB, Grafana 를 이용한 시스템 모니터링은 여러번 사용해본 경험이 있다. InfluxDB 는 마치 RDBMS 처럼 SQL 문을 이용해서 데이터를 조회할 수 있다.

ElasticSearch RPM 패키지 설치 Security

ElasticSearch 를 RPM 패키지로 설치할 경우에 Security 설정을 어떻게 해야하는지에 대해서 다룬다. Security 설정은 X-Pack 을 활성화 하기 위함이며 이를 위해서는 인증서 관련 문제를 해결해야 한다.

사례

일단, 엘라스틱 서치는 대부분 3대로 구성한다. 대부분 호스트를 다음과 같이 정할 것이다.

  • es-01
  • es-02
  • es-03

이때, es-01 서버에서 다음과 같은 작업을 해야 한다.

es-01 서버에서 인증서 작업

X-Pack 을 활성화하기 위해서는 보안을 활성화해야 하는데, 보안을 활성화할 경우에 각 노드별로 SSL 통신을 하게된다. 이때 인증서가 필요한데, 인증서 작업을 해야 한다.

중요한 것은 인증서를 한 곳에서 해야하고 모두 서버에 배포를 해야 한다. 여기서는 es-01 서버에서 하는 것으로 가정한다.

뭐라 뭐라 나오지만 중요한건 위 두줄인데, 그냥 Enter 만 두번 쳐주면 된다. 이렇게 하면 /usr/share/elasticsearch 디렉토리에 ‘elastic-stack-ca.p12’ 파일이 생성된다.

그리고 이제 루트 인증서를 가지고 인증서를 다음과 같이 만든다.

역시 뭐라뭐라 나오는데, Enter 만 세번 쳐준다. 이렇게하면 /usr/share/elasticsearch 디렉토리에 ‘elastic-certificates.p12’ 파일이 생성된다.

위 과정으로 인해서 2개의 파일 ‘elastic-stack-ca.p12’, ‘elastic-certificates.p12’ 파일이 생성된다.

이 두개의 파일을 이제 3개의 엘라스틱서버 모두에 /etc/elasticsearch 디렉토리로 복사해 준다. 그리고 다음과 같이 소유권과 퍼미션을 변경해 준다.

설정

이제 3대 서버 모두에 ‘elastic-stack-ca.p12’, ‘elastic-certificates.p12’ 두개 파일이 /etc/elasticsearch 디렉토리에 있을 것이다. 모두 es-01 에서 만든 같은 파일이다.

이제 각 서버의 /etc/elasticsearch/elasticsearch.yml 파일 맨 마지막에 다음과 같이 설정을 해준다.

이게 es-01 서버부터 시작을 해준다. 그러면 잘 될 것이다.

패스워드 생성

마지막으로 엘라스틱서치에 인증이 필요한 계정에 패스워드를 생성해 준다.

Kibana 에서는 username 이 kibana 계정과 위에서 생성한 패스워드를 입력해 준다.

Kubernetes API 서버 인증서에 도메인 추가하기

Kubernetes API 서버는 http 를 통해서 쿠버네티스에 대한 연산을 제공해 준다. kubectl 명령어로 실행되는 것들은 모두 API 서버를 거쳐서 이루어진다. 하지만 API 서버는 인증서를 기반으로 통신이 이루어지는데, 이 인증서에 기재된 도메인이나 IP가 아니면 통신이 이루어지지 않는다.

API 서버의 인증서는 SAN 인증서여야 한다. 도메인 리스트를 가지고 있는 SAN 인증서. 현재 API 서버의 인증서 상태는 다음과 같다.

위 apiserver.crt 파일 상태를 보면 SAN 에 이미 도메인과 IP 들이 들어가 있다. 내용을 보면 haproxy2.systemv.local 도메인, 192.168.96.7 IP 가 들어가 있는데 이 서버에서 API 서버와 통신이 가능하다.

만일 추가적으로 도메인, IP 를 추가하고 싶다면 어떻게 해야할까? 이에 대해서 알아본다.

kubeadm-config 업데이트

kubeadm-config 라고 불리는 ConfigMap 을 업데이트 해줘야 한다. 이를 위해서 먼저 기존이 설정을 뽑아내야 하는데 다음과 같이 하면 된다.

파일 내용을 보면 SAN 리스트가 없다. 도메인이나 IP 를 SAN 으로 추가하기 위해서 apiServer 아래에 certSANs 를 추가해 준다. 이미 다른 도메인이 있다면 제거하나 추가할 수도 있다.

위와같이 SAN 에 추가할 도메인, IP를 적어준다.

apiserver.crt 파일 업데이트

기존의 존재하는 apiserver.crt 파일을 백업한다.

kubeadm 을 이용해 새로운 인증서를 생성해 준다.

새로운 인증서가 생성되면서 certSANs 에 설정된 도메인, IP 주소들이 모두 인증서에 업데이트 된다. 이제 새로운 인증서를 가지고 구동되도록 api 서버를 재시작 시켜줘야 한다.

Docker 기반의 경우에는 다음과 같이 하면 된다.

  • docker ps | grep kube-apiserver 명령어로 kube-apiserver 의 컨테이너 ID 를 파악한다.
  • docker kill <containerID> 로 컨테이너를 킬(kill) 한다. 이렇게 하면 api 서버가 재시작 된다.

만약 containerd 를 이용하는 경우에는 다음과 같이 하면 된다.

  • crictl pods | grep kube-apiserver 로 kube-apiserver 의 Pod ID 를 파악한다.
  • crictl stopp <pod-id> 로 pod 를 정지
  • crictl rmp <pod-id> 로 pod 를 제거 합니다. 이렇게하면 다시 Pod 가 재시작 된다.

위와같이 Api 서버가 재시작되면서 새롭게 만들어진 API 서버 인증서를 인식하게 된다.

클러스터 설정 업데이트

마지막으로 클러스터 설정을 업데이트 해줘야 한다.

이렇게 하면 최종적으로 Api 서버에 인증서가 업데이트 된다.

Kubernetes 의 Role Based Access Control(RBAC)

쿠버네티스는 RBAC 기반으로 허가권(Permission) 을 조정하도록 설계 되었다. 그런데, 쿠버네티스는 다음과 같이 네가지의 Role 관련 리소스를 가지고 있다. 그 차이는 다음과 같다.

  1. ClusterRole – 전체 클러스터에 적용하기 위한 역할(Role) 에 할당된 허가권(Permission)
  2. ClusterRoleBinding – 특정 계정(Account) 에 ClusterRole 을 바인딩
  3. Role – 특정 네임스페이스에 적용하기 위한 역할(Role) 에 할당된 허가권(Permission)
  4. RoleBinding – 특정 계정(Account) 에 Role 을 바인딩

RBAC 을 적용하기 위해서는 계정이 필요하다. 이 계정은 쿠버네티스의 사용자를 말하는것이 아닌 쿠버네티스에서 운영되는 자원에 대한 계정을 말한다.

예를들어 ingress-nginx 라는 계정을 생성했다면 이제 이 계정에 ClusterRole 과 Role 을 Binding 을 통해서 ingress-nginx 계정과 연결하는 형식이다.

참고: Role Based Access Control (RBAC)

Istio, Pod CrashLoopBackOff 해결하기

Istio 를 설치하고 Pod 를 생성했는데, 다음과 같이 오류가 발생했다.

istio-init 컨테이너가 오류가 발생한 것을 알 수 있다. Pod 안에 컨테이너가 여러개일 경우에 컨테이너 로그를 봐야하는데 다음과 같이 Pod 에 속한 컨테이너 로그를 볼수 있다.

이 문제는 istio cni 컴포넌트를 함께 설치해주면 된다. 보통 Istio 를 설치할때에 Profile 만 지정하는데, demo 프로파일에 경우에 CNI 를 설치하지 않는다. 다음과 같이 재설치를 해준다.

이렇게 CNI 를 활성화해서 재설치를 하면 문제없이 작동 된다.

문제점

여기서 한가지 문제가 있다. CNI 는 보통 Flannel, Calico 등을 이용하는데, 이것과 별도로 Istio-cni 를 설치하게 되는 것이다. 이왕이면 기존에 있는 것을 활용하는 방안을 고려해야 한다.

Calico 의 경우에 이에 대해서 기술하고 있는 문서가 있으니 참고해서 한번 해볼만 하다.

Istio 설치

Istio 는 쿠버네티스의 Network 레벨의 Mesh 서비스다. 비교하자면 Netflix OSS 에 Ribbon 과 비슷하다고 볼 수 있다.

Istio 설치 방법

Istio 설치 방법은 다양하다. 처음에 Istio 를 시작할때에 가장 헷깔리는 것이 바로 설치 방법이다. 구글에서 검색을 하면 설치방법이 나오지만 읽어보면 제각각인 이유가 다양한 설치 방법 때문이다.

그래서인지 Istio 홈페이지에서 다양한 설치 방법을 적어놨는데 대략 3가지 방법이 많이 쓰인다.

  1. Install with Istioctl
  2. Install with Helm
  3. Install Istio Operator

여기서는 Istoctl 을 이용해 설치하는 법을 다룬다. 이 방법은 다음 문서에 잘 나와 있다.

Download Istioctl

다음과 같이 Istio 를 다운로드 한다.

istio profile

istioctl 은 말그대로 istio 관련 작업을 위한 툴이다. 설치를 할때도 이를 활용할 수 있다.

istio 설치는 미리 정의되어 있는 프로파일을 정의하면 그 프로파일에 맞는 컴포넌트들을 같이 설치해 준다. 미리정의된 프로파일은 다음과 같이 조회가 가능하다.

프로파일의 내용은 대략 다음과 같다.

  • default: 프로덕트 환경에 적합하도록 기본세팅되어 있다.
  • demo: 쇼케이스를 위해서 세팅된 값을 쓴다.
  • minimal: 오진 컨트롤 플레인만 설치된다.
  • empty: 아무것도 디폴로이 되지 않는다. 이것은 커스텀 설정을 위한 베이스 프로파일처럼 사용할 수 있다.

각 프로파일의 내용은 다음과 같이 dump 옵션을 사용해 가능하다.

위 내용을 보면, cni, egressGateway 와 istiodRemote 가 비활성화 되어 있다.

전체설정의 서브셋만 보고 싶다면 –config-path 를 사용하면 가능하다.

프로파일에 차이를 알고 싶다면 다음과 같이 확인할 수 있다.

demo profile 설치

demo 프로파일을 이용해 설치를 진행 한다. istio 문서대로 한번 해보는 것이다.

자동으로 Envoy 사이드카 프록시를 자동으로 주입시키기 위한 네임스페이스에 라벨을 추가해준다.

default 네임스페이스에 라벨링을 해줬다. default 네임스페이스에 드플로이를 해주면 Envoy 사이드카가 자동으로 주입된다.

istio 설치 확인

먼저 네임스페이스를 확인해 보자. 네임스페이스는 istio-system 이 생성된다.

그리고 이제 어떤것이 설치되었는지를 살펴보자.

CRD 도 함께 생성된다. 다음과 같이 확인 가능하다.

문제

이벤트(Events) 를 보면 다음과 같이 오류가 난것을 확인할 수 있다.

쿠버네티스 curl 사용하기

쿠버네티스에서 클러스터내에서 Pod 에 데이터가 잘 나오는지를 확인하는 방법은 CURL 일 것이다. ClusterIP 로 IP 가 할당되면 클러스터내에서 접근이 가능한데 이때에 다음과 같이 사용하면 된다.

curl 을 비롯한 ping, nslookup 도 가능하다.