본 포스팅은 "Tekton 사용해보기" 시리즈의 다섯번째 글입니다.
시리즈의 이전 글들은 아래 링크에서 확인할 수 있습니다.
Tekton 사용해보기(4) GCP Terraform 인프라를 Validation하는 파이프라인 구축하기
Tekton 사용해보기(3) Tekton Dashboard에 OIDC를 기반으로 RBAC 적용하기
Tekton 사용해보기(2) Tekton으로 인프라를 자동 배포하는 Terraform Pipeline을 만들어보자
Tekton 사용해보기(1) Tekton으로 쿠버네티스에서 CI/CD 파이프라인을 구성해보자
Tekton은 컨테이너를 기반으로 다양한 기능을 추가할 수 있는 강력한 Opensource CI/CD 파이프라인 도구입니다.
본 시리즈의 이전 글들에서 Tekton의 다양한 기능들을 알아보며 그 강력함을 직접 확인해볼 수 있습니다.
게다가 이 글에는 소개되어 있지 않아도 Tekton Hub에서 다양한 Component들을 지원하고 있기 때문에 원하는 파이프라인을 구성할 수 있다는 장점도 있는데요.
하지만 그런 Tekton에도 Native하게 지원되지 않는 기능이 하나 있습니다.
바로 인간의 승인 절차를 통해 다음 Task의 진행 여부나, 분기를 처리할 수 없다는 것입니다.
대부분의 CI/CD 파이프라인은 다음 절차를 실행하기 전 인간이 직접 Approval 여부를 결정할때까지 대기하는 기능이 있기 때문에 적용 내용을 더블체크하거나, 우발적인 실행을 방지할 수 있었는데요.
Tekton의 경우 이러한 기능을 제공하고 있지 않기 때문에 파이프라인을 구성하는데 있어 작은 결점이 있을 수 밖에 없었습니다.
하지만 Tekton의 장점인 Extension과 Custom 기능 추가를 활용해서 Approval을 구현할 수 있습니다.
이번 포스팅에서는 Tekton에서 Native하게 지원되지 않는 Human Approval 기능을 추가해보고, 이를 통한 파이프라인 구성 방법을 알아보겠습니다.
1. Tekton Approval DEMO
Tekton Approval에 대해 알아보기 전에 Human Approval을 활용한 Pipeline 데모를 보고 어떤 방식으로 프로세스가 흘러가는지 파악해보겠습니다.
1-1. Tekton Approval을 활용한 Terraform Pipeline
Tekton Approval을 활용한 CI/CD Pipeline 구성도는 위와 같습니다. 구성도를 순서대로 나열하면 아래와 같습니다.
- Tekton Pipeline 내의 Task들을 실행하다가 Tekton Approval Task의 차례가 오면 다음 작업을 멈추고 대기합니다.
- Tekton Approval Task는 지정된 User의 Email로 Approval을 요청하는 Notification mail을 발송합니다.
- 지정된 User, 즉 Approver는 Notification mail이 안내한 Dashboard에서 다음 Task 실행의 승낙, 혹은 거절을 선택합니다.
- 결과값을 Tekton Approver Task가 받기 전에, 올바른 User가 요청을 처리했는지를 Oauth2.0 인증으로 확인합니다.
- 승낙, 혹은 거절 결과값에 따라 정해진 다음 Task를 실행합니다. 예를 들어 승낙시에는 다음 Task를 실행, 거절시에는 아무런 작업을 처리하지 않아 Pipeline을 Timed-out 상태로 만들 수 있습니다.
이와 같은 Tekton Approval을 활용한 CI/CD Pipeline 프로세스를 기반으로 Terraform 코드를 배포하는 Pipeline의 DEMO를 보겠습니다.
Terraform Source code가 존재하는 git repository에 Push Webhook을 보내는 것으로 Tekton Pipeline을 시작합니다.
Tekton Dashboard에서 Tekton Pipeline이 정상적으로 실행되는 것을 확인합니다
Pipeline 상태를 보면 테라폼으로 인프라를 배포하는 "terraform apply" Task를 실행하기 전에 Pipeline이 멈추어 있는 것을 볼 수 있습니다. Pipeline은 "terraform plan" Task에서 terraform plan log를 확인하고 승낙 여부를 결정하기 위해 Approval Task에서 대기합니다.
이 상태에서 Approver로 지정된 Email의 메일함을 확인해보면 Approval을 요청하는 Notification mail이 온 것을 확인할 수 있습니다.
해당 Mail을 클릭하면 Approval을 기다리는 Pipelinerun의 이름을 확인할 수 있습니다. 아래의 "Go to approval task" 버튼을 통해 Approve 작업을 실행할 수 있는 Dashboard로 진입할 수 있습니다.
Approval Dashboard로 진입하면 해당 Task를 승낙, 혹은 거절 여부를 선택할 수 있습니다.
Approval 여부를 결정하기 위해 이전의 "terraform plan" Task에서 terraform plan 로그를 확인합니다.
plan 로그가 적절하다면 Tekton approval dashbaord에서 "Approve" 버튼을 클릭해 작업을 승낙합니다. 해당 Approval에 대한 Comment도 남길 수 있습니다.
Approve를 클릭하면 해당 Pipelinerun이 승낙되었음을 알리는 페이지를 볼 수 있습니다.
이후 Tekton Dashboard에서 Pipeline 상태를 보면 다음 Task가 실행되는 것을 확인할 수 있습니다. 이 DEMO의 경우 "terraform apply" Task를 실행해 테라폼 코드를 기반으로 인프라를 배포합니다.
추가적으로 Tekton Dashboard 좌측의 Extension -> Approval Tasks 페이지에서 현재까지 Approval Task 실행 내역을 확인할 수 있습니다.
Approval 내역을 클릭하면 YAML 페이지에서 Comment에 입력했던 내용과 승낙 여부, 승인자 등의 내용을 확인할 수 있습니다.
2. Tekton Approval 소개
이전 장에서 Tekton Approval을 활용한 Pipeline이 어떤 방식으로 흘러가는지 DEMO를 통해 확인해봤습니다.
그럼 이제 본격적으로 Tekton Approval이 무엇인지, 어떤 기능이 있는지 알아보겠습니다.
Tekton Approval을 개발한 Automatiko의 Blog를 참고하면 더 많은 정보를 얻을 수 있습니다.
https://blog.automatiko.io/2022/02/12/tekton-approvals.html
2-1. Automatiko Approval Task 개요
Tekton Pipeline을 사용하던 중 Manual Approval이 필요해 기능을 찾아봤지만, 아래 Tekton Issue에서 볼 수 있듯이 해당 기능이 Native하게 지원하지 않는다는 것을 알게 됐었는데요.
대체 기능을 찾던 중 Automatiko Approval Task를 알게 되어 사용 중입니다.
Tekton의 Roadmap에서는 Approval 기능의 지원 계획은 가지고 있지만 언제 출시될지 모르니 현재는 해당 Approval task를 유용하게 사용 중입니다.
https://github.com/tektoncd/pipeline/issues/2159
Automatiko 사의 Tekton Approval은 Tekton에 내장되어 있지 않은 Approval 기능을 사용할 수 있게끔 하기 위해 Tekton의 다양한 컴포넌트와 통합된 기능입니다.
Tekton Approval은 승인 절차를 구현하기 위해서 Tekton Pipeline, Tekton Dashboard, 그리고 Email을 통한 Notification 등의 기능들을 제공하고 있습니다.
2-2. Approval Task의 기능
Approval Task에서 Approval을 구현하기 위해 제공하는 기능들은 크게 다음과 같습니다.
- Custom Task를 통한 Tekton Pipeline과의 연동
- Extension을 통한 Tekton Dashboard와의 연동
- email을 통한 notification 기능
- Oauth2.0을 통한 Authentication 기능
- 다양한 Approval 전략 제공
위 기능들을 하나씩 알아보도록 하겠습니다.
2-2-1. Custom Task를 통한 Tekton Pipeline과의 연동
Tekton Approval은 Tekton의 확장 기능인 Custom Task 기능을 통해 Tekton Pipeline과 통합되어 있습니다.
Custom Task는 CRD(Custom Resource Definition)를 통해 기존의 Task가 아닌 다른 Task를 만들어서 사용할 수 있는 기능인데요.
Approval Task 또한 ApprovalTask라는 이름의 CRD로 정의되어 이를 참조해 사용할 수 있습니다.
apiservice에서는 "v1beta1.tekton.automatiko.io"로 Approval Task의 API를 확인할 수 있습니다.
다음은 "ApprovalTask" Custom Task를 이용한 Tekton Pipeline의 예입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
- name: approval
taskRef:
apiVersion: tekton.automatiko.io/v1beta1
kind: ApprovalTask
name: approvaltask
params:
- name: pipeline
value: "$(context.pipelineRun.name)"
- name: description
value: "Sample approval from pipeline $(context.pipeline.name)"
- name: approvers
value:
- "john"
|
cs |
"taskRef" Attribute에 아래와 같이 적어 Approval Task를 이용할 수 있습니다.
apiVersion: tekton.automatiko.io/v1beta1
kind: ApprovalTask
name: approvaltask
그리고 아래와 같은 Parameter들을 사용할 수 있습니다.
- pipeline - Approval Task가 포함된 pipeline명입니다.
- description - Approval Task를 설명하기 위한 설명란입니다.
- approvers - 승낙,혹은 거절 행위를 할 수 있는 승인자를 지정합니다. 지정된 승인자만이 승낙,혹은 거절을 할 수 있습니다. Appro Array를 이용해 여러명을 지정할 수 있으며 Username과 Email 계정을 사용할 수 있습니다. Oauth2.0 인증을 사용할 시 지정된 승인자만 인증을 수행할 수 있습니다.
- groups - 승낙,혹은 거절 행위를 할 수 있는 승인 Group을 지정합니다. approval과 groups는 동시에 사용할 수 없습니다.
- strategy - Approval 전략을 지정합니다. 현재는 SINGLE, MULTI, FOUR_EYES 전략을 제공하고 있습니다. 지정하지 않을 시 SINGLE 전략을 사용합니다.
2-2-2. Extension을 통한 Tekton Dashboard와의 연동
Tekton Approval을 Tekton Dashboard를 통해 Web UI 환경에서 확인할 수 있습니다.
Tekton Dashboard의 Extension 기능을 통해 Tekton Approval의 현황을 표시할 수 있는데요.
Tekton Dashboard Extension은 "Extension" CRD를 통해 대시보드상에 추가적인 리소스를 표시할 수 있는 기능입니다.
Tekton Approval Task를 대시보드에 표시하기 위한 Extension 리소스는 아래와 같이 확인할 수 있습니다.
여기에 추가적으로 Tekton Dashboard Service account에게 approval task 리소스를 표시하기 위해 필요한 권한들을 부여해야 하는데요.
아래와 같은 Approval Task에 대한 접근 권한들을 담은 Clusterrole을 Tekton Dashboar의 Service account에게 Binding하는 방식으로 권한을 부여할 수 있습니다.
Extension 리소스와 권한 부여를 모두 준비했다면 아래와 같이 Tekton Dashboard에서 Extension 탭 아래에 Approval Tasks가 추가된 것을 확인할 수 있습니다.
Approval Tasks에는 현재까지 진행된 Approval Task들의 목록을 볼 수 있으며, Overview 탭에서 각 Approval Task의 현재 상태(승낙, 거절, 진행 중)과 Description을 확인할 수 있습니다.
YAML 탭에서는 Approval Task의 yaml 매니페스트를 볼 수 있으며, 여기서 Approval 시 적었던 Comment와 해당 Approval Task의 Approval 작업을 할 수 있는 페이지 URL을 확인할 수 있습니다.
2-2-3. email을 통한 Notification 기능
Tekton Approval이 제공하는 기능 중에는 email을 통해 Approval 작업이 생성되었음을 알려주는 Notification 기능이 있습니다.
Notification 기능을 이용하기 위해서는 mail을 발신하기 위한 smtp 서버가 필요한데요.
직접 smtp 서버를 구성해 사용하거나, Google 등의 미리 준비된 smtp 서버를 사용할 수 있습니다.
메일은 지정된 Approver에게 발신해야 하며, 이 때문에 Notification 기능을 이용하면 Approver에는 Username이 아니라 아래와 같이 User email address를 사용해야만 합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
tasks:
- name: approval
taskRef:
apiVersion: tekton.automatiko.io/v1beta1
kind: ApprovalTask
name: approvaltask
params:
- name: pipeline
value: "$(context.pipelineRun.name)"
- name: description
value: "Sample approval from pipeline $(context.pipeline.name)"
- name: approvers
value:
- "john@email.com"
- "mary@email.com"
|
cs |
2-2-4. Oauth2.0을 통한 Authentication 기능
Tekton Approval은 기본적으로 Approval이 필요한 Pipelinerun명과 Approver의 이름만 알고 있으면 Approval 행위를 할 수 있습니다.
하지만 이들은 모두 확인하기 쉬운 정보들이기 때문에 승인되지 않은 User가 몰래 Approval을 할 수도 있다는 문제점이 존재하는데요.
이같은 문제를 해결하기 위해 Tekton Approval은 Oauth2 proxy를 통한 Oauth2.0 Authentication을 지원하고 있습니다.
Oauth2.0 인증을 사용하면 Google, MS, Okta 등의 Provider들에게서 인증 정보를 받은 뒤, 인증을 성공한 User만 Approval Dashboard에 접근하도록 할 수 있습니다.
이를 통해 Approval 행위를 하려면 Pipelinerun과 Approver 정보 뿐만이 아니라, 타 Provider에서 받은 인증 Token도 요구함으로써 보안성을 강화할 수 있습니다.
이 기능은 앞의 Email Notification과 연계하여 Approver의 Email로 Notification mail을 보내고 그 계정으로 Oauth2.0 인증까지 처리하는 방식으로 사용할 수도 있습니다.
2-2-5. 다양한 Approval 전략 제공
앞서 Tekton Approval은 "strategy" parameter를 사용해 Approval 전략을 지정할 수 있다고 했는데요.
Tekton Approval은 다양한 승인 전략을 제공하여 Approval에 필요한 절차 및 인원을 조정할 수 있습니다.
현재 제공되는 승인 전략 및 기능은 다음과 같습니다.
- SINGLE : 얼마나 많은 수의 Approver가 지정되어 있는지에 상관없이 단 한 명의 Approver가 승인 절차를 실행하면 그 결과를 토대로 Pipeline을 진행합니다. 아무 승인 전략도 지정되어 있지 않을 시 기본적으로 사용하는 전략입니다.
- MULTI : 지정된 Approver들이 모두 승낙 의사를 밝힐 시에만 Pipeline을 진행합니다. 하지만 Approver들 중 한 명이라도 거절 의사를 밝힐 시 Pipeline은 바로 중단됩니다.
- FOUR_EYES : "Four eyes principle"에 기반을 둔 전략으로, 승인 절차를 2단계로 구성해 진행합니다. 각 절차는 같은 Approver가 참여할 수 있으나 첫번째 절차에서 의사를 밝힌 인원은 두번째 절차에서 의사를 밝혀도 이를 반영하지 않습니다. Pipeline이 진행되려면 두 절차 모두 승낙되어야 하며, 첫번째 절차에서 거절 의사가 나오면 두번째 의사는 진행되지 않고 Pipeline이 중단됩니다.
3. Tekton Approval을 이용한 파이프라인 구성
지금까지 Tekton Approval이 어떤 특징과 기능이 있는지 알아봤습니다.
그럼 이제 본격적으로 Tekton Approval을 구성해 사용하는 방법에 대해 알아보겠습니다.
본 포스팅에서는 Tekton Pipeline의 구성에 대해서는 담고 있지 않습니다. 해당 내용에 대해 알고 싶다면 Tekton 사용해보기(1) Tekton으로 쿠버네티스에서 CI/CD 파이프라인을 구성해보자 등 Tekton 사용해보기 시리즈의 글을 참고 바랍니다.
Tekton Approval의 설치에 대한 자세한 내용은 공식 Github 페이지에서 확인할 수 있습니다.
https://github.com/automatiko-io/automatiko-approval-task
3-1. Tekton Approval 설치 및 구성
가장 먼저 Tekton Approval에 필요한 Kubernetes 오브젝트들을 구성해보겠습니다.
필요한 오브젝트들은 크게 Tekton Dashboard의 Extension을 위한 ClusterRole & ClusterRolebinding,
Tekton Approval의 CRD(CustomResourceDefinition),
그리고 Approval의 Oauth2.0 인증 및 메일 발신과 같은 핵심 기능을 담당하는 Deployment로 이루어져 있습니다.
3-1-1. Tekton Dashboard Extension 구성
먼저 Tekton Dashobard Extension에 Approval을 띄우기 위한 RBAC 오브젝트를 구성하겠습니다.
아래 Manifest를 적용합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: tekton-dashboard-approvaltasks-extension
rules:
- apiGroups: ["tekton.automatiko.io"]
resources: ["approvaltasks"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: tekton-dashboard-approvaltasks-role-binding
roleRef:
kind: ClusterRole
apiGroup: rbac.authorization.k8s.io
name: tekton-dashboard-approvaltasks-extension
subjects:
- kind: ServiceAccount
name: tekton-dashboard
namespace: tekton-pipelines
|
cs |
Manifest는 Tekton Dashboard의 ServiceAccount에 "approvaltasks" 리소스에 대한 get, list, watch 권한을 부여하는 Clusterrole & Clusterrolebinding으로 이루어져 있습니다.
이 구성을 통해 Tekton Dashboard가 Approval Task에 접근하여 대시보드에 Approval 리스트를 띄울 수 있습니다.
적용 뒤 Tekton Dashboard에 아래와 같이 Extensions -> Approval Tasks가 나타났다면 정상적으로 적용된 것입니다.
3-1-2. Tekton Approval CRD 구성
다음으로는 Tekton Approval 리소스를 정의하기 위한 CRD를 구성하겠습니다.
아래 Manifest를 적용합니다.
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
52
53
54
55
56
57
58
59
60
|
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: approvaltasks.tekton.automatiko.io
spec:
group: tekton.automatiko.io
names:
kind: ApprovalTask
plural: approvaltasks
singular: approvaltask
scope: Namespaced
versions:
- name: v1beta1
schema:
openAPIV3Schema:
properties:
spec:
properties:
strategy:
enum:
- FOUR_EYES
- MULTI
- SINGLE
type: string
approvers:
items:
type: string
type: array
groups:
items:
type: string
type: array
pipeline:
type: string
description:
type: string
type: object
status:
properties:
results:
properties:
decision:
type: string
comment:
type: string
type: object
status:
type: string
reason:
type: string
approvalUrl:
type: string
message:
type: string
type: object
type: object
served: true
storage: true
subresources:
status: {}
|
cs |
이 Manifest를 통해 ApprovalTask 리소스를 사용할 수 있습니다.
"kubectl get crd" 명령어를 실행했을때 아래와 같이 approvaltasks.tekton.automatiko.io가 리스트에 있다면 정상적으로 적용된 것입니다.
3-1-3. Tekton Approval Deployment 구성
마지막으로 Tekton Approval의 핵심 구성 요소인 Deployment를 구성해보겠습니다.
Approval Deployment는 Approval 기능과 oauth2 proxy Sidecar container를 이용한 Oauth2.0 인증, 그리고 메일 발송 기능을 담당합니다.
아래 Manifest를 적용합니다. Manifest는 메일 발송을 위한 SMTP 서버를 smtp.google.com으로, Oauth2.0 인증을 위한 Provider를 Google로 설정한 예시입니다.
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
|
---
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
app.quarkus.io/build-timestamp: 2022-02-05 - 11:22:03 +0000
labels:
app.kubernetes.io/version: 0.6.0
app.kubernetes.io/name: automatiko-approval-task
name: automatiko-approval-task
---
apiVersion: v1
kind: Service
metadata:
annotations:
app.quarkus.io/build-timestamp: 2022-02-05 - 11:22:03 +0000
labels:
app.kubernetes.io/name: automatiko-approval-task
app.kubernetes.io/version: 0.6.0
name: automatiko-approval-task
spec:
ports:
- name: http
port: 80
targetPort: 8888
selector:
app.kubernetes.io/name: automatiko-approval-task
app.kubernetes.io/version: 0.6.0
type: ClusterIP
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: automatiko-approval-task-view
roleRef:
kind: ClusterRole
apiGroup: rbac.authorization.k8s.io
name: view
subjects:
- kind: ServiceAccount
name: automatiko-approval-task
namespace: TEKTON_NAMESPACE
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: approvals-cluster-role
rules:
- apiGroups:
- tekton.automatiko.io
resources:
- approvaltasks
- approvaltasks/status
verbs:
- get
- list
- watch
- create
- delete
- patch
- update
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: josdk-crd-validating-cluster-role
rules:
- apiGroups:
- apiextensions.k8s.io
resources:
- customresourcedefinitions
verbs:
- get
- list
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: customruns-cluster-role
rules:
- apiGroups:
- tekton.dev
resources:
- customruns
- customruns/status
verbs:
- get
- list
- watch
- patch
- update
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: approvals-cluster-role-binding
roleRef:
kind: ClusterRole
apiGroup: rbac.authorization.k8s.io
name: approvals-cluster-role
subjects:
- kind: ServiceAccount
name: automatiko-approval-task
namespace: TEKTON_NAMESPACE
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: approvals-crd-validating-role-binding
roleRef:
kind: ClusterRole
apiGroup: rbac.authorization.k8s.io
name: josdk-crd-validating-cluster-role
subjects:
- kind: ServiceAccount
name: automatiko-approval-task
namespace: TEKTON_NAMESPACE
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: customruns-cluster-role-binding
roleRef:
kind: ClusterRole
apiGroup: rbac.authorization.k8s.io
name: customruns-cluster-role
subjects:
- kind: ServiceAccount
name: automatiko-approval-task
namespace: TEKTON_NAMESPACE
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: runs-crd-validating-role-binding
roleRef:
kind: ClusterRole
apiGroup: rbac.authorization.k8s.io
name: josdk-crd-validating-cluster-role
subjects:
- kind: ServiceAccount
name: automatiko-approval-task
namespace: TEKTON_NAMESPACE
---
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
app.quarkus.io/build-timestamp: 2022-02-05 - 11:22:03 +0000
labels:
app.kubernetes.io/version: 0.6.0
app.kubernetes.io/name: automatiko-approval-task
name: automatiko-approval-task
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/version: 0.6.0
app.kubernetes.io/name: automatiko-approval-task
template:
metadata:
annotations:
app.quarkus.io/build-timestamp: 2022-02-05 - 11:22:03 +0000
labels:
app.kubernetes.io/version: 0.6.0
app.kubernetes.io/name: automatiko-approval-task
spec:
volumes:
containers:
- env:
- name: KUBERNETES_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: QUARKUS_OPERATOR_SDK_NAMESPACES
value: default
- name: QUARKUS_AUTOMATIKO_SERVICE_URL
value: SERVICE_URL
- name: QUARKUS_PROFILE
value: securedwithemail
- name: QUARKUS_MAILER_FROM
value: FROM_MAILER_NAME
- name: QUARKUS_MAILER_HOST
value: smtp.gmail.com
- name: QUARKUS_MAILER_PORT
value: "587"
- name: QUARKUS_MAILER_USERNAME
value: MAILER_NAME
- name: QUARKUS_MAILER_PASSWORD
value: MAILER_PASSWORD
image: automatiko/automatiko-approval-task
imagePullPolicy: Always
name: automatiko-approval-task
livenessProbe:
failureThreshold: 3
httpGet:
path: /q/health/live
port: 8080
scheme: HTTP
initialDelaySeconds: 0
periodSeconds: 30
successThreshold: 1
timeoutSeconds: 10
name: automatiko-approval-task
ports:
- containerPort: 8080
name: http
protocol: TCP
readinessProbe:
failureThreshold: 3
httpGet:
path: /q/health/ready
port: 8080
scheme: HTTP
initialDelaySeconds: 0
periodSeconds: 30
successThreshold: 1
timeoutSeconds: 10
- name: oauth-proxy
args:
- --provider=google
- --redirect-url=REDIRECT_URL
- --http-address=:8888
- --email-domain=*
- --prefer-email-to-user=true
- --upstream=http://localhost:8080
- --client-id=CLIENt_ID
- --client-secret=CLIENT_SECRET
- --pass-access-token=true
- --cookie-secret=COOKIE_SECRET
- --cookie-secure=false
image: quay.io/oauth2-proxy/oauth2-proxy
readinessProbe:
failureThreshold: 3
httpGet:
path: /ping #Thus "/" path return 403, Define readinessProbe manually to define healthcheck path to "/ping"
port: 8888
scheme: HTTP
imagePullPolicy: IfNotPresent
ports:
- name: oauth-proxy
containerPort: 8888
protocol: TCP
serviceAccountName: automatiko-approval-task
|
cs |
위 Manifest는 Deployment 및 다양한 RBAC 리소스로 이루어져 있습니다.
Deployment를 적용하기 전에 각 컨테이너에 기입해야 할 Attribute를 수정해야 하는데요.
먼저 "Approval Task" 컨테이너의 Attribute 설명과 넣어야 할 주요 값의 리스트는 아래와 같습니다.
Attribute | Description | Value |
QUARKUS_AUTOMATIKO_SERVICE_URL | Approval Service의 URL | Approval Service의 호스트 네임 |
QUARKUS_MAILER_FROM | Notification Mail의 수신인 | Mail을 수신받을 계정 Mail |
QUARKUS_MAILER_HOST | Notification Mail을 발송할 smtp 서버 | smtp.gmail.com |
QUARKUS_MAILER_PASSWORD | Notification Mail의 발신인 PW* | Mail을 발신할 계정의 App password |
QUARKUS_MAILER_PORT | Notifcation Mail을 발송할 Port | 587 |
QUARKUS_MAILER_USERNAME | Notification Mail의 발신인 ID | Mail을 발신할 계정 Mail |
QUARKUS_OPERATOR_SDK_NAMESPACE | Approval Operator가 존재하는 Namespace | Namespace 명 |
QUARKUS_PROFILE | "secured"와 "securedwithemail" 값 선택 가능. 인증만 필요하면 secured, 인증과 메일 Notification이 필요하면 securedwithemail을 기입 | securedwithemail |
* Google 계정의 경우 일반 PW가 아닌 App Password를 발급받아 사용하는 것이 안전합니다. Google의 App Password에 대한 자세한 내용은 아래 링크를 참조하세요.
https://support.google.com/accounts/answer/185833?hl=en
다음은 oauth2 proxy 컨테이너의 Attribute 설명과 넣어야 할 주요 값의 리스트입니다.
Attribute | Description | Value |
provider | Oauth2.0 서비스 제공자 | |
redirect-url | Oauth2.0 Redirect URL* | Redirect URL |
http-address | HTTP Client가 Listen할 주소 | :8888 |
email-domain | 인증 메일의 도메인명 | * |
prefer-email-to-user | upstream으로 정보를 보낼 시, Emil 주소를 Username으로 보낼 지 여부 | true |
upstream | Upstream endpoint 주소 | http://localhost:8080 |
client-id | Oauth Client ID** | 발급받은 Oauth Client ID |
client-secret | Oauth Client Secret | 발급받은 Oauth Client Secret |
pass-access-token | Oauth access_token을 X-Forwarded_acces_Token 헤더로 보낼지 여부 | true |
cookie-secret | Cookie Secret 값*** | 발급받은 Cookie Secret |
cookie-secure | Secure Cookie 설정 여부 | false |
* Google의 경우 Oauth Origin URL에 "/oauth2/callback"을 붙인 값을 사용합니다.
** Google Cloud에서 발급받은 Oauth Client ID에서 Client ID값과 Client Secret을 사용합니다. 자세한 내용은 Tekton 사용해보기(3) Tekton Dashboard에 OIDC를 기반으로 RBAC 적용하기 에서 확인할 수 있습니다.
*** Cookie Secret을 생성하는 방법은 아래 oauth2 proxy 문서에서 확인할 수 있습니다.
https://oauth2-proxy.github.io/oauth2-proxy/docs/configuration/overview
Approval Deployment를 정의하는 Manifest에서 oauth-proxy 컨테이너의 readiness probe attribute는 기존에 존재하지 않았지만, 나중에 추가한 코드입니다.
GCP의 GKE 클러스터에서 이 구성을 적용할 경우, readiness probe를 정의하지 않으면 해당 Deployment와 연결된 GCP Load Balancer는 "/" Path로 HealthCheck를 보내게 됩니다. HealthCheck가 실패하면 Load Balancer는 Backend로 트래픽을 보내지 않습니다.
하지만 Oauth-proxy는 "/ping" Path에서 200을 return하도록 되어 있으므로, readiness probe를 따로 정의해서 "/ping" Path로 Probe를 보내 HealthCheck가 성공하도록 구성했습니다.
3-2. Tekton Approval Pipeline 사용
모든 구성을 마쳤으면 Tekton Approval을 사용할 수 있습니다.
가장 기본적인 사용 방법은 Tekton Pipeline에 Approval Task를 추가하는 것입니다.
아래는 Approval Task를 사용한 Terraform Deployment Pipeline의 예시입니다.
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: clone-terraform-cli
spec:
description: |
This pipeline clones a git repo, run "terraform plan" command based on .tf config file
params:
- name: repo-url
type: string
tasks:
- name: fetch-source
params:
- name: url
value: $(params.repo-url)
taskRef:
kind: Task
name: git-clone
workspaces:
- name: output
workspace: shared-data
- name: ssh-directory
workspace: ssh-key
- name: terraform-plan
params:
- name: chdir
value: ''
- name: ARGS
value:
- plan
runAfter:
- fetch-source
taskRef:
kind: Task
name: terraform-cli
workspaces:
- name: source
workspace: shared-data
- name: terraform-approval
params:
- name: pipeline
value: $(context.pipelineRun.name)
- name: description
value: Approval from pipeline $(context.pipeline.name) for development environment
- name: approvers
value:
- APPROVER_NAME
runAfter:
- terraform-plan
taskRef:
apiVersion: tekton.automatiko.io/v1beta1
kind: ApprovalTask
name: approvaltask
- name: terraform-apply
params:
- name: chdir
value: ''
- name: ARGS
value:
- apply
- '-auto-approve'
runAfter:
- terraform-approval
taskRef:
kind: Task
name: terraform-cli
when:
- input: $(tasks.terraform-approval.results.decision)
operator: in
values:
- 'true'
workspaces:
- name: source
workspace: shared-data
- name: terraform-rejected
params:
- name: decision
value: REJECTED
- name: comment
value: $(tasks.terraform-approval.results.comment)
runAfter:
- terraform-approval
taskRef:
kind: Task
name: print-decision
when:
- input: $(tasks.terraform-approval.results.decision)
operator: in
values:
- 'false'
workspaces:
- name: shared-data
- name: ssh-key
|
cs |
위 Manifest에 사용된 Approval 관련 Attribute와 값은 아래와 같습니다.
Attribute : Key | Description | Value |
params.name : decision | Approval Task의 PIpeline명 | $(context.pipeline.name) |
params.name : description | Approval Task의 설명 | Approval을 설명할 문구를 기재 |
params.name : approver | Approval을 실행할 계정, 기재되지 않은 계정이 Approval을 시도할시 인증에 실패 | Approver 계정 Email |
runAfter | Approval을 실행하기 전 Task명 | terraform-plan |
taskRef | 참조할 Tekton Task | apiVersion: tekton.automatiko.io/v1beta1 kind: ApprovalTask name: approvaltask |
위 Pipeline을 실행했을 시, Dashboard의 Approval Tasks란에 아래와 같이 Task가 추가되면 성공적으로 적용된 것입니다.
Approval Task가 실행될 차례가 되면 Email로 Notification이 오며, Approval을 진행할 수 있는 Dashboard에서 의사 결정을 내릴 수 있습니다.
4. 마무리
지금까지 Tekton Approval Task로 Tekton에서 Human Approval 기능을 구현하는 방법에 대해 알아봤습니다.
Tekton은 현재 Native하게 제공되는 Approval 기능이 없지만, Extension과 CRD를 이용한 Tekton Approval을 통해 Task가 실행되기 전 Email Notification로 승인 절차를 밟을 수 있게 됩니다.
아직 Web UI에서 승인 절차를 밟을 수 없다는 점, Approval을 처리해야 할 Deployment가 따로 구성되어 있어야 한다는 점 등 단점이 존재하기는 하지만, 아직 나온지 얼마 안된 기능이기 때문에 발전의 여지가 있는 것 같습니다.
이 포스팅을 보시는 분들이 Tekton으로 Approval 기능을 구현하는데 도움을 받으셨으면 합니다.
'Devops' 카테고리의 다른 글
Argo 사용해보기 (1) Argo Project로 CI/CD Pipeline을 구성해보자 (0) | 2023.04.29 |
---|---|
컨테이너 빌드 도구 선택을 위한 특성 및 성능 비교 (Kaniko, Buildah, Buildkit) (5) | 2023.03.26 |
Terraform으로 Replace없는 GCP Compute Instance 부트 디스크를 구성하는 방법 (0) | 2023.01.29 |
Tekton 사용해보기 (4) GCP Terraform 인프라를 Validation하는 파이프라인 구축하기 (0) | 2022.12.31 |
Tekton 사용해보기 (3) Tekton Dashboard에 OIDC를 기반으로 RBAC 적용하기 (0) | 2022.11.13 |