연습 - Kubernetes를 사용하여 인프라 복원력 구현
이전 단원에서는 .NET 네이티브 복원력 확장을 사용하여 오류 처리 코드를 추가하여 복원력을 구현했습니다. 그러나 이 변경은 변경한 서비스에만 적용됩니다. 많은 서비스가 포함된 대규모 앱을 업데이트하는 것은 간단하지 않습니다.
이 단원에서는 코드 기반 복원력을 사용하는 대신 인프라 기반 복원력이라는 전체 앱에 걸쳐 있는 접근 방식을 사용합니다. 다음을 수행합니다.
- 복원력 없이 앱을 Kubernetes에 다시 배포합니다.
- Kubernetes 클러스터에 Linkerd를 배포합니다.
- 복원력을 위해 Linkerd를 사용하도록 앱을 구성합니다.
- Linkerd를 사용하여 앱 동작을 탐색합니다.
앱 다시 배포
Linkerd를 적용하기 전에 먼저 앱 상태를 코드 기반 복원력이 추가되기 전으로 되돌립니다. 되돌리려면 다음 단계를 수행합니다.
아래쪽 패널에서 터미널 탭을 선택하고 다음 git 명령을 실행하여 변경 내용을 실행 취소합니다.
cd Store git checkout Program.cs git checkout Store.csproj cd .. dotnet publish /p:PublishProfile=DefaultContainer
Kubernetes 설치
코드스페이스에서 Kubernetes 및 k3d를 설치합니다. k3d는 로컬 컴퓨터의 VM(Virtual Machine) 내에서 단일 노드 Kubernetes 클러스터를 실행하는 도구입니다. Kubernetes 배포를 로컬로 테스트하는 데 유용하며 codespace 내에서 잘 실행됩니다.
다음 명령을 실행하여 Kubernetes 및 MiniKube를 설치합니다.
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | sudo gpg --dearmor -o /etc/apt/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.28/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubectl
curl -s https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | bash
k3d cluster create devcluster --config k3d.yml
Docker 허브에 eShop 서비스 배포
빌드하는 서비스의 로컬 이미지는 Kubernetes에 배포할 수 있도록 컨테이너 레지스트리에 호스트되어야 합니다. 이 단원에서는 Docker 허브를 컨테이너 레지스트리로 사용합니다.
다음 명령을 실행하여 이미지를 Docker Hub에 푸시합니다.
sudo docker login
sudo docker tag products [your username]/productservice
sudo docker tag store [your username]/storeimage
sudo docker push [your username]/productservice
sudo docker push [your username]/storeimage
docker-compose 파일을 Kubernetes 매니페스트로 변환
현재 Docker에서 앱이 실행되는 방식을 정의합니다. Kubernetes는 앱 실행 방법을 정의하기 위해 다른 형식을 사용합니다. Kompose라는 도구를 사용하여 docker-compose 파일을 Kubernetes 매니페스트로 변환할 수 있습니다.
Docker Hub에 푸시한 이미지를 사용하려면 이러한 파일을 편집해야 합니다.
codespace에서 backend-deploy.yml 파일을 엽니다.
이 줄을 변경합니다.
containers: - image: [YOUR DOCKER USER NAME]/productservice:latest
자리 표시자 [YOUR DOCKER USER NAME]을 실제 Docker 사용자 이름으로 바꿉니다.
frontend-deploy.yml 파일에 대해 다음 단계를 반복합니다.
이 줄을 변경합니다.
containers: - name: storefrontend image: [YOUR DOCKER USER NAME]/storeimage:latest
자리 표시자 [YOUR DOCKER USER NAME]을 실제 Docker 사용자 이름으로 바꿉니다.
Kubernetes에 eShop 앱을 배포합니다.
kubectl apply -f backend-deploy.yml,frontend-deploy.yml
다음 메시지와 유사한 출력이 표시됩니다.
deployment.apps/productsbackend created service/productsbackend created deployment.apps/storefrontend created service/storefrontend created
모든 서비스가 실행되고 있는지 확인합니다.
kubectl get pods
다음 메시지와 유사한 출력이 표시됩니다.
NAME READY STATUS RESTARTS AGE backend-66f5657758-5gnkw 1/1 Running 0 20s frontend-5c9d8dbf5f-tp456 1/1 Running 0 20s
포트 탭으로 전환하여 Kubernetes에서 실행되는 eShop을 보려면 프런트 엔드(32000) 포트 옆에 있는 지구본 아이콘을 선택합니다.
Linkerd 설치
개발 컨테이너는 Linkerd CLI를 설치해야 합니다. 다음 명령을 실행하여 Linkerd 필수 구성 요소가 충족되는지 확인합니다.
curl -sL run.linkerd.io/install | sh
export PATH=$PATH:/home/vscode/.linkerd2/bin
linkerd check --pre
다음과 유사한 출력이 표시됩니다.
kubernetes-api
--------------
√ can initialize the client
√ can query the Kubernetes API
kubernetes-version
------------------
√ is running the minimum Kubernetes API version
√ is running the minimum kubectl version
pre-kubernetes-setup
--------------------
√ control plane namespace does not already exist
√ can create non-namespaced resources
√ can create ServiceAccounts
√ can create Services
√ can create Deployments
√ can create CronJobs
√ can create ConfigMaps
√ can create Secrets
√ can read Secrets
√ can read extension-apiserver-authentication configmap
√ no clock skew detected
pre-kubernetes-capability
-------------------------
√ has NET_ADMIN capability
√ has NET_RAW capability
linkerd-version
---------------
√ can determine the latest version
√ cli is up-to-date
Status check results are √
Kubernetes에 Linkerd 배포
먼저 다음 명령을 실행하여 CRD(사용자 지정 리소스 정의)를 설치합니다.
linkerd install --crds | kubectl apply -f -
그런 후 다음 명령을 실행합니다.
linkerd install --set proxyInit.runAsRoot=true | kubectl apply -f -
위의 명령은 다음을 수행합니다.
linkerd install
은 필요한 컨트롤 플레인 리소스를 사용하여 Kubernetes 매니페스트를 생성합니다.- 생성된 매니페스트는
kubectl apply
로 파이프되어 Kubernetes 클러스터에 컨트롤 플레인 리소스를 설치합니다.
출력의 첫 번째 줄은 컨트롤 플레인이 고유 linkerd
네임스페이스에 설치되었음을 보여 줍니다. 나머지 출력은 생성되는 개체를 나타냅니다.
namespace/linkerd created
clusterrole.rbac.authorization.k8s.io/linkerd-linkerd-identity created
clusterrolebinding.rbac.authorization.k8s.io/linkerd-linkerd-identity created
serviceaccount/linkerd-identity created
clusterrole.rbac.authorization.k8s.io/linkerd-linkerd-controller created
Linkerd 배포 유효성 검사
다음 명령을 실행합니다.
linkerd check
위의 명령은 Linkerd CLI 및 컨트롤 플레인의 구성을 분석합니다. Linkerd가 올바르게 구성된 경우 다음과 같은 출력이 표시됩니다.
kubernetes-api
--------------
√ can initialize the client
√ can query the Kubernetes API
kubernetes-version
------------------
√ is running the minimum Kubernetes API version
√ is running the minimum kubectl version
linkerd-existence
-----------------
√ 'linkerd-config' config map exists
√ heartbeat ServiceAccount exist
√ control plane replica sets are ready
√ no unschedulable pods
√ controller pod is running
√ can initialize the client
√ can query the control plane API
linkerd-config
--------------
√ control plane Namespace exists
√ control plane ClusterRoles exist
√ control plane ClusterRoleBindings exist
√ control plane ServiceAccounts exist
√ control plane CustomResourceDefinitions exist
√ control plane MutatingWebhookConfigurations exist
√ control plane ValidatingWebhookConfigurations exist
√ control plane PodSecurityPolicies exist
linkerd-identity
----------------
√ certificate config is valid
√ trust anchors are using supported crypto algorithm
√ trust anchors are within their validity period
√ trust anchors are valid for at least 60 days
√ issuer cert is using supported crypto algorithm
√ issuer cert is within its validity period
√ issuer cert is valid for at least 60 days
√ issuer cert is issued by the trust anchor
linkerd-api
-----------
√ control plane pods are ready
√ control plane self-check
√ [kubernetes] control plane can talk to Kubernetes
√ [prometheus] control plane can talk to Prometheus
√ tap api service is running
linkerd-version
---------------
√ can determine the latest version
√ CLI is up to date
control-plane-version
---------------------
√ control plane is up to date
√ control plane and CLI versions match
linkerd-addons
--------------
√ 'linkerd-config-addons' config map exists
linkerd-grafana
---------------
√ grafana add-on service account exists
√ grafana add-on config map exists
√ grafana pod is running
Status check results are √
팁
설치된 Linkerd 구성 요소 목록을 보려면 kubectl -n linkerd get deploy
명령을 실행합니다.
Linkerd를 사용하도록 앱 구성
링커드는 배포되었지만 구성되지 않았습니다. 앱의 동작은 변경되지 않습니다.
Linkerd는 서비스 내부를 인식하지 못하고 오류가 발생한 요청을 다시 시도하는 것이 적절한지 여부를 확인할 수 없습니다. 예를 들어 오류가 발생한 HTTP POST를 결제에 다시 시도하는 것은 좋지 않은 생각입니다. 이러한 이유로 서비스 프로필이 필요합니다. ‘서비스 프로필’은 서비스의 경로를 정의하는 사용자 지정 Kubernetes 리소스입니다. 또한 재시도 및 시간 제한과 같은 경로별 기능을 사용하도록 설정합니다. Linkerd는 서비스 프로필 매니페스트에 구성된 경로만 다시 시도합니다.
간단히 하기 위해 집계 서비스와 쿠폰 서비스에만 Linkerd를 구현합니다. 이러한 두 서비스에 대해 Linkerd를 구현하려면 다음을 수행합니다.
- Linkerd가 Pod에 프록시 컨테이너를 만들도록 eShop 배포를 수정합니다.
- 쿠폰 서비스의 경로에 대한 재시도를 구성하려면 클러스터에 서비스 프로필 개체를 추가합니다.
eShop 배포 수정
Linkerd 프록시 컨테이너를 사용하도록 서비스를 구성해야 합니다.
템플릿 메타데이터에서 backend-deploy.yml 파일에
linkerd.io/inject: enabled
주석을 추가합니다.template: metadata: annotations: linkerd.io/inject: enabled labels:
같은 위치에 있는
linkerd.io/inject: enabled
frontend-deploy.yml 파일에 주석을 추가합니다.Kubernetes 클러스터에서 배포를 업데이트합니다.
kubectl apply -f backend-deploy.yml,frontend-deploy.yml
제품 서비스에 Linkerd 서비스 프로필 적용
제품 서비스에 대한 서비스 프로필 매니페스트는 다음과 같습니다.
apiVersion: linkerd.io/v1alpha2
kind: ServiceProfile
metadata:
name: backend
namespace: default
spec:
routes:
- condition:
method: GET
pathRegex: /api/Product
name: GET /v1/products
isRetryable: true
retryBudget:
retryRatio: 0.2
minRetriesPerSecond: 10
ttl: 120s
위의 매니페스트는 다음과 같이 구성됩니다.
/api/Product
패턴과 일치하는 idempotent HTTP GET 경로를 다시 시도할 수 있습니다.- 재시도는 요청 로드에 추가 20% 이하 및 추가로 초당 10개의 “무료” 재시도를 추가할 수 있습니다.
다음 명령을 실행하여 Kubernetes 클러스터의 서비스 프로필을 사용합니다.
kubectl apply -f - <<EOF
apiVersion: linkerd.io/v1alpha2
kind: ServiceProfile
metadata:
name: backend
namespace: default
spec:
routes:
- condition:
method: GET
pathRegex: /api/Product
name: GET /v1/products
isRetryable: true
retryBudget:
retryRatio: 0.2
minRetriesPerSecond: 10
ttl: 120s
EOF
다음과 같은 출력이 표시됩니다.
serviceprofile.linkerd.io/backend created
서비스 메시에 모니터링 설치
링커드에는 추가 기능을 제공하는 확장이 있습니다. viz 확장을 설치하고 Linkerd의 대시보드에서 앱의 상태를 확인합니다.
터미널에서 다음 명령을 실행하여 확장을 설치합니다.
linkerd viz install | kubectl apply -f -
다음 명령을 사용하여 대시보드를 봅니다.
linkerd viz dashboard
포트 탭으로 이동하여 링커드 비주얼리제이션 대시보드 실행 프로세스와 함께 전달된 새 포트를 확인합니다. 브라우저에서 열기를 선택하여 대시보드를 엽니다.
Linkerd 대시보드에서 네임스페이스를 선택합니다.
HTTP 메트릭에서 기본값을 선택합니다.
Linkerd 복원력 테스트
재배포된 컨테이너가 정상 상태이면 다음 단계에 따라 Linkerd를 사용하여 앱의 동작을 테스트합니다.
다음 명령을 사용하여 실행 중인 Pod의 상태를 확인합니다.
kubectl get pods --all-namespaces
모든 제품 서비스 Pod를 중지합니다.
kubectl scale deployment productsbackend --replicas=0
eShop 웹앱으로 이동하여 제품을 확인합니다. "제품을 로드하는 데 문제가 있습니다"라는 오류 메시지가 표시될 때까지 지연이 발생할 수 있습니다. 나중에 다시 시도하세요."
제품 서비스 Pod를 다시 시작합니다.
kubectl scale deployment productsbackend --replicas=1
이제 앱에 제품이 표시됩니다.
Linkerd는 코드 기반 복원력과는 다른 복원력 접근 방식을 따릅니다. Linkerd는 빠르게 연속해서 작업을 여러 번 다시 시도했습니다. 이 동작을 지원하기 위해 앱을 변경할 필요가 없었습니다.
추가 정보
Linkerd 구성에 대한 자세한 내용은 다음 리소스를 참조하세요.