jboss-cli 를 통한 로깅 설정

자바 웹 애플리케이션에 대한 로깅은 중요한 일이다. 웹 애플리케이션이 어떻게 동자하는지를 잘 알아야 하는데, 그 방법이 로깅이기 때문이다. 하지만 웹 애플리케이션의 로깅을 변경할 경우에 대부분 웹 애플리케이션을 배포한다. 물론 배포를 하지 않고도 가능하지만, 대부분 배포를 다시 하게 된다.

JBoss 에서는 배포를 하지 않고 jboss-cli 를 통해서 런타임으로 설정이 가능하다.

만일, 인증을 설정했다면 ID/Password 를 입력해야 한다.

logging Subsystem

Jboss 는 JEE 스펙을 구현한 서버이다. JEE 스펙을 각각 Subsystem 으로 구현해놨다. Subsystem 으로 모듈화를 해놨기 때문에 각각의 설정을 Subsystem 에 귀속되고 서로 간섭되지 않는다. 독립적인 모듈이다 보니 만일 득정 기능을 쓰지 않는다면 Subsystem 을 끄면 되고 그렇게 껐다고 해서 전체 서버가 문제가 되지 않는다. 아주 잘 만들어졌다.

jboss-cli 는 마치 파일시스템의 디렉토리를 접근하듯이 사용한다. 실제 명령어도 cd, ls 명령어를 그대로 사용할 수 있다.

subsystem 이 보인다. 저곳으로 들어가야 한다. cd 명령어를 사용해 들어간다.

jboss 내에 컴포넌트들이 보이는데, logging 이 보인다.

logging 관련된 많은 정보들을 볼 수 있다. 여기서는 logger 를 봐야 한다.

위와같이 보일 것이다.

logger 추가하기

이제 여기서 로거(logger) 를 추가해 보자.

위와같이 로거를 추가할 수 있다. 하지면 내용을 보면 핸들러(handler) 가 정의되어 있지 않다.

속성 추가

속성을 추가하기 위해서는 write-attribute 를 이용하면 된다. 레벨(level) 속성을 다음과 같이 변경할 수 있다.

레빌이 DEBUG 로 변경되었다.

핸들러 추가

핸들러 추가는 다음과 같이 한다.

한줄 명령어

지금까지 작업을 한줄 명령어 가능하다. 디렉토리 접근법을 사용하기 때문에 루트(root) 부터 따라들어가서 속성을 설정하면 되는식이다.

위와 같이 한줄 명령어로 충분히 가능하다.

VIM 세팅

vim 은 리눅스의 기본 에디터이다. 많은 기능을 제공하지만 이 기능을 사용하기 위해서는 설정을 해야 한다. 그런데, 이런 설정을 하나하나 하기 보다는 간단하게 Plugin 형태로 제공해 네트워크를 통해서 설치를 도와주는 플러그인 프로그램이 있다. 이것을 이용해서 기본적인 세팅을 해보자.

VIM 세팅을 위해서 git 명령어가 설치되어 있어야 한다. 그리고 기본적으로 시스템 계정 홈디렉토리를 기본으로 한다.

또, 반드시 네트워크가 연결되어 있어야 한다. 443 이나 80 포트가 OutBound 로 열려 있어야 한다.

Vundle

VIM 플러그인 설치를 도와준다. 네트워크를 통해서 설치하고 픈 플러그인을 지정해주면 설치를 해준다. 플러그인에 대한 설정은 여전히 사용자가 해줘야 하지만 하나하나 찾아서 해주는 것보다는 낫다.

다음과 같이 Vundle 를 설치 해준다.

.vimrc 파일 작성

이제 다음과 같이 간단하게 .vimrc 파일을 작성해 준다.

위와같이 작성한 후에 vim 을 실행해 명령어 모드에서 다음과 같이 입력해줍니다.

이렇게 하면 화면이 분할되면서 왼쪽에 Vundle Plugin 이 설치 된다.

airline 상태바(statusbar) 설치

VIM 은 화면 하단에 상태 정보를 표시한다. 하지만 많은 정보를 표시하지도 않거니와 보기도 그렇게 좋지 않다. 그래서 좀 더 인식하기 좋고 정보도 많이 표시하도록 도와주는 플러그인이 필요한데 ariline 이 이를 도와준다.

다음과 같이 .vimrc 에 설정을 해준다.

그리고 맨 아래에 다음을 추가 한다.

중간에 airline_theme 는 .vim/bundle/vim-airline-themes/autoload/airline/themes/ 디렉토리에 있는 파일 이름을 적어주면 된다.

YAML 플러그인

YAML 파일이 많이 사용 된다. YAML 문법을 제공해 준다.

만일 Ansible 을 사용한다면 이 플러그인은 설치해서는 안된다.

Ansible 플러그인

Ansible 플러그인은 Ansible 을 위한 플러그인이기 때문에 Yaml 플러그인과 충돌 날수도 있다.

Nginx 플러그인

Nginx 플러그인은 nginx 의 설정 파일에 대한 문법 하이라이트를 제공 한다.

Trac 첨부 파일 삭제

Trac 은 위키나 티켓에 파일을 첨부할 수 있다. 하지만 첨부파일이 잘못되었을 경우에 삭제를 해야 하는데, 아쉽게도 Trac UI 에서 할 수가 없다. CLI 를 이용해서 다음과 같이 삭제할 수 있다.

삭제 명령어

삭제를 위해서는 CLI 명령어를 사용해야 하는데, 대략 다음과 같은 형식이다.

예를들어 첨부 파일에 파일명에 공백이 있을 경우에 위키나 티켓 본문에 넣을 방법이 없다. 따옴표로 감싸거나 %20 으로 HTML 엔터티로 바꿔놔도 안된다. 이럴때는 삭제하고 파일명을 바꾼뒤에 다시 첨부해야 한다. 삭제할때는 다음과 같이 할 수 있다.

