Category: Linux

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?

Nginx 이용한 로드 밸런싱(Load Balancing) 구현하기

Nginx 는 전세계적으로 인기있는 웹 서버 입니다. 기존 웹 서버들과 달리 고속이며 대량의 접속을 적은 자원으로 처리해줍니다. 또, Nginx 는 Reverse Proxy 기능도 아주 훌륭하게 수행하며 이에 더해서 로드밸런싱 기능도 제공하는듯 다양한 기능을 다른 웹서버들보다 훌륭하게 수행합니다.

아키텍쳐(Architecture)

먼저 다음과 같은 아키텍쳐를 생각해 봅시다.

Nginx 로드 밸런싱 아키텍쳐

AWS 에 흔히 볼수 있는 기본적인 아키텍쳐입니다. 외부 접속은 External ELB가 담당하고 이것을 뒤에 Nginx 서버가 ELB의 접속을 받아서 Nginx 뒤에 있는 Jboss EAP 서버에 분배 접속을 하도록 하는 것입니다.

Nginx 로드 밸런싱(Load Balancing)

Nginx 는 자체적으로 로드 밸런싱 기능을 제공합니다. 이는 Nginx 의 Upstream 모듈을 통해서 제공 합니다. 기본적인 설정 방법은 다음과 같습니다.

ELB 에서 Nginx 로 80 포트(port)로 접속을하면 proxy_pass 에 정의된 upstream 인 myapp1 으로 연결을 시켜주며 myapp1 upstream 에 정의된 서버 3대 중에 하나에 연결을 시켜줍니다.

upstream 에서 다양한 옵션을 제공 합니다. 대표적인 것이 Nginx 뒤에 서버의 연결 상태를 어떻게 체크할 것인가 하는 것입니다. 예를들면,

srv1.example.com 서버는 30초 동안 최대 3번 접속이 실패하면 30초 동안 접속이 불가한 것으로 판단 합니다. 30초가 지나면 또 최대 3번의 접속 실패가 발생하고 나서야 30초동안 접속을 하지 않습니다.

지속적인 서비스를 제공해야하는 상황에서 접속이 잘되는지 안되는지 실제로 접속을 해봐야만 한다면 고객들에게 불편을 제공할 것입니다.

AWS ELB 방식

AWS ELB 방식은 위 Nginx 의 max_fails 방법과는 다릅니다. ELB 는 뒤에 연결되는 인스턴스(Instance)가 살았는지 죽었는지를 판단하는 Health Check 기능을 제공합니다. 이것은 5초에 한번 Health Check 를 하고 10번이상 성공했다면 인스턴스가 살았다라고 판단해(InService 상태) 연결을 활성화 해줍니다. 만일 5초에 한번 Health Check 를 하는데 2번 실패를 했다면 인스턴스가 죽었다고 판단해(OutOfService 상태) 더 이상 연결을 시도하지 않습니다.

즉, 일정한 기준을 만족해야만 연결을 활성화 해준다는 겁니다. Nginx 에서도 이렇게 동작하면 얼마나 좋을까?

nginx_http_upstream_check_module

nginx_http_upstream_check_module 모듈은 Nginx.org 에서 배포하지 않고 개인 개발자가 개발한 Third Party 모듈 입니다. 이 모듈은 앞에서 언급했던 ELB 의 Health Check 기능을 제공해 줍니다. 특정한 기준을 통과하면 연결을 활성화 시켜주는 것입니다.

이를 활용하기 위해서는 Nginx 설치시에 같이 컴파일 설치를 해줘야 합니다.

Nginx 설치

이번 Nginx 설치는 Upstream Health Check Module 를 함께 설치하는 과정을 포함 합니다.

설치 환경은 다음과 같습니다.

  • Ubuntu 14.04 64bit
  • 컴파일을 위해서 설치한 패키지들: build-essential, automake, unzip, patch, libpcre++-dev, zlib1g-dev, geoip-bin, libgeoip-dev

Nginx 다운로드를 해줍니다.

nginx_http_upstream_check_module 는 git를 이용해서 다운(?) 받습니다.

이제 Nginx 에 nginx_http_upstream_check_module 다음과 패치를 해줍니다.

그리고 다음과 같이 서버 Signiture 를 바꿔 줍니다.

이렇게하면 서버가 PowerServer/1.0 이라고 나와서 Nginx 를 쓴다는것을 숨길 수가 있습니다.

마지막으로 openssl 최신 소스를 다운받아 nginx 디렉토리에 놓습니다.

 

Nginx 설정하기

