post Image
[超簡単!]kubernetesでオートスケール

kubernetes1.10ではCPUベースの水平オートスケーリングが可能です。
Deployment,ReplicaSet,Podに対して設定可能。
ただBareMetalに構築したkubernetesクラスタでは、ちょこちょこ追加でインストールしたり設定する必要があったのでまとめました。

ゴール

CPUベースでNginxのPodを水平オートスケーリングする。

前提

kubernetesのクラスタを物理マシンに構築済み
構築していない方はこちらを参考に
ansibleでkubernetes環境の構築 1
ansibleでkubernetes環境の構築 2

説明しないこと

kubernetesの使い方
kubernetesの基本的なサービスの説明(Podとはなんぞや。みたいな)

環境

物理マシン
Ubuntu18.04
kubernetes 1.10

やっていく

オートスケーリングするためにはkubectl topコマンドでPodのリソースを取得できている必要があります。

$ kubectl top node
Error from server (NotFound): the server could not find the requested resource (get services http:heapster:)

なんで???
とりあえずエラー内容にheapsterがどうのこうのといっているのでheapsterをインストールしてみます。
※後述しますが、heapsterのデプロイは必要ありませんでした!

heapsterのinstall

git cloneしてきてstandaloneのheapsterをデプロイします。

$ git clone https://github.com/kubernetes/heapster.git
$ cd heapster
$ kubectl apply -f deploy/kube-config/standalone/heapster-controller.yaml

おお、動いた。

$ kubectl top pod prometheus-k8s-0
NAME               CPU(cores)   MEMORY(bytes)
prometheus-k8s-0   74m          41Mi

ダッシュボードにも取得したメトリクスが表示されていい感じに。
スクリーンショット 2018-08-01 8.09.32.png

負荷テスト

テスト用にnginxのDeploymentをデプロイします。

nginx-test-deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-test
  labels:
    name: nginx-test
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      name: nginx-test
  template:
    metadata:
      labels:
        name: nginx-test
    spec:
      containers:
      - name: nginx-test
        image: nginx:stable-alpine
        ports:
        - name: nginx-port
          containerPort: 80
        resources:
          requests:
            cpu: 100m
            memory: 30Mi
          limits:
            cpu: 100m
            memory: 30Mi
      dnsConfig:
        nameservers:
          - 8.8.8.8
---
kind: Service
apiVersion: v1
metadata:
  name: nginx-test
  labels:
    name: nginx-test
  namespace: default
spec:
  selector:
    name: nginx-test
  ports:
  - name: nginx-port
    port: 80
    targetPort: 80
    protocol: TCP
  type: "NodePort"
scale.yaml
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
  name: nginx-test-scale
  namespace: default
spec:
  scaleTargetRef: # ここでautoscale対象となる`scaled resource object`を指定
    apiVersion: extensions/v1beta1
    kind: Deployment
    name: nginx-test
  minReplicas: 1 # 最小レプリカ数
  maxReplicas: 5 # 最大レプリカ数
  metrics:
  - type: Resource
    resource:
      name: cpu
      targetAverageUtilization: 5 # CPU使用率が常に50%になるように指定`

デプロイしたnginxにオートスケーリングの設定をします。
で,それぞれ実行。

$ kubectl apply -f nginx-test-deployment.yaml
$ kubectl apply -f scale.yaml

デプロイしたNginxに負荷をかけます。
最近Golangにハマりかけているので、Golangで実行。

stress.go
package main

import (
    "net/http"
    "sync"
    "log"
    "time"
)


func main() {
    url := "http://192.168.100.100:30534/"          // アクセスするURLだよ!

    maxConnection := make(chan bool,1000)    // 同時に並列する数をしていできるよ!(第二引数)
    wg := &sync.WaitGroup{}                 // 並列処理が終わるまでSleepしてくれる便利なやつだよ!

    count := 0                              // いくつアクセスが成功したかをアカウントするよ!
    start := time.Now()                     // 処理にかかった時間を測定するよ!
    for maxRequest := 0; maxRequest < 50000; maxRequest ++{     // 10000回リクエストを送るよ!
        wg.Add(1)                       // wg.add(1)とすると並列処理が一つ動いていることを便利な奴に教えるよ!
        maxConnection <- true               // ここは並列する数を抑制する奴だよ!詳しくはググって!
        go func() {                         // go func(){/*処理*/}とやると並列処理を開始してくれるよ!
            defer wg.Done()                 // wg.Done()を呼ぶと並列処理が一つ終わったことを便利な奴に教えるよ!

            resp, err := http.Get(url)      // GETリクエストでアクセスするよ!
            if err != nil {                 // err ってのはエラーの時にエラーの内容が入ってくるよ!
                return                      // 回線が狭かったりするとここでエラーが帰ってくるよ!
            }
            defer resp.Body.Close()         // 関数が終了するとなんかクローズするよ!(おまじない的な)

            count++                         // アクセスが成功したことをカウントするよ!
            <-maxConnection                 // ここは並列する数を抑制する奴だよ!詳しくはググって!
        }()
    }
    wg.Wait()                               // ここは便利な奴が並列処理が終わるのを待つよ!
    end := time.Now()                       // 処理にかかった時間を測定するよ!
    log.Printf("%d 回のリクエストに成功しました!\n", count) // 成功したリクエストの数を表示してくれるよ!
    log.Printf("%f 秒処理に時間がかかりました!\n",(end.Sub(start)).Seconds())            //何秒かかったかを表示するよ!
}

負荷いってらっしゃい!

$ go run stress.go

…..負荷はあがってきたけど、オートスケーリングしない。
ダッシュボードに次のような出力がありました。
unable to get metrics for resource cpu
heapsterをデプロイしたのに、なぜかPodのcpuが取得できていないです。

githubのissue漁りました。
kubernetes1.8以降はheapsterの代わりに、metrics-serverを使うみたいです。もっと調べておけばよかった。。
ということでmetrics-serverのデプロイをします。

metrics-serverのインストール

$ git clone https://github.com/kubernetes-incubator/metrics-server.git
$ cd metrics-server
$ kubectl create -f deploy/1.8+/

超簡単に終わりました。

これでもう一度負荷をかけます。
スクリーンショット 2018-08-01 8.25.42.png

スクリーンショット 2018-08-01 8.25.04.png

感動。。。

まとめ

heapsterのインストールの必要はなし!
heapsterの代わりにmetrics-serverのインストールが必要
できたら感動する!
現状はCPUベースのスケーリングしかできないが、ロードマップにはtraficやmemory,discなどがあるのでそのうちもっといろいろできるようになるはず!

AWSのEKSのHPA,heapsterについて書かれている記事がありました。
なんとAWSではどちらも使えないとのこと。
もしかしてEKSではオートスケーリング使えないのかもしれないです。
AWS好きじゃないので別にいいんやけど
EKSでkubectl topやHorizontal Pod Autoscaler (HPA) が使えない理由 – Qiita

追記
EKSでもオートスケーリングできるみたいです。
当然か!
EKSでkubectl topやHorizontal Pod Autoscaler (HPA) が使えない理由 – Qiita

参考サイト

https://github.com/kubernetes/kubernetes/issues/64027
https://github.com/kubernetes/kubernetes/issues/46915
https://github.com/kubernetes-incubator/kubespray/issues/3006


『 機械学習 』Article List
Category List

Eye Catch Image
Read More

Androidに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

AWSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Bitcoinに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

CentOSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

dockerに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

GitHubに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Goに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Javaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

JavaScriptに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Laravelに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Pythonに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Rubyに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Scalaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Swiftに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Unityに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Vue.jsに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Wordpressに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

機械学習に関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。