集群中的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