kakakakakku blog

Weekly Tech Blog: Keep on Learning!

「Japan Container Days v18.04」に参加して1日中コンテナのことを考えていた

今日は「Japan Container Days v18.04」に参加してきた.正直「Container Days」と言うよりも「Kubernetes Days」って感じだったけど,1日ずっとコンテナのことばかりを考えていた.発表テーマも多岐にわたっていて,バランスが非常に良かったと思う.僕が参加したセッションをまとめておく.

containerdays.jp

サイバーエージェントにおけるプライベートコンテナ基盤 AKE を支える技術

  • ake client を使ってクラスタを起動できる
    • ake client の裏は OpenStack Heat を使っている
  • Kubernetes にパッチを当てているため,ビルドから始める
  • Kubernetes と Swarm をサポートしている
  • Datadog / Elastic Stack なども連携できる
  • 既存のエコシステムは採用しなかった
    • OpenStack Magnum
    • Rancher
    • Tectonic

3年前まで所属してたアドテクスタジオからの発表だった.「おうち Kubernetes」の事例などは知っていたけど,AKE の詳細解説は今まで聞いたことがなかった.実装は大変そうだけど,既にプロダクションでも稼働してるとのことで,すごいなぁー!

developers.cyberagent.co.jp

speakerdeck.com

マイクロサービスアプリケーションとしての機械学習

  • メルカリの画像認識機能
    • 出品時に写真を撮ると,名前,カテゴリー,色などを自動推定する
  • 機械学習エンジニア側で Dockerfile を用意すれば,残りは SRE で構築してもらうことができた
    • Web Server / Queue / Worker / 機械学習モデルなど
  • 継続的デリバリーは Spinnaker を使っている
    • GUI で直感的に使える
  • 機械学習モデルのリリースは,最初は「意図的に手動で」運用していた
    • 多様である機会学習モデルの運用がどういうものなのかを把握するため
    • 汎用性の不足もある
  • Persistent Volumes でデータを共通化すれば,機械学習モデルの Blue/Green Deployment が実現できる

話を聞いて感じたのは「やはりメルカリ強いなぁー」ということだった.アカデミック出身の機械学習エンジニアがいたり,フルスタックなアーキテクチャ(資料参照)を1週間で作ってしまう SRE がいたり.また「意図的に手動で」運用をして,様子を見るというフローも良かった.実際に「画像認識機能」は使ったことがあるので,この機能の裏側はこんな感じだったのかーと知れて良かった.

speakerdeck.com

Yahoo! JAPAN の Kubernetes-as-a-Service で加速するアプリケーション開発

  • Yahoo! ズバトク on Kubernetes
  • 今までの課題
    • 簡単にスケールアウトできなかった
    • リリースの自動化ができていなかった
  • そこで Kubernetes を導入した
    • Concourse CI を使ってデプロイをしている
    • デプロイ時間も早くなった
    • OpenStack のノードがダウンしても,セルフヒーリングでポッドを再配置できる
  • アプリケーションも合わせて変えないと Kubernetes の恩恵を受けられないので,マイクロサービスに書き換えた
  • Z Lab では Yahoo! Japan の Kubernetes-as-a-Service を開発している
  • Kubernetes-as-a-Service on Kubernetes

Z Lab って聞いたことないなと思ったら,Yahoo! で使う基盤を作る 100% 子会社だった.Kubernetes-as-a-Service on Kubernetes というパワーワードも出ていたけど,他社と似ていて,OpenStack に Kubernetes クラスタを立てて共通基盤として提供するような感じだった.さらに Kubernetes を「分散システム基盤」という側面で考えているのは勉強になった.

www.slideshare.net

Kubernetes のセキュリティベストプラクティス

  • フロントエンドのポッドから /var/run/secrets/kubernetes.io/serviceaccount/token などの秘匿情報が漏れてしまう場合
    • リクエストヘッダーに Bearer Authentication を指定して接続されてしまう可能性がある
  • RBAC (Role-Based Access Control) を使う
  • API Server Firewall
    • gcloud container cluster--master-authorized-networks オプションを使う
  • Kubernetes Network Policies
    • もしパスワードが取れたとしても,Web ポッドから,Redis ポッドに直接繋がらないようにできる
    • 必要なポッド間だけを通す
  • securityContext に設定する項目
    • runAsUser
      • root ユーザー以外でプロセスを実行する
    • readOnlyRootFilesystem
      • ルートファイルシステムを読み取り専用にする
    • allowPrivilegeEscalation
      • 特権を取らせないようにする
  • Seccomp で不要な syscall を呼べないようにする
  • Istio など,サービスメッシュを使って,ポッド間のアクセスを制御することもできる

Kubernetes を運用するときに必要になるセキュリティ関連のパラメータを聞くことができた.まだ Kubernetes クラスタは運用していないけど,Network Policies など,注意するべきパラメータを知ることができたので,いざ運用するときに活かせそう.最後にサービスメッシュの話も少し出ていた.

