一、模拟企业环境进行一个实战部署
[root@master node]# kubectl apply -f pod-tomcat.yaml
 pod/tomcat-test created
 [root@master node]# kubectl get pods
 NAME          READY   STATUS    RESTARTS   AGE
 tomcat-test   2/2     Running   0          2s
 [root@master node]# kubectl get pods -o wide
 NAME          READY   STATUS    RESTARTS   AGE   IP               NODE    NOMINATED NODE   READINESS GATES
 tomcat-test   2/2     Running   0          8s    10.244.166.137   node1   <none>           <none>
 [root@master node]# cat pod-tomcat.yaml
 apiVersion: v1
 kind: Pod
 metadata:
   name: tomcat-test
   namespace: default
   labels:
     app:  tomcat
 spec:
   nodeName: node1
   containers:
   - name:  tomcat-java
     ports:
     - containerPort: 8080
     image: xianchao/tomcat-8.5-jre8:v1
     imagePullPolicy: IfNotPresent
   - name: busybox-test
     image: busybox:1.28
     imagePullPolicy: IfNotPresent
     command:
     - "/bin/sh"
     - "-c"
     - "sleep 3600"
[root@node1 ~]# kubectl label node node2 version=v1
[root@master node]# kubectl apply -f pod-tomcat.yaml
 pod/tomcat-test created
 [root@master node]# kubectl get pod -owide
 NAME          READY   STATUS    RESTARTS   AGE   IP              NODE    NOMINATED NODE   READINESS GATES
 tomcat-test   2/2     Running   0          6s    10.244.104.10   node2   <none>           <none>
 [root@master node]# cat pod-tomcat.yaml
 apiVersion: v1
 kind: Pod
 metadata:
   name: tomcat-test
   namespace: default
   labels:
     app:  tomcat
 spec:
   nodeSelector:
     version: v1
   containers:
   - name:  tomcat-java
     ports:
     - containerPort: 8080
     image: xianchao/tomcat-8.5-jre8:v1
     imagePullPolicy: IfNotPresent
   - name: busybox-test
     image: busybox:1.28
     imagePullPolicy: IfNotPresent
     command:
     - "/bin/sh"
     - "-c"
     - "sleep 3600"
[root@node1 ~]# kubectl label node node1 zone=foo
[root@master node]# kubectl apply -f affinity.yaml
 pod/pod-affinity created
 [root@master node]# kubectl get pod
 NAME           READY   STATUS    RESTARTS   AGE
 pod-affinity   1/1     Running   0          24s
[root@master node]# cat affinity.yaml
 apiVersion: v1
 kind: Pod
 metadata:
   name: pod-affinity
   namespace: default
   labels:
     app: myapp
 spec:
   affinity:
     nodeAffinity:
       requiredDuringSchedulingIgnoredDuringExecution:
         nodeSelectorTerms:
         - matchExpressions:
           - key: zone
             operator: In
             values:
             - foo
             - bar
   containers:
   - name: myapp
     image: docker.io/ikubernetes/myapp:v1
     imagePullPolicy: IfNotPresent
[root@master node]# kubectl apply -f pod-nodeaffinity-demo-2.yaml
 pod/pod-node-affinity-demo-2 created
 [root@master node]# cat pod-nodeaffinity-demo-2.yaml
 apiVersion: v1
 kind: Pod
 metadata:
   name: pod-node-affinity-demo-2
   namespace: default
   labels:
     app: myapp
     tier: frontend
 spec:
   containers:
   - name: myapp
     image: docker.io/ikubernetes/myapp:v1
     imagePullPolicy: IfNotPresent
   affinity:
     nodeAffinity:
       preferredDuringSchedulingIgnoredDuringExecution:
       - preference:
           matchExpressions:
           - key: zone1
             operator: In
             values:
             - foo1
             - bar1
         weight: 10
       - preference:
           matchExpressions:
           - key: zone2
             operator: In
             values:
             - foo2
             - bar2
         weight: 20
 [root@master node]# kubectl get pods
 NAME                       READY   STATUS    RESTARTS   AGE
 pod-affinity               1/1     Running   0          8m3s
 pod-node-affinity-demo-2   1/1     Running   0          10s
