ROMANCE DAWN for the new world

Microsoft Azure を中心とした技術情報を書いています。

Azure Container Service (AKS) を試してみた

先週、Azure のマネージドな Kubernetes サービスとして Azure Container Service (AKS) のプレビューがリリースされたので、試してみました。
azure.microsoft.com

Azure Container Service (AKS) を作成する

Azure Container Service (AKS) Documentation - Tutorials, API Reference | Microsoft Docs

公式ドキュメントにも記載されているように、Azure Portal の Cloud Shell を使うと、サクッと試すことができます。
ただ、実際の開発作業で使うことを考えると、ローカルの開発マシンで AKS を操作したいので、Azure CLI の Docker Image を使って試してみます。

Cloud Shell には、Kubectl (Kubernetes のクライアントツール) と Helm (Kubernetes のパッケージマネージャー)がインストール済みですが、 Azure CLI の Docker Image には含まれていません。
そのため、Kubectl と Helm がインストール済みの Dockerfile を書いてみました。

FROM azuresdk/azure-cli-python:2.0.20

# Install kubectl
RUN wget -O /usr/local/bin/kubectl https://storage.googleapis.com/kubernetes-release/release/v1.8.2/bin/linux/amd64/kubectl \
 && chmod +x /usr/local/bin/kubectl

# Install Helm
RUN wget https://storage.googleapis.com/kubernetes-helm/helm-v2.7.0-linux-amd64.tar.gz \
 && tar -zxvf helm-v2.7.0-linux-amd64.tar.gz \
 && mv linux-amd64/helm /usr/local/bin/helm \
 && rm -rf linux-amd64

ローカルの開発マシンでは、Kubectl と Helm の接続情報、SSH 接続キーをマウントして、この Docker Image を実行します。
develop ディレクトリは、Kubernetes にデプロイする YAML ファイルやカスタムの Helm Chats を想定して、マウントしてます。

$ docker run -it --rm -v ${HOME}/.kube/aks:/root/.kube -v ${HOME}/.helm/aks:/root/.helm -v ${HOME}/.ssh/aks:/root/.ssh -v ${HOME}/develop:/develop thara0402/azure-cli-k8s:latest

Azure CLI にログインします。

$ az login

まだプレビュー中なので、サブスクリプションごとにアクティブ化が必要です。

$ az provider register -n Microsoft.ContainerService

リソースグループを作成します。利用できるリージョンは限られており、まだ日本は使えません。

$ az group create --name aks --location westus2

AKS を作成します。

$ az aks create --resource-group aks --name myK8sCluster --node-count 1 --generate-ssh-keys

kubectl の接続情報をダウンロードします。

$ az aks get-credentials --resource-group=aks --name=myK8sCluster

Agent Node が1つ作成されました。Master Node は、Azure 側に管理を任せているので表示されません。

$ kubectl get nodes
NAME                        STATUS    ROLES     AGE       VERSION
aks-agentpool1-29980149-0   Ready     agent     2d        v1.7.7

Azure Portal で確認すると、2つのリソースグループが作成されています。どちらのリソースグループにも、Master Node の仮想マシンは表示されていません。

ASP.NET Core アプリケーションをデプロイする

ASP.NET Core アプリケーションの Docker Image を使って、AKS にデプロイします。

$ kubectl run mvcapp --image thara0402/mvcapp:v1
$ kubectl get pods
NAME                     READY     STATUS    RESTARTS   AGE
mvcapp-614172684-tddnb   1/1       Running   0          1m

$ kubectl expose deployments mvcapp --port=5000 --type=LoadBalancer
$ kubectl get svc
NAME         TYPE           CLUSTER-IP     EXTERNAL-IP      PORT(S)          AGE
kubernetes   ClusterIP      10.0.0.1       <none>           443/TCP          2d
mvcapp       LoadBalancer   10.0.121.196   52.175.213.163   5000:31552/TCP   3m

ブラウザで 52.175.213.163:5000 に接続すると、ASP.NET Core MVC のテンプレートが表示されます。
f:id:TonyTonyKun:20171031035658p:plain
次に、Agent Node の数を3つに増やしてみます。

