> For the complete documentation index, see [llms.txt](https://renhongcai.gitbook.io/kubernetes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://renhongcai.gitbook.io/kubernetes/di-shi-jiu-zhang-kubernetes-sheng-tai/19.1-kind/1.3-port-forward.md).

# 19.1.3 配置端口转发

集群中的`Service`（服务）默认为`ClusterIP`类型，该类型的`Service`只能在集群内部访问。有时需要对Service进行调试，在不改变`Service`配置的情况下，还可以借助`kubectl`提供的端口转发能力。

下面我们在一个`kind`集群中部署一个`ClusterIP`类型的`nginx`服务，然后借助`kubectl`的端口转发能力实现从主机上访问。

## 创建集群

首先使用常规的`kind create cluster`命令创建一个名字为`rainbow`的集群：

```bash
# kind create cluster --name rainbow
```

## 部署服务

接着在集群中分别部署一个`nginx`的`Deployment`和`Service`，配置如下所示。

`Deployment`的配置：

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx
        name: nginx
        ports:
        - containerPort: 80
```

`Service`的配置：

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

该服务的端口为`80`，类型为`ClusterIP`，此时是无法在主机上直接访问的。

## 配置端口转发

接着使用`kubectl port-forward`命令启动端口转发：

```
# kubectl port-forward --namespace default svc/nginx --address 0.0.0.0 3001:80
Forwarding from 0.0.0.0:3001 -> 80
```

其参数解释如下：

* `--namespace`：指定`Service`所在的namespace（默认为default）；
* `svc/nginx`：指定`Service`的类型和名字，也可以使用全称`service/nginx`;
* `--address`：指定绑定主机的IP；
* `3001:80`：指定监听主机上的`3001`端口，并将消息转发到服务的`80`口上；

该命令执行后不会自动退出，显示以上信息就表示成功地在本机和服务的容器之间建立了一条链接，命令终止执行时，该链接会自动中断。

此时访问本机的`3001`端口即可访问服务。例如访问`localhost` IP：

```
# curl localhost:3001
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
</html>
...
```

如果本机配置了外部IP，还可以通过浏览器访问，比如`http://x.x.x.x:3001`.

## 小结

`kubectl`的`port-forward`本质上是在本地主机和集群中的`Pod`之间建立一个用于流量转发的连接，在上面的例子中，我们也可以直接指定`Pod`建立连接，比如：

```
# kubectport-forward pod/nginx-7848d4b86f-c7fbr --address 0.0.0.0 8888:80
```

上面的例子中可以指定`Service`建立连接，是因为`kubectl`会根据`Service`查找到后端的`Pod`，并最终与Pod建立建立连接。类似的，除了`Service`，还可以指定`Deployment`，比如：

```
# kubectl port-forward deployment/nginx 8888:80
```

更多的例子，有兴趣的读者可以查看命令的帮助手册：`kubectl port-forward --help`。

## 参考链接：

* port-forward官方文档：<https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/>
* port-forward实现原理（英文）：<https://prefetch.net/blog/2018/02/03/how-the-kubectl-port-forward-command-works/>
* port-forward实现原理（译文）：<https://vflong.github.io/sre/k8s/2020/03/15/how-the-kubectl-port-forward-command-works.html>