二、命令+命令解析
### 1. **部署第一个 Pod(`tomcat-test`)**
 #### 操作:
 ```bash
 kubectl apply -f pod-tomcat.yaml
 ```
#### 配置文件 (`pod-tomcat.yaml`):
 ```yaml
 apiVersion: v1
 kind: Pod
 metadata:
   name: tomcat-test
   namespace: default
   labels:
     app: tomcat
 spec:
   nodeName: node1
   containers:
   - name: tomcat-java
     ports:
     - containerPort: 8080
     image: xianchao/tomcat-8.5-jre8:v1
     imagePullPolicy: IfNotPresent
   - name: busybox-test
     image: busybox:1.28
     imagePullPolicy: IfNotPresent
     command:
     - "/bin/sh"
     - "-c"
     - "sleep 3600"
 ```
#### 解释:
 - **`nodeName: node1`**:指定 Pod 必须调度到 `node1` 节点。
 - **`containers`**:
   - `tomcat-java`:运行 Tomcat 应用,监听 8080 端口。
   - `busybox-test`:运行一个 BusyBox 容器,执行 `sleep 3600` 命令(保持容器运行 1 小时)。
 - **`imagePullPolicy: IfNotPresent`**:如果本地已有镜像,则不会从远程仓库拉取。
#### 查看 Pod:
 ```bash
 kubectl get pods -o wide
 ```
 - 输出:
   ```
   NAME          READY   STATUS    RESTARTS   AGE   IP               NODE    NOMINATED NODE   READINESS GATES
   tomcat-test   2/2     Running   0          8s    10.244.166.137   node1   <none>           <none>
   ```
   - Pod 状态为 `Running`,表示已成功调度到 `node1` 节点并运行。
---
### 2. **为 `node2` 添加标签**
 #### 操作:
 ```bash
 kubectl label node node2 version=v1
 ```
#### 解释:
 - 为 `node2` 节点添加一个标签 `version=v1`。
 - 标签可以用于节点选择器(`nodeSelector`)或亲和性规则(`affinity`)。
---
### 3. **部署第二个 Pod(`tomcat-test`)**
 #### 操作:
 ```bash
 kubectl apply -f pod-tomcat.yaml
 ```
#### 配置文件 (`pod-tomcat.yaml`):
 ```yaml
 apiVersion: v1
 kind: Pod
 metadata:
   name: tomcat-test
   namespace: default
   labels:
     app: tomcat
 spec:
   nodeSelector:
     version: v1
   containers:
   - name: tomcat-java
     ports:
     - containerPort: 8080
     image: xianchao/tomcat-8.5-jre8:v1
     imagePullPolicy: IfNotPresent
   - name: busybox-test
     image: busybox:1.28
     imagePullPolicy: IfNotPresent
     command:
     - "/bin/sh"
     - "-c"
     - "sleep 3600"
 ```
#### 解释:
 - **`nodeSelector`**:指定 Pod 必须调度到带有 `version=v1` 标签的节点(即 `node2`)。
 - 其他配置与第一个 Pod 相同。
#### 查看 Pod:
 ```bash
 kubectl get pods -o wide
 ```
 - 输出:
   ```
   NAME          READY   STATUS    RESTARTS   AGE   IP              NODE    NOMINATED NODE   READINESS GATES
   tomcat-test   2/2     Running   0          6s    10.244.104.10   node2   <none>           <none>
   ```
   - Pod 状态为 `Running`,表示已成功调度到 `node2` 节点并运行。
---
### 4. **为 `node1` 添加标签**
 #### 操作:
 ```bash
 kubectl label node node1 zone=foo
 ```
#### 解释:
 - 为 `node1` 节点添加一个标签 `zone=foo`。
 - 该标签将用于后续的亲和性调度。
