android的后台运行在很多service,它们在系统启动时被SystemServer开启,支持系统的正常工作,比如MountService监听是否有SD卡安装及移除,ClipboardService提供剪切板功能,PackageManagerService提供软件包的安装移除及查看等等,应用程序可以通过系统提供的Manager接口来访问这些Service提供的数据,以下将说明他们的工具流程
2. 举例说明基本流程
以android系统支持sensor(传感器)实例来说明框架层的service和manager是如何配合工作的
1) 什么是sensor
sensor是传感器, 比如控制横竖屏切换利用的就是重力传感器(gsensor), 还有accelerator sensor可取得x, y, z三个轴上的加速度(应用如平衡球, 小猴吃香蕉等)
2) 应用程序调用(以下为关键代码)
sensorManager=(SensorManager)getSystemService(context.SENSOR_SERVICE)
lightSensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT)
sensorManager.registerListener(sensorListener, lightSensor, SensorManager.SENSOR_DELAY_NORMAL)
3) Manager层
a) 提供给应用程序调用的接口,同实与Service交互,实现功能
frameworks/base/core/java/android/hardware/SensorManager.java
4) Service层
a) 开机时就运行的管理Sensor的后台服务
frameworks/base/services/java/com/android/server/SensorService.java
b) snesor后台服务需要的JNI,通过它与系统级交互
frameworks/base/services/jni/com_android_server_SensorService.cpp
5) 系统层
a) 传感器的头文件,硬件提供商按此文件的定义实现其功能
hardware/libhardware/include/hardware/sensors.h
b) 传感器的系统层实现,与内核交互,此处通常是硬件提供商提供的
hareware/libsensors
6) 内核及硬件层
内核访问硬件,同时以设备文件等方式提供给上层控制接口和传感器数据
3. 系统层实现
1) frameworks/base/core/java/android/*Manager.java 对应用的接口
2) frameworks/base/core/jni/ 对应用的接口的JNI
3) frameworks/base/services/java/com/android/server/后台服务
4) frameworks/base/services/jni/JNI与系统层接口
5) hardware/libhardware/include/ 系统层头文件
6) hardware/libxxx 系统库支持
7) 内核支持
4. 应用程序如何使用
1) 查看系统提供哪些服务
find frameworks/base/core/java/android/ -name *Manager.java
此处可以看到调用系统提供服务的入口
2) 一般register listener,事件发生时都收到回调
5.新建一个service(以froyo为例)
1) 接口:接口供应用调用
frameworks/base/core/java/android/app/ContextImpl.java 加服务名与Manager对应
frameworks/base/core/java/android/content/Context.java加服务名定义
2) Manager:提供服务对应的调用接口
frameworks/base/core/java/android/app/StartXXXXManager.java实现调用接口
frameworks/base/core/java/android/app/IXXXXManager.aidl 定义调用接口
frameworks/base/Android.mk 加入aidl的编译
3) service:提供后台服务支持
frameworks/base/services/java/com/android/server/XXXXService.java 服务实现
frameworks/base/services/java/com/android/server/SystemServer.java 启动服务
http://kubernetes.kansea.com/docs/user-guide/services/
• 在多个Pod情况下,service 如何实现负载均衡的?
答:通过node节点kube-proxy组件完成请求转发
• Pod重启后IP变化,service是如何感知容器重启后的IP?
答:Kubernetes提供了一个简单的Endpoints API,service通过selector标签选择器不断的对Pod进行筛选,并将结果POST到同名的Endpoints对象。
• 如何通过域名访问后端应用?
答:通过集群内部coredns解析到service 的cluser-IP, 然后通过kube-proxy转发请求,同一命名空间的直接请求service-name即可,不同命名空间,则service-name.namespace-name
• 防止Pod失联
• 定义一组Pod的访问策略
• 支持ClusterIP,NodePort以及LoadBalancer三种类型
• Service的底层实现主要有Iptables和IPVS二种网络模式
service要动态感知后端IP的变化,得介入一个endpoints控制器,也就是每个service都有对应一个endpoints控制器,endpoints帮它关联后端的pod,service 通过selector标签选择器关联pod, 具体实现动态IP变化由endpoints来实现。
kubectl get endpoints 或 kubectl get ep
• 通过label-selector 相关联
• 通过Service实现Pod的负载均衡(TCP/UDP 4层)
• ClusterIP: 默认,分配一个集群内部可以访问的虚拟IP(VIP)
• NodePort: 在每个Node上分配一个端口作为外部访问入口
• LoadBalancer: 工作在特定的Cloud Provider上,例如Google Cloud,AWS,OpenStack
Service 默认类型,分配一个集群内部可以访问的虚拟IP(VIP),同一个集群内部应用之间相互访问
ClusterIP yaml配置文件:
在每个Node上分配一个端口作为外部访问入口, 让外部用户访问到集群内部pod应用
NodePort yaml资源配置文件:
用浏览器打开nodeIP:30001即可访问到pod应用。在node节点上使用 ipvsadm -ln 可以看到很多做端口轮询转发的规则。如果要提供给外用户访问,在前面再加个负载均衡器,比如nginx,haproxy,或公有云的LB,转发到指定的某几台node,域名解析到负载均衡器即可。
工作在特定的Cloud Provider上,例如Google Cloud,AWS,OpenStack, 不是我们自建的kubernetes集群里,是公有云提供商提供,公有云LB可以自动将我们node 上的service 的IP和端口加入LB中。
NodePort请求应用流:
用户--->域名 ---->负载均衡器(后端服务器) --->NodeIP:Port --->PodIP:Port
LoadBalancer请求应用流:
用户--->域名 ---->负载均衡器(LB) --->NodeIP:Port --->PodIP:Port
LoadBalancer 提供特定云提供商底层LB接口,例如AWS,Google,Openstack
NodePort类型service IP和端口的限制是在master 节点的kube-apiserver配置文件中的两个参数指定 --service-cluster-ip-range 和 --service-node-port-range
在 Kubernetes 集群中,每个 Node 运行一个 kube-proxy 进程。kube-proxy 组件负责为 Service 实现了一种 VIP(虚拟 IP)的形式,完成流量转发规则的生成。kube-proxy网络底层流量代理转发与负载均衡实现有两种方式:
• Iptables
• IPVS
可以通过kube-proxy配置文件指定 --proxy-mode :
代理模式之Iptables工作原理:
kube-proxy 会监视 Kubernetes master 对Service 对象和 Endpoints 对象的添加和移除。 对每个 Service,它会生成 iptables 规则,从而捕获到该 Service 的 clusterIP(虚拟 IP)和端口的请求,进而将请求重定向到 Service 的一组 backend pod中的某个上面。 对于每个 Endpoints 对象,它也会生成 iptables 规则,这个规则会选择一个 backend Pod。默认的策略是,随机选择一个 backend pod。 实现基于客户端 IP 的会话亲和性,可以将 service.spec.sessionAffinity 的值设置为 "ClientIP" (默认值为 "None" )。和 userspace 代理类似,网络返回的结果是,任何到达 Service 的 IP:Port 的请求,都会被代理到一个合适的 backend pod,不需要客户端知道关于 Kubernetes、 Service 、或 Pod 的任何信息。 这应该比 userspace 代理更快、更可靠。然而,不像 userspace 代理,如果初始选择的 Pod 没有响应,iptables 代理不能够自动地重试另一个 Pod ,所以它需要依赖readiness probes(Pod检查检查策略,也就是探针)
代理模式之IPVS工作原理:
iptables方式service过多时的弊端:
• 创建很多iptables规则(更新,非增量式)
• iptables规则从上到下逐条匹配(延时大)
• iptables工作在用户态
救世主:IPVS
IPVS工作在内核态,iptables工作在用户态;
LVS 基于IPVS内核调度模块实现的负载均衡;
阿里云SLB,基于LVS实现四层负载均衡。
kube-proxy 使用的IPVS模式,启动之后会在node生成一个kube-ipvs0网卡,此网卡的ip就是对应service 的CLUSTER-IP
这里的real server正是我们启动的pod。ipvs 转发后端IP正好是pod IP
Iptables:
• 灵活,功能强大(可以在数据包不同阶段对包进行操作)
• 规则遍历匹配和更新,呈线性时延
IPVS:
• 工作在内核态,有更好的性能
• 调度算法丰富:rr,wrr,lc,wlc,ip hash...
在企业中尽可能使用IPVS模式,调度算法可以在kube-proxy配置文件中配置参数重启即可: --ipvs-scheduler=wrr
service CLUSTER-IP 也不是固定不变的,在应用程序也不可能写CLUSTER-IP,这里建议写域名(service名称),kubernetes集群DNS 将service 名称解析为CLUSTER-IP,DNS服务实时监视Kubernetes API,为每一个Service创建DNS记录用于域名解析。
通过yaml配置文件部署
https://github.com/kubernetes/kubernetes/blob/master/cluster/addons/dns/coredns/coredns.yaml.sed
这里主要修改几个参数:DNS域、DNS地址(IP),coredns pod内存限制和镜像地址
ClusterIP A记录格式:
<service-name>.<namespace-name>.svc.cluster.local
示例:my-service.default.svc.cluster.local
跨命名空间做域名解析:
pod 请求同一个命名空间service时,只写service名称即可;请求不在同一个命名空间service时,得在service名称加上“.命名空间”,比如: my-service.default
Web Service技术, 能使得运行在不同机器上的不同应用无须借助附加的、专门的第三方软件或硬件, 就可相互交换数据或集成。依据Web Service规范实施的应用之间, 无论它们所使用的语言、 平台或内部协议是什么, 都可以相互交换数据。Web Service是自描述、 自包含的可用网络模块, 可以执行具体的业务功能。Web Service也很容易部署, 因为它们基于一些常规的产业标准以及已有的一些技术,诸如标准通用标记语言下的子集XML、HTTP。Web Service减少了应用接口的花费。Web Service为整个企业甚至多个组织之间的业务流程的集成提供了一个通用机制。web广泛用到的技术:
TCP/IP:通用网络协议,被各种设备使用
HTML(标准通用标记语言下的一个应用):通用用户界面,可以使用HTML标签显示数据
.NET: 不同应用程序间共享数据与数据交换
Java:写一次可以在任何系统运行的通用编程语言,因为java具有跨平台特性
XML(标准通用标记语言下的一个子集):通用数据表达语言,在web上传送结构化数据的容易方法,他们的特点是其开放性,跨平台性,开放性正是Web services的基础。
欢迎分享,转载请注明来源:夏雨云
评论列表(0条)