hitsumabushi845の日記

心理的安全性の保たれた空間に書く適当なメモ

『Kubernetes Certified Application Developer (CKAD) with Tests』記録 - セクション6

引き続き、『Kubernetes Certified Application Developer (CKAD) with Tests』を進めていく。
今回は Section 6: POD Design。

Section 6: POD Design

Labels, Selectors and Annotations

リソースを分類する方法について。
ラベルは metadata.labels に設定でき、設定したラベルにしたがって kubectl get pods --selector key=value といったように絞り込むことができる。

ReplicaSet や Deployment では、ラベルをもとに指定したリソースの数を判断している。 また、Service では、ターゲットとなるリソースをラベルから指定できる。

上述の通り、ラベルはリソースを分類・振り分けするためのフィールドだが、アノテーションはそのほかの情報を付与するためのフィールド。 ... と説明されているが、場合によってはアノテーションも分類・振り分け用途に使う気がする...

Rolling Updates & Rollbacks in Deployments

Deployment のローリングアップデートとロールバックについて。
Pod では、使用しているコンテナイメージを更新するためには Pod の再作成が必要になる。 一方、Deployment では配下の Pod についてコンテナイメージの更新をローリングアップデートで行える。

Deployment では、アップデート戦略(StrategyType)のデフォルトが RollingUpdate であるので、 ローリングアップデートは kubectl set image でイメージを変更するか、マニフェストを更新して kubectl apply をするだけでよい。
StrategyTypeRecreate にすると、Deployment であっても再作成により更新が行われる。

変更のロールバックには kubectl rollout undo が使用される。リビジョンを指定しなかった場合は1つ前にもどる。
リビジョンは kubectl rollout history で確認できる。

ここのハンズオンは結構楽しい。Recreate と RollingUpdate の挙動について実際に手を動かして確認できた。

Jobs, CronJobs

Job について。
Pod などのリソースは常に動作していることが期待されるものだが、Job はバッチ処理など、特定の実行単位があり、終了する処理を行うリソース。

Pod でも終了する処理を実行することは可能だが、終了してしまうがゆえにヘルスチェックに失敗し、コンテナの再起動が走ってしまう。 また、Job では、同一の処理を並列で実行させたり、成功数を規定できたりする。

CronJob は、指定した時間に Job を作成するリソース。spec.schedule に cron と同じフォーマットで時間を指定できる。

apiVersion が、Job は batch/v1, CronJob は batch/v1beta1 なのに注意。

『Kubernetes Certified Application Developer (CKAD) with Tests』記録 - セクション4・セクション5

前回の記録から間が空いてしまったが引き続き、『Kubernetes Certified Application Developer (CKAD) with Tests』を進めていく。
今回は Section 4: Multi-Container PODs と Section 5: Observability。

これらのセクションは結構短い。

Section 4: Multi-Container PODs

マルチコンテナ Pod のパターンについて、アプリケーションコンテナとロギングを扱うコンテナの2つのコンテナを例に説明。このセクションは以下の説明と Practice test のみ。

  • Sidecar pattern
    アプリケーションコンテナのログをログサーバなどのサービスに送信するなど、補助的な機能をもつコンテナを配置する。
  • Adapter pattern
    アプリケーションコンテナのログをフォーマットするなど、外部とのインターフェースを提供するコンテナをもつパターン。アダプタコンテナがインターフェースを担うことで、アプリケーションコンテナ自身のログの柔軟性を高めることが出来る。
  • Ambassador pattern
    アプリケーションコンテナのログの送信先を扱うような、外部のサービスとの接続を仲介するコンテナを持つパターン。このコンテナがあることで、アプリケーションコンテナからは常にこのコンテナ(localhost)に接続すればよく、アンバサダーコンテナを差し替えることで接続先を柔軟に切り替えられる。

Practice Test は、Elasticsearch に Sidecar コンテナからログを送信し、Kibana からログを閲覧できるようにするハンズオンだった。といっても既存の Pod に指定のコンテナを追加するだけだが。

Section 5: Observability

Readiness Probes

Pod が作成されると、Pending -> ContainerCreating -> Running といったように、Status が遷移する。 コンテナが起動した後、"Running" であることを Kubernetes はどう知るのか?
Jenkins を Kubernetes で立ち上げると、Web 画面は利用可能でないが Pod は "Running" になる。 Service は "Running" な Pod にルーティングするので、アプリケーションとして利用可能でないのにルーティングされてしまう可能性がある。

そこで、アプリケーションが利用可能であること(リクエストを受け付けることができること)を Readiness Probes を用いて検証する。 これは HTTP APITCP, コマンド実行で検証する。 この検証に失敗した場合、Service はその Pod へトラフィックをルーティングしない。

これは spec.containers[*].readinessProbe に設定する。

    readinessProbe:
      httpGet:
        path: /api/ready
        port: 8080
    readinessProbe:
      tcpSocket:
        port: 3306 
    readinessProbe:
      exec:
        command:
        - cat
        - /app/is_ready

Liveness Probes

Docker では、コンテナの作成に失敗したらそのコンテナは失敗したままだが、Kubernetes では Pod の作成に失敗したら、再作成を行う。 Pod の作成に成功したこと(Pod 内のコンテナが正常に動作していること)を検証するための機構が Liveness Probe。 この検証に失敗した場合、コンテナを再起動する。

