この記事は:birthday:アイスタイル Advent Calendar 2020:birthday:15日目の記事になります
みなさんこんにちは
istyle入社2年目のkuriyamayです
私は普段、@cosmeのアプリやwebページのいろんなところに表示されている記事フィードを扱う配信基盤を担当しています
アドカレでは循環的複雑度(Cyclomatic complexity)について書こうかと思っていましたが、最近kubernetesを勉強しているので、復習も兼ねてkubernetesのことを書いていきます
目次
- kubernetesをテーマにした理由
- kubernetesとは
- kubernetesをさわってみる
- ローカル環境構築
- アプリケーションのデプロイ
- 動作確認
- スケールと自動復旧
- 今後の展望
- 最後に
kubernetesをテーマにした理由
私が現在担当してるプロダクトはJava11 + Spring Boot/Vue.jsの構成となっています
今まで携わってきた業務もGolangやPHPを使ったプロダクトでインフラはほぼ未経験
そんな私がどうしてkubernetesに手を出したのか・・・
理由は簡単
おもしろそうだから、ですね:smile:
一応他にも
IaCの知識を深めたいとか
業務でもっとコンテナを活用していきたいとか
いつかはインフラやりたいとか
いろいろとありますが、きっかけとしてはこの理由になります:smile:
kubernetesとは
Dockerを取り巻くオーケストレーションシステムのデファクトスタンダードとしてkubernetes(k8s)が挙げられますね
- コンテナを用いたアプリケーションのデプロイ
- Dockerホストの管理
- サーバリソースを考慮したコンテナ配置
- スケーリング
- ロードバランサー
- 死活監視
等々、いろんな仕組みを備えているコンテナオーケストレーションシステムです
kubernetesをさわってみる
まずローカル環境にkubernetesを構築していき、それをもとにいろいろとさわりながら理解を深めていこうと思います
環境情報はこちら
macOS Catalina: v10.15.7
Docker for Mac
Docker Engine: v19.03.13
Kuvernetes: v1.19.3
ローカル環境構築
Docker for Mac ~ kubernetes有効化
dockerアカウントを作成しDocker for Macをインストール
https://hub.docker.com/editions/community/docker-ce-desktop-mac/
インストールが完了し、dockerが起動したら :whale: さんマークが出てくるので、そこを押してDashboardを開きます
続いて、settings -> Kubernetesを開きKubernetesを有効にします
kubernetesが有効になるとrunning
と表示されますね
簡単!
この状態でいくつかのコマンドを叩いてみましょう
$ docker version
Client: Docker Engine - Community
Cloud integration: 1.0.2
Version: 19.03.13
...省略
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.3", GitCommit:"1e11e4a2108024935ecfcb2912226cedeafd99df", GitTreeState:"clean", BuildDate:"2020-10-14T12:50:19Z", GoVersion:"go1.15.2", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.3", GitCommit:"1e11e4a2108024935ecfcb2912226cedeafd99df", GitTreeState:"clean", BuildDate:"2020-10-14T12:41:49Z", GoVersion:"go1.15.2", Compiler:"gc", Platform:"linux/amd64"}
$ kubectl get pods --namespace=kube-system
NAME READY STATUS RESTARTS AGE
coredns-f9fd979d6-282wr 1/1 Running 6 12d
coredns-f9fd979d6-77kzs 1/1 Running 6 12d
etcd-docker-desktop 1/1 Running 6 12d
kube-apiserver-docker-desktop 1/1 Running 6 12d
kube-controller-manager-docker-desktop 1/1 Running 6 12d
kube-proxy-9hw4c 1/1 Running 6 12d
kube-scheduler-docker-desktop 1/1 Running 26 12d
kubernetes-dashboard-6ff6454fdc-xwzxx 1/1 Running 8 10d
storage-provisioner 1/1 Running 27 12d
vpnkit-controller 1/1 Running 6 12d
kubectlというコマンドが出てきました
これはkubernetesのコマンドラインツールで、リソースやクラスタの操作の他、コンテナのシェルに入ったりすることも出来ます
よく使うコマンドは覚えておきたいですね
Kubernetes Dashboard
kubernetesにはDashboardが用意されています
https://github.com/kubernetes/dashboard
READMEに書いてある通りやっていきましょう
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.5/aio/deploy/recommended.yaml
namespace/kubernetes-dashboard unchanged
serviceaccount/kubernetes-dashboard unchanged
service/kubernetes-dashboard unchanged
secret/kubernetes-dashboard-certs unchanged
secret/kubernetes-dashboard-csrf configured
secret/kubernetes-dashboard-key-holder unchanged
configmap/kubernetes-dashboard-settings unchanged
role.rbac.authorization.k8s.io/kubernetes-dashboard unchanged
clusterrole.rbac.authorization.k8s.io/kubernetes-dashboard unchanged
rolebinding.rbac.authorization.k8s.io/kubernetes-dashboard unchanged
clusterrolebinding.rbac.authorization.k8s.io/kubernetes-dashboard unchanged
deployment.apps/kubernetes-dashboard configured
service/dashboard-metrics-scraper unchanged
deployment.apps/dashboard-metrics-scraper configured
$ kubectl proxy
Starting to serve on 127.0.0.1:8001
proxyサーバを立ち上げ下記URLを開くとこのような画面になります
http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/
tokenでログインしたいので下記コマンドでtokenを探しましょう
kubectl -n kube-system get secret
default-token-*をコピったら次はこちらのコマンドを実行しtokenをコピー、Dashboardに貼り付けてSign inします
kubectl -n kube-system describe secret default-token-*
おけおけ!いい感じですね!
ここまでがローカル環境構築です
次はアプリケーションのデプロイに挑戦します
アプリケーションのデプロイ
deploymentとserviceのマニフェストファイル作成
deployment.yml
アプリケーションのデプロイをするのに必要なdeploymentのマニフェストファイルを作成します
このdeploymentとは
- ReplicaSetの世代管理をする
- ReplicaSetは同じ仕様のPodを複数生成・管理をする
- Podはコンテナ集合体の単位でコンテナを実行する方法を定義する
というものですが、、、うーんいきなり複雑になりましたね:persevere:
deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: go-app
spec:
selector:
matchLabels:
app: go-app
replicas: 1
template:
metadata:
labels:
app: go-app
spec:
containers:
- name: go-app
image: nyankuri/golang-gin
ports:
- containerPort: 8080
使用してるimageは今回のアドカレ用に作成したGo + ginのアプリケーションです
service.yml
deploymentのマニフェストファイルを作ったら次はserviceです
serviceとは
- Podの集合にアクセスするための経路を定義する
こちらは理解しやすいですね:yum:
service.yml
apiVersion: v1
kind: Service
metadata:
name: go-app-service
spec:
type: NodePort
ports:
- port: 8080
selector:
app: go-app
動作確認
deploymentとserviceのマニフェストファイルが用意できたのでkubernetesにデプロイしていきます
$ kubectl apply -f k8s/deployment.yml
deployment.apps/go-app created
$ kubectl apply -f k8s/service.yml
service/go-app-service created
この状態でDashboardを見てみます
Deployments/Pods/Replica Setsが動いてるのがわかりますね:yum:
Servicesはこのようになっています
go-app-service -> Internal Endpointsの下にあるportに接続してみましょう
deployment.ymlのimageに定義したアプリケーションに繋ぐことができました!よかった:yum:
スケール
kubernetesの動きをもうちょっと見たいのでスケールさせます
まずは今の状態
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
go-app-df6ddf76d-rtp9b 1/1 Running 0 15m
次にdeployment.ymlのreplicasを1 -> 4に変更してapplyします
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
go-app-df6ddf76d-bzz4p 1/1 Running 0 22s
go-app-df6ddf76d-dvmmb 1/1 Running 0 22s
go-app-df6ddf76d-rtp9b 1/1 Running 0 18m
go-app-df6ddf76d-tr67c 1/1 Running 0 22s
マニフェストファイルの定義を変更するだけで簡単にスケールすることが出来ました
自動復旧
続いて自動復旧をさせてみます
tr67cのpodに消えてもらいましょう:innocent:
$ kubectl delete pod go-app-df6ddf76d-tr67c
pod "go-app-df6ddf76d-tr67c" deleted
そしてまたpodの状態を見ると、、、
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
go-app-df6ddf76d-bzz4p 1/1 Running 0 2m20s
go-app-df6ddf76d-dvmmb 1/1 Running 0 2m20s
go-app-df6ddf76d-dxrvf 1/1 Running 0 10s
go-app-df6ddf76d-rtp9b 1/1 Running 0 20m
tr67cが消えて新たにdxrvfが出来てます
podが消えても自動で復旧してくれましたね
今後の展望
ゆくゆくは本番環境でkubernetesを使ってみたいなと思っていますが、それまでには覚えること、やるべきことがいっぱいあります
Dockerフレンドリなアプリケーションを作ったり、運用方法をしっかり考えたり、Linuxの知識をもっと身につけたりと、自分にできることを少しずつやってゴールに向かっていきたいと思います
最後に
kubernetesの構築とアプリケーションのデプロイ等を確認しましたがけっこう長くなってしまいました
ここまで読んで頂きありがとうございます:whale:
明日のアドベントカレンダーはsakohさんのCompletableFutureをJSのPromise.allっぽく扱う(Java)
ですね
どんな内容なのかとても楽しみです:yum: