EKS上のCluster Autoscalerの挙動
学習のアウトプットの場としてブログに戻ってきてみました。 最近K8sに入門したので、その辺りを中心に自分まとめのようなものを挙げてみます。
今回は主にEKS上のCluster AutoscalerとEC2 AutoScaling Groupについての整理です。
(誤りや改善点があればご指摘いただけると幸いです)
そもそもCluster Autoscalerとは
- Cluster Autoscalerはノードをオートスケールするコンポーネント
- クラスタ自体のオートスケーリング。ノードを自動的に追加する機能
- スケジュール不可能な(=pending) podの検出をトリガーに、スケジュールに最適なノードグループを決定してスケールアウトする
- デフォルトでは10分以上、そのノードで動く全podの合算の要求リソース(request)が、ノードの割り当て可能なリソースの50%以下であり、かつ全podが他のノードに安全に移動可能で、スケールインを妨げる他の要因(PDBやアノテーションなど)がない場合、スケールインされる
- Cluster Autoscalerの状態は、
cluster-autscaler-statusconfigmapで確認できる
EKS上のCluster AutoscalerとEC2 AutoScaling Group
- EKSでは、ノードグループがノードの作成、管理を行う
- このノードグループはEC2 AutoScaling Groupとして実装される。ノードグループを新規で定義すると、自動的にEC2 AutoScaling Groupとして追加される
- EC2 AutoScaling Groupは、Capacityに基づきノードを増減させる
- Cluster AutoscalerをEKSにデプロイすることで、クラスタのresource使用状況を踏まえて、EC2 AutoScaling Groupの、Minimum CapacityとMaximum Capacityを尊重しながら、Desired Capacityの調整を自動化できる。(また、どのノードグループを採用するかも決定する)
- そのためノードの増減を行う実態は、EC2 AutoScaling Groupとなる
- オートスケーリングの判断や、適切なノードグループの選択は、Cluster Autoscalerが行う
参考
git rebaseのちょっとしたまとめ
rebase、分かったつもりになってまたわからないを繰り返しているので少しまとめておきます。
rebaseとは
- 現在いるブランチを、rebaseしてきたブランチの先頭にくっつけます。
- この時、現在いるブランチのコミットを一瞬退避(一時保存)し、rebaseしてきたブランチに現在いるブランチを
git reset --hardして、保存していたコミットを上にのせる仕組みです。 - リベースを行うとコミットのidが変わり、別物として扱われます。これはコミットが新しく作られるためであり、リモートリポジトリに既にpushしていた場合は、ローカルと一致しなくなってしまいpushできなくなります。
- 上記のパターンでpushがrejectされた場合、
git push -fで対応します。 - rebaseするとその際のコミットが作られません。(mergeするとマージコミットができちゃいます。)
git rebase
rebaseはこんな感じで使えます。これはgit checkout branchB+ git rebase branchAを組み合わせたものです。
# branchAをbranchBにリベース(Bが先行する) $ git rebase branchA branch B
git pullとpull --rebaseについて
git pullは以下のように、fetch + mergeです。
# リモートBからリモート追跡Bにコピー $ git fetch # リモート追跡B(=リモートBのコピー)からローカルBにマージ $ git merge origin/master # 上記二つをいっぺんに $ git pull origin master
一方git pull --rebase(←オプション)は、fetch + rebaseをします。
$ git pull --rebase origin master
git rebase -i
git rebase --interactive。過去のコミットを編集することができます。
git rebase -i <編集したいコミットID>~と使用します。
ちなみに間違えて編集した場合は、git reset --hard <編集前のコミットID>で修正できました。
間違えたパターンの再現
3つのcommitを用意しました。 (1・2はpush済みで3が未push状態でした。)
$ git log --oneline 058deaf (HEAD -> practise) commit3 b100354 (origin/practise) commit2 4ceebb5 commit1
push済みでもrebase -iで編集はできます。しかしこの時間違えてcommit2を、commit1にsquashしてしまいました。
pick 4ceebb5 commit1 s b100354 commit2 pick 058deaf commit3 # Rebase bf5a488..058deaf onto bf5a488 (3 commands) # # Commands: # p, pick <commit> = use commit # r, reword <commit> = use commit, but edit the commit message # e, edit <commit> = use commit, but stop for amending # s, squash <commit> = use commit, but meld into previous commit # f, fixup <commit> = like "squash", but discard this commit's log message # x, exec <command> = run command (the rest of the line) using shell # b, break = stop here (continue rebase later with 'git rebase --continue') # d, drop <commit> = remove commit # l, label <label> = label current HEAD with a name # t, reset <label> = reset HEAD to a label
その結果こうなります。
$ git log --oneline
75df8ce (HEAD -> practise) commit3
7d51144 commit1
$ git reflog
75df8ce (HEAD -> practise) HEAD@{0}: rebase (finish): returning to refs/heads/practise
75df8ce (HEAD -> practise) HEAD@{1}: rebase (pick): commit3
7d51144 HEAD@{2}: rebase (squash): commit1
4ceebb5 HEAD@{3}: rebase (start): checkout 4ceebb5~
058deaf HEAD@{4}: commit: commit3
b100354 (origin/practise) HEAD@{5}: commit: commit2
4ceebb5 HEAD@{6}: commit: commit1
間違えた編集をした場合、git reset --hard <編集前のコミットID>で対応できました。今回の場合は058deaf時点に戻しました。
reset --hardを使用することでコミットが抹消しないか心配だったのですが、問題なく意図通りrebase編集前状態に戻すことができました!
$ git reset --hard 058deaf
HEAD is now at 058deaf commit3
$ git reflog
058deaf (HEAD -> practise) HEAD@{0}: reset: moving to 058deaf
$ git log --oneline
058deaf (HEAD -> practise) commit3
b100354 (origin/practise) commit2
4ceebb5 commit1
そして本来やりたかった、commit3をcommit2にsquashしました。
※この場合であれば、$ git commit --amendでもOKですが今回は敢えてrebase -i使っています
$ git rebase -i 4ceebb5~ pick 4ceebb5 commit1 pick b100354 commit2 s 058deaf commit3
大丈夫そうですね。
$ git log --oneline
2a18a66 (HEAD -> practise) commit2
4ceebb5 commit1
$ git reflog
2a18a66 (HEAD -> practise) HEAD@{0}: rebase (finish): returning to refs/heads/practise
2a18a66 (HEAD -> practise) HEAD@{1}: rebase (squash): commit2
b100354 (origin/practise) HEAD@{2}: rebase (start): checkout 4ceebb5~
058deaf HEAD@{3}: reset: moving to 058deaf
75df8ce HEAD@{4}: rebase (finish): returning to refs/heads/practise
75df8ce HEAD@{5}: rebase (pick): commit3
7d51144 HEAD@{6}: rebase (squash): commit1
4ceebb5 HEAD@{7}: rebase (start): checkout 4ceebb5~
rebaseによってcommitIDが変更されてしまっているので、このままでは普通にpushできません。
なので以下のように強制pushします。--force-with-leaseを利用すれば、他の人のコミットは維持したまま上書きすることができます。
$ git push origin ブランチ --force-with-lease
Fjordのメンターodaillyさんのまとめがわかりやすかったです🙆♀️
- 参考:コミットを整理してみよう
Scrapboxに草を生やす
最近自分のメモ書き用にScrapboxを使用しており、結構使い心地が良くなってきました。ブログと違い、気軽にまとめたり小さな単位でアウトプットできることが良いなと思っています。
利用頻度がある程度増えてきたので、Scrapboxに草を生やすことにしました。
Pixela
Githubのグラフのような物を提供してくれるWebAPIです。 今回はScrapboxの投稿を可視化するのに利用しました。
手順
Pixelaにユーザー登録
$ curl -X POST https://pixe.la/v1/users -d '{"token":"XXXXX", "username":"chiroru", "agreeTermsOfService":"yes", "notMinor":"yes"}'
=>{"message":"Success. Let's visit ~~~ , it is your profile page!","isSuccess":true}
今回利用するグラフの作成
$ curl -X POST https://pixe.la/v1/users/chiroru/graphs -H 'X-USER-TOKEN:XXXXX' -d '{"id":"scrapbox-graph", "name":"my-scrapbox-graph", "unit":"updates", "type":"int", "color":"shibafu", "timezone":"Asia/Tokyo"}'
=>{"message":"Success.","isSuccess":true}
Webhook作成
Webhookとは、あるアプリケーションの更新情報を、他のアプリに提供する仕組みのことで、今回でいうとScrapboxの投稿情報を、Pixelaに提供してグラフの草を生やすのに利用します。
$ curl -X POST https://pixe.la/v1/users/chiroru/webhooks -H 'X-USER-TOKEN:XXXXX' -d '{"graphID":"scrapbox-graph", "type":"increment"}'
=>{"message":"Success.","isSuccess":true,"webhookHash":"~~~~~"}
※ 参考:Webhookとは?
ScrapboxでNotificationsに設定する
Project settings/Notificationsに、以下を追加する。
https://pixe.la/v1/users/chiroru/webhooks/webhookHash
Scrapboxで表示する
以下のようにURLを追加します。
https://pixe.la/v1/users/chiroru/graphs/scrapbox-graph.svg
するとこんな感じで表示できます↓あっという間!

