본문 바로가기
WIKI 기술 지식 베이스

Argo CD와 함께 GitOps로 Linkerd 사용하기

원문 보기 위키 갱신

Argo CD와 함께 GitOps로 Linkerd 사용하기 (Using GitOps with Linkerd with Argo CD)

Git은 단일 진실의 원천(single source of truth)으로 삼아 Kubernetes 인프라와 애플리케이션의 관리·배포를 자동화하는 GitOps 방식을, Argo CD로 Linkerd 설치와 업그레이드에 적용하는 방법을 배워요.

출처: Linkerd Using GitOps with Linkerd with Argo CD

본문

GitOps는 Git을 단일 진실의 원천으로 사용해 Kubernetes 인프라와 애플리케이션의 관리·배포를 자동화하는 방식이에요. 보통 소프트웨어 에이전트들을 활용해 Git의 버전 관리 아티팩트와 클러스터에서 실행 중인 것 사이의 차이를 감지하고 조정(reconcile)해요.

이 가이드는 GitOps 워크플로우로 Linkerd의 설치와 업그레이드를 관리하도록 Argo CD를 설정하는 방법을 보여줘요.

Linkerd 프로덕션 팁

이 페이지는 오픈소스 커뮤니티의 최선(best-effort) 노력으로 작성된 내용이에요. 미션 크리티컬 애플리케이션을 운영하는 프로덕션 사용자는 Linkerd 프로덕션 리소스를 숙지하고, 상용 Linkerd 제공업체와 연결하는 것을 권장해요.

구체적으로 이 가이드는 Sealed Secrets와 cert-manager를 사용해 Linkerd의 mTLS 개인 키와 인증서를 안전하게 생성하고 관리하는 방법을 안내해요. 또한 자동 프록시 주입(auto proxy injection) 기능을 워크플로우에 통합하는 방법도 보여줘요. 마지막으로 GitOps 워크플로우를 따라 Linkerd를 더 새로운 버전으로 업그레이드하는 단계로 마무리해요.

Linkerd GitOps workflow

이 가이드에 사용된 소프트웨어와 도구는 데모 목적으로만 선정됐어요. 요구사항에 가장 적합한 다른 것을 선택해도 좋아요.

이 예시 저장소를 로컬 머신에 클론하고, 다음 섹션에서 정의한 단계를 따라 Kubernetes 클러스터에 복제해야 해요.

이 가이드는 Linkerd 클러스터가 mTLS를 적용할 때 사용하는 인증서를 만드는 데 step CLI를 사용하므로, 환경에 step을 설치했는지 확인하세요.

저장소 설정하기 (Set up the repositories)

예시 저장소를 로컬 머신에 클론해요.

git clone https://github.com/linkerd/linkerd-examples.git

이 저장소는 가이드 후반부에서 add, commit, push 같은 Git 작업을 시연하는 데 사용될 거예요.

다음 섹션에서 설정할 클러스터 내 Git 서버를 가리키도록 저장소에 새 원격 엔드포인트를 추가해요.

cd linkerd-examples

git remote add git-server git://localhost/linkerd-examples.git

참고

이 가이드의 단계를 단순화하기 위해 포트 포워딩으로 클러스터 내 Git 서버와 상호작용할 거예요. 그래서 방금 만든 원격 엔드포인트는 localhost를 대상으로 해요.

클러스터의 scm 네임스페이스에 Git 서버를 배포해요.

kubectl apply -f gitops/resources/git-server.yaml

이 가이드 후반부에서 Argo CD는 이 Git 서버가 호스팅하는 저장소를 감시하도록 구성될 거예요.

참고

이 Git 서버는 git 프로토콜 위에서 daemon으로 실행되며, Git 데이터에 인증 없는 접근을 허용하도록 구성되어 있어요. 이 구성은 프로덕션 사용에는 권장되지 않아요.

Git 서버가 정상인지 확인해요.

kubectl -n scm rollout status deploy/git-server

예시 저장소를 클러스터 내 Git 서버에 클론해요.

git_server=`kubectl -n scm get po -l app=git-server -oname | awk -F/ '{ print $2 }'`

