k8s之containerPort、servicePort、nodePort、hostPort解析

这篇具有很好参考价值的文章主要介绍了k8s之containerPort、servicePort、nodePort、hostPort解析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        上次写博客是n多年以前了,以前的几十篇在blogjava里面应该还能吵到。最近遭遇变故,忽然想把自己近期学的一点东西记录下来,日后查阅起来也是方便。

        话不多说,笔者最近在啃k8s,容器也好、k8s也罢,里面和服务相关的port概念五六个,索性整理一下,看看他们之间的关系。

首先看一下我们的测试环境:

一组三从的k8集群:

root@dev-4-control-plane# sh node.sh
|NODE                          |INTERNAL_IP
|dev-4-control-plane           |172.18.0.2
|dev-4-worker                  |172.18.0.5
|dev-4-worker2                 |172.18.0.4
|dev-4-worker3                 |172.18.0.3

三副本的前端服务:

root@dev-4-control-plane# sh pod.sh
|NAME                                |NODE                            |IP              |STATUS
|frontend-5b79c8694b-6hjrc           |dev-4-worker3/172.18.0.3        |10.244.1.9      |Running
|frontend-5b79c8694b-87xnh           |dev-4-worker2/172.18.0.4        |10.244.3.9      |Running
|frontend-5b79c8694b-lkbt5           |dev-4-worker/172.18.0.5         |10.244.2.9      |Running


root@dev-4-control-plane# sh svc.sh
|NAME           |CLUSTERIP       |PORT              |TARGETPORT  |ENDPOINTS
|frontend       |10.96.48.151    |NodePort%         |80/TCP      |10.244.1.9:80,10.244.2.9:80,10.244.3.9:80

接下来看看我们的service及deployment中的port定义:

root@dev-4-control-plane# kubectl describe svc frontend
Name:                     frontend
Namespace:                default
Type:                     NodePort
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.96.48.151
IPs:                      10.96.48.151
Port:                     <unset>  8088/TCP
TargetPort:               80/TCP
NodePort:                 <unset>  30080/TCP
Endpoints:                10.244.1.9:80,10.244.2.9:80,10.244.3.9:80
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

root@dev-4-control-plane# kubectl describe deployment frontend
Name:                   frontend
Namespace:              default
CreationTimestamp:      Thu, 20 Apr 2023 03:11:12 +0000
Labels:                 <none>
Annotations:            deployment.kubernetes.io/revision: 1
Selector:               app=guestbook
Replicas:               3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  app=guestbook
  Containers:
   php-redis:
    Image:      anjia0532/google_samples.gb-frontend:v5
    Port:       8081/TCP
    Host Port:  9088/TCP
    Environment:
      GET_HOSTS_FROM:  dns
    Mounts:            <none>
  Volumes:             <none>

好了,开始进入今天的主题。从上面的内容中可以获取如下信息:

	clusterIP: 10.96.48.151
	nodeIP: 172.18.0.3\172.18.0.4\172.18.0.5
	podIP: 10.244.1.9\10.244.2.9\10.244.3.9
	containerPort: 8081(这个端口就是deployment中的port,由于测试中使用的image的问题,apache使用的80端口不可修改,因此这个8081定义实际不起作用)
	hostPort:9088(这个端口就是deployment中的port)
	servicePort: 8088(service中的port)
	TargetPort: 80 (这个端口理论上需要和container保持一致,但因为咱们实验中的镜像使用了不可改的80,因此containerPort不生效,为了不影响测试,这个targetPort直接指向了实际listen的port)
	NodePort: 30080

        准备好两个客户端,分别为 dev-4-worker3(同集群客户端)、dev-2-worker(异集群客户端),看看他们分别可以通过哪些途径访问pod中的service。验证结果如下,其中同集群客户端有三种方式访问,分别为:podIP+containerPort、nodeIP+nodePort、clusterIP+servicePort,而集群外的客户端只有一种访问方式,即:nodeIP+nodePort。

    #dev-4-worker2:
    #1、podIP+containerPort: curl http://10.244.1.9:80
    #2、nodeIP+nodePort:  curl http://172.18.0.3:30080
    #3、clusterIP+serviePort: curl http://10.96.48.151:8088
    
    #dev-2-worker:
    #1、nodeIP+nodePort:  curl http://172.18.0.3:30080

        不过大家发现问题没有?我们定义了hostPort,理论上hostPort和nodePort是一致的,但为什么无论集群内外的客户端都无法通过nodeIP+hostPort方式访问呢?看一下iptable信息吧

	root@dev-4-worker3:/# iptables -t nat -nvL | grep 9088
    0     0 CNI-HOSTPORT-SETMARK  tcp  --  *      *       10.244.1.0/24        0.0.0.0/0            tcp dpt:9088
    0     0 CNI-HOSTPORT-SETMARK  tcp  --  *      *       127.0.0.1            0.0.0.0/0            tcp dpt:9088
    0     0 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:9088 to:10.244.1.8:8081
    0     0 CNI-DN-ae37526a616fce7a60616  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            /* dnat name: "kindnet" id: "d5c4b7e0630bd6419d118eabcefe960976097792ac610eec265eecc691f9087a" */ multiport dports 9088
	

      看到了吗?9088端口的流量被转发给无效containerPort 8081了(说明deployment中的hostPort代理了外部到containerPort的流量),访问自然无法正常。我们修改一下containerPort,看看能否正常访问。
    
    看一下路由表,DNAT成功指向了80端口,再访问一下试试:

    root@dev-4-worker3:/# iptables -t nat -nvL | grep 9088
    0     0 CNI-HOSTPORT-SETMARK  tcp  --  *      *       10.244.1.0/24        0.0.0.0/0            tcp dpt:9088
    0     0 CNI-HOSTPORT-SETMARK  tcp  --  *      *       127.0.0.1            0.0.0.0/0            tcp dpt:9088
    0     0 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:9088 to:10.244.1.8:80
    0

