UBUNTU 18.04 KVM 게스트에 콘솔 접속하기

KVM 가상화를 사용하고 있고 게스트로 Ubuntu18.04 를 사용하고 있다면 콘솔 접속을 위해서는 다음과 같이 해주어야 한다.

/etc/default/grub 편집

grub 에서 ttyS0 에 콘솔 접속이 되도록 다음과 같이 편집해 준다.

위와같이 편집을 한 후에 grub 을 다시 작성해준다.

위와같이 설정을 하고 재부팅을 한 후에 KVM 콘솔 접속을 하면 아주 잘 된다.

외부MySQL 에서 AWS Aurora로 마이그레이션

데이베이스 이전은 매우 중요한 작업이다. 다른 IT 인프라와는 다른 속성을 가진 데이터베이스를 물리적 공간도 다른 곳에 옮기기는 쉬운 일이 아니다. 더군다나 데이터베이스는 모든 IT 비지니스에 핵심으로 사업 성공에 성패를 가르기도 한다.

AWS 를 사용하다보면 데이터베이스 이전 작업을 종종 겪게 된다. 처음부터 AWS 에서 제공하는 DaaS 인 RDS, Aurora 를 사용한다면 별 걱정이 없겠지만 AWS도 아닌 일반 IDC 의 데이터베이스를 AWS RDS, Aurora 로 옯기기는 매우 힘든 작업이다.

외부 MySQL 에서 RDS로 마이그레이션 하기
외부 MySQL 에서 RDS로 마이그레이션 하기

한마디로 말하면 답이 없는 작업이다. AWS 의 모범사례를 보면 이렇게 외부에MySQL 데이터베이스가 존재할 경우에 mysqldump 명령어를 이용해서 데이터를 Export 한 다음에 AWS RDS, Aurora 에 데이터를 Import 하고 외부MySQL(Master) – AWS RDS,Aurora(Slave) 로 묶어 둔 후에 Application 에서의 작업을 통해서 최종적으로 AWS RDS Aurora 만 사용하도록 하고 있다.

외부MySQL 과 RDS 의 리플리케이션 연결
외부MySQL 과 RDS 의 리플리케이션 연결

문제는 용량이다. 만일 외부MySQL 데이터베이스의 용량이 10TB, 아니 4TB 라고 해보자. 그러면 4TB 를 덤프 뜨는 시간이 얼마나 걸릴지 예상하기도 쉽지 않다. MySQL 은 데이터를 덤프 뜨는 동안 테이블을 잠그기 때문에 그동안 서비스를 중단해야 한다.

서비스 중단없이 어떻게 데이터 이전을 할것인하는 건 모든 사업자라면 하는 고민일 것이다.

Netflix 도 이에 대한 고민을 했던 것으로 보인다. 더군다나 외부데이터베이스 시스템이 Oracle 이고 이전하고자하는 데이터베이스가 MySQL 이라면 데이터 변환작업도 함께 진행되어야 한다. 거기다 무중단 서비스…

Netflix 의 이러한 고민은 다음의 기사로 나왔는데, 결론은 Oracle 의 Golden Gate 를 이용했다는 것이다. OGG 라고 불리우기도하는데, 개인적인 경험으로 매우 훌륭한 툴이다. OGG 와 같은 동일한 역할을 하는 소프트웨어가 여럿 존재할 것이다.

핵심은 외부 데이터베이스를 AWS 로 이전하려고 할 경우에 서비스 무중단을 원한다면 OGG 와 같은 프로그램을 이용하는게 답이라는 거다.

만일 무중단 데이터 이전을 자체적으로 하기 힘들다면 국내에 데이터베이스 기술지원을 하는 업체를 돈을 들여서라도 이용하는 편이 낫다. 괜히 능력도 안되는데 의지만 앞선 나머지 일을 진행하다가 데이터 손실이라도 발생하면 사업에 아주 심각한 영향을 줄것이기에 데이터베이스 만큼은 확실한 방법이 요구된다.

AWS Aurora Endpoint and WAS Connection Pool

Abstract

AWS Aurora 는 DB Cluster 로 구현된다. DB Cluster 는 Aurora 인스턴스와 Endpoint 를 포함한 일종의 그룹 개념이다. 이 DB Cluster 에는 1개의 Primary 인스턴스와 15개의 Replica 를 가질 수 있다.

각각의 구성에서 접속이 가능한 지점은 다음과 같이 3가지가 있다.

  • Cluster Endpoint
  • Read Replica Endpoint
  • Instance Endpoint

이러한 Endpoint 와 Aurora 인스턴스 그리고 Primary, Replica 를 조합한 아키텍쳐는 다음과 같다.

AWS Aurora Architecture
AWS Aurora Architecture

Cluster Endpoint

Cluster Endpoint 는 Aurora Cluster 에서 현재 Primary 인스턴스에 접속하기 위한 Endpoint 이다. 모든 Aurora Cluster 는 반드시 하나의 Primary 인스턴스와 이를 연결하는 Cluster Endpoint 를 가진다.

Primary 인스턴스는 Insert, Update, Delete 그리고 DDL(Data Definition Language) 에 관한 모든 쓰기 연산을(write operation) 지원하며 데이터 읽기 연산인 Select 도 지원한다. Cluster Endpoint 는 read/write 를 연산을 제공하는 Primary 인스턴스 접속을 제공한다.

Cluster Endpoint 는 read/write 접속에 대한 자동 FailOver 를 제공한다. Primary 인스턴스에 문제가 발생하면 Replica 인스턴스 중 하나를 Primary 인스턴스로 선택한다. Cluster Endpoint 는 DNS 를 이용해 기존의 Primary 인스턴스의 도메인을 버리고 Replica 인스턴스로 변경한다. 이렇게 함으로써 Cluster Endpoint 도메인 주소는 변경없이 계속 유지 된다. Cluster Endpoint 에서 새로운 Primary 인스턴스로 지정된 Replica 인스턴스는 read/write 역할을 위해서 Primary 인스턴스로 승격된다.

Reader Endpoint

Reader Endpoint 는 Aurora Replica 중에 하나와 연결된다. Aurora Replica 는 읽기 연산(read operation) 만 지원하기 때문에 Reader Endpoint 는 읽기 전용 연결지점이 된다.

만일 Aurora Replica 가 한개 이상이라면 Reader Endpoint 는 Load Balancing 을 지원한다. 각각의 연결은 Round robin 방법으로 Replica 인스턴스 하나와 연결이 되어 연결에 따른 부하가 분산된다.

Instance Endpoint

Aurora DB 를 생성은 결국 Instance 를 생성하게 된다. 모든 Aurora 에 인스턴스는 Endpoint 를 가지는데 이게 Instance Endpoint 이다. 모든 Instance 는 타입과 관련없이 유일한 Instance Endpoint 를 가진다.

이 Instance Endpoint 는 도메인 이름으로 불변이며 Cluster Endpoint, Reader Endpoint 에 CNAME 으로 등록되어 이들의 연결지점으로 사용되어 진다.

WAS Connection Pool

이제 WAS 에서 AWS Aurora 접속을 위한 설정에 대해서 이야기 해보자. WAS 서버가 무엇이든 AWS Aurora 접속을 위해서는 MySQL, MariaDB Connector/j 드라이버를 사용해야 한다.

그런데, Aurora Cluster 를 구성할 경우에 Primary 인스턴스와 Replica 인스턴스로 구성하고 Endpoint 를 각각 Cluster, Reader 로 구성하게 될 것이다. 이렇게되면 WAS 에서는 이를 분산해서 접속해야 할 필요가 생긴다.

