Tagged: 아파치

Apache Proxy Load Balancer 구성

Apache 웹 서버는 세계적으로 많이 사용되는 웹 서버이다. 많은 기능을 내장하고 있는데, 그 중에서 Proxy Load Balancer 구성에 대해서 설치부터 설정까지 기술 한다.

기술 환경은 다음과 같다.

  • 배포판: Ubuntu14.04 64bit
  • Apache: 2.4.25
  • 컴파일 설치.

운영환경도 아주 중요하다. 이 문서에서 기술한 운영 환경은 AWS 환경이며 External ELB 바로 뒤에 Apache 웹 서버가 있다. 이 Apache 웹 서버는 뒤에 WAS 서버가 존재하는 환경이다.

Apache Proxy Load Balancer 운영 환경

의존성 패키지 설치

컴파일 설치를 하기전에 의존성 패키지를 다음과 같이 설치해 줍니다.

 

설치

설치는 소스를 받아 직접 컴파일을 했다. 소스는 현재 최신버전인 2.4.25 버전으로 다운받아 압축 해제한다.

Apache 웹 서버의 확장 모듈을 설치하거나 별도의 유틸리티를 사용하기 위해서 apr, apr-utils 도 함께 설치해주어야 한다. 이 기능을 사용하기 위해서는 컴파일 시에 ‘–with-included-apr’ 옵션을 주어야 한다.

이제 다음과 같이 Configure 해줍니다.

아무런 오류 없이 끝나면 다음과 같이 컴파일, 설치 해줍니다.

설치 디렉토리로 이동해서 다음과 같이 심볼릭 링크를 생성해 줍니다.

 

httpd.conf 설정

Apache 웹 서버의 주요 설정은 httpd.conf 파일에서 이루어 집니다. 웹 서버이름, 실행할 데몬 소유자, 로깅, 사용할 모듈, 사용할 기능파일등에 대해서 설정할 수 있습니다.

사용할 모듈 설정

컴파일 설치를 했어도 사용할 모듈들을 최소화할 수 있습니다. 다음과 같이 해줍니다.

어떤 기능을 사용할 것인지에 따라서 위 설정은 달라지지만, 적어도 Proxy Load Balancer 를 운영하기 위해 필요한 것과 불필요한 것만 위에서 기술 했다.

현재 활성화된 모듈이 무엇인지는 다음의 명령어로 확인 가능하다.

 

데몬 사용자/그룹 지정

Apache 웹 서버는 실행 프로세스와 HTTP 를 처리하는 데몬의 사용자/그룹를 다르게 지정할 수 있다. mod_unixd 에서 제공하는 것으로 다음과 같이 지정할 수 있다.

RemoteIp 사용 설정

Apache 웹 서버 앞에 AWS ELB 가 있다. AWS 의 ELB 는 Client IP 를 ‘X-Forwarded-IP’ 헤더에 담아 뒤로 넘겨준다. 하지만 Apache 웹 서버는 이것이 Client IP 인지를 인식하지 못하는데, ‘X-Forwarded-IP’ 헤더 필드 값이 실제 IP 로 사용하도록 지정할 수 있는데 mod_remoteip 가 이를 담당 한다. 다음과 같이 설정해 준다.

이렇게 설정을 해주면 이제부터 Apache 내부에서 사용하던 Client IP 관련 환경변수들이 ‘X-Forwarded-For’ 값으로 대체(override)된다. 바꿔말해서 Client IP 관련 환경 변수들을 하나하나 찾아서 ‘X-Forwarded-For’ 값으로 대체하지 않아도 된다.

log 설정

mod_remoteip 를 사용할 경우에 Apache 웹 서버의 로그에 Client IP 가 기록되도록 다음과 같이 추가해 준다.

기준의 combined 로그 포맷을 이용해 ‘%h’ -> ‘%a’, ‘%b’->’%O’ 로 교체해주고 ‘proxy_combined’ 이름의 로그 포맷을 정의했다.

추가 설정

Apache 웹 서버는 기능별로 설정들을 따로 모아서 conf/extra 디렉토리에 모아 뒀다. 필요한 기능과 설정을 하고 싶다면 이 파일들을 수정하고 httpd.conf 파일에서 Include 명령어로 포함시켜주면 동작한다.