위와같이 첨부파일에 공백이 있을 경우에 CLI 를 이용해서 삭제할 수 있다.

AWS S3 PreSigned URL 설정하기

AWS S3 PreSigned URL 설정에 대해서 알아 본다. AWS S3 는 저장된 객체에 대해 HTTP 를 통해서 다운로드를 제공 한다. 문제는 이렇게 객체를 다운로드 하도록 주소를 공개할 경우에 누구나 다운로드 할 수있게 되서 보안상 좋지 않다. 그래서 AWS S3 는 인증 과정을 통해서 특정 시간 동안만 URL 에 다운로드 권한을 부여하는 PreSigned URL 기능을 제공하는데 이에 대해서 알아 본다.

AWS 사용자

먼저 PreSigned URL 에 인증 과정에서 사용할 Signiture 생성을 위해서 accesskey, secretkey 가 필요하다. 이것은 결국 AWS 사용자가 필요하다는 것과 같다.

사용자를 추가할때는 “AWS 액세스 유형 선택” 에서 “액세스 키- 프로그래밍 방식 액세스” 유형으로 계정을 생성해야 한다. AWS 콘솔로 로그인이 불필요한 사용자 이기 때문인데, 이렇게 생성을 진행하면 마지막에 accesskey, secretkey 가 발급되어 진다. 이것을 잘 보관 하자.

IAM Role, Policy

AWS S3 Presigned URL 을 위해 생성한 AWS 계정에는 그 어떤 IAM Role, Policy 가 필요하지 않다. 이것은 사용자에 S3 권한 설정을 IAM 을 통해서 할지 아니면 AWS S3 의 Permission Policy 로 할지에 따라 다를 수 있다. AWS S3 에서도 Permission Policy 를 설정할 수 있고 이 설정에서 특정 사용자에게 정책을 부여할 수 있다.

AWS S3 Presigned URL 만을 위한 계정이기 때문에 IAM 에서 권한을 부여하지 말고 AWS S3 에서 권한을 부여 방법을 선택 했다.

AWS S3 생성

AWS S3 는 글로벌 한 서비스이지만 생성할 리전을 선택할 수 있다. 생성할때에 S3 버킷에 대해서 별다른 설정을 하지 않고 그냥 기본값으로 생성한다. 나중에 설정을 얼마든지 변경할 수 있는데, 단 Presigned URL 을 한다고 해서 “Block Public Access settings for this bucket” 을 손대서는 안된다.

PreSigned URL 을 한다고 버킷의 공개 접근 설정을 변경해서는 절대로 안된다. 혹자는 URL 자체를 제공해줘야 하기 때문에 공개설정을 해줘야 한다고 하지만 특정 사용자에게 URL 을 제공하는 방식이기 때문에 버킷의 공개 접근 설정은 불 필요 하다.

AWS S3 Bucket Policy

여기서 핵심인데, 앞에서 AWS 계정에 아무런 권한 설정을 하지 않았다. 이제 그 권한 설정을 AWS S3 버킷에서 해주면 된다. Permission 탭에서 Bucket Policy 를 볼 수 있는데, 여기서 다음과 같이 해주자.

Principal 에 앞에서 생성한 AWS 계정이다. Resource 에는 Bucket 의 arn 을 주면 된다.

테스트

이제 테스트를 해보자. 테스트는 간단하게 Python 코드를 작성해 해보면 된다.

access key id 와 secret key id, Bucket Name 에 본인에 맞게 수정해 준다. 거기다 ‘utils/putty.exe’ 는 AWS S3 버킷에 있는 객체다.

위 코드를 실행하면 Presigned URL 이 출력이 된다. 유효기간은 expiration 변수에 값을 수정하거나 인자로 주면 된다. 기본값은 60초 이다.

윈도우즈10 에 Trac 1.2 설치하기

2021년에 아직도 Trac 을 사용하는 사람이 있을지 모르겠다. 하지만 프리랜서로 많은 프로젝트를 하는데 있어서 Trac 만큼 간단하면서도 필요한 기능이 다 있는 툴은 찾기가 힘들다. 프로젝트에 투입되면 Windows 10에 Trac 을 설치하고 프로젝트를 위한 여러가지 작업을 Trac 으로 하게 된다. Trac 을 이용하는 기능은 다음과 같다.

  • Wiki
  • Ticket
  • Calendar
  • Gant Calendar

문서도 작성하고 요청한 사항들을 정리하고 일정을 확인하는데, 그것도 로컬 컴퓨터에서 Python 으로 아주 가볍게 동작하는 툴을 본적이 없다. Jira 와 같은 협업툴이 많이 나왔지만, 프리랜서로서 자신만의 뭔가를 정리하려고할때 이만한 게 없다.

Trac 1.2

현재 Trac 은 죽어가는 프로젝트다. 조만간에 아카이빙을 해야할 정도라고 해도 된다. 그도 그럴것이 현재 Python 2 버전에서만 작동된다. Python3 이 새롭게 나왔는데 이것으로 바꿀 생각이 없어 보인다. 그래서 이 문서는 (아마도) Trac 1.2 버전에 관해 마지막 설치 문서가 될 것이다.

Trac 1.2 버전이 많은 플러그인들을 지원한다. 최신버전의 경우에 개발이 중단된 플러그인들을 제대로 인식하지 못한다. 내부적으로 바뀐부분도 많아서 고칠려면 꽤 손이 가는 일이라 안하는게 낫다.

Trac 은 Python 프로젝트이기 때문에 Python 이 있어야 하고 그것도 2.x 버전을 필요로 한다.

Python 2.7 설치하기

Windows 용 Python 을 다운받아서 설치해야 하는데, 2021년 현재 2.7.18 이 마지막 버전이며 MSI 인스톨러를 파일을 다운받을 수 있다. 다운로드 받은 파일을 더블클릭해 설치해주는데, 설치 디렉토리를 나의 경우에 F:\Python27 로 해줬다.

