kakakakakku blog

Weekly Tech Blog: Keep on Learning!

ytt を使ってテンプレートから YAML を生成する

記述したテンプレートから YAML を生成するツール 「ytt」 を試す.ytt は YAML に対して「テンプレート機能」「オーバーレイ機能」が使える.VMware 社を中心に開発されているツールセット Carvel に含まれている.

carvel.dev

YAML のテンプレート機能やオーバーレイ機能と言えば,特に Kubernetes の文脈だと KustomizeHelm が代表的だと思う.ytt も似たように使えるけど Kubernetes に限らず「汎用的に使える」というメリットがある.他にはテンプレート構文を含めても「YAML フォーマットとしては valid のまま」という点もメリットに挙げられると思う.汎用的に使えるということは,例えば AWS CloudFormation テンプレートを生成することにも活用できる.ytt と関連ツールの違いは以下のドキュメントに詳細に載っている.

carvel.dev

インストール

今回は Homebrew で macOS にインストールする.最新版 v0.41 を使う.

$ brew tap vmware-tanzu/carvel
$ brew install ytt
$ ytt version
ytt version 0.41.1

ドキュメントに載っている Shell Completion を設定すれば ytt コマンドの補完も使えるようになる.

$ ytt completion zsh > /usr/local/share/zsh/site-functions/_ytt

$ ytt [tab] 
completion  -- Generate the autocompletion script for the specified shell
fmt         -- Format YAML templates
help        -- Help about any command
template    -- Process YAML templates (deprecated; use top-level command -- e.g. `ytt -f-` instead of `ytt template -f-`)
version     -- Print version
website     -- Starts website HTTP server

carvel.dev

もし ytt をササッと試すならドキュメントに含まれている「Interactive Playground」を使うと便利!

ytt を試す : テンプレート機能

ytt では YAML のコメント記法 #@ を使ってテンプレートを記述する.そして ytt -f xxx.yaml のように ytt コマンドを実行すると YAML を生成できる.基本的な構文を試していく.

1. 変数

ytt YAML

#@ title = 'kakakakakku blog'
#@ author = 'kakakakakku'
#@ url = 'https://kakakakakku.hatenablog.com/'
blog:
  title: #@ title
  author: #@ author
  url: #@ url

生成した YAML

blog:
  title: kakakakakku blog
  author: kakakakakku
  url: https://kakakakakku.hatenablog.com/

2. if (boolean)

ytt YAML

#@ is_debug = True

#@ if is_debug:
debug: enabled
#@ else:
debug: disabled
#@ end

生成した YAML

debug: enabled

3. if (>=)

ytt YAML

#@ score = 70
#@ threshold = 80

#@ if score >= threshold:
result: pass
#@ else:
result: fail
#@ end

生成した YAML

result: fail

4. for (index)

ytt YAML

ids:
#@ for id in range(0, 5):
- #@ id + 1
#@ end

生成した YAML

ids:
- 1
- 2
- 3
- 4
- 5

5. for (value)

ytt YAML

users:
#@ for name in ['alice', 'bob', 'kakakakakku']:
- #@ name
#@ end

生成した YAML

users:
- alice
- bob
- kakakakakku

6. 関数

ytt YAML

#@ on_sale = True
#@ def price(x):
#@   if on_sale:
#@     return x * 0.7
#@   else:
#@     return x
#@   end
#@ end

price: #@ price(1000)

生成した YAML

price: 700

ytt を試す : オーバーレイ機能

オーバーレイ機能を使うと YAML を部分的に書き換えられる.例えば「プロダクション環境」「開発環境」で YAML の値を変えられる.そして ytt -f _config.yaml -f xxx.yaml のように ytt コマンドを実行すると YAML を生成できる.

1. 上書き

ytt YAML (template)

autoscaling:
  min: 1
  max: 1

ytt YAML (config)

#@ load("@ytt:overlay", "overlay")

#@overlay/match by=overlay.all
---
autoscaling:
  min: 5
  max: 20

生成した YAML

autoscaling:
  min: 5
  max: 20

2. 追加

ytt YAML (template)

users:
- admin

ytt YAML (config)

#@ load("@ytt:overlay", "overlay")

#@overlay/match by=overlay.all
---
users:
- prd-user1
- prd-user2
- prd-user3

生成した YAML

users:
- admin
- prd-user1
- prd-user2
- prd-user3

まとめ