설치가 끝났다면 이제 설정을 해야 합니다. 설정에 앞서서 현재 Nginx 의 아키텍쳐를 상기시켜봅시다.

  • Nginx 앞에는 AWS ELB 에 있다. AWS ELB 는 실제 접속자인 Client IP 를 ‘X-Forewarded-For’ 헤더값에 저장해 넘겨준다.
  • Nginx 뒤에는 두대의 WAS 서버가 존재한다.
  • Nginx 는 뒤에 두대의 WAS 에 대해서 Health Check 하고 특정값 기준으로 Alive/Down 을 결정하도록 한다.

위 내용을 설정에 반영하면 다음과 같습니다.

먼저 7번째 줄에 Nginx 에서 실제 IP를 ‘X-Forewarded-For’ 헤더 값이라고 알려 주도록 설정한 것입니다. 8번째 줄은 AWS ELB 의 주소 범위를 말합니다. Nginx 는 AWS ELB 로부터 접속을 받기 때문에 그것을 지정해줄 필요가 있는데 그것이 바로 8줄 설정입니다. 12줄 ~ 14줄은 뒤에 WAS 서버에 넘겨줄 헤더값을 지정해주고 있습니다. WAS 서버도 실제 Client IP가 필요하기 때문에 이것을 ‘X-Forewarded-For’ 에 지정해 줍니다. 그외에 ‘X-Forewarded-Server’, ‘X-Forewarded-Host’ 도 지정해 줍니다.

18번째 줄부터는 이제 upstream 설정하는 부분인데, 24줄이 Health Checker 를 해주는 부분으로 nginx_http_upstream_check_module 기능 입니다. 3초에 한번 체크를 하는데 그 방법은 TCP를 이용하고 5번 연속으로 실패할 경우에 뒤에 서버는 다운된것으로 하고 2번 연속 성공하면 뒤에 서버가 살아있는것으로 해서 연결을 시켜줍니다. 마치 AWS ELB 처럼 동작하는 것입니다.

/status URL 을 호출하면 다음과 같이 나옵니다.

Nginx Upstream Health Status
Rise Counts, Fall counts 는 3초마다 체크해서 그 수를 센 것입니다. 현재 뒤에 WAS 서버들이 하나는 살아 있고, 하나는 죽은것으로 되어 있고 Down 된 서버는 빨강색으로 표시됩니다.

체크하난 프로토콜을 변경할 수 있는데, http 를 이용할 경우에 보내는 url 과 기대되는 리턴되는 http 의 상태값(status)를 지정해주면 됩니다.

Ubuntu 16.04 KVM 게스트에 콘솔 접속하기

KVM 가상화를 사용하고 있고 게스트로 Ubuntu16.04 를 사용하고 있다면 콘솔 접속을 위해서는 Grub2 설정을 다음과 같이 해주면 된다.

위와같이 해주고 다음과 같이 grub 을 갱신해준다.

 

[AWS] Private Subnet 으로 서비스 구성하기.

AWS 는 전 세계적으로 가장 인기있는 Cloud Platform 이다. Web Console을 이용해서 원하는 자원을 구성하고 컴퓨터, 네트워크, 저장소등을 실시간으로 생성할 수 있으며 네트워킹 구성도 실시간으로 구성이 가능하다.

그래서 많은 IT 업체들이 AWS 클라우드를 사용하고 있다. 특히나 전 세계를 대상으로 인터넷 서비스를 하려는 업체들은 AWS 를 통해서 막대한 IT 인프라 구축비용 절감하고 있다.

오늘은 AWS 클라우드를 이용해서 가장 많은 구성이며 기본적인 구성인 Web Service 를 Private Subnet 을 이용해 구성해보도록 하겠다.

이 포스트는 AWS 클라우드에 대해서 어느정도 기초지식을 갖추고 있다고 가정하고 쓰여졌다. AWS 클라우드를 사용하기 위해서는 기본적인 개념들이 존재하는데, 예를들어 VPC, ELB, Security Group, Route Table, InterGateWay 등에 대해서 모두 알고 있다라고 가정한다.

목표

내가 목표로하는 전체적인 시스템 구성은 다음과 같다.

Private Subnet 서비스 구성도

위 구성도에서 눈여겨 봐야할 포인트는 다음과 같다.

  • 외부 인터넷과 연결을 위해서 반드시 Public Subnet 이 한개는 있어야 한다.
  • 서비스를 제공할 인스턴스들은 Private Subnet 에 있어야 한다.
  • Private Subnet 에 있는 인스턴스들에서 외부와의 인터넷 통신은 Public Subnet 에 있는 NAT 서버를 통해서 한다.
  • Private Subnet 에 Web Service 인스턴스들은 ELB(Elastic Load Balancer) 를 통해서 하며 ELB는 반드시 Public Subnet 에 있어야 한다.

 

VPC 생성하기

