今回のJAZUG札幌支部「きたあず」勉強会はMicrosoftの寺田佳央さんに来て頂きまして、「Kubernetesハッカソン」として開催しました。
きたあずとしては初のハッカソンで、2日間終日開催という全くゆるくない勉強会でした。
- DockerイメージのビルドからKubernetesクラスタへのデプロイを一通り理解出来た
- ServiceでLoadBlancerを使用しない
- ポータビリティに注意
概要説明と準備
まず寺田さんによるコンテナからKubernetesまでの概要説明があり、その後は実際にチームになってハッカソンをしました。
まず、みんなでポストイットに「今回のハッカソンでやりたいこと」を記入しホワイトボードに貼り付けました。
この「やりたいこと」をベースに寺田さんが流れをアレンジしてハッカソンを進めていきました。
実際のハッカソンの流れ
今日の流れとハマりポイントをメモ。(主に自分用)
まず、Kubernetes上にデプロイ・動作させるDockerコンテナを作るところから始めました。
http://example.com/api/values
とリクエストを投げると、
["value1"],["value2"]
というレスポンスを返すようなコンテナを作成しました。
- VisualStudioで生成されるDockerfileだと、パスの問題でbuild出来なかった
- VSで生成されたDockerfileは、特にディレクトリ遷移まわりを見直す必要がある。
ビルドしたdockerイメージをAzure Container Registoryにpushするには、まず事前に追加したContainer Registoryにログインする。
$ docker login -u kitaazu22 kitaazu22.azurecr.io
$ sudo docker push kitaazu22/application:1
kubectlコマンドでContainer RegistoryからDockerイメージを取得出来るようにするには、認証情報(secret)を設定する必要がある。
$ kubectl create secret docker-registry docker-reg-credential \
--docker-server=kitaazu22.azurecr.io \
--docker-username=username \
--docker-password=xxxxxxxxxxxxxxxxxxxxxxx \
--docker-email=foo-bar@example.com
出来たかどうかを行う
$ kubectl get secret
結果はこうなる
NAME TYPE DATA AGE
default-token-c98jz kubernetes.io/service-account-token 3 25h
docker-reg-credential kubernetes.io/dockerconfigjson 1 21h
KubernetesのPodは各ノードに分散されるため、外部からの通信リクエストに一元的に応答させるには、一定の固定IPが必要になる。serviceを指定してエンドポイントを準備する。
apiVersion: v1 kind: Service metadata: labels: app: kitaazu22-service name: kitaazu22-service spec: ports: - port: 80 name: http targetPort: 80 selector: app: kitaazu22-service version: v3 sessionAffinity: None type: ClusterIP
サービスをこれで登録する。
$ kubectl apply -f sample-externalip.yaml
・LoadBalancerは本番環境では使用しないこと
次に、外部からの通信を受け付けるためにingressを設定する。
通信の流れを、「 インターネット → service」 ではなく、「インターネット → ingress → service 」にする。
kind: Ingress metadata: name: kitaazu22 annotations: kubernetes.io/ingress.class: addon-http-application-routing spec: rules: - host: kitaazu22.hogehogoehogeabb25d.eastus.aksapp.io http: paths: - backend: serviceName: kitaazu22-service servicePort: 80 path: /
そして適用する。
$ kubectl apply -f ingress.yaml
クラスタへのデプロイ設定を記述する。ここで、ローリングアップデートを設定したり、使用するコンテナを指定出来る。
eployment.yml apiVersion: apps/v1beta2 kind: Deployment metadata: name: kitaazu22-service spec: replicas: 2 selector: matchLabels: app: kitaazu22-service template: metadata: labels: app: kitaazu22-service env: test version: v1 spec: imagePullSecrets: - name: docker-reg-credential containers: - name: kitaazu22-service image: kitaazu22.azurecr.io/kitaazu22app:1
deployment.yamlをKubernetesに適用する。
$ kubectl apply -f deployment.yaml
新しいコンテナをデプロイする際、サービスを止めること無くアップデートを行う。この方法を使うと、クラスタ内のレプリカを少しずつ差し替えしていくことで、無停止アップデートを行うことが出来る。
apiVersion: apps/v1beta2 kind: Deployment metadata: name: kitaazu22-service-fuwa spec: minReadySeconds: 20 progressDeadlineSeconds: 600 strategy: type: RollingUpdate rollingUpdate: maxSurge: 50% maxUnavailable: 30% replicas: 3 selector: matchLabels: app: kitaazu22-service template: metadata: labels: app: kitaazu22-service env: test version: v3 spec: imagePullSecrets: - name: docker-reg-credential containers: - name: kitaazu22-service-fuwa image: kitaazu22.azurecr.io/kitaazu22:5 livenessProbe: httpGet: path: /api/healthx port: 80 initialDelaySeconds: 20 timeoutSeconds: 5 periodSeconds: 10 failureThreshold: 3 readinessProbe: httpGet: path: /api/healthy port: 80 initialDelaySeconds: 30 timeoutSeconds: 5 periodSeconds: 10 failureThreshold: 5
感想
仕事ではKubernetesを使っておらず、夜の仕事の研究枠でAKSやRacncherOSを使ってきました。業務で使えるようになるべく自分の環境でKubernetesクラスターを作ったりしてきたのですが、断片的な情報で構築していたため、知識の抜けが出ていました。
今回のハッカソンでも知識の抜けが表面に出てしまい、実際に自分が皆の前でkubectlコマンドを打ち込む際にも手間取ってしまいました。
今回のハッカソンでは、全員が1つのチームとなって教えあいながら進めることが出来たため、自分自身の問題に気づくことが出来ました。これは非常に大きな成果だと思っています。このような機会が無いと自分の問題に気づけませんし、改善を図るチャンスも得られなかったと思います。
また、結構kubectlやDockerのビルドまわりでミスをしながらハマりポイントを見つけることが出来たのも収穫かなと思っています。こういう所でどんどんミスをしていかないと、大事な時にミスって事故を招いちゃうので・・・
「英語のドキュメントをどんどん読んでいかないと追いつかない」という寺田さんの言葉にはとても共感しました。
英語のドキュメントはなかなか日本語訳されないし、日本語訳が来るのを待ってるとその分世界的に取り残されちゃうんですよね。
私自身も同じ事を考えているのですが、「日本語化への協力」という形で対応してきました。
Microsoft Azureのdocsの日本語を直してみたただ寺田さんとの会話で、それも限界に近いと感じました。発信されてくる情報は日々増えており、元情報は全て英語です。そのため、いくら翻訳や修正に協力してもどこかで破綻するような気づきが得られました。英語の文章を和訳すること無くそのまま理解し、知識化することが今後エンジニアには重要になると確信することが出来ました。
とりあえず、私はAzure Portalの言語設定を英語にするところからスタートしました。