Kubernetes and VSTSのDevOps記事の第2部の翻訳を読んでください。
一連の記事「コンテナについて語る」:
1. 高速展開コンテナ 。
2. KubernetesおよびVSTSを使用したDevOps。 パート1:ローカル履歴。
3. KubernetesおよびVSTSを使用したDevOps。 パート2:クラウド履歴。
4. Kubernetesの容量が無限大のノード。
最初の部分では、ラップトップ上の仮想マシンで単一ノードを実行する本格的なk8s環境であるKubernetes (k8s)、またはむしろminikubeを使用してマルチコンテナアプリケーションを開発する方法を示しました。 前の記事で、2つのコンテナー(DotNet Core APIとフロントエンドSPA( Aurelia )(DotNet Coreアプリの静的ファイルとして)を使用して、 このリポジトリーをクローンしました (dockerブランチがデプロイされていることを確認します)。 コンテナーをローカルで作成してminikubeで実行し、ConfigMapsの機能を使用して構成を操作する方法を示しました。
この記事では、ローカル開発をCI / CDに転送し、VSTSを使用して自動ビルド/リリース生成のパイプラインを作成する方法を説明します。 オーケストレーションメカニズムとしてk8sを使用して、Azureでコンテナーレジストリとコンテナーサービスを作成します。
VSTSのKubernetesのCI / CDパイプライン
Nigel Poultonの PluralSightでのKubernetes入門 (英語の翻訳者のメモ、有料のサブスクリプションが必要です)と呼ばれるNigel Poultonの優れた入門レベルのコースと、MicrosoftのAtul Malaviyaの記事をご覧になることを強くお勧めします。 Nigelのコースは初心者向けのKubernetesの優れた紹介であり、Atulの記事はVSTSとk8の相互作用を理解するのに役立ちましたが、コースも記事もパイプラインを完全にはカバーしていませんでした。 これらのうち、CI / CDパイプラインでイメージの更新がどのように実装されているのかまだ理解していませんでした。 まあ、私は一連の実験を自分で行い、この記事を準備しなければなりませんでした!
Azure Container Servicesでk8をデプロイする
k8sは、AWSまたはGoogle CloudまたはAzureでローカルに実行できます。 Azure Container Serviceを使用します。 ただし、この記事で説明するCI / CDパイプラインは、特定のクラウドホスティングに依存せず、あらゆるk8sクラスターに適しています。 また、Azureでプライベートコンテナーレジストリを作成しますが、再度、任意のコンテナーレジストリを使用できます。
Azureポータルでk8sクラスターを作成できます。 ただし、Azure CLIを使用すると、これをより迅速に行うことができ、接続する必要があるキーを保存するため、このメカニズムを使用することにしました。 また、kubectlでBash for Windowsを使用しますが、kubectlとAzure CLIを備えたプラットフォームであればすべて使用できます。
コマンドは次のとおりです。
# set some variables export RG="cd-k8s" export clusterName="cdk8s" export location="westus" # create a folder for the cluster ssh-keys mkdir cdk8s # login and create a resource group az login az group create --location $location --name $RG # create an ACS k8s cluster az acs create --orchestrator-type=kubernetes --resource-group $RG --name=$ClusterName --dns-prefix=$ClusterName --generate-ssh-keys --ssh-key-value ~/cdk8s/id_rsa.pub --location $location --agent-vm-size Standard_DS1_v2 --agent-count 2 # create an Azure Container Registry az acr create --resource-group $RG --name $ClusterName --location $location --sku Basic --admin-enabled # configure kubectl az acs kubernetes get-credentials --name $ClusterName --resource-group $RG --file ~/cdk8s/kubeconfig --ssh-key-file ~/cdk8s/id_rsa export KUBECONFIG="~/cdk8s/kubeconfig" # test connection kubectl get nodes NAME STATUS AGE VERSION k8s-agent-96607ff6-0 Ready 17m v1.6.6 k8s-agent-96607ff6-1 Ready 17m v1.6.6 k8s-master-96607ff6-0 Ready,SchedulingDisabled 17m v1.6.6
注:
- 2〜4行目:変数を作成します。
- 6行目:sshキーとkubeconfig構成ファイルのディレクトリを作成します。
- 9行目:Azureにログインします(ログインメニューでブラウザーでページを開く要求。Azureサブスクリプションをお持ちでない場合は、今すぐ無料サブスクリプションを作成してください!)。
- 10行目:作成するすべてのリソースをホストするグループを作成します。
- 行13:新しく作成したリソースグループと渡した名前を使用してk8sクラスターをデプロイします。 sshキーを生成し、指定されたディレクトリに配置します。 指定された仮想マシンサイズの2つのエージェント(ノード)が必要です。
- 行16:管理者アクセス権を持つ同じリソースグループにAzureコンテナーレジストリを作成します。
- 19行目:kubectlを使用してクラスターに接続するための資格情報を取得します。 受信したsshキーを使用して、指定されたkubeconfigファイルに資格情報を保存します。
- 20行目:kubectlに、デフォルトの構成(他のk8sクラスターまたはminikube構成がある場合があります)の代わりにこの構成を使用するように依頼します。
- 23行目:クラスターに接続する機能を確認します。
- 24〜27行目:接続が成功しました!
ブラウザを起動し、Azureポータルに移動してリソースグループを開くと、次の簡単なコマンドによって作成された量が表示されます。
心配しないで、あなた自身でリソースを管理する必要はありません。 Azureとk8sクラスターが引き継ぎます!
名前空間
コンテナアプリケーションをビルドおよびビルドする前に、プロモーションモデルを見てみましょう。 通常、スキームは次のようなものです。開発->ユーザー受け入れテスト->実稼働環境(Dev-> UAT-> Prod)。 c k8sの場合、minikubeはローカル開発環境であり、素晴らしいです。 これはラップトップ上の本格的なk8sクラスターであるため、configMapsなどのk8sコンストラクトの使用を含め、ローカルでコードを実行できます。 UATとProdはどうですか? オプションは個別のクラスターをデプロイすることですが、このアプローチは高価になる可能性があります。 クラスターリソースを名前空間と共有することもできます。
k8sの名前空間はセキュリティの境界として機能しますが、分離の境界にもなります。 prod名前空間リソースを使用するdev名前空間にアプリケーションの新しいバージョンをデプロイできますが、同時に完全に不可視のままです(ネイティブIPアドレスなど)。 もちろん、このような構成内では負荷テストを実行しないでください。実稼働環境のアプリケーション向けに大量のリソースを消費するためです。 この概念は、Azureアプリケーションサービスの展開スロットに似ており、アプリケーションを運用環境に転送する前にシームレスにテストするために使用されます。
k8sクラスターを作成すると、kube-systemおよびkube-public名前空間(k8sポッドを使用)に加えて、デフォルトの名前空間が取得されます。 明確な指示がない限り、作成するサービス、展開、またはポッドはすべてこの名前空間に分類されます。 ただし、devとprodという2つの追加の名前空間を作成します。 yamlは次のとおりです。
apiVersion: v1 kind: Namespace metadata: name: dev --- apiVersion: v1 kind: Namespace metadata: name: prod
このファイルには、両方の名前空間の定義が含まれています。 Applyコマンドを実行して名前空間を作成します。 すべての手順を完了すると、クラスター内のすべての名前空間を一覧表示できます。
kubectl apply -f namespaces.yml namespace "dev" created namespace "prod" created kubectl get namespaces NAME STATUS AGE default Active 27m dev Active 20s kube-public Active 27m kube-system Active 27m prod Active 20s
コンテナレジストリのシークレットを構成する
コードに進む前に、最終設定を行います。k8sクラスターが実行するイメージを取得するとき、作成したコンテナーレジストリにアクセスする必要があります。 レジストリはプライベートであるため、このレジストリは安全にアクセスできます。 したがって、yamlデプロイメントファイルで簡単に参照できるレジストリシークレットを設定する必要があります。 コマンドは次のとおりです。
az acr credential show --name $ClusterName --output table USERNAME PASSWORD PASSWORD2 ---------- -------------------------------- -------------------------------- cdk8s some-long-key-1 some-long-key-2 kubectl create secret docker-registry regsecret --docker-server=$ClusterName.azurecr.io --docker-username=$ClusterName --docker-password=<some-long-key-1> --docker-email=admin@azurecr.io secret "regsecret" created
最初のコマンドは、azを使用して管理者権限を持つユーザーのキーを取得します(管理者権限を持つユーザー名はコンテナレジストリ名と同じなので、cdk8s.azurecr.ioを作成し、管理者ユーザー名はcdk8sになります)。 いずれかのキーを(どちらでも)パスワードとして渡します。 電子メールアドレスは使用されないため、何でも指定できます。 これで、regsecretというレジストリシークレットが作成されました。これは、k8sクラスターにデプロイするときに参照できます。 K8sはこの秘密を使用して、レジストリで認証します。
VSTSエンドポイントを構成する
k8sクラスターとコンテナーレジストリーをセットアップします。 これらのエンドポイントをVSTSに追加して、リリースの準備中にアセンブリを作成し、k8sクラスターのコマンドを実行するときにコンテナーをレジストリに転送できるようにします。 エンドポイントを使用すると、資格情報がリリースの定義に直接保存されないように、認証を抽象化できます。 エンドポイントを表示および使用するためのアクセスを制限するロールを作成することもできます。
VSTSを起動し、チームプロジェクトを開きます(または新しいプロジェクトを作成します)。 チームプロジェクトに移動し、歯車アイコンをクリックして、このチームプロジェクトの設定ノードを開きます。 サービスをクリックします。 [+新しいサービス]をクリックして、新しいDockerレジストリエンドポイントを作成します。 kubectlを使用してk8sでレジストリシークレットを作成するために使用したのと同じ資格情報を入力します。
次に、k8sエンドポイントを作成します。 URLを入力します:https://$ClusterName.$location.cloudapp.azure.com(clusternameとlocationは、クラスターの作成時に使用した変数です)。 〜/ cdk8s / kubeconfigファイルの内容全体を(異なる名前を付けることもできます)資格情報テキストボックスにコピーする必要があります。資格情報テキストボックスは、az acs kubernetes get-credentialコマンドの実行後に作成されます。
これで、ビルド定義とリリース定義で使用できる2つのエンドポイントができました。
組立
これで、コードをコンパイル/テストするアセンブリを作成し、ドッカーイメージを作成してコンテナレジストリに配置し、それに応じてマークを付けることができます。 [ビルドとリリース]、[ビルド]の順にクリックして、アセンブリノードを開きます。 新しいアセンブリ定義を作成します。 ASP.NET Coreテンプレートを選択し、[適用]をクリックします。 以下の設定を行う必要があります。
- タスク->プロセス:k8s-demo-CIなどの名前を入力し、Hosted Linux Previewキューを選択します。
- オプション:アセンブリの形式が1.0.0.xになるように、アセンブリ番号の形式を$ 1.0.0(rev:.r)に変更します。
- タスク->ソースの取得:OAuthまたはPAT認証を使用するGithubリポジトリを選択します。 AzureAureliaDemoを選択してから、デフォルトのブランチとしてdockerを選択します。 私と一緒に手順を実行する場合は、リポジトリの「プラグ」を作成する(または単にVSTSにインポートする)必要があります。
- タスク-> DotNet Restore:変更を加えないでください。
- タスク-> DotNetビルド:--version-suffix $(Build.BuildNumber)をビルド引数に追加して、バージョンとビルド番号が一致することを確認します。
- タスク→DotNetテスト:ソリューションではDotNetテストを使用しないため、このタスクを無効にします(もちろん、テストがある場合は、タスクを再度有効にできます)。
- タスク-> npmタスクを追加します。 作業ディレクトリとしてフロントエンドを選択し、インストールコマンドが使用されていることを確認します。
- タスク->コマンドラインタスクを追加します。 ツールとして、ノードを選択し、引数を指定します:node_modules / aurelia-cli / bin / aurelia-cli.js testおよび作業ディレクトリ:frontend。 したがって、Aureliaテストを実行します。
- タスク->テスト結果の公開タスクを追加します。 [テスト結果ファイル]フィールドにtest * .xmlを指定し、[検索フォルダー]フィールドに$(Build.SourcesDirectory)/ frontend / testresultsと入力します。 したがって、Aureliaのテスト結果を公開します。
- タスク->コードカバレッジの公開タスクを追加します。 [カバレッジツール]フィールドで、[サマリーファイル]フィールドにCoberturaと入力します-$(Build.SourcesDirectory)/frontend/reports/coverage/cobertura.xml、[レポートディレクトリ]フィールドに-$(Build.SourcesDirectory)/ frontend / reports / coverage / html。 これは、Aureliaのテストカバレッジデータを公開する方法です。
- タスク->コマンドラインタスクを追加します。 ツールとして、ノードを選択し、引数を指定します:node_modules / aurelia-cli / bin / aurelia-cli.js build --env prodおよび作業ディレクトリ:フロントエンド。 このようにして、Aurelia SPAアプリケーションをコンパイル、処理、およびパッケージ化します。
- タスク→DotNet Publish。 引数として、-c $(BuildConfiguration)-o publishと入力し、[Zip Published Projects]チェックボックスをオフにします。
- タスク-> Docker Composeタスクを追加します。 Container Registry Typeフィールドで、Azure Container Registryを指定します。Azureコンテナーのサブスクリプションおよびレジストリとして、以前にエンドポイントを作成したレジストリを指定します。 Additional Docker Compose Filesフィールドで、docker-compose.vsts.ymlをActionフィールド-Build service images、Additional Image Tagsフィールド-$(Build.BuildNumber)で指定して、アセンブリ番号がイメージのタグとして使用されるようにします。
- Docker Composeタスクのクローンを作成します。 名前としてプッシュサービスイメージを指定し、プッシュサービスイメージアクションを選択します。 [最新のタグを含める]ボックスをオンにします。
- タスク→アーティファクトの公開。 [発行するパス]フィールドと[アーティファクト名]フィールドで、k8sを選択します。 そのため、リリースに含めるためにk8s yamlファイルを公開します。
タスクの最終リストは次のようになります。
[保存してキューに入れる]をクリックして、アセンブリを保存してキューに入れることができます。 ビルドプロセスが完了すると、テスト/カバレッジの概要が表示されます。
コンテナレジストリの内容を表示して、ビルド番号に対応するラベルが付いた、新しく移行されたサービスイメージを表示することもできます。
リリース
これで、必要なサービスを作成/更新するリリースを構成できます。 これを行うには、構成管理を提供します。 構成をコードに含めるだけでもかまいませんが、この場合、機密データ(パスワードなど)はバージョン管理ツールに分類されます。 リリース管理ソリューションがバージョン管理ツールによって制御される領域外に機密データを配置するように、構成をトークン化することを好みます。 VSTSリリース管理ソリューションでは、個々の環境またはリリースのシークレットを作成できます。また、再利用をサポートする変数グループでシークレットを作成することもできます。 さらに、 Azure Key Vaultとのシームレスな統合がサポートされるようになりました。
トークンの代わりに環境固有の値を使用するには、トークンを置き換えるタスクが必要です。 幸いなことに、VSTS MarketplaceからダウンロードしたColinのALM Corner Build&Release Tasks拡張モジュールのクロスプラットフォームReplaceTokensタスクがあります。 リンクをクリックして目的のページに移動し、[インストール]をクリックしてアカウントの拡張機能をインストールします。
アセンブリの概要ページで、右側の[展開]セクションまでスクロールし、[リリースの作成]リンクをクリックします。 [リリース]をクリックして、そこから新しい定義を作成することもできます。 空のテンプレート(空)から開始し、チームプロジェクトとソースアセンブリとして作成したアセンブリを選択します。 正しいビルドごとにリリースを自動的に作成するには、[継続的な展開]チェックボックスをオンにします。
定義の名前としてk8sまたは説明的なものを指定します。 [全般]タブで、リリース番号を常に使用してビルド番号を簡単に判別できるように、リリース番号の形式を$(Build.BuildNumber)-$(rev:r)に変更します。 環境セクションに戻り、環境1ではなくdev 1と入力します。 [エージェントで実行]リンクをクリックし、[展開キュー]フィールドで[Hosted Linux Preview]が選択されていることを確認します。
次のタスクを追加します。
- トークンを置き換えます。
- ソースパス:エクスプローラーで、k8sディレクトリを開きます。
- ターゲットファイルパターン:* -release.yml。 したがって、ymlファイルでは、トークンは-releaseで終わる名前に置き換えられます。 このようなファイルが3つあります。サーバーとクライアントのサービス/展開ファイル、およびクライアント構成ファイルです。 このタスクは、ファイル内のトークン(プレフィックスとポストフィックス__を含む)を検出し、同じ名前の変数を探します。 各変数はその値に置き換えられます。 しばらくしてから変数を作成します。
- Kubernetesタスク1(クライアントの構成を適用)。
- 以前に作成したエンドポイントへのk8s接続を構成します。 また、Azureコンテナーレジストリへの接続を構成する必要があります。 これはすべてのKubernetesタスクに適用されます。 [コマンド]フィールドで[適用]を選択し、[構成ファイルを使用する]チェックボックスをオンにして、ファイルピッカーを使用してk8s / app-demo-frontend-config-release.ymlファイルを指定します。 引数のテキストボックスに--namespace $(名前空間)を指定します。
- 以前に作成したエンドポイントへのk8s接続を構成します。 また、Azureコンテナーレジストリへの接続を構成する必要があります。 これはすべてのKubernetesタスクに適用されます。 [コマンド]フィールドで[適用]を選択し、[構成ファイルを使用する]チェックボックスをオンにして、ファイルピッカーを使用してk8s / app-demo-frontend-config-release.ymlファイルを指定します。 引数のテキストボックスに--namespace $(名前空間)を指定します。
- Kubernetesタスク2(サーバー側サービス/展開定義を適用)。
- k8sサービスとAzureコンテナーレジストリに同じ接続設定を設定します。 今回は、[Secret Name]フィールドで、regsecretを指定します(これは、k8sクラスターの構成時に作成したシークレットの名前であり、展開定義のimagePullSecretパラメーターで参照する名前です)。 Force update secretをチェックします。 これにより、k8sシークレット値がAzureのキーと確実に一致します。 キーを手動で作成したため、このパラメーターはスキップできます。
- [コマンド]フィールドで[適用]を選択し、[構成ファイルを使用する]チェックボックスをオンにして、ファイルピッカーを使用してk8s / app-demo-backend-release.ymlファイルを指定します。 引数のテキストボックスに--namespace $(名前空間)を指定します。
- Kubernetesタスク3(クライアントのクライアント/サービス定義の適用)。
- 設定は前のタスクと同様で、k8s / app-demo-frontend-release.ymlファイルを選択するだけです。
- Kubernetesタスク4(サーバー側のイメージを更新)。
- k8sサービスとAzureコンテナーレジストリに同じ接続設定を設定します。 ここでは秘密は必要ありません。 [コマンド]フィールドで[セット]を選択し、[引数]フィールドで、イメージの展開/ demo-backend-deployment backend = $(ContainerRegistry)/ api:$(Build.BuildNumber)--record --namespace = $(namespace)を指定します。
- そのため、使用するコンテナイメージのバージョン(タグ)を更新します。 K8sは、新しいコンテナを起動して古いコンテナを無効にすることにより、順次更新を実行します。この間、サービスは常に動作します。
- Kubernetesタスク5(クライアント側のアップグレードイメージ)。
- パラメーターは前のタスクと似ていますが、引数フィールドで、イメージの展開/ demo-frontend-deployment frontend = $(ContainerRegistry)/ frontend:$(Build.BuildNumber)--record --namespace = $(namespace)を指定する必要があります
- 開発カードの[...]ボタンをクリックし、[変数の構成]をクリックして変数を構成します。 以下の値を設定します。
- BackendServicePort:30081
- FrontendServicePort:30080
- ContainerRegistry:<コンテナレジストリ> .azurecr.io
- 名前空間:$(Release.EnvironmentName)
- AspNetCoreEnvironment:開発
- baseUri:http:// $(BackendServiceIP)/ api
- BackendServiceIP:10.0.0.1
これにより、ymlファイルのすべての変数に環境固有の値が設定されます。 トークンの置換タスクは、必要な値をファイルに書き込みます。 トークン化されたファイルの1つを簡単に見てみましょう(トークン化された行は強調表示されています)。
apiVersion: v1 kind: Service metadata: name: demo-frontend-service labels: app: demo spec: selector: app: demo tier: frontend ports: - protocol: TCP port: 80 nodePort: __FrontendServicePort__ type: LoadBalancer --- apiVersion: apps/v1beta1 kind: Deployment metadata: name: demo-frontend-deployment spec: replicas: 2 template: metadata: labels: app: demo tier: frontend spec: containers: - name: frontend image: __ContainerRegistry__/frontend ports: - containerPort: 80 env: - name: "ASPNETCORE_ENVIRONMENT" value: "__AspNetCoreEnvironment__" volumeMounts: - name: config-volume mountPath: /app/wwwroot/config/ imagePullPolicy: Always volumes: - name: config-volume configMap: name: demo-app-frontend-config imagePullSecrets: - name: regsecret
BackendServiceIPの値に関するコメント:k8sがサーバー側でサービスを開始するときにAzureがこのサービスにIPアドレスを割り当てるため、置換テキストとして10.0.0.1を使用します(AzureポータルのリソースグループにパブリックIPアドレスが表示されます)。 これを一度実行してサービスを作成し、更新して実際のIPアドレスを取得し、サービスがクライアント側で機能していることを確認する必要があります。 また、ネームスペースの値として$(Release.EnvironmentName)を使用するため、dev(およびprod)のネームスペースは、作成したもの(文字の場合を含む)と一致する必要があります。
サービス/展開および構成が変更されない場合、最初の3つのk8sタスクは基本的に機能しません。 一部の結果は、setコマンドによってのみ提供されます。 しかし、サービス/展開および構成ファイルをべき等に適用できるため、これは素晴らしいことです! 必要に応じて変更され、他のすべての状況で障害を引き起こすことはありません-繰り返しリリースするための理想的なアプローチです!
定義を保存します。 [+リリース]をクリックして、新しいリリースを作成します。 リリース番号(1.0.0.1-1など)をクリックして開きます。 ログをクリックしてログを表示します。
リリースの作成が完了すると、Kubernetesダッシュボードに展開が表示されます。 次のコマンドを使用して、ダッシュボードを開きます。
az acs kubernetes browse -n $ClusterName -g $RG --ssh-key-file ~/cdk8s/id_rsa Proxy running on 127.0.0.1:8001/ui Press CTRL+C to close the tunnel... Starting to serve on 127.0.0.1:8001
最後の引数は、クラスターの作成時に生成されるSSHキーファイルへのパスです(現在のパスを指定します)。 これで、ブラウザページhttp:// localhost:8001 / uiを開くことができます。 名前空間のドロップダウンメニューから[dev]を選択し、[展開]をクリックします。 それぞれに2つの実行可能な炉がある2つの正常な展開が表示されます。 デプロイメントで実行されるイメージも確認できます。 タグとして示されているアセンブリ番号に注意してください!
サービスを表示するには、[サービス]をクリックします。
これでサービスのサーバーIPアドレスが得られたため、リリースで変数を更新できます。 その後、新しいバージョンをキューに入れることができ、今回はクライアント構成でサーバー側サービスの正しいIPアドレスが示されます(この場合は23.99.58.48です)。 ブラウザにカスタマーサービスのIPアドレスを入力して、すべてが機能することを確認できます。
実稼働環境の作成
開発環境が機能していることを確認したので、リリースに戻って開発環境のクローンを作成し、コピーprodに名前を付けます。 2つの環境の間にブレークポイントがあるように、devの事後承認(またはprodの事前承認)を示します。
次に、ノードのポートと、AspNetCoreEnvironment変数およびBackendServiceIP変数の値を変更するだけで完了です。 もちろん、k8s / Azureによってprodサーバーに割り当てられたIPアドレスを見る前に、まずprod名前空間にデプロイする必要があります。 その後、リリース作成手順を再起動して構成を更新する必要があります。
nodePortパラメーターを定義から削除し、k8sプラットフォームにホストポート自体を選択させることができますが、ポートが明示的に指定されている場合、クラスターでサービスが使用するポートを正確に知ることができます(外部アクセス用ではありません)。
--namespace , , Pull Request vsts-tasks Github, !
CI/CD
, dev prod CI/CD , . «K8s demo» . , , , , dev. dev ( 1.0.0.3 , , 1.0.0.1), prod 1.0.0.1.
dev , prod , prod 1.0.0.3.
json , ( , , ).
おわりに
k8s . yml « » . , configMaps . Azure CLI k8s Azure . VSTS k8s CI/CD, . minikube, k8s , , (Dev/CI/CD).
, CI/CD ! k8s . , k8s !
k8sing!
PS ( Quantum Quintum ) .