AWS 서비스에 가입하면 각 Region 마다 기본적인 사항들이 자동으로 생성된다. 그중에 VPC도 다음과 같이 기본으로 생성이 된다. Tokyo Region은 다음과 같다.

  • VPC CIDR: 172.31.0.0/16
  • Route table: rtb-ef0bcd8a
  • Network ACL: acl-3cef2859
  • Subnet: subnet-55d41722
  • Subnet Type: Public

Default VPC 은 인터넷과 자동으로 연결된 거대한 하나의 Public Subnet 기도 하다. 하지만 나는 이 Public Subnet 을 사용하지 않고 새롭게 VPC을 생성할 것이다. VPC 의 생성에서 고려해야할 사항은 얼마만큼의 IP 대역을 사용할 것인가에 있다.

Web Service VPC 생성
Web Service VPC 생성

Subnet 생성하기

이제 서브넷을 생성해야 한다. 중요한 것은 Public Subnet 1개와 Private Subnet 1개는 반드시 있어야 한다.

여기서 중요한 것도 IP 대역이다. 한 서브넷에 얼마만큼의 IP 대역을 쓸것인가 하는 것이다. 나는 다음과 같이 할당 했다.

  • Public Subnet: 10.31.0.0/22 – 1018 개 IP 대역, AZ: ap-northeast-1b, Name: JumpSubnet(NAT)
  • Private Subnet: 10.31.4.0/22 – 1018 개 IP 대역, AZ: ap-northeast-1b, Name: WebSubnet

여기서 한가지 Public Subnet, Private Subnet 을 구분하는 설정값은 존재하지 않는다. AWS 에서 이 둘의 구분은 Internet Gateway 와 연결이 되어진 네트워크이냐 아니냐에 따라 달라진다. Internet Gateway 에 연결되었다면 Public, 그렇지 않으면 Private 이라는 개념이다. 그럼 이러한 연결 설정은 어디서 하는가?

Subnet 에 대해서 Internet Gateway 연결을 하거나 기타 네트워크 경로 설정은 Route Table 에서 하기 된다.  Route Table 에서 생설할때에 고려해야 할 사항은 다음과 같다.

  • 어느 서브넷과 연결시킬 것인가?
  • 어떤 외부세계와 연결시킬 것인가?

Route Table 이 존재하면 수정을하고 없으면 생성을 하면 된다.

Public Subnet

Public 서스넷 Route Table 서브넷 연결
Public 서스넷 Route Table 서브넷 연결
Public 서스넷 Route Table 라우팅 테이블
Public 서스넷 Route Table 라우팅 테이블

Public Subnet 을 위한 Route Table 은 위와같이 연결할 서브넷과 라우팅 테이블을 정의해주면 된다. 여기서 핵심은 라우팅 테이블에서 Internet Gateway 연결을 해줘야한다. 위 화면에서 igw-98de5cfd 가 바로 그것이다.

Internet Gateway 가 연결되어 있다면 그것이 Public Subnet 이 된다.

Private Subnet

Private 서스넷 Route Table 서브넷 연결
Private 서스넷 Route Table 서브넷 연결
Private 서스넷 Route Table 라우팅 테이블
Private 서스넷 Route Table 라우팅 테이블

Private Subnet 을 위한 서브넷 연결과 라우팅 테이블은 위와 같습니다. 라이팅 테이블을 보면 Internet Gateway 연결이 없다. 그래서 이 라우팅 테이블과 연결된 Subnet 은 Private Subnet 이 된다.

Private Subnet 은 외부 인터넷과 연결이 안되기 때문에 Private Subnet 인스턴스에 접속하고 제어하고 Private Subnet 의 인스턴스들이 인터넷연결을 위한 NAT 인스턴스가 필요하다.

Security Group 생성

Security Group 은 인터넷 방화벽이라고 생각하면 편하다. Security Group 은 인스턴스마다 할당할 수 있다. Security Group 에도 NAT를 위한 것과 NAT 에 의존해야할 인스턴스를 위한 것 두개를 만든다.

Security Group 을 생성할대는 Inbound 프로토콜, 포트 와 Outbound 프로토콜, 포트 를 생각해야 한다.

NAT Security Group

Outbound 는 “All Traffic” 으로 제약을 풀어줘도 된다. 보안상 외부로의 접속을 차단해야할 상황이라면 설정을 해야하면 된다.

Inbound 접속 제한을 해야함으로 다음과 같이 설정해준다.

NAT 를 위한 Security Group
NAT 를 위한 Security Group

중요한 사항은 80, 443, ICMP 에 대한 NAT 접속은 Private Subnet 으로부터 받는걸로 설정을 해야 한다는 것이다.

NAT 의존하는 인스턴스를 위한 Security Group

Outbound 는 “All Traffic” 으로 제약을 풀어줘도 된다. 물론 보안상 문제가 된다면 제한을 걸고 싶은 포트를 지정해주면 된다.