kubectl -n scm exec "${git_server}" -- \
  git clone --bare https://github.com/linkerd/linkerd-examples.git

원격 저장소가 성공적으로 클론되었는지 확인해요.

kubectl -n scm exec "${git_server}" -- ls -al /git/linkerd-examples.git

포트 포워딩을 통해 로컬 저장소에서 원격 저장소로 push할 수 있는지 확인해요.

kubectl -n scm port-forward "${git_server}" 9418  &

git push git-server master

Argo CD CLI 설치하기

진행 전에, OS에 맞는 안내를 따라 Argo CD CLI를 로컬 머신에 설치하세요.

Argo CD 배포하기

Argo CD를 설치해요.

kubectl create ns argocd

kubectl -n argocd apply -f \
  https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

모든 pod가 준비됐는지 확인해요.

for deploy in "dex-server" "redis" "repo-server" "server"; \
  do kubectl -n argocd rollout status deploy/argocd-${deploy}; \
done

kubectl -n argocd rollout status statefulset/argocd-application-controller

포트 포워딩으로 Argo CD 대시보드에 접근해요.

kubectl -n argocd port-forward svc/argocd-server 8080:443  \
  > /dev/null 2>&1 &

이제 Argo CD 대시보드는 기본 admin 사용자 이름과 비밀번호로 https://localhost:8080에서 접근할 수 있어요.

Argo CD CLI를 인증해요.

password=`kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d`

argocd login 127.0.0.1:8080 \
  --username=admin \
  --password="${password}" \
  --insecure

프로젝트 접근과 권한 구성하기

우리의 애플리케이션들을 그룹화하도록 demo 프로젝트를 설정해요.

kubectl apply -f gitops/project.yaml

이 프로젝트는 우리 애플리케이션이 작업할 수 있는 허용된 리소스 종류와 대상 클러스터 목록을 정의해요.

프로젝트가 올바르게 배포됐는지 확인해요.

argocd proj get demo

대시보드에서:

New project in Argo CD dashboard

애플리케이션 배포하기 (Deploy the applications)

다른 모든 애플리케이션의 "부모(parent)" 역할을 하는 main 애플리케이션을 배포해요.

kubectl apply -f gitops/main.yaml

참고

"app of apps" 패턴은 Argo CD 워크플로우에서 애플리케이션을 부트스트랩하는 데 흔히 사용돼요. 자세한 내용은 Argo CD 문서를 참고하세요.

main 애플리케이션이 성공적으로 배포됐는지 확인해요.

argocd app get main

main 애플리케이션을 동기화해요.

argocd app sync main

Synchronize the main application

main 애플리케이션만 동기화된 것을 주목하세요.

다음으로 나머지 애플리케이션들을 개별적으로 동기화할 거예요.

cert-manager 배포하기

cert-manager 애플리케이션을 동기화해요.

argocd app sync cert-manager

cert-manager가 실행 중인지 확인해요.

for deploy in "cert-manager" "cert-manager-cainjector" "cert-manager-webhook"; \
  do kubectl -n cert-manager rollout status deploy/${deploy}; \
done

Synchronize the cert-manager application

Sealed Secrets 배포하기

sealed-secrets 애플리케이션을 동기화해요.

argocd app sync sealed-secrets

sealed-secrets가 실행 중인지 확인해요.

kubectl -n kube-system rollout status deploy/sealed-secrets

Synchronize the sealed-secrets application

mTLS 트러스트 앵커 생성하기

Linkerd 배포를 진행하기 전에 mTLS 트러스트 앵커를 생성해야 해요. 그런 다음 트러스트 앵커 인증서를 관리하기 위해 linkerd-bootstrap 애플리케이션도 설정할 거예요.

새 mTLS 트러스트 앵커 개인 키와 인증서를 생성해요.

step certificate create root.linkerd.cluster.local sample-trust.crt sample-trust.key \
  --profile root-ca \
  --no-password \
  --not-after 43800h \
  --insecure

새 트러스트 앵커의 세부 정보(암호화 알고리즘, 만료일, SAN 등)를 확인해요.

step certificate inspect sample-trust.crt