こちらも同様に、HTTP API call や TCP, コマンド実行で検証を行う。

書き方は、おおむね Readiness Probe の readinessProbelivenessProbe に変更したもの。

Container Logging

kubectl logs コマンドについて。Pod 名を指定して Pod のログを見たり、加えてコンテナ名を指定してコンテナのログを絞って見たり。ここは普段よく使っているので流す。

Monitor and Debug Applications

kubernetes のノード監視について。通常の運用では Prometheus や Datadog などを使ってメトリクスを記録していくが、CKAD では公式に開発されている Metrics Server を用いるようだ。過去は heapster というコンポーネントだったが、今は metrics-server らしい。

こいつはメモリ上に記録するため、メトリクスを過去に遡って見ることはできないが,kubectl top コマンドでノードや Pod のメトリクスを確認できるようになる。

7ヶ月かけて NURO を開通させた話

もうタイトルで言いたいこと全て言っているのだが、7ヶ月かけて NURO を開通させた。 これはなにも NURO の工事に7ヶ月待たされたという話ではなく、「初めての一人暮らし」であったり「賃貸物件の共用部への工事」といった要素が絡み合って時間がかかってしまった。

特に後者の「賃貸物件の共用部への工事」を解決するための戦いに多くの時間を費やし、先日ついに開通したためその記録を残したい。

引っ越しと1度目の宅内工事

昨年9月に実家を出る形で引っ越しをした。実家でも NURO を通していたこと、またリモートワーク環境を整えるための引っ越しであることから、引き続き NURO を利用しようと考えていたため、物件探しの段階で「NURO の工事が可能なこと」を条件に物件を探していた。

その後工事可能なマンションを契約し、引っ越し予定日に宅内工事を予約した。

そして宅内工事当日。 集合住宅の場合、宅内工事は宅内から MDF 盤まで光ファイバを通すことを目的とする。 つまり、部屋 (-> IDF) -> MDF といった経路で光ファイバを通すことになる。

MDF(Main Distribution Frame): 集合住宅やオフィスビルの共用部に設置される電話回線や光ファイバなどの集線装置。
IDF(Intermediate Distribution Frame): MDF から各戸分配するにあたって中間に設置される中継機器。複数フロアの物件の場合は通常各階に設置される。

しかし、この工事では 部屋 -> IDF の経路でファイバを通す途中でファイバが詰まってしまい、IDF まで通せないという事態に陥った。既設の電話回線等により配線を通すパイプが詰まっていたのである。

工事作業者と一緒になって、ファイバの通る音を頼りに詰まってしまっている地点を特定したが、そこは共用部(マンション廊下の天井裏)であり、またその地点に点検口などといったものが無かった。

そのため、この宅内工事では「別途点検口を設けるなどして、通線可能な状態にならない限り開通不可能」という結論となった。

ここでの学び

  • 入居前の「工事可能」はできるだけ厳密に確認しておく
  • 光アウトレットが既設の物件であればなおよい(こういった物件はほぼ築浅なので家賃は高い)
  • IDF とか MDF とか、このへんではじめて知った

点検口を開けてもらうための5ヶ月

さて通常、集合住宅かつ賃貸物件の場合は共用部へ点検口を設けるなどといった工事は許容されないことが多い。特に今回問題になっているのは 部屋 -> IDF の経路であるため、ここに点検口を設けるとなると他のフロアにも等しく設ける必要があるかもしれない。オーナーがこのコストを支払うのを避けたい気持ちは十分に理解できる。 しかしそもそも私は「工事が可能」という条件で物件を契約しているため、これを武器に戦うこととした(たとえ、この条件が不動産屋が深く考えずに発言した内容であっても)。

物件は私とオーナーとの間に管理会社が入っているので、まずは管理会社と交渉することになる。 ここからが長い戦いの始まりであった。

最初の1ヶ月