NAT 에 의존하는 인스턴를 위한 Security Group
NAT 에 의존하는 인스턴를 위한 Security Group

SSH 서비스 접속포트는 NAT 서버 주소를 지정해준다. HTTP, HTTPS, ICMP 는 모든 영역에서 접속을 허용하도록 한다. 왜 이렇게 하냐하면 HTTP, HTTPS 는 AWS 의 Public ELB 를 통해서 외부로 서비스를 해야하는데 Public ELB -> private subnet 인스턴스에 접속이 이루어져야 하기 때문인데 문제는 접속할 IP를 알수가 없다. 그래서 접속하는 주소지를 모두 열어준다.

NAT Instance 생성

NAT Instance 가 필요한 이유는 다음과 같다.

  • Private Subnet 에 있는 인스턴스들을 제어하기 위해
  • Private Subnet 에 있는 인스턴스들이 인터넷을 하기 위해.

Private Subnet 에 있는 인스턴스들이 인터넷이 되어야 하는 이유는 OS 및 각종 소프트웨어의 자동 업데이트 때문이다. 보안 업데이트를 하기위해서는 업데이트 프로그램을 다운로드해야하는데 대부분 인터넷을 통해서 다운로드가 된다. 따라서 Private Subnet 도 인터넷이 되어야 한다.

또다른 이유는 AWS 의 S3 와 같은 외부 서비스를 이용하기 위해서다. S3 저장소는 HTTP 주소를 통해서 자원에 접근할 수 있도록 해주는데, 이를 Private Subnet 에서 이용하기 위해서는 인터넷이 되어야 한다.

NAT Instance 는 외부에서 연결을 해야함으로 EIP를 할당해준다. EIP가 없더라도 Public Ip를 할당해줘야 한다. 그리고 Subnet 은 Public Subnet 과 연결해 준다.

  • Instance: EC2 Linux System
  • Subnet: JumpSubnet(NAT)
  • Seucrity Group: NAT 를 위해 생성한 Security Group
  • EIP, Public IP 할당

중요한 것은 반드시 Public Subnet 에 인스턴스를 생성해 준다.

Private Subnet Route Table 조작

이제 앞에서 Private Subent 의 Route Table 을 조작할 때다. Private Subnet 의 Route Table 은 Local 외에 모든 연결을 NAT Instance 로 가게 설정 한다.

Private Subnet 을 위한 라우팅 테이블 조작
Private Subnet 을 위한 라우팅 테이블 조작

위와 같이 두번째 타켓으로 NAT 인스턴스를 지정해 준다. 그러면 이 라이팅에 연결된 Subnet 들은 외부와 통신을 위해서 NAT 인스턴스를 통해서 이루어지게 된다.

NAT 인스턴스 마스커레이딩 설정

지금까지의 내용은 인터넷을 찾아보면 나온다. 하지만 여기까지만 하면 절대로 Private Subnet 에 인스턴스에서 인터넷이 될수가 없다. 지금까지의 작업은 Network 단에서의 작업이였다. Security Group은 인스턴스단에서 이루어진 방화벽 작업일뿐 패킷의 경로를 조작해주는 것은 아니였다.

그런데, 이 모든 것을 다한다고 하더라도 OS에서 패킷의 경로를 원하는대로 조작해주지 않으면 Private Subnet 에 인스턴스들로부터 온 패킷과 받는 패킷들은 전송되지 않는다.

NAT 라는 것을 간단하게 설명하자면 우리가 가정에서 많이 쓰는 공유기와 같은 기능을 한다. 외부의 공인아이피를 가지고 내부의 사설 아이피를 할당해서 인터넷이 되게하는 것이 공유기의 역활인데, NAT 도 똑같다.

공유기가 없던 시절에 리눅스를 이용해서 공유기를 만들었었는데, 리눅스에 네트워크 카드를 두개 끼우고 하나는 외부망에 하나는 내부망에 연결하고 내부망에 허브를 두고 서로 통신이되도록 리눅스에서 설정을 해줬었다. 이 설정을 마스커레이딩(MASQUERADE) 이라 불렀다.

먼저 리눅스 커널에서 패킷을 포워딩 하도록 다음과 같이 설정해 준다.

그리고 iptables 에 nat 체인에 마스커레이딩 설정을 해준다.

Private 인스턴스 접속

Private 인스턴스를 접속하기 위해서는 다음과 같은 절차를 따른다.

  • 먼저 NAT 서버에 SSH 접속을 한다.
  • NAT 서버에서 Private 인스턴스로 접속을 한다.

Private 인스턴스에 접속한 후에 OS 업데이트 명령을 쳐보고 잘된다면 설정이 제대로 된 것이다.