$ az aks scale --resource-group=aks --name=myK8SCluster --agent-count 3
$ kubectl get nodes
NAME                        STATUS     ROLES     AGE       VERSION
aks-agentpool1-29980149-0   Ready      agent     29m       v1.7.7
aks-agentpool1-29980149-1   Ready      agent     16m       v1.7.7
aks-agentpool1-29980149-2   Ready      agent     16m       v1.7.7

最後に、Kubernetes Cluster を ver.1.8.1 にバージョンアップしてみます。

$ az aks upgrade --name myK8sCluster --resource-group aks --kubernetes-version 1.8.1
$ kubectl get nodes
NAME                        STATUS     ROLES     AGE       VERSION
aks-agentpool1-29980149-0   Ready      agent     40m       v1.8.1
aks-agentpool1-29980149-1   Ready      agent     30m       v1.8.1
aks-agentpool1-29980149-2   Ready      agent     30m       v1.8.1

Helm を使ってデプロイする

Helm を使ってデプロイしようと試しましたが、エラーが発生してしまいました。

$ helm list
Error: forwarding ports: error upgrading connection: error dialing backend: dial tcp 10.240.0.4:10250: getsockopt: connection refused

調べてみると、Helm の FAQ に該当しそうな Workaround があったのですが、Master Node で作業する必要があり、試すことができませんでした。

helm/install_faq.md at master · kubernetes/helm · GitHub

これ以外にも、Kubernetes Dashboard が表示できなかったりするので、まだプレビューということもあり、もう少し様子をみたいと思います。

まとめ

これまでも Azure Container Service で Kubernetes を展開することはできましたが、どちらかと言うと仮想マシンのテンプレートでした。
ちょっとした動作確認に使う分にはいいですが、本番環境で運用するとなると、IaaS と同等の運用コストがかかります。
AKS は、Google Container Engine (GKE) のようなサービスで、Kubernetes の Master Node の管理を Azure 側に任せてしまい、Agent Node とデプロイするアプリケーションの管理に注力できます。
GA に向けて、クラウドらしい便利なサービスになることを期待したいです。

Azure Container Service の Kubernetes に Helm を使ってアプリケーションをデプロイする

Azure Container Service に Kubernetes を展開して、Helm を使ってアプリケーションをデプロイしてみます。

Helm とは

Kubernetes のパッケージマネージャーです。

docs.helm.sh

Kubernetes にデプロイする YAML ファイルをまとめたパッケージは、Charts と呼ばれます。Helm の公式リポジトリとして、KubeApps が提供されていて、WordPress や Jenkins など100以上のアプリケーションの Charts が公開されています。

Helm をインストールする

こちらのドキュメントに従ってインストールします。

docs.helm.sh

まず、Azure Portal から Azure Container Service を作成します。Kubernetes の Master Node に SSH で接続して、Helm のバイナリをダウンロードします。

$ curl -O https://storage.googleapis.com/kubernetes-helm/helm-v2.6.1-linux-amd64.tar.gz
$ tar -zxvf helm-v2.6.1-linux-amd64.tar.gz
$ sudo mv linux-amd64/helm /usr/local/bin/helm

次に、helm init コマンドを実行します。

$ helm init

これで、Helm のインストールが完了です。

Helm を使って WordPress をデプロイする

KubeApps で公開されている Charts を使って、WordPress をデプロイしてみます。
WordPress の Charts を指定して、helm install コマンドを実行します。

$ helm install --name my-wp stable/wordpress
NAME:   my-wp
LAST DEPLOYED: Sat Sep 23 17:43:09 2017
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/PersistentVolumeClaim
NAME             STATUS  VOLUME                                    CAPACITY  ACCESSMODES  STORAGECLASS  AGE
my-wp-wordpress  Bound   pvc-493f1d91-a03b-11e7-944e-000d3a72a60e  10Gi      RWO          default       13s
my-wp-mariadb    Bound   pvc-4942547b-a03b-11e7-944e-000d3a72a60e  8Gi       RWO          default       13s