最初の1ヶ月は、まず管理会社に「なぜ NURO を通したいか」を理解していただくための期間であった。 集合住宅の場合、一口に光回線といっても各戸分配する方式によって品質が大きく変わる。(参考: https://internet-flets-campaign.net/column/separatefiber/

このマンションには NTT の VDSL 設備はすでに備わっているため、対外的には「光回線が利用できます」と謳っていたし、管理会社の方もまた「光回線が利用できる」という認識であった。 そのおかげで、まず「なぜ NURO を通したいか」の説明が必要となった。

もちろん、光配線方式がとれればどの事業者でもよいので、個人的には NURO でもフレッツでも何でもよかった。 しかしフレッツはサービスとして VDSL と光配線の両方を提供している。 以下に示すやりとりを経て、「フレッツを利用したい」というスタンスでいると余計な混乱を招きそうと判断し、「NURO を通したい人」で通すことにした。

NTT の VDSL 設備が備わっている場合、VDSL 方式のフレッツ光は当然今のままでも利用可能である。 そのためか、管理会社から「フレッツなら光回線を通せます」という旨の回答を受けた。

この回答を逆手に取り、フレッツ光なら通せるんですか?光配線方式でも?」 と質問したところ、おそらくあまり考えておらずに 「はい!通せます!」 と返ってきた。
もちろん通せるわけはないので、 「本当に通せるんですか?光配線方式って何か分かってますか?」 と改めて確認したところ、 「はい!わかります!」 と返ってきた。
分かっているとのことなので、改めて VDSL 方式と光配線方式の違いを説明できますか?」 と確認した。

すると ADSL ですか?」 と返ってきたため、改めてこれらの違いを説明し、理解いただいた。 ほかにも、「NURO が使える物件は付加価値が高まりますよ」的なことも(無責任に)言った気がする。

ここで辛抱強く説明を重ねて理解いただいたことで、以降管理会社の方がこちらの味方についてくれることとなる。このステップがなかったら以降の点検口開口の交渉も難しかったのではないかと思う。

これが最初の1ヶ月。

ここでの学び

  • 辛抱強く説明すると分かってくれることがある
  • 分かってくれると味方になってくれることがある
  • VDSL 方式と光配線方式の違いについて結構調べた

その後の3ヶ月

「なぜ NURO を通したいか」を理解いただいてからは、管理会社と物件オーナーとの交渉となる。 交渉の目的は点検口の工事可否確認になるのだが、先述の通り物件オーナーからすると共用部への工事は敬遠される。

さて、この期間は管理会社とオーナーの間での交渉が行われていたため、基本的に私がすることはなかった。 この間に私がしていたことは主に以下の2つである。

進捗確認

1つ目が進捗の確認。これは管理会社側が交渉の進捗をこちらに報告してくれないためであった。そもそもこちらから問い合わせないと報告しないというスタンスならそれでよかったが、彼らはいつも「いついつまでに改めてご連絡します」と言っていたのにも関わらずそれを守らなかったのであった。思い返してみると、これが守られたことは1度もなかったように思う。

そのため、平均的には2週間に1度、多いときは週に1度のペースで確認を取っていた。

直接引き込みの可否確認

そして2つ目が「点検口を開けずに工事を行う方法の確認」である。 そもそも私は「ただ単に点検口を開けたいだけの人」ではなく「NURO を通したい人」であるので、点検口を開けずに工事が可能ならそれでも良かったのだ。

点検口を開ける必要があるのは 部屋 -> IDF -> MDF といった経路での通線を行う場合であって、直接部屋に引き込むことができればその限りではない。実際 NURO は集合住宅であっても場合によっては部屋に直接引き込むことが可能である。(参考: https://www.nuro.jp/article/mansionjyouken/)

つまり、for マンションプランでなく通常プランであれば電柱から直接光回線を自室に引き込むことができる。通常プランは、以前は7階建て以下の集合住宅という条件があったものの、この条件は2019年に撤廃されたそうだ。

自室に直接引き込むことができれば、IDF や MDF のことを考えずに済むため、こちらの可能性についても検討した。

さて、自室に直接引き込むにあたり障壁となるのが「壁への穴開け」である。外壁から屋内にファイバを通すための穴開け、並びに穴へのカバー取り付けのためビス留めが必要となるのである。これらは外壁への穴開けとなり、賃貸物件の場合はほぼ容認されない工事となる。

しかし、これについても回避することが可能である。詳細はこの記事を確認してほしい。

要約すると、エアコン等の配管を利用してファイバを通し、ビス留めは両面テープで代替するなどの方法による回避である。

外壁への穴開けを回避できることが分かったため、管理会社に「外壁への穴開けがなければ工事してもよいか」、NURO に「私の住んでいる物件は直接引き込みが可能か」の確認をそれぞれ行った。

前者は穴開けがなければ良いとのことだったが、後者が不可能であった。つまり、私の住んでいる物件は直接引き込みができないのであった。

従って、NURO を開通させるにはやはり点検口を設けてもらうしかないということとなった。

そして

さて、これらのことを進めている間に管理会社とオーナー間の交渉は進んでいた。 管理会社の尽力のおかげか、オーナーの理解も得られ、点検口開口の工事が可能となったのである。

これが2021年1月中旬の出来事である。開始からすでに4ヶ月が経過していた。

ここでの学び

  • NURO は集合住宅であっても場合によっては直接引き込むことが可能
  • NURO は直接引き込みの際、場合によっては外壁に穴開けをしない施工が可能

最後の1ヶ月

ここは実際に点検口を開ける工事を待つだけのほぼ消化試合であった。 そして2月中旬、ついに点検口が誕生した。

つなぎの VDSL

引っ越し当初は、まず引っ越し予定日に宅内工事完了、その後1〜2ヶ月で屋外工事完了といったスケジュール感でいたため、モバイル Wi-Fi(WiMAX) をレンタルして仕事をしていた。

しかし、戦いが長丁場になりそうだったこと、モバイル Wi-Fi では仕事にならないことから、つなぎになる VDSL を契約することとした。

つなぎに利用する回線は、契約期間の縛りがないことが優先される。 NURO が開通できた場合即座に解約することとなるため、違約金等が発生するのは避けたい。また、契約期間の縛りがなければ、NURO の開通が不可能であった場合も改めて適切な事業者を選択することができる。

契約期間の縛りがないプロバイダは検索するといくつか出てくるが、enひかりを選択した。IPv6 オプションを追加することで IPoE での接続が行えるためだが、他でもできたかもしれない。

この VDSL は 12 月に開通した。都合 4 ヶ月で解約することとなったが、モバイル Wi-Fi から解放してくれて感謝している。

ここでの学び

  • NURO の工事待ちが長期化することが見込まれる場合、契約期間の縛りのないプロバイダを契約するとよい
  • モバイル Wi-Fi をレンタルし続けるくらいなら、さっさとつなぎの回線を契約した方がよい(工事費がかかるが、モバイル Wi-Fi による諸々のストレスをなくせるほうが大きい)

点検口が誕生し、2度目の宅内工事

点検口が誕生し、3月上旬、2度目の宅内工事が行われた。2度目の宅内工事では、1度目の工事と同じ作業者の方が来てくれた。作業者の方は1度目の工事のことを覚えてくださっていて、半年越しで工事を完了でき、お互いに戦友みたいな感じになった。

ただ、開けてもらった点検口の場所が微妙に良くなかったらしく、結局 IDF への通線は少し苦戦したらしい。

ともあれ、宅内工事が完了した。これが3月初頭。ここまでで5ヶ月半が経過していた。

そして終戦

宅内工事が完了し、残すは屋外工事のみとなった。NURO の屋外工事は長く待たされることで有名だが、私の場合は約1ヶ月半後の 4/22 に行われることとなった。 そして先日 4/22、ついに屋外工事が完了したわけである。

というわけで、VDSL と NURO の速度比較画像をもって本記事の結びとしたい。 なお、開通したプランとしては NURO 光 G2 V(旧: マンションミニ)プランである。

f:id:hitsumabushi845:20210504023218p:plain
VDSL

f:id:hitsumabushi845:20210504023249p:plain
NURO

余談

屋外工事にあたって、管理会社に連絡をしたところ、半年に渡って協力してくれた管理会社の担当の方が異動かなにかで担当を外れてしまっていた。最後にお礼を申し上げたいところだったが、叶わず。

ここでの学び

  • 光配線方式しか勝たん。
  • 半年経つと人は異動する可能性がある

おわりに

というわけで、7ヶ月かけて NURO の通っていない賃貸物件に NURO を開通させることに成功した。管理会社の方を味方につけたことや、(結果としてこの方法は取れなかったが)直接引き込みの検討など、様々なアプローチで NURO 開通へ向けて邁進したことがこの結果に繋がったのではないかと思う。

また会社の slack でこれらの進捗を逐一実況しており、多くの方が見守ってくれたことも支えとなった。開通したときは多くのリアクションをいただけて、ありがたい限り。

f:id:hitsumabushi845:20210504023614p:plain
開通したときのリアクション

『Kubernetes Certified Application Developer (CKAD) with Tests』記録 - セクション3

引き続き、『Kubernetes Certified Application Developer (CKAD) with Tests』を進めていく。
今回は Section 3: Configuration。

Section 3: Configuration

Pre-Requisite - Commands and Arguments in Docker

Docker コンテナのコマンドと引数について。
Dockerfile の CMD, ENTRYPOINT について説明されている。

Docker をちゃんと触ったことないので助かる(そんな状態で Kubernetes に手を出してるのはアレだが...)

Commands and Arguments in Kubernetes

Pod manifest における spec.containers[*].command, spec.containers[*].args フィールドについて、Dockerfile の例と比較して。
commandENTRYPOINT を、argsCMD を上書きする。

Environment Variables

コンテナ内の環境変数について(spec.containers[*].env)。
後段の ConfigMap への布石。

ConfigMaps

あんまり触れてなかったのでちゃんと書く。 env で指定するような key-value pair を外出しできるやつ。
kubectl create configmap で作成したり、

$ kubectl create configmap \
    app-config --from-literal=APP_COLOR=blue \
               --from-literal=APP_MODE=prod

yaml を書いたり。

apiVersion: v1
kind: ConfigMap
metadata:
    name: app-config
data:
    APP_COLOR: blue
    APP_MODE: prod

spec.containers[*].envFrom[*].configMapRef で、ConfigMap を環境変数として注入できる。

ほか、ボリュームとして注入してファイルとして扱うなど。

Secrets

ConfigMap は平文で格納されるが、Secret は Base64エンコードされた状態で格納されるやつ。 kubectl create secret generickubectl create secret tls で作成するか、yaml を書くか。

$ kubectl create secret generic \
    <secret-name> --from-literal=<key>=<value as plain>
$ kubectl create secret generic \
    <secret-name> --from-file=<path-to-file>
apiVersion: v1
kind: Secret
metadata:
    name: <secret-name>
data:
    <key>: <base64 encoded value>

spec.containers[*].envFrom[*].secretRef で、Secret を環境変数として注入できる。 注入したあとはデコードされた値が利用できる。

Docker Security

Docker のプロセス分離について。Namespace でプロセスを分離している。 コンテナ内の実行ユーザーについて。デフォルトは root、--user=xxxdocker run 時に指定したり、Dockerfile の USER フィールドに指定することで異なるユーザで実行できる。 ユーザの権限を操作する場合は、--cap-add, --cap-drop--privileged を使う。

Container Security

k8s におけるコンテナは Pod で抽象化されているため、Pod 単位でのセキュリティ設定が可能。 Pod 単位で設定した場合は、Pod 内の全てのコンテナに反映される。

spec:
  securityContext:
    runAsUser: 1000
  containers:
  ~~

コンテナ単位で設定する場合は、containers 以下に設定する。 コンテナ単位での securityContext では、capabilities を設定でき、ユーザの権限を操作できる。これは Pod 単位ではできない。

Service Account

KSA は認証/認可やRBACに関わってくるけど、CKAD では KSA の使い方だけ分かってればいいらしい。 k8s のアカウントは User Account と Service Account に大別される。

Service Account はアプリケーションが k8s クラスタを操作するためのアカウント。 例えば Prometheus が k8sAPI を叩いてメトリクスを取得する際などに使う。

> kubectl create serviceaccount <serviceaccount name>
> kubectl create sa <serviceaccount name>

describe すると、Token というフィールドが見える。 これは k8sAPI を叩くための認証トークンとクライアント証明書を持った Secret で、KSA を作成すると自動的に作成される。

default という名称の ServiceAccount は各 namespace にはじめから存在する。 そもそも Pod は ServiceAccount と紐付いている必要があり、マニフェストで指定しなかった場合は default が使用される。default SA は権限が弱く、基本的なクエリしか実行できない。 default をマウントさせたくない場合は、spec.automountServiceAccountTokenfalse にする。

異なる ServiceAccount を使用する場合は、Pod マニフェストspec.serviceAccount に明示的に指定する。

Resource Requirements

kube-scheduler はノードのリソース状況(CPU, Memory, Disk)を見ながら最適なノードに Pod をスケジューリングする。

ワークロードの使用するリソースの最低値・最大値を指定するには、spec.containers[*].resources フィールドを使用する。 resources.requests には要求値(最低値)、resource.limits に最大値を指定する。

LimitRange リソースをつかって、resource フィールドを指定しなかった場合のデフォルト値を指定できる。

なお、負荷に応じてワークロードをスケールさせる HPA とか VPA とかは CKAD では範囲外。

Taints and Tolerations

Taint と Toleration は Pod を特定の Node にスケジューリングさせないための仕組み。
これらは、スケジューリングさせないための仕組みであって、Pod を特定の Node にスケジューリングさせるための仕組みは後述する Node Selector や Node Affinity が担う。

Taint は Node に、Toleration は Pod に設定する。 Node に設定された Taint と合致する Toleration が設定された Pod がスケジューリングされる。

Taint は kubectl taint nodes {node name} key=value:taint-effect で設定できる。 key, value が Taint の条件となり、taint-effect でその振る舞いを設定できる。
taint-effect には NoSchedule, PreferNoSchedule, NoExecute がある。

Toleration は、manifest の spec.tolerations に設定される。

Master Node に Pod がスケジューリングされないのもこれのおかげ。

Node Selectors

Pod を特定の Node にスケジューリングさせるための仕組み。 manifest の spec.nodeSelector に、Node に設定したラベルを指定する。

Node にラベルを設定するには、kubectl label nodes {node name} key=value を実行する。

Node Selector では、指定されたラベルへの完全一致のみサポートしているが、OR条件やNOT条件などを利用したいケースがあり、これは Node Affinity でサポートされる。

Node Affinity

Node Selector より柔軟な設定が可能なもの。 spec.affinity.nodeAffinity に設定され、requiredDuringSchedulingIgnoredDuringExecutionpreferredDuringSchedulingIgnoredExecution の2種類が設定できる1

required~ は必須条件。マッチする Node がない場合はスケジューリングされない。
preferred~ は推奨条件。マッチする Node がない場合は他の Node へスケジューリングされる。
IgnoredDuringExecution とあるように、実行中の Pod に対してはこの設定は影響せず、例えば nodeAffinity を設定した Pod が実行されている Node から、その nodeAffinity の条件を満たさなくなるようにラベルを削除したとしても、その Pod は削除されない2

かなり柔軟に設定できるため、フィールドがいろいろあって混乱する。 この辺をブックマークして、試験中に見れるようにしておこう。
https://kubernetes.io/ja/docs/concepts/scheduling-eviction/assign-pod-node/
https://kubernetes.io/ja/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/

Taints & Tolerations vs Node Affinity

特定の Node に特定の Pod だけをスケジューリングさせたい場合は、Taints/Tolerations と Node Affinity を併用しようねという話。


Section 3 はここまで。ちょっと忘れちゃいそうな点がままあるので、折に触れて復習していこうと思う。


  1. 将来的に requiredDuringSchedulingRequiredDuringExecution が提供される予定。

  2. 当然、requiredDuringSchedulingRequiredDuringExecution の場合は削除される。

『Kubernetes Certified Application Developer (CKAD) with Tests』記録 - セクション1・セクション2

今年上半期は Certified Kubernetes Application Developer(CKAD) の取得を目指して勉強していく。
先人の受検ログを見ると、Udemy にある Mumshad Mannambeth 氏の『Kubernetes Certified Application Developer (CKAD) with Tests』を活用している人が多かったので、先日のセールのタイミングで購入。

www.udemy.com

同氏による CKA のコースも合わせて購入した。

まずはセクション1と2を完了したので、記録。

Section 1: Introduction

このセクションでは、コースの概観や CKAD の説明が行われる。

このコースでは CKAD の取得を目的として、出題範囲に従ってレクチャーが展開される。
Workloads APIs や Service APIs 等の基礎、Kubernetesアーキテクチャといった基礎の部分は前提知識となるため、全くの初心者は以下のコースから取り組むことが推奨されていた。

www.udemy.com

上記のコースの存在は知らなかったが、すでに『Kubernetes 完全ガイド』を写経しながら通読したこと、Kubernetes the Hard Way をやったこと1からスキップしてよいと判断し、このまま進めていく。

特筆すべき点は、ここで CKAD/CKA の受験料が 15% オフになるバウチャーコードが提供されること。 通常 $300 の受験料が $255 になるので、セールのタイミングで購入しておくと実質無料になる。

イントロダクションはサクッとこんな感じ。次セクションから具体的な解説に入るようだ。 完全ガイドを通読したとはいえ、忘れてしまっているところも結構あるので復習も兼ねて進めていこう。

Section 2: Core Concepts

このセクションでは、Pod, ReplicaSet, Deployment, Namespace, Service といった基本的なリソースについての説明とハンズオンテストが提供される。

この2つはわりと日頃触れてるのでサクッと流す。
ここではじめて Practice Test が入る。Practice Test は、KodeKloud(Katacoda) を使って作られており、ブラウザ上で実際に k8s クラスタを触りながら確認テストができる。
これが学習体験としてけっこう楽しい。

f:id:hitsumabushi845:20210325011608p:plain
Practice Test のイメージ

  • Recap - ReplicaSets

ReplicaSet は普段使わないので、思い出しがてらちょっとしっかりやる。 ReplicationController の存在を(ほぼ)はじめて知る。ReplicaSet には selector を定義できるが、ReplicationController はできない。

Deployment と違い、ローリングアップデートもできない。
例えば kubectl edit などで定義を書き換えても配下の Pod は再作成されない。
というかそもそも、ReplicaSet の上位に存在して、ReplicaSet を管理することでローリングアップデートやロールバック(など)を可能にしたリソースが Deployment。

  • Recap - Deployments

というわけで Deployment。
Deployment 固有のフィールドとか結構忘れてるなーと思ったけど、このセクションではそれは扱わないっぽい。ここでは基礎のみ復習して、後段のセクションで詳細を扱うようだ。

  • Recap - Namespaces

Namespace リソースそのものは簡単なのでサクッと。
...と思ったら急に Service とか DNS が出てきてびっくりした。Namespace をまたいだ名前解決の話もここだったようだ。

  • Certification Tip: Imperative Commands

yaml を使わずに kubectl コマンドだけでリソースを作る方法について。
CKAD の試験は時間がタイトなので、この手法をよく使うらしい。

Practice Test では Pod と Deployment の作成は難なくできたが、Service の作成が慣れておらず手間取った。

セクション2はここまで。次はセクション3: Configuration。


  1. これは kubeadm 使用/非使用でそれぞれ行った。kubeadm を使用したクラスタ構築の記録は Qiita に書いた。qiita.com

2021年の目標など

こまめにブログを書きますまいか。
新年一発目のブログということで、今年の目標など書いていきましょう。

資格をとる

今年受検したいと思っているものは以下の通り。

  • CKA or CKAD
    昨年12月より副業で Kubernetes を触っているので、せっかくなら...と思っている。
    "or" とあるように、どちらか一方だけかもしれないし、どっちもかもしれない。
    あわよくば本業の資格取得補助制度を活用したい。
  • TOEIC
    本来であれば昨年受検するつもりだったもの。
    昨年申し込んだものの、コロナ禍により抽選方式になっていて、落選してしまった。
    最後に受検したのが3年前なので、いい加減更新したいと思っている。
    TOEIC はこれまで特別な勉強をしていないのだが、スコアは 4xx -> 6xx -> 7xx と過去3回着実に伸ばしている。
    そのため今回は 800 点台を目指したいが、いい加減それ用の勉強をしないと厳しそう。

こまめにブログを書く

このブログでは特定の技術に関する話題以外の、技術以外の話やポエムなどを書いていきたいと思っている。
特定の技術要素については、せっかく Organization に属しているので Qiita に書くつもりでいる。

こまめにと言っても、せいぜい月2程度のペースでゆるくやっていきたい。
いままでできていない身で変に高い目標を掲げてもつらくなるだけなので。

Terraform を勉強する

2021年から本業・副業ともに Terraform を扱うようなので、ゆるく勉強する。
仕事で使うのでまあ勉強できるだろうと高をくくっている。

特に到達目標はないが、仕事が回る程度に扱えればよいと思う。

golang を勉強する

そろそろ新しい言語を勉強したい。
golang は、複数のプラットフォームに向けてコンパイルできるということで、かねてより興味は持っていたが、
Kubernetes に触れるようになったことでより勉強するモチベーションが上がっている。

とりあえず、Gopher 道場 を進めていこう。

おわりに

ひとまず現時点で考えている目標はこの程度。
今年を象徴するテーマとなるような、新しい趣味の目標がひとつほしいところ*1

*1:一昨年はカメラとDJ、昨年は一人暮らしをそれぞれはじめた。

今年のおしごと2020

来年はもう少しこまめにブログを書きたい。
今年のおしごとを四半期刻みで振り返ります。もちろん外に向けて書けるものだけ。

1月~3月

今年は昨年3月から引き続き、オンプレ向け自社製品デプロイツール開発として働いていました。
1~3月のお仕事は大きく2つ。

Amazon Corretto JRE のデプロイ機能開発

自社製品は Java で動いており、サーバにランタイムとして JRE を配置する必要がある。

そこで、デプロイ時に JRE の更新も自動で行いたいという需要が生まれたので、
ツールに対して新規機能として実装。

製品や環境ごとに JRE の配置先が違ったりするため、それらを吸収するためデプロイ先を任意に変更できるよう開発した。

Google Form と Slack の連携スクリプト作成

これは主務とは異なるタスクのため、合間を縫って*1*2実装していた。

お客様との窓口となるコンサルの、顧客訪問時の記録を Google Form で行うという施策において、
Slack に自動的に連携され、Slack 上で様々なやりとりをできるようにしたいという需要が生まれた。

Google Apps Script(GAS) をつかって、Form 送信時に Slack に自動通知される仕組みを作成した。

・・・というとあっという間に作れそうに思えるが、つらみポイントがいくつかあったので書いておこう。

Slack 通知の対象となるフォームが20以上ある

GAS には、Spreadsheet や Form などの Google Apps と紐付くスクリプトContainer-bound script)がある。 これをつかうと、Spreadsheet であれば編集時やシートを開いた時、Form であれば回答の送信時など、Apps 固有のイベントを手軽にスクリプトのトリガーとして利用できる。
そのため、フォーム送信時にスクリプトを発火させる場合は Container-bound script を使うのが都合がよいのだが、 20以上あるフォームそれぞれにこれを設定するのは実装コストも保守コストも爆上がりしてしまう。

そこで、Google Apps と紐付かないスクリプトStandalone script)に実装し、
外からイベントトリガーを定義することで、単一のスクリプトで複数のフォームのイベントを管理することとした。

