我无法理解为什么kubernetes在部署语句中需要一个只能包含一个pod模板的pod选择器?请随意告诉我为什么kubernetes工程师在部署防御中引入选择器语句而不是从模板中自动选择pod?
---
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:
...
答案 0 :(得分:13)
啊!有趣的是,我曾经尝试过围绕标签选择器的概念。所以,这就是......
首先,这些标签到底用于什么? kubernetes中的标签是识别物体的核心手段。控制器根据标签而不是名称控制pod。在这种特殊情况下,它们例如用于识别属于部署副本集的pod。
使用.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
时,该字段将是强制性的。我希望这样能回答你的问题而且我没有让它变得更加令人困惑;)
答案 1 :(得分:4)
据我所知,部署中的选择器是一个可选属性。
模板是规范唯一必填字段。
因此,您不需要在部署中使用标签选择器,在您的示例中,我不明白为什么您不能使用后者?
答案 2 :(得分:2)
但是,如果不这样做,则一旦用于选择更改的一个或多个标签会出现在kubectl应用中的问题,因为kubeclt应用将在以下情况下查看kubectl.kubernetes.io/last-applied-configuration:比较更改,该注释将仅在用户创建资源时包含用户输入,并且没有默认字段。
引用Toon的答案。
我的解释是,从逻辑上讲完全没有必要。仅仅是由于当前Kubernetes实现的局限性,它具有一些怪异的“行为”,因为它用来“比较”两个部署/对象的功能并未考虑“默认值”。