就活の軸について考える

はじめに

この記事はあくあたん工房GWアドベントカレンダー最終日の記事です.
他の記事を読んでない方も,これをきっかけにのぞいていただければと思います.

さてGWが終わると,早い人は就職活動が徐々に始まりますね.
その一方で多くの人が,初めての就活に何をすればよくわからず,ネットでググったり先輩や友達に相談したりするのではないのでしょうか. そうしているとおそらくどこかで「就活の軸」というワードが出てきたり,あるいは企業との面談や面接で「あなたの就活の軸は何ですか?」と聞かれたりするかと思います.

ここでは就活の軸について,そもそもこの軸は必要なのか,そしてどのようにしてこの軸を作っていくのか自身の考えをまとめました.
なおこの記事ではプログラマ・ITエンジニア職を主な対象にしており,内容の多くが筆者の私見である点に留意していただければと思います.

就活の軸の必要性

さてまず初めに就活の軸を作る必要があるのかについて考えてみましょう. といっても僕を含め,多くの人が多少なりとも必要だと感じているのではないかと思うので,この軸の必要性についてもう少し深掘りします.

日本には数百万社の企業が存在している一方,内定を承諾できる企業は一つだけです. 自分の志望分野やそもそも採用活動をしているかで絞られるにせよ,やはりそれだけで一社に絞り切ることは難しいかと思います.
そのため,多くの就活生が消極的な理由であれ,積極的な理由であれ,何かしらの基準を以って企業を選択する場面が出てきます. ただ選ぶだけなら神頼みでもよいかもしれません. しかし,どこに就職するかは今後の人生に影響するため,多くの人が納得のいく選択をしたいと思っていることでしょう. そんなときに就活の軸が確立していれば,その軸に基づいて選択をすることで,なぜその企業を選んだのか明確な理由づけをすることができます. 加えて,そういった選択は,後々振り返ったときにも納得のいく選択になると考えています. すなわち就活の軸をもつことは,今だけでなく今後の自分にとっても納得のできる選択につながるため,必要なのではないかと僕は考えています.

就活の軸とは

では改めて,そもそも就活の軸とは何でしょう?
自分は就活の軸とは,就職する企業に対して自身が期待することだと捉えています. おそらく万人にとって良いという企業は世の中にはほぼ無く,何かしらの強み弱みをもっているかと思います. これらの各企業の強み弱みに対して,自分の価値観に基づいた重みをつけてくれるものが就活の軸なのではないかと自分は考えています.
一方で,これは企業を選ぶ基準そのものとは異なると思っています. 企業を選ぶ基準は軸に対して,企業のどの側面を評価するか観点を与えたときに現れるものだと考えています.

就活の軸の作り方

さてそれでは就活の軸はどのようにして作ればいいのでしょう?
これについては,人それぞれ様々な方法があるかと思いますが,ここでは選択基準から作る方法と自身の経験から作る方法の二つについて書きます.

選択基準から作る方法では,まずパッと思いつく,こういう企業で働きたいなという項目をいくつか書き出します. 例えば「〇〇という言語を使って開発している」や「チーム間の異動がしやすい」などです. これらの項目はより具体的であるとよいかと思います. 次はそれらの項目の共通項を探します. 例えば「挑戦がしやすい」や「働くことを楽しめる」といったことが挙げられるかと思います. この共通項,または複数あればそれらをまとめたものが就活の軸となります.

自身の経験から作る方法では,自分の開発経験や,インターンの経験で感じたことをもとに軸を考えます. おそらくそういった経験の中には,自分が良かったと感じたこと,悪かったと感じたことがあるかと思います. それらの今まで感じたことを書き出し,それらの共通項を見つけることで,自分が何を大切にしているかを明確にし,就活の軸を作ります.

大抵,就活の軸は一文で簡潔に表されるものになるのではないかと思います. もし,複数であったり長文になっているようであれば,軸ではなく選択基準そのものになっているかもしれません. そうなったときは一度見直してみることをおすすめします.

おわりに

今回は就活の軸について自分の考えをまとめました.
自分は就活中に色々と悩む場面が多く,どれを選択するかということに加えて,どうやって選択すれば後悔しないかをよく考えていました. この記事はそのとき考えていたことを,改めて自分なりにまとめてみたものでした.

拙い文章でしたが最後まで読んでいただきありがとうございます.この記事がこれから就活に挑む誰かの役に立てれば幸いです.

Kubernetesで同名の異なる内容のリソースを同時にapplyしたときの挙動について調べてみた

