Spinnaker (1)



Spinnaker는 Netflix에서 개발한 멀티 클라우드 CD(Continuous Delivery)를 위한 플랫폼입니다. 

Spinnaker는 AWS, GCE, Azure, Kubernetes(이하 k8s) 등 다양한 멀티 클라우드 환경에 서비스를 배포할 수 있는 CD 환경을 제공합니다. 

또한 Jenkins, Docker Registry, Git 등의 다양한 트리거를 통해 비교적 쉬운 UI로 파이프라인을 구성할 수 있게 해줍니다. 

배포 중 문제가 생기면 쉽게 이전 버전으로 Rollback이 가능하고 자체적으로 Red/Black(=Blue/Green)이나 Canary 배포 전략을 제공하고 있습니다. 

얼마 전, Git-Jenkins-Spinnaker-k8s로 이어지는 CICD 환경을 구성해야 하는 미션이 있어서 온프라미스 환경에 Spinnaker를 설치하였습니다. 

설치 도중 겪은 문제나 (알고나면 쉽지만) 컨셉적으로 약간 이해하기 어려웠던 부분에 대해서 도움이 되고자 공유합니다.



Concept


먼저, Spinnaker가 무엇인지 찾아보면 제일 먼저 볼 수 있는 것이 아래 컨셉 이미지입니다. 분명히 익숙한 단어들인데 처음엔 아무리 설명을 읽어봐도 Spinnaker에서 어떤 의미로 쓰인다는 것인지 와 닿지가 않았습니다.


출처 : https://www.spinnaker.io/concepts/


힌트는 Provider별로 매핑되는 용어가 다르다는 것입니다. 

위에서도 언급했듯이 Spinnaker는 서비스를 멀티클라우드 환경에 배포할 수 있고, Spinnaker에서는 각 환경을 Provider라고 부릅니다.

즉, AWS, K8s, Azure 등 서비스가 배포되는 환경이 Provider입니다.


레퍼런스 문서를 보면 이 Provider별로 각 용어를 매핑시켜 놓았는데요. 

예를들어, K8s Provider의 경우 각 용어는 아래와 같은 K8s 리소스들과 매핑됩니다.


 - Server Group = Replica Set Resource

 - Cluster = Deployment Resource

 - Load Balance = Service Resource

 - Firewall = Ingress Resource


Spinnaker UI의 각 메뉴에서 해당되는 K8s Resource를 배포하고 모니터링할 수 있습니다.  


출처 : https://www.spinnaker.io/guides/tutorials/codelabs/kubernetes-source-to-prod/


예를들어, Load Balancer 메뉴에서 Create Load Balancer를 하면 버전에 따라 yaml 형식의 manifest를 직접 입력하거나 UI가 제공하는 템플릿을 이용하여 K8s 환경에 Service Resource를 생성할 수 있습니다. 

그 외 Provider별로 매핑시켜놓은 가이드는 https://www.spinnaker.io/reference/providers/ 를 참고하시기 바랍니다.



Spinnaker Architecture


Spinnaker는 MSA 구조를 가지고 있기 때문에 구동 시 굉장히 많은 서비스들이 실행됩니다. 


출처 : https://www.spinnaker.io/reference/architecture/


- Deck : Web UI (Port: 9000)

- Gate : API Gateway. UI를 비롯한 모든 API Call은 이 Gate를 통해 호출됩니다. 

     여러 서비스들을 호출하기 위한 단일 Endpoint 입니다. (Port: 8084)

- Orca : 오케스트레이션 엔진으로 모든 ad-hoc과 파이프라인을 핸들링합니다. 

- Front50 : 어플케이션, 파이프라인과 같은 메타데이터를 스토리지에 저장합니다. 

- Rosco : Packer 기반으로 GCE 이미지, AWS AMI, Azure VM 이미지를 생성하는 Bakery 역할을 담당합니다. 

- Igor : 파이프라인을 구성 시 CI Job을 트리거로 사용할 수 있습니다. 

            예를들어, Jenkins, Travis CI와 같은 CI Job을 Polling 해서 파이프라인을 실행시킵니다. 

- Echo : 파이프라인 단계에서 Slack, email, SMS 등에 노티를 줍니다. 

- Flat : 권한 

- Keyenta : Automated Canary Analysis 서비스로 Canary 배포를 가능하게 해줍니다.

- *Halyard : Spinnaker 관련 설정들을 적용해서 실제로 위의 서비스들을 구동시키는 역할을 합니다. 

                  Halyard CLI를 통해 Spinnaker 설정 정보를 변경할 수 있고 변경 후에는 위의 서비스들을 재구동시켜 Spinnaker에 적용합니다. 

                  Spinnaker를 설치하는 다음 포스팅에서 실제 사용하는 방법을 자세히 보도록 하겠습니다. 


지금 모든 서비스들에 대해서 다 이해할 필요는 없습니다. 이런 기능들이 있구나 정도로만 이해하고, 실제로 Spinnker를 구동시켜 보고 UI에 있는 기능들을 사용해보면 자연스럽게 매핑이 될 것입니다.