주요하게 포함되어지는 파일들은 다음과 같다.

 

httpd-mpm.conf

Apache 웹 서버의 프로세스 모델을 설정하는 파일이다. Apache 2.4 에서는 주요하게 세가지를 제공 한다.

  • event (2.4 기본)
  • profork
  • worker

event 프로세스 모델은 ‘mpm_event_module’ 을 이용해서 설정 가능하며 httpd-mpm.conf 파일 중간쯤에 있다.

모델별로 동작 방법은 다르지만 설정하는 내용은 비슷하다. 대부분이 초기 프로세스 개수, 최소, 최대 쓰레드(Thread) 개수, 한 쓰레드당 최대 worker 등을 지정하는 식이다.

이 값은 얼마만큼 Apache 웹 서버가 일하는지에 따라서 달리 설정되어 진다. 이 값은 서비스 오픈전 부하 테스트를 거쳐서 확정된다.

httpd-default.conf

이 설정은 매우 중요하다. 특히나 AWS ELB 뒤에 Apache 웹 서버를 운영중이라면 아주 중요하다.

여기에서 reqtimeout_module 부분을 수정하지 않으면 아마도 로그에  ‘ELB-HealthChecker/1.0’ 요청에 대해서 408 을 리턴하는 것을 볼 수 있다.

이는 httpd-default.conf 파일에서 다음을 수정해줘야 한다.

이렇게 해야 하는 이유는 AWS ELB 의 Health Checker 가 Apache 웹 서버의 Alive 를 알아내기 위해서 패킷을 보내는데, AWS ELB 의 기본 Idle 값(60)보다 크게 잡아야 하기 때문이다.

위와같이 설정하면 408 오류는 보이지 않게 된다.

httpd-vhosts.conf 

Proxy Load Balancer 설정

Proxy Load Balancer 설정을 위해서는 Proxy 설정을 먼저 알아야 한다. Apache 웹 서버의 Proxy 설정은 다음과 같다.

Proxy 는 ReverseProxy 로 동작하게 하면서 Load Balancer 를 지정하고 있다. URL 이 /adm 으로 들어올 경우에 위 설정을 따르게 되고 Load Balancer 로 연결이 된다.

Load Balancer 설정에서는 Balancer 를 위한 서버의 Member 를 등록한다. route 는 Sticky Session 부분과 관련이 있으며 Tomcat의 jvmRoute 파라메터에서 사용되어지기도 해서 WAS 서버 설정과 관련이 있다.

그러나 WAS 서버에서 Session Cluster 설정을 했다면 route 는 그냥 WAS 서버의 호출 주소를 적어줘도 된다.

CustomLog 설정

CustomLog 설정에서 rotatelogs 시에 파일명을 날짜별로 되도록 다음과 같이 수정한다.

 

지금까지 Apache 2.4 에서 기초적인 Reverse Proxy 설정을 기술했다. 기본적인 설정일뿐이며 이를 기반으로 다양한 기능들을 추가하면 된다. 추가적인 기능으로는 CustomLog 에서 파일형태(그림파일), URI 별로 쪼개서 로깅하기 혹은 IP 를 기반으로 차단하기, 이미지 파일 캐싱하기 등등이 있다.

Apache 2.4 환경변수를 이용한 로그 남기기 – mod_setenvif

Apache 2.4 에서 로그를 남기는 다양한 방법이 있는데, mod_setenvif 모듈을 이용하면 다양한 조건에 부합한 것만 로그를 남길 수 있다.

위 예제는 access.2017-04-13.log 파일에 로깅을 하는데 combinedio 로 정의된 로그 포맷대로 기록하며 86400(1day) 하루에 한번 로그 로테이션을 하도록 설정한 것이다.

그런데, 만일 기록되어지는 로그중에 특정 형식의 URI 로 시작하는 경우에 별도의 로그 파일에 기록하고 싶다면 어떻게 해야할까?

위 처럼 /wp-admin 으로 시작하는 URI 를 별도 파일로 기록하고 싶다면 다음과 같이 하면 된다.