具体的には、TriggerBuilderを使って各フォームごとにスクリプトからトリガーを定義した。
これによって、ひとつの関数を実行するだけですべてのフォーム送信イベントをトリガーとして定義できるようになったのだが、 ここでもう一つの問題が生じた。

1ユーザあたり、スクリプトに設定できるトリガーが20個までという制限

題通りなのだが、GAS にはあるスクリプトに設定できるトリガーの数に制限がある。
具体的には、20 トリガー/ユーザ の制限となる。ref: https://developers.google.com/apps-script/guides/services/quotas#current_limitations
そのため、20以上あるフォームに対してトリガーを1人で設定することが不可能なのである。

こればかりはどうひっくり返っても回避不可能なので、トリガーの設定を行う人を複数立て、
Google Spreadsheet にトリガー設定履歴を記録することとした。

この制限結構きついなあ。

そして

まあ、いくつかの面倒くさいポイントはあったものの、今でも元気にスクリプトは動いている。 どうもコンサル組織においてわりと重要な仕組みになっているようで、噂によると今年の秋時点で1万件以上の記録が Slack に連携されているみたいです。

4月~6月

この辺から在宅勤務が本格化。
実家には小さな折りたたみテーブルと MacBookPro しかないので、会社に比べて画面が小さく辟易した。