参考
2020 Rails Girlsの活動を振返る
この記事はRails Girls Japan Advent Calendar 2020の15日目の記事です。
前回はcobachieさんのRails Girls Gathering Japan を開催した理由でした。
今回は、 私のRails Girlsでの1年の活動を振返りたいと思います。
Rails Girls Nagoyaでオーガナイザーをした
1月31日・2月1日にRails Girls Nagoya 5thが開催され、オーガナイザーとして参加しました。この頃は、新型コロナウイルスが流行り始めた時期で開催が懸念されましたが、どうにかギリギリ予定通り実施できました。
私がオーガナイザーになろうと思った理由は、初めて参加したコミュニティのRails Girlsでの体験が、とても楽しくて忘れられない経験となり、次は「自分がいただいたものを、また他の誰かに届けたい」と思ったためです。
運営として私が大事にしたのは「自分の目標、また参加者の方の目標(目的)はそれぞれ異なる」ということです。 だからその上で私は、「個人の目標を達成してもらいかつ楽しんでもらう」ことを目標に、それをオープニングの言葉としました。
当日はGirls10名、運営12名での比較的小規模(?)な開催でありましたが、いちオーガナイザーとしてまたRails Girlsに携わることができ、とてもとても幸せでした🌸
Nagoya More! / Nagano More!がある
Rails Girlsのイベントが終わっても、月1ペースのMore!勉強会に参加できます💪
どちらもオンラインでの勉強会で、Nagoya More!では、『現場で使える Ruby on Rails 5速習実践ガイド』輪読会・『Railsの教科書』各自勉強・もくもく会・watchパーティー(ジョブスの映画鑑賞)などに今年は取り組みました。
またNagoyaと親和性の高いNagano More!にも参加しており、Naganoでは『webを支える技術』の輪読会と、ビブリオトークを今年やってきました。(ビブリオトークは、現在自分が読んでいる本をジャンル問わず紹介する企画です。 )
今年は本を紹介されてばかりだったので、来年はもっとたくさん本を読んで紹介する側になっていきたいなぁと思います📚
Tokyo More!にもオンライン参加
コロナの影響で、今まで参加できなかったTokyo More!(※コロナ以前は、オフライン開催)にも参加させていただきました🤲
igaigaさんが座学をしてくださる会で、参加者もたくさんいてワイワイしていました!
(その時のブログ→RailsGirls Online More!に参加しました!)
Rails Girls Gathering Japanの運営スタッフに挑戦
先日12月12日に、Rails Girls Japan初のオンラインLT会を実施しました🎉
今年の締めくくりに、私は有志で募られたスタッフとして、運営に携わらせていただきました。
およそ2ヶ月くらい前から打ち合わせが始まり、イベントの名前を決めたり、募集要項の作成や告知、また当日の運営等全部が初めてでしたが、運営チームで力を合わせ、盛況のうちに終えることができました🙏
予想以上に参加申し込みをしてくださる方がおり(イベント中にも申し込みしてくださる方がたくさんおりました!)、当日は影武者ながらとても緊張していましたが、SNSで拡散していただいたコメントを読み、勇気を出して運営やって良かったなぁと嬉しい気持ちになりました。
まとめ
Rails Girlsというコミュニティを通じて、たくさんの素敵な人々と出会うことができました。 そして (私が今通っている)FjordBootCampという素晴らしいコミュニティに出会えたのも、Rails Girlsで出会った方々のお陰です🌸
これからもこの場所を、この輪を大切にし、そして今度はまた別の誰かに運ぶことができるよう、過ごしていければなぁと思います。
Prettierの導入
【目次】
インストール
// prettierをインストール
$ npm i -D prettier
ESLintと一緒に使うために
- prettier-eslint
- prettier-eslint-cli
ESLintの記述ルール(JavaScript Standard Style)を反映するために
- eslint-config-standard
をインストールします。
$ npm i -D prettier-eslint prettier-eslint-cli eslint-config-standard
package.jsonにPretterのコマンドを追加します。
--writeオプションを指定することで整形後の内容で保存できます。コードフォーマッターを適用する対象をformatに記述します。
// package.json { "scripts": { "format": "prettier --write '/**/*.js'" }, "devDependencies": { "prettier": "^2.1.1" } }
実行
$ npm run formatで実行できます。
ここではeslint自動修正と合わせて実行しています。
$ npx eslint test2.js /Users/name/xxx/Javascript/test2.js 1:4 error Multiple spaces found before 'hoge' no-multi-spaces 1:7 error 'hoge' is assigned a value but never used no-unused-vars 1:7 error 'hoge' is never reassigned. Use 'const' instead prefer-const 1:11 error Multiple spaces found before '=' no-multi-spaces 1:15 error 'func' is not defined no-undef 1:19 error Unexpected whitespace between function name and paren func-call-spacing 2:1 error Expected indentation of 2 spaces but found 4 indent 2:5 error 'parameter1' is not defined no-undef 2:16 error Multiple spaces found before 'parameter2' no-multi-spaces 2:19 error 'parameter2' is not defined no-undef 2:31 error 'parameter3' is not defined no-undef 2:42 error Multiple spaces found before 'parameter4' no-multi-spaces 2:46 error 'parameter4' is not defined no-undef 3:1 error Expected indentation of 2 spaces but found 3 indent 3:4 error 'parameter6' is not defined no-undef 3:15 error Multiple spaces found before 'parameter7' no-multi-spaces 3:17 error 'parameter7' is not defined no-undef 4:1 error Expected indentation of 2 spaces but found 9 indent 4:10 error 'parameter8' is not defined no-undef 4:20 error Unexpected trailing comma comma-dangle 5:1 error Expected indentation of 0 spaces but found 14 indent 5:16 error Extra semicolon semi ✖ 22 problems (22 errors, 0 warnings) 13 errors and 0 warnings potentially fixable with the `--fix` option. $ npx eslint test2.js --fix /Users/name/xxx/Javascript/test2.js 1:7 error 'hoge' is assigned a value but never used no-unused-vars 1:14 error 'func' is not defined no-undef 2:3 error 'parameter1' is not defined no-undef 2:15 error 'parameter2' is not defined no-undef 2:27 error 'parameter3' is not defined no-undef 2:39 error 'parameter4' is not defined no-undef 3:3 error 'parameter6' is not defined no-undef 3:15 error 'parameter7' is not defined no-undef 4:3 error 'parameter8' is not defined no-undef ✖ 9 problems (9 errors, 0 warnings) $ npm run format > javascript@1.0.0 format /Users/name/xxx/Javascript > prettier-eslint --write '/Users/name/xxx/Javascript/*.js' success formatting 1 file with prettier-eslint 1 file was unchanged
参考
ページごとにサイドバーのコンテンツを切替える
お手伝いしているRailsのサービスサイトで、サイドバーに全ページに共通の広告を表示しているのですが、掲載数の変更に伴いページごとに種類を変えて広告バナーを表示することにしました。
現状としてはapplication.html.erbで統一されたサイドバーを表示していますが、 これをページごとに分割するのに「名前付きyield」が使えそうです。
【目次】
名前付きyieldの指定
まずapplication.html.slim側では、= yield :nameの形式でyieldに名前をつけます。
現在広告バナーはページのcol-md-3の部分に表示しているため、col-md-9はそのまま現状のものを表示できるよう= yieldを、そしてxxxページ・yyyページでそれぞれバナーを変更したいcol-md-3の内部に名前付きyieldを記述します。
.row
.col-md-9
= yield
.col-md-3
.sidebar-content
= yield :xxx
= yield :yyy
viewのメイン部分は常に「名前なしyield」としてレンダリングされるため、コンテンツを名前付きのyieldとしてレンダリングするには、content_forメソッドを使用します。
content_forメソッドでレイアウトに挿入
名前付きのyieldとしてレイアウトに挿入する場合、各ページ(index.html.slim)でcontent_for :name doの形式で指定します。
xxx/index.html.slim
= h1 名前なしyieldとして挿入される
- content_for :xxx do
.sidebar-content
h2 名前付きyieldとして挿入される
.card
yyy/index.html.slim
= h1 名前なしyieldとして挿入される(yyy)
- content_for :yyy do
.sidebar-content
h2 名前付きyieldとして挿入される(yyy)
.card
これらのレンダリング結果がレイアウトに挿入されると、最終的には以下のようなHTMLとして出力されます。
xxx/index.html
<div class="row"> <div class="col-md-9"> <h1>名前なしyieldとして挿入される</h1> <div class="col-md-3"> <div class="sidebar-content"> <h2>名前付きyieldとして挿入される</h2> <div class="card">
yyy/index.html
<div class="row"> <div class="col-md-9"> <h1>名前なしyieldとして挿入される(yyy)</h1> <div class="col-md-3"> <div class="sidebar-content"> <h2>名前付きyieldとして挿入される(yyy)</h2> <div class="card">
これでxxxページ・yyyページそれぞれ異なる広告バナーを表示させることができるようになりました!
レイアウトをコントローラーごとに指定するのもいいかも
今回は各ページで広告バナーのみ切替がしたかったので使用しませんでしたが、コントローラーにレイアウトを指定することで表示を変える方法も良さそうです。
例えばxxx_controllerのshowページでは、applicationファイルのようなサイドバナー広告の表示が不要であるとします。
そんな時はviews/layouts下に、別途レイアウトファイルを作成し、コントローラーでlayoutメソッドを指定することで切り替えられます。
今回はバナーなしのno_banner.html.slimを作成したとします。
作成できたら、xxxコントローラーにて以下のように指定しましょう。
layout "no_banner", only: :show # または def show render layout: "no_banner" end
参考
Githubのデフォルトブランチがmainになった
【目次】
- mainになっていた
- そもそもgit init時にmasterブランチが作成されている
- リポジトリをcloneしてきてから作業するのも良いかも
- zshならgitの補完機能も使えるかも
- [追記] ブランチ名をあとで変更すれば良いだけかも
mainになっていた
Githubのデフォルトのブランチが「master」から「main」になったようです。
GitHub、これから作成するリポジトリのデフォルトブランチ名が「main」に。「master」から「main」へ変更
これを知らずにリポジトリを作成後、masterにプッシュしてしまいInitial commitがうまくいきませんでした。

