環境 - Kubernetes リソース
Azure DevOps Services | Azure DevOps Server 2022 | Azure DevOps Server 2020
Kubernetes リソース ビューでは、リソースにマップされている名前空間内のオブジェクトの状態が表示されます。 このリソース ビューでは、パイプラインの追跡可能性もオーバーレイされるため、Kubernetes オブジェクトからパイプラインまで、そしてコミットまで戻ることができます。
Kubernetes リソースを使用して、デプロイの環境内の Kubernetes クラスターをターゲットにします。 パイプラインを使用して、他のクラウド プロバイダーから Azure Kubernetes Service (AKS) およびクラスターにデプロイします。
Kubernetes リソースはパブリック クラスターまたはプライベート クラスターで使用できます。 リソースのしくみの詳細については、YAML のリソースリソースのセキュリティに関するを参照してください。
概要
環境内で Kubernetes リソース ビューを使用する利点を次に示します。
パイプラインの追跡可能性 - デプロイに使用される Kubernetes マニフェスト タスクにより、リソース ビューでのパイプラインの追跡可能性を示す注釈が追加されます。 パイプラインの追跡可能性は、名前空間内のオブジェクトに対して行われた更新を担当する、元の Azure DevOps 組織、プロジェクト、パイプラインを特定するのに役立ちます。
リソースの正常性の診断 - ワークロードの状態は、新しいデプロイによって発生した間違いや回帰をすばやくデバッグするのに役立ちます。 たとえば、imagePullSecrets が未構成で ImagePullBackOff エラーが発生した場合、ポッドの状態情報は問題の根本原因を特定するのに役立ちます。
レビュー アプリ - レビュー アプリは、Git リポジトリから環境内の動的 Kubernetes リソースにすべての pull request をデプロイすることで機能します。 レビュー担当者は、ターゲット ブランチにマージされて運用環境にデプロイされる前に、それらの変更がどのように表示され、他の依存サービスと連携するかを確認できます。
Azure Kubernetes Service を使用する
Azure Kubernetes Service (AKS) を使用すると、選択したクラスターと名前空間に ServiceAccount が作成されます。 Kubernetes RBAC 対応クラスターの場合、作成されたサービス アカウントのスコープを選択した名前空間に制限するために、RoleBinding も作成されます。 Kubernetes RBAC が無効なクラスターの場合、作成された ServiceAccount にはクラスター全体 (名前空間全体) の権限が与えられます。
AKS Kubernetes リソースを追加する
環境の詳細ページで、[リソースの追加] を選択し、[Kubernetes] を選択します。
[プロバイダー] ドロップダウンで、[Azure Kubernetes Service] を選択します。
Azure サブスクリプション、クラスター、名前空間 (新規または既存) を選択します。
[検証と作成] を選択して Kubernetes リソースを作成します。
環境のクラスターが表示されることを確認します。 クラスターにコードをまだデプロイしていない場合は、「これまで配置したことがない」というテキストが表示されます。
既存のサービス アカウントを使用する
Azure Kubernetes Service は、環境内の Kubernetes リソースを名前空間にマップします。
環境外での Kubernetes サービス接続の設定の詳細については、「サービス接続」の「Kubernetes サービス接続」セクションを参照してください。
ヒント
汎用プロバイダー (既存のサービス アカウント) を使用して、Kubernetes リソースを非 AKS クラスターの名前空間にマップします。
AKS 以外の Kubernetes リソースを追加する
環境の詳細ページで、[リソースの追加] を選択し、[Kubernetes] を選択します。
プロバイダーとして [汎用プロバイダー (既存のサービス アカウント)] を選択します。
クラスター名と名前空間の値を追加します。
サーバー URL を追加します。 URL は、次のコマンドを使用して取得できます。
kubectl config view --minify -o 'jsonpath={.clusters[0].cluster.server}'
シークレット オブジェクトを取得します。
Kubernetes 1.22 以降
service-account-name
は、自分のアカウント名に置き換えてください。kubectl get secret -n <namespace> -o jsonpath='{.items[?(@.metadata.annotations.kubernetes\.io/service-account\.name==\"service-account-name\")]}'
何も取得しない場合は、「ServiceAccount の有効期間が長い API トークンを手動で作成する」を参照してください。
Kubernetes 1.22 以下:
- サービス アカウントのシークレット名を検索する
kubectl get serviceAccounts <service-account-name> -n <namespace> -o 'jsonpath={.secrets[*].name}'
<service-account-secret-name>
をこのコマンドの前のコマンドの値に置き換えます
kubectl get secret <service-account-secret-name> -n <namespace> -o json
前のステップの出力を使用してシークレット オブジェクトを取得します。
kubectl get secret <service-account-secret-name> -n <namespace> -o json
JSON 形式でフェッチされたシークレット オブジェクトをコピーして [シークレット] フィールドに貼り付けます。
[検証と作成] を選択して Kubernetes リソースを作成します。
パイプラインで Kubernetes リソースを参照する
Azure Kubernetes Service を使用して YAML パイプラインを構築する場合、パイプラインを構成する最も簡単な方法は、テンプレートを使用することです。 リポジトリに接続し、次の 2 つの Kubernetes Service オプションのいずれかを選択します。
- [Azure Kubernetes Services へのデプロイ] テンプレート
- Kubernetes にデプロイする - Azure Dev Spaces によるレビュー アプリ
テンプレートを使用すると、最初から YAML コードを記述したり、明示的なロール バインドを手動で作成したりすることなく、レビュー アプリを設定できます。
レビュー アプリを設定する
次の例では、PR 以外のブランチに対して最初のデプロイ ジョブを実行し、環境で通常の Kubernetes リソースに対してデプロイを実行します。 2 番目のジョブは PR ブランチに対してのみ実行され、オンデマンドで生成されたレビュー アプリ リソース (Kubernetes クラスター内の名前空間) に対してデプロイされます。 環境のリソース一覧ビューでは、リソースには "レビュー" というラベルが付けられます。 パイプラインで使用する変数を定義します。 [Azure Kubernetes Services へのデプロイ] テンプレートを使用すると、これらの変数が定義されます。
# Build and push image to Azure Container Registry; Deploy to Azure Kubernetes Service
trigger:
- main
resources:
- repo: self
variables:
# Container registry service connection established during pipeline creation
dockerRegistryServiceConnection: '12345' # Docker service connection identifier
envName: 'myEnv' # name of your environment
imageRepository: 'name-of-image-repository' # name of image repository
containerRegistry: 'mycontainer.azurecr.io' # path to container registry
dockerfilePath: '**/Dockerfile'
tag: '$(Build.BuildId)'
imagePullSecret: 'my-app-secret' # image pull secret
# Agent VM image name
vmImageName: 'ubuntu-latest'
# Name of the new namespace being created to deploy the PR changes.
k8sNamespaceForPR: 'review-app-$(System.PullRequest.PullRequestId)'
stages:
- stage: Build
displayName: Build stage
jobs:
- job: Build
displayName: Build
pool:
vmImage: $(vmImageName)
steps:
- task: Docker@2
displayName: Build and push an image to container registry
inputs:
command: buildAndPush
repository: $(imageRepository)
dockerfile: $(dockerfilePath)
containerRegistry: $(dockerRegistryServiceConnection)
tags: |
$(tag)
- upload: manifests
artifact: manifests
- stage: Production
displayName: Deploy stage
dependsOn: Build
jobs:
- deployment: Production
condition: and(succeeded(), not(startsWith(variables['Build.SourceBranch'], 'refs/pull/')))
displayName: Production
pool:
vmImage: $(vmImageName)
environment:
name: $(envName).$(resourceName)
resourceType: Kubernetes
strategy:
runOnce:
deploy:
steps:
- task: KubernetesManifest@0
displayName: Create imagePullSecret
inputs:
action: createSecret
secretName: $(imagePullSecret)
dockerRegistryEndpoint: $(dockerRegistryServiceConnection)
- task: KubernetesManifest@0
displayName: Deploy to Kubernetes cluster
inputs:
action: deploy
manifests: |
$(Pipeline.Workspace)/manifests/deployment.yml
$(Pipeline.Workspace)/manifests/service.yml
imagePullSecrets: |
$(imagePullSecret)
containers: |
$(containerRegistry)/$(imageRepository):$(tag)
- deployment: DeployPullRequest
displayName: Deploy Pull request
condition: and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/pull/'))
pool:
vmImage: $(vmImageName)
environment:
name: $(envName).$(resourceName)
resourceType: Kubernetes
strategy:
runOnce:
deploy:
steps:
- reviewApp: default
- task: Kubernetes@1
displayName: 'Create a new namespace for the pull request'
inputs:
command: apply
useConfigurationFile: true
inline: '{ "kind": "Namespace", "apiVersion": "v1", "metadata": { "name": "$(k8sNamespaceForPR)" }}'
- task: KubernetesManifest@0
displayName: Create imagePullSecret
inputs:
action: createSecret
secretName: $(imagePullSecret)
namespace: $(k8sNamespaceForPR)
dockerRegistryEndpoint: $(dockerRegistryServiceConnection)
- task: KubernetesManifest@0
displayName: Deploy to the new namespace in the Kubernetes cluster
inputs:
action: deploy
namespace: $(k8sNamespaceForPR)
manifests: |
$(Pipeline.Workspace)/manifests/deployment.yml
$(Pipeline.Workspace)/manifests/service.yml
imagePullSecrets: |
$(imagePullSecret)
containers: |
$(containerRegistry)/$(imageRepository):$(tag)
- task: Kubernetes@1
name: get
displayName: 'Get services in the new namespace'
continueOnError: true
inputs:
command: get
namespace: $(k8sNamespaceForPR)
arguments: svc
outputFormat: jsonpath='http://{.items[0].status.loadBalancer.ingress[0].ip}:{.items[0].spec.ports[0].port}'
# Getting the IP of the deployed service and writing it to a variable for posting comment
- script: |
url="$(get.KubectlOutput)"
message="Your review app has been deployed"
if [ ! -z "$url" -a "$url" != "http://:" ]
then
message="${message} and is available at $url.<br><br>[Learn More](https://aka.ms/testwithreviewapps) about how to test and provide feedback for the app."
fi
echo "##vso[task.setvariable variable=GITHUB_COMMENT]$message"
既存のパイプラインでこのジョブを使用するには、通常の Kubernetes 環境リソースをバッキングするサービス接続を [クラスター管理者の資格情報を使用する] に変更する必要があります。 それ以外の場合は、基になるサービス アカウントのレビュー アプリ名前空間に対してロール バインドを作成する必要があります。