Я не понимаю, зачем кубернетам нужен селектор модулей в операторе развертывания, который может содержать только один шаблон модуля? Не стесняйтесь объяснить мне, почему инженеры Kubernetes ввели оператор выбора внутри определения развертывания вместо автоматического выбора модуля из шаблона?
---
apiVersion: v1
kind: Service
metadata:
name: grpc-service
spec:
type: LoadBalancer
ports:
- name: grpc
port: 8080
targetPort: 8080
protocol: TCP
selector:
app: grpc-test
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: grpc-deployment
spec:
replicas: 1
revisionHistoryLimit: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 0
selector:
matchLabels:
app: grpc-test
template:
metadata:
labels:
app: grpc-test
spec:
containers:
...
Почему бы просто не определить что-то подобное?
---
apiVersion: v1
kind: Service
metadata:
name: grpc-service
spec:
type: LoadBalancer
ports:
- name: grpc
port: 8080
targetPort: 8080
protocol: TCP
selector:
app: grpc-test
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: grpc-deployment
spec:
replicas: 1
revisionHistoryLimit: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 0
template:
metadata:
labels:
app: grpc-test
spec:
containers:
...

Насколько мне известно, селектор в развертывании является необязательным свойством.
шаблон - единственное обязательное поле спецификация.
Итак, вам не нужно использовать селектор ярлыков в развертывании, и в вашем примере я не понимаю, почему вы не могли использовать последнюю часть?
Если в template.metadata определены 2 метки, должны ли мы определить все метки в селекторе? спецификация: реплики: 1 шаблон: метаданные: метки: приложение: foo-bar elastic-instance: foo
Ах! Как ни странно, я как-то пытался осмыслить концепцию селекторов меток и раньше. Итак, поехали ...
Во-первых, для чего, черт возьми, используются эти ярлыки? Ярлыки в кубернетах являются основным средством идентификации объектов. Контроллер управляет модулями на основе их меток, а не имени. В этом конкретном случае они, например, предназначены для идентификации модулей, принадлежащих к набору реплик развертывания.
На самом деле вам не нужно было неявно определять .spec.selector при использовании расширений v1beta1. В этом случае это будет дефолт от .spec.template.labels. Однако, если вы этого не сделаете, вы можете столкнуться с проблемами с kubectl apply после того, как одна или несколько меток, которые используются для выбора изменения, потому что kubeclt apply будет смотреть на kubectl.kubernetes.io/last-applied-configuration при сравнении изменений, и эта аннотация будет содержать только ввод пользователя, когда он создал ресурс и ни одно из полей по умолчанию. Вы получите сообщение об ошибке, потому что он не может вычислить разницу, например:
spec.template.metadata.labels: Invalid value: {"app":"nginx"}: `selector` does not match template `labels`
Как видите, это довольно большой недостаток, поскольку он означает, что вы не можете изменить какие-либо метки, которые используются в качестве метки селектора, иначе это полностью нарушит процесс развертывания. Это было «исправлено» в apps/v1beta2, требуя явного определения селекторов, что запретило изменение этих полей.
Итак, в вашем примере вам на самом деле не нужно их определять! Создание будет работать и будет использовать ваш .spec.template.labels по умолчанию. Но да, в ближайшем будущем, когда вам нужно будет использовать v1beta2, это поле станет обязательным. Я надеюсь, что это ответит на ваш вопрос, и я не сделал его более запутанным;)
Пришел сюда через Google, и я не нашел этот ответ очень удовлетворительным. Я полностью понимаю мотивацию использования меток со службами, селекторами узлов и т. д. Однако Kubernetes предписывает, чтобы сам шаблон модуля соответствовал селектору, поэтому он может быть только более свободным, чем назначенные метки. Однако эта свобода не имеет значения, поскольку она также предписывает, что селекторы развертывания в пространстве имен не должны перекрываться. Итак, актуальный вопрос: почему даже есть свобода указывать селектор, а не принудительно создавать автоматически сгенерированные метку и селектор модуля, такие как owning-deployment=<deployment-uid>?
Вопрос заключался в том, какова цель метки селектора и почему она якобы требуется в спецификации развертывания. Думаю, я ответил на этот вопрос. Что касается вашего вопроса, селекторы меток не предназначены для обеспечения уникальности, это то, для чего нужен UID. Они предоставляют только средства для группировки объектов. И эти объекты не обязательно должны быть уникальными в своем роде. Но да, в этом случае действительно нет особого смысла в том, чтобы настраивать его и открывать для человеческой ошибки, поскольку вы не хотите, чтобы ваше развертывание контролировало больше модулей, чем те, которые указаны в вашей спецификации.
@ToonLamberigts, можете ли вы предоставить ссылки на официальную документацию Kubernetes, где явно указано, для каких API-интерфейсов использование селектора matchLabels является обязательным и почему?
@ToonLamberigts, вопрос не в этом. OP также говорит, что селектор является обязательным и имеет только одно возможное значение, и поэтому он должен автоматически генерироваться кубернетами, а не просить пользователя дублировать информацию. Итак, вопрос OP заключается в том, почему требуется, чтобы селектор был определен явно, когда единственное возможное определение селектора - это метки в шаблоне. Ваш ответ определенно не отвечает на этот вопрос.
@ Оливер, возможно, ты захочешь еще раз прочитать мой ответ. Они сделали поля селектора обязательными, чтобы запретить для них мутацию.
«поскольку вы не хотите, чтобы ваше развертывание управляло большим количеством модулей, чем указано в вашей спецификации» - @ToonLamberigts. Если бы вы создавали модуль вручную, без родительского элемента развертывания, и у него была метка: xyz. Будет ли существующее развертывание с селектором для xyz поглощать этот модуль и считать его своим? Если это так, это может быть действительно полезно для определенных нишевых приложений, подобных тому, которое я пытаюсь создать.
@ user2896438, Развертывание на самом деле не управляет своими модулями напрямую, что могло сбить с толку мое объяснение. Развертывание создает ReplicaSet, цель которого - поддерживать «набор» «реплик» указанного развертывания. Каждый модуль, принадлежащий ReplicaSet, получит уникальное поле «metadata.ownerReferences» с идентификатором этого ReplicaSet. Здесь интересно то, что когда есть модуль, который фактически соответствует меткам селектора RS, не имея действительного поля ownerReferences, RS будет считать этот модуль частью своего набора. Так что теоретически с этим можно поработать;)
However, if you don’t, you can run into problems with kubectl apply once one or more of the labels that are used for selecting change because kubeclt apply will look at kubectl.kubernetes.io/last-applied-configuration when comparing changes and that annotation will only contain the user input when he created the resource and none of the defaulted fields.
Цитата из ответа Toon.
Моя интерпретация такова, что в этом нет никакой логической необходимости. Только из-за ограничений текущей реализации Kubernetes у него есть странное «поведение» в том, что функциональность, которую он использует для «сравнения» двух развертываний / объектов, не принимает во внимание «значения по умолчанию».
Это верно для расширений / v1beta1 Deployments, но не для приложений / v1 Deployments. По-видимому, также требуется в v1beta2, из вопроса OP.