上次我们对Service服务有了详细的了解,今天给大家分享Service服务究竟有哪些类型以及各个类型又是怎么样的存在?
对一些应用(如 Frontend)的某些部分,可能希望通过外部(Kubernetes 集群外部)IP地址暴露Service服务。
Kubernetes Service Types允许指定一个需要的类型的Service,默认是ClusterIP类型。
服务类型有:
1. ClusterIP
2. nodePort
3. LoadBalancer
4. ExternalName
01ClusterIP
ClusterIP(内网ip),暴露集群IP和端口号,解决IP随Pod变化的问题.
编辑一个service-clusterip.yaml文件,内容如下:
apiVersion: v1
kind: Service
metadata:
name: service-clusterip
namespace: test
spec:
selector:
app: nginx
clusterIP: 10.96.0.11 #表示sevice的IP地址,可以设置,也可以不设置,不设置会默认分配一个
IP地址
type: ClusterIP
ports:
- protocol: TCP
port: 80 #表示设置service的端口
targetPort: 80 #表示设置pod的端口
再使用以下命令进行创建
[root@master ~]# kubectl apply -f service-clusterip.yaml
创建成功后,可以使用以下命令查看service的详情
[root@master ~]# kubectl describe svc service-clusterip -n test
Name: service-clusterip
Namespace: test
Labels: <none>
Annotations: <none>
Selector: app=nginx
Type: ClusterIP
IP: 10.96.0.11
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.104.29:80,10.244.104.51:80,10.244.104.7:80
Session Affinity: None
Events: <none>
在上面的信息中可以看到三个POD节点对应的IP地址,其中endpoints是kubernetes中的一个资源对象,存储在etcd中,用来记录一个service对应的所有pod的访问地址,它是根据service配置文件中selector描述产生的。
再使用以下命令查看KUBE-SERVICES target:
[root@master ~]# iptables -nvL -t nat | grep KUBE-SVC
0 0 KUBE-SVC-QVNRCSZEL5TGFQEZ tcp -- * * 0.0.0.0/0
0.0.0.0/0 /* test/service-nodeport */ tcp dpt:30002
0 0 KUBE-SVC-LOLE4ISW44XBNF3G tcp -- * * 0.0.0.0/0
0.0.0.0/0 /* default/web */ tcp dpt:32259
0 0 KUBE-SVC-CEZPIJSAUFW5MYPQ tcp -- * * 0.0.0.0/0
0.0.0.0/0 /* kubernetes-dashboard/kubernetes-dashboard */ tcp
dpt:32349
0 0 KUBE-SVC-JD5MR3NA4I4DYORP tcp -- * * 0.0.0.0/0
10.96.0.10 /* kube-system/kube-dns:metrics cluster IP */ tcp
dpt:9153
0 0 KUBE-SVC-Z6GDYMWE5TV2NNJN tcp -- * * 0.0.0.0/0
10.96.59.159 /* kubernetes-dashboard/dashboard-metrics-scraper
cluster IP */ tcp dpt:8000
0 0 KUBE-SVC-NPX46M4PTMTKRN6Y tcp -- * * 0.0.0.0/0
10.96.0.1 /* default/kubernetes:https cluster IP */ tcp dpt:443
0 0 KUBE-SVC-QVNRCSZEL5TGFQEZ tcp -- * * 0.0.0.0/0
10.96.217.148 /* test/service-nodeport cluster IP */ tcp dpt:80
0 0 KUBE-SVC-LOLE4ISW44XBNF3G tcp -- * * 0.0.0.0/0
10.96.210.17 /* default/web cluster IP */ tcp dpt:80
0 0 KUBE-SVC-H6S3G453RTJY5LVE tcp -- * * 0.0.0.0/0
10.96.0.11 /* test/service-clusterip cluster IP */ tcp dpt:80
接下来可以使用以下命令来测试负载的算法:
[root@master ~]# while true;do curl 10.96.0.11:80;sleep 5;done;
10.244.104.7
10.244.104.29
10.244.104.51
10.244.104.51
10.244.104.51
上面的测试是先修改了每台nginx首页的内容,具体如何修改,步骤如下:
#1.先查看pod节点名
[root@master ~]# kubectl get pods -n test
NAME READY STATUS RESTARTS AGE
web-test-7f4fc68488-4swtz 1/1 Running 10 66d
web-test-7f4fc68488-b4t6r 1/1 Running 10 66d
web-test-7f4fc68488-jcwhx 1/1 Running 10 66d
#2.进入pod节点容器
[root@master ~]# kubectl exec -it web-test-7f4fc68488-4swtz -n test -- /bin/sh
#3.执行echo命令,修改首页内容
# echo '10.244.104.7' > /usr/share/nginx/html/index.html
02nodePort
上面介绍了ClusterIP的通信方式,但有一个问题是ClusterIP只允许内部通信,这个通信是不能通过外界来访问的,如果需要将这个端口暴露到外面,则可以使用nodeport方式。
生产环境比较好的方案就是借助云服务商使用LoadBalancer的方式,但由于是测试环境就使用了比较简单的NodePort来暴露服务,在实践过程中,也加深了对K8s概念的理解。
NodePort是外部流量访问K8s的一种方式,即nodeIP:nodePort,是提供给外部流量访问K8s集群资源的一种方式。
例如需要暴露服务的端口给外界访问的话可以通过命令:
[root@master ~]# kubectl expose deployment web-test --type=NodePort -n test
service/web-test exposed
编辑一个nodeport的yaml文件,内容如下:
apiVersion: v1
kind: Service
metadata:
name: service-nodeport
namespace: test
spec:
selector:
app: nginx
type: NodePort
ports:
- protocol: TCP
port: 80 #服务器访问端口
nodePort: 30002 #指定绑定的node的端口(默认的取值范围是:30000-32767),如果不指定,
会默认分配
targetPort: 80 #容器端口
容器的端口,也是最终底层的服务所提供的端口,所以说targetPod也就是Pod的端口。从port或者是nodePort进入的流量,经过路由转发之后,最终都会都通过targetPort进入到Pod中。
再创建service资源
[root@master ~]# kubectl apply -f service-nodeport.yaml
再使用以下命令查看service的详细信息
[root@master ~]# kubectl get svc -n test -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
SELECTOR
service-clusterip ClusterIP 10.96.0.11 <none> 80/TCP 23h
app=nginx
service-nodeport NodePort 10.96.217.148 <none> 80:30002/TCP 67d
app=nginx
web-test NodePort 10.96.50.184 <none> 80:30648/TCP 52m
app=nginx
这可样就可以通过http://192.168.158.100:30002/来访问站点
03LoadBalancer
使用云提供商的负载均衡器向外部暴露服务。外部负载均衡器可以将流量路由到自动创建的NodePort 服务和 ClusterIP 服务上。
loadbalancer-my-service.yaml 配置文件的内容如下,设置 type 的值为 LoadBalancer,将为Service 提供负载均衡器。负载均衡器是异步创建的,关于被提供的负载均衡器的信息将会通过 Service的 status.loadBalancer 字段发布出去。通过 kubectl 命令创建,kubectl apply -f loadbalancer-myservice.yaml。
apiVersion: v1
kind: Service
metadata:
name: loadbalancer-my-service
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
type: LoadBalancer
status:
loadBalancer:
ingress:
- ip: 192.0.2.127