MySQL, MariaDB 는 이렇게 read/write 접속과 read only 접속을 분리해서 연결하도록 하는 기능을 제공하는데 이를 Smart Driver 라고 부른다.

한가지 먼저 짚고 넘어가자면, AWS Aurora 를 사용할 경우에는 MariaDB Connector/j 드라이버를 사용할 것을 권장하고 있는데, MariaDB Connector/j 드라이버는 Aurora 를 공식적으로 지원한다.

MariaDB Connector/j 드라이버를 이용해 Cluster Endpoint, Reader Endpoint 를 설정하는 방법은 다음과 같다. (Tomcat 기준 JNDI 설정이다)

이렇게 Cluster Endpoint, Reader Endpoint 주소를 연속해서 주면 된다. 이렇게하면 서버단에서 접속 설정은 끝이난다.

하지만, 이렇게 서버단에서의 설정만으로 접속이 분리되는 것은 아니다. Spring MVC 기준으로 말을 하자면 Transactional 의 ReadOnly 프로퍼티를 준 경우에만 Reader Endpoint 로 접속이 이루어지고 이외에는 전부 Cluster Endpoint 로 접속이 이루어진다.

Spring MVC 에서 이것을 각각 지정하기보다는 TX, AOP 설정을 통해서 한꺼번에 설정이 가능하다.

위와같이 했을 경우에 get* 으로 시작하는 메소드 이름을 가진 Service 빈에서 Read-Only 속성을 부여해 Reader Endpoint 로만 접속하도록 하게 할 수 있다.

마지막으로 고려해야할 것이 한가지 더 있는데, Connection Pool 의 경우에는 접속/해제에 대한 오버헤드를 줄이기 위해서 미리 연결을 해놓는 경우인데, 만일 Aurora FailOver 기능을 사용할 경우에 기존의 Fail된 인스턴스와 연결을 계속 유지하는 경우가 생긴다.

Cluster Endpoint FailOver
Cluster Endpoint FailOver

Replica Role 이 승격되서 새로운 Primary Role 이 되면서 Read/Write 역할을 수행하게 되는데, 이때 Cluster Endpoint 의 DNS 의 CNAME 이 변경된다. 하지만 WAS 서버의 Connection Pool 은 장애가 발생한 기존 Primary Role 인스턴스를 가지고 있게 된다.

MariaDB Connector/J 드라이버에는 이를 위해서 SOCKET_TIMEOUT 값을 두고 있다. Aurora 의 경우에는 10000ms 로 10초 동안 접속이 이루어지지 않을 경우에 Socket Timetout 으로 간주해 FailOver 로직을 수행한다.

Socket Timeout 은 JDBC 드라이버 측에서 설정을 해줘야 한다. 이는 대부분 URL 에 파라메터로 지정하는데, 다음과 같이 할 수 있다.

MariaDB connector/J 에서 connectTimeout 기본값은 0이며 socketTimeout 의 경우 Aurora 일 경우 10000ms 로 되어 있다. 이정도면 MariaDB Connector/J 를 사용하는데 있어서 별도의 설정을 해주지 않아도 될 정도다.

AWS Aurora With MySQL

AWS Aurora(오로라) 는 AWS RDS 서비스 중에 하나 이다. 다른 RDS 서비스들은 기존 오픈소스, 상용 데이터베이스를 이용해 만든 반면에 Aurora 는 AWS가 자체 개발한 데이터베이스이다.

AWS RDS 는 Database-as-a-service (DBaaS) 인데, 이는 데이터베이스 관리에 많은 부분을 AWS가 알아서 해준다. 예를들면 데이터베이스 서버운영, 버그 패치, 이중화, 자동 FailOver등이며 웹 콘솔을 이용해 사용자의 각종 설정들을 처리해는 서비스다.

이 글은 AWS Aurora, 그중에서 MySQL Engine 에 대해서만 간단히 정리한 것이다. 이 글은 AWS Aurora 전부를 담고 있지 않음을 주의해야 한다.

Aurora MySQL Engine

Aurora 는 2가지 엔진(PostgreSQL, MySQL) 을 호환 엔진을 가진다. MySQL 호환 엔진의 경우에 MySQL 메이저 버전별로(MySQL 5.6, 5.7) 또 나뉜다.

Aurora MySQL 엔진을 이해하기 위해서 먼저 MySQL 를 간단히 살펴보자.

MySQL Architecture

기존의 MySQL 이중화 아키텍쳐는 다음과 같다.

MySQL With Replica On AWS
MySQL With Replica On AWS

AWS RDS MySQL 인데, 일반적인 MySQL 의 Replication 도 위와 동일 하다. 이 그림이 설명하는 특징은 다음과 같다.

  • MySQL 서버들은(Primary, Replica) 자신만의 Storage 를 가진다.
  • Storage 는 EBS Storage 이다.
  • Replica Instance 는 Primary Instance 로부터 Binary log 를 전송받아 이것을 Relay 해 데이터를 복제한다.

AWS RDS MySQL 서비스조차도 MySQL이 제공하는 복제방식을 그대로 사용했기 때문에 On-Demand 의 MySQL Replication 아키텍쳐와 동일하다.

이런 아키텍쳐 운영에서 문제는 추가적인 Replica 구성에 있다. 추가적인 Replica 를 더했을 경우에 기존 데이터를 전부 덤프를 뜨고 Restore 해준다음에 Position 값을 맞춰줘야 한다.

거기다 Replica가 바쁜 상태일때에 Binlog Relay가 느려지는 Replication Lag 현상도 문제다. Primary 에 추가된 레코드가 한참이 지나도록 Replica 에서 조회가 안될 수도 있다.

Aurora Architecture

AWS Aurora Architecture
AWS Aurora Architecture

AWS Aurora 아키텍쳐로 특징은 다음과 같다.

  • Storage 는 모든 인스턴스에 공유 된다. .
  • Storage 는 EBS 가 아닌 Distributed Virtual Volume Storage 다.
  • Redo Log 만 전송된다.
  • Pallarel Query 를 지원한다.

Aurora MySQL 특징

가장 큰 차이점을 살펴봤는데, 이외에도 몇가지 차이가 존재한다.

  • Multi-AZ 를 지원하지 않는다. – 오해의 소지가 있는데, 기존의 Multi-AZ 는 내부 StandBy 서버를 말했었다. 하지만 Aurora 는 Muti-AZ Deployment 를 할 경우에 내부 StandBy 서버 없이 Read Replica 가 AZ 로 생성되면서 이 역할을 대신한다. 용어의 혼돈이 존재하는 부분이다.
  • MySQL 의 Single thread connection 방식인데, Aurora MySQL 은 Dynamic 방식이다. 내부적으로 Epoll Multiplex 를 사용한다.
  • 사용할 Storage 용량을 정하지 않아도 된다. 10GB 씩 최대 64TB 까지 자동으로 늘어난다. (AWS RDS MySQL 의 경우 EBS 한계치인 16TB 까지다.)
  • Replica 에 대한 LoadBalancer 를 지원해 이중화를 지원한다. 이를 위해서는 읽기전용 Cluster Endpoint를 사용해야 한다.
  • FailOver 시에 Read Replica 중에 하나를 Primary Role 로 승격 시킨다. Primary Cluster Endpoint 를 사용하면 접속지점 변경이 없다.

중요한 특징들도 존재한다.

  • Aurora DB Cluster 역추적(Backtrack, 되감기)

보통의 DB 에서 특정 시점으로 되돌리기 위해서는 백업본을 이용해 Point-In-Time 복원을 수행해야 한다. AWS RDS 의 경우 특정 시점의 백업을 이용해 복원해 새로운 DB 클러스터를 만들어 내는데 이것이 Aurora DB 클러스터 백업 및 복원에 대한 개요 다.

