一、实战部署
[root@master node]# cat pod-required-affinity-demo-1.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-first
labels:
app2: myapp2
tier: frontend
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
[root@master node]# cat pod-required-affinity-demo-2.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-second
labels:
app: backend
tier: db
spec:
containers:
- name: busybox
image: busybox:1.28
imagePullPolicy: IfNotPresent
command: ["sh","-c","sleep 3600"]
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app2
operator: In
values:
- myapp2
topologyKey: kubernetes.io/hostname
[root@master node]# kubectl get pods -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-first 1/1 Running 0 12m 10.244.166.140 node1 <none> <none>
pod-second 1/1 Running 0 3m13s 10.244.166.141 node1 <none> <none>
二、代码解释
以下是对你提供的命令和配置文件的详细解释:
---
### 1. **部署第一个 Pod(`pod-first`)**
#### 配置文件 (`pod-required-affinity-demo-1.yaml`):
```yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-first
labels:
app2: myapp2
tier: frontend
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
```
#### 解释:
- **`metadata.labels`**:为 Pod 设置标签。
- `app2: myapp2`:定义标签 `app2=myapp2`。
- `tier: frontend`:定义标签 `tier=frontend`。
- **`spec.containers`**:定义容器。
- `name: myapp`:容器名称为 `myapp`。
- `image: ikubernetes/myapp:v1`:使用镜像 `ikubernetes/myapp:v1`。
- `imagePullPolicy: IfNotPresent`:如果本地已有镜像,则不会从远程仓库拉取。
#### 操作:
```bash
kubectl apply -f pod-required-affinity-demo-1.yaml
```
#### 查看 Pod:
```bash
kubectl get pods -o wide
```
- 输出:
```
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-first 1/1 Running 0 12m 10.244.166.140 node1 <none> <none>
```
- Pod 状态为 `Running`,表示已成功调度到 `node1` 节点并运行。
---
### 2. **部署第二个 Pod(`pod-second`)**
#### 配置文件 (`pod-required-affinity-demo-2.yaml`):
```yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-second
labels:
app: backend
tier: db
spec:
containers:
- name: busybox
image: busybox:1.28
imagePullPolicy: IfNotPresent
command: ["sh","-c","sleep 3600"]
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app2
operator: In
values:
- myapp2
topologyKey: kubernetes.io/hostname
```
#### 解释:
- **`metadata.labels`**:为 Pod 设置标签。
- `app: backend`:定义标签 `app=backend`。
- `tier: db`:定义标签 `tier=db`。
- **`spec.containers`**:定义容器。
- `name: busybox`:容器名称为 `busybox`。
- `image: busybox:1.28`:使用镜像 `busybox:1.28`。
- `command: ["sh","-c","sleep 3600"]`:容器启动后执行 `sleep 3600` 命令(保持容器运行 1 小时)。
- **`affinity.podAffinity`**:定义 Pod 亲和性规则。
- **`requiredDuringSchedulingIgnoredDuringExecution`**:调度时必须满足的条件。
- **`labelSelector`**:匹配其他 Pod 的标签。
- `key: app2`:匹配标签键为 `app2` 的 Pod。
- `operator: In`:标签值必须在 `values` 列表中(即 `myapp2`)。
- **`topologyKey: kubernetes.io/hostname`**:指定拓扑域为节点主机名(`hostname`),即要求 Pod 必须调度到与匹配 Pod 相同的节点。
#### 操作:
```bash
kubectl apply -f pod-required-affinity-demo-2.yaml
```
#### 查看 Pod:
```bash
kubectl get pods -o wide
```
- 输出:
```
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-first 1/1 Running 0 12m 10.244.166.140 node1 <none> <none>
pod-second 1/1 Running 0 3m13s 10.244.166.141 node1 <none> <none>
```
- `pod-second` 状态为 `Running`,表示已成功调度到 `node1` 节点并运行。
- 由于 `pod-second` 定义了 Pod 亲和性规则,它被调度到与 `pod-first` 相同的节点(`node1`)。
---
### 3. **Pod 亲和性规则的作用**
- **`podAffinity`**:用于定义 Pod 之间的亲和性规则。
- **`requiredDuringSchedulingIgnoredDuringExecution`**:调度时必须满足的条件。
- **`labelSelector`**:匹配其他 Pod 的标签。
- **`topologyKey`**:指定拓扑域(如节点、区域等),用于限制 Pod 的调度范围。
- 在本例中:
- `pod-second` 必须调度到与 `pod-first` 相同的节点(因为 `topologyKey: kubernetes.io/hostname`)。
- `pod-second` 通过 `labelSelector` 匹配 `pod-first` 的标签 `app2=myapp2`。
---
### 4. **总结**
- **`pod-first`**:一个简单的 Pod,带有标签 `app2=myapp2` 和 `tier=frontend`。
- **`pod-second`**:通过 Pod 亲和性规则,强制调度到与 `pod-first` 相同的节点。
- **Pod 亲和性**:用于控制 Pod 之间的调度关系,适用于需要将某些 Pod 部署在同一节点或区域的场景。
如果还有其他问题,欢迎继续提问!