k8s资源对象(3)service
service的使用介绍
1.Service
在kubernetes中,pod是应用程序的载体,我们可以通过pod的ip来访问应用程序,但是pod的ip地址不是固定的,这也就意味着不方便直接采用pod的ip对服务进行访问。
为了解决这个问题,kubernetes提供了Service资源,Service会对提供同一个服务的多个pod进行聚合,并且提供一个统一的入口地址。通过访问Service的入口地址就能访问到后面的pod服务。service创建后, 会创建一个同名的endpoint控制器,用来管理后端endpoint。通过就绪探针来检测后端端点是否正常工作。为pod添加标签,service使用标签选择器,来选择自己的后端端点,还能够根据探针(使用endpoint)对后端端点进行就绪状态检测
Service在很多情况下只是一个概念,真正起作用的其实是kube-proxy服务进程,每个Node节点上都运行着一个kube-proxy服务进程。当创建Service的时候会通过api-server向etcd写入创建的service的信息,而kube-proxy会基于监听的机制发现这种Service的变动,然后它会将最新的Service信息转换成对应的访问规则。
1.1kube-proxy的代理模型
最早的userpace模式:是通过iptables规则拦截,由kube-proxy代理,现在已经不受支持:因为要从用户空间-内核空间-用户空间。
iptables模式:iptables拦截规则后,然后重定向到Kube-proxy,然后在通过Kube-proxy代理。报文直接经过内核iptables规则转发。但是大型的K8s集群会产生大量的iptables规则,会影响性能。
ipvs模式:一个调度只需要一个规则。
1.2Service的类型
ClusterIP:通过集群内部IP地址,来暴露服务,该地址仅在集群内部可见、可达,它无法被集群外部的客户端访问;默认类型。
NodePort:NodePort是ClusterIP的增强类型,它会在ClusterIP的功能之外,在每个k8s主机节点上使用一个相同的端口号将外部流量引入到该service上来(端口号范围30000-32767)。
LoadBalancer:使用外接负载均衡器完成到服务的负载分发,注意此模式需要外部云环境支持。
ExternalName:把集群外部的服务引入集群内部,直接使用。
1.3修改kube-proxy为ipvs
[root@master1 service]# kubectl edit cm kube-proxy -n kube-system
kind: KubeProxyConfiguration
metricsBindAddress: ""
mode: "ipvs" #默认为空,空即为ipvs,默认调度规则为rr
nodePortAddresses: null
oomScoreAdj: null
portRange: ""
showHiddenMetricsForVersion: ""
#检查pod是否重启
#如果没有重启,可以把标签带有proxy的pod全部删除(生产环境中禁止)
[root@master1 service]# kubectl delete pods -l k8s-app=kube-proxy -n kube-system
#此时去node节点上,可以看到kube-ipvs0的虚拟接口
[root@node1 ~]# ifconfig kube-ipvs0
kube-ipvs0: flags=130<BROADCAST,NOARP> mtu 1500
inet 10.96.0.10 netmask 255.255.255.255 broadcast 0.0.0.0
ether 92:d3:97:76:dc:04 txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
#每一个service 的clusterIP都配置在了这个网络接口上
[root@node1 ~]# ip addr show kube-ipvs0
71: kube-ipvs0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default
link/ether 92:d3:97:76:dc:04 brd ff:ff:ff:ff:ff:ff
inet 10.96.0.10/32 scope global kube-ipvs0
valid_lft forever preferred_lft forever
inet 10.105.245.105/32 scope global kube-ipvs0
valid_lft forever preferred_lft forever
inet 10.96.0.1/32 scope global kube-ipvs0
valid_lft forever preferred_lft forever
inet 10.97.193.4/32 scope global kube-ipvs0
valid_lft forever preferred_lft forever
#安装ipsvadm,可以看到所有的规则
[root@node1 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.17.0.1:30253 rr
-> 10.244.1.61:80 Masq 1 0 0
-> 10.244.2.48:80 Masq 1 0 0
TCP 192.168.10.102:30253 rr
-> 10.244.1.61:80 Masq 1 0 0
-> 10.244.2.48:80 Masq 1 0 0
TCP 10.96.0.1:443 rr
-> 192.168.10.101:6443 Masq 1 0 0
TCP 10.96.0.10:53 rr
-> 10.244.0.2:53 Masq 1 0 0
-> 10.244.0.3:53 Masq 1 0 0
TCP 10.96.0.10:9153 rr
-> 10.244.0.2:9153 Masq 1 0 0
-> 10.244.0.3:9153 Masq 1 0 0
TCP 10.97.193.4:80 rr
-> 10.244.1.61:80 Masq 1 0 0
-> 10.244.2.48:80 Masq 1 0 0
TCP 10.105.245.105:443 rr
-> 10.244.1.58:4443 Masq 1 0 0
TCP 10.244.1.0:30253 rr
-> 10.244.1.61:80 Masq 1 0 0
-> 10.244.2.48:80 Masq 1 0 0
TCP 10.244.1.1:30253 rr
-> 10.244.1.61:80 Masq 1 0 0
-> 10.244.2.48:80 Masq 1 0 0
UDP 10.96.0.10:53 rr
-> 10.244.0.2:53 Masq 1 0 0
-> 10.244.0.3:53 Masq 1 0 0
1.4创建service
资源清单
apiVersion: v1
kind: Service
metadata:
name:
namespace:
spec:
type <string> #service的类型,默认为clusterIP
selector <map[string]string> #等值类型的标签选择器,内含"与"逻辑
ports: #Service的端口列表
- name: <string> #端口名称
protocol <string> #协议,目前仅支持TCP、UDP和STCP,默认为TCP
port <integer> #service的端口号
targetPort <string> #后端pod目标进程的端口号或者名称,名称需由Pod规范定义
nodePort <integer> #节点端口号,仅适用于NodePort和LoadBalancer类型
clusterIP <String> #service的集群IP,建议由系统自动分配
externalTrafficPolicy <string> #外部流量策略的处理方式,local表示当前节点处理,cluster表示向集群范围调度。如果式local的话,本机无pod会服务不可达。
loadBalancer <string> #外部负载均衡器使用的IP地址,仅适用于LoadBalancer
externalName <string> #外部服务名称,该名称将作为Service的 DNS CNAME值
首先通过deploy创建一组pod。这个镜像可以输出pod的内部地址,方便检验。
[root@master service]# cat deploy-demoapp.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-demoapp
spec:
replicas: 3
selector:
matchLabels:
app: demoapp-pod
template:
metadata:
labels:
app: demoapp-pod
spec:
containers:
- name: nginx
image: ikubernetes/demoapp:v1.0
[root@master service]# kubectl apply -f deploy-demoapp.yaml
deployment.apps/deployment-demoapp created
[root@master service]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
deployment-demoapp-56c4f6b8f4-55hzx 1/1 Running 0 71s 10.244.2.64 node2 <none> <none>
deployment-demoapp-56c4f6b8f4-brfln 1/1 Running 0 71s 10.244.1.67 node1 <none> <none>
deployment-demoapp-56c4f6b8f4-vbx82 1/1 Running 0 71s 10.244.2.65 node2 <none> <none>
#访问测试
[root@master service]# curl 10.244.2.64
iKubernetes demoapp v1.0 !! ClientIP: 10.244.0.0, ServerName: deployment-demoapp-56c4f6b8f4-55hzx, ServerIP: 10.244.2.64!
1.4.1clusterIP类型
[root@master1 service]# cat service-clusterip-demo.yaml
apiVersion: v1
kind: Service
metadata:
name: demoapp-clusterip-service
namespace: default
spec:
clusterIP:
selector:
app: demoapp-pod
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
[root@master service]# kubectl apply -f service-clusterip-demo.yaml
service/demoapp-clusterip-service created
[root@master service]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
demoapp-clusterip-service ClusterIP 10.97.37.131 <none> 80/TCP 3s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d
#访问service,可以看出来是轮询
[root@master service]# curl 10.97.37.131
iKubernetes demoapp v1.0 !! ClientIP: 10.244.0.0, ServerName: deployment-demoapp-56c4f6b8f4-vbx82, ServerIP: 10.244.2.65!
[root@master service]# curl 10.97.37.131
iKubernetes demoapp v1.0 !! ClientIP: 10.244.0.0, ServerName: deployment-demoapp-56c4f6b8f4-55hzx, ServerIP: 10.244.2.64!
[root@master service]# curl 10.97.37.131
iKubernetes demoapp v1.0 !! ClientIP: 10.244.0.0, ServerName: deployment-demoapp-56c4f6b8f4-brfln, ServerIP: 10.244.1.67!
[root@master service]# curl 10.97.37.131
iKubernetes demoapp v1.0 !! ClientIP: 10.244.0.0, ServerName: deployment-demoapp-56c4f6b8f4-vbx82, ServerIP: 10.244.2.65!
[root@master service]# curl 10.97.37.131
iKubernetes demoapp v1.0 !! ClientIP: 10.244.0.0, ServerName: deployment-demoapp-56c4f6b8f4-55hzx, ServerIP: 10.244.2.64!
[root@master service]# curl 10.97.37.131
iKubernetes demoapp v1.0 !! ClientIP: 10.244.0.0, ServerName: deployment-demoapp-56c4f6b8f4-brfln, ServerIP: 10.244.1.67!
1.4.2NodePort类型
在之前的样例中,创建的Service的ip地址只有集群内部才可以访问,如果希望将Service暴露给集群外部使用,那么就要使用到另外一种类型的Service,称为NodePort类型。NodePort的工作原理其实就是将service的端口映射到Node的一个端口上,然后就可以通过NodeIp:NodePort来访问service了。
创建service-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
name: service-nodeport
spec:
selector:
app: demoapp-pod
type: NodePort # service类型
ports:
- port: 80
nodePort: 30002 # 指定绑定的node的端口(默认的取值范围是:30000-32767), 如果不指定,会默认分配
targetPort: 80
[root@master service]# kubectl apply -f service-nodeport.yaml
service/service-nodeport created
[root@master service]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
demoapp-clusterip-service ClusterIP 10.97.37.131 <none> 80/TCP 108m
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d2h
service-headliness ClusterIP None <none> 80/TCP 4m44s
service-nodeport NodePort 10.106.67.51 <none> 80:30002/TCP 3s
[root@master service]# curl 192.168.10.101:30002
iKubernetes demoapp v1.0 !! ClientIP: 10.244.0.0, ServerName: deployment-demoapp-56c4f6b8f4-vbx82, ServerIP: 10.244.2.65!
[root@master service]# curl 192.168.10.101:30002
iKubernetes demoapp v1.0 !! ClientIP: 10.244.0.0, ServerName: deployment-demoapp-56c4f6b8f4-55hzx, ServerIP: 10.244.2.64!
[root@master service]# curl 192.168.10.101:30002
iKubernetes demoapp v1.0 !! ClientIP: 10.244.0.0, ServerName: deployment-demoapp-56c4f6b8f4-brfln, ServerIP: 10.244.1.67!
[root@master service]# curl 192.168.10.102:30002
iKubernetes demoapp v1.0 !! ClientIP: 10.244.1.0, ServerName: deployment-demoapp-56c4f6b8f4-vbx82, ServerIP: 10.244.2.65!
[root@master service]# curl 192.168.10.102:30002
iKubernetes demoapp v1.0 !! ClientIP: 10.244.1.0, ServerName: deployment-demoapp-56c4f6b8f4-55hzx, ServerIP: 10.244.2.64!
[root@master service]# curl 192.168.10.102:30002
iKubernetes demoapp v1.0 !! ClientIP: 10.244.1.1, ServerName: deployment-demoapp-56c4f6b8f4-brfln, ServerIP: 10.244.1.67!
[root@master service]# curl 192.168.10.102:30002
iKubernetes demoapp v1.0 !! ClientIP: 10.244.1.0, ServerName: deployment-demoapp-56c4f6b8f4-vbx82, ServerIP: 10.244.2.65!
1.4.3 LoadBalancer类型的Service
LoadBalancer和NodePort很相似,目的都是向外部暴露一个端口,区别在于LoadBalancer会在集群的外部再来做一个负载均衡设备,而这个设备需要外部环境支持的,外部服务发送到这个设备上的请求,会被设备负载之后转发到集群中。
1.4.4ExternalName类型的Service
ExternalName类型的Service用于引入集群外部的服务,它通过externalName属性指定外部一个服务的地址,然后在集群内部访问此service就可以访问到外部的服务了。
apiVersion: v1
kind: Service
metadata:
name: service-externalname
namespace: dev
spec:
type: ExternalName # service类型
externalName: www.baidu.com #改成ip地址也可以
# 创建service
[root@k8s-master01 ~]# kubectl create -f service-externalname.yaml
service/service-externalname created
# 域名解析
[root@k8s-master01 ~]# dig @10.96.0.10 service-externalname.dev.svc.cluster.local
service-externalname.dev.svc.cluster.local. 30 IN CNAME www.baidu.com.
www.baidu.com. 30 IN CNAME www.a.shifen.com.
www.a.shifen.com. 30 IN A 39.156.66.18
www.a.shifen.com. 30 IN A 39.156.66.14
1.4.5补充externalIP
如果集群中本身只有一个节点具有一个公网IP,可以通过该公网IP引入外部流量。
例如:在node1上增加一个虚拟IP演示。
[root@node1 ~]# ip addr add 192.168.10.105/24 dev eth0
#创建service
[root@master service]# vim service-external-demo.yaml
apiVersion: v1
kind: Service
metadata:
name: demo-externalip-svc
namespace: default
spec:
type: ClusterIP
selector:
app: demoapp-pod
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
externalIPs:
- 192.168.10.105
[root@master service]# kubectl apply -f service-external-demo.yaml
service/demo-externalip-svc created
[root@master service]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
demo-externalip-svc ClusterIP 10.99.14.50 192.168.10.105 80/TCP 3s
demoapp-clusterip-service ClusterIP 10.97.37.131 <none> 80/TCP 141m
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d2h
service-headliness ClusterIP None <none> 80/TCP 37m
service-nodeport NodePort 10.106.67.51 <none> 80:30002/TCP 32m
#访问测试
[root@master service]# curl 192.168.10.105
iKubernetes demoapp v1.0 !! ClientIP: 10.244.0.0, ServerName: deployment-demoapp-56c4f6b8f4-vbx82, ServerIP: 10.244.2.65!
[root@master service]# curl 192.168.10.105
iKubernetes demoapp v1.0 !! ClientIP: 10.244.0.0, ServerName: deployment-demoapp-56c4f6b8f4-55hzx, ServerIP: 10.244.2.64!
[root@master service]# curl 192.168.10.105
iKubernetes demoapp v1.0 !! ClientIP: 10.244.0.0, ServerName: deployment-demoapp-56c4f6b8f4-brfln, ServerIP: 10.244.1.67!
[root@master service]# curl 192.168.10.105
iKubernetes demoapp v1.0 !! ClientIP: 10.244.0.0, ServerName: deployment-demoapp-56c4f6b8f4-vbx82, ServerIP: 10.244.2.65!
更多推荐
所有评论(0)