Aurora DB Cluster 역추적은 백업/복원 과정이 아닌 데이터베이스를 특정시점으로 되감는 것이다. 새로운 DB 클러스터는 생성되지 않는다.

역추적 기능이 활성화된 상태에서 생성한 DB 클러스터에서만 역추적이 가능하다. (새 DB 클러스터를 만들 때, DB 클러스터의 스냅샷을 복원할 때, DB 클러스터를 복제할 때) 역추적 기능이 비활성화된 상태에서 생성한 DB 클러스터에서 역추적이 불가능 하다.

역추적이 활성화된 Aurora DB 클러스터를 업데이트하면 변경 레코드가 생성된다. Aurora은 대상 기간에 대한 변경 레코드를 보존하며 이 레코드를 저장하기 위해 시간당 요금을 지불한다.

  • Aurora Storage IOPs 는 오직 Aurora 의 인스턴스 타입에 따른다.

AWS RDS MySQL 의 경우에 EBS Storage 를 사용하기 때문에 IOPs 를 따로 결정할 수 있다. 하지만 AWS Aurora 의 경우에는 Storage 타입이 존재하지 않음으로 인해서 IOPs 는 인스턴스 타입에 따른다.

결과적으로 빠른 IOPs 가 필요하다면 Aurora 인스턴스 타입을 업그레이드 해줘야 한다.

  • Global Database 지원 – Region Replica 를 지원 한다.

Region 간 복제를 지원하는것인데, 현재 3개 지역만 지원한다.

  • Multi Master Replica

현재 Preview 단계에 있다. 언제 정식 서비스 될지는 모르지만 Preview로 맛을 볼수는 있다.

  • Free Tier 를 제공하지 않는다.

AWS Aurora 는 Free Tier 를 제공하지 않는다. 공자 사용 안된다는 이야기.

  • T2 타입에서 Performance Schema 활성화 안됨

적용 Capacity 를 가진 타입의 경우에 Performance Schema 활성화가 안된다.

AWS Aurora 비용

선택한 옵션에 따라서 추가 비용 부담이 있지만 기본적으로 가장 많은 비용이 들어가는 것으로는 다음과 같다.

  1. Storage I/O 요금 – 1백만 건당 0.22 USD
  2. 스토리지 요금 – 월별 GB 0.11 USD
  3. Global Database – 복제된 쓰기 I/O 백만 건당 0.22 USD

Storage I/O 요금을 주의해야 하는 것은 데이터 이관시다. AWS Aurora 로 데이터베이스를 바꿀려고 할 경우에 데이터를 부어야 하는데, 이때 대량의 Storage I/O 가 발생하게 되며 고 비용을 물어야 한다. – 처음부터 AWS Aurora 를 선택하는게 좋을 수 밖에..

[펌]코딩하는 아내

나는 프로그래머의 아내다.

결혼한지 2년이 되었다. 오늘 남편과 나는 근사한 식당에 가서 맛있는 식사를 했고, 꽃다발도 선물로 주었다.

공대생 혹은 프로그래머는 보통의 여자들에게 인기 없는 부류의 사람일 수 있다. 부드러움, 따듯함, 이해심을 느끼기 어렵고, 공감 제로, 차갑고 논리적인 사람이라는 인상을 준다. 그래서 소개팅 후에… 몇 번 만나보고나서.. 아 별로야.. 이 사람 자상하지 않아.. 하고 만남을 그만두는 사람들 이야기를 들으면 한숨이 지어진다.

사실 프로그래머의 아내, 여자친구로 있는다는 것은 아쉬운 때도 있겠지만, 매우 매력적인 자리이다.

일례로, 집에서 ‘쿵’ 하는 굉음이 나며 내가 ‘아야!’ 하는 비명을 질렀다고 하자. 남편은 들여다보지도 않고 하던 일 계속 한다. 못들은 것이다. 뭐…. 자상함이고 배려심이고.. 뭔가 꼬인 마음이 있거나 한 것이 아니다. 무언가에 집중해있어서 단지 못들은 것 뿐이다.

실수가 많은 나는 자주 다친다. 부딪히고 까지고 지금은 발목 타박상을 입어 근육파열로 붕대를 감고 있다. 그런 내가 어디가 아파하면.. 교제할 시절의 남편은 슬쩍 보고 지나갔다. 아무것도 아니네.. 라고 생각한 것이다. 나는 서러웠다. 죽을 병이 아니어도.. 여자는 공감 받고 싶고, 위로 받고 싶다. 몇번의 아쉬움 끝에.. 나는 이야기를 했다.

나: 오빠! 내가 아플 때 걱정해주면 안돼?

남편: 나 걱정해. 걱정하는데? 아~~ 걱정된다.

나: 아니 그거 말고 정말 진심으로 걱정하면 안돼?

남편: 아니 뭐!! 그게 도대체 어떻게 하는건데?

나: (순간 고민…) 나라면.. 이렇게 하겠어. “으~~~~ 어떡해… 괜찮아?”

그 이후로 오빠는. 단 한번도 레파토리가 바뀌지 않은 채 ‘으~~~ 어떡해.. 괜찮아?’ 를 기계적으로 해준다. 단 한번의 응용도 없었고 순서가 바뀐 적도 없다. 하지만 나는 내가 원하는 걸 얻었다. 공감의 말…

여자는 요구가 어렵다.
알아서 해주길 원한다.
기념일엔 아라서 꽃다발 사줬으면 좋겠고…
알아서 케익 사왔으면 좋겠고…
알아서 데려다줬으면 좋겠다.
은근히 기대하고.. 기대대로 안 되면 실망한다. 그래서 혼자 삐지고 툴툴댄다.
하지만 남자 입장에서 말 안하고 꽁하고 있으면? 절대 모른다.
절대로 남초 집단에서 퀴즈와 과제로 밤을 꼴딱꼴딱 새는 남자집단에서 그런 여자 마을을 알리가 없다.
헛된 기대 금지.
그들이 특별하게 차가운 인간인 것이 아니다.
그들은 단지 모를 뿐이다.

프로그래머랑 사귄다는 것은 이런 점에서 그 매력을 십분 발휘한다. 그들의 습득력은 정말 놀랍다. 코딩을 해주면 정말 그것대로 반응한다. 그래서 나는 이런 저런 코딩을 한다.

오빠. 집에 들어오면 나한테 인사를 해.

오빠. 결혼 기념일에 꽃을 사줘.

오빠. 음식점에서 음식이 나오자마자 혼자 먹지 말고. 한번쯤 나 한입 먹여줘

이럴땐 이렇게.. 저럴때 저렇게…

몰라서 그렇지, 코딩해 주고 그게 이해가 되면 그대로 해준다. 그래서 뿌듯함까지 느낄 수 있다.

하루종일 컴퓨터와 대화하며 논리적 사고가 익숙해있는 남편과 이야기할 때면 가끔 기계랑 대화하는 것 같은 느낌이 들때가 있다. 하지만 기계의 장점이 있다. 예상이 가능하다.

남편은 가끔, 집에 신나서 달려온다.

혜린아!! 내가 오늘 하루종일 한게 뭔줄 알아?

봐봐!! 여기 이렇게 누르면 폴더가 스르륵 커지지?

이거 내가 한거야!! 멋지지?

사실 그 폴더가 스르륵 커지든 화들짝 커지든 아니면 안 커지든.. 나는 별로 관심도 없고.. 변화도 모르겠는데…

그들의 기쁨의 원천은 자신이 이룩한 결과물에 대한 인정이다. 이럴 땐 활짝 웃으며 멋지다!!! 어떻게 이런 걸 다 했어? 라고 해주면 또 신나서 달려 나간다.

