集群中的Service
(服务)默认为ClusterIP
类型,该类型的Service
只能在集群内部访问。有时需要对Service进行调试,在不改变Service
配置的情况下,还可以借助kubectl
提供的端口转发能力。
下面我们在一个kind
集群中部署一个ClusterIP
类型的nginx
服务,然后借助kubectl
的端口转发能力实现从主机上访问。
创建集群
首先使用常规的kind create cluster
命令创建一个名字为rainbow
的集群:
# kind create cluster --name rainbow
部署服务
接着在集群中分别部署一个nginx
的Deployment
和Service
,配置如下所示。
Deployment
的配置:
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
的配置:
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