4~6月にやったことは以下の通り。

  • オンプレサーバーヘルスチェック機能開発
  • Qiita Organization に入った
  • 部内で LT? をした

オンプレサーバーヘルスチェック機能開発

オンプレサーバの物理マシンはデータセンターにあったりお客様先にあったりと、日頃のメンテナンスがおろそかになっていることがある。
その場合、ディスク等の枯渇が突然発生してシステムが正常に動かないトラブルが発生することがある。

そこで、開発しているツールにディスクと表領域のチェック機能を実装した。 ツールはWebアプリケーションとして動くため、チェック方法のわからない(スキルを持たない)人でも使えるよう、
ボタンをポチポチするだけでチェックできるよう実装した。

UI/UX には結構気を遣ったつもり。

Qiita Organization に入った

ついに弊社も Qiita に Organization を作ったらしいので参加した。
昔取った杵柄で、Contribution 数がちょっとあったので、参加したての頃は Organization の Contribution 数の大半をぼくが占めるということに。

今はあの記事とかあるので、全然たいしたことない。

部内で LT? をした

月次の全体ミーティングでは、持ち回りで LT をすることになっている*3
6月は私が担当だったので、これまでの1年ちょっとの経験から得られたサポートエンジニアとしての心構えを紹介した。

スライドは Internal な内容が多いので公開できないが、ざっくり以下のような内容を話した。

  • 問い合わせは回答スピードが命。
  • スピードは大事だが、回答の質も大事。
  • つまり、質とスピード*4を両立する必要がある。
  • そのために必要なことは以下の3つ
    • 事実と推測を区別する
    • ゴールを明確にイメージし、そこから逆算する
    • いち早く事実だけを積み重ねる