그러므로 결론은?
프로그래머. 꽤 괘찮은 남편감이다. 아니, 훌륭하다.
다른 직업만큼 술 약속도 없고. 가정적이며 열정적이다!
그러니까 공대생. 프로그래머의 매력을 느껴보기 전에..
섣불리 여자 맘 모른다고 차버리지 말자.
그들은 순수한 것이다. 단지 그 순수함에 하나씩 코딩을 해주면 된다.
그러면 100 퍼센트 완벽한 남자친구. 남편이 될 수 있다. 남편 최고!

코딩하는 아내

어느 프로젝트의 면접 후기

지난주에 어떤 프로젝트를 위해서 면접을 봤다. 최근에 이슈가 되고 있는 어느 업체의 클라우드로 마이그레이션을 진행하는 프로젝트였다. 면접을 보는 내내 답답함 뿐이였다. 물론 그런 답답함은 그쪽도 느꼈는지, 자신들이 찾는 사람이 아닌거 같다는 말로 갈음했다.

클라우드내 있는 서비스들은 수백가지가 넘는다. 하지만 큰 카테고리로 혹은 덩어리로 분류를 할 수 있는데, 최근에 이슈가 되고 있는 IoT, Big Data, AI, Micro Service 그리고 내가 레거시(Legacy) 라고 여기는 전통적이고도 일반적인 서비스들로 나뉜다.

문제는 모든 것을 다 속속들이 다 알 수는 없다. 예를들어, 데이터베이스 서비스로 RDS 서비스와 Aurora 서비스가 있다. 만일 어떤 프로젝트를 수행함에 있어서 RDS 를 사용해봤다고 Aurora 는 그져 한번 검토하는 정도에서 끝났다고 치면 Aurora 에 대한 경험은 없는 것이다.

클라우드로 마이그레션을 하기 위해서는 한 두가지 서비스를 알아야하는 일도 아닐텐데, 그 많은 것을 다 알기도 힘들지만 그것의 내부 옵션이나 한계치를 모두 알고 있는 것은 이론적으로 머리속에 암기하는 수준으로는 안된다.

답답함은 차라리 어떤 서비스 영역에 대해서 집중적으로 물어봤으면 좋았을 텐데하는데 기인한다. 그런데, 이런 저런 서비스들에 대해서 알고 있는지를 물어보는데, 내가 신도 아니고….

또 다른 답답함은 Kinesis 물음 있었다. Kinesis 는 AWS 에서 제공하는 데이터스트림 서비스다. 이들이 동작 방법은 Shard 라고 불리는 블럭단위의 격리공간에 파티션키를 기반으로 데이터 스트림이 기록된다. 이렇게 기록된 데이트를 레코드(Record) 라고 한다.

문제는 Shard 에 대해서 알고 있냐 없냐와 적정 Shard 를 어떻게 나눌 거냐 하는 거다. 이거는 단순 계산식이 존재한다. 초당 1,000 에 1MB 이다. 그러면 초당 몇건이 들어오는지에 따라서 Shard 를 정하면 된다????

내가 기대했던 질문은 Shard 을 얼마나 정하는가가 아니라 Shard 를 늘리고 줄이는데 어떻게 할 거냐 하는데 있다. AWS 는 Elastic 아키텍쳐를 지향한다. 거기다 비용을 고려하게되면 데이터 양에 따라서 Shard 의 갯수를 늘렸다 줄였다 할 수 있어야 한다.

당연히 Kinesis 는 이를 지원하는데, 한가지 함정이 있다. Kinesis 의 Shard 의 증가는 단순하게 Shard가 추가되는 것이 아니라 부모 사드를 분리(Split) 된다. A Shard 가 열심히 데이터를 받는 상황에서 2개의 Shard 를 추가한다면 2개의 Shard 가 추가되고 A Shard 를 부모, 2개는 자식으로 관계를 맺는다. 2개의 자식이 추가되는 순간부터 부모 A Shard 에 데이터는 쌓이지 않는다.

문제는 A Shard 에 데이터를 자식에게 자동으로 넘겨주지 않는다. 프로그램에서 A Shard 에서 데이터가 남아있는지 검색해서 소비시켜줘야 한다. 여분의 Shard 를 없이기 위해서 병합을 할때도 이는 마찬가지다.

이것을 어떻게 할 것인가? Kinesis 는 AutoScaling Shard 가 안되는 건가? (된다.)

Kinesis 를 설계할때 핵심은 Shard 갯수라고 하기 어렵다. 대~~~충 적당한 갯수로 놓고 그때 그때 Shard 갯수를 조절할 수 있어야 한다. Shard 의 갯수는 돈이다. 24시간 거의 편차가 없이 초당 데이터 갯수가 들어온다면 문제가 안되지만 낮에는 100만건, 밤에는 1천건 들어오는데 100만건에 맞춰 Shard 갯수를 정할 건가?

Aurora … 만일 내가 면접자라면 이런 식의 질문은 하지 않는다. Aurora 의 사용경험도 물론 중요하다. 하지만 프로젝트가 마이그레이션이 주 목적이라면 반드시 데이터 이전이 동반된다. 이럴 경우 Oracle 에서 Aurora 로 이전하거하는 작업이 필요할텐데 이를 어떻게 할 것인가…. 쉬운 일이 아니다.

얼마나 Best Practice 아키텍쳐들을 알고 있는지도 중요하다. 하지만 단편적인 몇몇 서비스들에 대해서 “이거 아냐?” 하는 질문은 별로 인거 같다. 전체적인 아키텍쳐에 대해서 물어보고 세부 사항에 대해서 질문을 했다면 어땠을까 싶다.

마지막으로 짜증났던 것은 Maven 을 사용할줄 아냐?, 젠킨스로 빌드 시스템 구축 가능하냐?, Python 할줄 아냐?, Ansible 사용할줄 아냐?? 문서는 잘 작성하냐?

다 갖춘 슈퍼맨을 뽑는건지…..

20 개의 Ansible 인터뷰 질문

이 글은 Arie Bregman 씨의 “20 Ansible Interview Questions” 을 번역한 것입니다.

질문1

Ansible 에서 다음 각각의 컴포넌트에 대해서 이들 사이의 관계를 포함해 설명하시오.

  • Task
  • Module
  • Play
  • Playbook
  • Role

Answer

이 질문은 당신이 Ansible 의 기본적인 컴포넌트에 익숙한지 않한지, 그들이 어떻게 상호작동 하는지를 체크한다. 나는 이것이 우리가 Ansible 로 하고자하는 모든 것에 기본인만큼 매우 중요한 것임을 알았다.

  • Task – 특정 Ansible 모듈(Module) 호출하기
  • Module – 여러분의 호스트나 원격 호스트에서 Ansible 에 의해서 실제 실행되어지는 코드의 묶음. 모듈들은 카테고리로(database, file, network, …) 인덱스되고 task 플러그인처럼 첨조된다.
  • Play – 주어진 호스트에 실행되어질 하나 혹은 그 이상의 Task 들.
  • Playbook – 하나 혹은 그 이상의 Play들. 각각의 Play 들은 같은 호스트 혹은 다른 호스트들에서 실행되어질 수 있다.
  • Role – Ansible Role 은 어떤 기능이나 서비스를 기반으로 자원들을 그룹화 해 쉽게 재사용할 수 있도록 해준다. Role 에서 variables, defaults, files, templates, handlers, tasks 그리고 metadata 를 위한 디렉토리를 가진다. 그리고 Role 을 Playbook 에 지정해서 사용할 수 있다.