Python2.7.18 (x64) 설치 – 모든 사용자든, 나 혼자든 원하는데로 선택하면 된다.
Python2.7.18 (x64) 설치 – 설치 경로를 F:\Python27 로 해준다.
Python2.7.18 (x64) 설치 – 설치 컴포넌트들은 기본으로 놔두고 Next
Python2.7.18 (x64) 설치 – 설치가 진행되고 완료 된다.

pip.exe 를 이용한 의존성 설치

Trac 은 Python 으로 제작되었지만, 여러가지 의존성 라이브리를 필요로 한다. 이를 설치하기 위해서는 pip 프로그램을 이용하는게 가장 쉽다. pip.exe 는 Python 설치 디렉토리에 Scripts 폴더에 존재한다.

먼저 pip.exe 자체를 최신버전으로 유지시켜주기 위해서 업데이트를 먼저 해준다.

Upgrade pip (터미널은 Fluent Terminal 이다)

이제 Trac 1.2 의존성 패키지를 설치해야 하는데, 관련 문서는 다음과 같다.

한가지, 데이터 저장소로 데이터베이스를 선택하지 않았다. 기본적으로 Trac 은 데이터저장소로 sqlite3 을 사용하는데, Python 2.7 에 기본 포함되어 있어 별도의 의존성을 설치할 필요가 없다.

Genshi, version > 0.6

Genshi 를 설치해 줘야 한다. pip 를 이용해서 설치 한다.

Babel, version 0.9.6 or ≥ 1.3, needed for localization support

지역화 번역을 사용하기 위해서 필요하다고 한다.

docutils, version ≥ 0.3.9 for WikiRestructuredText.

Wiki 기능을 위해서 설치해 준다.

Pygments for syntax highlighting

문법 강조를 위해서 설치해 준다.

pytz 도 설치해줘야 하지만 Babel 을 설치하면서 함께 설치되었다.

Trac 설치

Trac 설치는 1.2.6 버전을 설치해야 한다. pip 를 이용해서 설치해야 하는데, 특정 버전을 설치하기 위해서는 반드시 버전을 명시해줘야 한다. 그렇지 않으면 최신버전을 설치하게 되는데, 현 시점에서(2021.08.27) Trac 1.4 가 최신 버전이다.

성공적으로 설치가 완료 됐다.

Trac 프로젝트 만들기 – trac-admin.exe

이제 Trac 프로젝트를 만들어야 한다. Trac 은 원래 멀티 프로젝트를 지원하지 않는다. 대신 Trac 프로젝트라고 해서, 비유를 하자면 웹 서버 가상호스팅 처럼 여러 시스템 계정을 가상 호스팅 루트로 서빙하듯이 여러 프로젝트 디렉토리를 생성해서 이를 루트로 인식시켜 작동하도록 했다.

Trac 프로젝트를 만들기 위해서는 trac-admin.exe 를 이용하며 프로젝트 디렉토리를 지정해 주면 생성 된다.

꼭 기억해야 할 것이 Trac 프로젝트의 루트 디렉토리명과 프로젝트 이름이다. 데이터베이스는 sqlite3 을 이용하기로 했음으로 그냥 엔터치고 넘어간다.

그러면 뭔가 F:\LocalProject 디렉토리에 복사가 되고 프로젝트가 생성이 된다.

마지막으로 프로젝트 관리를 위한 관리자를 생성하고 권한을 부여 해야 한다.

admin 이라는 ID 를 추가하면서 퍼미션을 TRAC_ADMIN 으로 부여 했다.

TracAccountManager 설치

Trac 에 AccountManager 플러그인을 설치해 준다. AccountManager 는 Trac 웹UI 에서 사용자 인증과 생성, 삭제등 관리를 해줄 수 있게 도와주는 툴이다. pip 를 이용해서 간단하게 설치해준다.

로그인 인증 설정

admin 이라는 ID 로 로그인 인증을 위해서는 인증을 위한 방법을 먼저 정의해야 한다. 인증 방법에는 다음과 같이 두가지 방법이 있다.

  • Basic Auth by HTTP
  • Htdigest

나의 경우에는 Htdigest 방법을 사용한다. 이를 위해서 AccountManager 플러그인을 설치했다.  그리고 Htdigest 인증 파일을 작성해줘야 한다. 이를 위해서 다음과 같이 Htdigest 인증 파일을 만들어주는 trac-digest.py 파일을 이용한다.

위 소스를 trac-digest.py 로 저장한다. 그리고 다음과 같이 실행해 준다.

AccountManager 플러그인을 활성하고 이를 이용해서 이 인증 방법을 지정해준다. 다음과 같이 trac.ini 설정 파일을 편집해 준다.

Trac 실행

이제 실행을 해보자. 실행을 할때에 인증방식을 파라메터로 줘야 한다. 앞에서 users.htdigest 를 작성했기 때문에 이를 이용하는 방법이다.

–auth 파라메터를 줘야 한다.

Trac 접속

접속을 하면 위 화면 처럼 나온다. 멀티 프로젝트를 지원하진 않지만, 프로젝트별 링크가 생성되기 때문에 멀티 프로젝트가 가능한 구조인 것이다(?)

LocalProject 메인 화면

LocalProject 링크를 누르면 메인 화면이 나온다. 여기서 “로그인” 버튼을 클릭하면 HTTP 인증 창이 나오는데, users.htdigest 의 인증 정보를 입력하면 로그인 된다.

admin 계정으로 로그인하면 “관리” 버튼이 보인다.

일단 로그인 되었다면 성공적으로 세팅이 된 것이다.

Trac 관리