==> v1/Service
NAME             CLUSTER-IP    EXTERNAL-IP  PORT(S)                     AGE
my-wp-mariadb    10.0.73.148   <none>       3306/TCP                    13s
my-wp-wordpress  10.0.193.167  <pending>    80:30912/TCP,443:30683/TCP  13s

==> v1beta1/Deployment
NAME             DESIRED  CURRENT  UP-TO-DATE  AVAILABLE  AGE
my-wp-mariadb    1        1        1           0          13s
my-wp-wordpress  1        1        1           0          13s

==> v1/Secret
NAME             TYPE    DATA  AGE
my-wp-wordpress  Opaque  3     14s
my-wp-mariadb    Opaque  2     14s

==> v1/ConfigMap
NAME           DATA  AGE
my-wp-mariadb  1     14s

NOTES:
1. Get the WordPress URL:

  NOTE: It may take a few minutes for the LoadBalancer IP to be available.
        Watch the status with: 'kubectl get svc --namespace default -w my-wp-wordpress'

  export SERVICE_IP=$(kubectl get svc --namespace default my-wp-wordpress -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
  echo http://$SERVICE_IP/admin

2. Login with the following credentials to see your blog

  echo Username: user
  echo Password: $(kubectl get secret --namespace default my-wp-wordpress -o jsonpath="{.data.wordpress-password}" | base64 --decode)

WordPress と MariaDB がデプロイされたことが分かります。Kubernetes の5つのオブジェクトで構成されています。

  • PersistentVolumeClaim
  • Service
  • Deployment
  • Secret
  • ConfigMap

これらのオブジェクトを1つのパッケージとして、Helm Install コマンドだけでデプロイできました。Charts の内容は、GitHub で確認することができます。

github.com

数分待つと、デプロイが完了するので、サービスの EXTERNAL IP にブラウザからアクセスしてみます。

f:id:TonyTonyKun:20170930163933p:plain

削除するときは、Helm delete コマンドを使います。

$ helm delete my-wp --purge

Helm Charts を作ってみる

自分が作った ASP.NET Core のアプリケーションをデプロイする Charts を作ってみます。
helm create コマンドを実行すると、Charts のテンプレートが作成されます。

$ helm create mvcapp

f:id:TonyTonyKun:20170930164003p:plain

deployment.yaml と service.yaml を確認します。

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: {{ template "fullname" . }}
  labels:
    chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}"
spec:
  replicas: {{ .Values.replicaCount }}
  template:
    metadata:
      labels:
        app: {{ template "fullname" . }}
    spec:
      containers:
      - name: {{ .Chart.Name }}
        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
        imagePullPolicy: {{ .Values.image.pullPolicy }}
        ports:
        - containerPort: {{ .Values.service.internalPort }}
        livenessProbe:
          httpGet:
            path: /
            port: {{ .Values.service.internalPort }}
        readinessProbe:
          httpGet:
            path: /
            port: {{ .Values.service.internalPort }}
        resources:
{{ toYaml .Values.resources | indent 12 }}
apiVersion: v1
kind: Service
metadata:
  name: {{ template "fullname" . }}
  labels:
    chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}"
spec:
  type: {{ .Values.service.type }}
  ports:
  - port: {{ .Values.service.externalPort }}
    targetPort: {{ .Values.service.internalPort }}
    protocol: TCP
    name: {{ .Values.service.name }}
  selector:
    app: {{ template "fullname" . }}

この yaml を見ると分かるように、Charts に対して外部からパラメータを指定できるようになっています。
values.yaml を編集して、ASP.NET Core のアプリケーションをデプロイできるようにします。

replicaCount: 1
image:
  repository: thara0402/mvcapp
  tag: v1
  pullPolicy: IfNotPresent
service:
  name: mvcapp-service
  type: LoadBalancer
  externalPort: 80
  internalPort: 5000
resources:

この Charts を指定して、helm install コマンドを実行します。