概ね好評だったようなので、いつか再放送できるといいなーと思っている。

7月~9月

先述の在宅勤務環境が耐えられなくなったことと、Stay Home によって少しお金が貯まったので、
これを機に一人暮らしを始めた。

この時期はあまり特筆すべきことがない。というか外に向けて書けることがない。

インターンのメンターをした

いわゆる「夏インターン」のメンターをした。
Withコロナということで、完全オンラインのインターンシップとなり、在宅にてZoomやSlackを活用したインターンであった*5

ぼく自身は学生時代にインターンに参加したことはなく、自社も通常の新卒採用での採用だったため、
そもそもインターン自体はじめてであった。

インターンは3日間行われ、その間学生のアウトプットのレビューをしたり、
Zoomのブレイクアウトセッションを使って行われているグループワークを見回ったりしていた。

初日のアウトプットを見たときは「大丈夫かこれ...というか3日でどうにかなるものなのか...???」と不安になったものだが、
終わってみるとどのグループもとてもよくできていて、なんというか感動した。

というか、(就職活動とはいえ)学生が真摯に課題に取り組む姿や、3日間を通して明らかに成長している姿を見て、
むしろ自分が学ぶことが多かったなという印象。

社会人も3年目に突入し、ある程度"惰性で"働くことができるようになってしまっているので、
この時の学生の取り組み方を折に触れて思い出し、自らの働き方を修正していきたいと思っている。