記述したテンプレートから YAML を生成するツール 「ytt」 を使って基本的な「テンプレート機能」「オーバーレイ機能」を試した.Kubernetes に限らず「汎用的に使える」のは便利だと思う.そして簡単に使えるので導入自体もしやすいと思う.テンプレート構文を含めても「YAML フォーマットとしては valid のまま」なのもメリットだとは思うけど,YAML のコメント記法 #@ に依存している仕組みは複雑になりすぎると個人的にはちょっと可読性の観点でデメリットになりそうだと感じた.なお #@ に続いて書く擬似コードは Starlark に準拠している.

ytt のドキュメントを読んだら他にも多くの構文をサポートしていた.使えそうな機会があったら導入してみるぞ!

github.com

実験管理を便利に行う MLflow Tracking に入門した

実験管理やモデルレジストリなど,機械学習ライフサイクルをうまく管理するプラットフォームとして有名な「MLflow」に入門する.GitHub リポジトリの Star は 12000 もあってスゴイ!MLflow は MLOps の文脈でもよく聞くので,1度試しておこうと思った.

現在,MLflow には大きく「4種類」のコンポーネントがある.

  • MLflow Tracking : 実験管理 / ハイパーパラメータや評価メトリクスなどを記録したり比較できたりする
  • MLflow Projects : パッケージング / 機械学習を実行するための設定情報などを再現可能にする
  • MLflow Models : モデル化 / さまざまなデプロイツールをサポートする汎用的なモデル形式を提供する
  • MLflow Model Registry : モデルレジストリ / レジストリとしてモデルを管理する

github.com

MLflow Tutorial

今回は MLflow のドキュメントに載っている「Tutorial」「Quickstart」を参考にしながら,MLflow の中で基本となるコンポーネント「MLflow Tracking」を試す.ドキュメントを読みながら進めて,特にハマるところもなく試せた.

mlflow.org

mlflow.org

準備

準備として MLflow と scikit-learn をインストールする.さらに MLflow の GitHub リポジトリにある examples を使うため git clone もしておく.今回は macOS を使って環境を構築する.それぞれのバージョンは以下の通り.

  • MLflow : 1.26.1
  • scikit-learn : 1.1.1
$ pip install mlflow
$ pip install scikit-learn
$ git clone https://github.com/mlflow/mlflow

次に mlflow ui コマンドを実行して,実験結果を表示する画面を起動する.デフォルトでは http://127.0.0.1:5000/ で表示できる.準備 OK!

$ mlflow/examples
$ mlflow ui

MLflow 用語

今から出てくる MLflow 用語の関係性を以下にまとめておく.Experiment(実験)に複数の Run(実行)が紐付く.

  • Experiment(実験)
  • Run(実行)

MLflow Tracking サンプルコード

MLflow Tracking のイメージを掴むために,まず「Quickstart」に載っている quickstart/mlflow_tracking.py を実行する.コードのポイントは大きく3点ある.

  • log_param() 関数を使って「パラメータ : param1を登録する
  • log_metric() 関数を使って「メトリクス : fooを登録する
  • log_artifacts() 関数を使って「アーティファクト : test.txtを登録する
import os
from random import random, randint

from mlflow import log_metric, log_param, log_artifacts

if __name__ == "__main__":
    print("Running mlflow_tracking.py")

    log_param("param1", randint(0, 100))

    log_metric("foo", random())
    log_metric("foo", random() + 1)
    log_metric("foo", random() + 2)

    if not os.path.exists("outputs"):
        os.makedirs("outputs")
    with open("outputs/test.txt", "w") as f:
        f.write("hello world!")

    log_artifacts("outputs")

MLflow の関数は以下のドキュメントに詳細に載っている.

今回は「計3回」実行する.

$ python quickstart/mlflow_tracking.py
$ python quickstart/mlflow_tracking.py
$ python quickstart/mlflow_tracking.py

実行後に画面を更新すると実行結果を確認できる.また param1foo など登録したパラメータとメトリクスも一覧できる.

個別に実行を選択するとアーティファクトも確認できる.便利!

MLflow Tracking と scikit-learn を組み合わせる

次は「Tutorial」に載っている sklearn_elasticnet_wine/train.py を使って実践的なトレーニングを実行する.今回のお題として,ワインの品質を予測する.アルゴリズムとしては scikit-learn の ElasticNet を使って回帰分析をする.ハイパーパラメータとしては alpha(L1, L2 正規化項の合計)と l1_ratio(L1 正則化項の割合)を変えながらパフォーマンスを確認する.モデルの評価メトリクスとしては RMSE(二乗平均平方根誤差) を使う.