路由结果正常了,我们再分别测试一下两个客户端的访问情况:

	同集群节点访问
    root@dev-4-worker3:/# wget http://172.18.0.3:9088
	--2023-04-20 03:13:13--  http://172.18.0.3:9088/
	Connecting to 172.18.0.3:9088... connected.
	HTTP request sent, awaiting response... 200 OK
	
	成功,再从异集群节点访问看看,
	
	root@dev-2-worker:/# wget http://172.18.0.3:9088
	--2023-04-20 03:15:30--  http://172.18.0.3:9088/
	Connecting to 172.18.0.3:9088... connected.
	HTTP request sent, awaiting response... 200 OK

为什么我们再deployment中定义了containerPort为8081,而实际侦听端口仍旧为80呢?检查一下image文件就可以发现端倪(ExposePorts已经写死了80为服务端口)。

	root@dev-4-worker2:/# crictl ps
	CONTAINER           IMAGE               CREATED             STATE               NAME                ATTEMPT             POD ID              POD
	8b328f18c15e7       4ea64ff11cebf       About an hour ago   Running             php-redis           0                   11329fb49ffe0       frontend-5b79c8694b-87xnh
	52a2ff4407dc2       2355926154447       5 hours ago         Running             leader              7                   d532eeac5a9ee       redis-leader-6b57b8f94f-598mp
	93d983ce50eee       eb3079d47a23a       5 hours ago         Running             kube-proxy          182                 c2c0ac4a7dbff       kube-proxy-sbrgc
	4106a715cae68       a329ae3c2c52f       5 hours ago         Running             kindnet-cni         7                   aa69fb8caeffe       kindnet-qvdcd
	
    root@dev-4-worker2:/# crictl inspecti 4ea64ff11cebf
	{
	  "status": {
		"id": "sha256:4ea64ff11cebf416e4a0629549d7f66275b8f1ba8e6dc714e44a1c47241b82d1",
		"repoTags": [
		  "docker.io/anjia0532/google_samples.gb-frontend:v5"
		],

		......

		"imageSpec": {
		  "created": "2021-12-31T18:54:06.462754392Z",
		  "architecture": "amd64",
		  "os": "linux",
		  "config": {
			"ExposedPorts": {
			  "80/tcp": {}
			},
			

好了,最后对几个port做一下简单的总结,如果错误不吝斧正:

container:containerPort 容器中服务的listen port,当然这个port能否通过containerPort指定取决与image的写法,比如文中所提写死80的做法,此时containerPort怎么设置都不会生效。
service:port 这个servicePort通常结合clusterIP使用的,用于集群内服务调用,当然集群内互访也可以通过podIP+containerPort、nodeIP+nodePort等方式访问,但这些方式没法做负载均衡和故障恢复透明。
service:targetport 这个需要和container的containerPort保持一致,我们看到service的endpoint列表中使用的是这个端口,如果和container不一致,则数据无法正常理由
service:nodePort 用于提供集群外的客户端访问,通过nodeIP + nodePort即可访问,但更常见的是用于前端的load balancer的服务端点
container:hostPort

这个和nodePort类似,早期k8s中nodePort会在node上起对应的nodePort侦听,而hostPort不会起侦听,不过现在的版本中无论hostPort还是nodePort都是通过ipvs实现端口映射,不会再启用侦听,不知道这两个port概念将来会不会删掉一个。



    文章来源地址https://www.toymoban.com/news/detail-553979.html

到了这里,关于k8s之containerPort、servicePort、nodePort、hostPort解析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • k8s-基础知识(Service,NodePort,CusterIP,NameSpace,资源限制)

    Node Node 是 Pod 真正运行的主机,可以是物理机,也可以是虚拟机。 Annotations 原文链接 Annotations 是 key/value 形式附加于对象的注解。不同于 Labels 用于标志和选择对象,Annotations 则是用来记录一些附加信息,用来辅助应用部署、安全策略以及调度策略等。比如 deployment 使用 an

    2024年01月24日
    浏览(56)
  • 【k8s完整实战教程5】网络服务配置(nodeport/loadbalancer/ingress)

    系列文章:这个系列已完结,如对您有帮助,求点赞收藏评论。 读者寄语: 再小的帆,也能远航! 【k8s完整实战教程0】前言 【k8s完整实战教程1】源码管理-Coding 【k8s完整实战教程2】腾讯云搭建k8s托管集群 【k8s完整实战教程3】k8s集群部署kubesphere 【k8s完整实战教程4】使用

    2024年02月13日
    浏览(69)
  • 一文读懂k8s的外网访问方式,Ingress/NodePort/LoadBanlancer

    本文首发自「慕课网」,想了解更多IT干货内容,程序员圈内热闻,欢迎关注\\\"慕课网\\\"! 作者:一凡|慕课网讲师 在k8s中创建的微服务,大部分都是在集群内部互相调用,这时候,使用DNS就可以很方面访问。 比如:服务名是 my-service,端口号是8080,命名空间是yifan,那么就可以

    2024年02月10日
    浏览(48)
  • k8s ipvs 模式下不支持 localhost:<nodeport>方式访问服务

    简介 今天去定位一个nodeport的问题,发现curl 127.0.0.1:32000 访问nodeport的时候会规律的hang住,本来以为是后端服务的问题,但是curl管理ip:nodeport 是正常的。这个就奇怪了,深入研究了下发现 ipvs模式下是不支持这样访问的,如果想使用 localhost: 得使用iptables模式。 下面是一个歪

    2024年02月22日
    浏览(39)
  • k8s服务发现(service discovery)常用的两种方式Nodeport和ClusterIP

    NodePort: 主要特点: 为Service在每个节点上分配一个固定的端口(NodePort),允许外部流量通过节点的IP地址和NodePort访问Service。 NodePort将流量从集群外部引入到Service内部。 Service类型为NodePort时,还会创建一个ClusterIP,但它只是一个内部的ClusterIP,通常不会直接使用。 使用场

    2024年02月05日
    浏览(45)
  • k8s的service资源类型有ClusterIP、Nodeport、ExternalName、LoadBalancer、Headless(None)

    ClusterIP 是在所有节点内生成一个虚拟IP,为一组pod提供统一的接入点,当service存在时,它的IP地址和端口不会发生改变,客户端通过service的ip和端口建立连接,由service将连接路由到该服务的任意一个后端pod上,通过这种方式,客户端不需要知道每个pod的具体ip,pod可以随时移

    2024年02月11日
    浏览(38)
  • 完美解决k8s master节点无法ping node节点中的IP或Service NodePort的IP

    1、问题一 使用搭建好了K8S集群,先是node节点加入k8s集群时,用的内网IP,导致master节点无法操作node节点中的pod(这里的不能操作,指定是无法查看node节点中pod的日志、启动描述、无法进入pod内部,即 kubectl logs 、kubectl  describe、kubectl exec -it 等等的命令都不能) 解决办法:

    2024年02月05日
    浏览(43)
  • 【K8S系列】深入解析k8s网络

    你只管努力,其他交给时间,时间会证明一切。 文章标记颜色说明: 黄色 :重要标题 红色 :用来标记结论 绿色 :用来标记一级论点 蓝色 :用来标记二级论点 Kubernetes (k8s) 是一个容器编排平台,允许在容器中运行应用程序和服务。今天学习一下k8s网络相关的内容 希望这篇

    2024年02月03日
    浏览(50)
  • 【K8S系列】深入解析K8S监控

    做一件事并不难,难的是在于坚持。坚持一下也不难,难的是坚持到底。 文章标记颜色说明: 黄色 :重要标题 红色 :用来标记结论 绿色 :用来标记论点 蓝色 :用来标记论点 Kubernetes (k8s) 是一个容器编排平台,允许在容器中运行应用程序和服务。今天学习一下k8s监控相关

    2024年02月12日
    浏览(46)
  • 【K8S系列】深入解析K8S调度

    做一件事并不难,难的是在于坚持。坚持一下也不难,难的是坚持到底。 文章标记颜色说明: 黄色 :重要标题 红色 :用来标记结论 绿色 :用来标记论点 蓝色 :用来标记论点 Kubernetes (k8s) 是一个容器编排平台,允许在容器中运行应用程序和服务。今天学习一下k8s调度相关

    2024年02月11日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包