오케스트레이션

오케스트레이션과 오토메이션

데브옵스 관점에서 오케스트레이션은 소프트웨어 개발의 자동화를 위해 태스크를 만드는 작업이다.
데브옵스 관점에서 오토메이션은 CI 툴을 사용해서 빌드나 소스 코드 정적 검사를 자동화하는 작업이다.

일반적으로 오케스트레이션 및 오토메이션의 접근 방법은 두가지로 나뉜다.

  • 프로그래밍 언어처럼 애플리케이션 설치나 설정 순서를 열거하고 절차형 툴을 통해 자동화
  • 애플리케이션에 최적화된 인프라 상태를 템플릿 형태로 정의하고 이를 관리하는 선언형 기능 사용

절차형 툴은 앤서블 등이 대표적이다. 절차형 툴은 구성 정보나 설정 정보를 관리하는 서버와 설정을 적용하는 클라이언트로 나뉜다. 서버가 클라이언트의 상태를 모니터링하면서 원하는 상태로 유지되도록 관리한다.
선언형 툴은 AWS CloudFormation이 있다. 시스템 리소스들을 하나의 템플릿으로 정의하고 이 템플릿으로 인프라의 프로비저닝을 한다.

절차형 툴과 선언형 툴의 작용 범위
절차형 툴과 선연형 툴의 작용 범위가 다르다.
선언형 툴은 네트워크 및 블록 스토리지를 준비하고 이미지를 사용한 서버를 기동하는 등 인프라 리소스를 구성할 때 주로 사용된다.
절차형 툴은 선언형 툴이 구성한 클라우드 리소스 위에 OS를 설치하고 어플리케이션을 설치할 때 주로 사용된다.
이 차이를 잘 알고 충돌하지 않도록 툴을 사용해야 한다.

오케스트레이션과 리소스 집합체의 기본 사상

클라우드 리소스를 관리할 때 REST API를 활용해서 제어해도 된다. 문제는 관리할 리소스가 매우 많아지거나 의존성 때문에 API 호출 순서가 복잡해지면 리소스 관리가 어려워진다. 그래서 리소스를 그룹으로 묶어서 관리하는 상황에 이르게 된다.
오케스트레이션은 궁극적으로 리소스의 집합체를 정의하는 기술이다. 오케스트레이션은 액션에 해당하는 API로 처리하는 방식에서 리소스 그룹으로 처리하는 방식으로 전환함을 의미한다. 리소스의 집합체를 스택으로 지칭하며 스택을 활용하면 개별 리소스마다 액션에 해당하는 API 호출보다 훨씬 적은 API 호출로 다수의 리소스를 관리할 수 있다.

오케스트레이션의 근간인 템플릿

템플릿은 리소스를 정의하는 역할을 한다. 템플릿은 클라우드 서비스마다 상이하다. 다만 몇 가지는 공통된다. 리소스, 파라미터, 아웃풋이 공통된다.

리소스

템플릿이 오케스트레이션의 근간이면, 리소스는 템플릿의 근간이다. 템플릿에는 다수의 리소스를 정의할 수 있다. 리소스의 이름, 타입, 프로퍼티를 통해 리소스에 대한 정보를 정할 수 있고, 필요하면 다른 리소스와 의존관계를 표현해서 리소스 간 순서를 제어할 수도 있다.(AWS CloudFormation에서 DependsOn) 다른 리소스의 속성 정보를 참조하는 Ref도 활용할 수 있다.

다음은 시큐리티 그룹에 속한 EC2 인스턴스를 정의하는 AWS CloudFormation의 리소스 부분이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
"Resources": {
"EC2Instance": {
"Type": "AWS::EC2::Instance",
"Properties": {
"InstanceType": {
"Ref": "InstanceType"
},
"SecurityGroups": [
{
"Ref": "InstanceSecurityGroup"
}
],
"KeyName": {
"Ref": "KeyName"
},
"ImageId": {
"Fn::FindInMap": [
"AWSRegionArch2AMI",
{
"Ref": "AWS::Region"
},
{
"Fn::FindInMap": [
"AWSInstanceType2Arch",
{
"Ref": "InstanceType"
},
"Arch"
]
}
]
}
}
}
"InstanceSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "Enable SSH access via port 22",
"SecurityGroupIngress": [
{
"IpProtocol": "tcp",
"FromPort": "22",
"ToPort": "22",
"CidrIp": {
"Ref": "SSHLocation"
}
}
]
}
}
},