---
### 5. **部署第三个 Pod(`pod-affinity`)**
 #### 操作:
 ```bash
 kubectl apply -f affinity.yaml
 ```
#### 配置文件 (`affinity.yaml`):
 ```yaml
 apiVersion: v1
 kind: Pod
 metadata:
   name: pod-affinity
   namespace: default
   labels:
     app: myapp
 spec:
   affinity:
     nodeAffinity:
       requiredDuringSchedulingIgnoredDuringExecution:
         nodeSelectorTerms:
         - matchExpressions:
           - key: zone
             operator: In
             values:
             - foo
             - bar
   containers:
   - name: myapp
     image: docker.io/ikubernetes/myapp:v1
     imagePullPolicy: IfNotPresent
 ```
#### 解释:
 - **`nodeAffinity`**:定义节点亲和性规则。
   - **`requiredDuringSchedulingIgnoredDuringExecution`**:调度时必须满足的条件。
   - **`matchExpressions`**:匹配节点的标签。
     - `key: zone`:匹配标签键为 `zone` 的节点。
     - `operator: In`:标签值必须在 `values` 列表中(即 `foo` 或 `bar`)。
 - 由于 `node1` 有 `zone=foo` 标签,Pod 将被调度到 `node1`。
#### 查看 Pod:
 ```bash
 kubectl get pods
 ```
 - 输出:
   ```
   NAME           READY   STATUS    RESTARTS   AGE
   pod-affinity   1/1     Running   0          24s
   ```
   - Pod 状态为 `Running`,表示已成功调度到 `node1` 节点并运行。
---
### 6. **部署第四个 Pod(`pod-node-affinity-demo-2`)**
 #### 操作:
 ```bash
 kubectl apply -f pod-nodeaffinity-demo-2.yaml
 ```
#### 配置文件 (`pod-nodeaffinity-demo-2.yaml`):
 ```yaml
 apiVersion: v1
 kind: Pod
 metadata:
   name: pod-node-affinity-demo-2
   namespace: default
   labels:
     app: myapp
     tier: frontend
 spec:
   containers:
   - name: myapp
     image: docker.io/ikubernetes/myapp:v1
     imagePullPolicy: IfNotPresent
   affinity:
     nodeAffinity:
       preferredDuringSchedulingIgnoredDuringExecution:
       - preference:
           matchExpressions:
           - key: zone1
             operator: In
             values:
             - foo1
             - bar1
         weight: 10
       - preference:
           matchExpressions:
           - key: zone2
             operator: In
             values:
             - foo2
             - bar2
         weight: 20
 ```
#### 解释:
 - **`nodeAffinity`**:定义节点亲和性规则。
   - **`preferredDuringSchedulingIgnoredDuringExecution`**:调度时优先满足的条件(非强制)。
   - **`preference`**:定义偏好规则。
     - `key: zone1` 和 `key: zone2`:匹配节点的标签。
     - `operator: In`:标签值必须在 `values` 列表中。
     - `weight`:规则的权重(值越大,优先级越高)。
 - 由于没有节点满足 `zone1` 或 `zone2` 的标签,Pod 将被调度到任意可用节点。
#### 查看 Pod:
 ```bash
 kubectl get pods
 ```
 - 输出:
   ```
   NAME                       READY   STATUS    RESTARTS   AGE
   pod-affinity               1/1     Running   0          8m3s
   pod-node-affinity-demo-2   1/1     Running   0          10s
   ```
   - Pod 状态为 `Running`,表示已成功调度并运行。
---
### 总结
 - **`nodeName`**:强制 Pod 调度到指定节点。
 - **`nodeSelector`**:根据节点标签调度 Pod。
 - **`nodeAffinity`**:定义更复杂的节点亲和性规则(强制或偏好)。
 - 通过这些机制,可以灵活控制 Pod 的调度行为,满足不同的部署需求。
如果还有其他问题,欢迎继续提问!
