Recommanded Free YOUTUBE Lecture: <% selectedImage[1] %>

Contents

소개

약 2년 정도 AWS 위에서 2개의 서비스를 개발했고, 서비스 아키텍처로 참여했다. 운 좋게 이들 서비스는 전 세계를 대상으로 하는 서비스였고 복잡한 서비스 였으며, 역시 운이 좋게도 (스타트업이나 인터넷 서비스 기업이 아닌)기성기업의 요구를 만족하는 서비스여야 했다.

전 세계를 대상으로 하는 복잡한 서비스라면 배울게 많으니 운이 좋다라고 생각할 수 있겠는데, 기성기업의 (복잡한) 요구를 만족해야 하는 건 오히려 제약사항인 것 아니냐라고 생각할 수도 있겠다.

이 상황을 이해하기 위해서는 기성기업(중견/대기업)의 IT 서비스에 대한 시각을 살펴볼 필요가 있을 것 같다.

이들 기업은 "접속 권리"를 획득하는 것보다는 "자원을 소유"하는 것에 익숙하다. 소유와 통제가 주요 관심사이기 때문에, 접근이 통제가 되는 특정장소에 역시 물리적 실체를 가진 장비를 배치하고, 여기에 데이터를 저장해야 안심하는 경향이 있다. 그게 실체가 없는 "데이터"라고 해도 마찬가지다. 데이터를 종이에 적어서 저장하느냐, 자기 디스크에 기록해서 저장하느냐의 차이가 있을 뿐이다. 관성의 힘도 무시할 수가 없다. 꽉 짜여진 프로세스를 바꾸는게 쉬운일이 아니라서..

퍼블릭 클라우드는 자원의 소유가 아닌 "자원을 대여"하는 개념으로 기성기업의 "자원을 소유"한다는 개념과는 상당한 차이가 있다. 기성기업이 퍼블릭 클라우드의 사용에 적극적이지 않은 이유다. 그렇다고 퍼블릭 클라우드라는 대세를 무시할 수는 없어서, 내놓은 차선책이 하이브리드 클라우드와 프라이빗 클라우드라는 좀 애매모호한 솔류션을 고민하고 있는 형국이다.

내가 진행한 프로젝트는 기존의 애매모호한 방식이 아닌, 퍼블릭 클라우드를 기본 인프라로 활용하기로 했다. 대기업으로서는 그리 흔하지 않은 접근 방식다. 몇몇 대기업에서 퍼블릭 클라우드를 사용하고 있다라는 소식을 듣기는 했지만, 유저 종단 서비스용으로 사용할 일부 자원을 퍼블릭에 두었던 것으로 기억한다.

클라우드를 전적으로 사용하는 대신 기존의 데이터 소유 방식과 동등한 혹은 납득할 만한 수준의 장치를 퍼블릭 클라우드에 적용해야 했다. 예컨데,
  • 자원에 대한 엄격한 접근 통제
  • 서비스 트래픽과 관리 트래픽의 분리
  • 전체 네트워크의 격리
  • 다양한 서비스들의 수용
  • 수용된 서비스들 간의 격리
  • 모니터링과 이슈 대응 프로세스. 이 프로세스를 지원하기 위한 시스템의 개발
  • 통합 관리/관제 솔류션
  • 기존 IDC에서 사용했던 수준의 보안정책 적용
데이터 센터를 AWS로 그대로 올리는 거라고 보면 되겠다.. 운이 좋았다고 말하는 이유다. AWS위에 데이터 센터를 구축하는 건 쉽게 할 수 있는 경험이 아닐테니까. 이 요구사항을 모두 만족하고, 덤으로 퍼블릭 클라우드라서 얻을 수 있는 장점들을 추가 제시하는 것으로 AWS를 기본 인프라로 제안했다.
  • 가용성 확보
  • 글로벌 대응 가능
  • 탄력적인 운용
  • 비용 절감
비용 절감이라는 문제를 언급하고 넘어가야 할 것 같다. "AWS의 장점은 탄력적인 자원의 운용, 빠른 서비스 전개와 회수에 있지 비용에 있는 건 아니다. 생각한 만큼 싸지 않다. 비용을 장점으로 생각하긴 힘들다"라는 주장도 있다.

