我们上一章介绍了Docker基本情况,目前在规模较大的容器集群基本都是Kubernetes,但是Kubernetes涉及的东西和概念确实是太多了,而且随着版本迭代功能在还增加,笔者有些功能也确实没用过,所以只能按照我自己的理解来讲解。
我们上一小节介绍了如何创建一个svc以及svc如何通过标签绑定到工作负载上。并且也介绍了svc有几种类型,默认不做任何标识的情况下,就是ClusterIP,这个服务类型只能在集群内部访问,也就是只能在k8s所有的节点访问。如果要对k8s集群外部访问,则需要通过其他方式,下面我们将介绍其他几种服务类型。
NodePort
这种类型的Service在ClusterIP的基础上,为Service在每个节点的IP上提供一个静态端口(NodePort)。这样,Service可以通过<NodeIP>:<NodePort>
的方式从集群外部访问。NodePort通常在30000-32767之间的范围内分配,如果你有特殊需求也可用通过修改kube-apiserver.yaml文件,在里面添加参数--service-node-port-range=20000-30000(注意格式),来调整这个端口范围。
#这个是修改以后查询结果。
[root@master01 ]# kubectl cluster-info dump |grep service-node-port-range
"--service-node-port-range=20000-30000"
[root@master01 ]#
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: NodePort # 添加此行以更改服务类型为 NodePort,未添加则是ClusterIP
selector:
app: myapp
ports:
- protocol: TCP
port: 80 # 服务的集群内部端口
targetPort: 80 # Pod 上的应用程序端口
nodePort: 30008 # 可选:指定 NodePort 的端口号,如果不指定则自动分配
这样,我们就可用通过集群任意节点的30008端口访问到这个服务,比如当前集群有2个ip地址:192.168.31.211,192.168.31.212,则它可以通过192.168.31.211:30008和192.168.31.212:30008访问,如果还有更多节点也可用通过其他节点的30008端口进行访问。
LoadBalancer
这种Service类型在NodePort的基础上,还会请求云提供商的负载均衡器。这个负载均衡器会将外部的流量分发到集群中的Pods。这是让Service能够从互联网上可达的常用方式。
当然这个需要额外第三方的负载均衡才能实现支持,本地测试环境可用使用metallb来模拟,由于暂时没下载到镜像,后期把镜像准备好以后单独再出一期。实际上就是在我们原来的NodePort之外再套一层ip地址,这个ip地址的后端就是所有的NodeIP+NodePort。
无头服务(Headless Service)
无头服务(Headless Service)是 Kubernetes 中的一种特殊类型的服务,它允许你创建没有集群 IP 的服务。这意味着该服务不会分配一个虚拟的集群 IP 地址,而是直接将 DNS 查询解析为后端 Pod 的 IP 地址列表。实际上主要就是StatefulSet在使用。
apiVersion: v1
kind: Service
metadata:
name: my-headless-service
spec:
clusterIP: None # 设置为 None 来创建无头服务
selector:
app: myapp
ports:
- protocol: TCP
port: 80
targetPort: 80
从上图可用看到,我们这个svc是没有ip地址的,所以我们不能直接通过svc名字来解析,而它主要同sts配合使用,服务地址就和sts的pod名字相关,这里涉及到coredns,由于我们还没讲到coredns,所以这里只需要知道它的这个无头服务是怎么构成即可。
sts容器名字.服务名字.命名空间.svc.集群名字,有了这个固定名字我们哪些有状态应用就可用通过这个地址维持集群状态。
#3个pod就有3个地址,cluster.local是集群名字
nginx-statefulset-1.my-headless-service.default.svc.cluster.local
nginx-statefulset-2.my-headless-service.default.svc.cluster.local
nginx-statefulset-3.my-headless-service.default.svc.cluster.local
sts需要和这个svc名字对应起来。
spec:
serviceName: "my-headless-service"
#太久没使用,写这篇文章都折腾了很久才找到问题。
这里涉及到coredns的服务,稍后我们会单独出一期来讲。