10月~12月

さて、記憶にも新しい最後の四半期。
10~12月にやったことは以下の通り。

  • Webマニュアルをリニューアルした
  • 副業を始めた
  • 引き継ぎをした

Webマニュアルをリニューアルした

開発しているツールのマニュアルは Web から参照できる Web マニュアルとして提供している。
このWebマニュアル、現在は Asciidoc を用いて作成されており、ここから HTML ドキュメントを生成している*6

Asciidoc はあまり利用することがなく、実際このマニュアルの作成以外では利用しない。
そのため、できれば Markdown でマニュアルを作りたいと思っており、合間を縫って*7マニュアルのリニューアルに取り組み始めた。

せっかくなので頑張ったポイントについて書いていこう。

MkDocs をつかった

マニュアルのベースとなるフォーマットを Asciidoc から Markdown に変更するにあたりもっとも大きな問題は、
Asciidoc に比べて Markdown は表現力に乏しいこと。

特に、Asciidoc における「ブロック」が一般的な Markdown では利用できないため、
警告や Tips などの情報の表現が難しい。

そこで、Markdown ベースの静的サイトジェネレータである MkDocs を利用した。
これは、Python-Markdown 拡張を利用でき、これによって通常の Markdown 以上の表現が可能となる。

また、サードパーティーテーマも豊富にあり、きれいなドキュメントを簡単に作成できる。
作成した Web マニュアルでは Material for MkDocs を利用した。