인터넷 서비스 기술을 가진 스타트업이나 인터넷 서비스 회사가 크게 복잡하지 않은 서비스를 AWS에 올린다면, 위의 주장이 맞다. 보통 이런 서비스를 위한 인프라는 한,두명의 개발자가 개발과 설계, 구축, 운영을 동시에 한다. 설계, 구축, 운영에 대한 비용이 추가되지 않기 때문에 트래픽과 인스턴스비용이 전체 비용의 대부분을 차지 한다. 네트워크와 인스턴스에 대한 비용은 공짜 수준이라고 봐도 될 정도로 하향 평준화 되었기 때문에, 비용 절감 효과를 누리기가 힘들다.

하지만 일반 중견/대기업의 경우는 상황이 많이 다르다. IDC위에서 서비스를 만들려고 하면, "설계 시작합시다"라는 사인이 떨어지는데 6개월 정도의 시간이 걸리는 곳이다. 설계도 좀 경험있는 개발자 한/두명이 할 수 있는 일이 아니다. 혼자 할 수 있는 능력이 있다고 하더라도, 혼자할 수 없다. 시스템/네트워크 엔지니어와 협업을 해야 한다. 구축과 운영도 마찬가지로 독립된 조직을 필요로 한다.

참여하는 조직도 많고, 의사 결정과정도 (소프트웨어 개발 측면에서)비효율적이다 보니, 결정이 느리고 설계, 구축, 운영에 엄청난 비용이 들어간다. 이런 서비스 인프라를 AWS위에 구축하면, 비용 절감 효과가 굉장히 크다. 10명으로 1년 걸릴 인프라 구축을 1.5명이 한달에 구축 할 때의 비용절감을 생각하면 되겠다.

Name 관리

가장 먼저 Name 정책을 정리했다. 가장 먼저 수행한 이유는 (가장 쉬워서가 아니라), 제일 중요한 일이기 때문이다. 자원은 자원에 할당된 "이름"을 통해서 자신의 위치와 롤(역할)을 알 수 있기 때문이다.

인프라 전체 형상은 Chef를 이용해서 중앙에서 관리할 것이다. Chef의 역할이라는 것은 1. 자원의 위치와 2. 자원이 하는 일을 파악해서, 그에 맞는 데이터와 코드를 내려주는데 있다. 이들을 관리하는게 "이름"이다.

예를 들어 보자.

인터넷 서비스라면 "dev", "staging", "service" 3개로 구성된 개발->스테이징->서비스 주기를 가질 것이다. 여기에 맞춰서 dev와 staging와 service 인프라를 구축해야 한다. 유저 보안의 경우 각 단계에 따라 달라져야 하는데, dev는 개발자에게 sudo root 권한을 주겠지만 staging, service의 경우에는 그렇지 않을 것이다. service의 경우는 보안을 중요시 해야 하는 만큼, 개발자는 "일반 권한"만 가지며 특수한 경우에만 sudo 권한을 획득할 수 있을 거다.

데이터베이스도 각 위치에 따라 권한이 다르게 적용된다. Iptable, TCP Wrapper, SSH 접속 정책, Security group 정책도 위치에 따라서 달라진다. 롤도 마찬가지다. 서비스의 종류에 따라서, 각 서비스에서 어떤 역할을 맡고 있는지에 따라서 설정 값이 달라진다. 글로벌 서비스라면, 지역에 대한 정보도 알고 있어야 한다. 기타 데이터 수집과 분석, 모니터링, 관제 시스템, 빌링 시스템등의 구축을 위해서도 필수 정보다.

Domain Name

인프라의 형상을 설계하는데, 가장 중요한 요소가 "이름"이라는 것을 알았다. 이제 "이름 관리 시스템"을 선택해야 하는데, 나는 Domain Name을 선택하기로 했다. Domain Name을 선택한 이유는
  1. 도메인시스템은 인터넷 표준으로 관련 기술이 잘 알려져 있다.
  2. 자원을 계층적으로 관리할 수 있다.
  3. 도메인 이름관리를 위한 경험이 많다.
  4. 도메인 이름을 관리하기 위한 툴이 많다.
  5. 운영체제의 host name과 엮어서 사용하기 쉽다.