speakerdeck.com

Horizontal Pod Autoscalers

  • 規模感
    • マイクロサービス 124+
    • kubernetes ノード 80+
    • コンテナ 3000+
  • Horizontal Pod Autoscaler (HPA)
  • 要件
    • 突然のスパイクに勝てる
    • 秒単位でスケールできること
    • 新規サービスも反映できる共通化された設定
      • Distributed Monolith にならないように
  • モニタリング
    • k8s-prometheus-adapter
    • Prometheus でメトリクスを取得する
    • nginx_exporter をサイドカーパターンで稼働させれば,メトリクスは簡単に取れる

Kubernetes でポッドをオートスケールしながら,メトリクスを取得する話だった.Wantedly のマイクロサービスはどんどん増えている気がする.既に120個超え!実際に負荷をかけたときのメトリクスを紹介するスライドに hey というコマンドが使われていた.Go で書かれた負荷ツールだと Vegeta を普段使っていて,hey は知らなかった.

github.com

speakerdeck.com

Container Networking Deep Dive

発表の最後に「Kubernetes を運用するなら,ネットワークも理解しましょう!」と言われていて「うっ確かに」という感じだった.ネットワークレイヤーの話で難しかったけど,ポッド同士がどのように疎通しているのか,図解がわかりやすくて良かった.

www.slideshare.net

Spinnaker を利用した Kubernetes への継続的デリバリ

  • Kubernetes は CI / CD の実現が課題になる
  • Spinnaker
    • Spinnaker
    • Netflix 社が開発している OSS
    • マルチクラウドに対応している
    • Kubernetes にデプロイができる
    • GUI で簡単にパイプランを作ることができる
  • デプロイ方法
    • Red/Black Deploy ( = Blue/Green )
      • Netflix では Red/Black と呼んでいて,意味は一緒
    • Rolling Red/Black Deploy
    • Canary Deploy
  • CI は Jenkins or Travis CI と連携できる
    • 逆にそれ以外は連携できない
  • Chaos Monkey Integration

メルカリの事例などで,最近よく聞くようになった Spinnaker の話だった.初心者セッションだったので,基礎的なところから聞くことができて,良かった.GUI 中心で Kubernetes の継続的デリバリーができるのは非常に便利だけど,それだと「Spinnaker おじさん」が出そうだから,どこまで Infrastructure as Code ができるのか,気になるところ.Netflix のデプロイ事例は以下の記事に載っている.

medium.com

speakerdeck.com

Kubernetes のない世界 すべてがサーバーレスになる

今日1番面白かったセッションだった.雰囲気としては「@yoshidashingo と @toricls のトークショー✨」という感じだったけど,コンテナ,Kubernetes,サーバレス,オンプレなど,注目のキーワードを軸に様々な視点から議論を繰り広げていた.まさに「ご意見番」って感じ.特に「Less Ops, More Code」というスローガンは良かった.Fargate など,コンテナを用意すればあとは良しなにやってくれる系のサービスが普及するのは素晴らしいと思っているし,もし EKS Fargate が出れば,Kubernetes をほとんど意識せずに使えるような未来が来そう.

www.slideshare.net

まとめ

  • Japan Container Days v18.04 に参加してきた
  • 各社 Kubernetes 最高!という感じだけど,セキュリティ,モニタリング,ログ,デプロイなど,運用面で工夫されていた
  • 「Less Ops, More Code」を目指して Kubernetes を意識しないような未来の話を聞けたのも良かった
  • 最後少し CNCF の話を聞けたのも良かった
  • あまりにも Kubernetes に偏ってたので,ECS や Fargate の話があればさらに良かったかなとは思う

関連記事

これから Kubernetes を学ぶなら,ワークショップ資料「aws-workshop-for-kubernetes」がオススメ!

kakakakakku.hatenablog.com

ElastiCache for Redis でシングルコアに対応したメトリクス EngineCPUUtilization が追加された

今月発表された ElastiCache for Redis のリリースで,新 CloudWatch メトリクス EngineCPUUtilization が追加された.

今まで

もともと Redis はシングルコアで稼働するため,例えば vCPU 4 を搭載する cache.r4.xlarge を使う場合,CPUUtilization の 25% で「実質 100%」を意味する.この仕様を理解できていないと,Redis の CPU 負荷を見逃してしまう可能性もあり,よく知られていると思う.Black Belt 資料にも記載がある.

www.slideshare.net

これから

今後はシングルコアに対応したメトリクス EngineCPUUtilization を使えば,vCPU を気にせずにモニタリングすることができる.監視設定で計算をする必要もなくなり,とにかく便利!

新しいメトリックスは以前存在した CPUUtilization メトリックスに加えられ、その他のオペレーティングシステムや管理プロセスを含むサーバーインスタンスの CPU の使用状況の全体をまとめて示します。新しい EngineCPUUtilization と以前の CPUUtilization メトリックスの両方をまとめて使用して、お使いの Redis 環境の CPU 使用状況の詳細を理解されることをお勧めいたします。

