Введение
Функциональность Kubernetes можно расширять с помощью новых типов ресурсов. Объект CustomResourceDefinition (обычно называемый CRD) регистрирует новый API-ресурс в API-сервере Kubernetes. После этого вы можете использовать привычные команды kubectl для создания, получения, описания, добавления меток и внесения изменений в объекты этого нового типа.
В этой лабораторной работе вы создадите небольшой CRD с областью видимости в пространстве имен (namespaced) под названием AppProfile, обнаружите его с помощью команд API Kubernetes, создадите пользовательские ресурсы из YAML-файлов и обновите их так же, как обычные объекты Kubernetes. Для этой лабораторной работы не требуется контроллер; основное внимание уделяется пониманию того, как появляются пользовательские типы ресурсов и как работать с их объектами.
Подготовка пространства имен для пользовательских ресурсов
На этом этапе вы подготовите чистое пространство имен для практики работы с пользовательскими ресурсами.
Начните работу в директории /home/labex/project. В этой директории вы будете создавать CRD и манифесты пользовательских ресурсов.
mkdir -p /home/labex/project
cd /home/labex/project
Проверьте, доступен ли API-сервер Kubernetes. Если виртуальная машина только что запустилась и узел еще не готов, подождите несколько секунд и выполните команду снова.
kubectl get nodes --request-timeout=5s
Ожидаемый вывод включает:
NAME STATUS ROLES AGE VERSION
labex-v135 Ready control-plane ... v1.35...
Дождитесь готовности пода сетевого взаимодействия кластера, прежде чем создавать объекты приложений.
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
На этом этапе вы создадите CustomResourceDefinition с именем AppProfile.
CRD имеет два важных уровня именования. 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, чтобы прочитать схему, которую Kubernetes получил из CRD. Поле 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, которые вы уже применяете для встроенных объектов.
Внесите изменения (patch) в пользовательский ресурс frontend, чтобы изменить количество реплик. Опция --type=merge указывает Kubernetes объединить ваш JSON-объект с существующим, вместо того чтобы полностью заменять ресурс.
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:
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, дождались его установки, обнаружили новый API-ресурс с помощью kubectl api-resources и kubectl explain, создали пользовательские ресурсы, обновили их, выполнили выборку по меткам и использовали сокращенное имя. Это те же операционные навыки, которые вам понадобятся при выполнении задач CKAD, связанных с ресурсами, установленными операторами, контроллерами или расширениями платформы.


