k8s的部署构架

shell编程


k8s的部署构架
kubernets中有两类资源,分别是master和nodes,master和nodes上跑的服务如下图
k8s的部署构架_第1张图片
master:负责管理整个集群,例如,对应用进行调度(扩缩)、维护应用期望的状态,对应用进行发布等。
node:集群中的宿主机(可以是物理机也可以虚拟机),每个弄得上都有一个agent,名为kubelet,用于跟master通信。同时一个node需要有管理容器的工具包,用于管理在node上运行的容器(docker或rkt)。一个k8s集群至少要有3个节点。
kubelet通过master暴露的API与master通信,用户可以直接调用master的API做集群的管理。

k8s中的对象Objects
POD
k8s中的最小部署单元,不是一个程序/进程,而是一个环境(包括、存储、网络IP:port、容器配置)。其中可以运行一个或多个container(docker或其他的容器)
pod
k8s中的最小部署单元,不是一个程序/进程,而是一个环境(包括容器、存储、网络ip:port、容器配置)。其中可以运行1个或多个container(docker或其他容器),在一个pod内部的container共享所有资源,包括共享pod的ip:port和磁盘。
pod是临时性的,用完即丢弃的,当pod中的进程结束、node故障,或者资源短缺时,pod会被干掉。基于此,用户很少直接创建一个独立的pods,而会通过k8s中的controller来对pod进行管理。
controller通过pod templates来创建pod,pod template是一个静态模板,创建出来之后的pod就跟模板没有关系了,模板的修改也不会影响现有的pod。
service
由于pod是临时性的,pod的ip:port也是动态变化的。这种动态变化在k8s集群中就涉及到一个问题:如果一组后端pod作为服务提供方,供一组前端的pod所调用,那服务调用方怎么自动感知服务提供方。这就引入了k8s中的另外一个核心概念,services.
service是通过apiserver创建出来的对象实例,举例,
k8s的部署构架_第2张图片
这个配置将创建出来一个新的Service对象,名为my-service,后端是所有包含app=MyApp的pod,目标端口是9376,同时这个service也会被分配一个ip,被称为集群ip,对应的端口是80. 如果不指定targetPort, 那么targetPort与port相同。关于targetPort更灵活的设定是,targetPort可以是一个String类型的名字,该名字对应的真实端口值由各个后端pod自己定义,这样同一组pod无需保证同一个port,更加灵活。
ervices组件与bns不同的一点,bns的节点是自己指定了name和后端的关联关系,而services是根据pod上的标签(label)自动生成的,更灵活。ali的group就更别提了,group是隶属于app的,扩展性方面更弱一些。
上文说在创建service的时候,系统为service分配了一个集群虚IP和端口,服务使用方通过这个vip:port来访问真实的服务提供方。这里的vip就是kube-proxy提供出来的。

虚ip和service proxies
kube-proxy的模式
userspace: client -> iptables -> kube-proxy -> backend pod(rr), iptables只是把虚ip转换成kube-proxy的ip,通过kube-proxy自己维护的不同端口来轮询转发到后端的pod上;
iptables: client -> iptables -> backend pod(random),kube-proxy只是监听master上service的创建,之后动态添加/删除本机上的iptables规则;
ipvs: client -> ipvs ->backend pod, ipvs是一个内核模块
服务发现
服务使用方如何找到我们定义的Service? 在k8s中用了两个方案,环境变量 && DNS。
1、环境变量
每当有service被创建出来之后,各个node(宿主机)上的kubelet,就会把service name加到自己宿主机的环境变量中,供所有Pod使用。环境变量的命名规则是{SERVICE_NAME}_SERVICE_HOST, ${SERVICE_NAME}SERVICE_PORT,其中SERVICE_NAME是新serviceName的大写形式,serviceName中的横杠-会被替换成下划线.
使用环境变量有一个隐含的创建顺序,即服务使用方在通过环境变量访问一个service的时候,这个service必须已经存在了。
这么简单粗暴的方案…这样做有个好处,就是省的自己搞名字解析服务,相当于本地的agent做了“域名劫持”。serviceName对应到上文提到的,由kube-proxy提供的vip:port上。
2、DNS
这是官方不推荐的做法,推荐用来跟k8s的外部服务进行交互,ExternalName.
Headless services
在创建service的时候,用户可以给spec.clusterIp指定一个特定的ip。前提是这个ip需要是一个合法的IP,并且要在apiServer定义的service-cluster-ip-range范围内。
当然,如果用户有自己的服务发现服务,也可以不用k8s原生的service服务,这时,需要显式地给spec.clusterIp设置None,这样k8s就不会给service分配clusterIp了。
如果用户将spec.cluster设置为None,但指定了selector,那么endpoints controller还是会创建Endpoints的,会创建一个新的DNS记录直接指向这个service描述的后端pod。否则,不会创建Endpoints记录。

发布服务,服务类型
clusterlp:默认配置,给service分配一个集群内部IP,k8s集群外部不识别
Nodeport:宿主机端口,集群外部的服务也访问,使用nodelp:nodePort。
loadBalancer:通过云负载均衡,将service暴露出去
Externalname:将serviceName与externalName绑定,让外网可以访问到。要求kube-dns
的版本>=1.7。

你可能感兴趣的:(kubernets)