위와같이 mod_setenvif 모듈이 제공하는 SetEnvIfNoCase 문을 이용해 URI 에 형태를 정규표현식을 이용해 매칭시키고 이것을 변수로 등록한다. 그리고 CustomLog 를 하나 더 추가해 ‘combinedio env=object_is_admin’ 처럼 환경변수를 인식 시켜준다.

위와같이 하면 access_wp_admin.%Y-%m-%d.log 파일에는 /wp-admin 으로 시작하는 URI 에 대해서만 기록하게 된다.

한가지 주의할 것은 기존의 access.%Y-%m-%d.log 파일에도 여전히 /wp-admin 으로 시작하는 URI 도 함께 기록된다는 것이다. 이를 피하기 위해서 다음과 같이 지정해줄 수 있다.

access.%Y-%m-%d.log 에는 ‘combinedio env=!object_is_admin’ 을 적용함으로써 /wp-admin 으로 시작하는 URI 는 기록하지 못하도록 했다.

그런데, 만일 두가지 환경변수를 함꺼번에 적용하고 싶다면 어떻게 해야 할까?

두가지의 환경 변수를 정의했을 경우에 이 두가지를 한꺼번에 정의하기 위해서는 env 를 쓸수가 없다. env 는 OR 연산자를 제공하지 않았다. 다음의 경우

위와 같이 할 경우에 configtest 는 통과하고 재시작도 아주 잘되지만 적용되지 않는다.

이럴때는 변수 선언을 key=value 형식으로 바꾸고 CustomLog 에는 expr 를 사용해야 한다.

위와같이 expr 를 사용해 AND, OR 연산을 이용할 수 있다.

참고: How to impose two conditions at once for Apache CustomLog?

Apache Tomcat 연동하기 – mod_jk

Tomcat 을 단독으로 운영하지는 않는다. 여러 서버에서 설치한 후에 이것을 부하분산하는 방법으로 운영하는데, 자주 쓰이는 방법이 Tomcat 앞단에 Apache 웹 서버를 두고 이 둘을 연결해주는 방법으로 사용을 한다.

이때 연결방법이 여러가지가 있는데, Tomcat 과 Apache 를 위한 전용의 모듈이 있는데 그것이 바로 mod_jk 이다. mod_jk 는 AJP 프로토콜을 사용해서 이 둘을 연결해주는데, 다른 연결들보다 성능이 우수하다.

환경

이번 테스트한 환경은 다음과 같다.

  • OS: CentOS7 x86_64
  • Java Version: jdk-1.8.0_u65
  • WAS: Tomcat 8.0.30

그리고 서버는 한대이고 Tomcat 을 여러개 설치했다. 이때에 하나의 Tomcat 을가지고 멀티인스턴스 생성방법을 사용했다. 각각의 WAS 서버의 정보는 다음과 같다.

  • instance1, 8109 AJP Port
  • instance2, 8209 AJP Port
  • instance3, 8309 AJP Port

Apache 웹 서버는 CentOS 7 에 Yum 을 이용해서 설치했다. 이때 설치할때에 “httpd-devel.x86_64” 도 함께 설치해줘야 한다.

mod_jk 설치

mod_jk 는 Apache 홈페이지에서 다운로드 가능하다.

설치는 apxs 를 이용해서 Apache 모듈로 설치를 해주면 끝나게 된다.

위와같이 오류없이 libtool 로 설치가 완료되면 정상이다.

mod_jk 설정

mod_jk 에 대한 설정은 기본적으로 두가지 측면에서 이루어진다. 첫째는 Apache 웹서버에서 mod_jk 를 핸들링을 어떻게 할건지에 대한 설정이고 두번째는 mod_jk 가 Apache로부터 받은 요청을 어떻게 Tomcat 에 전달할 것인지에 대한 것이다.

Apache 웹서버에서 mod_jk 설정

mod_jk 를 정상적으로 컴파일 설치했다면 Apache 웹서버에서 이를 인식시켜주고 설정을 해줘야 한다.

여기서 한가지 주의해야할 것이 있는데, CentOS7 에서 Yum 으로 설치한 Apache 의 경우에는 설정하는데 카테고리별로 디렉토리를 분리를 해놨다.

  • 모듈 로딩 설정 디렉토리: /etc/httpd/conf.modules.d
  • 모듈별 설정 디렉토리:  /etc/httpd/conf.d

