0
点赞
收藏
分享

微信扫一扫

15、创建Service资源规范及Service的三种类型实例

创建Service资源
由Service表示的负载均衡器,主要定义如下内容

负载均衡器入口:ClusterIP及相关的Service Port、NodePort(每个节点的Node IP都可用)
◆ 根据通信需求,确定选择的类型

标签选择器:用于筛选Pod,并基于筛选出的Pod的IP生成后端端点列表(被调度的上游端点)

Service类型的专有配置

Service资源规范
Kubernetes上标准的API资源类型

apiVersion: v1
kind: Service
metadata:
name: …
namespace: …
spec:
type <string> # Service类型,默认为ClusterIP
selector <map[string]string> # 等值类型的标签选择器,内含“与”逻辑
ports: # Service的端口对象列表
- name <string> # 端口名称
protocol <string> # 协议,目前仅支持TCP、UDP和SCTP,默认为TCP
port <integer> # Service的端口号
targetPort <string> # 后端目标进程的端口号或名称,名称需由Pod规范定义
nodePort <integer> # 节点端口号,仅适用于NodePort和LoadBalancer类型(最好交给集群自己选择,即使自己指定端口,也只能指定30000-32768之间,不建议自己制定端口)
clusterIP <string> # Service的集群IP,建议由系统自动分配
externalTrafficPolicy <string> # 外部流量策略处理方式,Local表示由当前节点处理,Cluster表示向集群范围调度
loadBalancerIP <string> # 外部负载均衡器使用的IP地址,仅适用于LoadBlancer
externalName <string> # 外部服务名称,该名称将作为Service的DNS CNAME值

Service资源示例

ClusterIP Service

kind: Service
apiVersion: v1
metadata:
name: demoapp
spec:
type: ClusterIP # 类型标识,默认即为ClusterIP;
selector:
app: demoapp
ports:
- name: http # 端口名称标识
protocol: TCP # 协议,支持TCP、UDP和SCTP
port: 80 # Service的端口号
targetPort: 80 # 目标端口号,即后端端点提供服务的监听端口号

NodePort Service和LoadBalancer

kind: Service
apiVersion: v1
metadata:
name: demoapp
spec:
type: NodePort # 必须明确给出Service类型 ,如果是LoadBalancer,改为即可
selector:
app: demoapp
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
nodePort: 30080 # 可选,为避免冲突,建议由系统动态分配

实际案例:clusterIP

拉取pod
kubectl create deployment demoapp --image=ikubernetes/demoapp:v1.0 --replicas=2
给pod打标签
[root@K8s-master01 chapter7]#kubectl label pods demoapp-55c5f88dcb-6g9k4 version=v1.0
pod/demoapp-55c5f88dcb-6g9k4 labeled
查看pods的标签
[root@K8s-master01 chapter7]#kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
demoapp-55c5f88dcb-6g9k4 1/1 Running 0 8m3s app=demoapp,pod-template-hash=55c5f88dcb,version=v1.0
demoapp-55c5f88dcb-c6lb2 1/1 Running 0 8m3s app=demoapp,pod-template-hash=55c5f88dcb,version=v1.0

service引用标签
[root@K8s-master01 chapter7]#cat services-clusterip-demo.yaml
---
kind: Service
apiVersion: v1
metadata:
name: demoapp-svc
namespace: default
spec:
clusterIP: 10.97.72.1
selector: #标签选择器
app: demoapp
version: v1.0
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
创建service
[root@K8s-master01 chapter7]#kubectl apply -f services-clusterip-demo.yaml
service/demoapp-svc created
查看service
[root@K8s-master01 chapter7]#kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
demoapp-svc ClusterIP 10.97.72.1 <none> 80/TCP 28s
查看更多信息,可显示标签选择器
[root@K8s-master01 chapter7]#kubectl get svc -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
demoapp-svc ClusterIP 10.97.72.1 <none> 80/TCP 74s app=demoapp,version=v1.0
查看service的详情,可查看到service下对应的pod
[root@K8s-master01 chapter7]#kubectl describe service demoapp-svc
Name: demoapp-svc
Namespace: default
Labels: <none>
Annotations: <none>
Selector: app=demoapp,version=v1.0
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.97.72.1
IPs: 10.97.72.1
Port: http 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.3.62:80,10.244.4.60:80
Session Affinity: None
Events: <none>

实际案例:NodePort(适合内部使用)

拉取pod
kubectl create deployment demoapp --image=ikubernetes/demoapp:v1.0 --replicas=1
给pod打标签
[root@K8s-master01 chapter7]#kubectl label pods demoapp-55c5f88dcb-6g9k4 version=v1.0
查看pods的标签
[root@K8s-master01 chapter7]#kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
demoapp-55c5f88dcb-wkmk7 1/1 Running 0 81m app=demoapp,pod-template-hash=55c5f88dcb,version=v1.1

定义service的yaml文件
[root@K8s-master01 chapter7]#cat services-nodeport-demo.yaml
---
kind: Service
apiVersion: v1
metadata:
name: demoapp-nodeport-svc
spec:
type: NodePort
#clusterIP: 10.97.56.1 #为了避免冲突,clusterIP尽量不要指定
selector:
app: demoapp
version: v1.1
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
nodePort: 31398
# externalTrafficPolicy: Local #定义成Local会出问题,pod在哪个节点上,只能在哪个节点接入,因为他只会调度到该节点之上的pod,如果该节点没有pod,又正好访问到这个节点,流量就不会转过去。除非前面自己加了LoadBalancer,明确知道往哪里调度,能自动通过API-Server查找出来。外部流量不要改为local