ELB  설정.

Elastic Load Balancer 는 여러개의 서버들을 한대 묶어서 분산을 시켜주는 역활을 한다. 기존의 L4 스위치와 같은 역활을 하는 것인데 설정을 하게되면 ELB 접속을 위한 도메인이 생성된다. 이 도메인은 Amazon 에서 자동할당된 것으로 이것을 바꾸고 싶다면 DNS 서버에서 CNAME 으로 도메인을 등록하면 된다.

한가지 ELB의 제약 조건이 있는데, 그것은 반드시 Internet Gateway 와 연결되어야 한다. 이 말을 바꿔서 말하면 ELB는 반드시 Public Subnet 에 위치해야 한다는 뜻이다.

결국 ELB 때문이라도 반드시 하나의 Public Subnet 이 있어야 한다는 결론이 나온다.

ELB 설정
ELB 설정

위 그림을 보면 JumpSubnet(NAT)가 보이는데, 이게 바로 Public Subnet 이다. 반드시 1개의 Public Subnet 을 포함한다면 나머지 서브넷은 Private 이여도 상관이 없고 Private Subnet 에 있는 인스턴스들도 ELB를 통해서 서비스를 할 수 있게 된다.

ELB 에서 뒷단의 인스턴스들을 선택하기 위해서는 먼저 Subnet 을 반드시 선택해줘야 한다.

Private Subnet 의 인스턴스가 선택된 상태
Private Subnet 의 인스턴스가 선택된 상태

위와 같이 Private Subnet 의 인스턴스를 선택할 수 있다. ELB의 경우 대부분 HTTP 80 을 Inbound 로 받기 때문에 Private Subnet 안에 설치한 인스턴스에 웹서버를 올리기 되면 ELB를 통해서 서비스를 제공할 수 있게 된다.

 

이것으로 간단하게 Private Subnet 으로 서비스 구성하기 에 대해 간단하게 정리해 봤다.

가상 Guest 이미지 마운팅

가상 Guest OS의 이미지를 마운트하는 법을 설명합니다. 이미지 마운트에는 두가지 방법이 있습니다.

첫번째방법

1.Guest OS 이미지에 파티션으로부터 디바이스 맵(Device Map)을 생성합니다.

2.볼륨(Volume) 그룹을 스캔합니다.

이렇게 볼륨이 잡히면 이 방법은 유효합니다. 그렇지 않으면 두번째 방법을 사용해야 합니다.

3.볼륨(volume) 그룹의 속성을 바꿉니다.

볼륨의 상태를 확인합니다.

4.이제 볼륨을 마운팅하면 됩니다.


이렇게 마운트가 되면 마운트 포인터(Mount Point)를 통해서 접근할 수 있습니다. 언마운트(Umount)는 다음과 같이 합니다.

5.언마운트(Unmount) 합니다.

6.볼륨속성을 바꿉니다.

7.디바이스 맵을 지웁니다.

두번째 방법

두번째 방법은 위의 첫번째 방법 2번째에서 오류가 날경우에 사용하면 됩니다. 즉, 볼륨을 스캔했는데 볼륨이 없다면 바로 마운팅하는 것입니다.

1.Guest OS 이미지에 파티션으로부터 디바이스 맵(Device Map)을 생성합니다.

2.볼륨 그룹을 스캔합니다.

이렇게 볼륨 그룹이 없다고 나옵니다.

3.그냥 마운트를 하면 됩니다.

4.Unmount 는 다음과 같이 합니다.

 

CentOS 7 Systemd 이해하기

CentOS 7로 배포판 버전이 바뀌면서 가장 크게 바뀐것이 Systemd 입니다. 기존의 볼수 없었던 서비스 하나일뿐이라고 생각할 수 있지만 Systemd 는 단지 서비스 하나의 문제가 아닙니다.

Linux 의 기본 뼈대 프로세스

Linux는 운영체제 입니다. 전원을 넣고 부팅이 되는 과정에서 시스템을 초기화하고 기타 서비스들을 위한 환경을 조성하고 그들을 시작시켜주는 일을 하는 초기화 프로세스가 필요합니다.

CentOS 6 까지는 Sys V 라고해서 init 프로세스가 이것을 담당했습니다. 커널이 메모리에 로딩되면 가장 먼저 실행되는 프로세스로 init 프로세스를 실행시킵니다. 이 프로세스는 init 스크립트, init 설정등을 기반으로 RunLevel 이나 각 서비스별 실행 스크립트를 실행시키는 겁니다.

