pod是有生命周期的,为了给对应的客户端提供一个固定的访问端点。在客户端与服务pod之间提供一个中间层Service,service严重依赖kubernetes(1.11.2)之上的附件CoreDNS(kube-dns)
kubernetes的名称解析,强依赖于CoreDNS,在kubernetes中的名称解析中必须存在CoreDNS
kubernetes提供的网络功能,需要依赖于第三方网络方案,通过CNI - Container Network Interface(容器网络接口)来进行接入任何遵循此标准的方案,常见的:flannel等
其中,在kubernetes中有三类网络,node网络,pod网络,cluster网络,node和pod网络是实时存在配置的,而cluster(集群)网络是虚拟网络(virtual),并没有实时存在,仅存在Service的virtual当中
在每个节点之上,工作有kube-proxy,kube-proxy通过watch始终监视api-server中关于service资源有关资源变动信息。一旦有service资源发生变动,kube-proxy都会转换成当前节点之上,实现service资源调度,用户请求调度的规则。如:iptables,ipvs,这取决于service实现方式
而service实现方式在kubernetes上有三种模型
- userspace: 用户空间
如果来自内部则到达Service上:请求到达service,service(内核空间)转发到本地的(用户空间)kube-proxy来进行处理,处理完成后在转交给service IP(内核空间),而后在分发(iptables,ipvs)给各个pod,实现调度,如下:在用户空间和内核空间转换两次,这种方式效率很低。因此,又到了第二种方式client pod请求直接到service ip,这个请求被本地内核空间的service 规则所截取,直接调动到server pod上,这种方式直接工作在内核空间,由IPtables或者ipvs规则负责调度。而上图的方式是由工作在用户空间的kube-proxy负责调度的
在1.1之前 用的是userspace,在1.1默认用的是ipvs(如果ipvs被激活的,如果未被激活,则降级为iptables)如果某服务背后的pod资源发生改变,标签选择器中适用的资源会返回到apiserver的etcd中,而kube-proxy则会监听etcd,倘若发生变化,则会转换为ipvs或者iptables规则。不管是增加还是删除,都是立即生效。
创建清单
在service中,仍然是有4个字段apiVersion,kind,metadata,spec。在spec中,重要字段:
spec:
ports:端口
selector : 关联资源
sessionAffinity: 会话粘性
ClientIP: 同一个客户端IP调度到同一个pod
None: 默认随机调度
externalName: CNAME记录,能够被解析
type:
clusterIP: 固定IP,仅用于集群内部通信
port: service端口
targePort: 协议,默认tcp,pod上端口
NodePort: 节点IP,节点类型有用
LoadBalancer: 负载均衡一键调用,自动触发在外部创建负载均衡器
ExternalName: 将集群外部的服务应用到集群内部
None: 无头service
redis pod创建
[root@linuxea linuxea]# kubectl apply -f redis.yaml
deployment.apps/redis created
[root@linuxea linuxea]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE
redis-66ccc9b5df-4qq9q 1/1 Running 0 2m 172.16.3.45 linuxea.node-3.com <none>
svc yaml在yaml文件中,selector字段的值需要和创建redis字段的值一样
[root@linuxea linuxea]# cat svc-redis.yaml
apiVersion: v1
kind: Service
metadata:
name: redis
namespace: default
spec:
selector:
app: redis
role: Logstorage
clusterIP: 10.96.65.65
type: ClusterIP
ports:
- port: 6379
targetPort: 6379
kubectl apply -f svc-redis.yaml
创建
[root@linuxea linuxea]# kubectl apply -f svc-redis.yaml
service/redis created
查看redis ip定义
[root@linuxea linuxea]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 12d
redis ClusterIP 10.96.65.65 <none> 6379/TCP 4s
kubectl describe svc redis
查看svc详情
[root@linuxea linuxea]# kubectl describe svc redis
Name: redis
Namespace: default
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"redis","namespace":"default"},"spec":{"clusterIP":"10.96.65.65","ports":[{"por...
Selector: app=redis,role=Logstorage
Type: ClusterIP
IP: 10.96.65.65
Port: <unset> 6379/TCP
TargetPort: 6379/TCP
Endpoints: 172.16.3.45:6379
Session Affinity: None
Events: <none>
[root@linuxea linuxea]#
Endpoints(地址加端口):service到pod是有一个中间层,service先到Endpoints,Endpoints在关联到后端的pod。并且可以手动为service 创建Endpoints资源当一个服务创建完成,会自动在kubernetes的coredns中动态添加service的资源记录,A记录等,添加完成就可以进行解析