파라미터

템플릿의 리소스와 프로퍼티 값이 고정되어 있으면 템플릿을 특정 설정에만 사용할 수 있게 된다. 즉 재사용이 안된다. 이를 대응하는 부분이 파라미터다. 파라미터는 템플릿의 가변적인 정보를 입력할 수 있는 부분이다. 파라미터를 통해 템플릿 재사용성을 높일 수 있다.

파라미터로 입력된 값을 사용하려면 앞서 리소스에서 언급한 Ref로 파라미터의 이름을 입력하면 된다.

다음은 시큐리티 그룹에 속하는 EC2 인스턴스를 만드는 AWS CloudFormation의 템플릿 중 파라미터 부분이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
"Parameters": {
"KeyName": {
"Description": "Name of an existing EC2 KeyPair to enable SSH access to the instance",
"Type": "AWS::EC2::KeyPair::KeyName",
"ConstraintDescription": "must be the name of an existing EC2 KeyPair."
},
"InstanceType": {
"Description": "WebServer EC2 instance type",
"Type": "String",
"Default": "t2.small",
"AllowedValues": [
"t1.micro",
//...생략
"cg1.4xlarge"
],
"ConstraintDescription": "must be a valid EC2 instance type."
},
"SSHLocation": {
"Description": "The IP address range that can be used to SSH to the EC2 instances",
"Type": "String",
"MinLength": "9",
"MaxLength": "18",
"Default": "0.0.0.0/0",
"AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
"ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x."
}
}

아웃풋

템플릿 처리 과정에서 출력하는 내용을 다룬다.

Fn::GetAtt로 리소스의 프로퍼티 정보를 직접 인용할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
"Outputs": {
"InstanceId": {
"Description": "InstanceId of the newly created EC2 instance",
"Value": {
"Ref": "EC2Instance"
}
},
"AZ": {
"Description": "Availability Zone of the newly created EC2 instance",
"Value": {
"Fn::GetAtt": [
"EC2Instance",
"AvailabilityZone"
]
}
},
"PublicDNS": {
"Description": "Public DNSName of the newly created EC2 instance",
"Value": {
"Fn::GetAtt": [
"EC2Instance",
"PublicDnsName"
]
}
},
"PublicIP": {
"Description": "Public IP address of the newly created EC2 instance",
"Value": {
"Fn::GetAtt": [
"EC2Instance",
"PublicIp"
]
}
}
}

템플릿을 어느 세월에 다만드냐..?
일일히 템플릿을 작성하는게 부담되는 경우, 이미 존재하는 리소스를 기반으로 템플릿을 생성할 수 있다.(AWS CloudFormer)

오케스트레이션의 장점

인프라 환경 구축 단계 관점

서버, 네트워크, 스토리지를 생성할 때 웹 콘솔을 사용하던지 API를 조합한 CLI를 실행하던지 SDK를 활용한 프로그램을 사용할 수 있다. 다만 이런 방법들은 리소스 종류가 달라지면 수정해줘야 한다.

오케스트레이션은 템플릿으로 리소스 관계 및 상태를 정의할 수 있게 돕고, 오케스트레이션 엔진이 리소스 배치와 시스템 상태 유지를 자동으로 지원한다.
관리자는 리소스마다 상태 확인할 필요 없이 각 스택의 상태를 확인하면 된다. 그리고 템플릿의 상한 값 설정으로 잘못된 값 입력을 방지할 수 있다.

인프라 환경 운영 단계 관점

리소스가 생성되고 나서도 오케스트레이션의 장점이 있다. 먼저 리소스 간 의존 관계를 정의해서 리소스 기동 순서를 제어할 수 있다.
또한 오토스케일링과 오토 힐링도 구현할 수 있다. 감시서버를 두고 로드 밸런서가 장애를 통보하면 이를 오케스트레이션 API를 통해 오케스트레이션 엔진에게 알려주고 오케스트레이션 엔진이 서버 API를 통해 리소스를 다시 기동하거나 리소스를 추가하는 방식으로 대응할 수 있다. (오토 힐링과 오토스케일링은 굳이 오케스트레이션이 아니어도 가능하다.)

