Kubernetes 将Service暴露到集群外部

Kubernetes 为Service 创建的CLusterIP 地址是对后端Pod列表的一层抽象,对于集群外部来说并没有意义,但有许多Service 是需要对集群外部提供服务的,Kubernetes提供了多种机制将Service 是暴露出去,供集群外部的客户端访问。这可以通过Service 资源对象的类型字段“type” 进行设置。

目前Service的类型如下:
(1)ClusterIP : Kubernetes 默认会自动设置Service 的 虚拟IP地址,仅可被集群内部的客户端应用访问,当然,用户也可手工指定一个ClusterIP 地址,不过需要确保该IP 在Kubernetes集群设置的ClusterIP 地址范围内(通过kube-apiserver服务的启动参数–service-cluster-ip-range设置),并且没有被其他Service 使用。
(2)NodePort: 将Service 的端口号映射到每个Node的一个端口号上,这样集群中的任意Node 都可以作为Service 的访问入口地址,即NodeIP:NodePort。
(3)LoadBalancer: 将Service 映射到一个已存在的负载均衡的IP 地址上,通常在公有云环境中使用。
(4)ExternalName: 将Service 映射为一个外部域名地址,通过externalName 字段进行设置。

1. NodePort类型
下面的例子设置Service的类型为NodePort,并且设置具体nodePort端口号为30002:

# webapp-svc-nodeport.yaml 
apiVersion: v1
kind: Service
metadata: 
  name: webapp
spec: 
  type: NodePort
  ports: 
  - port: 8080
    targetPort: 8080
    nodePort: 8081 -> 30002 # 这里我报错了,如下
  selector: 
    app: webapp

创建:

[root@k8s-master ~]# kubectl create -f webapp-svc-nodeport.yaml 
The Service "webapp" is invalid: spec.ports[0].nodePort: Invalid value: 8081: provided port is not in the valid range. The range of valid ports is 30000-32767

这是什么错误呢,是因为端口号受限了。

解决的办法:

#编辑 kube-apiserver.yaml文件
vim /etc/kubernetes/manifests/kube-apiserver.yaml
#找到 --service-cluster-ip-range 这一行,在这一行的下一行增加 如下内容
- --service-node-port-range=1-65535
#最后 重启 kubelet
systemctl daemon-reload
systemctl restart kubelet

在这里插入图片描述
这里说明一下,我换了一个端口号,将8081 改成30002

[root@k8s-master ~]# kubectl create -f webapp-svc-nodeport.yaml 
service/webapp created

r然后就可以通过任意一个node 的IP 地址和NodePort. 30002 端口号访问服务:

[root@k8s-master ~]# curl 172.16.185.161:30002
<!DOCTYPE html>
<html lang="en">
.....
[root@k8s-node-1 ~]# curl 172.16.185.162:30002
<!DOCTYPE html>
<html lang="en">
.....
[root@k8s-node-2 ~]# curl 172.16.185.163:30002
<!DOCTYPE html>
<html lang="en">
.....

在默认情况下,Node的kube-proxy 会在全部网卡(0.0.0.0)上绑定NodePort 端口号。

在很多数据中心环境中,一台主机会配置多块网卡,作用各不相同(例如存在业务网卡和管理网卡等)。从Kubernetes 1.10 版本开始,kube-proxy 可以通过设置特定的IP 地址将NodePort 绑定到特定的网卡上,而无须绑定再全部网卡上,其设置方式为配置启动参数,“–nodeport-addresses”,指定需要绑定的网卡IP地址,多个地址之间使用逗号分隔。例如仅在10.0.0.0和192.168.18.0 对应的网卡上绑定NodePort 端口号,对其他IP 地址对应的网卡不会进行绑定,配置如下:

--nodeport-addresses=10.0.0.0/8,192.168.18.0/24

另外,如果用户在Service 定义中不设置具体的nodePort 端口号,则Kubernetes 会自动分配一个NodePort 范围内的可用端口号。

2. LoadBalancer类型
通常在公有云环境中设置Service 的类型为“LoadBalancer” ,可以将Service 映射到公有云提供的某个负载均衡器的IP地址,客户端通过负载均衡器的IP 和 Servcie 的端口号就可以访问到具体的服务,无须再通过kube-proxy提供的负载均衡机制进行流量转发。公有云提供的LoadBalancer 可以直接将流量转发到后端Pod 上,而负载分发机制依赖于公有云服务商的具体实现。

下面的例子设置Service 的类型为LoadBalancer:

apiVersion: v1
kind: Service
metadata: 
  name: my-service
spec: 
  type: LoadBalancer
  selector: 
    app: MyApp
  ports: 
  - ptotocol: TCP
    port: 80
    targetPort: 9376
  clusterIP: 10.1.10.125

[root@k8s-master ~]# kubectl create -f loadBalancer.yaml 
service/my-service created

[root@k8s-master ~]# kubectl get svc
NAME         TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
my-service   LoadBalancer   10.1.10.125    <pending>     80:30357/TCP     10m

可以看到的是状态一直都是 pending。

我们先查看详情有没有报错:

[root@k8s-master ~]# kubectl describe svc my-service
Name:                     my-service
Namespace:                default
Labels:                   <none>
Annotations:              <none>
Selector:                 app=MyApp
Type:                     LoadBalancer
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.1.10.125
IPs:                      10.1.10.125
Port:                     <unset>  80/TCP
TargetPort:               9376/TCP
NodePort:                 <unset>  30357/TCP
Endpoints:                <none>
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

问题原因:
查看了官方文档,自己搭建的k8s集群 (公有云环境除外),是没有LB能力的。
在这里插入图片描述

3.ExternalName 类型
ExternalName类型的服务用于将集群外的服务定义为Kubernetes 的集群的Service,并且通过externalName 字段指定外部服务的地址,可以使用域名或IP 格式,集群内的客户端应用通过访问这个Service 就能访问外部服务了。这种类型Service 没有后端Pod,所以无须设置Label Selector ,例如:

apiVersion: v1
kind: Service
metadata: 
  name: my-service
  namespace: prod
spec: 
  type: ExternalName
  externalName: my.database.example.com
    

在本例中设置的服务名为my-service,所在namspace 为prod ,客户端访问服务地址my-service.prod.svc.cluster.local时,系统将自动指向外部域名my.database.example.com。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝颜~岁月

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值