각 서비스들에 대해서 더 자세히 알고 싶은 분들은 https://www.spinnaker.io/reference/architecture/ 를 참고하시기 바랍니다. 



참고 

https://www.spinnaker.io/



문제) 1로 만들기_백준1463


         세 가지 연산을 이용해서 정수 N을 1로 만들려고 할 때, 연산 횟수의 최소값 출력

         1. X가 3으로 나누어 떨어지면, 3으로 나눈다.

         2. X가 2로 나누어 떨어지면, 2로 나눈다.

         3. 1을 뺀다.         


Input

 10        // 정수 N

 

Output

 3



점화식 (정수 i를 만들 때, 연산 횟수의 최소값)

D[i] = min(D[i/3], D[i/2], D[i-1]) + 1 (1<=i<=N)

Ans = D[N]


점화식을 세울 때 팁은 마지막 연산을 어떻게 지지고 볶아 원하는 값을 만들까 생각해 보는 것이다.

당연한 것이긴 하지만 처음 공부하면서 헷갈릴 때는

"점화식은 마지막 연산으로, D배열은 앞에서 부터 채워 나간다"라는걸 각인시키고 풀었다. 


연산 종류는 세 가지이고 각 연산을 수행할 수 있는 경우 이전 연산 횟수에 +1을 해주고 최소값을 구한다. 


예를들어, 

6을 계산할 수 있는 방법은 다음 세 가지가 있다. 


 1. D[6] = D[6/3] + 1 => 6은 3으로 나누어 떨어지므로 

                                          D[2] (2를 1로 만들때 연산의 최소 횟수) + 1 (6을 3으로 나누는 현재 연산 횟수)


 2. D[6] = D[6/2] + 1 => 6은 2로 나누어 떨어지므로 

                                          D[3] (3을 1로 만들때 연산의 최소 횟수) + 1 (6을 2로 나누는 현재 연산 횟수)


 3. D[6] = D[6-1] + 1 => D[5] (5를 1로 만들때 연산의 최소 횟수) + 1 (6에서 1을 빼는 현재 연산 횟수)


D[6]을 계산할땐 D[1]~D[5]까지 계산 되어있기 때문에, 위 세 가지 값 중 최소값을 D[6]에 넣어주면 된다.



최종코드

public class Main {
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
br.close();

int[] D = new int[N+1];

for(int i=2; i<=N; i++){
D[i] = Integer.MAX_VALUE;

if(i % 3 == 0){
D[i] = Math.min(D[i], D[i/3] + 1);
}
if(i % 2 == 0){
D[i] = Math.min(D[i], D[i/2] + 1);
}
D[i] = Math.min(D[i], D[i-1] + 1);
}
System.out.print(D[N]);
}
}


'알고리즘 > DP' 카테고리의 다른 글

[DP] Knapsack 동전교환  (0) 2018.03.06
[DP]Matrix Chain Multiplication  (0) 2018.03.06

문제) 잔돈을 주기 위해 필요한 최소 동전의 수


Input

3         // 동전 종류 N 1 4 6     // 각 동전 단위 A[] 8         // 잔돈 W

Output

2


점화식 (j원을 만들 떄 최소 동전 개수)

D[j] = min(D[j], D[j-A[i]]+1)  
Ans = D[W]

D배열을 채워보면 1~8원 순서로 검->빨->파 순서로 실행되며 최소값을 갱신한다.

 j원

 0

 1

 4

 5

 6

 7

 8

 D[j]

 0





D[1-1]+1 = 1





D[2-1]+1 = 2





D[3-1]+1 = 3





D[4-1]+1 = 4

D[4-4]+1 = 1



=> min : 1

D[5-1]+1 = 2

D[5-4]+1 = 2



=> min : 2

D[6-1]+1 = 3

D[6-4]+1 = 3

D[6-6]+1 = 1


=> min : 1

D[7-1]+1 = 2

D[7-4]+1 = 4

D[7-6]+1 = 2


=> min : 2

D[8-1]+1 = 3

D[8-4]+1 = 2

D[8-6]+1 = 3


=> min : 2


최종코드

public class source {
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
int[] A = new int[N+1];

StringTokenizer st = new StringTokenizer(br.readLine());
for(int i=1; i<=N; i++){
A[i] = Integer.parseInt(st.nextToken());
}

int W = Integer.parseInt(br.readLine());
int[] D = new int[W+1];

for(int i=1; i<=W; i++){
D[i] = 64001;
}

for(int i=1; i<=N; i++){
for(int j=A[i]; j<=W; j++){
if(A[i] == j) D[j] = 1;

D[j] = Math.min(D[j], D[j-A[i]]+1);
}
}
System.out.println(D[W]);
}
}


'알고리즘 > DP' 카테고리의 다른 글

[DP] 1로 만들기 :: 1463번  (0) 2018.03.08
[DP]Matrix Chain Multiplication  (0) 2018.03.06

+ Recent posts