実際に CloudWatch で確認をしてみた.

f:id:kakku22:20180417193941p:plain

注意点は ElastiCache for Redis クラスタを構築した時期によって EngineCPUUtilization を取得できないことで,日本語のドキュメントには「2017/11/01 以降」と書かれていた.ただし,英語のドキュメントには「February 14, 2017 19:58 (UTC)」と書かれていて,そこそこズレているので,実際に確認してみるのが良さそう.

docs.aws.amazon.com

docs.aws.amazon.com

Mackerel AWS Integration

昨日のリリースで,Mackerel AWS Integration でも EngineCPUUtilization を取得できるようになった.ElastiCache は Mackerel でモニタリングをしているので,すぐにリリースしてもらえて助かった.

mackerel.io

実際に Mackerel で確認をしてみた.

f:id:kakku22:20180417194157p:plain

まとめ

  • ElastiCache for Redis のメトリクスに EngineCPUUtilization が追加された
  • 今後は vCPU を気にせずにモニタリングすることができる
  • Mackerel AWS Integration でも,既にメトリクスが取得できるようになっている

Amazon Elasticsearch Service で「アクセスポリシー」を即時反映できるようになっていた

Amazon ES (Amazon Elasticsearch Service) で,例えば「アクセス許可 IP」を追加するなど「アクセスポリシー」を変更する場合,クラスタも再構築されてしまうため,待ち時間が長時間化したり,場合によっては再構築がエラーになって,クラスタが死んでしまう場合もあった.Amazon ES を運用している人たちと話すと必ず話題に出るツライ仕様だったし,これまで何度も AWS サポートに改善要望を出していた 😰

最近どうしても「アクセスポリシー」を変更する必要があり,試したところ,数分以内で完了してしまった.今までは Amazon ES の CloudWatch メトリクス Nodes を見ていると,一時的にノード数が2倍にスケールアウトして,徐々にスケールインするという挙動だったのに,その挙動も確認できなかったため,もしかして改善された?と思ったら,本当に改善されていた!

僕はリリースノートを見逃していて,Twitter で教えて頂いた @shinodogg さんに感謝 🎉

インスタントアクセスポリシーアップデート : 2018/03/07 リリース

「インスタントアクセスポリシーアップデート」って,カタカナで書くと名前が長いけど,ようするに Amazon ES の「アクセスポリシー」を変更すると,クラスタを再構築せずに,即時反映できる機能と言える.リリースノートにも書いてある通り,全ての Elasticsearch バージョンで使えるのも良かった.個人的には Amazon ES 関連で,過去最大の神アップデートだと思う❗️

詳細な構成はわからないけど,Amazon ES は Elasticsearch クラスタの前にロードバランサがあるので,ロードバランサのレイヤーで「アクセスポリシー」を反映できるようになった感じ?

www.slideshare.net

まとめ

「インスタントアクセスポリシーアップデート」は Amazon ES 運用者にとって神アップデートなのに,あまり知られていないような気がするので,普及のために記事を書いた.最近は Elasticsearch 6.2 までサポートされていたり,待望だった VPC 対応もリリースされたり,Amazon ES も日々良くなっているので,今後も積極的に使っていく❗️

関連記事

去年に比較的大きめの Elasticsearch クラスタを Amazon ES に移行した事例をまとめた記事もある.

kakakakakku.hatenablog.com

Amazon ES を運用するコツをまとめた記事もある.

kakakakakku.hatenablog.com

AWS で Kubernetes クラスタを構築して学ぶワークショップ「aws-workshop-for-kubernetes」

Kubernetes を学ぶため,AWS から公式に公開されているワークショップ資料「aws-workshop-for-kubernetes」を試した.Kubernetes を学ぶためのコンテンツが網羅的にあるため,今回はワークショップの紹介と,実際に試した一部のコンテンツをまとめたいと思う.既に Kubernetes を詳しく知っている人であれば早く進められるかもしれないけど,Kubernetes 初心者だと,理解しながら進めることになるので,全コンテンツを終えるのはかなりの時間が必要になる気がする.ワークショップ資料は全て GitHub に公開されていて,誤植などがあれば,プルリクエストを送ることもできる.

github.com

なお,ワークショップ資料は AWS Technical Evangelists の「グプタ先生」がメインで作成されていて,それだけでもうモチベーションが上がる!

aws.amazon.com

aws-workshop-for-kubernetes 紹介

「aws-workshop-for-kubernetes」には,大きく3種類の「コース」がある.まずは「Standard」を試して,次に「Developer」か「Operations」に進むようになっている.

ワークショップ資料には計27個の「コンテンツ」があり,「コース」ごとに「コンテンツ」が割り当てられている.一部の「コンテンツ」はどの「コース」にも割り当てられていなかったりもするので,以下に割り当て表を作ってみた.気になる「コンテンツ」だけを試すこともできる.かなり,幅広く Kubernetes を学べるようになっている.