はじめに

 Kubernetesではアプリケーションの実行や,そのアプリケーションを外部に公開するための設定の適用,Kubernetesクラスタ(以下クラスタと表記)内の権限管理など多くの操作を"リソース"と呼ばれるものを用いて行います.
例えば下のyaml形式のテキストはKubernetesにおけるアプリケーションの最小実行単位であるPodを定義したマニフェストです.

apiVersion: v1
kind: Pod
metadata:
  labels:
    run: demo
  name: demo
spec:
  containers:
  - image: nginx:latest
    name: nginx
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Never

Kubernetesの使用者はこのようなマニフェストAPIサーバに渡してあげることで様々な操作を行います.

 さてこのマニフェストAPIサーバに渡してあげる方法ですが,これにはいくつかの方法が用意されています. そのうちおそらく誰もが使ったことがあるであろう方法がkubectlと呼ばれるCLIツールを用いる方法です.
 このkubectlにはクラスタを操作するためのサブコマンドがいくつか用意されていますが,リソースの作成に関するコマンドの一つがkubectl applyです. このapplyコマンドでは作成対象のリソースがクラスタになければ新しく作成し,もしあった場合は変更部分を更新します.
実行すると以下のような結果が出力されます.

$ kubectl apply -f demo-pod.yaml
pod/demo created
# 使用イメージのタグを変更したものをapplyする
$ kubectl apply -f demo-pod-changed.yaml
pod/demo configured

ところでこのapplyコマンドを下のように同時に実行したらどうなるのでしょう?

# pod-changed.yamlはpod.yaml内の使用イメージタグのみを変更したもの
$ kubectl apply -f pod.yaml & kubectl apply -f pod-changed.yaml

おそらく結果として考えられるの以下の3つです.

  1. どっちかがcreateされて,どっちかがconfiguredされる
  2. 同じ名前の違う内容のリソース(ここではPod)が複数作成される
  3. エラーで失敗する

さて結果はどうなるのでしょうか?
確認してみましょう!

kubectl applyを同時に2個実行してみた

 実行結果を貼り付けます.

$ kubectl apply -f pod.yaml  & ./kubectl apply -f pod-changed.yaml
pod/demo created
Error from server (AlreadyExists): error when creating "pod.yaml": pods "demo" already exists

どうやらpod.yamlに記載されているPodリソースを作成時にAPIサーバ内でエラーが発生したようです.1
というわけで正解は3. エラーで失敗するでした.

ところで先ほどapplyコマンドについて以下のような説明をしました.

このapplyコマンドでは作成対象のリソースがクラスタになければ新しく作成し,もしあった場合は変更部分を更新します.

にも関わらずAlready Existsで失敗するのは何故でしょう?
すでに存在しているのがわかったなら更新してくれよという気持ちになる人も多いと思います. 少なくとも僕はそんな気持ちです.

どうしてこんなことになるのか,次は実際にコードを見てみることにしましょう.

kubectl apply のコードを見てみる

 幸いKubernetesのコードはGitHubで誰でも見れるようになっているのでこれを見ていきます.

github.com

まずはkubectlコマンドのコードリーディングの入口を確認します.

kubernetes/cmd/kubectl/kubectl.go L35-L52