도메인 이름은 대략 다음과 같이 구성 할 수 있다. 아래 구성은 예시일 뿐이다. 구축목적에 따라서 얼마든지 달라질 수 있다.

  1. 지역 : US-EAST 리전에 위치하며
  2. 단계 : 개발을 위해서 사용한다.
  3. 서비스 : 메시지 서비스
  4. 역할 : 워커 컴포넌트다.
  5. 도메인 : mydomain.com 이라는 조직에서 관리한다.
도메인 이름이 만들어지면, 아래 그림과 같은 형상의 계층적 구성을 만들 수 있다. 이 구성이 중요한 이유는, 이 구성에 따라서 chef의 데이터 구조가 만들어지기 때문이다. 반대로 계층적인 구성을 먼저 만든 다음에, 도메인 이름을 만드는 방식으로 갈 수도 있다.

예를들어 Tokyo-Dev의 Service-1에 인스턴스를 하나 올린다고 가정해 보자. 인스턴스의 프로비저닝 단계에서 유저 접근을 위한 SSH-Key를 배포하기 위한 chef data-bag은 대략 아래와 같이 구성할 수 있을 것이다.
# cat ssh-key.json
{
  "ID" : "SSH Configuration",
  "Tokyo" : {
    "DEV": {
        "SSHD-CONF":{
          "RemoteRootLogin":"off",
          "PasswordLogin":"off",
          "FailureRetryLimit":"5",
          "SessionTimeOut":"600"
        },
        "SSH-KEY": {
            "Service-1": {
               "User1":{
                   "SudoRoot": "on",
                   "PrivateKey": ".......",
                   "PublicKey": ".......",
               },
               "User2":{
                   "PrivateKey": ".......",
                   "PublicKey": ".......",
               }
            }
        }
    },
    "STAGING": {

    },
    "Service": {

    } 
  }
}

AV-Zone, subnet 위치(Public network인지 Private network)인지 등의 정보를 추가하면 자원의 위치를 좀 더 명확히 할 수 있다. 이렇게 하면 관리자는 도메인 이름만 보고도 자원의 정확한 용도를 파악할 수 있다는 장점있다. 반면, 도메인 이름이 쓸데없이 길어진다는 단점도 있다. 어느 정도의 해상도를 가질 지는 설계자가 정해야 한다. 경험해본 바로는 AV-zone과 subnet의 위치까지, 도메인 이름에 넣을 필요는 없었다. 이들 정보는 다른 방식으로 충분히 찾아낼 수 있다.

Name을 이용한 Auto Provisioning

이름이 결정되면 아래와 같은 프로세스에 따라서 자원을 자동으로 Provisioning 할 수 있다.

  1. Domain name 설정 : 웹 기반의 관리자 페이지가 필요할 테다. 손으로 도메인이름을 적을 수는 없는 노릇이다.
  2. 설정 값을 submit하면 Domain name의 node를 chef-server에 등록한다. chef는 Domain 이름을 이용해서, 어느 위치에 프로비저닝 해야 하는지를 알 수 있다.
  3. 이 도메인은 monitering에 추가된다. 나는 모니터링 툴로 zabbix를 이용한다. 아직 인스턴스가 만들어져있기 않기 때문에, 그대로 추가했다가는 에러가 발생할 것이다. 메인터넌스 모드로 실행하고, 인스턴스가 올라오면 실행 모드로 바꾸면 된다.
  4. AWS API를 이용해서 인스턴스를 만든다. 이때 user data에 (다른 정보들과 함께)도메인 이름이 들어간다.
  5. 인스턴스가 올라온다. cloud-init로 user-data를 읽어오고 hostname을 설정한다.
  6. 인스턴스가 올라오고 IP를 확인하면, 도메인 서버에 도메인을 추가한다. 나는 Dnsmasq로 도메인 서비스를 만들었다.
  7. cloud-init로 chef-client를 실행한다.
  8. chef-client는 hostname에 설정된 도메인이름으로 chef-server에 연결한다.
  9. chef 코드를 실행한다.
