Kubernetes——使用NodePort的方式让外部访问Tomcat集群

本文档介绍了如何使用Kubernetes的NodePort方式让外部访问Tomcat集群。首先,解释了Service概念,然后展示了创建Service的YML配置,详细说明了port、targetPort、nodePort的区别。接着,通过创建并部署Service,实现了外部通过主机IP和nodePort访问Tomcat服务。最后,针对访问问题进行了排查和解决。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用NodePort的方式外部访问Tomcat集群

一、通过NodePort的方式

1.1 引入服务概念

此时,就要涉及到service[服务](# 3.6、Service(服务))的概念了

上面使用yml部署的Tomcat暂时无法被外部访问,此时就需要如下的结构图
在这里插入图片描述
图中的各种IP为容器内部的虚拟IP

1.2 yml中写一个service

apiVersion: v1
kind: Service
metadata:
  name: tomcat-service
  labels:
    app: tomcat-service
sepc:
  type: NodePort
  # 选择器,此处的app名称,对应了前面deploy部署tomcat时候设置的label值
  selector:
    app: tomcat-cluster
  ports:
  - port: 8000
    targetPort: 8080
    nodePort: 31000
image-20211122121809036
1.2.1 关于port、targetPort、nodePort的解释

Service:将流量引向一个pod。

TargetPort:你的应用程序在容器内运行的真实的端口。

Port:有些时候,你在容器内的应用程序在不同的端口上提供了不同的服务。

例子:实际的应用程序运行在8080,而这个应用程序的健康检查可以在容器的8089端口上进行。

因此,如果你在没有端口的情况下访问Service,它不知道应该把请求重定向到容器的哪个端口。所以Service需要有一个映射,以便它能定位到容器的指定端口上。

kind: Service
apiVersion: v1
metadata:
  name: my-service
spec:
  selector:
    app: MyApp
  ports:
    - name: http
      nodePort: 30475
      port: 8089
      protocol: TCP
      targetPort: 8080
    - name: metrics
      nodePort: 31261
      port: 5555
      protocol: TCP
      targetPort: 5555
    - name: health
      nodePort: 30013
      port: 8443
      protocol: TCP
      targetPort: 8085 

​ 如果你访问my-service:8089,流量会被路由到容器(目标端口)的8080上。同样,如果你访问my-service:8443,那么它将被重定向到容器的8085(目标端口)。但是这个myservice:8089是kubernetes集群内部的,当一个应用程序想与另一个应用程序通信时可以使用。因此,要从集群外部访问该服务,需要在运行kubernetes的主机上公开暴露该端口,这样,流量就会被重定向到容器的一个端口。这就是"node port"(在物理主机暴露的端口)。

​ 上面的例子中,你可以通过host_ip:nodePort从集群外部访问服务。

​ 假设你的主机ip是10.10.20.20,你可以通过10.10.20.20:3047510.10.20.20:3126110.10.20.20:30013来访问http、metrics、health服务。

从 **Service(服务)**角度来考虑问题:

  • nodePort:物理节点上的端口,外部流量将通过该端口进入。
  • port::服务的端口。
  • targetPort:要转发流量到pod上容器的真实目标端口。

流量从nodePort进入,转发到服务的port,然后转发到pod上的targetPort

值得强调的是,nodePort是为外部流量服务的。集群中的其他pod可能需要访问该服务,将只使用port,而不是nodePort,因为这只是对服务的内部访问。

另外值得注意的是,如果没有设置targetPort,它将默认为与port相同的值。例如,80:80代表服务端口80,目标是容器端口80

1.3 部署service

1.3.1 创建service
[root@k8s-master tomcat-service]# kubectl create -f test-service.yml 
service/tomcat-service created

1.3.2 查看service状态

[root@k8s-master tomcat-service]# kubectl get service
NAME             TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
kubernetes       ClusterIP   10.96.0.1        <none>        443/TCP          16d
tomcat-service   NodePort    10.100.153.181   <none>        8000:31000/TCP   110s

1.3.3 查看service详细状态

[root@k8s-master tomcat-service]# kubectl describe service tomcat-service
# 当前service的名称
Name:                     tomcat-service
# 默认的命名空间
Namespace:                default
# 当前service的标签
Labels:                   app=tomcat-service
Annotations:              <none>
# 哪些deploy归这个service管理
Selector:                 app=tomcat-cluster
Type:                     NodePort
# service的ip,与tomcat-cluster中的每一个ip都是互联互通的
IP:                       10.100.153.181
# 服务的port,供一个pod内部由多个服务时使用
Port:                     <unset>  8000/TCP
# 容器内部的port
TargetPort:               8080/TCP
NodePort:                 <unset>  31000/TCP
Endpoints:                <none>
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

1.3.4 访问测试

http://192.168.8.65:31000

http://192.168.8.66:31000

此时会发现

image-20211122154617587

这个是正常现象,可以进入容器内部查看一下,和docker学习的时候一样,会发现实际上在容器的tomcat内部,存在两个目录,一个webapps,一个webapps.dist,而webapps是空目录,webapps.dist才是我们所认知中的那个初始页面,我们只需要删除webapps目录,随后再把webapps.dist重命名即可。

image-20211122154912662
[root@k8s-master tomcat-deploy]# kubectl get pod
NAME                             READY   STATUS    RESTARTS   AGE
tomcat-deploy-5fd4fc7ddb-8mlm7   1/1     Running   0          96s
tomcat-deploy-5fd4fc7ddb-kv2qc   1/1     Running   0          96s
[root@k8s-master tomcat-deploy]# kubectl exec -ti tomcat-deploy-5fd4fc7ddb-kv2qc bash
root@tomcat-deploy-5fd4fc7ddb-kv2qc:/usr/local/tomcat# ls
BUILDING.txt  CONTRIBUTING.md  LICENSE	NOTICE	README.md  RELEASE-NOTES  RUNNING.txt  bin  conf  lib  logs  native-jni-lib  temp  webapps  webapps.dist  work
root@tomcat-deploy-5fd4fc7ddb-kv2qc:/usr/local/tomcat# rm -rf webapps
root@tomcat-deploy-5fd4fc7ddb-kv2qc:/usr/local/tomcat# ls
BUILDING.txt  CONTRIBUTING.md  LICENSE	NOTICE	README.md  RELEASE-NOTES  RUNNING.txt  bin  conf  lib  logs  native-jni-lib  temp  webapps.dist  work
root@tomcat-deploy-5fd4fc7ddb-kv2qc:/usr/local/tomcat# mv webapps.dist/ webapps
lsroot@tomcat-deploy-5fd4fc7ddb-kv2qc:/usr/local/tomcat# ls
BUILDING.txt  CONTRIBUTING.md  LICENSE	NOTICE	README.md  RELEASE-NOTES  RUNNING.txt  bin  conf  lib  logs  native-jni-lib  temp  webapps  work

再次访问,即可出现梦想中的页面

image-20211122155240210

Kubernetes其他文档列表

### 配置 Kubernetes 外部访问 Tomcat Pod 的最佳实践 在 Kubernetes 中实现外部网络访问 Tomcat Pod 可以通过两种主要方式完成:Service 和 Ingress。以下是这两种方法的具体说明。 #### 使用 Service 实现外部访问 Kubernetes 提供了几种类型的 Service 来暴露应用给外部流量,其中最常用的是 `NodePort` 和 `LoadBalancer` 类型的服务: - **NodePort**: 将服务映射到节点上的特定端口 (范围通常为 30000 到 32767),从而允许外部客户端通过 `<node-ip>:<node-port>` 访问该服务。 ```yaml apiVersion: v1 kind: Service metadata: name: tomcat-service spec: type: NodePort ports: - port: 8080 targetPort: 8080 nodePort: 30001 selector: app: tomcat ``` - **LoadBalancer**: 如果云提供商支持,则会自动创建一个负载均衡器并将请求转发至集群内的服务实例。此选项适用于托管环境下的 K8S 集群[^1]。 #### 使用 Ingress 实现外部访问 对于更复杂的路由需求或者希望减少对外暴露的 IP 地址数量时,可以考虑采用 Ingress 资源配合相应的控制器一起工作: - 创建一个名为 `ingress-tomcat.yaml` 文件定义如下规则: ```yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: tomcat-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - host: tomcat.example.com http: paths: - pathType: Prefix path: "/" backend: service: name: tomcat-service port: number: 8080 ``` - 确保已经安装并运行了一个合适的 Ingress 控制器(比如 NGINX),它负责监听 API Server 并动态更新其内部代理设置以便于处理传入连接[^4]。 上述配置中提到的 Host 字段可以根据实际域名调整;Path 定义了匹配 URL 前缀的行为模式。当用户尝试打开指定地址时,他们的浏览器会被引导至关联好的后端服务上去[^2]。 最后值得注意的一点在于某些情况下可能还需要额外的安全措施诸如 SSL/TLS 加密传输数据流等操作,在这种场景下可以通过修改 YAML 添加 secret 引用字段来启用 HTTPS 支持[^3]。 ```bash kubectl apply -f ingress-tomcat.yaml ``` 以上命令用于提交更改后的 manifest 至当前上下文中所选 namespace 下生效执行整个流程直至成功部署完毕为止。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值