はじめに
Kubernetes は、新しいリソースタイプを追加することで機能を拡張できます。CustomResourceDefinition(通常は CRD と呼ばれます)は、新しい API リソースを Kubernetes API サーバーに登録する仕組みです。CRD を登録すると、使い慣れた kubectl コマンドを使用して、その新しいタイプのリソースを作成、取得、詳細表示、ラベル付け、パッチ適用などが可能になります。
この実験では、AppProfile という名前の小さな名前空間スコープの CRD を作成します。その後、Kubernetes の API 探索コマンドを使用してそのリソースを確認し、YAML からカスタムリソースを作成し、通常の Kubernetes オブジェクトと同様に更新する方法を学びます。この実験ではコントローラーは不要です。カスタムリソースタイプがどのように表示され、どのように操作するかを理解することに焦点を当てます。
カスタムリソース用の名前空間の準備
このステップでは、カスタムリソースの練習用にクリーンな名前空間を準備します。
/home/labex/project から開始します。このディレクトリ内に CRD とカスタムリソースのマニフェストを作成します。
mkdir -p /home/labex/project
cd /home/labex/project
Kubernetes API サーバーに接続できるか確認します。VM が起動した直後でノードの準備ができていない場合は、数秒待ってから再度コマンドを実行してください。
kubectl get nodes --request-timeout=5s
期待される出力例:
NAME STATUS ROLES AGE VERSION
labex-v135 Ready control-plane ... v1.35...
アプリケーションオブジェクトを作成する前に、クラスターネットワークの Pod が Ready 状態になるまで待ちます。
kubectl wait --namespace kube-system --for=condition=Ready pod -l k8s-app=calico-node --timeout=120s
期待される出力:
pod/calico-node-... condition met
ckad-prep-customresources という名前の名前空間を作成します。
kubectl create namespace ckad-prep-customresources
この名前空間を現在のコンテキストの名前空間として設定します。
kubectl config set-context --current --namespace=ckad-prep-customresources
現在の名前空間を確認します。
kubectl config view --minify --output 'jsonpath={..namespace}'; echo
期待される出力:
ckad-prep-customresources
CRD による新しいリソースタイプの登録
このステップでは、AppProfile という名前の CustomResourceDefinition を作成します。
CRD には 2 つの重要な命名レイヤーがあります。metadata.name は、複数形のリソース名と API グループを組み合わせたもの(例:appprofiles.training.labex.io)です。spec.names セクションでは、ユーザーがそのリソースをどのように参照するかを定義します(kind: AppProfile、plural: appprofiles、singular: appprofile、および省略名 appprof)。
app-profile-crd.yaml を作成します。
cat > app-profile-crd.yaml <<'EOF'
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: appprofiles.training.labex.io
spec:
group: training.labex.io
scope: Namespaced
names:
plural: appprofiles
singular: appprofile
kind: AppProfile
shortNames:
- appprof
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
required:
- image
- replicas
properties:
image:
type: string
replicas:
type: integer
minimum: 1
tier:
type: string
EOF
CRD を適用します。
kubectl apply -f app-profile-crd.yaml
期待される出力:
customresourcedefinition.apiextensions.k8s.io/appprofiles.training.labex.io created
API サーバーが CRD を「Established(確立済み)」と報告するまで待ちます。
kubectl wait --for=condition=Established crd/appprofiles.training.labex.io --timeout=120s
期待される出力:
customresourcedefinition.apiextensions.k8s.io/appprofiles.training.labex.io condition met
CRD の名前とスコープを確認します。
kubectl get crd appprofiles.training.labex.io -o 'jsonpath={.spec.names.kind}{" "}{.spec.names.plural}{" "}{.spec.scope}{"\n"}'
期待される出力:
AppProfile appprofiles Namespaced
カスタムリソースの発見と作成
このステップでは、新しいリソースタイプを発見し、最初の AppProfile を作成します。
kubectl api-resources は、API サーバーが認識しているリソースタイプを一覧表示します。CRD が確立されると、組み込みのリソースタイプと並んでこの探索結果に表示されます。
kubectl api-resources --api-group=training.labex.io
期待される出力例:
NAME SHORTNAMES APIVERSION NAMESPACED KIND
appprofiles appprof training.labex.io/v1 true AppProfile
kubectl explain を使用して、CRD から Kubernetes が学習したスキーマを読み取ります。spec フィールドには、アプリケーション固有の設定が含まれます。
kubectl explain appprofile.spec
期待される出力例:
GROUP: training.labex.io
KIND: AppProfile
VERSION: v1
FIELD: spec <Object>
frontend-profile.yaml を作成します。
cat > frontend-profile.yaml <<'EOF'
apiVersion: training.labex.io/v1
kind: AppProfile
metadata:
name: frontend
labels:
app.kubernetes.io/part-of: storefront
tier: web
spec:
image: nginx:1.27
replicas: 2
tier: web
EOF
カスタムリソースを適用します。
kubectl apply -f frontend-profile.yaml
期待される出力:
appprofile.training.labex.io/frontend created
複数形名を使用してカスタムリソースを一覧表示します。
kubectl get appprofiles
期待される出力例:
NAME AGE
frontend ...
jsonpath を使用してカスタムリソースからフィールドを読み取ります。
kubectl get appprofile frontend -o 'jsonpath={.spec.image}{" "}{.spec.replicas}{" "}{.spec.tier}{"\n"}'
期待される出力:
nginx:1.27 2 web
カスタムリソースの更新と選択
このステップでは、組み込みオブジェクトに対して既に使用しているのと同じ kubectl パターンでカスタムリソースを管理します。
frontend カスタムリソースにパッチを適用し、希望するレプリカ数を変更します。--type=merge オプションは、リソース全体を置き換えるのではなく、JSON オブジェクトを既存のオブジェクトにマージするように Kubernetes に指示します。
kubectl patch appprofile frontend --type=merge -p '{"spec":{"replicas":3}}'
期待される出力:
appprofile.training.labex.io/frontend patched
更新された値を確認します。
kubectl get appprofile frontend -o 'jsonpath={.spec.replicas}{"\n"}'
期待される出力:
3
worker という名前の 2 つ目のカスタムリソースを作成します。
cat > worker-profile.yaml <<'EOF'
apiVersion: training.labex.io/v1
kind: AppProfile
metadata:
name: worker
labels:
app.kubernetes.io/part-of: storefront
tier: worker
spec:
image: busybox:1.36
replicas: 1
tier: worker
EOF
kubectl apply -f worker-profile.yaml
期待される出力:
appprofile.training.labex.io/worker created
storefront アプリケーションに属するカスタムリソースのみを一覧表示します。カスタムリソースは通常の Kubernetes ラベルをサポートしているため、これが可能です。
kubectl get appprofiles -l app.kubernetes.io/part-of=storefront
期待される出力例:
NAME AGE
frontend ...
worker ...
省略名 appprof を使用して、各リソース名とレプリカ数を表示します。
kubectl get appprof -o 'jsonpath={range .items[*]}{.metadata.name}{"="}{.spec.replicas}{"\n"}{end}'
期待される出力例:
frontend=3
worker=1
まとめ
CRD を作成し、それが確立されるのを待ち、kubectl api-resources と kubectl explain を使用して新しい API リソースを発見し、カスタムリソースを作成し、パッチを適用し、ラベルで選択し、省略名を使用する方法を学びました。これらは、CKAD 試験において、オペレーター、コントローラー、またはプラットフォーム拡張機能によってインストールされたリソースを扱う際に必要となる操作スキルと同じです。