관리 페이지는 Trac 을 관리하기 위한 페이지다. TRAC_ADMIN 권한이 있어야지만 볼 수 있다. Trac 을 설치하고 나면 맨 먼저 해야 할 곳이 이 부분인데, 여기서 주로 플러그인에 대한 세팅을 한다거나 플러그인을 설치하고 설정을 해준다.

TracAccountManager 0.5.0

먼저 TracAccountManager 를 설정해 줘야 한다. 관리->플러그인을 클릭하면 현재 설치된 플러그인들을 볼 수 있는데, 그중에 TracAccountManager 를 볼 수 있다.

Trac 에 설치된 플러그인들

여기서 ConfigurationAdminPanel, UserAdminPanel 을 체크해 활성해 준다.

두개의 기능을 활성화 해준다.

이 두개의 기능을 활성화 하면 왼쪽에 Account 메뉴에 설정, Users 링크가 생성이 되는데, Users 에서는 사용자를 추가/삭제/수정하고 사용자에게 퍼미션을 웹을 통해서 부여할 수 있게 된다.

Account 관리 페이지에 Users 페이지. 사용자를 관리할 수 있게 된다.

이제 유용한 플러그인을 설치해 보자.

TracTocMacro

이 플러그인은 Table of Content 로 위키에 목차를 생성해 준다. 설치는 pip 를 이용해도 되고 직접 소스코드를 다운로드 받아서 설치해 줘야 된다. 링크는 다음과 같다.

소스를 다운로드 받아서 설치해 보자. 홈페이지에 들어가면 zip 파일로 압축된 파일을 다운로드 할 수 있도록 링크되어 있다. 다운받아서 압축을 해제해 준다.

Trac 프로젝트를 재시작해 주면 관리 페이지 플러그인에 목록에 나오고 활성화해 주면 된다.

TocMacro 플러그인 활성화

TicketCalendarPlugin

티켓에 대한 달력으로 표시해 준다. 이것도 소스를 다운로드 받아서 압축 해제하고 설치 해준다. TocMacro 처럼 활성화만 해준다. 이렇게 하면 상단 메뉴에

TicketCalendar 활성화 이후에 일정보기 메뉴가 생긴다

티켓을 생성하면 위 달력에 표시가 된다.

TracGanttCalendar

칸트 달력을 위한 플러그인이다. 티켓에 대한 것도 함께 출력을 해준다. 이 달력은 여러 플러그인에 대해서 표시를 해준다. 한가지, 마지막 소스코드 버전이 0.11 인데 이것은 국제화가 안되어 있어서 한글이 나오지 않는다.

그래서 SVN 에 있는 MultiLanguage 지원 버전을 다운로드 받아서 설치해야 한다.

그런데, 이것을 그대로 설치하면 오류가 발생한다. 이것은 데이터베이스 API 가 Trac 1.2 로 넘어오면서 변경되었는데 이것이 반영이 되지 않아서 이다. 다음과 같이 코드를 수정해 줘야 한다.

또, templates 디렉토리에 macros.html 파일을 작성해야 한다. 빈 파일로 해서는 안되고 다음과 같이 html 이 기본 뼈대만 갖도록 해준다.

이렇게 소스코드를 조금 수정해준 다음에 설치를 해준다.

설정을 조금 해줘야 하는데, 이것은 trac.ini 파일을 편집해줘야 한다. 다음과 같이 설정을 해준다.

이렇게 설정한 후에 Trac 프로젝트를 재 시작 해준다. 그러면 새로운 티켓 생성하기에서 다음과 같이 시작날짜와 만료날짜 Completed 가 나타난다.

Ticket 생성하기

이제 필요한 플러그인은 모두 설치가 되었다.

우선순위 번역

관리 페이지에 우선순위가 있다. 영문으로 되어 있는데 다음과 같이 번역을 해준다.

우선순위 한글로 번역

해결방법 번역

관리 페이지에 해결방법이 있다. 영문으로 되어 있는데 다음과 같이 번역을 해준다.

해결방법 한글로 번역

티켓 종류 번역

관리 페이지에 티켓 종류가 있다. 영문으로 되어 있는데 다음과 같이 번역을 해준다.

티켓 종류 한글로 번역

이렇게 모든 설치와 설정은 끝났다.

결론

이제는 팀 협업을 위한 툴들이 아주 많다. 굳이 Trac 을 사용할 필요도 없으면 협업툴을 익히는 것이 직장생활(?)을 오래하는 방법이기도 하다. 하지만 프리랜서로서 일을 할때에 협업툴도 사용을 하겠지만 개인적인 업무를 기록하고 업무요청을 Ticket으로 기록하는 것 만큼 좋은 방법은 없다고 생각하는데 Trac 이 여기에 딱 맞아 보인다.

강남의 클라우드 회사들.. 테크 기업 맞나?

한국뿐만 아니라 전 세계적으로 이제는 클라우드(Cloud) 가 대세다. 이런 대세속에서 특이하게도 한국은 아직 그 시장 크지 않다. 정확하게 말하면 클라우드로 전환해서 쓰는 비율이 잘해야 15% 정도. 아직도 랙 서버 기반의 IDC 서버를 많이 쓴다.

최근에 금융권에서도 공공 클라우드 사업자를 선정해 클라우드로 전환하는 사례가 있다. 대표적인게 국민카드. 리브메이트 앱이 아마도 클라우드로 구축된 사례일 것이다.

이렇게 큰 규모에 경우에 클라우드 사업을 위해서는 클라우드를 잘 아는 기업을 선정해서 기술지원을 받는다. 국내에 클라우드는 AWS, Azure, GCP 삼파전인데 이들 글로벌 클라우드 회사에 기술을 가져다 다른 기업에 기술지원과 전환작업을 해주는 회사들이 존재하는데 그런 회사를 MSP 회사라고 한다. 이런 MSP 회사들 중에 한국에서는 대표적인 회사 두 회사가 있는데 강남에 있다. 신기하게도 한 두블럭이면 갈 수 있을 정도로 인접해 있다.