SealedSecret을 만들기 전에 kubeseal 유틸리티를 여기 안내된 대로 설치했는지 확인하세요.

이제 암호화된 트러스트 앵커를 저장할 SealedSecret 리소스를 생성해요.

LINKERD_VERSION=$(linkerd version --client --short)
kubectl create ns linkerd
kubectl -n linkerd create secret tls linkerd-trust-anchor \
  --cert sample-trust.crt \
  --key sample-trust.key \
  --dry-run=client -oyaml | \
kubeseal --controller-name=sealed-secrets -oyaml - | \
kubectl patch -f - \
  -p '{"spec":{"template":{"type":"kubernetes.io/tls","metadata":{"labels":{"linkerd.io/control-plane-component":"identity","linkerd.io/control-plane-ns":"linkerd"},"annotations":{"linkerd.io/created-by":"linkerd/cli '"${LINKERD_VERSION}"'"}}}}' \
  --dry-run=client \
  --type=merge \
  --local -oyaml > gitops/resources/linkerd/trust-anchor.yaml

이 명령은 로컬 gitops/resources/linkerd/trust-anchor.yaml 파일의 기존 SealedSecret 리소스를 덮어써요. 이 변경 사항을 클러스터 내 Git 서버로 push할 거예요.

spec.encryptedData만 변경됐는지 확인해요.

git diff gitops/resources/linkerd/trust-anchor.yaml

새 트러스트 앵커 시크릿을 커밋하고 클러스터 내 Git 서버로 push해요.

git add gitops/resources/linkerd/trust-anchor.yaml

git commit -m "update encrypted trust anchor"

git push git-server master

커밋이 성공적으로 push됐는지 확인해요.

kubectl -n scm exec "${git_server}" -- git --git-dir linkerd-examples.git log -1

linkerd-bootstrap 배포하기

linkerd-bootstrap 애플리케이션을 동기화해요.

argocd app sync linkerd-bootstrap

참고

issuer와 certificate 리소스가 degraded 상태로 나타난다면, SealedSecrets 컨트롤러가 봉인된(sealed) linkerd-trust-anchor 시크릿을 복호화하는 데 실패했을 가능성이 높아요. SealedSecrets 컨트롤러에서 오류 로그를 확인하세요.

디버깅 목적으로 봉인된 리소스는 kubectl -n linkerd get sealedsecrets linkerd-trust-anchor -oyaml 명령어로 조회할 수 있어요. 이 리소스가 앞서 클러스터 내 Git 서버로 push한 gitops/resources/linkerd/trust-anchor.yaml 파일과 일치하는지 확인하세요.

Synchronize the linkerd-bootstrap application

SealedSecrets는 복호화된 트러스트 앵커가 담긴 시크릿을 생성했어야 해요. 시크릿에서 복호화된 트러스트 앵커를 조회해요.

trust_anchor=`kubectl -n linkerd get secret linkerd-trust-anchor -ojsonpath="{.data['tls\.crt']}" | base64 -d -w 0 -`

앞서 로컬 sample-trust.crt 파일로 생성한 복호화된 트러스트 앵커 인증서와 일치하는지 확인해요.

diff -b \
  (echo "${trust_anchor}" | step certificate inspect -) \
  (step certificate inspect sample-trust.crt)

Linkerd 배포하기

이제 Linkerd를 설치할 준비가 됐어요. 방금 조회한 복호화된 트러스트 앵커를 identityTrustAnchorsPEM 파라미터로 설치 과정에 전달할 거예요.

Linkerd를 설치하기 전에 identityTrustAnchorsPEM 파라미터가 "빈(empty)" 인증서 문자열로 설정되어 있다는 점을 주목하세요.

argocd app get linkerd-control-plane -ojson | \
  jq -r '.spec.source.helm.parameters[] | select(.name == "identityTrustAnchorsPEM") | .value'

Empty default trust anchor

linkerd 애플리케이션에서 이 파라미터를 ${trust_anchor} 값으로 오버라이드할 거예요.

로컬 gitops/argo-apps/linkerd-control-plane.yaml 파일에서 identityTrustAnchorsPEM 변수를 찾아 그 value를 ${trust_anchor} 값으로 설정하세요.