Remote - Containers をつかってマニュアル編集用の環境を整備した

MkDocs ドキュメントを編集する際は、ローカルに Python と MkDocs 関連の各種ライブラリといったものをインストールしなくてはならない。
これらの環境構築は往々にして社内ドキュメントに手順がまとめられるが、だいたいメンテナンスが漏れたり、環境依存のトラブルが発生する。

そのため、VSCode拡張機能 Remote - Containers をつかって、環境をコンテナ化することにした。
Remote - Containers は VSCode 自体もコンテナ上で動くため、VSCode 拡張機能も含めてパッケージ化できることが魅力。
MkDocs 編集環境をパッケージ化するため、MarkdownYAML 用の拡張機能も併せてパッケージ化した。

詳細はアドベントカレンダーとして Qiita にも書いたので、リンクを貼っておく。

qiita.com

副業を始めた

12月から副業を始めた。
副業はもともとする気がなかったのだが、会社の先輩が副業3つやってる話を聞いたこと、友人から副業の誘いを受けたことから、「1つくらいならできるかな?」と思い、開始。

内容としては Kubernetes を扱ってなんかしています(まだよくわかっていない)。
Kubernetes 自体、知ってはいたが利用するのははじめてなので、『Kubernetes 完全ガイド』 を写経しながら読み進めている。

来年は CKA, CKAD の取得を目指したい。

引き継ぎをした

さて、昨年3月からやってきたオンプレ向けデプロイツール開発であるが、2021年1月から別部署に異動が決定した。
そのため、12月後半は各種業務の引き継ぎを行っていた。

異動する身としては、仕事を新たに自分でやっても意味が無いと思い、なるべく自分から仕事をとらないようにしていた。
その結果として12月後半はめちゃくちゃ暇だった。

おわりに

というわけで、来年からは新しい部署で働くことになりました。
副業もどうなっていくのかわからないし、2021年は今のところまったく予測不可能です。 とりあえずフルリモートワークになることはほぼ確定だそうなので、いろいろアウトプットを増やしていけるといいなー。

*1:いわゆる「スカンクワーク」というやつなのだが、今の弊社においてこの文化は明文化されていない。悲しい。

*2:前職(?)の公式ウェブサイトを見ても今現在では明文化されていない。おい、どうしちまったんだ。

*3:LTといっても、10分程度なので少し長め

*4:© t_wada

*5:東洋経済に取材されたので掲載しておく

*6:AsciiDoctor を利用している。

*7:これもいわゆる「スカンクワーク」