はじめに
こんにちは、ACS事業部の吉川です。
Microsoft Build、ご覧になられていますでしょうか。
私の所属するACS事業部では、Azure のコンテナサービスを中心にお客様の内製化を支援しています。
業務的に関連が深いこともあり、Microsoft Build においても特にコンテナ関連のアップデートに注目していました。
その中でこんな内容を目にしました。
Draft 2を使えば、開発者はアプリの作成、コンテナ化、Kubernetesへのデプロイを行うことができます。
Draft 2 とはどういったものでしょうか?
試しに少し触ってみましたので、簡単にレポートします。
使用にあたっては公式の英語版ドキュメントを参考にしています。
Draft とは
Draft は2017年に Microsoft が公開したコンテナアプリケーションの構築ツールです。
開発言語を自動で判別してDockerfileを生成、Kubernetesへのデプロイができるなど、デベロッパーがよりアプリ開発に注力できるような支援ツールです。 Microsoft が買収したDeis社の技術をベースとして開発されていたものが、この度バージョン2としてリブートした模様です。
もともと https://github.com/Azure/draftv2 というリポジトリ名だったものが、https://github.com/Azure/draft に改名されたようです。v1 は draft-classic として以下のリポジトリで公開されています。
本記事では以降 Draft 2 のことを Draft と表記します。
Draft の利用準備
Draftは Azure CLI にプレビュー機能として統合されています。
プレビュー機能を有効にするために、以下のコマンドを実行します。
# Azure CLIの最新化 az upgrade # プレビュー機能の有効化 az extension add --name aks-preview # 過去にプレビュー機能を有効化していた場合は、以下のコマンドで更新する az extension update --name aks-preview
GitHub CLIも必要です。事前にインストールしておきましょう。
draft create - Dockerfile/Manifests の自動生成
環境準備が終わったら実際に Draft を試してみましょう。
サンプルとして以下の Python ファイルを準備しました。Python の http.server ドキュメント からの引用です。
import http.server import socketserver PORT = 8000 Handler = http.server.SimpleHTTPRequestHandler with socketserver.TCPServer(("", PORT), Handler) as httpd: print("serving at port", PORT) httpd.serve_forever()
作業用にディレクトリを作り、この Python ファイルを配置します。合わせて requirements.txt も作成しておきます。(中身は空でOK)
vi app.py
touch requirements.txt
以下のようなファイル配置です。
. ├── app.py └── requirements.txt
このディレクトリ内で以下のコマンドを実行します。
az aks draft create
対話形式でプロンプトが表示されます。必要な内容を入力していきましょう。
[Draft] --- Detecting Language --- [Draft] --> Draft detected Python (100.000000%) [Draft] --- Dockerfile Creation --- # Dockerfile 内で EXPOSE するポート番号を入力 ✔ Please Enter the port exposed in the application: 8000 [Draft] --> Creating Dockerfile... [Draft] --- Deployment File Creation --- Use the arrow keys to navigate: ↓ ↑ → ← # Kubernetes のデプロイファイルの形式を選択。今回は manifests を選択しました。 ? Select k8s Deployment Type: helm kustomize ▸ manifests # Kubernetes の Pod の公開ポート番号を入力 ✔ Please Enter the port exposed in the application: 8000 # Kubernetes 上でのアプリケーションの名前を入力 ✔ Please Enter the name of the application: draftapp [Draft] --> Creating manifests Kubernetes resources... [Draft] Draft has successfully created deployment resources for your project 😃 [Draft] Use 'draft setup-gh' to set up Github OIDC.
コマンドの実行が完了すると、Dockerfileとマニフェストが生成されています。
. ├── .dockerignore ├── Dockerfile ├── app.py ├── manifests │ ├── deployment.yaml │ └── service.yaml └── requirements.txt
Dockerfile
FROM python ENV PORT 8000 EXPOSE 8000 WORKDIR /usr/src/app COPY requirements.txt ./ RUN pip install --no-cache-dir -r requirements.txt COPY . . ENTRYPOINT ["python"] CMD ["app.py"]
manifests/deployment.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: draftapp labels: app: draftapp spec: replicas: 1 selector: matchLabels: app: draftapp template: metadata: labels: app: draftapp spec: containers: - name: draftapp image: draftapp ports: - containerPort: 8000
manifests/service.yaml
apiVersion: v1 kind: Service metadata: name: draftapp spec: type: LoadBalancer selector: app: draftapp ports: - protocol: TCP port: 80 targetPort: 8000
ファイルが生成されました!
draft setup-gh - GitHub Actions 用 OIDC 自動設定
続いての機能 setup-gh は、GitHub Actions の OpenID Connect の設定を自動で行ってくれます。
Azure AD へのアプリ/サービスプリンシパルの登録と、GitHub への認証情報の登録を 1 コマンドで実行してくれるのでとっても便利です。
が、現状では draft のバイナリにバグがありうまく動きません。(当方が試した限り v0.0.20 ではサービスプリンシパルの作成あたりでエラーになってしまいます)
以下の Pull Request で修正されており main ブランチにマージ済みのため、まもなく修正版バイナリがリリースされると思われます。
早く試したかったので、バイナリをビルドして動かしてみます。ビルドには Go 1.18.x が必要です。
git clone git@github.com:Azure/draft.git cd draft make # Azure CLI が利用している draft バイナリを置き換え cp draft ~/.aksdraft/draft-linux-amd64
あらかじめ Azure のリソースグループと GitHub のリポジトリを作成しておく必要があります。以下のように作成しておきましょう。
# Azure リソースグループ作成 az group create -n rg-draft -l japaneast # draft-sample という名前のプライベート リポジトリを作成 gh repo create draft-sample --private
準備ができたら draft setup-gh を実行してみましょう。
az aks draft setup-gh
以下のように対話形式で進んでいきます。
# draft のバイナリを新しいもので置き換えるか。上記手順でビルドしたものを利用するので N を選択する。 We have detected a newer version of Draft. Would you like to download it? (y/N): # Azure AD に登録するアプリの名前を入力 ✔ Enter app registration name: for-gh-workflow # Azure サブスクリプションを選択する Use the arrow keys to navigate: ↓ ↑ → ← ✔ ########-####-####-####-############ ? Please choose the subscription ID you would like to use.: # Azure リソースグループの名前を入力 ✔ Enter resource group name: rg-draft # GitHub リポジトリの名前を入力 ✔ Enter github organization and repo (organization/repoName): <GitHub ユーザー名>/draft-sample [Draft] Draft has successfully set up Github OIDC for your project 😃 [Draft] Use 'draft generate-workflow' to generate a Github workflow to build and deploy an application on AKS.
完了すると Azure AD 側ではアプリの作成とフェデレーション情報の登録が完了しており、
GitHub 側では Secret が登録されています。
割と面倒な OpenID Connect の登録がサクサク行えるのはとてもイイですね!
draft generate-workflow - GitHub Actions のワークフロー生成
最後に紹介する機能は GitHub Actions のワークフロー生成機能です。
事前に Azure Container Registry(ACR) と AKS クラスターを作成しておきます。
# ACR 作成 az acr create -g rg-draft -n drafttestregistry --sku Basic # AKS クラスター作成 az aks create -g rg-draft -n draft-test-cluster --node-count 1
先ほど az aks draft create を実行したディレクトリ内で、以下のコマンドを実行してみましょう。
az aks draft generate-workflow
対話式のプロンプトが開始されますので、順に入力していきます。
# draft のバイナリを新しいもので置き換えるか。上記でビルドしたものを利用するので N を選択する。 We have detected a newer version of Draft. Would you like to download it? (y/N): # ACR 名を入力 ✔ Please enter container registry name: drafttestregistry # ビルドするコンテナの名前を入力 ✔ Please enter container name: draftapp # AKS クラスターのリソースグループ名を入力 ✔ Please enter cluster resource group name: rg-draft # AKS クラスター名を入力 ✔ Please enter AKS cluster name: draft-test-cluster # ワークフローの対象とするブランチ名を入力。今回は main としています。 ✔ Please enter name of the repository branch to deploy from, usually main: main [Draft] Draft has successfully generated a Github workflow for your project 😃
完了すると、以下のようにワークフローファイルが生成されています。
. ├── .dockerignore ├── .github │ └── workflows │ └── azure-kubernetes-service.yml ├── Dockerfile ├── app.py ├── manifests │ ├── deployment.yaml │ └── service.yaml └── requirements.txt
.github/workflows/azure-kubernetes-service.yml
name: Build and deploy an app to AKS "on": push: branches: - main workflow_dispatch: null env: AZURE_CONTAINER_REGISTRY: 'drafttestregistry' CLUSTER_NAME: draft-test-cluster CONTAINER_NAME: draftapp DEPLOYMENT_MANIFEST_PATH: ./manifests IMAGE_PULL_SECRET_NAME: drafttestregistry secret RESOURCE_GROUP: rg-draft jobs: buildImage: permissions: contents: read id-token: write runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Azure login uses: azure/login@v1.4.3 with: client-id: ${{ secrets.AZURE_CLIENT_ID }} subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} tenant-id: ${{ secrets.AZURE_TENANT_ID }} - name: Build and push image to ACR run: | az acr build --image ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} --registry ${{ env.AZURE_CONTAINER_REGISTRY }} -g ${{ env.RESOURCE_GROUP }} . createSecret: permissions: contents: read id-token: write runs-on: ubuntu-latest steps: - name: Azure login uses: azure/login@v1.4.3 with: client-id: ${{ secrets.AZURE_CLIENT_ID }} subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} tenant-id: ${{ secrets.AZURE_TENANT_ID }} - name: Get K8s context uses: azure/aks-set-context@v2.0 with: cluster-name: ${{ env.CLUSTER_NAME }} resource-group: ${{ env.RESOURCE_GROUP }} - id: get-acr-creds name: Get ACR credentials run: | az acr update -n ${{ env.AZURE_CONTAINER_REGISTRY }} -g ${{ env.RESOURCE_GROUP }} --admin-enabled true ACR_USERNAME=$(az acr credential show -g ${{ env.RESOURCE_GROUP }} -n ${{ env.AZURE_CONTAINER_REGISTRY }} --query username -o tsv) ACR_PASSWORD=$(az acr credential show -g ${{ env.RESOURCE_GROUP }} -n ${{ env.AZURE_CONTAINER_REGISTRY }} --query passwords[0].value -o tsv) echo "::add-mask::${ACR_USERNAME}" echo "::set-output name=username::${ACR_USERNAME}" echo "::add-mask::${ACR_PASSWORD}" echo "::set-output name=password::${ACR_PASSWORD}" - name: Create K8s secret for pulling image from ACR uses: Azure/k8s-create-secret@v1.1 with: container-registry-password: ${{ steps.get-acr-creds.outputs.password }} container-registry-url: ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io container-registry-username: ${{ steps.get-acr-creds.outputs.username }} secret-name: ${{ env.IMAGE_PULL_SECRET_NAME }} deploy: permissions: actions: read contents: read id-token: write runs-on: ubuntu-latest needs: - buildImage - createSecret steps: - uses: actions/checkout@v3 - name: Azure login uses: azure/login@v1.4.3 with: client-id: ${{ secrets.AZURE_CLIENT_ID }} subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} tenant-id: ${{ secrets.AZURE_TENANT_ID }} - name: Get K8s context uses: azure/aks-set-context@v2.0 with: cluster-name: ${{ env.CLUSTER_NAME }} resource-group: ${{ env.RESOURCE_GROUP }} - name: Deploys application uses: Azure/k8s-deploy@v3.1 with: action: deploy imagepullsecrets: ${{ env.IMAGE_PULL_SECRET_NAME }} images: | ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} manifests: ${{ env.DEPLOYMENT_MANIFEST_PATH }}
リポジトリにPushして、動作を確認してみます。
git init git add -A git commit -m "first commit" git branch -M main git remote add origin git@github.com:<GitHubユーザー名>/draft-sample.git git push -u origin main
Push をトリガーにジョブが起動し、
コンテナイメージのビルド&ACR への Push が行われ、
AKS へのデプロイまで行われます。
超・簡・単!
おわりに
Draft を使うことで、コンテナイメージの作成/AKS へデプロイがとっても簡単になります。
対話形式で必要情報を入力していくので、使い方もわかり易く Kubernetes に自信のない方でも比較的使いやすい形で提供されています。
まだプレビューということで一部動作に不安もありますが、今後に期待できそうな機能です。ぜひ使ってみてください!