运行service并查看
[root@K8s-master01 chapter7]#kubectl apply -f services-nodeport-demo.yaml
service/demoapp-nodeport-svc created
[root@K8s-master01 chapter7]#kubectl get svc -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
demoapp-nodeport-svc NodePort 10.108.186.163 <none> 80:31398/TCP 4m34s app=demoapp,version=v1.1
查看详情
[root@K8s-master01 chapter7]#kubectl describe svc demoapp-nodeport-svc
Name: demoapp-nodeport-svc
Namespace: default
Labels: <none>
Annotations: <none>
Selector: app=demoapp,version=v1.1
Type: NodePort
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.100.240.189
IPs: 10.100.240.189
Port: http 80/TCP
TargetPort: 80/TCP
NodePort: http 31398/TCP
Endpoints: 10.244.5.47:80 #关联的端点
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
根据标签选择器过滤查看端点IP在那个节点上运行
[root@K8s-master01 chapter7]#kubectl get pods -l version=v1.1 -L version -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES VERSION
demoapp-55c5f88dcb-wkmk7 1/1 Running 0 88m 10.244.5.47 k8s-node02 <none> <none> v1.1
可知service的端点IP在k8s-node02运行

用集群外部服务对集群的节点进行访问测试,可得到下列信息(随意节点ip加port)
iKubernetes demoapp v1.0 !! ClientIP: 10.244.0.0, ServerName: demoapp-55c5f88dcb-wkmk7, ServerIP: 10.244.5.47!

如果service定义的yaml文件中,把外部流量策略定义成Local,那流量不会接入到服务上。因为有的节点上没有所访问服务得pod,他不会自动调度到有服务的节点上去
externalTrafficPolicy: Local (除了访问服务所在的节点IP+Port可以接收到流量)
不加流量策略,默认为Cluster

实际案例:LoadBalancer(依赖条件:集群外部的负载均衡,需要LBaaS服务的支持或需要LoadBalancer底层公有云服务与节点建立关联关系)

[root@K8s-master01 chapter7]#cat services-loadbalancer-demo.yaml 
kind: Service
apiVersion: v1
metadata:
name: demoapp-loadbalancer-svc
spec:
type: LoadBalancer
selector:
app: demoapp
version: v1.0
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
#loadBalancerIP: 1.2.3.4 #加上去,可能也不会有什么作用,因为没有外部的loadBalancer可以用

创建service并查看
[root@K8s-master01 chapter7]#kubectl apply -f services-loadbalancer-demo.yaml
service/demoapp-loadbalancer-svc created
[root@K8s-master01 chapter7]#kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
demoapp-loadbalancer-svc LoadBalancer 10.104.82.171 <pending> 80:30234/TCP 18s

通过外部访问节点IP加port(任何节点IP+Port都可以,并且可以自动做负载均衡。因为默认的流量策略是集群级的)
iKubernetes demoapp v1.0 !! ClientIP: 10.244.1.0, ServerName: demoapp-55c5f88dcb-wkmk7, ServerIP: 10.244.5.47!

ExternalIP

service在使用LoadBalancer类型时,在External-IP字段上,正常会生成IP地址,如果没有便一直处于pending状态,意味着没能对接到外部的LoadBalancer所谓的LBaaS服务之上来得到IP地址,可以人为的手动分一个地址
此地址为某个节点特有,除非使用keepalived把公网地址能够在多个节点上进行漂移并绑定Service
[root@K8s-master01 chapter7]#kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
demoapp-loadbalancer-svc LoadBalancer 10.104.82.171 <pending> 80:30234/TCP 18s

第一步:在某一节点增加公网地址
第二步:定义service的资源配置
kind: Service
apiVersion: v1
metadata:
name: demoapp
spec:
type: ClusterIP # 类型标识,默认即为ClusterIP;
selector:
app: demoapp
ports:
- name: http # 端口名称标识
protocol: TCP # 协议,支持TCP、UDP和SCTP
port: 80 # Service的端口号
targetPort: 80 # 目标端口号,即后端端点提供服务的监听端口号
externalIPs:
-172.29.6.200
kubectl apply -f demoapp.yaml
会发现有一地址已经绑定

Service接入流量入口

ClusterIP:内部流量 
NodePort: 外部流量
ExternalIP:外部流量 (某个节点特有,除非使用keepalived把公网地址能够在多个节点上进行漂移并绑定Service)

总结

Service类型:
ClusterIP:只能接收集群内部流量
NodePort:增强版的Cluster,可以接受集群内部的流量,也可以接收集群外部的流量
externalTrafficPolicy:流量策略
Local
Cluster
端口范围: (30000-32768)
非标准端口,访问不变,这种类型实验用,客户端不知道端口,访问不便,不适合生产中使用

LoadBalancer:依赖于底层公有云的环境或基础设施环境满足其需要的功能。就是在集群外部为每一个定义成LoadBalancer类型的服务创建一个负载均衡器
依赖调减:集群外部的负载均衡器(OpenELB),还得能够与API-Server进行联动以实现更加高级的功能

举报

相关推荐

0 条评论