そして,今回は「Tutorial」の手順を一部変更する.そのまま実行すると Default Experiments に紐付くため,新しく sklearn-elasticnet-wine Experiments を作って紐付ける.今回は id=1 の Experiments になった.

import mlflow

experiment_id = mlflow.create_experiment('sklearn-elasticnet-wine')
print(experiment_id)

コードのポイントは大きく4点ある.その他のコードはデータセットを分割したり,scikit-learn を使ってトレーニングをしたり,一般的な機械学習コードそのものなので,紹介は割愛する.

  • 実行を sklearn-elasticnet-wine Experiments に紐付けるために mlflow.start_run()mlflow.start_run(experiment_id=1) に変更する
  • log_param() 関数を使って「ハイパーパラメータ : alphal1_ratioを登録する
  • log_metric() 関数を使って「メトリクス : rmser2maeを登録する
  • log_model() 関数を使って「モデル」を登録する
# The data set used in this example is from http://archive.ics.uci.edu/ml/datasets/Wine+Quality
# P. Cortez, A. Cerdeira, F. Almeida, T. Matos and J. Reis.
# Modeling wine preferences by data mining from physicochemical properties. In Decision Support Systems, Elsevier, 47(4):547-553, 2009.

import os
import warnings
import sys

import pandas as pd
import numpy as np
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
from sklearn.model_selection import train_test_split
from sklearn.linear_model import ElasticNet
from urllib.parse import urlparse
import mlflow
import mlflow.sklearn

import logging

logging.basicConfig(level=logging.WARN)
logger = logging.getLogger(__name__)


def eval_metrics(actual, pred):
    rmse = np.sqrt(mean_squared_error(actual, pred))
    mae = mean_absolute_error(actual, pred)
    r2 = r2_score(actual, pred)
    return rmse, mae, r2


if __name__ == "__main__":
    warnings.filterwarnings("ignore")
    np.random.seed(40)

    # Read the wine-quality csv file from the URL
    csv_url = (
        "http://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-red.csv"
    )
    try:
        data = pd.read_csv(csv_url, sep=";")
    except Exception as e:
        logger.exception(
            "Unable to download training & test CSV, check your internet connection. Error: %s", e
        )

    # Split the data into training and test sets. (0.75, 0.25) split.
    train, test = train_test_split(data)

    # The predicted column is "quality" which is a scalar from [3, 9]
    train_x = train.drop(["quality"], axis=1)
    test_x = test.drop(["quality"], axis=1)
    train_y = train[["quality"]]
    test_y = test[["quality"]]

    alpha = float(sys.argv[1]) if len(sys.argv) > 1 else 0.5
    l1_ratio = float(sys.argv[2]) if len(sys.argv) > 2 else 0.5

    with mlflow.start_run(experiment_id=1):
        lr = ElasticNet(alpha=alpha, l1_ratio=l1_ratio, random_state=42)
        lr.fit(train_x, train_y)

        predicted_qualities = lr.predict(test_x)

        (rmse, mae, r2) = eval_metrics(test_y, predicted_qualities)

        print("Elasticnet model (alpha=%f, l1_ratio=%f):" % (alpha, l1_ratio))
        print("  RMSE: %s" % rmse)
        print("  MAE: %s" % mae)
        print("  R2: %s" % r2)

        mlflow.log_param("alpha", alpha)
        mlflow.log_param("l1_ratio", l1_ratio)
        mlflow.log_metric("rmse", rmse)
        mlflow.log_metric("r2", r2)
        mlflow.log_metric("mae", mae)

        tracking_url_type_store = urlparse(mlflow.get_tracking_uri()).scheme

        # Model registry does not work with file store
        if tracking_url_type_store != "file":

            # Register the model
            # There are other ways to use the Model Registry, which depends on the use case,
            # please refer to the doc for more information:
            # https://mlflow.org/docs/latest/model-registry.html#api-workflow
            mlflow.sklearn.log_model(lr, "model", registered_model_name="ElasticnetWineModel")
        else:
            mlflow.sklearn.log_model(lr, "model")

