[CI/CD] Spinnaker - 3. App 배포 - kubernetes Provider

Seunghyun Moon·2023년 5월 4일
0

CI/CD

목록 보기
4/4

Spinnaker란?

Spinnaker 는 넷플릭스에서 개발하여 오픈 소스화한 멀티 클라우드를 지원하는 Continuous Delivery Platform 이다. 구글 클라우드, 아마존, 마이크로소프트등 대부분의 메이져 클라우드를 지원하며, Kubernetes 나, OpenStack 과 같은 오픈소스 기반의 클라우드 또는 컨테이너 플랫폼을 동시에 지원한다.


Prerequisites

  • gke cluster
  • gcloud auth login(or equivalent permission)
  • mgmt vm(helm 설치)
curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null
sudo apt-get install apt-transport-https --yes
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
sudo apt-get update
sudo apt-get install helm
 
sudo apt-get install -y kubectl google-cloud-sdk-gke-gcloud-auth-plugin bash-completion wget git
  
cat >> ~/.bashrc <<EOL
export USE_GKE_GCLOUD_AUTH_PLUGIN=True
export PROJECT_ID=prj-sandbox-devops-9999
source <(kubectl completion bash)
alias k=kubectl
complete -o default -F __start_kubectl k
EOL
source ~/.bashrc

아키텍처

To continuously deliver application updates to your users, you need an automated process that reliably builds, tests, and updates your software. Code changes should automatically flow through a pipeline that includes artifact creation, unit testing, functional testing, and production rollout. In some cases, you want a code update to apply to only a subset of your users, so that it is exercised realistically before you push it to your entire user base. If one of these canary releases proves unsatisfactory, your automated procedure must be able to quickly roll back the software changes.

With Kubernetes Engine and Spinnaker you can create a robust continuous delivery flow that helps to ensure your software is shipped as quickly as it is developed and validated. Although rapid iteration is your end goal, you must first ensure that each application revision passes through a gamut of automated validations before becoming a candidate for production rollout. When a given change has been vetted through automation, you can also validate the application manually and conduct further pre-release testing.

After your team decides the application is ready for production, one of your team members can approve it for production deployment.

Application delivery pipeline

In this lab you build the continuous delivery pipeline shown in the following diagram.


배포 작업

SA Key 생성

Pipeline 생성 시 메타데이터를 GCS에 저장하게 하기 위해서 권한이 필요합니다. storage admin을 가지고 미리 생성한 SA의 키를 생성합니다.

export SA_ACCOUNT="spinnaker-gcs-account"
export PROJECT=$(gcloud info --format='value(config.project)')
export SA_EMAIL=$(gcloud iam service-accounts list \
    --filter="displayName:$SA_ACCOUNT" \
    --format='value(email)')
 
 
gcloud projects add-iam-policy-binding $PROJECT \
    --role roles/storage.admin \
    --member serviceAccount:$SA_EMAIL
 
 
gcloud iam service-accounts keys create spinnaker-sa.json \
     --iam-account $SA_EMAIL

Pub/Sub 생성

Spinnaker Pipeline을 트리거 하기 위한 Pub/sub을 생성합니다.

gcloud pubsub topics create projects/$PROJECT/topics/spinnaker-demo-topic
 
 
gcloud pubsub subscriptions create spinnaker-demo-topic-triggers \
    --topic projects/${PROJECT}/topics/spinnaker-demo-topic
 
 
# Spinnaker의 SA에게 생성한 subscription에 대한 권한을 줍니다.
gcloud beta pubsub subscriptions add-iam-policy-binding spinnaker-demo-topic-triggers \
    --role roles/pubsub.subscriber --member serviceAccount:$SA_EMAIL

Helm 이용해 Spinnaker 배포

Helm과 Spinnaker에 Cluster-admin 역할을 바인딩 해줍니다.

kubectl create clusterrolebinding user-admin-binding \
    --clusterrole=cluster-admin --user=$(gcloud config get-value account)
 
 
kubectl create clusterrolebinding --clusterrole=cluster-admin \
    --serviceaccount=default:default spinnaker-admin

먼저 Pipeline의 Configuration을 저장할 버킷을 생성합니다.

export BUCKET=spinnaker-demo-config
 
gsutil mb -c nearline -l asia-northeast3 gs://$BUCKET

spinnaker-config.yaml 파일을 생성합니다.

export SA_JSON=$(cat spinnaker-sa.json)
 
cat > spinnaker-config.yaml <<EOF
gcs:
  enabled: true
  bucket: $BUCKET
  project: $PROJECT
  jsonKey: '$SA_JSON'
dockerRegistries:
- name: gcr
  address: https://gcr.io
  username: _json_key
  password: '$SA_JSON'
  email: 1234@5678.com
# Disable minio as the default storage backend
minio:
  enabled: false
# Configure Spinnaker to enable GCP services
halyard:
  spinnakerVersion: 1.29.3
  image:
    repository: us-docker.pkg.dev/spinnaker-community/docker/halyard
    tag: 1.55.0
    pullSecrets: []
  additionalScripts:
    create: true
    data:
      enable_gcs_artifacts.sh: |-
        \$HAL_COMMAND config artifact gcs account add gcs-$PROJECT --json-path /opt/gcs/key.json
        \$HAL_COMMAND config artifact gcs enable
      enable_pubsub_triggers.sh: |-
        \$HAL_COMMAND config pubsub google enable
        \$HAL_COMMAND config pubsub google subscription add spinnaker-demo-topic-triggers \
          --subscription-name spinnaker-demo-topic-triggers \
          --json-path /opt/gcs/key.json \
          --project $PROJECT \
          --message-format GCR
