์กธ์
ํ๋ก์ ํธ๋ฅผ ์งํํ๋ฉฐ Spring Boot ์ดํ๋ฆฌ์ผ์ด์
์ ๋ํ CI/CD๋ฅผ ๊ตฌ์ถํด์ผํ๋ ๋์ฆ๊ฐ ์์๊ณ ๋ค์ํ ๋๊ตฌ๋ค์ ์ดํด๋ณด๋ค๊ฐ ์ฟ ๋ฒ๋คํฐ์ค์ ์นํ์ ์ธ Argo ํ๋ก์ ํธ๋ฅผ ์ฌ์ฉํ์์ต๋๋ค. ์ด๋ฒ ๊ธ์์๋ Argo Project์ธ Argo Event
์ Argo Workflow
๋ฅผ ์ด์ฉํ CI์ Argo CD
๋ฅผ ์ด์ฉํ CD ์ํคํ
์ณ๋ฅผ ๊ตฌ์ถํ๋ ๊ณผ์ ์ ๋ํด ๋ค๋ค๋ณด๊ณ ์ ํฉ๋๋ค.
CI Overview
์ด๋ฒ ๊ธ์์ ๊ตฌ์ถํ CI ๊ณผ์ ์ ๊ฐ๋ตํ๊ฒ ์๊ฐํ๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- Github Webhook๋ฅผ Argo Event๊ฐ ๋ฐ์ CI Workflow ํ์ฑํ
- ์ ํ๋ฆฌ์ผ์ด์ ๋จ์ ํ ์คํธ ์ํ
- ๋์ปค ์ด๋ฏธ์ง ๋น๋
- GCR์ ์ด๋ฏธ์ง ํธ์
- Deploy Repository์ Kustomize ํ์ผ ์์ (์ต์ ํ๊ทธ๋ฅผ ๋ฐ์ํ ์ด๋ฏธ์ง)
- Deploy Repository์ Pull Request ์์ฑ
Argo Event
์ด์ Github์ Webhook์ ํตํด Push Event๋ฅผ ๋ฐ๋ Argo Event
๋ฅผ ์์ฑํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
Argo Event Architecture
๋จผ์ Argo Event
์ ์ํคํ
์ณ๋ ์๋ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ต๋๋ค.
์ถ์ฒ : https://argoproj.github.io/argo-events/concepts/architecture/
Argo Event
์ ์ปดํฌ๋ํธ๋ ๋ค์๊ณผ ๊ฐ์ ์ญํ ์ ์ํํฉ๋๋ค.
- Event Source
์ธ๋ถ๋ก๋ถํฐ ๋ฐ์ ์ด๋ฒคํธ์ ๋ํ ์ค์ ์ ์ ์ํฉ๋๋ค. - Eventbus
Event Source
์Event Sensor
๋ฅผ ์ฐ๊ฒฐํ๊ธฐ ์ํ ์ ์ก ๊ณ์ธต์ผ๋ก ๋์ํฉ๋๋ค. - Event Sensor
event dependency์ ์งํฉ๊ณผ trigger๋ฅผ ์ ์ํฉ๋๋ค. ์ฌ๊ธฐ์ event dependency ์งํฉ์ input, trigger๋ output์ ๊ฐ๋ ์ผ๋ก ์๊ฐํ๋ฉด ๋ฉ๋๋ค. - Trigger
Event Sensor
์ ์ํด ์ํ๋ ํ๋์ ์๋ฏธํฉ๋๋ค.
Custom Resource ์ค์น
๋จผ์ ํ์ํ Argo Event
CR์ ๋ค์ด๋ฐ์ต๋๋ค.
> kubectl apply -f \
https://raw.githubusercontent.com/argoproj/argo-events/stable/manifests/namespace-install.yaml
Event Bus ๋ฐฐํฌ
๋ค์์ผ๋ก Event Source
์ Event Sensor
๊ฐ์ ๋ฐ์ดํฐ ์ ์ก์ ์ํ Event Bus
์ ๋ฐฐํฌํฉ๋๋ค.
kubectl apply -n argo-events -f \
https://raw.githubusercontent.com/argoproj/argo-events/stable/examples/eventbus/native.yaml
Github Argo Event ์ฐ๋
admin:repo_hook
๊ถํ์ ๊ฐ์ง Github API ํ ํฐ์ ์์ฑํ๊ณ ์ธ์ฝ๋ฉํ์ฌ argo-events
๋ค์์คํ์ด์ค์ ์ํฌ๋ฆฟ์ผ๋ก ๋ฑ๋กํฉ๋๋ค.
Encoding
echo -n <api-token-key> | base64
github-access
apiVersion: v1
kind: Secret
metadata:
name: github-access
namespace: argo-events
type: Opaque
data:
token: <access token>
username: <github username>
password: <github password>
Event Source
argo event repo๋ฅผ ์ฐธ๊ณ ํ github event-source
๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- event-source.yaml
apiVersion: argoproj.io/v1alpha1
kind: EventSource
metadata:
component: github-event-source
name: github-event-source
namespace: argo-events
spec:
type: "github"
github:
source_repo:
# owner of the repo
owner: seongpyoHong
# repository name
repository: argo-ci-cd
# Github will send events to following port and endpoint
webhook:
# endpoint to listen to events on
endpoint: /push
# port to run internal HTTP server on
port: "12000"
# HTTP request method to allow. In this case, only POST requests are accepted
method: POST
# url the event-source will use to register at Github.
# This url must be reachable from outside the cluster.
# The name for the service is in `<event-source-name>-eventsource-svc` format.
# You will need to create an Ingress or Openshift Route for the event-source service so that it can be reached from GitHub.
url: "http://github-event-source-eventsource-svc.argo-events.svc:12000"
# type of events to listen to.
# following listens to everything, hence *
# You can find more info on https://developer.github.com/v3/activity/events/types/
events:
- "push"
# apiToken refers to K8s secret that stores the github api token
apiToken:
# Name of the K8s secret that contains the access token
name: github-access
# Key within the K8s secret whose corresponding value (must be base64 encoded) is access token
key: token
# type of the connection between event-source and Github.
# You should set it to false to avoid man-in-the-middle and other attacks.
insecure: true
# Determines if notifications are sent when the webhook is triggered
active: true
# The media type used to serialize the payloads
contentType: json
๊ธฐ์กด์ ์กด์ฌํ๋ Gateway๋ผ๋ CR์ ํตํด Event Source์ Event Sensor๋ฅผ ์ฐ๊ฒฐํด์ฃผ๋ ์๋น์ค๋ฅผ ์์ฑํ์์ง๋ง, ์ต์ ๋ฆด๋ฆฌ์ฆ ๋ฒ์ ์์๋ Gateway๊ฐ event source์ ํฌํจ๋์๊ธฐ ๋๋ฌธ์ ๋ฐ๋ก ์์ฑํ์ง ์์๋ ๋ฉ๋๋ค.
- event-source-svc
apiVersion: v1
kind: Service
metadata:
name: github-event-source-eventsource-svc
namespace: argo-events
spec:
selector:
eventsource-name: github-event-source
ports:
- port: 12000
targetPort: 12000
type: LoadBalancer
๊ณต์ ๋ฌธ์๋ฅผ ์ฐธ๊ณ ํ๋ฉด Github์ webhook์ด ์ ๊ทผํ ์ ์๋ ์๋น์ค๋ฅผ ์ ์ํด์ผํฉ๋๋ค. ์ด๋ฅผ ์ํด <event-source-name>-eventsource-svc
๋ผ๋ ์ด๋ฆ์ service๋ฅผ ํตํด ๋
ธ์ถํฉ๋๋ค.
Event Sensor ์์ฑ
๋ค์์ผ๋ก Github Event Source
๋ฅผ ๋ฐ์์ ์ค์ ๋ Trigger
๋ฅผ ์ํํ๋ Event Sensor
๋ฅผ ์์ฑํฉ๋๋ค. CI ๊ณผ์ ์ ์ ๋ถ ์ํํ๊ธฐ ์ ์ ์์ ๊ฐ๋จํ๊ฒ Pod์ ์์ฑํ๋ trigger๋ฅผ ์ค์ ํ์ฌ ํ
์คํธ ํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
- Event Sensor (Pod Create)
apiVersion: argoproj.io/v1alpha1
kind: Sensor
metadata:
name: webhook
namespace: argo-events
spec:
template:
serviceAccountName: argo-events-sa
dependencies:
- name: test-dep
eventSourceName: github-event-source
eventName: source_repo
triggers:
- template:
name: webhook-pod-trigger
k8s:
group: ""
version: v1
resource: pods
operation: create
source:
resource:
apiVersion: v1
kind: Pod
metadata:
generateName: hello-world-
spec:
serviceAccountName: argo-events-sa
containers:
- name: hello-container
args:
- "hello-world"
command:
- cowsay
image: "docker/whalesay:latest"
parameters:
- src:
dependencyName: test-dep
dest: spec.containers.0.args.0
์ด์ ๋ฑ๋กํ Repository์์ event๋ฅผ ๋ณด๋ด๋ฉด Event Source
์ Event Sensor
๋ ๋ค์๊ณผ ๊ฐ์ ๋ก๊ทธ๋ฅผ ๋ณด์ฌ์ค๋๋ค.
Event Source Log
{"level":"info","ts":1604321990.023797,"logger":"argo-events.eventsource","caller":"webhook/webhook.go:187","msg":"new event received, dispatching it...","eventSourceName":"github-event-source","eventSourceType":"github","eventName":"source_repo","eventSourceName":"github-event-source","eventName":"source_repo"}
Event Sensor Log
{"level":"info","ts":1604321990.0337672,"logger":"argo-events.sensor","caller":"standard-k8s/standar-k8s.go:163","msg":"creating the object...","sensorName":"webhook"} {"level":"info","ts":1604321990.055359,"logger":"argo-events.sensor","caller":"sensors/listener.go:266","msg":"successfully processed the trigger","sensorName":"webhook","triggerName":"webhook-pod-trigger"}
CI๋ฅผ ์ํ Trigger ์ค์
Pod์ ์์ฑํ๋ Trigger
์์ ์ด์ CI ์์
(Run Test, Build Docker Image, Push Image to Registry)๋ฅผ ์ํํ๋๋ก ๋ณ๊ฒฝํด๋ณด๊ฒ ์ต๋๋ค. ์ด ๋, Trigger
๋ Argo Workflow
๋ฅผ ํ์ฉํ์ฌ Unit Test, Docker Image Build, Docker Image Push ์์
์ ์ํํ๋๋ก ์ค์ ํด๋ณด๋ ค๊ณ ํฉ๋๋ค.
Why Argo Workflow?
CI์ ์ฌ์ฉ๋๋ Argo Workflow
๋ ์ด๋ฐ ์ฅ์ ๋ค์ ๊ฐ์ง๊ณ ์์ต๋๋ค.
- ๊ฐ ๋จ๊ณ์ Job์ด ์๋ก ๋ค๋ฅธ ์ปจํ ์ด๋์์ ๊ฐ๋ณ์ ์ผ๋ก ์ด๋ฃจ์ด์ง๊ธฐ ๋๋ฌธ์, ์คํ ํ๊ฒฝ์ ๋ ๋ฆฝ์ฑ์ด ๋ณด์ฅ๋ฉ๋๋ค.
- ํ๋์ ์ญํ ๋ง์ ๋ด๋นํ๋ Job์ ๋ ๋ฆฝ์ ์ผ๋ก ๊ฐ๋ฐํ ์ ์๊ณ ์ด๋ก ์ธํด ์ฌ์ฌ์ฉ์ฑ์ ๋์ผ ์ ์์ต๋๋ค.
ํ์ง๋ง, ๋ชจ๋ ๊ธฐ์ ์ ์ฅ๋จ์ ์ด ์๋ฏ์ด Argo Workflow
์ ๋ํ ๋จ์ ๋ ์กด์ฌํฉ๋๋ค.
- ๊ฐ Job์ ๋ ๋ฆฝ๋ Pod์ ์์ฑ์ด ํ์ํฉ๋๋ค. ๋ฐ๋ผ์ Pod์ ์์ฑ๊ณผ ์ญ์ ์ ๋ํ ์ค๋ฒํค๋๋ฅผ ๊ณ ๋ คํด์ผ ํฉ๋๋ค.
- Job๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ๊ณต์ ํ๊ธฐ ์ํ ์ถ๊ฐ Artifact๊ฐ ํ์ํฉ๋๋ค.
https://coffeewhale.com/kubernetes/workflow/argo/2020/02/14/argo-wf/ ๊ธ์ ์ฐธ๊ณ ํ์์ต๋๋ค.
Argo Workflow ์ค์น
๋จผ์ Argo Workflow
์คํ์ ์ํด ํ์ํ CR๋ค์ ๋ค์ด๋ฐ์ต๋๋ค. ์ด๋ namespace๋ argo
๋ก ์ค์ ํฉ๋๋ค.
> kubectl create ns argo
> kubectl apply -n argo -f \
https://raw.githubusercontent.com/argoproj/argo/stable/manifests/namespace-install.yaml
์ดํ CI/CD ๊ณผ์ ์์ git repository์ ์ ๊ทผํ๊ธฐ ์ํด ํ์ํ ์ ๋ณด๋ค์ secret
์ผ๋ก ์ ์ํด์ค๋๋ค.
- source / deploy repository์ ๋ํด ssh private key๊ฐ ํ์ํ๋ฏ๋ก 2๊ฐ์ ์ํฌ๋ฆฟ ์์ฑํฉ๋๋ค.- ssh-privatekey(source repo)
- ssh-privatekey (deploy key)apiVersion: v1 kind: Secret metadata: name: source-key namespace: argo type: Opaque data: ssh-privatekey: <ssh private key for source repository>
apiVersion: v1 kind: Secret metadata: name: deploy-key namespace: argo type: Opaque data: ssh-privatekey: <ssh private key for deploy repository>
- repository์ push, commit, pull request๋ฅผ ์ํํ๊ธฐ ์ํ ์ ๋ณด๋ฅผ ๋ด์ secret์ ์์ฑํฉ๋๋ค.
- github-access
apiVersion: v1 kind: Secret metadata: name: github-access namespace: argo-events type: Opaque data: token: <access token> username: <github username> password: <github password>
๋ค์์ผ๋ก ํ
์คํธ๊ฐ ์๋ฃ๋ ์ด๋ฏธ์ง๋ฅผ GCR์ pushํ๊ณ , artifacts๋ฅผ ์ ์ฅํ๊ธฐ ์ํ ์ ์ฅ์๋ก GCS๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํ ๊ถํ์ด ๋ด๊ฒจ์๋ gcp credential secret์ ์์ฑํฉ๋๋ค. ์๋์์ google.json
์ GCS์ GCR์ ๋ํ IAM์ ์ค์ ํ ๊ตฌ๊ธ ์๋น์ค ๊ณ์ ์ ํค ํ์ผ์
๋๋ค. GCP์ ์๋น์ค ๊ณ์ ์ ๋ํด์ ์์ธํ ์ค๋ช
์ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ์๊ธฐ ๋ฐ๋๋๋ค.
> kubectl create secret generic argo-gcp --namespace=argo --from-file=google.json
WorkflowTemplate
workflowTemplate
์ workflow
๋ฅผ ๋ฏธ๋ฆฌ ์ ์ํด๋์ ๋ฆฌ์์ค๋ก event sensor
์์ ๊ฐ์ ธ๋ค ์ธ ์ ์๋๋ก ํด์ค๋๋ค.
CI ๊ณผ์ ์์ ํ์ํ workflowTemplate
์ ์ ์ํ๊ณ event sensor
์ trigger
์์ ๊ฐ ๋จ๊ณ์ ํ์ํ Argo Workflow
๋ฅผ ์์ฑํ๋๋ก ์์ ํฉ๋๋ค.
์ฃผ์ํ ์
1. ClusterRole ์์ฑnamespace-install.yaml
์ผ๋ก ์ค์นํ argo-event-sa
์๋น์ค ๊ณ์ ์ argo
๋ค์์คํ์ด์ค์ ๋ฆฌ์์ค์ ์ ๊ทผํ ๊ถํ์ด ์๊ธฐ ๋๋ฌธ์ clusterRoleBindind
์ ํตํด ์ ๊ทผ ๊ถํ์ ์ค์ ํด์ค์ผ ํฉ๋๋ค.
- ClusterRole & ClusterRoleBinding
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: argo-cluster-role
rules:
- apiGroups:
- argoproj.io
resources:
- workflows
- workflowtemplates
verbs:
- create
- get
- list
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: argo-trigger
namespace: argo
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: argo-cluster-role
subjects:
- kind : ServiceAccount
name: argo-events-sa
namespace: argo-events
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: argo-trigger
namespace: argo-events
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: argo-cluster-role
subjects:
- kind : ServiceAccount
name: argo-events-sa
namespace: argo-events
2. Default Artifact ๋ฑ๋ก
Job ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ์ ๋, parameter
์ artifact
๋ฅผ ํตํด์ ์ฃผ๊ณ ๋ฐ์ ์ ์์ต๋๋ค. ์ด ์ค artifact
๋ฅผ ์ด์ฉํ๋ ค๋ฉด mino, s3, gcs์ ๊ฐ์ object storage๋ฅผ default artifact๋ก ์ค์ ํด์ค์ผ ํฉ๋๋ค.
๊ณต์ ๋ฌธ์๋ฅผ ์ฐธ๊ณ ํ GCS ์ค์ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. ์ ๋ GCS์ ๋ํ ๊ถํ๊ณผ GCR์ ๊ถํ์ ๋ชจ๋ ํ๋์ ์๋น์ค ๊ณ์ ์ ์ค์ ํ๊ธฐ ๋๋ฌธ์ GCR์ ๋ํ secret์ ์์ฑํ ๋์ ๊ฐ์ credential์ ์ฌ์ฉํ์ต๋๋ค.
$ kubectl edit configmap workflow-controller-configmap -n argo # assumes argo was installed in the argo namespace
...
data:
artifactRepository: |
gcs:
bucket: argo-ci-artifacts
endpoint: storage.googleapis.com
serviceAccountKeySecret:
name: argo-gcp
key: google.json
์ฝ๋
์ ์ฒด ์ฝ๋๋ ๋๋ฌด ๊ธธ์ด ๋งํฌ๋ฅผ ์ฐธ์กฐํฉ๋๋ค.
๊ฐ WorkflowTemplate
์ ๋ํ ๊ธฐ๋ฅ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- git-checkout-private
source repository๋ฅผ artifact์ checkout ํ๊ณ , commit id๋ฅผ ํตํด docker image์ ์ฌ์ฉํ tag๋ฅผ ์์ฑ - run-test
์ด ๊ธ์์๋ Spring Boot ์ดํ๋ฆฌ์ผ์ด์ ์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ gradle์ ํตํด ์์ฑ๋ ๋จ์ ํ ์คํธ๋ฅผ ์ํํ๊ณ ๋ชจ๋ ์ฑ๊ณต ์ jar ํ์ผ์ ์์ฑํด artifact์ ์ ์ฅ - build-and-push
๋จ์ ํ ์คํธ๊ฐ ์ฑ๊ณตํ source repository์ dockerfile์ ํตํด ์ด๋ฏธ์ง๋ฅผ ๋น๋ํ๊ณ GCR์ ํธ์ - git-new-branch
deploy repository์ ์๋ก์ด branch ์์ฑ - kustomize-image
deploy repository์ ์๋kustomization.yaml
ํ์ผ์ ์์ ๊ณผ์ ์์ ํธ์๋ ์ด๋ฏธ์ง๋ฅผ ์ฌ์ฉํ๋๋ก ํ๊ทธ ์์ - git-commit
deploy repository์ ๋ณ๊ฒฝ ์ฌํญ์ commit - git-pr
deploy repository์ Pull Request๋ฅผ ์์ฑ
Argo Server (UI)
CI๋ฅผ ์ํํ ๊ฒฐ๊ณผ๋ฅผ UI๋ก ๋ณด๊ณ ์ถ๋ค๋ฉด argo
namespace์ argo-server
๋ฅผ ์ธ๋ถ๋ก ๋
ธ์ถ์์ผ ์ ์ํ๋ฉด ๋ฉ๋๋ค. ์์ ์ค์ ์ ํตํ ๊ฒฐ๊ณผ ํ๋ฉด์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
Argo CD
Argo CD
๋ GitOps
๋ฐฉ์์ ์ง์ํ๋ CD ๋๊ตฌ์
๋๋ค.
GitOps๋?
GitOps
๋ ์ฟ ๋ฒ๋คํฐ์ค ๋ฆฌ์์ค์ ๋ํ ๋ฉ๋ํ์คํธ ์ ์ฅ์๋ก github์ ์ฌ์ฉํ๋ ๋ฐฉ์์ ์๋ฏธํฉ๋๋ค.
์ถ์ฒ : https://www.weave.works/technologies/gitops/
SSOT
GitOps์ ์ฅ์ ์ ๋ณด๊ธฐ ์ ์ SSOT(Single Source Of Truth)
, ๋จ์ผ ์ง์ค์ ์์ฒ์ ๋ํด ๋จผ์ ์์๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
๋จ์ผ ์ง์ค์ ์์ฒ์ด๋ ์ด๋ค ์ง์ค์ ๋ํ ์์ฒ์ด ๋จ ํ๋๋ง ์กด์ฌํ๋ค๋ ์๋ฏธ๋ก GitOps
๋ ๋ชจ๋ ๋ฐฐํฌ๋ฅผ ์ํ ์ ์๋ฅผ Git์์ ๊ด๋ฆฌํ์ฌ SSOT
๋ฅผ ๋ฐ๋ฆ
๋๋ค.
SSOT๋ฅผ ํตํด ์ป์ ์ ์๋ ์ฅ์ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
1. ๋ฐฐํฌ๋ฅผ ์ํ ์ ์๊ฐ Git์ ๋ชจ๋ ์กด์ฌํ๊ธฐ ๋๋ฌธ์ ํ์ฌ ์ํ๋ฅผ ํ์
ํ๊ธฐ ์ฝ์ต๋๋ค.
2. ๋ฐฐํฌ ๋ฐฉ๋ฒ์ ํต์ผํ์๊ธฐ ๋๋ฌธ์ ์๋ํ๊ฐ ์ฉ์ดํ๋ฉฐ, ์ฌ๋ฌ ๋ฐฐํฌ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ์ ๋ ๋ฐ์ํ ์ ์๋ ์ค์๊ฐ ์ค์ด๋ญ๋๋ค.
https://coffeewhale.com/kubernetes/workflow/argo/2020/02/14/argo-wf/ ๊ธ์ ์ฐธ๊ณ ํ์์ต๋๋ค.
GitOps์ ์ฅ์ ?
weavework์ ๋ฌธ์๋ฅผ ์ฐธ๊ณ ํ GitOps์ ์ฅ์ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- ์์ฐ์ฑ ํฅ์
ํตํฉ ํผ๋๋ฐฑ ์ ์ด ๋ฃจํ๋ฅผ ํตํ ์ง์์ ์ธ ๋ฐฐํฌ ์๋ํ๋ ํ๊ท ๋ฐฐํฌ ์๊ฐ์ ๋จ์ถํ ์ ์์ต๋๋ค. - ํฅ์๋ ๊ฐ๋ฐ์ ํ๊ฒฝ
๊ฐ๋ฐ์๋ค์ Git์ ์ฌ์ฉํ์ฌ kubernetes์ ๋ด๋ถ๋ฅผ ์ ํ์ ์์ด kubernetes์ ๋ํ ์ ๋ฐ์ดํธ์ ๊ธฐ๋ฅ์ ๋ณด๋ค ์ ์ํ๊ฒ ๊ด๋ฆฌํ ์ ์์ต๋๋ค. - ๊ฐ์ ๋ ์์ ์ฑ
Git ์ํฌํ๋ก์ฐ๋ฅผ ์ฌ์ฉํ์ฌ ํด๋ฌ์คํฐ๋ฅผ ๊ด๋ฆฌํ๋ฉด Kubernetes ์ธ๋ถ์์ ๋ชจ๋ ํด๋ฌ์คํฐ ๋ณ๊ฒฝ์ ๋ํ ํธ๋ฆฌํ ๊ฐ์ฌ ๋ก๊ทธ๋ฅผ ์ป์ ์ ์์ต๋๋ค. - ๋์ ์ ๋ขฐ์ฑ
Git์ rollback/revert ๋ฐ fork ๊ธฐ๋ฅ์ ํตํด ์์ ์ ์ด๊ณ ์ฌํ ๊ฐ๋ฅํ ๋กค๋ฐฑ์ ์ป์ ์ ์์ต๋๋ค. ๋ํ ์ ์ฒด ์์คํ ์ดGit์ ๊ธฐ๋ก๋์ด ์๊ธฐ ๋๋ฌธ์ ์ฅ์ ๋ฐ์ ํ ๋ณต๊ตฌํด์ผ ํ๋ ๋จ์ผ ์ถ์ฒ๋ ์์ผ๋ฏ๋ก ๋ณต๊ตฌ(MTTR)์๊ฐ์ ๋จ์ถํ ์ ์์ต๋๋ค. - ์ผ๊ด์ฑ ๋ฐ ํ์คํ
CI, CD๋ฅผ ํฌํจํ ์ด์์ ๋ฌด๊ฐ Git์ ํตํด์ ์ผ๊ด๋๊ฒ ๊ด๋ฆฌ๋ฉ๋๋ค.
์ด์ Argo CD๋ฅผ ์ค์นํ๊ณ CI ์์ ๊ฒฐ๊ณผ๋ฌผ์ธ ๋ฉ๋ํ์คํธ ํ์ผ์ ํตํด ๋ฐฐํฌ๋ฅผ ์งํํด๋ณด๊ฒ ์ต๋๋ค.
Install
๋จผ์ ์๋ ๋ช
๋ น์ด๋ฅผ ํตํด Argo CD
๋ฅผ ์ํ CR์ ์์ฑํ๊ณ UI์ ์ ๊ทผํ๊ธฐ ์ํด argocd-server
์ ์๋น์ค ํ์
์ LoadBalancer
๋ก ๋ณ๊ฒฝํฉ๋๋ค.
kubectl create namespace argocd kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'
Setting
Argo CD
์ค์ ์ UI๋ฅผ ํตํด์ ์ํํ ์ ์์ต๋๋ค. UI๊ฐ ๊ทธ๋ฆฌ ์ด๋ ต์ง ์์ผ๋ ๋ฉ์ธ ํ์ด์ง์ New App์ ํด๋ฆญํด์ ์ ๋ณด๋ฅผ ์
๋ ฅํด๋ณด๋๋ก ํฉ๋๋ค.
์ด ์์
์ UI๊ฐ ์๋ ์ฝ๋๋ก ๊ด๋ฆฌํ๋ ค๋ฉด Argo CD๊ฐ ์ ๊ณตํ๋ Application
CR์ ์ ์ํ์ฌ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค. Application
CR์ ๋ฉ๋ํ์คํธ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: spring-boot
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
syncPolicy:
automated:
prune: true
selfHeal: true
project: default
source:
repoURL: <SSH address of deploy repository>
targetRevision: master
path: .
destination:
server: https://kubernetes.default.svc
namespace: default
์ด ๋, Private Repository๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์๋ ssh private key๋ username/password secret์ด ํ์ํฉ๋๋ค. argocd docs๋ฅผ ์ฐธ๊ณ ํ์ฌ repository์ ๋ํ ์ค์ ์ด ๋ด๊ฒจ์๋ ConfigMap
์ ์์ฑํฉ๋๋ค.
repository.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
labels:
app.kubernetes.io/name: argocd-cm
app.kubernetes.io/part-of: argocd
data:
repository: |
- url: <deploy repository url>
sshPrivateKeySecret:
name: deploy-key
key: sshPrivateKey
์ฌ๊ธฐ์ ์ฃผ์ํ ์ ์ repository์ http ์ฃผ์๊ฐ ์๋ url์ ์ ๋ ฅํด์ผ ํฉ๋๋ค.
Result
์์์ ์ ๋ ฅํ ์ ๋ณด์ ๋ฐ๋ผ Springboot Deployment์ Service๊ฐ ๋ฐฐํฌ๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
TODO
sprintboot์์ ํ์ํ GCS ์ ๊ทผ ๊ถํ์ GKE Workload Identity๋ฅผ ํตํด service account๋ก ํด๊ฒฐํ๋ ค ํ์ต๋๋ค. ํ์ง๋ง application layer์์ ์ธ์ฆ์ ์ฌ์ฉํ ๋์๋ service account๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ํ๊ฒฝ ๋ณ์์ธ GOOGLE_APPLICATION_CREDENTIALS
์ ํตํด key.json
์ ์ฐพ๊ฒ ๋์ด GCS API์ ๋ํด 403์๋ฌ๊ฐ ๋ฐ์ํ์๊ณ , ์ด์ ๋ฐ๋ผ secret์ ๋ฏธ๋ฆฌ ์ค์ ํด๋๋ ๋ฐฉ์์ ์ฌ์ฉํ์์ต๋๋ค. ์ด ๋ถ๋ถ์ ๋ํด์๋ CD ๊ณผ์ ์์ Secret์ ๊ด๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ๋ํด Best Practice๋ฅผ ์์๋ณด๊ณ ์ ์ฉํ๋ ๊ณผ์ ์ด ํ์ํฉ๋๋ค.
๋ธ๋ก๊ทธ์ ์ฌ์ฉ๋ ๋ชจ๋ ์ฝ๋๋ Github์ ์กด์ฌํฉ๋๋ค.
์ฐธ๊ณ ์๋ฃ
- https://www.arctiq.ca/our-blog/2020/7/13/ci-cd-with-argo/
- https://medium.com/axons/ci-cd-with-argo-on-kubernetes-28c1a99616a9
- https://argoproj.github.io/argo/
- https://argoproj.github.io/argo-events/
- https://argoproj.github.io/argo-cd/
- https://www.weave.works/technologies/gitops/
- https://coffeewhale.com/kubernetes/workflow/argo/2020/02/14/argo-wf/
'๐ Kubernetes' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Dynamic Admission Controller ์ฌ์ฉํ๊ธฐ (0) | 2021.04.29 |
---|---|
[Kubernetes ๋ด๋ถ ๊ตฌ์กฐ ์ดํดํ๊ธฐ] 1. ์ฟ ๋ฒ๋คํฐ์ค ํด๋ฌ์คํฐ ๊ตฌ์ฑ ์์ (0) | 2021.04.12 |
Pinpoint Agent Helm Chart ์์ฑํ๊ธฐ (0) | 2021.03.06 |
Elasticsearch Operator ๊ฐ๋ฐํ๊ธฐ (0) | 2020.12.18 |
Kubernetes Operator (feat. Operator SDK) (0) | 2020.12.18 |
๋๊ธ