今回はハイパーパラメータを変更しながら「計5回」実行する.

  • 実行 1. alpha=0.5 / l1_ratio=0.5
  • 実行 2. alpha=0.4 / l1_ratio=0.4
  • 実行 3. alpha=0.3 / l1_ratio=0.3
  • 実行 4. alpha=0.2 / l1_ratio=0.2
  • 実行 5. alpha=0.1 / l1_ratio=0.1
$ python sklearn_elasticnet_wine/train.py
Elasticnet model (alpha=0.500000, l1_ratio=0.500000):
  RMSE: 0.7931640229276851
  MAE: 0.6271946374319586
  R2: 0.10862644997792614

$ python sklearn_elasticnet_wine/train.py 0.4 0.4
Elasticnet model (alpha=0.400000, l1_ratio=0.400000):
  RMSE: 0.7644619587468349
  MAE: 0.5966303605775048
  R2: 0.17197111491474282

$ python sklearn_elasticnet_wine/train.py 0.3 0.3
Elasticnet model (alpha=0.300000, l1_ratio=0.300000):
  RMSE: 0.7443224557281489
  MAE: 0.5754825491733004
  R2: 0.2150247343683439

$ python sklearn_elasticnet_wine/train.py 0.2 0.2
Elasticnet model (alpha=0.200000, l1_ratio=0.200000):
  RMSE: 0.7336400911821402
  MAE: 0.5643841279275428
  R2: 0.23739466063584158

$ python sklearn_elasticnet_wine/train.py 0.1 0.1
Elasticnet model (alpha=0.100000, l1_ratio=0.100000):
  RMSE: 0.7128829045893679
  MAE: 0.5462202174984664
  R2: 0.2799376066653344

実行後に画面を更新すると実行結果を確認できる.実行結果は sklearn-elasticnet-wine Experiments に紐付いている.

MLflow では metrics.rmse < 0.74 のようなクエリを書くことで実行結果をフィルタできる.

クエリ構文は以下のドキュメントに詳細に載っている.

www.mlflow.org

さらに実行結果(今回だと5件)を選択して評価メトリクス RMSE を比較できる.

さらにハイパーパラメータと評価メトリクスの関係性も比較できる.以下の例では,ハイパーパラメータ alpha と評価メトリクス RMSE の関係性を比較している.

そして,アーティファクトを確認するとモデル model.pkl も含まれている.

モデルをデプロイして推論する

MLflow CLI で mlflow models serve コマンドを実行すると,指定したモデルをデプロイした推論エンドポイントを起動できる.

www.mlflow.org

今回は最も RMSE の値が低くパフォーマンスが高かった実行 e8901371a1494c34bd0a26e8180c5441 のモデルをデプロイする.アーティファクトからパスを取得して,以下のように実行する.

$ mlflow models serve -m file:///Users/kakakakakku/mlflow/examples/mlruns/1/e8901371a1494c34bd0a26e8180c5441/artifacts/model -p 1234

推論エンドポイント http://127.0.0.1:1234 に以下のように curl コマンドを実行すると推論結果を取得できる.mlflow models serve コマンドのログを眺めていたら HTTP Server は Gunicorn を使っていた.

$ curl -X POST -H 'Content-Type:application/json; format=pandas-split' http://127.0.0.1:1234/invocations\
  --data '{"columns":["alcohol", "chlorides", "citric acid", "density", "fixed acidity", "free sulfur dioxide", "pH", "residual sugar", "sulphates", "total sulfur dioxide", "volatile acidity"],"data":[[12.8, 0.029, 0.48, 0.98, 6.2, 29, 3.33, 1.2, 0.39, 75, 0.66]]}' 
[10.652032783691832]

$ curl -X POST -H 'Content-Type:application/json; format=pandas-split' http://127.0.0.1:1234/invocations\
  --data '{"columns":["alcohol", "chlorides", "citric acid", "density", "fixed acidity", "free sulfur dioxide", "pH", "residual sugar", "sulphates", "total sulfur dioxide", "volatile acidity"],"data":[[15.8, 0.029, 0.48, 0.98, 6.2, 29, 3.33, 1.2, 0.39, 75, 0.66]]}' 
[10.83593352318585]

まとめ

今回は MLflow のドキュメントに載っている「Tutorial」「Quickstart」を参考にしながら,MLflow の中で基本となるコンポーネント「MLflow Tracking」を試した.実験管理がしやすく便利だった.他にもグラフ画像などを登録する log_figure() 関数や簡単にパラメータとメトリクスを登録する Automatic Logging など,まだまだ気になる機能がある.引き続き試していくぞ!