국내 금융권에서도 클라우드를 사용하고 하는 움직임이 있기 때문에 클라우드 엔지니어에 대한 수요가 상당하다. 문제는 이런 수요가 많은 만큼 그러한 기술을 지원해줄 사람들은 많이 없다는데 문제가 있다.

그런데, 사람이 아무리 없기로서니 아무나 다 뽑아서 프로젝트 매니저로 보내는 일은 없어야 하지 않을까? 프로젝트 매니저로 온 사람이라면 적어도 프로젝트에 대해 기술적 방향성이나 제안등을 할 수 있을 정도는 되어야 하는데 AWS EC2 가 뭔지도 모르거나, 그러다보니 전체적인 서비스를 서로 엮어서 전체적인 시스템을 만들어내는 아키텍쳐에 대한 지식도 없는 사람이 프로젝트 매니저를 하는 건 문제가 있다.

그런 기술적인 숙련도가 없는 사람을 그것도 강남에 클라우드 회사에서 정규직으로 뽑아놓고 현장에 뿌리고 있는데, 이런 현장에서는 매니저라는 사람의 사고 방식은 대부분 다음과 같다.

나는 프로젝트 매니저다. 기술은 잘 몰라도 내가 하라고 하면 너는 해야한다. 그러라고 돈주고 뽑은거다.

적도 프로젝트 매니저라면 몇년씩 클라우드 경력을 쌓은 사람에 대한 예의라도 있어야 하는데, 거꾸로 내가 책임자니까 무소 불휘의 권력을 쥔것마냥, 고작 한다는 것이 엑셀 파일에 자원 현황이나 기록하고 있고 그것을 잘 정리하지 않는다고 닥달하는 모습을 보여주는게 최근에 벌어지는 일이다.

클라우드 본사가 만든 한심한 아키텍쳐

강남에 이름 있다하는 클라우드 회사가 만들었다는 아키텍쳐에 일부다. AWS 클라우드 다이어그램인데, Public Subnet 이 두개, Private Subnet 그 뒤에 1개 있다.

EndPoint 를 NLB 가 받고 이것을 뒤에 Public Subnet 에 있는 웹 방화벽이 받고 있다. 웃기지 않나? 여기서 이것이 왜 문제가 되는지를 이해하지 못한다면 심각하게 자신의 능력을 한번 되돌아 봐야 한다.

웹 방화벽은 그야말로 웹에서 들어오는 패킷에 대한 보안검사기능을 한다. L7 패킷 검사가 가능한 장비. 그런데, 저렇게 Public Subnet 에 그것도 EIP 를 박아서 놔두면 십중팔구 DDOS 공격 대상이다. AWS 의 Shield 서비스를 해준다고 하지만 차라리 Private Subnet 구축하는게 훨씬 낫다. (AWS Shield Standard 는 EC2 인스턴스에 대한 DDOS 방어를 해주지 않는다. Advanced 는 가능하지만 한달에 3,000 달러다) 이렇게 웹 방화벽을 Public Subnet 에 올려놓고 구축하는 사례는 본적이 없다.

문제는 또 있다. 웹 방화벽은 EC2 인스턴스로 구축된다. 이 웹 방화벽은 뒤에 ALB 에 연결되는 구조다. 웹 방화벽이 ALB 의 도메인으로 연결이 된다고 하더라도 어짜피 커넥션은 IP 기반이 될 것이다. ALB 는 고정IP 가 아닌 유동 IP 이며 늘었다 줄었다 하게 된다. 웹 방화벽이 이렇게 유동적으로 변경되는 IP를 탐지해서 연결 설정을 해주면 고맙겠지만 안타갑게도 이중화를 위한 IP 2개만 들어간다.

십중팔구 트래픽일 몰리게 되면 방화벽이 뒤에 ALB 로 보내는 트래픽 양이 늘어날텐데 ALB 에서는 IP 를 늘리겠지만 그렇게 해봤자 아무런 소용이 없게 된다.

또 다른 문제는 EndPoint 로 NLB 를 사용했다는 데 있다. NLB 는 L4 계열이다. 네트워크 라우트 경로 설정에 유용하지 HTTP 기반의 연결에는 부적합하다. 가장 문제가 되는 것이 AWS WAF 문제다. AWS WAF 서비스는 Web 방화벽이다. Web 은 L7 기반인데, 당연히 NLB 에 연동될 수가 없다.

AWS WAF 의 경우에 ALB, CloudFront 등에 연동 된다. 요 몇일 AWS WAF 설정해야 한다고 난리던데, 그러면 WAF 를 EC2 웹 방화벽 뒤에 있는 Private Subnet 의 ALB 에 붙일 수 밖에 없든데, 얼간이 같은 설정이다. 앞에 이미 EC2 기반의 웹 방화벽이 일을 하고 있는데, 뒷단에 WAF 를 붙여서 뭣하게?

수준이 너무나 낮다

적어도 클라우드 MSP 사업을 영위하고 있다면, 적어도 프로젝트 매니징 능력이라도 있는 사람을 현장에 투입하고 아키텍쳐 또한 유기적인 조합이 가능하도록 해야 할 것이 아닌가?

더 크게 생각해볼 문제도 있다. 최근에 공정한 경쟁에 대한 관심은 우리 사회에 큰 논란을 낳기도 했다. 인국공 문제가 그런 것이다. 인천국제공항에 비정규직의 정규직화는 정규직 직원들에 대한 불공정 시비를 불렀다. 불공정한 경쟁으로 특정한 자리, 위치에 올라서 다른 사람을 부리는 것을 우리사회는 용납하지 않는다.

