Kubernetes を学ぶため,AWS から公式に公開されているワークショップ資料「aws-workshop-for-kubernetes」を試した.Kubernetes を学ぶためのコンテンツが網羅的にあるため,今回はワークショップの紹介と,実際に試した一部のコンテンツをまとめたいと思う.既に Kubernetes を詳しく知っている人であれば早く進められるかもしれないけど,Kubernetes 初心者だと,理解しながら進めることになるので,全コンテンツを終えるのはかなりの時間が必要になる気がする.ワークショップ資料は全て GitHub に公開されていて,誤植などがあれば,プルリクエストを送ることもできる.
なお,ワークショップ資料は AWS Technical Evangelists の「グプタ先生」がメインで作成されていて,それだけでもうモチベーションが上がる!
aws-workshop-for-kubernetes 紹介
「aws-workshop-for-kubernetes」には,大きく3種類の「コース」がある.まずは「Standard」を試して,次に「Developer」か「Operations」に進むようになっている.
- 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 にアクセスできるようになる.
次に,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
にする.
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 にアクセスする.認証ではトークンが必要になるため kubectl
で secret
を取得する.
$ 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 にアクセスすることができて,ノード一覧などを確認することができた.
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種類のマイクロサービス hello
と world
を起動し,お互いにリクエストを飛ばしてみた.
$ 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 でモニタリングすることができた.
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
試し終わったら
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度ワークショップを再開する予定.

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

コンテナ・ベース・オーケストレーション 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」の紹介も入っていて,どんな目的でワークショップ資料を作ったのか?などを聞くことができる.