chef 코드가 하는 일은 다음과 같다.
  1. Account 설정 : 위치에 맞는 Account 설정을 한다.
  2. SSH key 설정 : 생성한 account를 위한 ssh key를 설정한다. private key는 유저에게 메일등오로 전송한다. Public key와 Private key는 chef databag에 저장한다. chef는 외부에 완전히 격리된 위치에 있을 건데, 그럼에도 보안이 걱정된다면 Private key는 배포즉시 파기하는 등의 조치를 취할 수 있다.
  3. Network 설정
  4. 보안 설정
    1. TCP Wrapper : 시스템 유저는 VPN으로 접근한다. 유저는 VPN subnet을 가지는데, 이 VPN subnet 정보를 기준으로 TCP Wrapper룰을 만든다. VPN은 아래 따로 설명한다.
    2. IP tables
    3. 기타 접근 설정 : 원격 root 접근 금지. 로그인 실패 횟수 설정. 만료기간 설정등의 보안 설정을 한다.
  5. 보안 점검 : AMI형태로 인스턴스를 실행하는 경우가 있다. cloud-init와 chef가 인스턴스의 설정을 변경하겠지만, 이전의 설정이 남아 있을 수 있다. 사용하지 않은 유저들, 허가하지 않은 서비스 포트, 보안패치를 적용하지 않은 프로그램등이다. 예를들어 기껏 모든 시스템에 bash 보안을 적용했는데, 예전 bash를 포함한 AMI로 인스턴스를 올릴 수도 있다. 이런 것들까지 모두 검사하고, 필요한 조치를 취할 수 있다.
  6. 애플리케이션 설정 : 네트워크 환경과 지역에 따라서 애플리케이션 설정을 변경해줘야 한다.

자원에 대한 통계

인터넷 서비스를 개발하는데, 두 개 이상의 조직이 참여할 수 있다. 내가 개발 했던 인프라의 경우 빅데이터, 자연어 처리, 운영(Admin), 유저 프론트엔드 개발(Web service), Core 소프트웨어 개발팀 등 4-5개 정도의 조직이 참여했다.

이들 조직은 사실상 독립된 회사이기 때문에, 각 조직별로 자원의 모니터링, 자원의 라이프사이클 관리, 과금하기 위한 정보를 만들 수 있어야 했다. 도메인 이름에 사용한 이름 정보는 인스턴스에 태깅되는데, 향 후 과금 레포팅을 위해서 사용할 수 있다.

모니터링

모니터링 시스템은 모든 자원과 주요 서비스들을 모니터링 한다. 모니터링 결과는 중요도에 따라서 분류되고, 관련 담당자에게 통보한다. 도메인 이름을 기존으로 이벤트 정책을 수립할 수 있다.
  1. 이벤트의 중요도 : 동일한 이벤트라도 발생한 위치에 따라서 처리 정책에 차이가 생긴다. 인스턴스가 뻗었다고 가정해보자. service의 경우 즉시 운영자와 개발자 모두 SMS와 Email로 통지해야 하겠지만, staging는 Email 만으로도 충분할 것이다. DV는 알릴 필요도 없다.
  2. 통지 대상 : 도메인 별로 담당자가 정해져 있다. 이벤트가 발생한 자원의 도메인이름으로 어느 담당자에게 통지를 해야 할지를 알 수 있다.
모니터링 시스템은 이슈 관리 시스템과 연동이 되어서, 관리를 한다. 모든 과정은 자동으로 이루어지는데, 도메인 이름이 핵심 역할을 한다.

VPC를 이용한 네트워크 구성

이름 설계를 마치고 본격적으로 인프라 구성에 들어갔다.

기본 네트워크 단위 설계

아래의 요건을 만족하는 네트워크 시스템을 구축해야 했다.
  1. 격리된 네트워크위에 구성해야 한다.
  2. 필요한 최소한의 자원만 외부에서 접근할 수 있다. 이 경우 유저 서비스 서버(주로 웹서버)만 외부에서 접근가능하게 설정되어야 할 것이다.
  3. 나머지 자원은 인터넷으로 부터 격리된다. 이른바 DMZ을 구성해야 한다.
  4. 가용성 확보
VPC로 네트워크를 격리하고, 여기에 프로젝트 별로 subnet을 할당한다. 먼저 Public subnet과 Private subnet으로 나눴다. Public subnet은 Internet gateway로 직접 라우팅 된다. Private subnet은 Internet gateway를 가지지 않으며, 따라서 외부에서 직접 접근할 수 없다. Private subnet에 있는 자원에 접근하려면, public subnet을 거쳐야 한다. Public subnet이 DMZ 구간으로 작동하면서, Private subnet을 보호하는 모양새가 된다.