EOF

설치 및 port-forwarding

gcloud container clusters get-credentials moon-spinnaker-demo --region asia-northeast3 --project prj-sandbox-devops-9999
 
 
helm repo add stable https://charts.helm.sh/stable
helm repo update
helm install -n default cd stable/spinnaker -f spinnaker-config.yaml \
           --version 2.0.0-rc9 --timeout 10m0s --wait
 
 
export DECK_POD=$(kubectl get pods --namespace default -l "cluster=spin-deck" \
    -o jsonpath="{.items[0].metadata.name}")
 
 
kubectl port-forward --namespace default $DECK_POD 8080:9000 --address 0.0.0.0 >> /dev/null &

배포 화면


Build sample app image

소스리포지토리에 소스코드를 업로드합니다.

#  download source code
gsutil -m cp -r gs://spls/gsp114/sample-app.tar .
 
 
mkdir sample-app
tar xvf sample-app.tar -C ./sample-app
 
 
# commit to local repo
cd sample-app
git init
git config --local user.email "$(gcloud config get-value core/account)"
git config --local user.name "shmoon2"
 
 
git add .
git commit -m "Initial commit"
 
 
# create remote repo
gcloud source repos create spinnaker-demo-sample-app
# git config credential.helper gcloud.sh
git config --local credential.https://source.developers.google.com.helper gcloud.sh
 
 
git remote add google https://source.developers.google.com/p/prj-sandbox-devops-9999/r/spinnaker-demo-sample-app
git push --all google

생성 및 푸시 완료


Cloud build Trigger 생성

이벤트를 Push New Tag로 생성합니다.


K8s Manifest 파일 준비

Manifest 파일 보관을 위한 bucket을 만들고 커밋합니다.

export PROJECT=$(gcloud info --format='value(config.project)')
 
 
gsutil mb -l asia-northeast3 gs://spinnaker-demo-kubernetes-manifests
 
 
gsutil versioning set on gs://spinnaker-demo-kubernetes-manifests
 
 
sed -i s/PROJECT/$PROJECT/g k8s/deployments/*
## 필요시 cloudbuild.yaml의 k8s manifest location 을바꿔줍니다.
#vi cloudbuild.yaml
 
 
git commit -a -m "Set project ID"

git tag를 단 후 push 해 이미지를 생성하고 gcr에 업로드합니다.

git tag v1.0.0
git push google --tags

빌드가 성공하면 컨테이너 이미지가 지정한 gcr에 업로드 됩니다.


spin cli tool 활용한 spinnaker manage

설치

curl -LO https://storage.googleapis.com/spinnaker-artifacts/spin/1.14.0/linux/amd64/spin
 
chmod +x spin

어플리케이션 생성

./spin application save --application-name sample \
                        --owner-email "$(gcloud config get-value core/account)" \
                        --cloud-providers kubernetes \
                        --gate-endpoint http://localhost:8080/gate

생성 확인

파이프라인 생성

# 파이프라인 내부의 manifest file 경로를 바꿔줍니다.
  
sed s/PROJECT-/spinnaker-demo-/g pipeline-deploy.json > pipeline.json
sed -i s/PROJECT/$PROJECT/g pipeline.json
sed -i s/gcr-triggers/spinnaker-demo-topic-triggers/g pipeline.json

파이프라인 세이브

./spin pipeline save --gate-endpoint http://localhost:8080/gate -f sample-app/spinnaker/pipeline.json

pipeline delete

./spin pipeline delete --name Deploy --gate-endpoint http://localhost:8080/gate --application sample

생성 확인


pipeline 활용한 deploy

아래와 같이 파이프라인이 생성됐다면 파이프라인을 트리거해봅니다.

start manual execution을 클릭하고 run을 클릭합니다.

파이프라인이 작동합니다.



Troubleshooting

helm chart로 spinnaker를 배포했는데 타임아웃이 나면서 설치가 제대로 진행되지 않는 경우가 있습니다.

helm install -n default cd stable/spinnaker -f spinnaker-config.yaml \
           --version 2.0.0-rc9 --timeout 10m0s --wait

확인해보니 job pod는 정상이지만 spin-* 서비스 파드가 실행되지 않고 있었습니다.

  1. halyard 의 버전이 맞지 않는 경우
  • spinnaker-config.yaml 의 .halyard.image.tag 값을 최신(1.55.0) 으로 올려서 문제였습니다.
  • 다시 1.32.0으로 내려서 해결합니다.
  1. 환경변수가 빠져있는 경우
  • 중간에 세션이 끝났던지 해서

확인할때 사용한 명령어

  • helm install의 경우

    • --debug 사용
  • helm install을 다시 할 때

    • "cannot re-use a name that is still in use" 에러
      • k delete secrets sh.helm.release.v1.cd.v1
        해서 삭제합니다.
  • 파드의 로그 볼 때

    • kubectl logs -f po/cd-install-using-hal-gzn7f

    • 버전 맞지 않았을 때

    • 환경변수 빠져있을 때

제대로 배포됐을 때의 메세지 및 리소스 모습



참고

https://www.cloudskillsboost.google/focuses/552?parent=catalog

profile
I live fullest

0개의 댓글