CentOS 7 로 올라오면서 Sys V 의 init 프로세스를 버리고 Systemd 로 바꾼 겁니다. 이는 Linux 의 기본 뼈대 프로세스를 바꾼 것으로 매우 큰 변화라고 할만 합니다. Systemd 는 기준의 Sys V init 보다 훨씬 많은 기능을 제공 합니다.

  1. 시스템 부팅 프로세스
  2. Service Management
  3. cgroup 을 이용한 프로세스 자원관리
  4. 서비스 프로세스 관리

흔히들 Daemon 프로그램들을 위한 로깅, 자원할당, 부팅관리등 Systemd 로 모두 할 수 있습니다.

주요한 명령어들

Systemd 를 위한 주요한 명령어들은 다음과 같습니다.

  1. systemctl
  2. systemd-analyze
  3. systemd-cgls
  4. systemd-cgtop
  5. systemd-loginctl

현재 작동하고 있는 서비스들 목록은 다음과 같이 확인 가능 합니다.

위 목록은 현재 동작중인 서비스들만 보여주는데, 모든 서비스들을 보고 싶다면 다음과 같습니다.

서비스 활성화, 비활성화, 시작, 정지, 재시작

부팅시에 서비스를 시작하도록 하기위 해서는 다음과 같이 해줍니다.

서비스 비활성화, 시작, 중지, 재시작, 릴로드는 다음과 같습니다.

서비스가 활성화, 실행중인지 다음과 같이 질의를 할 수 있습니다.

서비스 및 설정 파악

서비스에 대한 systemd 설정에 대한 모든 정보를 다음과 같이 확인할 수 있습니다.

각 서비스들은 서로간의 의존관계를 가지고 있습니다. 이는 다음과 같은 명령어로 확인이 가능합니다.

특정 서비스에 대한 의존성을 알고 싶다면 서비스명을 주면 됩니다.

Systemd 자체를 재시작하기 위해서는 다음과 같이 합니다.

Unit File 편집

다음과 같이 Unit file 출력도 지원합니다.

Systemd 는 기본적으로 /usr/lib/system 디렉토리에 Unit File 을 보관합니다. 그런데, 커스터마이징 하기위해서 이 파일들을 직접 편집하기 보다는 /etc/systemd/system/ntpd.service.d 처럼 커스터마이징 하고 싶은 서비스의 디렉토리를 만들고 .conf 로 끝나는 설정파일을 만들어서 바꾸고자하는 설정을 넣으면 됩니다. 만일 이러한 과정이 귀찮다면 단순하게 다음과 같이 함으로써 자동으로 알아서 커스터마이징 설정파일을 만들어줍니다.

위 명령어는 다음을 수행 합니다.

  1. /etc/systemd/system/ntpd.service.d 디렉토리 생성
  2. 시스템에 등록된 기본 편집기(대부분 VIM)을 연다.
  3. 내용을 입력하고 저장하면 1에서 생성한 디렉토리에 override.conf 파일을 생성하고 내용을 읽는다. (여기서 systemctl daemon-reload 는 불필요)

만일 /usr/lib/system/system/ntpd.service Unit File 자체를 편집하고 싶다면 –full 옵션을 주면 됩니다.

부팅 상태 분석

Systemd 의 주요한 임무는 부팅 과정을 관리하고 정보를 제공하는 것입니다. 부팅 시간 정보는 다음과 같이 확인할 수 있습니다.

총 1분 28초 정도 부팅하는데 걸렸다는 걸 알수 있습니다.

부팅과정에 각 서비스별 초기화하는데 걸린 시간은 다음과 같이 확인할 수 있습니다.

초기화하는데 걸린 시간을 기준으로 정렬해서 정보를 보여줍니다. kdump.service 가 1분 4초정도의 시간을 소비했습니다.

이러한 분석은 다음과 같이 html 파일로 덤프해서 볼 수도 있습니다.

plot.html 은 다음과 같습니다.

systemd-analyze plot

부팅시에 시간이 많이 걸리는 서비스들에 대해서 빨강색으로 표시해줍니다. 이 정보는 부팅과정에서 소비되는 시간을 측정해서 개선점을 찾게 도와줍니다.

시간을 많이 잡아먹는 서비스들을 트리형태로 엮어서(chain)로 볼수도 있습니다.

MariaDB 서비스에 대해서 엮여서 시간을 많이 소모하는 하는 서비스들을 보여 줍니다.

특정 서비스에 대해서 critical-chain 을 보고 싶다면 인수로 서비스명을 주면 됩니다.

서비스 실행을 실패한 서비스들은 다음과 같이 체크 가능 합니다.

타겟바꾸기

Systemd 에서 타겟(Target)은 동시에 서비스들을 시작하는걸 허용하기 위한 그룹 메커니즘입니다. 이는 Sys V 에 Run Level 과 비슷합니다. Sys V 에서는 init 명령어를 통해서 Run Level 를 바꿀 수 있었는데, Systemd 는 타겟을 바꿀 수 있습니다.