www.mlflow.org

CKS 対策にもおすすめ /「Docker/Kubernetes 開発・運用のためのセキュリティ実践ガイド」を読んだ

コンテナワークロードにおけるセキュリティ対策の理解を深めるため「Docker/Kubernetes 開発・運用のためのセキュリティ実践ガイド」を読んだ.実は本書は 2021年7月頃 に1度読み終わっていたけど,実際に気になった部分を試したり,CKS (Certified Kubernetes Security Specialist) を受験 しながら読み直していたら書評記事をまとめるのが遅れてしまった (;・∀・)

本書を読んで1番良かったと感じるのは「セキュリティに関して "知らなかったことに気付けた"」ことだと思う.苦手意識のあるセキュリティ領域に対して「視野を広げる」ことができた.本当に読んで良かったと思うし,何よりも「日本語で」読めることに感謝しかない!本書は 2020年2月 に出版されていて,Kubernetes 1.16.1 を前提にしていたり,ランタイムなども含めて多少のアップデートはあると思うので,もし今後「第2版」で更新されるなら絶対に読み直したい!

目次

  • 第1章「Docker/Kubernetes のおさらい」
    • 1.1 Docker の復習
    • 1.2 Kubernetes の復習
  • 第2章「コンテナ運用における脅威の事例」
    • 2.1 API エンドポイントの設定ミス
    • 2.2 ランタイムやカーネルの脆弱性
    • 2.3 イメージの脆弱性
  • 第3章「ランタイムのセキュリティ Tips」
    • 3.1 Docker API エンドポイントを保護する
    • 3.2 コンテナ実行ユーザを変更する
    • 3.3 ケーパビリティやシステムコールを制限する
    • 3.4 ファイルアクセスを制御する
    • 3.5 リソースを制限する
    • 3.6 代替ランタイムを利用する
    • 3.7 コンテナを監視する
    • 3.8 設定を検証する
  • 第4章「イメージのセキュリティTips」
    • 4.1 Dockerfile からプライベートな Git や S3 にアクセスする
    • 4.2 コンテナ内で安全にイメージをビルドする
    • 4.3 イメージの脆弱性を検査する
    • 4.4 改竄されたイメージのデプロイを防ぐ
    • 4.5 プライベートレジストリを構築する (Harbor)
  • 第5章「Kubernetes クラスタのセキュリティ Tips」
    • 5.1 クラスタを最新の状態に保つために
    • 5.2 ミスや攻撃から守る API のアクセス制御
    • 5.3 認証モジュールの選び方と使い方
    • 5.4 Service Account によるサービス認証とアカウント管理
    • 5.5 認可モジュールの種類と利用方法
    • 5.6 Admission コントローラによる柔軟なアクセス制御
    • 5.7 Webhook で独自の Admission Control を追加する
    • 5.8 システムコンポーネント間通信の保護
    • 5.9 スケジューラによる割り当てノードの制御
    • 5.10 秘密情報を管理する
    • 5.11 GitOps のための Secret 管理
  • 第6章「アプリケーション間通信を守る」
    • 6.1 Network Policy を使って Pod の通信を制御する
    • 6.2 Istio を使って Pod 間の通信を守る
    • 6.3 SPIFFE によるアプリケーションの認証
    • 6.4 クラスタ外部との通信を守る

正誤表は以下に載っている.

book.mynavi.jp

第1章「Docker/Kubernetes のおさらい」

第1章では Docker と Kubernetes の基本的な仕組みを学べる.cgroupnamespace など理解があやふやになっている部分を重点的に読んだ.また個人的に苦手意識のある TLS (Transport Layer Security) の復習にもなって良かった.例えば CKS (Certified Kubernetes Security Specialist) を受験するときに CSR (Certificate Signing Requests) 関連も出題されるし,本書の「第5章」にも関連する内容が出てくる.

👉 試した記事 📝

第2章「コンテナ運用における脅威の事例」

第2章ではコンテナワークロードでのさまざまな「セキュリティ脅威」を学べる.実際に「CVE 識別番号」も載っていて,被害を想像すると怖い〜😱となった.例えば Docker / Kubernetes の設定ミスもあれば,コンテナランタイムや Kubernetes コンポーネントの脆弱性もある.改めて,セキュリティ意識を高めておこう!と思える「第2章」だった.

第3章「ランタイムのセキュリティ Tips」