コンテンツ Standard コース Developer コース Operations コース
101: Start Here
102: Create a Kubernetes cluster using kops
103: Introduction to the Kubernetes CLI
201: Monitoring a Kubernetes Cluster
202: Leveraging a Service Mesh
203: Upgrading a Kubernetes Cluster
204: Logging with an EFK Stack
205: Autoscaling a Kubernetes Cluster
206: Deploy Kubernetes with Terraform and CloudFormation
301: Setting up a Local Development Environment
302: Service Discovery for Microservices
303: Updating Applications on Kubernetes
304: Scaling Applications on Kubernetes
305: Tracing Applications with Jaeger and X-Ray
306: Manage Applications with Helm
307: Store Persistent Data with StatefulSets and PVs
308: Cicd Workflows
309: Deploying a Chart Repository
310: Applying Chaos Engineering
401: ConfigMaps and Secrets
402: Authentication, Authorization, and Access
403: Admission Control for Kubernetes on AWS
404: Network Policies
405: Ingress Controllers
406: CoreDNS
501: Best Practices
502: For Further Reading

所要時間と料金

README を読むと,以下のように書いてあったけど,個人的にはもっと時間が掛かると思う(Kubernetes の理解度による).

  • Standard
    • 少なくとも2時間
  • Developer
    • 少なくとも4時間
  • Operations
    • 少なくとも4時間

We recommend at least 2 hours to complete the workshop. We recommend at least 4 hours for each of the extended paths.

さらに Kubernetes クラスタを Multi-Master で構築すると,インスタンス数も増えるため,料金もそこそこになる.README には「1日 $20 以下」と書いてあった.

You will incur charges as you go through these workshop guides as it will exceed the limits of AWS free tier. An estimate of charges (<$20/day) can be seen at this simple monthly calculator

101: Start Here

まず,開発環境として Cloud9 を使うため,CloudFormation で構築をする.東京リージョンでは Cloud9 が使えないため,今回はバージニアリージョンにした.また「新規 VPC」と「既存 VPC」から選べるため,今回は「既存 VPC」を選んだ.スタックを書く必要はなく「Deploy to AWS」を押すだけで,テンプレートが指定された状態で起動する.「サブネット」を指定したら,あとは特に何も指定せず,ポチポチと「次へ」を押せば,Cloud9 にアクセスできるようになる.

f:id:kakku22:20180402205107p:plain

次に,Cloud9 のターミナルで以下のスクリプトを実行する.

$ aws s3 cp s3://aws-kubernetes-artifacts/lab-ide-build.sh . && \
chmod +x lab-ide-build.sh && \
. ./lab-ide-build.sh

実行すると kubectl / kops をインストールすることができる.例えば kubectl だと以下のように確認できる.まだ Kubernetes クラスタを構築していないので kubectl get nodes がエラーになるのは問題なし.

$ which kubectl
/usr/local/bin/kubectl
$ kubectl get nodes
The connection to the server localhost:8080 was refused - did you specify the right host or port?

102: Create a Kubernetes cluster using kops

次に Kubernetes クラスタを管理するためのツール kops を使って,Kubernetes クラスタを構築する.なお,今回はクラスタ名の接尾辞を example.cluster.k8s.local にする.

github.com

Kubernetes クラスタの構成には,以下の2種類がある.例えば「ローリングアップデート」など,一部の機能に制約があるため,ワークショップでは「Multi-Master Cluster」で構築することが推奨になっていた.

  • Single-Master Cluster
  • Multi-Master Cluster

kops でクラスタを構築するときの $AWS_AVAILABILITY_ZONES には,リージョンごとの AZ を設定している.

$ echo $AWS_AVAILABILITY_ZONES
us-east-1a,us-east-1b,us-east-1c,us-east-1d,us-east-1e,us-east-1f

次に kops で「Multi-Master Cluster」を構築する.今回は3台のマスターノードと5台のワーカーノードにした.

$ kops create cluster \
  --name example.cluster.k8s.local \
  --master-count 3 \
  --node-count 5 \
  --zones $AWS_AVAILABILITY_ZONES \
  --yes

すると,構築が開始されて kops validate cluster で,状況を確認することができる.全ノード Ready になると,以下のような結果になる.AZ もキレイに分散されている.

$ kops validate cluster
Using cluster from kubectl context: example.cluster.k8s.local

Validating cluster example.cluster.k8s.local

INSTANCE GROUPS
NAME                    ROLE    MACHINETYPE     MIN     MAX     SUBNETS
master-us-east-1a       Master  m3.medium       1       1       us-east-1a
master-us-east-1b       Master  m3.medium       1       1       us-east-1b
master-us-east-1c       Master  c4.large        1       1       us-east-1c
nodes                   Node    t2.medium       5       5       us-east-1a,us-east-1b,us-east-1c,us-east-1d,us-east-1e,us-east-1f