다중 라인 문자열이 올바르게 들여쓰기되었는지 확인하세요. 예를 들어:

source:
  chart: linkerd-control-plane
  repoURL: https://helm.linkerd.io/edge
  targetRevision: { { % chart-version % } }
  helm:
    parameters:
      - name: identityTrustAnchorsPEM
        value: |
          -----BEGIN CERTIFICATE-----
          MIIBlTCCATygAwIBAgIRAKQr9ASqULvXDeyWpY1LJUQwCgYIKoZIzj0EAwIwKTEn
          MCUGA1UEAxMeaWRlbnRpdHkubGlua2VyZC5jbHVzdGVyLmxvY2FsMB4XDTIwMDkx
          ODIwMTAxMFoXDTI1MDkxNzIwMTAxMFowKTEnMCUGA1UEAxMeaWRlbnRpdHkubGlu
          a2VyZC5jbHVzdGVyLmxvY2FsMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE+PUp
          IR74PsU+geheoyseycyquYyes5eeksIb5FDm8ptOXQ2xPcBpvesZkj6uIyS3k4qV
          E0S9VtMmHNeycL7446NFMEMwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYB
          Af8CAQEwHQYDVR0OBBYEFHypCh7hiSLNxsKhMylQgqD9t7NNMAoGCCqGSM49BAMC
          A0cAMEQCIEWhI86bXWEd4wKTnG07hBfBuVCT0bxopaYnn3wRFx7UAiAwXyh5uaVg
          MwCC5xL+PM+bm3PRqtrmI6TocWH07GbMxg==
          -----END CERTIFICATE-----

spec.source.helm.parameters.value 필드 하나만 변경됐는지 확인해요.

git diff gitops/argo-apps/linkerd-control-plane.yaml

변경 사항을 커밋하고 Git 서버로 push해요.

git add gitops/argo-apps/linkerd-control-plane.yaml

git commit -m "set identityTrustAnchorsPEM parameter"

git push git-server master

main 애플리케이션을 동기화해요.

argocd app sync main

새 트러스트 앵커가 linkerd 애플리케이션에 반영됐는지 확인해요.

argocd app get linkerd-control-plane -ojson | \
  jq -r '.spec.source.helm.parameters[] | select(.name == "identityTrustAnchorsPEM") | .value'

Override mTLS trust anchor

linkerd-crds와 linkerd-control-plane 애플리케이션을 동기화해요.

argocd app sync linkerd-crds
argocd app sync linkerd-control-plane

Linkerd가 준비됐는지 확인해요.

linkerd check

Synchronize Linkerd

emojivoto로 테스트하기

자동 프록시 주입을 테스트하기 위해 emojivoto를 배포해요.

argocd app sync emojivoto

애플리케이션들이 정상인지 확인해요.

for deploy in "emoji" "vote-bot" "voting" "web" ; \
  do kubectl -n emojivoto rollout status deploy/${deploy}; \
done

Synchronize emojivoto

Linkerd 업그레이드하기

(더 새로운 버전의 Linkerd가 릴리스되었다고 가정해요)

에디터로 gitops/argo-apps/linkerd-control-plane.yaml 파일의 spec.source.targetRevision 필드를 더 새로운 Helm 차트 버전으로 변경하세요.

targetRevision 필드만 변경됐는지 확인해요.

git diff gitops/argo-apps/linkerd-control-plane.yaml

이 변경 사항을 커밋하고 Git 서버로 push해요.

git add gitops/argo-apps/linkerd-control-plane.yaml

git commit -m "upgrade Linkerd"

git push git-server master

main 애플리케이션을 동기화해요.

argocd app sync main

linkerd-control-plane 애플리케이션을 동기화해요.

argocd app sync linkerd-control-plane

업그레이드가 성공적으로 완료됐는지 확인해요.

linkerd check

컨트롤 플레인의 새 버전을 확인해요.

linkerd version

정리 (Clean up)

모든 애플리케이션은 main 애플리케이션을 제거함으로써 삭제할 수 있어요.

argocd app delete main --cascade=true

더 알아보기 (Learn more)