재사용 템플릿을 활용한 환경 복제 방식 관점

오케스트레이션은 템플릿을 통해 동일한 인프라 환경 구성을 빠르게 복제할 수 있다. 특히 파라미터를 통해 하나의 템플릿도 동적으로 변화를 줄 수 있다. 예를 들면 어떤 검증을 해야 할 때 하나의 템플릿을 파라미터를 다르게 해서 여러 환경을 만들어서 병렬로 검증을 해볼 수 있다. 또한 리전 정보를 파라미터로 전달하면 특정 리전에 속한 리소스에 문제가 생겼을 경우, 빠르게 파라미터를 바꾸서 새로운 인프라를 구축해서 활용할 수 있다.

오케스트레이션을 활용한 지속적 통합 관점

기존의 지속적 통합은 특정 환경에 애플리케이션을 배포하는 용도로 많이 사용했다. 애플리케이션의 변경 사항만 반영해서 릴리즈하고 서버, 스토리지, 네트워크의 구성 변경에는 관여하지 않았다. 하지만 클라우드 환경에서는 오케스트레이션 기능으로 인프라도 코드처럼 제어할 수 있다. 즉 CI 작업에 인프라 변경도 포한할 수 있게 됐다. 스택에 인프라 환경 뿐만 아니라 애플리케이션을 함께 정의하는 방식으로 구현한다.

오케스트레이션의 주의사항

스택으로 생성한 리소스는 개별 액션 API로 변경하지 않는다.

스택으로 생성한 리소스, 즉 오케스트레이션 API로 관리하는 리소스를 개별 액션 API로 변경하면 안된다. 왜냐면 개별 액션 API로 스택 내부의 리소스를 변경하면 템플릿 설정 내용과 변경된 상태에 차이가 생겨 정합성이 깨지게 된다. 그렇다고 사소한 작업 모두 오케스트레이션 API를 활용하면 더 느리고 번거로울 수 있다. 그래서 현업에서는 오케스트레이션 API로 관리되는 리소스와 그렇지 않은 리소스를 나눠서 관리하곤 한다.

스택 반영 후 각 리소스에 정상 반영됐는 지 확인한다.

오케스트레이션에는 스택을 갱신하는 기능이 있다. 이 작업을 통해 리소스에 정상 반영됐는 지 모니터링 해야 한다. 특히 일부 리소스는 갱신하는 과정에서 일정 시간동안 서비스를 하지 못하는 다운 타임이 발생할 수 있다. (AWS에서는 Update requires: Replacement로 표시된 리소스가 해당) 이런 경우, 스택을 따로 만들어놓고 바꿔치는 이뮤터블 인프라 스터럭처를 고려해본다.

오케스트레이션 기능을 지원하지 않는 컴포넌트나 리소스를 미리 식별한다.

내가 사용할 리소스가 오케스트레이션으로 지원하지 않으면 당연히 문제가 된다. 이를 미리 파악하고 사용하자.

스택과 템플릿의 적정 크기와 스택 중첩

한 스택에서 관리하는 리소스의 갯수가 점점 늘어나고 리소스마다 릴리즈의 빈도나 서비스 수준이 달라질 수 있다. 이러면 스택을 분리해야 한다.
일반적으로 스택 분리는 공통 요소와 서브 시스템으로 나눈다. 서브 시스템으로 분리하면 서로 의존도가 낮아지고 릴리즈가 더 빨라진다.
공통 요소는 AWS CloudFormation에서 다음 예시들이 해당한다.

  • 공통 운영 서비스
  • 네트워크(VPC)
  • 인증(IAM)
  • 프론트엔드(DMZ)
  • 데이터스토어(DB, Storage)

이렇게 스택을 여러개로 나누면 스택 사이의 정보 전달이 필요할 수 있다. 이럴 때 쓰이는게 파라미터와 아웃풋이다. 한 스택의 아웃풋을 다른 스택의 파라미터로 활용하여 분리된 스택이 서로 소통할 수 있다.

Share