이번 프로젝트를 하면서 느낀 것이 바로 저러한 것이였다. 프로젝트 매니저라고 하는 사람은 아무것도 몰랐다. 그져 AWS 라는 것이 무엇이다 정도. PC 를 사용자중에서도 파워유저급과 비교될 정도 수준 일 뿐이다. 그런 사람이 프로젝트 매니저를 한다는 것이 그져 기술을 아는 사람을 대려다가 엑셀 파일이나 작성하며서 다 됐냐 안됐냐 만 따지는 것이 과연 공정한 것인가?

이런식이면 대학교를 막 졸업한 컴퓨터 관련 전공자를 앉혀놔도 될 정도다.

강남에 클라우드 회사는 테크 회사다. 본인들이 외주 업체 직원을 뽑을때에 기술이 낫을 거 같은 사람들이 많으니 기술면접을 엄격하게 진행하는 마당이면 적어도 본인들 회사 직원들 또한 그런 기준으로 뽑아야 하지 않겠나…..

Best Practice

클라우드를 하다보면 이런 말을 자주 듣게 된다. 한국어로 번역하자면 “모범 사례” 인데, 클라우드 아키텍쳐에 대한 모범사례를 다양하게 익히는 것이 좋다. 아키텍쳐라는 것이 정답이 없다보니 그나마 좋다라고 하는 것을 익히는 것이다.

여러 엔지니어, 특히나 강남에 클라우드에 다닌다는 사람들과 이야기를 하다보면 너도나도 모범 사례들을 이야기 한다. AWS 의 경우에 Re:Invent 행사에서 많이 다뤄지기도 해서 많이 알려진 것들도 많다. 하지만 이런 사람들이 도맡아 하는 기업의 아키텍쳐는 모범 사례는 고사하고 기초적인 3-Tier 모놀리틱 아키텍쳐를 클라우드로 구현하지 못한다.

대표적인 사례가 AutoScaling Group 사용을 하는 비율이 많지 않다. 금융권은 전멸이고 그나마 좀 사용한다는 곳이 쇼핑몰 들이다. CloudFront 를 EndPoint 로 하고 Static 파일은 S3, Dynamic 은 ALB 뒤에 EC2 서버로 서빙하는 구조를 가지는 아키텍쳐를 찾기도 힘들다.

HTTP 헤더 조작을 많이 한다면 이야기가 달라지만, 아직도 Apache + Tomcat 혹은 Nginx + Tomcat 으로 서버를 구성하는 곳도 지천이다. ALB – Apache – Tomcat 구조. Apache 에서는 mod_jk 로 톰캣 연동…. static 파일 서빙을 위해서 Apache 를 넣었다는 건데, 바보 같은 짓이다.

널리고 널렸다. 왜 이렇게 됐을까? 고객이라고 우쭈쭈쭈 고객님 말씀이 옳습니다 하는 바람에 이런 멍청한 구조가 나온 것이다.

기술의 발전은 인간을 이롭게 하는데 있다. 이것은 엔지니어에게도 그대로 적용된다. 왜 클라우드를 사용하는가? 기업의 대답은 “돈” 이겠지만 나의 대답은 “인간을 이롭게 하기 위해” 그냥 직접적으로 말한다면 “야근을 하지 않기 위해” 서다. 클라우드를 사용한다면 언제든지 Continuous 한 서비스 운영이 가능해지는데, 죽어도 이것을 하면 안된다고 하는 고객들을 설득할 마음조차도 없는게 국내 MSP 업체들이다.

그런 와중에 능력도 없는 프로젝트 매니저라니…. 대가리 박고 반성해라.. M사..

Office 365 Family 앱 선택 설치

Microsoft 에서 만든 킬러 애플리케이션인 MS Office 는 MS 의 클라우드 산업으로 선회하면서 가장 성공적인 클라우드 모델이기도 하다. MS Office 는 개인 사용자용부터 엔터프라이즈 사업자용까지 제품도 다양하지만 라이센스 또한 월 구독료 부터 한번 구매하면 영구적으로 인증되는 까지 다양 하다.

그런데, Office 365 특히나 Family 로 월 구독으로 구매한 사용자의 경우에 설치를 할때에 이 라이센스에 포함된 제품들을 선택적으로 설치할 방법이 없다. 예를들어 Office 365 Family 의 경우에 Access, Publisher 와 같은 앱도 포함되어 있는데, 사실 일반 사용자는 잘 사용하지 않는 제품들이다. 설치할때에 내가 필요로하는 MS Office 앱들만 설치할 수는 없을까?

ODT (Office Deploy Tool)

오피스 배포 툴이라고 할 수 있는데, 이것을 이용하면 Office 제품군의 설치할때에 필요한 것만 설치가 가능하다. 자세한 내용은 다음의 링크를 확인하면 된다.

위 내용을 읽어보면 ODT 를 다운로드 할 수 있는 링크도 제공하고 어떻게 사용하는지 잘 나와 있다. ODT 를 다운로드를 하고 더블클릭하면 압축이 해제되며 setup.exe 파일과 함께 xml 형식의 파일 3개가 나온다.

방법은 간단하다. xml 형식의 파일중 하나를 자신에 맞게 바꿔 주면 된다. 여기서 중요한 것이 제품에 대한 ID 를 알아야 하는데, 이 또한 위에 링크 페이지에 잘 설명이 나와 있다. 그런데, 글을 읽어보면 Office 365 Family 는 지원하지 않는 비지니스와 엔터프라이즈만 지원 되는 것처럼 되어 있지만, Office 365 Family 또한 지원 한다.

설치하기

먼저 XML 파일을 다음과 같이 작성한다.

필자의 Office 365 Family 의 Product ID 는 O365HomePremRetail 이다. 거기다 64bit 이며 한글 버전이다. 개인적으로 Access, Publisher 가 필요가 없기 때문에 설치시에 제외할 앱을 넣어 뒀다.

설치는 다음과 같이 하면 된다.

이렇게 하게 되면 설치할때에 위 XML 설정파일대로 진행이 된다. 내가 필요로 하는 제품만을 설치할 수 있게 되는 것이다. Office 365 Family 또한 잘 된다.

