Microsoft Build 2022 で Azure Container Apps が GA されました。東日本リージョンでも使えるようになりましたので、Blue-Green Deployments を試してみました。
Azure Container Apps とは
Azure Container Apps は、複数のコンテナアプリで構成されるシステム向けのサービスです。これまでは Web Apps for Containers か AKS の2択でしたが、新たに Container Apps が追加されたことになります。
docs.microsoft.com
Container Apps は Kubernetes を基盤に構成されています。下記のような Environment / Container App / Revision / Replica の構成要素を理解しておけば OK です。
Microsoft Docs から引用
Container Apps Environment を作成する
Azure Portal では App Service Plan にあたる Environment だけを作成できないため、Bicep を使って Environment を作成します。
environment.bicep では、Environment、LogAnalytics、Application Insights のリソースを定義します。
param environmentName string
param logAnalyticsWorkspaceName string = 'logs-${environmentName}'
param appInsightsName string = 'appins-${environmentName}'
param location string = resourceGroup().location
resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2020-08-01' = {
name : logAnalyticsWorkspaceName
location : location
properties : any({
retentionInDays : 30
features : {
searchVersion : 1
legacy : 0
enableLogAccessUsingOnlyResourcePermissions : true
}
sku : {
name : 'PerGB2018'
}
} )
}
resource appInsights 'Microsoft.Insights/components@2020-02-02' = {
name : appInsightsName
location : location
kind : 'web'
properties : {
Application_Type : 'web'
WorkspaceResourceId : logAnalyticsWorkspace.id
}
}
resource environment 'Microsoft.App/managedEnvironments@2022-03-01' = {
name : environmentName
location : location
properties : {
appLogsConfiguration : {
destination : 'log-analytics'
logAnalyticsConfiguration : {
customerId : logAnalyticsWorkspace.properties.customerId
sharedKey : logAnalyticsWorkspace.listKeys().primarySharedKey
}
}
daprAIInstrumentationKey : appInsights.properties.InstrumentationKey
zoneRedundant : false
}
}
output location string = location
output environmentId string = environment.id
main.bicep では、Resource Group 名にプレフィックスをつけて Environment 名を定義します。
param environmentName string = 'env-${resourceGroup().name}'
param location string = resourceGroup().location
module environment 'environment.bicep' = {
name : 'container-app-environment'
params : {
environmentName : environmentName
location : location
}
}
Azure CLI を使って、デプロイします。
$ az group create -n < ResourceGroup Name> -l japaneast
$ az deployment group create -f ./deploy/env/main.bicep -g < ResourceGroup Name>
作られたリソースは、こんな感じです。
Container Apps をデプロイする
Container Apps についても、Azure Portal では細かい構成を指定できないので、Bicep を使って作成します。
あらかじめ ASP.NET Core Web アプリケーションの Docker Image を作っておいたので、apps.bicep でデプロイします。
param containerAppName string
param location string = resourceGroup().location
param environmentId string
param containerImage string
param revisionSuffix string
param oldRevisionSuffix string
param isExternalIngress bool
@allowed([
'multiple'
'single'
])
param revisionMode string = 'single'
resource containerApp 'Microsoft.App/containerApps@2022-03-01' = {
name : containerAppName
location : location
properties : {
managedEnvironmentId : environmentId
configuration : {
activeRevisionsMode : revisionMode
ingress : {
external : isExternalIngress
targetPort : 80
transport : 'auto'
allowInsecure : false
traffic : ((contains(revisionSuffix, oldRevisionSuffix)) ? [
{
weight : 100
latestRevision : true
}
] : [
{
weight : 0
latestRevision : true
}
{
weight : 100
revisionName : '${containerAppName}--${oldRevisionSuffix}'
}
] )
}
dapr :{
enabled : false
}
}
template : {
revisionSuffix : revisionSuffix
containers : [
{
image : containerImage
name : containerAppName
resources : {
cpu : '0.25'
memory : '0.5Gi'
}
}
]
scale : {
minReplicas : 1
maxReplicas : 10
rules : [
{
name : 'http-scaling-rule'
http : {
metadata : {
concurrentRequests : '10'
}
}
}
]
}
}
}
}
output fqdn string = containerApp.properties.configuration.ingress.fqdn
main.bicep では、Blue-Green Deployments を行うため、revisions-mode に multiple
を指定します。
新旧 RevisionSuffix に v1
を指定することで、デプロイしたアプリケーションの traffic を 100%
にします。
param environmentName string = 'env-${resourceGroup().name}'
param containerAppName string = 'dapr-frontend'
param location string = resourceGroup().location
param containerImage string = 'thara0402/dapr-frontend:0.1.0'
param revisionSuffix string = 'v1'
param oldRevisionSuffix string = 'v1'
param isExternalIngress bool = true
param revisionMode string = 'multiple'
resource environment 'Microsoft.App/managedEnvironments@2022-03-01' existing = {
name : environmentName
}
module apps 'apps.bicep' = {
name : 'container-apps'
params : {
containerAppName : containerAppName
location : location
environmentId : environment.id
containerImage : containerImage
revisionSuffix : revisionSuffix
oldRevisionSuffix : oldRevisionSuffix
revisionMode : revisionMode
isExternalIngress : isExternalIngress
}
}
Azure CLI を使って、デプロイします。
$ az deployment group create -f ./deploy/app/main.bicep -g < ResourceGroup Name>
デプロイすると、dapr-frontend--v1
という Revision が作成されました。
dapr-frontend.bravewave-d4e6d1bd.japaneast.azurecontainerapps.io
という FQDN が自動生成されました。
ASP.NET Core Web アプリケーションがブラウザで表示されることを確認できます。
Blue-Green Deployments を行う
Staging へのデプロイを想定し、新しいバージョンをデプロイします。
main.bicep では、containerImage のタグを 0.2.0
、revisionSuffix のバージョンを v2
に更新することで、先ほどデプロイした Revision( dapr-frontend--v1
)へのトラフィックを 100%
のまま、新しい Revision をデプロイします。
param containerImage string = 'thara0402/dapr-frontend:0.2.0'
param revisionSuffix string = 'v2'
デプロイすると、dapr-frontend--v2
という Revision が追加されました。
traffic が「0」の新しい Revision には、ユーザーに公開される FQDN とは異なる FQDN が割り当てられるので、リリース前のテストができます。
dapr-frontend--v2.bravewave-d4e6d1bd.japaneast.azurecontainerapps.io/
という Revision が含まれた FQDN が自動生成されました。
リリース前のテストが完了したので、Azure CLI を使って Swap します。
拡張モジュールをインストールし、名前空間を登録します。Preview のときは Microsoft.Web 名前空間でしたが、Microsoft.App 名前空間に移行されています。
$ az extension add --name containerapp --upgrade
$ az provider register --namespace Microsoft.App
$ az containerapp ingress traffic set -n dapr-frontend -g < ResourceGroup Name > \
--revision-weight dapr-frontend--v1=0 latest=100
traffic のパーセンテージが入れ替わったことを確認できます。
ユーザーに公開される FQDN にアクセスすると、V2 に更新された ASP.NET Core Web アプリケーションが表示されます。
最後に、旧バージョンの Revision をシャットダウンします。アクティブのままだと、課金対象となってしまいます。
$ az containerapp revision deactivate -n dapr-frontend -g < ResourceGroup Name> --revision dapr-frontend--v1
新バージョンの Revision のみになったことを確認できます。
まとめ
Azure Container Apps で Blue-Green Deployments を試してみました。トラフィック制御の比率を変えることで AB テストやカナリアリリースもできます。
Envoy によるトラフィック制御以外にも、KEDA によるスケーリングや Dapr によるサイドカーなどの面白い機能があるので、引き続き試していきたいと思います。
今回のソースコードは、こちらのリポジトリで公開しています。
github.com