모듈을 로딩하기 위해서 다음과 같이 conf.modules.d 디렉토리에서 파일을 작성한다.

이렇게 하고나서 다음과 같이 문법 테스트를 해준다. 이 문법 테스트는 설정을 변경할때마다 해주는 것이 좋다.

 

이제 Apache 에서 mod_jk 에 대한 설정을 다음과 같이 해준다.

기본적인 설정은 위와 같다. 저장한 다음에 “workers.properties”, “uriworkermap.properties” 빈 파일을 만들어 줍니다.  Apache 문법 테스트를 해보고 오류가 없다면 정상이다.

mod_jk worker 설정

이 설정은 Apache 와 Tomcat 간에 어떻게 연결을 해야하는지에 대해 정의한다. 이 파일은 위에 “httpd-jk.conf” 파일에서 “conf.d/workers.properties” 로 정의되어 있다.

여기서 고려해야할 사항은 다음과 같다.

  • worker 이름: worker 이름은 정하기 나름이지만 각각 뒷단의 Tomcat 서버를 구분할 수 있는 이름이여야 한다. 이 worker 이름은 나중에 로드밸런싱을 할때에 Tomcat 에도 적용되어지는 이름이기에 잘 설정해야 한다.
  • worker port: 여기서 말하는 port 는 뒷단 Tomcat 서버의 AJP 포트를 말한다.
  • worker type: 이건 ajp13  으로 설정하면 된다.
  • worker lbfactor: 부하분산을 위한 설정으로 뒷단 Tomcat  서버들에 연결 무게를 설정해준다.

 

mod_jk uriworkermap 설정

이 설정은 특정 URI 에 대해서 mod_jk 의 woker 가 동작하도록 해서 요청을 Tomcat 에 넘길 수 있도록 해준다. Apache – Tomcat 구조에서 최초의 요청은 Apache 가 받아 URI 를 해석하는데, 이 설정을 해주면 특정 URI 에 대해서 Apache 가 Tomcat 에게 넘기게 된다.

여기서 간단한 시나리오를 생각해보자. 현재까지 설정은 부하분산(Loadbalance) 가 없는 것이다. 각 3대의 Tomcat 인스턴스에 대해서 동일한 무게를 주었을 뿐이다. 이렇게되면 특정 URI 요청이 있을때에 어느 Tomcat 인스턴스로 보낼것인지도 문제가 된다.

테스트를 위해서 Tomcat 설치시 나오는 메인페이지를 기준으로 하기로 했다. 이 페이지를 들여다보면 jsp, png, css 파일들로 이루어져 있다. 그러면 jsp 는 instance1 서버가 서빙을 하게하고 png 는 instance2 이 css 는 instance3 이 하게 하면 어떨까하는 시나리오를 만들고 이를 설정에 적용해 보자.

 

테스트

테스트는 간단하다. 브라우저를 실행시키고 http://apache-server-ip/index.jsp 주소로 이동해보는 것이다. 이때 Tomcat 초기 메인화면이 나온다면 정상이다.

그런데, 설정에서 jsp 는 instance1이 png 파일은 instance2 이 css 파일은 instance3 이 처리하도록 설정했었다. 그렇다면 실제로 그렇게 되고 있는지 확인을 해야하는데 확인방법은 각각 Tomcat 인스턴스에 접속 로그를 확인하면 된다.

내가 확인해본 바로는 원하는대로 로그가 찍혔다.

로드밸런스 설정

앞에 예제들은 로드밸런스 설정과는 관계가 없다. 로드밸런스라고 하면 instance1 인스턴스가 응답하지 않을 경우에 다른 서버들이 그 역활을 대신하는 것을 말한다. 이를 위해서는 woker 설정과 urlworkermap 설정을 변경해주어야 한다.

일단, 테스트를 위한 시나리오는 앞에서 서빙했던 jsp, png, css 파일들은 각각의 인스턴스들이 모두 제공하는 것으로 한다. 이렇게되면 urlworkermap 설정은 다음과 같이 바꿔주면 된다.