이 타겟에 따라서 부팅시 시작되는 서비스들이 달라집니다. 기본 값은 muti-user.target 입니다. 기본 값은 다음과 같이 바꿀 수 있습니다.

 

KVM Ubuntu 가상머신에 콘솔 접속하기

Ubuntu 를 KVM 가상머신으로 설치를 했다면 콘솔 접속을 해보면 안됩니다. 지난번에 CentOS6/7 배포판에서의 가상머신 콘솔접속에 대해서 다루어 었는데, Ubuntu 는 이들과 조금 다르기에 포스팅 해봅니다.

이 글은 ubuntu 14.04 를 대상으로 합니다.

처음 Ubuntu 를 KVM 가상머신으로 설치를 했다면 SSH 나 Virt-manager 나 vnc 를 이용해서 접속을 해야만 합니다. 그래야 콘솔접속을 위한 설정을 해볼 수 있습니다.

GRUB 설정

공통 Grub 설정은 /etc/default/grub 에 있습니다. 다음과 같이 설정을 해줍니다.

그리고 다음과 같이 업데이트를 해줍니다.

Serial 콘솔 만들기

다음과 같이 Serial 콘솔을 만들어 줍니다.

그리고 ttyS0.conf 파일을 다음과 같은 부분을 편집해 줍니다.

위와같이 수정해주고 리붓을 해줍니다.

테스트

Ubuntu 가상머신을 재부팅한 후에 호스트 서버에서 다음과 같이 콘솔 접속을 해봅니다. 그러면 다음과 같이 나오면 성공 입니다.

Enter 를 여러번 쳐주면 나옵니다.

 

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 해주는걸 잊지 말아야 한다.

 

 

가상 머신에 콘솔 접속하기

CentOS 6/7 혹은 RHEL 6/7 은 KVM 가상화를 지원 합니다. 가상화를 위한 네트워크를 설정하고 가상화 패키지를 설치하면 이제 가상 머신, 게스트 OS 를 설치할 수 있게 됩니다. 그런데, 맨 처음에 게스트 OS 를 설치하고 나면 더구나 DHCP 로 IP를 할당 받는다면 설치가 끝나고 나서 할당된 IP를 모르기 때문에 바로 접속을 할 수가 없습니다.

그래서 virt-manager 를 이용해서 게시트OS 화면에 접속하고 로그인을 하고 IP를 확인한 후에 SSH를 이용해서 외부에서 접속이 가능해 집니다. 하지만 이것말고 호스트 OS 터미널에서 게스트 OS로 virsh 명령어를 이용해서 접속할 수 있는데 이것이 가상 머신에 콘솔 접속하기 입니다.

virsh 명령어

virsh 명령어는 호스트OS에서 게스트OS(가상머신)을 관리하기 위한 명령어 입니다.

가상머신 이름이 나오는데, 이를 이용해서 다음과 같이 직접 게스트OS에 접속이 가능합니다.

하지만 게스트OS에 접속이 안됩니다.

게스트OS Grub 설정 변경

이를위해서 게스트OS에 Grub 에 옵션으로 다음과 같이 ‘console=ttyS0’ 을 추가해 줍니다.

하지만 이렇게 하나하나 다 하기보다는 다음과같은 명령어를 이용하면 편합니다.

CentOS6/RHEL6 의 경우 – grubby

grubby 는 각종 옵션들을 쉽게 설정할 수 있게 해줍니다. 위의 경우에 다음과 같이 할 수 있습니다.

CentOS6/RHEL6 에는 이렇게만 하고 서버를 재시작해줍니다.

CentOS7/RHEL7 의 경우 – /etc/default/grub 편집

CentOS7/RHEL7 의 경우에는 grub2 를 채택하고 있고 공통적인 옵션들은 ‘/etc/default/grub’ 파일에 있습니다. 이 파일을 편집해 줍니다.

이렇게 하고 grub2 를 다음과 같이 갱신해 줍니다.

위와같이 하고 난후에 가상머신을 재시작해줍니다.

접속 테스트

가상머신을 재시작한 후에 호스트OS에서 다음과 같이 접속을 해봅니다.

명령어를 입력해주고 Enter 를 두번 쳐주면 접속 로그인이 나옵니다. Console 접속을 해제하기 위해서는 Ctl+] 를 입력하시면 됩니다.

 

CentOS에서 SNMP 설치 및 설정하기

SNMP(Simple Network Management Protocol) 은 원래 네트워크 장비를 관리하기 위한 통신 규약입니다. 그런데, 이제는 네트워크 장비뿐만아니라 컴퓨터, 전자장비까지 확장해서 사용하고 있습니다. 리눅스 시스템에서도 SNMP를 사용할 수 있습니다.