더 자세한 Ansible core components 사항은 여기서 확인할 수 있다.

질문2

‘/tmp/new_directory’ 디렉토리를 생성하는 task 를 작성하라.

Answer

매우 기본적인 질문지만 당신이 Ansible 을 어떻게 활용하는지를 알수있게 해준다. 많은 사람들이 Shell 이나 Command 모듈을 사용하는 것으로 이 질문에 답합니다. 이것이 꼭 나쁜것은 아니지만, 제일 좋은 사례는 항상 명시적인 Ansible 모듈을 사용하는 것 입니다. (이 경우에, file 모듈을 사용하는 것이다.)

왜 그런가? 주요한 이유는 가독성(readability) 때문이다. 어떤 액션들은 서로 다른 운영체제에 따라 다르게 실행되지만, Module 은 언제나 같은 것을 사용하고(운영체제에 관계 없이) 어떤 Ansible 사용자라고 할지라도 Task 를 읽다보면 그것이 무엇을 뜻하는지를 알게된다. (특히 긴 쉘 명령어일 경우)

주의: 이것은 Module 이 ‘shell’ 이나 ‘command’ 로 지정한 명령어보다 반드시 좀 더 빠르다는 것을 의미하지 않는다.

디렉토리 생성 Task 는 다음과 같다. 

질문3

다음 Play 결과는 무엇인가?

Answer

작성된 코드가 주어지면 항상 철저히 검토하세요. 만약 여러분의 대답이 “이것은 실폐할 것이다” 라면 맞습니다. 이 코드는 실행한 호스트로부터 수집된 정보의 일부인 ansible_hostname 이라는 Fact를 사용하고 있다. 하지만 이 경우에, Fact 수집을 비활성화(gather_facts: no) 했기 때문에 ansible_hostname 변수는 정의되지 않을 것이며 따라서 결과는 실폐하게 된다.

이 질문의 목적은 Fact 가 무엇인지를 체크하기 위한 것이지만 여러분이 아주 세세한 부분까지 신경을 쓰고 있는지를 체크하는 것이기도 하다.

유사하게 다음과 같은 질문이 있을 수 있다.

  • 활용가능한 모든 Fact 를 나열하는 방법은?
  • 당신만의 Fact 를 지정하는 방법은?

질문4

시스템에 ‘/tmp/mario’ 파일이 존재한다면 모든 시스템에 ‘vim’, ‘zlib’ 설치를 위한 Playbook 을 작성해라.

Answer

이 질문에 답하기 위해서 여러분은 register, conditionals 그리고 loops 에 익숙해져 있어야 한다.

첫번째 Task 는 ‘stat’ 모듈을 사용해서 각 시스템에 파일이 존재하는 체크한 결과를 ‘register’ 를 사용해서 ‘mario_f’ 변수에 담아두는 것이다. 이렇게 하면 등록한 변수를 어떤 다른 Task 에서도 사용할 수 있다. 이 경우에, 우리는 ‘/tmp/mario’ 파일의 상태를 담았고 다음 Task 에서 만약 파일이 존재한다면 패키지들을 설치하게 된다.

여러분이 본것처럼, 패키지들을 설치하기 위해서 우리는 리스트(list)를 반복할 수 있게해주는 “with_items” 루프를 사용했고 리스트에 아이템마다 module/task 를 실행했다. loop는, 다른 프로그래밍 언어처럼, Ansible 의 기본적인 사항이고 여러분은 Ansible 이 지원하는 다른 타입의 loop 을 알고 있어야 한다.

다른 주목해야할 라인은 ‘become: yes’ 인데, 이것은 Task 를 root 처럼 실행하게 해주기도 하지만 다른 사용자로 실행되도록 사용자를 지정해줄 수 있다(e.g. become: ‘toad’). 패키지 설치는 시스템의 sudo 권한만으로 수행할 수 있기 때문에 이 라인이(become: yes) 이 포함되어 있지 않으면 패키지 리스트 설치 Task 는 실패할 것이다.

다른 주목해야할 라인은 ‘become: yes’ 인데, 이것은 Task 를 root 처럼 실행하게 해주기도 하지만 다른 사용자로 실행되도록 사용자를 지정해줄 수 있다(e.g. become: ‘toad’). 패키지 설치는 시스템의 sudo 권한만으로 수행할 수 있기 때문에 이 라인이(become: yes) 이 포함되어 있지 않으면 패키지 리스트 설치 Task 는 실패할 것이다.

*Bonus: 어떤 Ansible 모듈들은 인자로(argument) 리스트를 받을 수 있다. 이 질문에서, loop 처리는 ‘package’ 모듈에 package_list 변수를 직접 제공함으로써 완벽하게 제거할 수 있었다. 또, 우리는 Ansible 에 정규표현식으로 파일 리스트를 반복하는 ‘with_fileglob’ loop 를 사용함으로써 “stat” 모듈을 완벽하게 제거할 수 있다. 이를 종합하면 다음과 같다.

질문5

controller 그룹을 제외한 모든 서버에 다음의 내용을 가진 ‘/tmp/system_info’ 파일을 배포하는 Playbook 을 작성하라.

<HOSTNAME>과 <OS>는 실행되는 호스트의 실제 데이터로 바뀌어야 한다.

Answer

system_info 파일을 배포하는 Playbook 은 다음과 같다.

system_info.j2 템플릿 내용은 다음과 같다.

Template 사용은 여러분의 Playbook 이나 Role 들을 좀 더 다이나믹하게 해주고 다른 시나리오와 쉽게 적용할 수 있게 해준다. Ansible 은 파일의 동적 템플릿 구성을 위해서 ‘Jinja2(진자2)’ 불리는 강력한 템플릿 엔진을 사용한다. 많은 인기있는 프로젝트와 회사들이 이것을 사용중이고 우리는 시간을 갖지고 미래에 여러분이 그것을 잘 사용할 수 있도록 사용법을 익히는것을 강력히 추천 합니다.

Ansible 을 위한 Jinja 템플릿을 작성할때에 템플릿 최상단에 ‘ansible_managed’ 변수를 추가하는 것이 가장 좋은 사례 입니다. 이 변수는 Ansible 로 생성되거나 관리되는 출력파일을 누구나 읽을수 있는 문자열로 확장 됩니다. 그 다음, 우리는 호스트 이름을 위해서 ansible_hostname 을, OS 배포판을 위해서 ansible_distribution 을 사용했다.

이 질문은 다른 방법으로 구현 될 수 있다는 점에 유의해라. 예를들어, ansible_hostname 을 사용하는 대신 어떤분은 inventory_hostname 을 사용할 것이다. 그들은 같지 않지만, 이 경우에는 둘다 괜찮다.

질문6

어떻게 여러분의 Ansible 기반 프로젝트를 테스트 하는가?

Answer