Public subnet에는 웹 서버등 인터넷에 직접 노출해야 하는 자원이 배치되고 Private subnet에는 WAS, Woker, Database등 격리가 필요한 자원들이 배치된다. 가용성을 확보하기 위해서 두 개의 가용성 서브넷을 만들었다. 결과적으로 4개의 subnet으로 구성된 프로젝트 네트워크가 만들어졌다.

위 요구 조건을 만족하고 있는지 검토해 보자.
  1. 네트워크를 격리하기 위해서 VPC를 사용했다.
  2. Public subnet과 private subnet으로 구성, 주요 자원을 인터넷으로 부터 숨길 수 있다.
  3. AV-Zone으로 구성 가용성을 확보 했다.

기본 네트워크와 확장

이 인프라에는 두 개 이상의 조직이 참여할 수 있다. 각각의 조직에는 그들의 프로젝트를 위한 project network를 할당한다. 이들 project network는 같은 VPC로 통합된다. 다음과 같이 확장할 수 있을 거다.

프로젝트가 추가될 때마다, 기본 네트워크에서 만든 project network를 그대로 (cloudformation을 이용)복사하면 된다. 각 프로젝트는 Security group와 subnet security group을 이용해서 완전히 격리한다.

관리 트래픽과 서비스 트래픽의 격리

VPC 네트워크에는 "서비스 트래픽"과 "관리 트래픽" 두 개의 트리픽이 흐른다. 서비스 트래픽은 인터넷 유저가 서비스를 이용하기 위해서 사용하는 트래픽이다. 관리 트래픽은 VPC 인프라와 인스턴스 자원을 관리 하기 위한 트래픽이다. 관리 트래픽에 흐르는 정보들은 아래와 같다.
  • 개발/관리자 접근 트래픽 : 개발자나 관리자는 SSH를 이용해서 인스턴스에 접근해서 작업을 할 수 있어야 한다.
  • 모니터링 트래픽 : Zabbix 모니터링 트래픽
  • Chef 트래픽 : (나중에 설명한다)어딘가 중앙에있는 chef 서버와의 트래픽
이들 관리 트래픽과 서비스 트래픽은 당연히 격리해야 한다. IDC의 경우 하드웨어들은 2개 이상의 인터페이스 카드로 구성이 되는데, 하나 이상을 관리 네트워크에 연결하기 위해서 따로 빼놓는다.

나는 VPN(가상 사설망)을 이용해서 두 개의 성향이 다른 트래픽을 격리하기로 했다.

VPN 솔류션으로 OpenVPN을 선택했다. AWS는 VPC를 위한 IPsec 기반의 하드웨어 VPN 솔류션을 제공하는데, 굳이 OpenVPN을 선택한 이유는 다음과 같다.
  • 비용을 아끼고 싶다.
  • OpenVPN에 대한 경험을 가지고 있다.
  • 관리 트래픽은 가용성이 아주 중요하진 않다. 가끔 죽어도 빠르게 복구하면 된다.(OpenVPN이 죽는 일은 거의 없다.)
  • 가용성이 필요할 때가 되면, 그때 OpenVPN을 HA 구성하면 되겠다.
VPC에 별도의 VPN subnent을 만들고 여기에, OpenVPN 서버를 만들었따. OpenVPN 서버는 Internet gateway와 연결되며, 이 VPN을 이용해서 관리 트래픽이 이동한다. 예를들어 개발자와 관리자는 VPN을 이용해서 인스턴스와 데이터베이스에 접근해서 작업을 하면 된다.

글로벌 구성

이렇게 해서 하나의 지역을 서비스할 수 있는 인프라가 만들어졌다. 이 VPC를 Region VPC라고 하자. 이제 글로벌하게 전개 해야 한다. 지금의 네트워크 정보를 Cloudformation으로 저장한다음 찍어내는 걸로 간단하게 구성할 수 있을 것 같다. 이렇게