NODE STATUS
NAME                            ROLE    READY
ip-172-20-126-120.ec2.internal  node    True
ip-172-20-127-95.ec2.internal   master  True
ip-172-20-154-201.ec2.internal  node    True
ip-172-20-187-147.ec2.internal  node    True
ip-172-20-206-67.ec2.internal   node    True
ip-172-20-48-37.ec2.internal    node    True
ip-172-20-52-159.ec2.internal   master  True
ip-172-20-76-97.ec2.internal    master  True

Pod Failures in kube-system
NAME
kube-dns-7f56f9f8c7-qxxbd

Validation Failed
Ready Master(s) 3 out of 3.
Ready Node(s) 5 out of 5.

your kube-system pods are NOT healthy example.cluster.k8s.local

構築後にコンテキストを確認した.

$ kubectl config get-contexts
CURRENT   NAME                        CLUSTER                     AUTHINFO                    NAMESPACE
*         example.cluster.k8s.local   example.cluster.k8s.local   example.cluster.k8s.local 

$ kubectl config current-context
example.cluster.k8s.local

103: Introduction to the Kubernetes CLI

103 では,kubectl を使って,Kubernetes の基本的なコンセプトを学んだ.

kubectl get nodes

まずは kubectl get nodes で,今回は Multi-Master でクラスタを構築したため,3台のマスターノードと5台のワーカーノードを確認することができた.

$ kubectl get nodes
NAME                             STATUS    ROLES     AGE       VERSION
ip-172-20-126-120.ec2.internal   Ready     node      7m        v1.8.7
ip-172-20-127-95.ec2.internal    Ready     master    8m        v1.8.7
ip-172-20-154-201.ec2.internal   Ready     node      7m        v1.8.7
ip-172-20-187-147.ec2.internal   Ready     node      7m        v1.8.7
ip-172-20-206-67.ec2.internal    Ready     node      7m        v1.8.7
ip-172-20-48-37.ec2.internal     Ready     node      7m        v1.8.7
ip-172-20-52-159.ec2.internal    Ready     master    8m        v1.8.7
ip-172-20-76-97.ec2.internal     Ready     master    6m        v1.8.7

次に Kubernetes クラスタの中に nginx のポッドを起動する.ポッドだけではなく,デプロイメントも確認することができた.

$ kubectl run nginx --image=nginx
deployment.apps "nginx" created

$ kubectl get deployments
NAME      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx     1         1         1            1           10s

$ kubectl get pods
NAME                    READY     STATUS    RESTARTS   AGE
nginx-7c87f569d-vwxjw   1/1       Running   0          30s

さらに docker exec のように kubectl exec でポッドの中に入ることもできた.最後は kubectl delete でデプロイメントごと削除をした.

$ kubectl exec -it nginx-7c87f569d-vwxjw /bin/bash
root@nginx-7c87f569d-vwxjw:/# ls -al /etc/nginx/conf.d/default.conf 
-rw-r--r-- 2 root root 1093 Mar 20 10:03 /etc/nginx/conf.d/default.conf
root@nginx-7c87f569d-vwxjw:/# exit

$ kubectl delete deployment/nginx
deployment.extensions "nginx" deleted

他にも

  • ポッド作成
  • デプロイメント作成
  • サービス作成

なども試した.デーモンセット,ジョブあたりは,今回は割愛した.

201: Monitoring a Kubernetes Cluster

次は Kubernetes のモニタリングを3種類学んだ.

  • Kubernetes Dashboard
  • Heapster, InfluxDB and Grafana
  • Prometheus, Node exporter and Grafana

まずは Kubernetes Dashboard をインストールした.

$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml
secret "kubernetes-dashboard-certs" created
serviceaccount "kubernetes-dashboard" created
role.rbac.authorization.k8s.io "kubernetes-dashboard-minimal" created
rolebinding.rbac.authorization.k8s.io "kubernetes-dashboard-minimal" created

deployment.apps "kubernetes-dashboard" created
service "kubernetes-dashboard" created

次に Cloud9 で Kubernetes Dashboard を起動すると,ターミナルが待機状態になるので,プロキシの URL にアクセスする.認証ではトークンが必要になるため kubectlsecret を取得する.

$ kubectl proxy --address 0.0.0.0 --accept-hosts '.*' --port 8080

# https://ENVIRONMENT_ID.vfs.cloud9.REGION_ID.amazonaws.com/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/ にアクセスする

$ kubectl -n kube-system get secret
$ kubectl -n kube-system describe secret default-token-9znml  

すると,Kubernetes Dashboard にアクセスすることができて,ノード一覧などを確認することができた.

f:id:kakku22:20180402205259p:plain

f:id:kakku22:20180402205311p:plain

Heapster は今回は試さず,Kubernetes のモニタリングで導入事例もよく聞く Prometheus + Grafana を試した.ここはコンテンツの通りに進めることができた.

202: Leveraging a Service Mesh

次は Kubernetes で,サービスメッシュを実現するために,2種類のサービスを試した.

  • Linkerd
  • Istio

Linkerd

まず,Linkerd をインストールした.

