- 投稿日:2019-05-29T23:43:40+09:00
一足遅れて Kubernetes を学び始める - 12. リソース制限 -
ストーリー
- 一足遅れて Kubernetes を学び始める - 01. 環境選択編 -
- 一足遅れて Kubernetes を学び始める - 02. Docker For Mac -
- 一足遅れて Kubernetes を学び始める - 03. Raspberry Pi -
- 一足遅れて Kubernetes を学び始める - 04. kubectl -
- 一足遅れて Kubernetes を学び始める - 05. workloads その1 -
- 一足遅れて Kubernetes を学び始める - 06. workloads その2 -
- 一足遅れて Kubernetes を学び始める - 07. workloads その3 -
- 一足遅れて Kubernetes を学び始める - 08. discovery&LB その1 -
- 一足遅れて Kubernetes を学び始める - 09. discovery&LB その2 -
- 一足遅れて Kubernetes を学び始める - 10. config&storage その1 -
- 一足遅れて Kubernetes を学び始める - 11. config&storage その2 -
- 一足遅れて Kubernetes を学び始める - 12. リソース制限 -
- 一足遅れて Kubernetes を学び始める - 13. ヘルスチェックとコンテナライフサイクル -
前回
一足遅れて Kubernetes を学び始める - 10. config&storage その2 -では、storageについて学習しました。
今回は、リソース制限について学習します。※ リソースの種類から、次は「Metadata」だったのですが、kubernetes完全ガイドによると直接説明するのではなく、内容ベースで説明されていましたので、それに準拠します。
リソース制限
kubernetesで管理するコンテナに対して、リソース制限をかけることができます。主にCPUやメモリに対して制限をかけることができますが、Device Pluginsを使うことでGPUにも制限をかけることもできます。
※ CPUの指定方法は、1vCPUを1000millicores(m)とする単位となります。
requestsとlimits
requestは、使用するリソースの下限値です。
limitsは、使用するリソースの上限値です。requestは、空きノードに指定するリソースがなければスケジューリングされませんが、limitsは、関係なくスケジューリングされます。
とにもかくにも、試してみましょう。
まず、現状確認です。
pi@raspi001:~/tmp $ k get node NAME STATUS ROLES AGE VERSION raspi001 Ready master 31d v1.14.1 raspi002 Ready worker 31d v1.14.1 raspi003 Ready worker 30d v1.14.1 pi@raspi001:~/tmp $ k get nodes -o jsonpath='{.items[?(@.metadata.name!="raspi001")].status.allocatable.memory}' 847048Ki 847048Ki pi@raspi001:~/tmp $ k get nodes -o jsonpath='{.items[?(@.metadata.name!="raspi001")].status.allocatable.cpu}' 4 4 pi@raspi001:~/tmp $ k get nodes -o jsonpath='{.items[?(@.metadata.name!="raspi001")].status.capacity.memory}' 949448Ki 949448Ki pi@raspi001:~/tmp $ k get nodes -o jsonpath='{.items[?(@.metadata.name!="raspi001")].status.capacity.cpu}' 4 4jsonpathの使い方は、こちらにあります。
allocatableがPodに配置できるリソース量で、capacityはNode全体での配置できるリソース量です。
これだけだと、現在使っているリソース量が不明なので個別に調べます。pi@raspi001:~/tmp $ k describe node raspi002 ... Allocated resources: (Total limits may be over 100 percent, i.e., overcommitted.) Resource Requests Limits -------- -------- ------ cpu 200m (5%) 200m (5%) memory 150Mi (18%) 150Mi (18%) ephemeral-storage 0 (0%) 0 (0%) ... pi@raspi001:~/tmp $ k describe node raspi003 ... Allocated resources: (Total limits may be over 100 percent, i.e., overcommitted.) Resource Requests Limits -------- -------- ------ cpu 400m (10%) 300m (7%) memory 320Mi (38%) 420Mi (50%) ephemeral-storage 0 (0%) 0 (0%) ...現状のリソース状況を表にすると下記のとおりです。
node allocatable
(memory/cpu)capacity
(memory/cpu)used
(memory/cpu)remain
(memory/cpu)raspi002 847,048Ki/4000m 949,448Ki/4000m 150,000Ki/200m 697,048Ki/3800m raspi003 847,048Ki/4000m 949,448Ki/4000m 320,000Ki/400m 527,048Ki/3600m では、リソース制限を試してみましょう。
sample-resource.yamlapiVersion: apps/v1 kind: Deployment metadata: name: sample-resource spec: replicas: 3 selector: matchLabels: app: sample-app template: metadata: labels: app: sample-app spec: containers: - name: nginx-container image: nginx:1.12 resources: requests: memory: "128Mi" cpu: "300m" limits: memory: "256Mi" cpu: "600m"applyするpodで要求するmemoryの下限合計は384Mi(128Mi×3),cpuは900m(300m×3)です。
これだと、podがrunするはずです。pi@raspi001:~/tmp $ k apply -f sample-resource.yaml pi@raspi001:~/tmp $ k get pods NAME READY STATUS RESTARTS AGE sample-resource-785cd54844-7n89t 1/1 Running 0 108s sample-resource-785cd54844-9b5f9 1/1 Running 0 108s sample-resource-785cd54844-whj7x 1/1 Running 0 108s期待通りですね。
今度はリソース制限になる状態を試してみます。全WorkerNodeのmemory下限合計は1,224Mi(697,048Ki+527,048Ki)です。
これを超えるように先程のマニフェストを更新します。
replica数を3にしましたが、10にすれば良いですね(1,280Mi)期待動作として、9個(128Mi*9=1,152Mi)はRunningで、1個(128Mi)はPendingになるはずです。
sample-resource.yamlのreplicaを10に変更したあと↓
pi@raspi001:~/tmp $ k apply -f sample-resource.yaml pi@raspi001:~/tmp $ k get pods NAME READY STATUS RESTARTS AGE sample-resource-785cd54844-7n89t 1/1 Running 0 6m19s sample-resource-785cd54844-9b5f9 1/1 Running 0 6m19s sample-resource-785cd54844-dffsd 1/1 Running 0 61s sample-resource-785cd54844-jmkv6 1/1 Running 0 61s sample-resource-785cd54844-k9vcb 1/1 Running 0 61s sample-resource-785cd54844-l4smf 0/1 Pending 0 60s sample-resource-785cd54844-n4hl7 1/1 Running 0 60s sample-resource-785cd54844-th4bp 0/1 Pending 0 60s sample-resource-785cd54844-whj7x 1/1 Running 0 6m19s sample-resource-785cd54844-xclsk 1/1 Running 0 60sあれ、2つPendingになっていますね。もしかして、Nodeの空きリソースが中途半端にないからですかね。
確認してみましょう。pi@raspi001:~/tmp $ k describe node raspi002 ... Allocated resources: (Total limits may be over 100 percent, i.e., overcommitted.) Resource Requests Limits -------- -------- ------ cpu 1700m (42%) 3200m (80%) memory 790Mi (95%) 1430Mi (172%) ephemeral-storage 0 (0%) 0 (0%) ... pi@raspi001:~/tmp $ k describe node raspi003 ... Allocated resources: (Total limits may be over 100 percent, i.e., overcommitted.) Resource Requests Limits -------- -------- ------ cpu 1300m (32%) 2100m (52%) memory 704Mi (85%) 1188Mi (143%) ephemeral-storage 0 (0%) 0 (0%) ...raspi002は、847Mi中790Mi使っています。1つのPodを追加するためのリソース(128Mi)はないですね。
raspi003は、847Mi中704Mi使っています。こちらは空いている気がするのですが、なぜでしょうか。ここで、memoryの
704Mi (85%)
というところに着目すると、100%だった場合は828Miということになります。
確かに、それだと704Mi+128Mi=832Miでオーバーしています。では、allocatableで表示されていた847Miとの違いは何でしょうか。
allocatableというのは、全てのnamespaceにあるpodも込みのリソース配置可能量だからです。
defaultだけでなく、kube-systemなど他のnamespaceにあるpodも、もちろんリソースを消費しています。
828Miというのは、defaultで使えるリソース配置可能量ではないでしょうか。(現在のnamespaceはdefault)ちなみに、Limitsは、100%を超えていますね...。ひぇ〜...。
Cluster Autoscaler
需要に応じてKubernetes Nodeを自動的に追加されていく機能です。
これが動作するタイミングは、PodがPendingになったときに動作します。
つまり、先程の例であったように、requestsの下限によってスケールします。そのため、requestsが高すぎるために、実際はロードアベレージが低くてもスケールしてしまったり、
requestsが低すぎるために、実際は高負荷でもスケールしなくなったりします。
requestsは、パフォーマンステストをしつつ最適化していきましょう。LimitRange
さっきの例でもあったように、それぞれに対してrequests,limitを設定しても良いのですが、
もっと便利なものがあります。それがLimitRangeです。
これは、Namespaceに対してCPUやメモリのリソースの最小値や最大値を設定できます。
設定可能な制限項目として、下記があります。
- default
- デフォルトのLimits
- defaultRequest
- デフォルトのRequests
- max
- 最大リソース
- min
- 最小リソース
- maxLimitRequestRatio
- Limits/Requestsの割合
また、制限する対象は、Container,Pod,PersistentVolumeClaimがあります。
実運用する際は、きちんと定義しておきましょう。(プロバイダーによってはデフォルトで設定されているものもあるそうです)ResourceQuota
ResourceQuotaを使うことで、Namespaceごとに「作成可能なリソース数の制限」と「リソース使用量の制限」ができます。
「作成可能なリソース数の制限」を試そうと思います。sample-resourcequota.yamlapiVersion: v1 kind: ResourceQuota metadata: name: sample-resourcequota namespace: default spec: hard: # 作成可能なリソースの数 count/pods: 5pi@raspi001:~/tmp $ k delete -f sample-resource.yaml pi@raspi001:~/tmp $ k apply -f sample-resourcequota.yaml pi@raspi001:~/tmp $ k apply -f sample-resource.yaml pi@raspi001:~/tmp $ k get pods NAME READY STATUS RESTARTS AGE sample-resource-785cd54844-dll8t 1/1 Running 0 38s sample-resource-785cd54844-ljr7q 1/1 Running 0 39s sample-resource-785cd54844-r6txh 1/1 Running 0 38s sample-resource-785cd54844-sb6sq 1/1 Running 0 38s sample-resource-785cd54844-3ffeg 1/1 Running 0 38sこうすると、podsが5個までしか作成できないので、sample-resource.yamlを適用しても5個までしか作成されません。
replicaのような場合は、特に警告がなく単純に作られませんでした。
configmapを5個までに制限して、1つずつconfigmapをapplyすると、警告がでるそうです。HorizontalPodAutoscaler(HPA)
HPAは、Deployment,ReplicaSetで管理するPodのCPU負荷などに応じて自動的にスケールするリソースです。
30秒に1回の頻度でスケールするかチェックしています。必要なレプリカ数は、下記の数式で表します。
- 必要なレプリカ数 = ceil(sum(Podの現在のCPU使用率)/targetAverageUtilization)
KubernetesのPodとNodeのAuto Scalingについてで、
auto scalingはtarget valueに近づくようにpod数が調整されるということ。
という文がわかりやすかったです。つまり、targetAverageUtilizationが50なら、全体のCPU使用率が50%になるよう調整されます。
今回、試そうと考えたのですが、metrics-serverをinstallしていないため、動作確認できませんでした。
また今度installして試してみようと思います。VerticalPodAutoscaler(VPA)
VPAは、コンテナに割り当てるCPUやメモリのリソース割当をスケールさせるリソースです。
これは、HPAのスケールアウトではなく、Podのスケールアップを行うものです。お片付け
pi@raspi001:~/tmp $ k delete -f sample-resource.yaml -f sample-resourcequota.yaml最後に
今回は、RequestsやLimitsを操作してリソース制限をしてみました。
どれがいくらリソースを消費しているのか確認する術を学び、
ついでにjsonpathの使い方も知りました。
次回は、こちらです。
- 投稿日:2019-05-29T22:43:21+09:00
0から始めるPHP:1日目
本日の目標
定数や変数を扱えるようになる。
定数
定数とは、定数である。つまり、ずっと同じ値を保つ。最初に定義したら、あとは中身は変わらない。
関数
define()
を用いて、定数を定義してみる。
defという定数を作り、その中にHelloを入れる。<?php define("def","Hello"); print(def); ?>define("定数の名称",”定数の中身”) といったように書く。
実際に定義ができているか確認のため、関数print()
で出力してみる。変数
変数とは、定数との逆で何かしら操作すると値が変わる。
PHPでは、変数を定義するときに型を指定する必要がなく、勝手にやってくれる(多分)
今回は例として整数の変数を定義してみる。<php $var = 0; ?>$変数名 = 代入する値 というよに書く。
変数の型は整数以外にも文字列や、論理型などがある。本日の成果
定数と変数の意味を理解して、定義できるようになった。
- 投稿日:2019-05-29T22:17:54+09:00
0から始めるPHP
目的
独学でPHP言語を勉強し、何を勉強したかを記事にしていきます。
誰の役に立つか分かりませんが...備忘録として書いていくので、雑かもしれませんが悪しからず・・・環境
MAMPサーバでPHPを実行します。
エディタはBBeditのフリー機能のみで。PHPの書き方
<?php ?>PHPは基本的に
<?php
と>
の間に、関数やらなんやら記述する。文字列の出力
とりあえず、動かしてみよう
print()
関数でHello Worldを表示させる。<?php print("Hello World"); ?>文字列の出力には、他にも
printf()
やecho()
といった関数がある。
それぞれの関数の仕様については後ほど、まとめる。(maybe...)改行の仕方
改行したい!というときには文末に
<br>\n
といれる。<?php print("Hello World<br>\n"); ?>これで改行ができた。
本日の成果
関数
print()
、printf()
、echo()
を用いて、文字列を出力できた
- 投稿日:2019-05-29T22:17:54+09:00
0から始めるPHP:0日目
目的
独学でPHP言語を勉強し、何を勉強したかを記事にしていきます。
誰の役に立つか分かりませんが...備忘録として書いていくので、雑かもしれませんが悪しからず・・・環境
MAMPサーバでPHPを実行します。
エディタはBBeditのフリー機能のみで。PHPの書き方
<?php ?>PHPは基本的に
<?php
と>
の間に、関数やらなんやら記述する。文字列の出力
とりあえず、動かしてみよう
print()
関数でHello Worldを表示させる。<?php print("Hello World"); ?>文字列の出力には、他にも
printf()
やecho()
といった関数がある。
それぞれの関数の仕様については後ほど、まとめる。(maybe...)改行の仕方
改行したい!というときには文末に
<br>\n
といれる。<?php print("Hello World<br>\n"); ?>これで改行ができた。
本日の成果
関数
print()
、printf()
、echo()
を用いて、文字列を出力できた
- 投稿日:2019-05-29T22:16:25+09:00
Prometheus + Grafana で自分のMacを監視しよう
やること
今回は、自分のMACにPrometheusとGrafanaをインストールしたいと思います。
事前準備
https://docs.docker.com/docker-for-mac/install/
以上から、自分のMacにDockerをインストールしてください。各種ファイルの準備
terminalで以下のディレクトリを任意の箇所に置いてください。
(今回は、/Users/”user名”/下にこのディレクトリを作成します。)$ cd $ mkdir prometheus $ mkdir grafanaprometheus.yml
/Users/"user名"/prometheusに以下のファイルを作成
次回
次回、
```prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
external_labels:
monitor: 'codelab-monitor'rule_files:
- "/var/app/prometheus/alert.rules"
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets:
- 'localhost:9090'
```Grafana.env
/Users/"user名"/grafanaに以下のファイルを作成
docker 経由で grafana を起動する上で必要になります。
ただし、こちらのファイルは参照されないので、コメントアウトしています。gafana.env# [server] # GF_SERVER_DOMAIN=localhost # GF_SERVER_HTTP_PORT=3000 # GF_SERVER_PROTOCOL=httpdocker-compose.yml
/Users/"user名"/prometheusに以下のファイルを作成
docker-compose.ymlversion: '3' services: prometheus: image: prom/prometheus container_name: prometheus volumes: - /Users/"user名"/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml ports: - 9090:9090 grafana: image: grafana/grafana container_name: grafana ports: - 3000:3000 env_file: - /Users/"user名"/grafana/grafana.envdockerの起動
$ docker-compose -f docker-compose.yml upprometheus
起動したら、まずprometheusを確認してみましょう。
Status > Target を確認してみましょう。
先ほど、prometheus.ymlのscrape_configsに書いた設定が反映されています。ここまでを確認できましたでしょうか。
Grafana
そうしたら、次はGrafanaを見てみましょう。
え... どうやってログインするの
ってなった方!!!朗報です。両方「admin」と入力してみてください。
すると、passwordを設定する画面になりますので、自分の好きなpasswordを打ってください。
終わると、次の画面に映ります。
configuration > Data Sources を選択して下さい。
Add data source を選択して以下の画面に来ましたら、prometheusを選択して下さい。以下の状態になったら、
URL: http://localhost:9090
Access: Browser
と記入し、下の「Save & Test」を選択以下のものが表示されたら、完了です。
再度、Configuration > Data Sourse を選択すると、先ほど登録したPrometheusが表示されます。
この後やること
この後は、NodeExportetであったり、自作Exporterをprometheusと連携させて
自分好みの監視をしてみて下さい。
- 投稿日:2019-05-29T13:51:03+09:00
GoLandのインストールと基本設定(MacOS)
概要
MacOSでGoLangの開発を快適に行う環境構築をまとめた記事です。
ツールとしては GoLand を利用します。
対象読者
- MacOSを所持している方
- Linuxコマンドの基礎を理解しMacのターミナル操作が出来る方
前提条件
Homebrew がインストールされている前提でお話させて頂きます。
筆者の実行環境
- MacOS Mojave
- CPU 2.2 GHz Intel Core i7
- メモリ 16GB
GoLangをMac上にインストールする
最初に
brew update
を実行してpackageを最新の状態にします。続いて
brew install go
を実行します。
go version
を実行し下記のように表示されれば成功です。$ go version go version go1.12.5 darwin/amd64
ちなみに複数のGoLangプロジェクトを運用していて各プロジェクト毎にバージョンが異なる場合は goenv 等を利用すると良いでしょう。
(参考)Mac に goenv を利用して Go をインストールする
MacOS上にGoをインストール一番の理由は後の説明で出てくる GoLand によるコード補完やリファクタリング機能を利用しやすくする為です。
Docker 等を利用してバージョンが異なる複数のGoLang実行環境を作る事はさほど難しくないので無理に goenv を利用しなくても良いというのが個人的な見解です。
GoLandをMac上にインストールする
JetBrains製のIDEです。
現時点ではこのGoLandを利用する方法が最も開発体験が良いという印象です。
一応 IntelliJ IDEA のGo Pluginを利用する方法でも、ほぼ同様の事が実現出来るので、そちらを使っても問題ありません。(使い方もほぼ同じです)
(参考)IntelliJ IDEAでGo言語(golang)を始める〜GOPATHの設定など
https://www.jetbrains.com/go/download/#section=mac よりダウンロードを行います。
インストール手順に関しては非常に簡単なので省略させて頂きます。(アプリケーションディレクトリにコピーするだけ)
GoLandの設定を行う
アプリケーションを起動します。
最初は設定がないと思いますので
Do not import settings
を選び次に進みます。エディタの設定
ここは好みの領域になってきますが、私がいつもやっている設定を書いておきます。
Preferences → Editor → General
- Ensure line feed at file end on Save - ON「行末の不要なスペースやタブを保存時に削除する」
Preferences Editor → General → Appearance
- Show line number - ON「行番号の表示」
- Show method separators - ON「メソッドの区切り線」
- Show whitespaces - ON「空白の表示」
GoLandにGOROOTを認識させる
この記事の通りにやっていれば
/usr/local/Cellar/go/1.12.5/libexec
になります。Go → GOROOTを選択すればサジェスト欄に出てくるので、それを選択します。
ただし goenv を利用しているとサジェストで出てこないので、その場合は明示的に絶対パスを指定する必要があります。
下記の記事等を参考にすると良いでしょう。
(参考)GoLand のGOROOTにanyenv(goenv)内のgolangを指定する.
動作確認
動作確認用のプロジェクトを下記に用意しました。
https://github.com/keitakn/go-rest-api
上記のプロジェクトを自身のPCにダウンロードします。
git clone https://github.com/keitakn/go-rest-api.gitプロジェクトのインポートを行います。
「Open Project」より先程
git clone
した動作確認用プロジェクトをインポートします。Go Modulesを有効にする
このプロジェクトはGo Modulesをpackage管理として利用しています。
Go → Go Modules(vgo)からGo Modulesを有効にします。
プロジェクトルートで
go build
を実行して下さい。IDEでのコード補完が有効になった事を確認出来るかと思います。
以上になります。最後まで読んで頂きありがとうございました。
- 投稿日:2019-05-29T13:19:32+09:00
ポート番号の確認&解除
使用中のポート番号の確認と、解除の仕方をまとめます。
環境
MacOS Mojave
使用中のポート番号の確認
例:8080ポートの使用状況を確認したい場合、下記をターミナルに入力
mbp:~ mac$ lsof -i:8080 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME stackman 1087 mac 16u IPv4 0x2fbea4e1fe9b9e7d 0t0 TCP localhost:http-alt (LISTEN)
stackman
が8080ポートを使用しているのが確認できる。ポートの解除
上記
stackman
の接続を解除したい場合、下記を入力mbp:~ mac$ kill 1087参照元
- 投稿日:2019-05-29T12:22:41+09:00
Spacemacsはいいぞ
Spacemacs is なに?
- Emacsディストリビューション。Spacemacsよりも軽量なものにDoom Emacsなんかがあったりする。
- Vimの秀逸な入力インターフェイスにEmacsの強力な拡張性を併せ持つそれぞれのいいとこ取りのエディタ。
メリット
スペースキーを起点としたコマンドが秀逸。スペースキーを押した時点で エディタの下に次のキーの候補と何のコマンドかを表示してくれて親切。
デフォルトで多くレイヤーが用意されていて、
.rb
や.py
などの拡張子を初めて開く場合、最初にawesome-emacsに乗っているようなモジュールを入れるか聞いてくれるので言われるがままに入れとけばまず困らない。補完が結構効く。仕事でRubyを書いていてRubyMineでは設定が悪いのか全然補完してくれなかったものがSpacemacsでは補完してくれるようになってRubyMineやめた。Robeすごい。
Emacsの豊富な既存のモジュールをほぼそのまま使える。
themes-megapackレイヤーを入れれば有り余るほどテーマが入るので、私みたいに定期的にテーマを変えたい人にはありがたい。テーマの変更は設定ファイルからできる他に
Space T s
で簡単に変更できる。
デメリット
- 情報が少ないのでSpacemacs固有の問題にぶち当たったら解決するのが結構大変らしい。
- 立ち上げてしまえばサクサクだが、やはり素のEmacsやVimやVSCodeと比べて起動が遅い。(それでもRubyMineやその他IDEよりはずっと速い)
導入手順
私はmacOSを使っているためmacOSでの導入手順を書いておきます。その他OSの方はGithubのREADMEを参照してください。
また、すでにemacsを使っている方は
~/.emacs.d
のバックアップを忘れずにしてください。$ brew tap d12frosted/emacs-plus $ brew install emacs-plus $ brew linkapps emacs-plus $ git clone https://github.com/syl20bnr/spacemacs ~/.emacs.dよく使うコマンド
.rb
ファイルを開いた状態でSpace m '
: Robe(コードナビゲーション、ドキュメント検索、オートコンプリート)の起動Space p f
: プロジェクト内のファイル検索Space /
: プロジェクト内のテキスト検索Space f f
: ファイル検索Space T T
: エディタの透過調整Space g b
: git blameSpace T s
: エディタのテーマ変更Space w -
: エディタの水平分割Space w v
: エディタの垂直分割Space w w
: 次のウィンドウに移動Space {0~9}
: 指定した数字のウィンドウに移動Space p t
: プロジェクトツリー(Treemacs)