참고: How to customize Microsoft Office installation – Tutorial

쿠버네티스에 프로메테우스(Prometheus) 오퍼레이터 설치하기

프로메테우스(Prometheus)는 모니터링 시스템을 말한다. 프로메테우스는 파일 기반의 타임시리즈(Time-Series) 데이터베이스다. 시스템의 메트릭스들을 수집하기 위해서는 익스포터(Exportor) 를 설치해야 한다. 이외에도 알람을 전달해주는 AlertManager 도 있는데, 전체적인 아키텍쳐는 다음과 같다.

프로메테우스 아키텍쳐

프로메테우스는 쿠버네티스에서도 설치가 가능한데, 이글은 쿠버네티스에 프로메테우스 설치에 대한 글이다.

환경

환경은 다음과 같다.

  • Kubernetes 버전: 1.20
  • Kubernetes Nodes: Master 3개, Worker 3개
  • Prometheus 설치 방법: Helm Operator

설치

프로메테우스(Prometheus) 설치는 매우 다양한데, 검색을 해보면 Helm 을 이용한 방법 그중에서도 오퍼레이터(Operator) 를 이용한 방법이 많이 소개 되어 있다. 여기서도 이 오퍼레이터를 이용한 방법을 사용하고자 한다.

Prometheus Operator 로 검색을 해보면 github 저장소를 찾을 수 있다.

중간에 보면 Prometheus Operator vs kube-prometheus vs community helm chart 가 보인다. 자세히 읽어보면 쿠버네티스에 설치할 수 있는 방법이 세 가지로 나뉜다는 것을 알수 있다.

이중에서 나는 Helm chart 를 이용한 방법을 이용할 생각이다.

노드 레이블 설정

노드에 레이블을 설정하게 되면 쿠버네티스에 앱을 배포할때에 레이블을 지정함으로써 특정 노드에 생성되도록 강제할 수 있다. 프로메테우스 오퍼레이터 설치를 특정 노드에 하기 위해서 레이블을 부여할 생각이다. 대상 노드는 kworker3.systemv.local 노드이며 다음과 같이 레이블을 할당해 줬다.

kworker3.systemv.local 노드에 system.rule=monitoring 레이블이 새겨졌다.

Helm Chart 가지고 오기

Helm 를 이용하면 명령어 한줄로 설치가 되지만 설정을 변경하기 위해서는 챠트(Chart) 를 수정해줘야 한다. 이를 위해서 챠트를 다운받아야만 한다. Helm 챠트는 프로메테우스 커뮤니티에서 관리하고 있다.

많은 챠트가 존재하는데, 여기서 설치 대상은 kube-prometheus-stack 이다.

설정을 하기위해서 프로메테우스 오퍼레이터의 구성을 살펴볼 필요가 있다.

  • Prometheus – 프로메테우스 리소스 정의가 되어 있다. 프로메테우스를 위한 파드(Pod) 의 리플리카(Replica) 갯수, 퍼시스턴스 볼륨 구성등이다. 프로메테이스 오퍼레이터는 파드를 StatefulSet 으로 배포 한다. 그리고 어떤 애플리케이션, 혹은 리소스를 모니터링할 것이지를 지정하는 것인데, 이것은 ServiceMonitor 로 설정이 이루어 진다.
  • ServiceMonitor – 프로메테우스 오퍼레이터는 어노테이션 기반의 서비스 디스커버리를 지원하지 않으며 대신 PodMonitor, ServiceMonitor 를 이용한다. ServiceMonitor는 애플리케이션이나 서비스의 리소스를 모니터링할 것인지를 지정한다. 쿠버네티스의 NodeSelector 처럼 LableSelector 로 서비스의 리소스를 선택할 수 있고, 엔드포인트(EndPoint) 를 통해서 애플리케이션의 메트릭을 수집할 수 있다. ServiceMonitor 는 rule 을 기반으로 Prometheus의 모니터링 대상이 되는 ServiceMonitor를 scan하여 해당 정보를 Secret으로 배포한다. 그리고 이 Secret을 Prometheus StatefulSet에 마운트한다. 이런 방식으로 Prometheus 팟은 자신이 모니터링할 Service가 무엇인지 알 수 있다.
  • Altermanager – 알람 매니저 이다. 프로메테우스 컴포넌트중에 하나다.
  • PodMonitor – 파드에 대한 모니터다. 역시나 LabelSelector 를 통해서 모니터링하고자 하는 파드를 지정할 수 있다.

위 내용을 잘 알야하는 이유는 kube-prometheus-stack 디렉토리에 values.yaml 파일에 구조와 연관이 있다.

values.yaml 파일 편집

프로메테우스 오퍼레이터를 Helm 으로 설치할 때에는 values.yaml 파일의 설정을 참고하도록 되어 있다. values.yaml 에는 altermanager, Grafana, Prometheus 등에 대한 설정 값들이 들어가 있다. 앞에서 특정 노드에 배포하도록 하기 위해서 worker3.systemv.local 노드에 레이블링을 해줬기 때문에 이들 컴포넌트의 NodeSeletor 를 지정해 줘야 한다.

Grafana, Altermanager, Prometheus 의 파드들은 system.rule=monitoring 레이블링 된 노드에만 설치되도록 해뒀다.

Node Exportor 는 system.rule=monitoring 레이블링을 할당하지 않는다. 이들은 노드마다 작동되어야 하기 때문이다.

Helm 설치

이제 설치를 해야 하는데, 설치하기 앞서 의존성 챠트를 업데이트 해야 한다.

이제 다음과 같이 설치를 실행해 준다.

확인

이제 확인을 해보자.

이렇게 설치가 된것으로 보이지만, 사실 프로메테우스의 오퍼레이터는 CRD 를 이용해 리소스를 생성하였기 때문에 이를 알아야 한다. CRD 를 포함한 monitoring 네임스페이스에 모든 리소스를 보기 위해서 다음과 같이 할 수 있다.