이를 이용하면 SNMP 를 이용해서 중앙집중식으로 각각의 장비들의 자원, 자원사용량등을 장비에 거의 모든 것을 알 수 있고 가지고 올 수 있습니다. 저의 경우에는 Cacti 라는 시스템 자원 모니터링 시스템에서 원격 시스템의 자원 사용량을 가지고 오기 위해서 각 서버마다 SNMP를 사용합니다.

준비

이 문서는 다음과 같은 환경에서 작성되었습니다.

  • CentOS 7
  • X86_64

SNMP는 서버/클라언트 구조를 가지고 있습니다. 중앙 집중식으로 한 곳에서 정보를 모을 경우에는 중앙 서버를 제외하고 SNMP 데몬만 설치해주면 됩니다.

설치

설치는 Yum 을 이용해 다음과 같이 해주면 됩니다.

위에 뒷부분 ‘net-snmp-utils’ 는 SNMP 데몬하고는 아무런 관련이 없기 때문에 설치를 않해되 되지만 SNMP 데몬의 제대로 동작하는지를 테스트하기 위해서는 설치해주는 것이 좋습니다. ‘net-snmp-utils’ 는 말 그대로 SNMP를 다루기위한 여러가지 명령어들이 들어 있습니다.

설정

CentOS7 의 특징은 데몬이 실행될때에 옵션을 제공해 줄 수 있는데, 이를 위해서 ‘/etc/sysconfig’ 디렉토리에 데몬이름으로 파일을 가지게 됩니다. 그러면 데몬 실행 프로그램에서 이를 import 해서 사용하곤 하는데 SNMP 데몬도 이와 같습니다.

먼저 데몬 실행 옵션을 다음과 같이 설정 해줍니다.

위 옵션들은 다음과 같습니다.

  • -Ls 는 로그 메시지 stderr, stdout 으로 내보내고 로그레벨을 정한다. 기본은 -Lsd 로 d 는 LOG_DEBUG 을 말한다. 로그의 수준은 0 ~ 7 까지 존재하는데 다음과 같다.

    이는 -LSwd 나 -LS4d 식으로 숫자와 알파벳으로 지정할 수 있다. -LSed / -LS3d 같은 예제이다. 또, -LS1-5d 처럼 로그레벨 수준을 어디서 어디까지로 정할 수도 있다. 위 예제에서는 데몬 메시지를 syslog 로 보내는데 로그 레벨 1~5까지를 보내라는 뜻이다.
  • -Lf 는 지정한 파일로 로그 메시지를 보낸다. 위 예제에서는 /dev/null 임으로 로그 메시지를 삭제하는 효과를 보인다.
  • -p 는 pid 파일을 지정해 준다.

다음으로 SNMP 자체 설정을 합니다. 아래의 예제는 시스템 자원을 읽기 전용으로만 설정하는 것입니다.

SNMP 설정은 ‘sec.name’ 별로 설정을 할 수 있습니다. sec.name 을 여러게 정의하면 group도 여러개 설정할  수 있고 이렇게 되면 access 도 여러개 설정할 수 있습니다. 주목할 것은 access 에서 뒷부분에 read, write, notif 가 보이는데, 위 예제가 시스템 자원을 읽기만 할 것이기 때문에 read 부분만 all 로 하고 나머지를 none 으로 한 것입니다.

마지막으로 systemd 에 snmpd 를 활성화 해주고 시작해 줍니다.

로깅 변경

위 설정대로 하면 snmpd 로그가 /var/log/messages 에 저장이 됩니다. 하지만 /var/log/messages 는 커널 메시지도 저장되고 하는 중요한 것이여서 별도 파일에 저장하는 것이 좋습니다.

이를 위해서 snmpd 를 위한 별도의 로그 파일 설정을 해주는데, 먼저 /etc/sysconfig/snmpd 설정을 다음과같이 바꿔 줍니다.

rsyslog 데몬에서 다음과 같이 설정해 줍니다.

위에 예제에서 첫번째라인은 로그레벨 6 에 대해서는 /var/log/message 에서 제외하고 로그레벨6은 /var/log/snmpd.log 에 저장하도록 지정한 것입니다.

이렇게 해주고 데몬을 재시작 해줍니다.

로그 로테이션도 설정해 줍니다.

만일 일일이 출력하고 싶지 않다면 /etc/snmp/snmpd.conf 파일에 다음과 같이 설정해 줍니다.

 

Firewalld 설정

CentOS 7 에서는 iptables 에서 firewalld 로 변경되었습니다. snmpd 를 위해 firewalld 를 설정해 줘야 합니다.

먼저 snmp 관련해서 방화벽 열기위한 정보를 xml 파일로 작성해 줍니다.

그리고 다음과 같이 public zone 에 등록해줍니다.