func main() {
    rand.Seed(time.Now().UnixNano())

    command := cmd.NewDefaultKubectlCommand()

NewDefaultKubectlCommand()を読み進めていくとapplyコマンドの本体が見えてきます.
この中にo.RUN()というapply処理の本体ぽいものが見られます.
kubernetes/staging/src/k8s.io/kubectl/pkg/cmd/apply/apply.go L162-L206

Run: func(cmd *cobra.Command, args []string) {
            cmdutil.CheckErr(o.Complete(f, cmd))
            cmdutil.CheckErr(validateArgs(cmd, args))
            cmdutil.CheckErr(validatePruneAll(o.Prune, o.All, o.Selector))
            cmdutil.CheckErr(o.Run())
        },

o.Run()に飛ぶとコメントにRun executes the 'apply' command.とありますね. どうやら当たりのようです.
kubernetes/staging/src/k8s.io/kubectl/pkg/cmd/apply/apply.go L355-L403

// Run executes the `apply` command.
func (o *ApplyOptions) Run() error {

引き続き読み進めているとapplyOneObject()内でinfo.Get()を呼び出しており,作成リソースがすでに存在しないかどうかの判定を行っているのがわかります.
kubernetes/staging/src/k8s.io/kubectl/pkg/cmd/apply/apply.go

   if err := info.Get(); err != nil {
        if !errors.IsNotFound(err) {
            return cmdutil.AddSourceToErr(fmt.Sprintf("retrieving current configuration of:\n%s\nfrom server for:", info.String()), info.Source, err)
        }

そしてリソースがなかった場合はkubernetes/staging/src/k8s.io/cli-runtime/pkg/resource/helper.goCreate()以降でリソースの作成処理が行われ,あった場合はkubernetes/staging/src/k8s.io/kubectl/pkg/cmd/apply/patcher.go L183-L205Patch()以降でリソースの更新処理が行われています.2

ところでこのCreate()関数ですがkubectl createのコマンドでも使われているようです. つまりapplyコマンドはinfo.Get()で同名リソースが取得できなかった場合,createコマンドと同様の動作をするようです.
 createコマンドはapplyコマンド同様にリソース作成に用いられるコマンドですが,applyコマンドと違いリソースの更新作業は行いません.すでに存在するリソースを作成しようとするとエラー文を表示します. (ここでそういえばAlready Existsのエラーメッセージはcreateコマンドのときに見たことあるなあと思い出すなど...)

$ kubectl create -f pod.yaml
pod/demo created
$ kubectl create -f pod-changed.yaml
Error from server (AlreadyExists): error when creating "pod-changed.yaml": pods "demo" already exists

というわけでapplyコマンドを同時実行した際にエラーが発生したのはinfo.Get()実行時には同名リソースが存在しなかったが,その後のリソースのcreate処理中に同時実行されているもう片方で同名リソースが作成されていた」,というのが原因だということがわかりました.
めでたしめでたし.

さいごに

いかがでしたでしょうか?

実際にコードを読みながら動作を把握するのは面白いですね.
今回はAPIサーバ内の動作については深追いしませんでしたが,ここも見てみると面白いことがわかるかもしれません.
明日から使える知識...というほどの知見ではありませんが,この記事が誰かのクベ活に役立てれば幸いです.

というわけで本記事はあくあたん工房 Advent Calendar 2020 21日目の記事でした.
明日はkobaくんが何か書いてれるようです.お楽しみに〜

adventar.org


  1. 何度か実行すると場合によって片方がcreated,片方がconfigureになることもあります.

  2. 実際にはリソースへの作成または更新リクエストをAPIサーバに投げます

CNDK2019 に参加した

はじめに

先日行われたCNDK2019に参加してきました.
また参加にあたってインターンでお世話になっている株式会社イーシーキューブ様に参加費の援助をしていただきました.大変感謝しております.

本記事ではいくつか気になったセッションを取り上げてみようと思います.

なお当日の様子についてはこちらのtogetterにまとめられているため,よければ参照してみてください(スライドはCNDK公式サイトの各セッション紹介にリンクが貼られています).

f:id:tech_shanpu:20191202161658j:plain

セッション紹介

CloudNative Buildpacksで創る、CloudNativeな開発体験

こちらは開発者が開発に専念できる環境をどうやって作ったのかについてのセッションでした.
発表されていた山下さんのトークは非常に面白く,またスライドの情報量と話す内容の情報量のバランスがちょうどよく,自分の発表にも生かしたいなと思いました.

Dockerfileを書かずにDockerコンテナを作りたい

僕はDockerfileを書くのはわりと好きなのですが,特にアプリケーション開発者にとっては学習コストの高さや面倒さからできれば書きたくないという思いが強いようです.
確かにアプリケーション開発者が,アプリケーションを実行するための環境を構築するのに時間をかけるのは新機能の開発等かける時間に比べればもったいないと言えるでしょう.

セッションで紹介されていたCloudNative Buildpacksはアプリケーションコードをもとに,言語を特定,イメージのビルドを行ってくれます.
そのためDockerfileを書くことなくDockerコンテナのイメージを作成することが可能です.

CloudNative BuildpacksについてはCNDK2019の前夜祭で発表されていた@jacopenさんのスライドもわかりやすいので目を通してみるといいと思います.

パイプライン

ここではイメージのビルド・プッシュとクラスタへのデプロイにtektoncd/pipelineが紹介されていました.

tektonはContinuousDeliveryFoundationのプロジェクトの一つであり注目のOSSです.
しかし,現段階ではプレリリースかつ公式Webページも制作中のためドキュメントがあまりなく,使用する際はきちんと検証した方が良さそうです.

また,代替ツールとしてKpackも発表後のツイートに挙げられていました

Production Ready Kubernetesに必要な15のこと

こちらは本番環境Kubernetesクラスタの運用時に考慮すべき点をまとめたセッションです.
セッションとは関係ありませんが,発表されていた@go_vargoさんが技術書典7で頒布されていた「実践入門 Kubernetesカスタムコントローラへの道」はとてもわかりやすく個人的にオススメです.よければ確認してみてください.

40分で15項目の紹介でしたが,丁寧な解説で浅すぎず,非常にわかりやすいセッションだったと思います.
スライドもわかりやすく,これから本番環境にKubernetesクラスタを導入しようと考えている方には,導入時の指標となる良い資料になるかと思います.

Secretリソース内のデータの管理

セッション中ではSecretリソース内のデータの管理の方法としてberglasが挙げられていました.

Secretの管理というと個人的にはVaultをよく聞く印象がありますが,berglasはVaultと違ってサーバを必要とせず,Cloud KMSとCloud Storageを使って情報を管理するようです.
また権限管理にはGCPのIAMを用いるようです.
GCPを使用している方には導入,権限管理ともに比較的容易に行えるのではないかと感じました.
Kubernetesでのexampleはこちら

まとめ

朝から晩までさまざまなCloudNativeに関するセッションが聞くことができ,とても満足な1日でした.
今回のイベントで自分の知らない知識や様々な知見を得ることができたので,是非これからに生かしたり,これをもとに何かコミュニティに貢献したりできればと思いました.

次回か次々回か次々次回くらいには登壇したい

LINE DEV DAY 2019 に参加した

はじめに

先日行われたLINE DEV DAY 2019に参加してきました.
また,参加するにあたってLINE様より学生向け参加支援制度として交通費等を支援していただきました.大変感謝しております.

このイベントでは二日間,6つの会場でセッションが行われ,他にもBoothごとの展示やポスターセッション,ハンズオン,会場外での一枠10分程度でのセッションなど非常に内容の詰まった楽しいものでした.

この記事ではこのイベントの振り返りということで印象に残ったセッションをいくつかピックアップしようと思います.
なおセッションで使われたスライドはこちらにまとめられているので気になった方は覗いてみてください.

f:id:tech_shanpu:20191124103155j:plain

セッション紹介

プライベート Kubernetes クラスタにおける gRPC サービス開発 / LINE 宇井敬一朗

LINE LIVEKubernetesを用いてるとのことで,それぞれの使用しているミドルウェアについてなぜそれを採用したのか,どういう構成なのか,メトリクス収集や監視周りなどについてのセッションでした.

外部公開の部分はLB(クラスタ外)->NodePort->Envoyの順に構成されており,EnvoyがgRPCに対応していないアプリケーションに対して変換処理(gRPC-WebやJSONからgRPCへ)も行っているとのことでした.
またNodePortの後ろにさらにEnvoyをLBとして配置する理由として,一段目のLB(クラスタ外)->NodePortの部分ではあくまでNodeレベルでしか振り分けられないので,Podレベルでバランシングを行うためだという説明がありました.
externalTrafficPolicyClusterに設定することでEnvoyを使わずともPodレベルでバランシングが行えそうですが,(セッション中では述べられていませんでしたが)kube-proxyでのパケット転送時のSNATによりクライアントのIP情報がパケットから失われるといった作用が要件に合わなかったのかもしれません.
なおこのEnvoyですがingress-nginxでも同様の操作ができることから,そちらの使用も現在検討しているとのことでした.

ログ収集にはFluentdと共にエラーや警告といったものにはIMONという自社開発のLoggingシステムを用いているそうです.
詳細については以下のスライドで解説されていました.

LINEの独自LBaaSを支えるソフトウェアエンジニアリング / LINE 早川侑太朗

このセッションは社内向けのIaaSとして提供しているLBの開発についてのお話でした.
登壇されていた早川さんは話し方がとても上手く,わかりやすかったのが印象的でした.

Verda(LINE社内で運用されているプライベートクラウドの名称)で用いられているL4ロードバランサでは以前までステートレス,セッションテーブルを持たない形で実装されていたそうです.
この実装にはシンプルであることやスケーラブルであること,またセッションテーブルの枯渇を考えなくてよい点が利点として挙げられていました.
しかしこの場合,LB上にTCPコネクションの情報等が残らないため裏側のマシンのGracefulシャットダウンが難しい(セッション中では"できない"ではなく"難しい"と表現)ことや,宛先をハッシュ表で管理しているためにそれが更新されたときに既存のコネクションが意図しない形で切られる問題があったそうです.

これらの問題に対してはLBをステートフルな実装にすることで対処できますが,これはステートレスな実装方法とトレードオフな関係にあり,TCP SYN floodによるセッションテーブルの枯渇を考慮しないといけない等あったようです.
結果的に通常時はステートフルなLBとして,攻撃を検知した場合はステートレスなLBとして動作させることでこの問題を対処したとのことでした.

Journey of Feature Flag development in LINE Android /LINE 玉木英嗣

このセッションではFeature Branch戦略の欠点を克服するためにFeature Flag戦略というものを新たに導入し,そのためのGradleプラグインををOSSとして公開したというものでした.

Feature Flag戦略ではあるまとまった機能(従来のFeatureブランチの変更範囲にあたる)をmasterにマージするのではなく,細かいまとまりの変更をmasterにマージする形式をとるそうです.
このときFeature Flagと呼ばれるブール値によりその変更が有効か無効か管理することで,完成していないコード部分の実行を阻止するそうです.
これにより,

  • コンフリクトの数が減った
  • ある機能に問題が発生したときにFeature Flagの値を変更するだけで無効にできるので簡単

といった利点があるとのことでした.
またこのFeature Flagの管理を支援するGradleのプラグインOSSとしてリリースしたそうです.

github.com

このFeature Flag戦略,コード本体の可読性,複雑さは従来より増しそうですが,コードの有効な範囲を簡単な操作で絞ることができるので非常に面白い手法だと思いました.

さいごに

卒研等が忙しく,参加するか迷っていたLINE DEV DAYでしたが学べることが多く,参加してよかったです.
今回参加できなかった方も,それぞれのセッションのビデオアーカイブが後日配信されるとのことで,チェックしてみてはいかがでしょうか.

次回も学生参加支援あるといいなあ

CA Tech Challenge おうちk8s編に参加してきた

はじめに

先日,CyberAgentさんで開催されたCA Tech Challengeおうちk8s編に参加してきました.

当日はIntel NUCが各自に支給され,kindを用いて作ったクラスタ上に二日間で各自が設定したKubernetesに関する課題を達成するというものでした.

自分はPrometheus+Grafanaloki+GrafanaでKubernetesクラスタのモニタリング,ロギング基盤を構築しながら,余った時間でCNCF landscapeを眺めて気になったツールを色々と触ってみたりしていました.

この記事では当日の様子を振り返ってみたいなと思います.

イベントの様子

1日目

午前中は青山さん(@amsy810)からスライドを交えてKubernetesの簡単な復習とこれから使うkindの説明がありました(スライドは公開されていないようですがkindに関してはこちらとほぼ同一のものでした).

午後から本格的に開発スタートでした.
渡されたIntel NUCはあらかじめ必要なミドルウェアのインストールや設定は済まされており(ありがたい),すぐに作業を始めることができました.
この日やった作業は以下の通りです.

  • metrics-serverのデプロイ
  • helmのインストール
  • Prometheusのデプロイ
  • Grafanaのデプロイ

metrics-serverは必要ではありませんでしたが個人的にkubectl topを使えるようにしたかったため始めにクラスタに導入しました.

Prometheusのデプロイはhelm Chartを使いましたが,Prometheus Serverがpermission deniedでディレクトリを開くことができずエラーで止まり少し詰まりました.
調べてみるとver2.0から実行ユーザが非rootユーザになっており,そのせいによるものだとわかりました(参考: https://prometheus.io/docs/prometheus/2.0/migration/ ).
幸いhelmのvalueでsecurityContextが変更できたので,以下のように設定してあげたところ無事動いてくれました.

server:
  securityContext:
    runAsNonRoot: false
    runAsUser: 0
    fsGroup: 0

2日目

この日の作業内容は以下の通りです.

  • Grafanalokiのデプロイ
  • Grafanaのダッシュボードいじり
  • Harborのデプロイ
  • ArgoCDのデプロイ

Harborはjob-serviceポッドが突然死するため時間内に正常に動作するところまでは到達できませんでしたが,それ以外は概ねうまくいきました.
Grafanaダッシュボードはテンプレートを使いながら,入力補完に頼りつつ雰囲気でPromQLを書いて,いじっていました.
メンターさん曰く,慣れれば色々書けるとのことなので後日ちゃんと入門しようと思います.

2日目の終わりは各自の成果発表と,修了証書とメンターさんからコメントを頂く時間でした.
他の参加者の方が取り組んでいた内容も興味深いものが多く,ぜひ自分の手元でもやってみたいと思います.
また,頂いた修了証書には名前が書かれているだけでなく,裏面にコメントも添えられており,とても嬉しかったです.

おわりに

作業時間は決して長いものではありませんでしたが,社員の方からアドバイスを頂きながら色々と気になっていたツールを試すことができ,とても充実した2日間でした.
今回は作業時間が短いと思い,比較的簡単な課題を設定しましたが,振り返るともう少し尖った内容にしてもよかったなと反省です.

各ツールについての詳しい内容は後日改めて深掘りしながら,それぞれ記事にまとめたいなと思います.

f:id:tech_shanpu:20190921155106j:plain
2日間ありがとうございました!

ちなみに使ったIntel NUCはお土産として渡されました(太っ腹!).

レビューに使えるかもしれないコールを考えてみた

はじめに

みなさん,ダンベル何キロ持てますか?
自分は8kgが限界というところです.

ところでチームでのプログラミングの経験がある方は,一度はコードレビューをしたことがあるかと思います.
レビューでは誰かのコミットしてくれたコードを読んで,問題があればそれを指摘し,なければLGTM(Looks Good To Meの略)とコメントするのが一般的だと思います.

しかし,せっかく頑張ってコードを書いてくれたのにLGTMの四文字だけ返すのは,少し味気ないというものです.
LGTMの画像を貼り付けて気持ちを表現する方法もありますが,画像を用意するのも少々面倒です.

そこで現在,注目されているのがボディビル大会のコールです.
今回はこのコールでコードレビューに使えそうなもの,またはこれを少しアレンジしたものをまとめようと思います.

sports_body_builder_man.png

コール

  • ナイスコード! ナイスコミット!
    オーソドックスなコールです.
    レビューをして問題がないと思ったときに使いましょう.

  • 発想がキレてる!
    自分では思いつかなかったコードを見たときに使いましょう.

  • 発想が赤コーダー
    赤色は競技プログラミングコンテストを開催するAtcoderにおいて最上位クラスのコーダーを示す色です.
    異次元のコードを目にしたときの衝撃をこのコールで表現してください.

  • 仕上がってるよ〜
    完成に近いコードに対して使いたいコールです.
    また,軽微な修正箇所があるときに枕詞として「仕上がってるよ〜,でも〇〇のところだけ修正しよう!」というように使うのも良いです.

  • 脳にリンター載っけてんのかい!
    美しいコードに対して使いましょう.

  • 脳にtouristが住んでいる!
    touristは競技プログラミング界で有名な凄腕コーダーの名前です.
    コーディングの早さ正確さともに素晴らしいときに使いたいコールです.

  • 指にCPU積んでんのかい
    上と同じくコーディングの早さ正確さともに素晴らしいときに使いたいコールです.
    派生としては「指にインテル入ってる!」があります.

  • この変数名いいね〜
    素晴らしい変数名に対して使いましょう.

  • この〇〇,ナイスカット!
    プログラムが大きくなってくると,機能群に応じてファイルを切り分けたり,またはよく使われる処理を関数として切り出したりすると思います.
    このカットが秀逸なコードには「このモジュール,ナイスカット!」,「この関数,ナイスカット!」を使っていきましょう.

  • 土台が違うよ!土台が!
    優秀なプログラマや将来有望なプログラマに対して使いたいコールです.

  • このコードはGoogle社員も無視できない
    Googleには優秀なエンジニアが多く集まっています.
    素晴らしいコードを目にしたときに使いたいコールです.

  • そこまで計算量を絞るには眠れない夜もあっただろう
    これはコードレビューよりも競技プログラミング感想戦のときの方が使える場面が多いかもしれません.
    また派生として「そこまでクエリを減らすには眠れない夜もあっただろう」があります.
    苦労して最適化したコードに対して,労いのコールとして使っていきたいです.

まとめ

いかがだったでしょうか?
気に入ったコールがあればぜひ次回から活用してみてください.
これを活用すればチーム開発はより円満なものになるでしょう.

さいごに

今年の夏は暑いですね.外の気温計を見たら40℃になっているという日もありました.
お盆はご先祖様があの世からこの世に戻ってくる期間ですが,あまりの暑さに着いて早々帰り支度をしているかもしれません.とりあえず仏壇には冷蔵庫にあったポカリをお供えしておきました.
というわけでこの記事はあくあたん工房お盆アドベントカレンダー8月17日の記事でした.

皆さん熱中症には気をつけてくだサイド・チェスト!!

Cloud Native Kansai #05 でLTしてきた

Cloud Native Kansai #05でLTをしてきました.

今回はローカル環境でのKubernetes開発環境をテーマに,マルチノードクラスタを構築できるkindというツールを紹介しました.
この記事では当日やったデモの内容や発表しきれなかったことをまとめてみようと思います.

kindを触ってみる

インストール

あらかじめdockerとgo(1.11+)インストールしておきます(各ツールのインストール方法の詳細はこの記事では割愛します).
kindは次のコマンドでインストールできます.バージョンは適宜すきなものを選んでください

$ GO111MODULE="on" go get sigs.k8s.io/kind@v0.4.0

クラスタを作る

次のコマンドを実行することでシングルノードのクラスタを作ることができます.

# --name でクラスタの名前を指定できます(デフォルト名はkind)
# --loglevel で出力されるログの詳細度合いを変更することができます [panic, fatal, error, warning, info, debug, trace] 
$ kind create cluster --name shanpu 
Creating cluster "shanpu" ...
 ✓ Ensuring node image (kindest/node:v1.15.0) 🖼
 ✓ Preparing nodes 📦
 ✓ Creating kubeadm config 📜
 ✓ Starting control-plane 🕹️
 ✓ Installing CNI 🔌
 ✓ Installing StorageClass 💾
Cluster creation complete. You can now use the cluster with:

export KUBECONFIG="$(kind get kubeconfig-path --name="shanpu")"
kubectl cluster-info

contextは~/.kube内にkind-config-{cluster_name}の形式で作成されるため環境変数$KUBECONFIGで指定します.

# `kind get kubeconfig-path`でコンテキストのパスを取得してくれます
$ export KUBECONFIG="$(kind get kubeconfig-path --name="shanpu")"

マルチノードクラスタを構築する際はyaml形式のconfigファイルを用意しておきます. configファイルでは他にも色々指定できるので気になる方は公式ドキュメントを見てみてください

# ファイル名は何でも大丈夫です
$ cat kind-config.yml
kind: Cluster
apiVersion: kind.sigs.k8s.io/v1alpha3
nodes:
- role: control-plane
- role: control-plane
- role: control-plane
- role: worker
- role: worker
- role: worker

# --configでconfigファイルを生成します
$ kind create cluster --config kind-config.yml
Creating cluster "shanpu-multi" ...
 ✓ Ensuring node image (kindest/node:v1.15.0) 🖼
 ✓ Preparing nodes 📦📦📦📦📦📦📦
 ✓ Configuring the external load balancer ⚖️
 ✓ Creating kubeadm config 📜
 ✓ Starting control-plane 🕹️
 ✓ Installing CNI 🔌
 ✓ Installing StorageClass 💾
 ✓ Joining more control-plane nodes 🎮
 ✓ Joining worker nodes 🚜
Cluster creation complete. You can now use the cluster with:

export KUBECONFIG="$(kind get kubeconfig-path --name="shanpu-multi")"
kubectl cluster-info

クラスタを見てみる

クラスタの作成が終わるとnodeの数だけのコンテナが立ち上がっているのがわかると思います.
masterノードを複数作成した場合はapiサーバ用のロードバランサも自動的に作成されます.

$ docker container ls
CONTAINER ID        IMAGE                  COMMAND                  CREATED             STATUS              PORTS                                  NAMES
437c1138f1ff        kindest/node:v1.15.0           "/usr/local/bin/entr…"   5 minutes ago       Up 5 minutes                                               shanpu-multi-worker3
6cc8b3ba6920        kindest/node:v1.15.0           "/usr/local/bin/entr…"   5 minutes ago       Up 5 minutes        55447/tcp, 127.0.0.1:55447->6443/tcp   shanpu-multi-control-plane2
7b4ca009b0db        kindest/haproxy:2.0.0-alpine   "/docker-entrypoint.…"   5 minutes ago       Up 5 minutes        55450/tcp, 127.0.0.1:55450->6443/tcp   shanpu-multi-external-load-balancer
cf7660eaff59        kindest/node:v1.15.0           "/usr/local/bin/entr…"   5 minutes ago       Up 5 minutes        55449/tcp, 127.0.0.1:55449->6443/tcp   shanpu-multi-control-plane3
a35350c0f2b0        kindest/node:v1.15.0           "/usr/local/bin/entr…"   5 minutes ago       Up 5 minutes        55448/tcp, 127.0.0.1:55448->6443/tcp   shanpu-multi-control-plane
2e5aba47f81a        kindest/node:v1.15.0           "/usr/local/bin/entr…"   5 minutes ago       Up 5 minutes                                               shanpu-multi-worker2
6b3b8b49e07d        kindest/node:v1.15.0           "/usr/local/bin/entr…"   21 minutes ago      Up 21 minutes       55238/tcp, 127.0.0.1:55238->6443/tcp   shanpu-control-plane
97345685ba51        kindest/node:v1.15.0           "/usr/local/bin/entr…"   22 minutes ago      Up 22 minutes       55205/tcp, 127.0.0.1:55205->6443/tcp   demo-control-plane

このnodeコンテナの中にKubernetesクラスタを動かす上で必要なコンポーネントが自動的に用意されています.
ちなみにkubectl topは機能しません.別途メトリクスサーバー(ポッド)をデプロイする必要があります.

$ kubectl get all -n kube-system
pod/coredns-5c98db65d4-mc7sl                       1/1     Running   0          24m
pod/coredns-5c98db65d4-vxbh2                       1/1     Running   0          24m
pod/etcd-shanpu-control-plane                      1/1     Running   0          23m
pod/kindnet-2h7zv                                  1/1     Running   1          24m
pod/kube-apiserver-shanpu-control-plane            1/1     Running   0          23m
pod/kube-controller-manager-shanpu-control-plane   1/1     Running   0          24m
pod/kube-proxy-97ctv                               1/1     Running   0          24m
pod/kube-scheduler-shanpu-control-plane            1/1     Running   0          24m


NAME               TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE
service/kube-dns   ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP,9153/TCP   25m

NAME                        DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR                 AGE
daemonset.apps/kindnet      1         1         1       1            1           <none>                        25m
daemonset.apps/kube-proxy   1         1         1       1            1           beta.kubernetes.io/os=linux   25m

NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/coredns   2/2     2            2           25m

NAME                                 DESIRED   CURRENT   READY   AGE
replicaset.apps/coredns-5c98db65d4   2         2         2       24m

またリソース使用量は概ねmasterノードで1GiB,workerノードで200MiBくらいです.

$ docker stats
CONTAINER ID        NAME                                  CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
64431e8f7650        shanpu-multi-worker                   5.86%               222.4MiB / 7.787GiB   2.79%               1.77MB / 226kB      725kB / 98.3kB      105
437c1138f1ff        shanpu-multi-worker3                  2.37%               222.3MiB / 7.787GiB   2.79%               1.76MB / 219kB      1.35MB / 53.2kB     108
6cc8b3ba6920        shanpu-multi-control-plane2           18.42%              1.049GiB / 7.787GiB   13.47%              19.1MB / 11.8MB     1.85MB / 147kB      334
7b4ca009b0db        shanpu-multi-external-load-balancer   1.07%               58.4MiB / 7.787GiB    0.73%               21.6MB / 21.6MB     8.45MB / 0B         5
cf7660eaff59        shanpu-multi-control-plane3           14.27%              1.393GiB / 7.787GiB   17.89%              11.9MB / 8.23MB     1.2MB / 147kB       267
a35350c0f2b0        shanpu-multi-control-plane            17.50%              877.6MiB / 7.787GiB   11.01%              18.9MB / 34.6MB     7.4MB / 57.8MB      262
2e5aba47f81a        shanpu-multi-worker2                  2.50%               185.8MiB / 7.787GiB   2.33%               1.77MB / 226kB      1.34MB / 98.3kB     107
6b3b8b49e07d        shanpu-control-plane                  32.94%              600.2MiB / 7.787GiB   7.53%               23.4kB / 126kB      33.7MB / 57.9MB     349

クラスタのログをとる

kindにはログを出力するコマンドが用意されています.

$ kind export logs --name shanpu  
Exported logs to: ...

クラスタを削除する

次のコマンドでクラスタを削除することができます. またコンテキストファイルも同時に削除されます.

$ kind delete cluster --name shanpu 
Deleting cluster "shanpu" ...
$KUBECONFIG is still set to use /Users/shanpu/.kube/kind-config-shanpu even though that file has been deleted, remember to unset it

リンク

github.com

  • ドキュメント

kind.sigs.k8s.io

おわりに

kindいかがでしたでしょうか
この記事を書いてる時点ではまだpre-releaseですがKubernetesの検証用ツールとしては十分な機能とパフォーマンスを発揮してくれていると思います.
またSlackのKubernetesワークスペースには#kindというチャンネルがあります.気になった人はぜひのぞいてみてはいかがでしょうか.

この発表を通じて関西のKubernetes熱がさらに高まるとうれしいなあ( ´ω`)