**K8S与容器地址为什么不一致**

在使用Kubernetes(简称K8S)部署容器化应用时,可能会有一个容器地址与K8S服务地址不一致的情况。这是由于K8S内部的网络转发机制引起的。下面我将详细介绍为什么会出现这种情况以及如何解决。

### 为什么容器地址与K8S服务地址不一致?

K8S集群内每个容器都有一个独立的IP地址,而K8S服务则有一个虚拟IP地址。在K8S内部,通过Service来定义服务,并通过Endpoint将Service映射到对应的Pod。当一个服务被创建时,K8S会为该服务创建一个ClusterIP,用来代表整个服务。而容器的IP地址是由容器运行时在集群内部分配的。因此,容器地址与K8S服务地址不一致是因为K8S将这两者进行了解耦。

### 如何解决容器地址与K8S服务地址不一致的问题?

以下是解决这个问题的具体步骤:

| 步骤 | 操作 |
| ---- | ---- |
| 步骤一 | 创建一个K8S Deployment |
| 步骤二 | 创建一个K8S Service |
| 步骤三 | 调用Service的虚拟IP访问Deployment中的Pod |

#### 步骤一:创建一个K8S Deployment

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deployment
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-container
image: nginx:latest
```

在这个示例中,我们创建了一个名为my-deployment的Deployment,指定了3个Pod副本,并使用Nginx镜像运行容器。

#### 步骤二:创建一个K8S Service

```yaml
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIP
```

在这个示例中,我们创建了一个名为my-service的Service,通过selector与Deployment中的标签进行关联,将Service暴露在集群内部的虚拟IP上,并将流量转发到Pod的80端口。

#### 步骤三:调用Service的虚拟IP访问Deployment中的Pod

```bash
kubectl run -i --tty --rm debug --image=busybox --restart=Never -- sh
```

在命令行中执行以上命令后,会进入一个以busybox镜像为基础的Pod中。然后通过以下命令可以访问Service的虚拟IP,进而访问到部署的Pod。

```bash
wget -q -O - http://my-service
```

通过以上步骤,我们成功解决了K8S与容器地址不一致的问题,通过K8S Service的虚拟IP可以访问到部署的Pod,实现了容器服务的访问。

总结:Kubernetes内部的网络转发机制导致了容器地址与K8S服务地址不一致的现象,但通过创建Service并将其与Pod进行关联,可以很方便地解决这一问题。希望本文对初学者有所帮助。