하지만 중앙 관리라는 중요한 요소가 빠졌다. 중앙 관리가 필요한 이유를 적어보았다.
  1. Chef server : 어딘가에 chef 서버가 있어야 한다. 이 chef 서버는 전체 인프라를 관리해야 하므로 중앙에 있어야 한다.
  2. Git & CI : 소스코드는 한 곳에서 관리해야 한다.
  3. Monitering : 인프라 전체 상황을 모니터링 해야 한다.
  4. 유저 접근 통제 : 자원에 대한 중앙 접근 통제가 이루어져야 한다.
  5. 어드민 툴들 : 자원 관리를 위한 어드민 툴들이 필요하다. 주로 웹 서비스 형태로 제공될 거다. 관리자는 이 사이트에 접근해서, 빌링, 모니터링, 유저 관리, 보안정책, 프로젝트별 자원 현황, 자원 생성/삭제, 서비스 통계 등의 작업을 수행한다.
  6. 이슈추적 시스템 : 모니터링 시스템과 연계해서 인프라 이슈를 관리해야 한다.
이들 시스템과 기능을 통합하기 위해서 관리 네트워크를 구성하기로 했다. 이 관리 네트워크는 1. 흩어져 있는 region vpc에서 모두 접근할 수 있어야 하며 2. 격리된 네트워크로 구성해야 했다.

관리 네트워크는 역시 독립적인 VPC로 구성하는 것으로 인터넷에서 격리 시켰다.

관리 네트워크와 region vpc를 site-to-site VPN으로 연결했다. Site-to-site VPN 구성은 VPN 구성, VPC 보안, VPC 관리 전략 문서를 참고하자. 이제 각 지역에 흩어는 region vpc는 VPN을 통해서 Git, Zabbix, Chef, Jenkins, ssh 트래픽을 교환할 수 있게 됐다.

아직 끝이 아니다. 개발자와 관리자가 ssh로 접근하기 위한 네트워크 경로가 아직 뚫리지 않았다. 유저와 각 region vpc를 host-to-site 으로 연결하는 방법이 있지만, 이미 VPN으로 서로 묶여있는 와중에 또다른 통로를 뚫는 건 좋은 생각이 아니다. 유저의 접근도 중앙에서 관리할 수 있어야 한다. 나는 관리 네트워크에 유저 접근을 위한 VPN을 하나 더 만들기로 했다. 유저와 관리 네트워크는 host-to-site 방식으로 연결한다.

이제 유저는 vpn으로 관리망에 연결하는 것으로 모든 네트워크에 투명하게 연결할 수 있게 됐다.

마지막으로 접근 권한에 대한 정책을 설계해야 했다. 관리 네트워크에는 Dev, Staging, Service 네트워크가 함께 묶여있는데, 유저별로 접근할 수 네트워크를 제한해야 했다. 예컨데 일반 개발자는 service에 접근할 수 없도록 제한을 해야 했다. 두 가지 방법을 고려했다.
  1. 네트워크를 아예 격리한다 : Dev & Staging로 연결되는 VPN을 하나 만들고, Service VPN을 하나 더 만드는 방식이다. Service 자원에 접근하려면 Service VPN 접근 권한을 획득해야 한다.
  2. 유저 정책으로 제한 한다 : Dev와 Staging에 대해서는 개발자 일반계정에 sudo root 권한을 준다. Service VPN에는 일반계정 권한만 주고, 요청이 있을 경우 특정 기간에 한해서 sudo 권한을 허가한다.
1번 방법은 네트워크를 완전히 격리할 수 있다는 장점이 있지만, 쓸데 없이 복잡해진다는 단점이 있다. 그래서 2번 방법을 선택하기로 했다. 굳이 네트워크 단에서 유저 접근 제어가 필요하다면, 유저에게 부여된 static ip를 기반으로 security group을 변경하는 방법을 사용할 수도 있겠다.

기타 인프라 구성 요소들

이렇게 만들어진 인프라 설계도를 바탕으로 인프라를 구축했다. 구축한 인프라가 제대로 굴러가기 위해서는 인프라에 걸맞는 툴들과 정책의 도움이 필요하다. 기타 인프라 구성요소들을 정리했다.

유저 관리 시스템 과 보안 정책들

인프라에 접근하려면 유저는 Global Network에 접근하기 위한 권한 과 AWS 자원들(인스턴스, 데이터베이스등)에 접근하기 위한 권한을 획득해야 한다.

이들은 모두 Chef를 이용해서 관리한다. Chef는 각 단계(dv ~ service)별로 접근할 수 있는 네트워크 정보, VPN IP, 유저 이름, 연락처, Linux account, ssh key, sudo 권한, 유효 시간 등에 대한 정보를 가지고 있다.