몇몇 인터뷰때 이 질문을 했었는데, 아주 많은 다른 대답을 받았다. 그 답변들 중 몇가지 이다.

  • Manual run: “나는 그냥 그것을 실행시키고 시스템이 원하는 상태에 있는지를 체크한다” – 개인적으로 나는 이런 대답만 하는것을 싫어한다. 나는 이것이 가장 쉬운방법임에 동의하지만 잠재적으로 아주 위험하다. 비록 개발환경에서 새로 작성한 Role 을 테스트한다 할지라도, 이것이 프로덕트 환경에서 같은 결과를 얻는다는 것을 의미하지 않는다.
  • Check mode – yes, check mode 는 실제로 check mode 없이 실행할 경우 무슨일을 했는지 결과를 알려주므로 Ansible 코드를 테스트하기에 좋은 방법이다. 그래서 여러분은 Ansible이 실행되면 여러분이 기대한 행동이 나오는지를 쉽게 볼 수 있다. 하지만 여기서 “그리고 스크립트 어떤가?” 라는 질문이 있다. 보통, 나는 대답으로 “그게 뭔데?” 라는 소리를 들는데, 만일 롤(Roles)과 플레이북(Playbook) 에 스크립트를 사용하지 않는다면 괜찮겠지만, Check Mode 는 스크립나 명령어를 실행할 수 없다는 것을 알아야 한다. 그것을 실행하기 위해서는, “check_mode: no”를 사용하여 특정 Task에 대한 Check Mode 를 비활성화해야 한다.
  • Asserts – 나는 Python처럼 다른 언어를 테스트하는 방법과 비슷한 테스팅 메소드로 Assert 를 좋아하는데 중요한 것은 여러분의 시스템이 Check mode 와 같은 초안이 아닌 Task가 특정 자원을 원하는 상태로 변경했다는 실제 검증처럼 원하는 상태에 도달했는지 확인해준다.