まずこの解決方法として、以下のようにmasterブランチのコミットをmainブランチへ移しました。
$ git fetch origin * [new branch] main -> origin/main $ git checkout main Switched to a new branch 'main' $ git cherry-pick コミットID $ git push origin main
※コミットIDは、Github上でbranchのcommitsから確認できます

本来Github上でプルリクを出すことができるはずなのですが、masterブランチからmainブランチへはなぜかプルリクが出せない状態になっていた(何も表示がなかった)ので、今回はターミナル上で対応しました。
そもそもgit init時にmasterブランチが作成されている
git initで初期化する際に、masterブランチが生成されてしまっています。
デフォルトのブランチ名がmasterからmainに変わったのはGithubのみであるので、これらを一致させると良いでしょう。
このgit initで生成されるブランチ名をmainにするには、init.defaultBranchで設定できるようです。
※これはgit 2.28以上のバージョンでのみになります。
Git でデフォルトのブランチ名を master 以外に変更する方法
$ git config --global init.defaultBranch main
リポジトリをcloneしてきてから作業するのも良いかも
最初にGithubでリポジトリを作成してきて、$ git clone リポジトリのURLでクローンしてこれば、すでにあるmainブランチ上で作業を開始することもできます。
$ git clone URL
$ cd リポジトリ
$ git branch
* main
$ git add
・
・
$ git push origin main
zshならgitの補完機能も使えるかも
(私はbashなのでこちらは試せていないのですが)補完機能を利用して、持っているブランチを確認しつつ作業することもできるようです。
[追記] ブランチ名をあとで変更すれば良いだけかも
こちらを書いた時頭になかったのですが、普通にブランチ名をpush前にmainに変更するのでも良いですね。
$ git branch -m <変更するブランチ名> <変更後のブランチ名> // 現在使用しているブランチを変更する $ git branch -m <変更後のブランチ名>