유저들에게는 static IP가 할당되는데, 유저가 VPN과 인스턴스에 접근할 경우 그 기록을 남긴다. 이 기록을 이용해서, 유저의 접근을 추적할 수 있다.

보안에 대한 좀더 자세한 내용은 AWS 보안을 참고하자.(여기에도 단편적인 정보들 밖에 없긴 하다. 시간을 내서 좀 자세히 정리해야 겠다.)

모니터링 시스템

모든 인스턴스에는 zabbix agent가 설치되서 모니터링 된다. 모니터링 결과로 발생한 이벤트들은 중요도에 따라서, SMS, Email, Jira로 발행해서 관리 한다. Zabbix에 대한 내용은 Zabbix, Zabbix를 이용한 AWS 모니터링문서를 참고하자.

이슈를 Jira로 발행하기 위해서는 Jira API를 이용해서 매쉬업 서비스를 만들어야 한다. 이에 대한 내용은 Jira를 이용한 매쉬업 서비스 개발문서를 참고하자.

작업 요청 시스템

자원의 생성과 삭제/설정 변경, VPN 권한, Linux Account 작업, CS처리, 인프라 이슈 처리 등은 Jira로 통합해서 처리하도록 했다. 여러 조직이 함께 하는 이런 시스템에서 Jira와 같은 업무지원 시스템이 당연히 있어야 하는 것 아니냐고 반문할 수 있겠다. 하지만 소프트웨어 중심 업체가 아닌 곳에서의 Jira 시스템 적용은 그 자체가 하나의 과업이다.(경험해 본 사람은 이해할 것이다.) 여러번의 시행착오를 거치면서 정착시켰다.

그리고 Chef

이 모든 것에 중심에 Chef가 있다. Chef가 없으면 관리할 수 없는 시스템이다. chef에 대한 내용은 Chef를 이용한 클라우드 자동화문서를 참고하자.

정리

핵심

이름 정책이 핵심이라고 생각한다. AWS 클라우드를 활용하기 전에는 클라우드 시스템을 구축하는 일을 했었다. 그때도 가장 먼저 한 일이 "이름 정책"만들기 였다.

이름정책 만들기가 효율적인 이유는 "인지하기가 굉장히 쉽고, 단순하기" 때문이다. 설계는 사람의 인지능력을 실험하는 무대인데, 좋은 설계를 가로막는 가장 큰 장애물은 "한눈에 들어오지 않는 복잡한 단어와 복잡한 기술, 복잡한 구성"이다. 한눈에 들어오지 않는 어떤 대상은 인지하기가 쉽지 않다. 이름은 "단순하게"시작 할 수 있도록 도와준다.

다른 녀석들은 이름 정책대로 구현되도록 거들어 줄 뿐이다. 초기에 작게 시작하더라도 이름 정책만 잘 정의해 놓으면, 쉽게 확장할 수 있다. (그럴 수 밖에 없다. 이름에 형상정보가 다들어가니까.)

  1. 모든 서비스는 가용성, 확장성, 보안을 만족해야 한다.
  2. 위의 3 요소를 만족하려면, 제대로된 관리 시스템이 구성되야 한다.
  3. 자동화, 모니터링, 이슈추적, 정보관리가 Name 정책을 기반으로 유기적으로 묶여야 한다.

구축과 운영의 난이도

지나치게 복잡한 인프라 구성이라고 생각할 수도 있겠다. 하지만, 결코 복잡하지 않다. VPC 구성하는 것은 AWS 메뉴얼 보면서 따라하면 되고, VPN도 몇번의 시행 착오를 거치면 어렵잖게 구성할 수 있다. Chef, Zabbix, Git, jenkins, zookeeper ... 등등은 제대로 인터넷 서비스를 하려고 마음먹는 다면, 당연히 구축해야 하는 필수 요소가 된지 오래다.

구축도 어렵지 않다. IDC에 구축하는 거라면 개인은 엄두도 못내겠지만, AWS라면 혼자서도 구축할 수 있다. 내 경험을 공유하자면 한명이 한달 동안 인프라 설계를 했고, 한명이 한달 동안 기본적인 구축을 끝냈다. 한달이면 꽤나 오랜 시간 설계를 했다고 생각할 수 있겠는데, 설계에 투입한 시간 보다, 다른 조직과 설계를 설명하고 동의를 얻는데 더 많은 시간이 들어갔다(요구 사항을 만족해야 하니까.). 그 한달 동안 설계한대로 돌아갈지를 확인하기 위한 프로토타이핑을 함께 진행 했다.