第3章では Docker コンテナや Kubernetes Pod を安全に実行するための Tips を学べる.具体的には「seccomp(不要なシステムコールを制限する)」「AppArmor(ファイル操作などを制限する)」「Falco(コンテナワークロードの脅威を検出する)」などなど.他にも Security Context に関連する Tips もあり,気になった点は積極的に試して理解を深めた.

kubernetes.io

👉 試した記事 📝

第4章「イメージのセキュリティTips」

第4章ではコンテナイメージに特化した Tips を学べる.ビルドツールの「BuildKit」や脆弱性検査ツールの「Clair」「Trivy」などが紹介されている.日頃からDockerfile ベストプラクティスは意識しているけど,今まで使ったことがなかったツールなども知れて良かった.本書に載っていないけど関連する話題としては「ヒアドキュメント構文」のサポートや「hadolint」を使った Dockerfile の静的解析もあるかなーと.

👉 試した記事 📝

第5章「Kubernetes クラスタのセキュリティ Tips」

第5章では Kubernetes クラスタに関連するセキュリティを学べる.とは言っても内容は本当に幅広く,Cloud Native Security の「4C (Cloud / Clusters / Containers / Code)」という多層防御アプローチの説明もあるし,「認証・認可・Admission Controller」「Service Account」「秘密情報 (Secrets / CSI : Container Storage Interface)」なども詳細に解説されている.トピックはまだまだ他にもあって目次を見てもらえればと!個人的に苦手意識のある「認証・認可」の理解を深められた点と,多すぎて全体把握ができていなかった「Admission Controller」を整理できた点は「第5章」を読んだメリットとして印象に残っている.

kubernetes.io

👉 試した記事 📝

第6章「アプリケーション間通信を守る」

第6章では「Network Policy」「Istio を使った通信制御」など,アプリケーション間通信に関するセキュリティを学べる.またアプリケーション間通信の仕様でもある SPIFFE (Secure Production Identity Framework for Everyone) も解説されている.

📝 試した記事

まとめ

「Docker/Kubernetes 開発・運用のためのセキュリティ実践ガイド」を読んだ.本書を読んで「セキュリティに関して "知らなかったことに気付けた"」ことに価値があった.コンテナワークロードにおけるセキュリティ対策の理解を深めるために本書はおすすめだし,CKS (Certified Kubernetes Security Specialist) 対策としてもおすすめ!

関連記事

CKS (Certified Kubernetes Security Specialist) を受験するなら以下の記事も合わせて読んでもらえるとー 📝

kakakakakku.hatenablog.com

Kubernetes 関連のエントリー資格 KCNA (Kubernetes and Cloud Native Associate) に合格した

CNCF (Cloud Native Computing Foundation) の Kubernetes 関連資格 KCNA (Kubernetes and Cloud Native Associate) に合格した!

ついに「4冠」になったー 🎉

まだまだ KCNA の日本語情報は少なく,資格の普及も兼ねて紹介記事としてまとめておこうと思う.

www.cncf.io

前提と結果 ☸️

僕自身は技術講師として研修で Kubernetes と Amazon EKS を教える機会があったり,既に Kubernetes 資格 CKAD (Certified Kubernetes Application Developer)CKA (Certified Kubernetes Administrator)CKS (Certified Kubernetes Security Specialist) も取得している.よって,本資格の受験対象からズレている可能性もある.資格対策はあまりしてなく,2日間ほど(実際には4,5時間)出題範囲を見直した程度だけど,そこそこ高得点が取れた.って,4問も間違えてる... (;・∀・)

受験日 試験名 得点 結果
2022/06/01 KCNA (Kubernetes and Cloud Native Associate) 93 点 合格

技術講師として,今後 Kubernetes や Cloud Native を学び始めるお客様に「おすすめできる資格なのかどうか」を確認したくて受験することにした.あと少し「資格コレクター」精神もある.

KCNA (Kubernetes and Cloud Native Associate) ☸️

KCNA2021年11月 にリリースされた資格で「Kubernetes にフォーカスした Cloud Native の概念的な理解を証明する」エントリー資格と言える.まだリリースされて半年ほどなので,CKADCKACKS と比較すると,日本での認知度は低いのかもしれない.

  • 問題数 : 60問(選択式)
  • 制限時間 : 90分
  • 合格点 : 75%
  • 言語 : 英語(あくまで 2022年6月 時点)