이를 통해 확인할 수 있는 CRD 예로 ServiceMonitor, Prometheus 등을 확인해 볼 수 있다.

필자는 Metallb 를 이용해서 LoadBalancer 를 사용할 수 있기 때문에 grafana, prometheus 서비스에 대해서 타입을 ClusterIP 를 LoadBalancer 로 변경해 외부접속이 가능하도록 할 수 있다.

Metallb 에 의해서 EXTERNAL-IP 에 외부접속 IP 가 할당 되었다.

Ingress Nginx

인그레스(Ingress) 는 쿠버네티스에 설치하는 클러스터 내의 서비스에 대한 외부 접근을 관리하는 API 오브젝트이며, 일반적으로 HTTP를 관리한다. 인그레스를 위해서는 인그레스 오브젝트를 설치해야 하는데, 이를 구현한 것들이 꽤 있지만 nginx 가 대표적이다.

여기서는 Ingress-Nginx 에 대해서 간단히 알아 본다.

설치전 고려사항

첫째로 일단 쿠버네티스에 서비스(Service) 에 고려 해야 한다. 쿠버네티스의 서비스는 클러스터내에 접속지점을 생성해 준다. ClusterIP, LoadBalancer, NodePort 세 가지의 타입이 존재한다. 문제는 LoadBalancer 타입인데, 이 타입을 지정해주면 EXTERNAL-IP 가 할당되어야 하지만 일반적인 환경에서는 할당되지 않는다.

LoadBalancer 는 클라우드 서비스 제공 사업자를 위한 것으로 AWS, GCP, Azure 클라우드에서 제공하는 로드밸런서를 위한 것이다. 그래서 일반적인 베어메탈(Bare Metal) 이나 VM 환경(VMware, VirtualBox, KVM) 에서 쿠버네티스를 구성한 상태에서 LoadBalancer 를 사용하게 되면 EXTERNAL-IP 할당되지 않는다.

이렇게 하면 외부에서 접속이 되지 않는다. 이 접속은 클러스터내에 파드(Pod) 에서 호출할 수 있지만 외부에서는 호출이 되지 않는다.

그래서 베어메탈이나 가상환경에서 쿠버네티스에서 LoadBalancer 를 사용할 수 있도록 해주는 Metallb 을 이용했다. 이를 이용하면 서비스 타입을 LoadBalancer 로 지정했을 경우, EXTERNAL-IP 가 할당돼 외부에서 접속이 가능해 진다.

두번째로 ingress-nginx 를 Helm 으로 설치하지 말아야 한다. 현재 Helm 저장소에 올라온 ingress-nginx 는 api 버전이 과거에 버전이다. v1beta 버전으로 되어 있는데, 필자의 쿠버네티스에서는 오래된 버전으로 인식된다.

이를 해결하기 위해서는 github 저장소에 baremetal 버전에 deploy.yaml 파일을 이용해야 한다.

설치

먼저 ingress-nginx 의 github 에 접속해 baremetal 버전을 다운로드 받는다.

이 deploy.yaml 은 baremetal 버전인데, 여기의 서비스 타입은 NodePort 로 되어 있다. 필자는 앞에서도 말했지만 Metallb 를 설치했기 때문에 LoadBalancer 타입으로 변경을 해줘야 한다. deploy.yaml 파일을 열어서 바꿔 준다.

서비스 타입을 바꿨다면 이제 설치를 해 준다.

이 방법으로 설치를 하게 되면 다음과 같은 특징을 갖게 된다.

  • ingress-nginx 네임스페이스가 생성 된다.
  • LoadBalancer 타입이며, Metallb 으로 인해 EXTERNAL-IP 가 할당 된다.
  • apiVersion 이 networking.k8s.io/v1 최신 버전을 지원 한다.

LoadBalancer 에 EXTERNAL-IP 에 외부 접속을 하기 위한 IP가 할당되어 있다.

예제

예제는 springboot 를 이용한 서비스를 배포하고 ingress 를 통해서 접속해 본다. 이 예제는 하나의 서비스에 대한 것이다.

먼저 Deployment, Service 를 다음과 같이 작성 한다.

정상적으로 생성이 되었다. 이제 이것을 인그래스와 연결을 해줘야 한다. 인그래스에서 URI 가 /springboot 이면 지금 배포한 springboot 의 메시지가 화면 표시되도록 했다.

직접해보면 위와같이 오류가 발생한다. 이는 보안 관련 쪽에 문제가 있는 것으로 보이는데, 아마도 TLS 설정에 문제가 있기 때문인 것으로 추정 된다. 이를 해결하기 위해서는 webhook 설정을 삭제해주면 된다.

그리고 다시 한번 ingress-springboot.yaml 파일을 적용해주면 인그래스가 생성 된다.

/springboot URI 는 springboot-service 백엔드로 연결이 되어 있다걸 확인할 수 있다. 이제 인그레스 서비스에 LoadBalancer 의 외부 접속 IP 로 접속을 시도해 보자.

위와같이 인그레스가 정상적으로 동작함을 알 수 있다.

정리

지금까지의 예제는 쿠버네티스 인그레스 문서의 첫번째 다이어그램과 정확하게 같은 것이다.

단일 서비스에 인그레스 적용 다이어그램

클라이언트가 인그레스 로드 밸런서로 접속이 가능해야 했기 때문에 Metallb 을 이용해서 외부접속 IP를 할당해 주도록 설정을 했다.

인그레스 서비스는 설치할때 한번 생성되어지고 이것을 통해서 뒤에 서비스들과 연결이 되어지는데, 이 백엔드 서비스들에 어떻게 연결을 할 것이지에 대한 설정은 인그레스 컨트롤러에 의해서 결정되게 된다.