요약하면, 단순하게 여러분이 선택을 설명해야할때 자신감을 가져라.(또, 누군가 이것들을 모두 사용하도록 기대하는 것은 현실적이지 않기 때문에 이 모두를 사용하지 마세요.

질문7

데이터베이스 그룹에(RedHat 으로 가정하고) 모든 서버에 PostgreSQL 설치하고 postgresql.conf.j2 템플릿으로 postgresql.conf 설정을 업데이트하는 Playbook 을 작성하시오.

추가로, 설정 업데이트 task만 실행하기 위해나 방법을 제시하라.(패키지 설치하지 않고..)

Answer

여기에는 놓치지 말아야할 두가지가 있다: handlers 와 tags. 여러분의 Playbook 은 다음과 비슷할 것이다.

보시는 봐와같이, 하나의 파일에 모든 것을 담았지만 더 좋은 해결법은 Roles 를 생성하게 하고 각 섹션들을 그들만의 디렉토리에(vars, handlers, tasks,…) 넣는 것이다. 나중에 Roles에 대한 상세한 질문과 답변을 하겠다.

첫째로 봐야할 것이 ‘Handler’다. Handler는 변화에 따른(보통 task) 트리거 액션을 수행한다. 위에서 본것처럼, 문법은 확실히 단순하다, ‘notify’ 키워드를 사용함으로서 실행을 위한 액션 리스트를 제공할 수 있다. 이것은 설치를 위해 필요한 메인 Task와 PostgreSQL 설정이 무엇인지, Task를 완료하는데 필요한 작은 “sub” 액션이 무엇인지를 명확하게 구분하게 해준다.

두번째로 봐야할 것은 ‘tags’다. 이것은 어떻게 설정 업데이트 부분만 실행하도록 하는지에 대한 질문의 두번째 부분에대한 답변이다. 여러분이 100 task를 가지고 있고 그들중에 아주 오직 작은부분만 실행되길 원있다고 가정하고 애플리케이션 업데이트를 담당하는 네가지 Task 를 가정해보자. tags 가 없다면, 여러분의 playbook 에서 모든것을 실행해야만하지만 tags를 사용하면 특정 tag 로 표시한 tag만 실행할 수 있다.

질문8

다른 값을 가진 여러 장소에서 같은 변수이름을(whoami) 사용한다고 생각해보자.

  • role defaults -> whom:mario
  • extra vars(-e 를 통해서 Ansible CLI 로 전달되는 변수들) -> whom:toad
  • host facts -> whoami:luigi
  • inventory variables(타입과 상관없다) -> whoami:browser

최종적으로 어느것을 사용해야 합니까? 왜?

Answer

정답은 ‘toad’ 다.

Variable precedence 는 변수들이 다른 위치에 있을때에 어떻게 변수들이 서로 오버라이드(override) 하는지에 대한 것이다. 만약 아직 여러분이 그것을 다루어보지 못했다면 어느시점에서 그것을 다룰것인데, 그것을 깨닫기에 유용한 주제다.

질문의 문맥에서, 순서는 extra vars(매번 모든 다른 변수를 오버라이드한다) -> host facts -> inventory variables -> role defaults (제일 약하다)

전체 목록은 위 링크에서 찾을 수 있다. 한가지 주의해야 할것은 Ansible 1.x 와 Ansible 2.x 는 아주 다르다.

질문9

여러분에게 Ansible 모범 사례로 친숙한 것 (적어도) 3가지는?

Answer

  • 여러 파라메터를 사용할때에 YAML dictionary 포맷을 사용하는 것이 더 낫다. 나는 개인적으로 좀 더 읽기 편하다.
  • “항상 태스크 이름을 사용하라”. 여러분이 ‘debug’ 모듈을 사용하는 것처럼 아주 단순한 것일지라도 매번 태스크를 추가할때마다 name 을 사용하는 것으로 얻을 수 있는 이득이 있다. task의 name은 왜 추가되었고 그것이 무엇을 하는지와 같은 어떤 정보를 제공한다. 알려진 버그를 해결할 수 있는 벙법일 수도 있고 길고 지루한 명령일 수도 있으므로 사용자가 playbook을 읽거나 사용할때에 간단하게 무엇을 하는지를 기술한다면 고마워할 것이다.
  • Ansible 코드의 모든 변경은 ansible-lint 로 전달되어야 한다. 이것은 기본적으로 best-practices checker 인 또 다른 비공식 모범 사례다. This is why I consider it as one of the most important best practices to implement as it makes it easier to make sure other best practices are being followed, especially in a shared repository where you have several contributors(역, 모범 사례가 되기 위해서는 task 의 name 을 사용하는 것이 좋다. 여러 컨튜리뷰터들과 저장소를 공유할때에는 이러한 것이 모범 사례가 되게 만드는데 도움을 준다.

이미 언급한 바와같이, 언급된 모든 모범 사례가 공식적인(Ansible 문서) 것이 아니며 여러분이 그것이 왜 모범 사례인지를 설명할 수 있다면(좀 더 정확하게 좋은 연습사례) 그것으로 괜찮다.

질문10

“The inventory file is in <inventory_file_path> and the inventory groups are <inventory_groups>” 내용을 가지는 ‘/tmp/info’ 파일을 모든 호스트에 생성하는 Ansible Ad-Hoc command 를 작성하라

주의: 인벤토리 그룹에 포함된 호스트도 나열해야 한다.

Answer

Ansible 을 실행하는 다른 방법을 아는 것은 시간을 절약해 준다. 그중에 하나가 Ad-Hoc 방법인데, 원격 호스트에 빠르게 무엇이든 실행해준다.

이 경우에, ad-hoc command 는 다음과 같을 것이다.

-m은 모듈 이름을 지정하기 위한 것이다. 우리는 ‘copy’를 사용하지만, 동일한 결과를 얻기 위해서 다른 모듈을 사용할 수도 있다.

-a파일의 내용과 어디에 생성할지를 모듈에 전달하기 위한 아규먼트다.

나는 이것에 친숙해지기 위해, 실전에서 사용할때 충분히 편안함을 느낄수 있도록 ad-hoc command를 여러번 실행해 볼것을 권장한다.

질문11

ansible-pull 은 무엇인가? 어떻게 ansible-playbook 과 다른가?

Answer

우리는 ansible-playbook 을 실행하는 것이 컨트롤 노드로 알려진 호스트에서(우리가 명령을 실행하고 있는 노드) 운영중인 호스트에 어떤 설정을 강제한다는 것을 알고 있다.

ansible-pull 또한 설정을 적용하지만 컨트롤 호스트로부타가 아닌 관리 호스트로부터 실행된다. 이것은 주어진 URL 저장소로부터 설정을 pulling 한다.

이것은 여러분이 접속한 호스트에서 중앙 위치로부터 설정을 강제하는 Reversed Architecture 가 필요할때에 유용할 수 있다.

질문12

여러분은 디렉토리 목록을 가지고 있고 첫째로 발견한 디렉토리를 원격 서버로 복사하는 Task를 작성하기 원한다.

Answer

역주: Ansible 2.7 에서는 없어진듯 보인다. 공식문서에서 검색했지만 나오지 않는다.

질문13

다이나믹 인벤토리는 무엇인가?

새로운 dynamic inventory 스크립트를 작성할 때 어떤 규칙을 따르는것이 중요한가?

Answer

라인을 추가/삭제하거나 수동으로 호스트이름 목록을 업데이트하는 default 혹은 static 인벤토리와 다르게, dynamic inventory 는 클라우드(Cloud)나 LDAP 과 같은 외부 소스로부터 정보를 추출함으로써 생성어된다. 대부분의 이러한 dynamic 저장소 스크립트는 contrib/inventory 디렉토리에서 찾을 수 있다.

새로운 동적 인벤토리를 개발할 때 ‘-list’인수를 사용하여 호출하면 해당 스크립트의 중요한 결과가 JSON 형식에 그룹을 출력한다. 다음과 같이 group:managed_hosts 처럼 할 수 있다.

혹은 다음과 같이 group:dict_of_variables 처럼 할 수 있다.

물론, 두개를 혼합할 수 있다.

dynamic inventory 에 대한 더 많은 정보는 여기서 찾을 수 있다.

질문14

파일의 전체 또는 상대 경로가(-e 와 함께 변수를 전달 함) 주어지면 다음을 수행하십시오.

  1. 현재 작업 디렉토리나 주어진 위치에서 찾아라.
  2. 만일 파일을 찾을 수 있다면, 리모트 호스트 사용자 홈 디렉토리에 그것을 복사하라. 만일 파일을 찾지 못할 경우, run/execution 은 실패로 처리하라.

Answer

질문15

Apache 설치를 위한 롤을 작성하라.

Answer

나는 이 질문이 인터뷰에서 아주 인기 있는 질문이라고 생각한다. 왜냐하면 ‘role’은 Ansible의 핵심 컴포넌트이며 이것은 앞에 질문에서 논의했던 tasks, templates 그리고 variables 와같은 많은 컴포넌트들을 사용하도록 만들기 때문이다.

이 질문에 대한 하나 이상의 답이 있다는 점에 주의해야 한다. 나는 짧지만 포괄적인 답을 제공할 것이다. role 에서 모든 디렉토리를 사용하는 자세한 대답은 아마도 추가 점수를 줄 것이다.

구조부터 시작하자.

이것은 매우 표준적인 구조지만 여러분은 각 디렉토리가 왜, 무엇을 위해 사용되고 이 케이스에서 Apache 설치를 어떻게 구현하는지 익숙해질 필요가 있다.

이것은 매우 표준적인 구조지만 여러분은 각 디렉토리가 왜, 무엇을 위해 사용되고 이 케이스에서 Apache 설치를 어떻게 구현하는지 익숙해질 필요가 있다.

vars 를 시작해보자. vars 는 우리가 role 에서 사용할 모든 변수를 가진다. 무엇이 변수일 수 있나? 만약 우리가 서로다른 운영체제에 이 role 을 사용할것이라면, apache2의 서비스 이름은 변수일 수 있다. Fedora에서, 서비스 이름은 httpd 일 것이지만 Debian 에서는 apache2 로 부른다. 또 다른 변수로 각 운영체제에 패키지를 설치해기 위해 정의한 apache2_packages 일 수도 있다. 어떻게 이것을 구현하는지 보자.

RedHat.yml 살펴보자.

Debian.yml 살펴보자.

이제 Handler 로 가보자. Handler 는 어떤 변화(Change)에 따라 트리거되는 액션이다. 이 경우, 아주 흔한 handler 로 ‘restart service’ 일 수 있다.

이 handler 는 설정에 변경이 있은 후에 apache2 시작을 위해서 사용되어질 수 있다. {{ apache2_service }} 는 RedHat.yml 과 Debian.yml 에 정의되어 있음을 기억해라.

다음으로, 우리는 defaults/main.yml 에서 기본 변수들을 정의할 것이다.

만약 defaults 와 vars 차이에 의문이 든다면 여러분은 default를 모든 타입의 운영체제나 시나리오에 사용하기 위한 공통변수로 생각해야 한다. 반면에, vars 는 특별한 환경/케이스에 사용하기 위해 수정된 변수들이다. 이 경우 운영체제 타입이다.

meta folder 는 role 에서 별도의 행동을 정의하기 위한 장소처럼 행동한다. 일반적으로 대부분 role 의존성을 정의하는데 사용한다. 이것은 role 이 다른 role 에 의존성이 있는 경우인데, 예를들어 자바(Java) 기반 애플리케이션 설치하는데 설치된 자바가 필요한 것이다. 이 예제를 만들어보면 우리는 두개의 role 을 가질것이다.

  1. Java 설치 role
  2. Elasticsearch 설치 role

우리의 play 는 다음과 같을 것이다.

하지만 우리는 다른 사람과 role들을 공유하는 걸 좋아하기 때문에, ElasticSearch role을 사용하고자하는 유저는 ‘Java’ 라는 다른 role 을 의존성을 모를 수 있다. 따라서 meta folder에 다음과 같이 라인을 추가해줘야 한다.

이것은 ‘elasticsearch’ role 을 불러오기 전에 ‘java’ role 을 시도하고 실행할 것이다. 이것은 이전의 play 를 재작성하도록 해준다.

최종적으로, 우리는 몇개의 task들을 정의할 것이다. role의 핵심은, 무엇을 실행시킬 것인지를 정의하는 부분이다. 우리는 목적에 기반한 추가적인 task 를 포함하는 단순한 메인 파일을 가질 것이고 OS 타입에 따라서 그것이 동작할 것이다. 올바른 패키지를 설치하기 위해서, 우리는 각 OS에마다 사용할 이전에 정의했던 변수들을 포함할 것이다.

이제, install-RedHat.yml을 살펴보자.

최종적으로, 이것이 앞에 모든 파일들을 생성한 이후 구조다.

기억해라, 이것은 완전한 해결책이 아니며 당신이 더 장황하고 상세한 답변을 줄수록, 당신은 더 많은 신뢰를 얻을 것이다.예를들어, 설정을 위해 템플릿을 가지는 템플릿 디렉토리을 추가하거나 Apache 설정 Task 추가등이다.

질문16

여러분은 다음의 play 를 가진다.

그리고 여러분은 다음의 command 를 실행한다.

test 변수의 출력값은 무엇인가?

  • test 1 2 3
  • test
  • empty string
  • the variable is not defined

Answer

대답은 ‘test’다.

이것은 속임수이고 여러분이 shell 과 Ansible을 이해하고 있는지를 체크한다. 이 경우에, command는 shell에 의해서 우선 처리 때문에, 인용문의 내용과 백슬래쉬와 빈공백 이후의 모든것은 무시된다.

면접관으로서, 여러분은 대부분의 면접자들이 이것에 올바른 대답을 못것인지 아니면 단순한 추측은 아닌지 알아야 하며 이것이 Ansible에 익숙한지 아닌지를 나타내는 지표는 아니다.

해결책은 전체적으로 ‘-e’ 이후에 내용을 인용하는 것이다.

질문17

오직 task 이름들만 표시하도록 Ansible 실행의 출력 포맷을 어떻게 변경할 것인가?

Answer

해답은 “callback plugin” 이다. 여러분이 알고 있는 것만 바꿀것만 아니라 Ansible 에서 다른 이벤트를 기반으로 여러분이 원하는 모든것을 할 수 있다. 그래서 유사한 질문이 있을 수 있다: “어떻게 파일에 모든 것을 기록할 수 있나?” 그리고 대답은 여전히 callback plugin 일 수 있다.

여기에는 여러분이 callback plugins 에 대해서 알아야할 몇가지 포인트가 있다.

    • Ansible 트리에 몇가지 callback plugins 가 있다.
    • callback plugin을 활성화하기 위해서, ansible.cfg 에 다음과 같은 것을 포함해야 한다.
    • Ansible 실행에 기본 표준 출력을 바꾸기 위해서는, ansible.cfg 를 다음과 같이 바꿔라.
  • 새로운 callback plugin 을 개발할때, 부모 클래스 “CallbackBase” 로부터 상속이 필요하며 다음의 메소드를 오버라이드(override) 해야 한다.
    • v2_runner_on_skipped
    • v2_runner_on_unreachable
    • v2_runner_on_ok
    • v2_runner_on_failed

Callback plugin 은 여러분의 Ansible 실행을 커스터마이징을 위한 좋은 방법이고 여러분이 Ansible 아웃풋(Output)을 소비하는 방법이다.

질문18

다음의 컨텐츠를 포함하는 파일 ‘/tmp/excercise’ 가 있다.

하나의 Task 를 가지고, 다음과 같이 컨텐츠를 바꿔라.

Answer

새로운 컨셉이 아닌, 두개의 아이템을 매번 반복하는 곳에서 약간의 loop 문을 응용한 것이다. (regexp 과 line)

주목할 것은 이 문제를 ‘blockinfile’ 로 해결할 수도 있다.

질문19

문자열을 대문자로 바꾸는 필터를 작성해라.

Answer

우리는 매우 단순한 필터(filter)를 작성했다. 필터를 작성하는 Ansbile 을 마스터할때 자신의 것으로 하고 싶은 좋은 스킬인데, 거기에는 몇가지 이유가 있다.

첫째로, 믿던 안 믿던, 필터는 몇몇 게이스에서 여러분의 playbook 들을 좀 더 읽기편하게 해준다. 특히, 여러분이 아주 긴 명령어를 사용할때 사용자는 무엇을 왜 작성했는지 이해하는데 몇분이 소요된다. ‘hostname_to_ip’ 는 이해하기 아주 쉽다. right?

게다가, Ansible 의 모든 것을 맹목적으로 사용하지 마라. 이런것이 2차면접에서 의미있는 것은 아니다. 다른 사람이 이해하기 쉽고 성능에 영향을 미치지 않지만 어떤 경우에도 이를 고수하지 않을 경우 가능하면 Ansible 을 사용해라.

질문20

마지막 질문은 질문 요약이다. 10개의 지문이 있고 그것이 true 나 false 인지를 정해라.

    1. Module은 Task 의 집합이다.
    2. 특정한 Module 대신에 shell 이나 command 를 사용하는게 낫다.
    3. Host 팻츠(facts)는 play 변수들을 무시한다.
    4. Role 은 vars, meta 그리고 handler 를 포함할 수도 있다.
    5. 다이나믹 인벤토리는 외부 소스로부터 정보룰 추출함으로써 생성된다.
    6. 4칸 보다 2칸의 들여쓰기를 사용하는 것이 좋은 모범 사례다.
    7. 다음의 Task 는 성공적으로 실행될 것이다.
  1. ‘notify’ 는 Handler 를 트리거(Trigger)하는데 사용 된다.
  2. “hosts:all:!controllers” 는 ‘hosts 그룹에 controller 만 실행하라’ 라는 것이다.
  3. 기본 Role 은 role 변수를 무시한다.

Answer

  1. False play 는 Task들의 집합이다. Task 는 특정 모듈(Module)을 실행하는 것이다.
  2. False Shell 이나 Command 를 사용하는 것 좀 더 빠를 수 있지만, 일반적으로 Ansible 사용자를 위해서 더 쉽게 읽을수 있도록 언제나 특정 모듈을 사용하는 것이 좋습니다.
  3. False Play 변수들은 host 팻츠(Facts) 를 무시한다.
  4. True
  5. True OpenStack 과 같은 클라우드나 LDAP 일 수도 있다.
  6. False 이것은 정말 말이 안된다.
  7. Depends playbook 이나 role dl ‘become: yes’ 를 가지고 있다면, 이것은 성공적으로 실행되겠지만 그렇지 않다면 퍼미션때문에 실패할 것이다.
  8. True
  9. False Controller 들을 제외한 모든 hosts 를 대상으로 실행하라는 뜻이다.
  10. False Role 변수들은 role 기본값을 무시한다.

Practice is everything

여러분이 대부분의 질문에 올바르게 대답할 수 있었다면,이것은 Ansible 컨셉과 사용에 여러분이 익숙해 있다는 것을 확실하게 말해준다. 하지만 기억해야한다. 인터뷰 질문에 답하는것만이 아닌 연습만이 최고다.

더 많은 인터뷰 질문들

더 많은 인터뷰 질문이나 Ansible 을 배울때 검토할 주제의 체크리스트는 Github 저장소를 방문해라.

[Ansible] hosts did not meet host_list requirements 메시지 처리하기

Ansible 을 사용할때에 인벤토리 파일에 대해서 가끔 “hosts did not meet host_list requirements, check plugin documentation if this is unexpected” 메시지를 보게 된다. 이 메시지는 ‘ansible -vvv ‘ 처럼 -v 옵션을 주면 보인다.

이 메시지는 인벤토리 파일 형식으로 인한 것으로 ini 형식을때에 주로 나온다. 하지만 인벤토리 파일 형식이 ini 형식임을 ansible 이 인지하지 못해서 벌어지는 일인데, 이는 ansible.cfg 파일에 다음과 같이 함으로써 없앨 수 있다.

한국 직장에 고질병

한국 조직문화의 고질병

한국의 조직의 고질병은 능력있고 성실한 사람에게 보상을 주기는 커녕 일을 더 준다는 것에 있다. 그래서 능력있는 사람은 못 견디고 떠나가고 능력없는 사람은 일도 없고 스트레스도 없으니가 조직에 오래 남을 수 있음. 결국 무능한 사람만 남은 무능한 조직이 된다..

일은 일잘하는사람에게 밀어주고
진급은 술잘마시는 사람에게 시켜주고 …

이것이 한국 직장 병패임.

 

똑똑하고 일 잘하고 회사를 위한 합당한 이의제기를 하는 사람 보다
윗 사람의 말에 절대 반기안들고 YES만 하는 사람이 오래다니죠
사장 옆에는 항상 항상 그런 사람이 있더라구요…

 

대부분의 조직에서 능력있는 사람은 나가고 능력없는 사람만 남는 건 맞는데, 꼭 저렇게 능력있는 사람에게 보상없이 일만 줘서라기보단 더 나은 보상을 받을 수 있는 조직을 찾아 떠나는 거죠. 그럴 능력이 안 되면 마땅히 갈데가 없으니 붙어 있는 거고. 조직마다 줄 수 있는 보상의 한계치가 다르니…

Ansible fingerprint 접속 오류.

서버에 맨 처음 SSH 접속을 시도 하면 다음과 같은 오류가 발생한다.

이를 해결하기 위해서는 다음과 같이 환경변수를 지정해 주면 된다.

혹은 ~/.ansible.cfg 파일에 다음과 같이 지정해도 된다.