구축이 끝난 후 운영은 2명이 하고 있다. 단 두명으로 4개 이상의 조직으로 구성된 글로벌 인프라에 대한 보안정책 적용, 유저관리(VPN/Linux 계정 생성, 계정 삭제, Sudo 승급), 자원 관리(생성, 삭제), 모니터링, 각종 관리 툴 개발을 하고 있다. 나는 사실상 손을 뗀 상태다. 애초에 목적이 설계자의 개입없이 스스로 돌아가는 시스템을 만드는게 설계 목적의 하나이기도 했다.

적은 비용으로 큰 효과를 얻을 수 있다는 이야기다.

Devops

린 공정은 산업을 완전히 재편했다. 린 공정의 핵심은 "불필요한 단계를 줄이고 압축"해서 업무의 효율성을 높이는데 있다. 린 공정이 소프트웨어에 발전적으로 적용된게 애자일이고, 운영, 관리, 개발 전 공정에 적용된게 DevOps다. 클라우드는 인프라와 운영, 개발을 모두 압축하는 시스템으로 근본적으로 DevOps적인 관점에서 접근을 해야 한다.

즉 인프라 설계, 구축, 개발, 운영이 하나의 팀처럼 압축운영을 해야 제대로 활용을 할 수 있는 시스템이다. DevOps를 위해서는 아래와 같은 시스템의 구성이 필수적이다.

정보의 투명한 공유와 이를 지원하기 위한 시스템

시스템/서비스 정보, 모니터링 정보, 이슈, 업무 프로세스가 모두 공개되는 시스템의 개발이 필요하다. 특히 이슈 관리 시스템의 활용이 중요하다. 일반적으로 서비스 운영자와 개발자, 인프라 운영자는 관심 정보가 다르다고 생각하기 때문에, 정보 공유에 소홀한 경우가 많다. 이슈 관리 시스템을 이용해서 정보흐름을 원할하게 할 수 있다.

예를들어 고객 서비스 이슈는 다음과 같이 처리하고 있다.
  1. 고객은 웹이나 앱에 내장된 CS폼을 이용해서 요청사항(서비스 불편, 에러 등등)을 전송한다.
  2. 이 메시지는 Jira Ticket과 Email로 서비스 운영자에게 전달된다.
  3. 서비스 운영자는 자신이 처리할 수 없는 이슈의 경우 담당 개발자와 인프라 운영자에게 Ticket을 Assign 한다.
  4. 담당 개발자와 인프라 운영자는 협업해서 문제를 해결하고 Ticket을 Resolve 한다.
  5. 서비스 운영자는 (필요할 경우) 테스터에게 Ticket을 Re Assign해서 문제가 해결됐는지를 확인한다.
  6. 마지막으로 서비스 운영자가 고객메일을 작성하고, Ticket을 Close 한다.
고객과 서비스 운영자, 개발자, 인프라 운영자, 테스터를 하나의 시스템으로 묶을 수 있다. Jira 도입하자. 두번도입하자.

자동화

자원생성에서 회수, 이슈의 발생과 처리, 서비스 배포 모든 과정이 자동화 되야 한다. 자원을 생성은 구두가 아닌, 시스템을 통해서 이루어져야 한다. 역시 Jira가 중심에 있다. Jira를 이용해서 자원생성의 요청하면, 인프라 담당자는 요청정보를 확인해서 자원을 생성한다. 이 과정은 chef로 자동화 된다.

퍼블릭 클라우드의 미래에 대해서

아직까지 비 인터넷 서비스 기업들은 퍼블릭 클라우드에 대한 인식이 그다지 좋지 않은 것 같다. 그렇다고 클라우드의 장점을 버리기도 힘드니, 하이브리드 클라우드나 프라이빗 클라우드의 도입을 고민하고 있다. 나는 하이브리드 클라우드나 프라이빗 클라우드는 과도기로 보고 있다. 결국에는 기존의 다른 기업 자원들이 소유에서 대여로 넘어갔던 것처럼, 인터넷 자원도 퍼블릭 클라우드로 넘어갈거라고 보고 있다.