$ kubectl apply -f https://raw.githubusercontent.com/linkerd/linkerd-examples/master/k8s-daemonset/k8s/linkerd.yml
configmap "l5d-config" created
daemonset.extensions "l5d" created
service "l5d" created

$ kubectl get pods
NAME        READY     STATUS    RESTARTS   AGE
l5d-bd6w4   2/2       Running   0          28s
l5d-l47gd   2/2       Running   0          28s
l5d-ldhxd   2/2       Running   0          28s
l5d-t6c2k   2/2       Running   0          28s
l5d-vrhm7   2/2       Running   0          28s

$ kubectl get svc
NAME         TYPE           CLUSTER-IP      EXTERNAL-IP        PORT(S)                                        AGE
kubernetes   ClusterIP      100.64.0.1      <none>             443/TCP                                        32m
l5d          LoadBalancer   100.65.92.151   a2a9d866b34c4...   4140:31859/TCP,4141:32072/TCP,9990:30369/TCP   48s

$ LINKERD_ELB=$(kubectl get svc l5d -o jsonpath="{.status.loadBalancer.ingress[0].*}")
$ echo http://$LINKERD_ELB:9990

# URL にアクセスをする

次に,Linkerd のデモとして,2種類のマイクロサービス helloworld を起動し,お互いにリクエストを飛ばしてみた.

$ kubectl apply -f https://raw.githubusercontent.com/linkerd/linkerd-examples/master/k8s-daemonset/k8s/hello-world.yml
replicationcontroller "hello" created
service "hello" created
replicationcontroller "world-v1" created
service "world-v1" created

$ http_proxy=$LINKERD_ELB:4140 curl -s http://hello
Hello (100.96.3.5) world (100.96.3.6)!!

すると,マイクロサービス間のリクエストを Linkerd でモニタリングすることができた.

f:id:kakku22:20180402212846p:plain

Istio

次に Istio で,同じく kubectl apply でインストールをした.

$ curl -L https://git.io/getLatestIstio | sh -
$ cd istio-0.6.0

$ istioctl version
Version: 0.6.0
GitRevision: 2cb09cdf040a8573330a127947b11e5082619895
User: root@a28f609ab931
Hub: docker.io/istio
GolangVersion: go1.9
BuildStatus: Clean

$ kubectl apply -f install/kubernetes/istio.yaml

$ kubectl get all --namespace istio-system

NAME                             READY     STATUS              RESTARTS   AGE
istio-ca-cd9dfbdbb-vc8mb         1/1       Running             0          11s
istio-ingress-84c7ddcb7f-g9kmb   0/1       ContainerCreating   0          12s
istio-mixer-67d9bd59cb-8swld     0/3       ContainerCreating   0          16s
istio-pilot-5dd75b8f7f-qfp22     0/2       ContainerCreating   0          13s

NAME            TYPE           CLUSTER-IP       EXTERNAL-IP        PORT(S)                                                            AGE
istio-ingress   LoadBalancer   100.66.156.34    a858a858a34c5...   80:32168/TCP,443:31401/TCP                                         13s
istio-mixer     ClusterIP      100.69.49.254    <none>             9091/TCP,15004/TCP,9093/TCP,9094/TCP,9102/TCP,9125/UDP,42422/TCP   16s
istio-pilot     ClusterIP      100.68.195.148   <none>             15003/TCP,8080/TCP,9093/TCP,443/TCP                                13s

NAME            DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
istio-ca        1         1         1            1           12s
istio-ingress   1         1         1            0           12s
istio-mixer     1         1         1            0           16s
istio-pilot     1         1         1            0           13s

NAME                       DESIRED   CURRENT   READY     AGE
istio-ca-cd9dfbdbb         1         1         1         12s
istio-ingress-84c7ddcb7f   1         1         0         12s
istio-mixer-67d9bd59cb     1         1         0         16s
istio-pilot-5dd75b8f7f     1         1         0         13s

NAME            DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
istio-ca        1         1         1            1           12s
istio-ingress   1         1         1            0           12s
istio-mixer     1         1         1            0           16s
istio-pilot     1         1         1            0           13s

NAME                       DESIRED   CURRENT   READY     AGE
istio-ca-cd9dfbdbb         1         1         1         12s
istio-ingress-84c7ddcb7f   1         1         0         12s
istio-mixer-67d9bd59cb     1         1         0         16s
istio-pilot-5dd75b8f7f     1         1         0         13s

次に,書籍のレビューを管理するサンプルアプリを起動し,Ingress のエンドポイントにアクセスをする.

$ kubectl apply -f <(istioctl kube-inject -f samples/bookinfo/kube/bookinfo.yaml)
service "details" created
deployment.extensions "details-v1" created
service "ratings" created
deployment.extensions "ratings-v1" created
service "reviews" created
deployment.extensions "reviews-v1" created
deployment.extensions "reviews-v2" created
deployment.extensions "reviews-v3" created
service "productpage" created
deployment.extensions "productpage-v1" created
ingress.extensions "gateway" created