$ helm install --name my-mvc ./mvcapp
NAME:   my-mvc
LAST DEPLOYED: Sat Sep 23 17:43:18 2017
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/Service
NAME           CLUSTER-IP    EXTERNAL-IP  PORT(S)       AGE
my-mvc-mvcapp  10.0.124.120  <pending>    80:30617/TCP  4s

==> v1beta1/Deployment
NAME           DESIRED  CURRENT  UP-TO-DATE  AVAILABLE  AGE
my-mvc-mvcapp  1        1        1           0          4s


NOTES:
1. Get the application URL by running these commands:
     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
           You can watch the status of by running 'kubectl get svc -w my-mvc-mvcapp'
  export SERVICE_IP=$(kubectl get svc --namespace default my-mvc-mvcapp -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
  echo http://$SERVICE_IP:80

ASP.NET Core アプリケーションがデプロイされたことを確認できます。

f:id:TonyTonyKun:20170930164049p:plain

まとめ

Kubernetes に Helm を使って、アプリケーションをデプロイしてみました。
使いたいアプリケーションが KubeApps にあればすぐにデプロイできますし、自分で Charts を作ることもできます。Kubernetes の Service や Deployment だけなく、アプリとデータベースをまとめることもできます。
Helm は、Kubernetes にデプロイするアプリケーションを管理できる便利なツールなので、積極的に活用していきたいです。

書籍「新しい Linux の教科書」の感想

これまで Windows を使ってきたのですが、最近仕事で Linux を使うことが多くなってきたので、「新しい Linux の教科書」を読みました。

新しいLinuxの教科書

新しいLinuxの教科書

どんな書籍なのか?

この書籍は、これから Linux を学ぼうとしている初心者に向けた入門書です。他にも多くの Linux 入門書が出版されていますが、CLI を利用したシェルの活用に絞って解説しています。主に、CentOS を利用した例をベースに、Ubuntu では差異があるケースのみ追加する形式となっています。

Windows 経験者が押さえておきたいポイント

Linux のディレクトリ構造

Windows とは違ってシステム全体で1つのディレクトリツリーしかありませんし、各ディレクトリ(/etc、/usr、/var など)の役割を知っておく必要があります。

テキストエディタの操作

Linux のデフォルトのエディタである「Vim」の操作です。vi コマンドで起動し、終了させる方法をはじめとして、カーソルキーを使わない、h、j、k、lを利用したカーソル移動は慣れが必要です。

ファイルとディレクトリのパーミッション

ls -l コマンドで表示されるパーミッションや chmod コマンドでのパーミッション設定は重要です。ファイルの r:読み取り、w:書き込み、x:実行権限は、ディレクトリだと違った意味になりますし、パーミッションは数値モード(r:4, w:2, x:1)でも設定できます。

標準入出力とパイプライン

Linux は、1つ1つのコマンドが小さくシンプルですが、リダイレクトとパイプラインを組み合わせて連携させることで、さまざまなシェルスクリプトを作成できます。シェルスクリプトを作れば、同じ処理を再利用できますし、操作ミスをなくすことができます。

アーカイブと圧縮

Windows の zip ファイルは、Linux の tar ファイルや gzip ファイルのようにアーカイブと圧縮を区別していないので、違いを押さえておきたいです。

Linux の環境を Azure に構築する

読んだ内容の理解を深めるには、実際に Linux の環境を用意して、コマンドやシェルスクリプトを試してみるのが良いです。
Azure を活用すれば、簡単に Linux の環境を構築できます。

f:id:TonyTonyKun:20170827161849p:plain

Azure ポータルにログインして、Compute を選択して「centos-base」などで検索するといくつかイメージがヒットします。シンプルな「CentOS-base 7.3」などを選択すれば、5分ぐらいで Linux の環境を構築できます。
使わないときは、仮想マシンを停止しておくことで、無駄な課金を防ぐことができます。

まとめ

この書籍では、初心者を対象とした Linux の基本操作だけでなく、「Linux らしい考え方」を解説しているため、どうやって Linux を使えば良いわからない人にお勧めできる内容だと思います。