以下のリリース記事には「マーケティングからマネージャまで,誰もが用語とコアテクノロジーの概念を理解することにメリットがある(意訳)」「CKA / CKAD / CKS などの CNCF 資格をさらに追求するための道を開く(意訳)」と書いてある.Kubernetes や Cloud Native をより知ってもらうための資格として,従来のように Kubernetes クラスタを操作する実務試験ではなく「選択式」になっているんだと思う.

www.cncf.io

出題範囲 ☸️

カリキュラム(出題範囲)は GitHub に PDF として公開されている.

github.com

出題範囲 PDF を確認すると Kubernetes FundamentalsContainer Orchestration の比率が高いことがわかる.他にも「オブザーバビリティ」「アプリケーションデリバリー」など,概念としては幅広く出題される.よって,選択式の資格とは言え,Kubernetes やエコシステムの経験がないとそれなりに準備が必要になると思う.

Domain Detail Weight
Kubernetes Fundamentals - Kubernetes Resources
- Kubernetes Architecture
- Kubernetes API
- Containers
- Scheduling
46%
Container Orchestration - Container Orchestration Fundamentals
- Runtime
- Security
- Networking
- Service Mesh
- Storage
22%
Cloud Native Architecture - Cloud Native Architecture Fundamentals
- Autoscaling
- Serverless
- Community and Governance
- Personas
- Open Standards
16%
Cloud Native Observability - Telemetry & Observability
- Prometheus
- Cost Management
8%
Cloud Native Application Delivery - Application Delivery Fundamentals
- GitOps
- CI/CD
8%

勉強方法 ☸️

1. 出題範囲をより深く把握する

出題範囲をより深く把握するために GitHub に公開されている情報に一通り目を通した.具体的には以下の 2 リポジトリを参考にして,特に moabukar/Kubernetes-and-Cloud-Native-Associate-KCNA はよくまとまっていた.用語集や関連リンク集やサンプル問題も載っていて参考になった.個人的には Kubernetes リソースや Kubernetes コンポーネント,そして関連するエコシステムはどれもある程度は経験があり,基本的には理解できていると感じた.

github.com

github.com

他にも CNCF Serverless Whitepaper v1.0Cloud Native Glossary も参考になる!一度読んでおくと良いと思う.

github.com

github.com

2. A Cloud Guru で模擬テストを受験する

A Cloud Guru「Kubernetes and Cloud Native Associate (KCNA)」で, Practice Exam(60 問 x 2 回)を中心に使った.最初から 90% 以上は正解できたので,間違えたり,悩んだりした問題に関連する e-Learning をザッと観た.

A Cloud Guru の e-Learning に出てきて,個人的にあまり経験がなかった技術(やサービスなど)を以下にまとめておく.

  • 環境変数を使ったサービスディスカバリ
  • Selector なし Service
  • Rook
  • FinOps(Financial Operation : 財務と運用を組み合わせた思想)

「環境変数を使ったサービスディスカバリ」に関しては実際に試してブログ記事にまとめた.

kakakakakku.hatenablog.com

英語受験 ☸️

現時点(2022年6月 時点)で KCNA「英語のみ」での受験となる.CKADCKACKS と同じく将来的には日本語もサポートされるとは思うけど,特に情報はなかった.もしかしたら「英語だから諦めよう...⚡」という人もいるかもしれないけど,個人的な感想だと「最低限読める」なら問題ないと思う!

まず,試験監督員との受験前のやり取りは全て「チャット」だった.本人確認や部屋の撮影は事前に済ませているため「飲み物を机の上に置くなら見せて?」と言われた程度だった.受験中も問題文や選択肢は比較的短く,多くは馴染みのある技術用語ということもあり,そこまで不安に感じなくて良いと思う.正直言えば,数問は英語の解釈ができずに間違えてしまった可能性もあるけど!笑

注意点は PSI Secure Browser という専用アプリを使って受験するため,Google 翻訳の Chrome 拡張を使うという従来の Tips(僕自身は未経験だけど調べると CKS などで使った人がいそうだった)は使えなかった.

受験後のフィードバックに「日本語をサポートすると受験者が増えると思うよー!」と書いておいた😃

まとめ ☸️

KCNA (Kubernetes and Cloud Native Associate) に合格した.

「4冠」になったー 🎉