$ ISTIO_INGRESS=$(kubectl get ingress gateway -o jsonpath="{.status.loadBalancer.ingress[0].*}")
echo http://$ISTIO_INGRESS/productpage

# URL にアクセスをする

マイクロサービスに,星付きのレビュー(v3)と星なしのレビュー(v1)があり,Envoy で加重ルーティングをしている.よって,リクエストを繰り返すと,星の有無が変わるというデモを試すことができた.

$ kubectl create -f samples/bookinfo/kube/route-rule-all-v1.yaml
routerule.config.istio.io "productpage-default" created
routerule.config.istio.io "reviews-default" created
routerule.config.istio.io "ratings-default" created
routerule.config.istio.io "details-default" created

$ kubectl replace -f samples/bookinfo/kube/route-rule-reviews-50-v3.yaml
routerule.config.istio.io "reviews-default" replaced

f:id:kakku22:20180402205504p:plain

試し終わったら

Kubernetes クラスターを削除しないと,特に Multi-Master の場合はインスタンスが多く起動しているため,予想以上に料金が発生してしまう.よって,試し終わったら,必ず削除する.削除も kops でできる.

$ kops get cluster
NAME                            CLOUD   ZONES
example.cluster.k8s.local       aws     us-east-1a,us-east-1b,us-east-1c,us-east-1d,us-east-1e,us-east-1f

$ kops delete cluster example.cluster.k8s.local --yes

まとめ

  • 「aws-workshop-for-kubernetes」を試した
  • 計27個の「コンテンツ」があり,充実しているので,Kubernetes 初心者じゃなくても楽しめる
  • 大きく3種類の「コース」があるのも良かった
  • 今回は「Standard コース」の途中までを試した

合わせて読む

もう少し Kubernetes の知識を増やしてからワークショップを試した方が理解が深まりそうなので,以下の2冊を購入した.さっそく読んでみて,読み終わったら,もう1度ワークショップを再開する予定.

入門 Kubernetes

入門 Kubernetes

  • 作者: Kelsey Hightower,Brendan Burns,Joe Beda,松浦隼人
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2018/03/22
  • メディア: 単行本(ソフトカバー)
  • この商品を含むブログを見る

コンテナ・ベース・オーケストレーション Docker/Kubernetesで作るクラウド時代のシステム基盤

コンテナ・ベース・オーケストレーション Docker/Kubernetesで作るクラウド時代のシステム基盤

  • 作者: 橋本直哉,須江信洋,前佛雅人,境川章一郎,佐藤聖規,山田修司,青山尚暉,市川豊,平岡大祐,福田潔,矢野哲朗
  • 出版社/メーカー: 翔泳社
  • 発売日: 2018/03/15
  • メディア: 単行本(ソフトカバー)
  • この商品を含むブログを見る

AWS re:Invent 2017 : Mastering Kubernetes on AWS (CON308)

去年の re:Invent 2017 でグプタ先生の講演動画が公開されている.Kubernetes の構築(Minikube / Kops / EKS),Kubernetes における継続的デリバリー,IAM 管理,ロギングなど,多岐にわたる話が聞けてすごく良かった.グプタ先生が熱血すぎて英語が早すぎるけど(笑)講演の最後に「aws-workshop-for-kubernetes」の紹介も入っていて,どんな目的でワークショップ資料を作ったのか?などを聞くことができる.

www.youtube.com

Lambda / Kinesis / DynamoDB / X-Ray などを組み合わせた実装を学べる「サーバーレスアプリケーション開発ガイド」を読んだ

今月発売されたばかりの「サーバーレスアプリケーション開発ガイド」を読んだので,書評をまとめたいと思う.著者の西谷さん,献本ありがとうございます!

Amazon Web Servicesを使ったサーバーレスアプリケーション開発ガイド

Amazon Web Servicesを使ったサーバーレスアプリケーション開発ガイド

  • 作者:西谷 圭介
  • 発売日: 2018/03/16
  • メディア: 単行本(ソフトカバー)

なお,サポートページからソースコードをダウンロードできる.コマンドもソースコードもそこそこ量があるため,写経せずに試したいという人はダウンロードして使うと良いかと.

book.mynavi.jp

概要

「サーバレスとは何か?」という解説からはじまり,実際に数種類の「サーバレスアプリケーション」を実装しながら理解を深めていく流れになっている.特に,多くの AWS サービスを組み合わせて学べる点が素晴らしく,例えば X-Ray などは,僕もまだ試したことがなかったので,今回学ぶことができた.実装する「サーバレスアプリケーション」ごとに,組み合わせる AWS サービスをザッと挙げる.こんなにある!

  • Amazon CloudWatch のアラームをトリガーに自動処理をする
    • Kinesis
    • CloudWatch
    • SNS
    • Lambda
  • Web サイトの状態を定期的にチェックする
    • Lambda
    • CloudWatch Events
  • Amazon Kinesis を使って Twitter のデータを受け取る
    • EC2
    • Kinesis
    • Lambda
    • DynamoDB
  • 写真投稿サイト
    • API Gateway
    • Lambda
    • DynamoDB
    • Rekognition
    • S3
    • Cognito
    • CloudFormation
    • Serverless Application Model (AWS SAM)
  • デリバリプロセスの自動化
    • CloudFormation
    • Serverless Application Model (AWS SAM)
    • CodeBuild
    • CodePipeline
  • トラブルシューティング
    • CloudWatch
    • CloudWatch Logs
    • X-Ray