worker 이름을 balancer 라고 했는데, 이는 worker 설정파일에서 사용할 것이다.

로드밸런스는 특정 인스턴스가 죽었을 경우에 다른 서버가 그 역활을 대신하는 것이다. 이를 위해서 로드밸런스 역활을 위한 worker 이름을 정의하고 그 worker 에 로드밸런스를 위한 worker 이름을 정의해주면 된다. 기존의 worker 파일에 다음과 같이 로드밸런스 내용을 추가하면 된다.

강조한 라인을 주의깊게 보기 바란다.

한가지 더, Tomcat 인스턴스들에게 설정을 해줘야 한다. JvmRoute 설정이라고 하는데, 이 설정을 위한 방법은 두가지가 있다. 첫째는 System.property 를 이용한 방법이고 두번째는 server.xml 을 편집하는 방법이다.

첫번째 방법은 Tomcat 인스턴스 구동시에 커맨드라인으로 값을 넣어주는 것으로 다음과 같이 해주면 된다.

보통 Tomcat 의 시작 스크립트는 JVM_OPTS 옵션을 인식한다. 위와같이 Tomcat 인스턴스의 시작 스크립트에 커맨드 라인 옵션으로 jvmRoute 이름을 주면 인식하게 된다.

두번째는 server.xml 파일을 다음과 같이 편집하는 것이다.

위와같이 설정해주면 된다.

만일 두가지 설정을 모두 했을 경우에는 server.xml 파일 설정이 우선되어 적용된다.

테스트

편한 방법으로 설정하고 Apache와 Tomcat 인스턴스를 재시작해주고 index.jsp 를 호출해보면 된다.

HTTP 접속 포트 끄기

이렇게 Apache – Tomcat 연동을 하고나면 반드시 Tomcat 인스턴스의 HTTP 접속 포트를 Disable 해주는걸 잊지 말아야 한다.

 

 

아파치 로그 분석하기

Apache Logo

아파치 웹 서버에는 접속에 대한 로그를 남길 수 있습니다.

로그의 형식은 다양하지만 대략적으로 어느 컴퓨터(IP 주소)에서 어떤 기기, 어떤 프로그램을 이용해서 어떤 웹 페이지를 접속했는지, 각 컨텐츠의 전송량등의 정보가 담깁니다.

이 문서는 아파치 로그 분석하기 에 대한 것입니다.

전송량 통계

로그 파일에 컨텐츠의 전송량이 담기기 때문에 이것들을 전부 더하면 아파치 웹 서버가 내보낸 전송량을 알 수 있겠지요? awk 쉘 스크립트로 간단하게 할 수 있습니다.

여기서 중요한 것이 access_log 파일에 전송량을 표시하는 위치 입니다. 위 명령어 앞줄에 ‘s += $10’ 이 있는데, 공백을 기준으로 10번째 칸이 전송량을 표시한다는 거기 때문에 전송량 표시되는 부분이 12번째 칸이라면 이것을 ‘s += $12’ 로 고쳐줍니다.

좀 더 나가서 특정 아이피에 대한 것만 계산하고 싶다면 다음과 같이 해줍니다.

grep 을 이용해서 필요로하는 컨테츠만을 뽑아서 총 전송량을 계산할 수 있습니다.

로봇에 의한 전송량도 계산할 수 있습니다. 구글 봇이 페이지를 긁어가는데 들어간 전송량은 다음과 같이 계산할 수 있습니다.

HTTP 응답코드별 트래픽 계산은 다음과 같이 할 수 있습니다.

응답코드만을 다르게하면 응답코드별로 트래픽 양을 알수 있습니다.

HTTP 응답코드 세기

HTTP 응답코드는 중요 합니다. 이를 잘 파악하면 웹 사이트에 대한 상태를 알 수도 있습니다.

외부에서 이미지 링크 파악

종종 외부 사이트에서 내 사이트에서 이미지를 링크걸어놓은 것을 볼 수 있습니다. 트래픽을 절약하기 위해서 종종 사용하기도 하는데, 이러한 것을 다음과 같이 파악할 수 있습니다.

http://linux.systemv.pe.kr 부분을 자신의 웹사이트 주소를 입력해 주시면 됩니다.