k8s~deployment和service如何找到pod
<h1 id="deployment关联到pod">deployment关联到pod</h1><h2 id="specselectormatchlabelsdeployment-hello"><strong>spec.selector.matchLabels.deployment: hello</strong></h2>
<h3 id="作用">作用:</h3>
<p>这是<strong>选择器(Selector)</strong>,用于告诉Deployment:</p>
<ul>
<li><strong>识别哪些Pod属于这个Deployment管理</strong></li>
<li>它会<strong>匹配集群中已有的Pod标签</strong></li>
<li>一个Deployment只能管理与自己selector匹配的Pod</li>
</ul>
<h3 id="关键点">关键点:</h3>
<ul>
<li>用于<strong>查找和选择</strong>现有的Pod</li>
<li>决定Deployment的<strong>管理范围</strong></li>
<li>一旦设置后<strong>不能修改</strong>(除非删除整个Deployment重新创建)</li>
</ul>
<h2 id="spectemplatemetadatalabelsdeployment-hello"><strong>spec.template.metadata.labels.deployment: hello</strong></h2>
<h3 id="作用-1">作用:</h3>
<p>这是<strong>模板标签(Template Labels)</strong>,用于:</p>
<ul>
<li><strong>定义新创建Pod的标签</strong></li>
<li>当Deployment创建新Pod副本时,会给每个Pod打上这个标签</li>
<li>确保新Pod能够被上面的selector选中</li>
</ul>
<h3 id="关键点-1">关键点:</h3>
<ul>
<li>用于<strong>给新Pod打标签</strong></li>
<li>决定新Pod的<strong>身份标识</strong></li>
<li>可以修改(触发滚动更新)</li>
</ul>
<h2 id="两者关系图示"><strong>两者关系图示</strong></h2>
<pre><code>Deployment
├── selector.matchLabels: deployment=hello ← 查找标准("我要管理哪些Pod?")
│
└── template
└── metadata.labels: deployment=hello ← 创建标准("我创建的Pod长这样")
│
└── Pod1 (deployment=hello) ← 被selector匹配到
└── Pod2 (deployment=hello) ← 被selector匹配到
</code></pre>
<h2 id="为什么需要两者匹配"><strong>为什么需要两者匹配?</strong></h2>
<pre><code class="language-yaml">apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-deployment
spec:
replicas: 3
selector:
matchLabels:
deployment: hello# ← 查找标签为deployment=hello的Pod
template:
metadata:
labels:
deployment: hello# ← 创建Pod时给它打上deployment=hello标签
spec:
containers:
- name: nginx
image: nginx:1.14.2
</code></pre>
<h3 id="如果不匹配会发生什么">如果不匹配会发生什么?</h3>
<p>假设:</p>
<ul>
<li>selector匹配 <code>deployment: hello</code></li>
<li>但template标签是 <code>app: hello</code></li>
</ul>
<p>结果:</p>
<ol>
<li>Deployment创建Pod时打上 <code>app: hello</code> 标签</li>
<li>Deployment的selector查找 <code>deployment: hello</code> 的Pod</li>
<li><strong>找不到</strong>自己创建的Pod</li>
<li>会<strong>无限创建新Pod</strong>(因为永远达不到期望的副本数)</li>
<li>出现错误:"selector does not match template labels"</li>
</ol>
<h2 id="实际应用场景"><strong>实际应用场景</strong></h2>
<h3 id="1-版本管理">1. 版本管理</h3>
<pre><code class="language-yaml">selector:
matchLabels:
app: myapp# 匹配所有myapp的Pod,无论版本
template:
metadata:
labels:
app: myapp
version: v1.2.3# 创建特定版本的Pod
</code></pre>
<h3 id="2-多deployment共享pod">2. 多Deployment共享Pod</h3>
<pre><code class="language-yaml"># Deployment A
selector:
matchLabels:
app: myapp
tier: frontend
# Deployment B(也可以管理同样的Pod)
selector:
matchLabels:
app: myapp
managed-by: deployment-b
</code></pre>
<h3 id="3-金丝雀发布">3. 金丝雀发布</h3>
<pre><code class="language-yaml"># 主Deployment
selector:
matchLabels:
app: myapp
track: stable
# 金丝雀Deployment
selector:
matchLabels:
app: myapp
track: canary
</code></pre>
<h2 id="最佳实践"><strong>最佳实践</strong></h2>
<ol>
<li><strong>始终保持一致</strong>:selector的标签必须包含在template的标签中</li>
<li><strong>使用复合标签</strong>:不要只用一个标签,通常用2-3个标签组合</li>
<li><strong>避免修改selector</strong>:修改会导致Deployment无法管理现有Pod</li>
<li><strong>使用有意义的标签</strong>:</li>
</ol>
<pre><code class="language-yaml">labels:
app: shopping-cart
component: payment
environment: production
version: v2.1.0
</code></pre>
<h2 id="总结对比"><strong>总结对比</strong></h2>
<table>
<thead>
<tr>
<th>特性</th>
<th>selector.matchLabels</th>
<th>template.metadata.labels</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>作用</strong></td>
<td>选择管理哪些Pod</td>
<td>定义新Pod的标签</td>
</tr>
<tr>
<td><strong>方向</strong></td>
<td>从Pod到Deployment</td>
<td>从Deployment到Pod</td>
</tr>
<tr>
<td><strong>可修改</strong></td>
<td>不可修改(创建后)</td>
<td>可修改(触发更新)</td>
</tr>
<tr>
<td><strong>匹配关系</strong></td>
<td>必须⊆ template的标签</td>
<td>必须⊇ selector的标签</td>
</tr>
</tbody>
</table>
<p>简单记忆:<strong>selector是"我要找谁",template是"我造的人长什么样"</strong>。Deployment用selector找到自己该管的人,然后用template制造新人。</p>
<h1 id="service路由到pod">service路由到pod</h1>
<p><strong>完全正确!你的理解非常准确。</strong></p>
<h2 id="service-selector-的作用"><strong>Service Selector 的作用</strong></h2>
<pre><code class="language-yaml">apiVersion: v1
kind: Service
metadata:
name: hello-service
spec:
selector:
deployment: hello# ← 这是选择Pod的标签,不是选择Deployment!
ports:
- port: 80
targetPort: 8080
</code></pre>
<p><strong>Service的selector直接关联到Pod,而不是Deployment</strong>,这是Kubernetes服务发现的核心机制。</p>
<h2 id="详细解释"><strong>详细解释</strong></h2>
<h3 id="工作原理图示"><strong>工作原理图示</strong></h3>
<pre><code>┌─────────────┐ 管理 ┌─────────────┐ 标签匹配 ┌─────────────┐
│ Deployment│──────────▶│ Pod │◀────────────│ Service │
│ │ 创建Pod│ (deployment:hello) │ 流量转发 │ │
└─────────────┘ └─────────────┘ └─────────────┘
│ ▲ │
│设置Pod标签 │ 通过标签选择Pod
└──────────────────────────┘ │
流量
▼
客户端请求
</code></pre>
<h3 id="关键区别"><strong>关键区别</strong></h3>
<table>
<thead>
<tr>
<th>对象</th>
<th>选择目标</th>
<th>选择依据</th>
<th>作用</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Deployment Selector</strong></td>
<td>Pod</td>
<td>matchLabels</td>
<td>管理Pod的生命周期(创建、更新、删除)</td>
</tr>
<tr>
<td><strong>Service Selector</strong></td>
<td>Pod</td>
<td>selector</td>
<td>将流量路由到匹配的Pod</td>
</tr>
</tbody>
</table>
<h2 id="完整示例"><strong>完整示例</strong></h2>
<pre><code class="language-yaml"># 1. Deployment创建Pod并打标签
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-deployment
spec:
selector:
matchLabels:
app: hello-app# 管理标签匹配的Pod
template:
metadata:
labels:
app: hello-app # Service会匹配这个
version: v1 # Service也会匹配这个(如果selector包含)
environment: prod # 额外标签,Service不关心
spec:
containers:
- name: nginx
image: nginx:1.14.2
---
# 2. Service通过标签选择Pod
apiVersion: v1
kind: Service
metadata:
name: hello-service
spec:
selector:
app: hello-app # 选择具有app=hello-app标签的Pod
# version: v1 # 也可以同时匹配多个标签
ports:
- port: 80
targetPort: 80
</code></pre>
<h2 id="实际应用中的常见模式"><strong>实际应用中的常见模式</strong></h2>
<h3 id="模式1一对一关联"><strong>模式1:一对一关联</strong></h3>
<pre><code class="language-yaml"># Deployment
template.metadata.labels:
app: frontend
component: web
# Service
selector:
app: frontend
component: web
# 精确匹配特定应用的特定组件
</code></pre>
<h3 id="模式2一对多关联"><strong>模式2:一对多关联</strong></h3>
<pre><code class="language-yaml"># 多个Deployment创建相同标签的Pod
# Deployment A
template.metadata.labels:
app: backend
tier: api
# Deployment B(另一个版本的API)
template.metadata.labels:
app: backend
tier: api
# 单个Service负载均衡到所有匹配的Pod
# Service
selector:
app: backend
tier: api
# 流量会同时分发到两个Deployment创建的Pod
</code></pre>
<h3 id="模式3流量分片"><strong>模式3:流量分片</strong></h3>
<pre><code class="language-yaml"># 金丝雀部署场景
# 稳定版Deployment
template.metadata.labels:
app: shopping-cart
track: stable
# 金丝雀Deployment
template.metadata.labels:
app: shopping-cart
track: canary
# Service A(稳定流量)
selector:
app: shopping-cart
track: stable
# Service B(测试流量)
selector:
app: shopping-cart
track: canary
</code></pre>
<h2 id="重要特性"><strong>重要特性</strong></h2>
<h3 id="1-动态发现"><strong>1. 动态发现</strong></h3>
<pre><code class="language-bash"># 当新Pod启动并匹配Service的selector时
# Service会自动将其添加到端点列表
kubectl get endpoints hello-service
# 输出示例:
# NAME ENDPOINTS AGE
# hello-service 10.244.1.5:80,10.244.2.3:80,10.244.2.4:80 10m
# ↑
# Service自动发现的所有匹配Pod的IP
</code></pre>
<h3 id="2-标签变化的影响"><strong>2. 标签变化的影响</strong></h3>
<pre><code class="language-yaml"># 如果Pod的标签变化,不再匹配Service的selector
# Service会自动将其从端点列表中移除
原始Pod标签: app=frontend, version=v1
Service selector: app=frontend, version=v1
# 如果Pod标签变为: app=frontend, version=v2
# Pod将不再接收来自该Service的流量
</code></pre>
<h3 id="3-无selector的service"><strong>3. 无selector的Service</strong></h3>
<pre><code class="language-yaml"># Service也可以没有selector,手动指定端点
apiVersion: v1
kind: Service
metadata:
name: external-service
spec:
ports:
- port: 80
# 没有selector,需要手动创建Endpoints对象
</code></pre>
<h2 id="验证方法"><strong>验证方法</strong></h2>
<pre><code class="language-bash"># 1. 查看Pod标签
kubectl get pods --show-labels
# 2. 查看Service的selector
kubectl describe service hello-service | grep Selector
# 3. 查看Service关联的端点
kubectl get endpoints hello-service
# 4. 测试连接
kubectl run test-$RANDOM --rm -i --image=busybox --restart=Never -- \
wget -qO- hello-service
</code></pre>
<h2 id="常见误区澄清"><strong>常见误区澄清</strong></h2>
<ol>
<li>
<p><strong>❌ Service选择Deployment</strong></p>
<ul>
<li>✅ Service只选择Pod,与Deployment无关</li>
</ul>
</li>
<li>
<p><strong>❌ 修改Deployment会影响Service</strong></p>
<ul>
<li>✅ 只有Pod的标签变化才会影响Service</li>
</ul>
</li>
<li>
<p><strong>❌ Service和Deployment必须同名</strong></p>
<ul>
<li>✅ 它们可以任意命名,只需标签匹配</li>
</ul>
</li>
<li>
<p><strong>❌ 一个Service只能关联一个Deployment</strong></p>
<ul>
<li>✅ 一个Service可以关联多个Deployment创建的Pod</li>
</ul>
</li>
</ol>
<h2 id="总结"><strong>总结</strong></h2>
<ul>
<li><strong>Service selector → Pod标签</strong>:Service直接选择Pod,不关心Pod由谁创建</li>
<li><strong>标签匹配机制</strong>:Service的selector必须完全匹配Pod的标签(所有key-value都对上)</li>
<li><strong>动态更新</strong>:Pod标签变化时,Service的端点列表自动更新</li>
<li><strong>多对多关系</strong>:多个Service可以选择同一组Pod,一个Pod可以被多个Service选择</li>
</ul>
<p>记住这个简单规则:<strong>Service通过标签找Pod,不关心Deployment的存在。</strong></p>
</div>
<div id="MySignature" role="contentinfo">
<p></p>
<div class="navgood">
<p>作者:仓储大叔,张占岭,<br>
荣誉:微软MVP<br>QQ:853066980</p>
<p><strong>支付宝扫一扫,为大叔打赏!</strong>
<br><img src="https://images.cnblogs.com/cnblogs_com/lori/237884/o_IMG_7144.JPG"></p>
</div><br><br>
来源:https://www.cnblogs.com/lori/p/19414143
頁:
[1]