本書の特徴は「ほぼ全てのオペレーションを AWS CLI で行う」という点だと思う.管理コンソールのデザインが変わっても AWS CLI のオペレーションは大幅に変わらないというメリットがあるし,オペレーションを積極的に Infrastructure as Code にするという意味でも AWS CLI をベースに学べるのはメリットだと思う.ただし,管理コンソールを意識しなくなるため,ちょっとでも気を抜くと「今,何をしてるんだっけ?」と方向性を見失ってしまう場面があった.このあたりはトレードオフだし,西谷さんのブログ記事にも意図が詳細に書かれている.

keisuke69.hatenablog.jp

Kinesis リシャーディング

まず「Amazon CloudWatch のアラームをトリガーに自動処理をする」を実際に試してみた.アーキテクチャは以下のようになっていて,Kinesis のデータストリームに閾値以上のレコードが登録された場合に,自動的にリシャーディングを行う.

f:id:kakku22:20180326204618p:plain

Kinesis にレコードを登録するために,以下の put-records.py を使った(データストリーム名は sample となる).AWS CLI は量が多くなってしまうため,本書を読んでもらえればと!

import boto3
import datetime
import time
import uuid

kinesis = boto3.client('kinesis')
stream_name = 'sample'

partition_key = str(uuid.uuid4())
data = datetime.datetime.utcnow().strftime('%s')

for i in range(15):
    kinesis.put_record(
        StreamName=stream_name,
        Data=data,
        PartitionKey=partition_key,
    )

作成した Lambda 関数の構成は,以下のようになっている.

f:id:kakku22:20180326204947p:plain

実際にリシャーディングを行った結果が以下となる.ちゃんと OpenShardCount の値が 1 → 2 に変わっている.

# Before
$ aws kinesis describe-stream-summary --stream-name sample
{
    "StreamDescriptionSummary": {
        "OpenShardCount": 1,
        "EncryptionType": "NONE",
        "StreamStatus": "ACTIVE",
        "StreamName": "sample",
        "StreamARN": "arn:aws:kinesis:ap-northeast-1:111111111111:stream/sample",
        "EnhancedMonitoring": [
            {
                "ShardLevelMetrics": []
            }
        ],
        "StreamCreationTimestamp": 1521993626.0,
        "RetentionPeriodHours": 24
    }
}

# Put
$ python put-records.py

# After
$ aws kinesis describe-stream-summary --stream-name sample
{
    "StreamDescriptionSummary": {
        "OpenShardCount": 2,
        "EncryptionType": "NONE",
        "StreamStatus": "ACTIVE",
        "StreamName": "sample",
        "StreamARN": "arn:aws:kinesis:ap-northeast-1:111111111111:stream/sample",
        "EnhancedMonitoring": [
            {
                "ShardLevelMetrics": []
            }
        ],
        "StreamCreationTimestamp": 1521993626.0,
        "RetentionPeriodHours": 24
    }
}

X-Ray

トラブルシューティングの事例として紹介されている X-Ray も実際に試してみた.設定は特に難しくなく,Lambda のトレースモードを有効にして,あとは X-Ray の結果を見るだけだった.X-Ray は今まで使ったことがなかったので,実際に処理内部のトレース結果が見れて良かった.

$ aws lambda update-function-configuration \
--function-name s3-get-object --tracing-config Mode=Active

f:id:kakku22:20180326205003p:plain

まとめ

  • 「サーバーレスアプリケーション開発ガイド」を読んだ
  • AWS サービスを組み合わせて数種類のアプリケーションを実装できた
  • Lambda だけじゃなく Kinesis / DynamoDB / AWS SAM などに興味があるなら読むべき
  • 本書のメインコンテンツとも言える「写真投稿サイト」は Vue.js で実装されていてフロントエンドの勉強にもなった
    • 途中まで写経してたけど,量が多くて,途中からソースコードをダウンロードして進めた

関連記事

去年に読んだ「サーバーレスシングルページアプリケーション」と似ている部分も多かった.ただし,フロントエンドは jQuery → Vue.js になっているし,組み合わせる AWS サービスも多いし,今から読むなら「サーバーレスアプリケーション開発ガイド」かなぁーと.

kakakakakku.hatenablog.com

同じく去年に読んだ「実践 AWS Lambda」も関連書籍と言える.もし AWS CLI メインで改版されるなら,もう1度読む!

kakakakakku.hatenablog.com