动手动脑学Kubernetes系列教程之端口转发

查理谈科技 2024-05-10 00:13:12

在之前的文章中, 介绍了搭建好的#minikube#环境,如果你现在还没有一个可用的minikube环境, 那么可以去中直接下载;

在之前的文章中, 先后介绍了如何从源代码开始构建一个Node.js应用和Spring Boot 应用, 并且部署到Kubernetes 中(这个Kubernetes 环境主要是之前建好的#minikube#) , 现在我们开始进一步深入的学习Kubernetes, 用一个个可以实际运行的例子的形式, 深入理解#Kubernetes#的概念以及原理.

在#动手动脑学Kubernetes#系列教程中, 我们展示了Kubernetes的基本用法

在里, 学习了Pod的基本知识;在里, 学习了标签(Label)的语法, 使用Label来选择和过滤Kubernetes 资源;在里, 介绍了Deployment的使用, 介绍了Deployment与Replica Set、Pod的关系, 并展示了如何进行应用的版本回滚;在里, 介绍了Service的使用,使用Replication Controller创建Pod, 并创建Service, 展示了从Service 调用应用的方法; 随后又展示了扩展 Pod的数量为2, 比较了Service和之前的不同, 基本展示了Cluster IP 类型的Service的基本用法.在里, 介绍了Namespace的使用, 除了创建,列出系统的Namespace之外, 还说明Namespace 如何对资源进行隔离, 建立Development, Staging, Production等环境的方法.在里, 介绍了Service Discovery的使用, 讲解了如何检查Kube-dns, 如何检查和使用Service的FQDN等知识, 对Kubernetes的DNS 系统有整体的理解.

在这篇中,我们将介绍端口转发, 也就是Port Forwards的基本用法, 继续愉快地学习吧!

在Kubernetes上开发应用程序的时候,从本地环境中快速访问服务是很有必要, 这时候反而不太想使用负载平衡或ingress 。 在这种情况下,我们就可以使用端口转发。

从镜像开始

让我们创建一个由部署和名为simpleservice的服务组成的应用,该应用在端口80上提供服务:

Github地址:https://raw.githubusercontent.com/hintcnuie/kbe/main/specs/pf/app.yaml

文件内容:

apiVersion: apps/v1kind: Deploymentmetadata: name: sise-deployspec: replicas: 1 selector: matchLabels: app: sise template: metadata: labels: app: sise spec: containers: - name: sise image: quay.io/openshiftlabs/simpleservice:0.5.0 ports: - containerPort: 9876---apiVersion: v1kind: Servicemetadata: name: simpleservicespec: ports: - port: 80 targetPort: 9876 selector: app: sise

可以看到, 在一个文件中包含了Pod 和Service的定义, 中间只需要使用间隔符"--"即可.

创建Pod 和Service

来创建吧!

$kubectl apply -f https://raw.githubusercontent.com/hintcnuie/kbe/main/specs/pf/app.yamldeployment.apps/sise-deploy createdservice/simpleservice created

查看一下:

Service:

$ kubectl get svc simpleserviceNAME            TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGEsimpleservice   ClusterIP   10.97.30.49   <none>        80/TCP    115s

Pod:

kubectl get pods --show-labels -l app=siseNAME                          READY   STATUS    RESTARTS   AGE     LABELSsise-deploy-95f5f875c-mvq72   1/1     Running   0          9m55s   app=sise,pod-template-hash=95f5f875c

可以看到, 这个名称为simpleservice的Service, 端口服务在80 端口.

转发本地端口到Service

我们之前的调用方式是可以通过ClusterIP地址来调用:

$ kubectl get svc simpleserviceNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEsimpleservice ClusterIP 10.97.30.49 <none> 80/TCP 92m$ curl 10.97.30.49:80/info{"host": "10.97.30.49", "version": "0.5.0", "from": "172.17.0.1"}

下面我们来尝试一下端口转发, 我们想把本机的8080端口作为访问端口, 因此就需要把本机端口转发到minikube 里面的80端口:

先来在本机访问一下8080端口, 看看是否能访问:

$ curl http://localhost:8080/infocurl: (7) Failed connect to localhost:8080; Connection refused

然后启动端口转发:

$ kubectl port-forward service/simpleservice 8080:80Forwarding from 127.0.0.1:8080 -> 9876Forwarding from [::1]:8080 -> 9876

端口转发启动之后, 这个窗口是一直在那里运行的:

再来访问一下本机的8080端口:

$ curl http://localhost:8080/info{"host": "localhost:8080", "version": "0.5.0", "from": "127.0.0.1"}

可以看到, 这次我们就可以访问本机端口了, 整体的访问顺序如下:

来看一下kubectl port-forward的语法:

$ kubectl port-forward --helpForward one or more local ports to a pod. This command requires the node to have 'socat' installed. Use resource type/name such as deployment/mydeployment to select a pod. Resource type defaults to 'pod' if omitted. If there are multiple pods matching the criteria, a pod will be selected automatically. The forwarding session endswhen the selected pod terminates, and rerun of the command is needed to resume forwarding.Examples:  # Listen on ports 5000 and 6000 locally, forwarding data to/from ports 5000 and 6000 in the pod  kubectl port-forward pod/mypod 5000 6000    # Listen on ports 5000 and 6000 locally, forwarding data to/from ports 5000 and 6000 in a pod selected by thedeployment  kubectl port-forward deployment/mydeployment 5000 6000    # Listen on port 8443 locally, forwarding to the targetPort of the service's port named "https" in a pod selected bythe service  kubectl port-forward service/myservice 8443:https    # Listen on port 8888 locally, forwarding to 5000 in the pod  kubectl port-forward pod/mypod 8888:5000    # Listen on port 8888 on all addresses, forwarding to 5000 in the pod  kubectl port-forward --address 0.0.0.0 pod/mypod 8888:5000    # Listen on port 8888 on localhost and selected IP, forwarding to 5000 in the pod  kubectl port-forward --address localhost,10.19.21.23 pod/mypod 8888:5000    # Listen on a random port locally, forwarding to 5000 in the pod  kubectl port-forward pod/mypod :5000

可以看出, kubectl port-forward命令可以把一个或者多个本地端口转发到Pod中, 第二个参数要求是资源的类型, 例如我们使用kubectl port-forward service/simpleservice, 这就指明是转发Service 资源类型, 如果不指明资源类型, 默认的就是Pod.

如果端口转发的资源是Pod, 而且Pod又有多个的话, 那么端口转发就会随机选择一个Pod, 而且会停止端口转发的会话.

下面我们转发本机端口到Pod 来试试.

转发本机端口到Pod

先把我们的Pod 数量变成1个:

$ kubectl scale --replicas=1 deploy/sise-deploydeployment.apps/sise-deploy scaled$ kubectl get pods -l app=siseNAME                          READY   STATUS        RESTARTS   AGEsise-deploy-95f5f875c-hchbd   1/1     Terminating   0          40msise-deploy-95f5f875c-mvq72   1/1     Running       0          147m$ kubectl get pods -l app=siseNAME                          READY   STATUS    RESTARTS   AGEsise-deploy-95f5f875c-mvq72   1/1     Running   0          150m

现在只有一个Pod了, 来启动端口转发:

$ kubectl port-forward pod/sise-deploy-95f5f875c-mvq72 8081:9876Forwarding from 127.0.0.1:8081 -> 9876Forwarding from [::1]:8081 -> 9876Handling connection for 8081

访问本地端口8081:

$ curl http://localhost:8081/info{"host": "localhost:8081", "version": "0.5.0", "from": "127.0.0.1"}

可以看到Pod已经返回了正确的结果, 来看下Pod的log:

$ kubectl logs sise-deploy-95f5f875c-mvq722021-03-12T05:06:15 INFO This is simple service in version v0.5.0 listening on port 9876 [at line 142]2021-03-12T05:17:59 INFO /info serving from 10.97.30.49 has been invoked from 172.17.0.1 [at line 101]2021-03-12T05:17:59 INFO 200 GET /info (172.17.0.1) 1.06ms [at line 1946]2021-03-12T06:38:47 INFO /info serving from 10.97.30.49 has been invoked from 172.17.0.1 [at line 101]2021-03-12T06:38:47 INFO 200 GET /info (172.17.0.1) 0.48ms [at line 1946]2021-03-12T06:39:16 INFO /info serving from localhost:8080 has been invoked from 127.0.0.1 [at line 101]2021-03-12T06:39:16 INFO 200 GET /info (127.0.0.1) 0.35ms [at line 1946]2021-03-12T07:16:18 INFO /info serving from localhost:8080 has been invoked from 127.0.0.1 [at line 101]2021-03-12T07:16:18 INFO 200 GET /info (127.0.0.1) 0.76ms [at line 1946]2021-03-12T07:20:10 INFO /info serving from localhost:8080 has been invoked from 127.0.0.1 [at line 101]2021-03-12T07:20:10 INFO 200 GET /info (127.0.0.1) 0.49ms [at line 1946]2021-03-12T07:39:45 INFO /info serving from localhost:8081 has been invoked from 127.0.0.1 [at line 101]2021-03-12T07:39:45 INFO 200 GET /info (127.0.0.1) 0.40ms [at line 1946]

可以看到, Pod sise-deploy-95f5f875c-mvq72已经响应了来自127.0.0.1 的请求, 端口转发成功!

端口转发的更多示例

端口转发没有太多的理论知识可以系统的讲解, 不过端口转发不仅仅可以转发指定端口, 还有一些更多的操作:

一次转发到多个端口:

kubectl port-forward pod/mypod 5000 6000

指定Deployment里面的Pod资源, 转发到多个端口:

kubectl port-forward deployment/mydeployment 5000 6000

把本机端口8443 转发到Service的https端口:

kubectl port-forward service/myservice 8443:https

监听本地所有网络地址的8888端口, 并转发到Pod的5000端口:

kubectl port-forward --address 0.0.0.0 pod/mypod 8888:5000

监听localhost的8888端口和一个指定IP地址, 并转发到目标Pod的5000端口:

kubectl port-forward --address localhost,10.19.21.23 pod/mypod 8888:5000

随机监听本地的一个端口, 并转发到指定Pod的5000端口:

kubectl port-forward pod/mypod :5000

最后一个例子里,我实在不太理解, 监听本地的一个随机端口, 到底是一个什么场景!

总结

本篇介绍了端口转发的两种使用方法,第一种是转发本地端口到Service指定端口, 另一种是转发本地端口到Pod 的端口.

用到的命令:

kubectl port-forward service/simpleservice 8080:80

转发本地端口到Service指定端口

kubectl port-forward pod/sise-deploy-95f5f875c-mvq72 8081:9876

转发本地端口到Pod指定端口

kubectl logs sise-deploy-95f5f875c-mvq72

查看Pod 的log

kubectl port-forward pod/mypod 5000 6000

转发多个端口

kubectl port-forward deployment/mydeployment 5000 6000

转发本地端口到Deployment下面的Pod的指定端口

kubectl port-forward --address 0.0.0.0 pod/mypod 8888:5000

转发本地所有网络地址的8888端口到Pod的指定端口

拿了橘子跑啊

0 阅读:0

查理谈科技

简介:感谢大家的关注