CNCF のリリース記事にも載っていた通り,ソフトウェアエンジニアに限らず,最近「Kubernetes や Cloud Native という言葉をよく聞くから気になるなぁー」と感じる人におすすめできる資格だった!個人的にも「Serverless とは何?」など,改めて考え直す機会になって良かった.

もし未経験から受験を検討する場合は「Kubernetes 完全ガイド 第2版」を読むのも効果的だと思う.

おまけ : Prometheus Certified Associate (PCA) ☸️

2週間前(5月18日)にさらに新しい資格 PCA (Prometheus Certified Associate) が発表されていた!

これも気になるから受験を検討するぞー!日本語キボンヌ!

www.cncf.io

関連記事

kakakakakku.hatenablog.com

kakakakakku.hatenablog.com

Kubernetes の Service で「環境変数」を使ったサービスディスカバリを試す

Kubernetes の Service ドキュメントを読み直していたら「サービスディスカバリ」のモードとして「環境変数」「DNS」をサポートしていると書いてあった.一般的によく使うのは「DNS」{ServiceName}.{NamespaceName}.svc.cluster.local というレコードで名前解決できる.今回は「環境変数」を試すぞー💪

kubernetes.io

検証環境は以下の通り.

  • Kubernetes v1.23.0

準備をする

まず準備として backend1 アプリケーション (Service + Deployment) と backend2 アプリケーション (Service + Deployment) を適当に作る.作ったら backend1 Service と backend2 Service の ClusterIP を確認しておく.

$ kubectl create deployment backend1 --image nginx:1.21 --replicas 3
$ kubectl expose deployment backend1 --port 80

$ kubectl create deployment backend2 --image nginx:1.21 --replicas 3
$ kubectl expose deployment backend2 --port 80

$ kubectl get services
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
backend1     ClusterIP   10.97.227.158   <none>        80/TCP    30s
backend2     ClusterIP   10.98.163.125   <none>        80/TCP    20s
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP   25d

環境変数を確認する

次に frontend アプリケーション (Pod) を作る.Pod の中で printenv コマンドを使って環境変数を確認すると BACKEND1_SERVICE_HOSTBACKEND2_SERVICE_HOST などサービスディスカバリをしたサービス情報が自動的に設定されている!よって,環境変数の値を使ってサービスに接続できる💡

なるほどー!

$ kubectl run frontend --image nginx:1.21

$ kubectl exec -it frontend -- printenv | grep BACKEND | sort
BACKEND1_PORT=tcp://10.97.227.158:80
BACKEND1_PORT_80_TCP=tcp://10.97.227.158:80
BACKEND1_PORT_80_TCP_ADDR=10.97.227.158
BACKEND1_PORT_80_TCP_PORT=80
BACKEND1_PORT_80_TCP_PROTO=tcp
BACKEND1_SERVICE_HOST=10.97.227.158
BACKEND1_SERVICE_PORT=80
BACKEND2_PORT=tcp://10.98.163.125:80
BACKEND2_PORT_80_TCP=tcp://10.98.163.125:80
BACKEND2_PORT_80_TCP_ADDR=10.98.163.125
BACKEND2_PORT_80_TCP_PORT=80
BACKEND2_PORT_80_TCP_PROTO=tcp
BACKEND2_SERVICE_HOST=10.98.163.125
BACKEND2_SERVICE_PORT=80

注意点としては Service オブジェクトの「作成順序」に依存している点で,あくまで Pod を起動したときに存在するサービスディスカバリ結果を環境変数に設定する仕組みになっている.

以下に構成図をまとめた!

spec.enableServiceLinks: false で無効化する

自動的に環境変数が設定されるのは良さそうだけど,オブジェクトの「作成順序」に依存していることを考慮すると使いにくそうに感じる.実際にどういうときに積極的に使うんだろう❓

そこで,もし環境変数を使う予定がなかったり,不要な環境変数を設定したくないときは Pod の spec.enableServiceLinks: false で無効化できる.以下のように spec.enableServiceLinks: false を追加したマニフェストを作る.

apiVersion: v1
kind: Pod
metadata:
  name: frontend
spec:
  enableServiceLinks: false
  containers:
  - name: frontend
    image: nginx:1.21

もう1度 frontend アプリケーション (Pod) を作る.Pod の中で printenv コマンドを使って環境変数を確認すると,今度は設定されていなかった.ちゃんと無効化できた💡

なるほどー!

$ kubectl apply -f frontend.yaml

$ kubectl exec -it frontend -- printenv | grep BACKEND | sort