在之前的文章中, 介绍了搭建好的#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 115sPod:
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的指定端口
拿了橘子跑啊