k8s介绍

1. 介绍

Kubernetes(k8s)是自动化容器操作的开源平台,这些操作包括部署,调度和节点集群间扩展。

Kubernetes组件组成:

1 Kubectl

客户端命令行工具,将接受的命令格式化后发送给kube-apiserver,作为整个系统的操作入口。

2 kube-apiserver

作为整个系统的控制入口,以REST API服务提供接口,提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制。

3 kube-controller-manager

用来执行整个系统中的后台任务,包括节点状态状况、Pod个数、Pods和Service的关联等。负责维护集群的状态,比如故障检测、自动扩展、滚动更新等。

4 kube-scheduler

负责节点资源管理,接受来自kube-apiserver创建Pods任务,并分配到某个节点。

5 etcd

etcd 集群的主数据库,保存了整个集群的状态,负责节点间的服务发现和配置共享。

6 kube-proxy

运行在每个计算节点上,负责Pod网络代理。定时从etcd获取到service信息来做相应的策略。负责为Service提供cluster内部的服务发现和负载均衡。

7 kubelet

运行在每个计算节点上,作为agent,接受分配该节点的Pods任务及管理容器,周期性获取容器状态,反馈给kube-apiserver。负责维护容器的生命周期,负责管理pods和它们上面的容器,images镜像、volumes、etc。同时也负责Volume(CVI)和网络(CNI)的管理。

8 DNS

一个可选的DNS服务,用于为每个Service对象创建DNS记录,这样所有的Pod就可以通过DNS访问服务了。

2 相关概念

2.1 Pod

Pod是在K8s集群中运行部署应用或服务的最小单元,它是可以支持多容器的。Pod的设计理念是支持多个容器在一个Pod中共享网络地址和文件系统,可以通过进程间通信和文件共享这种简单高效的方式组合完成服务.比如你运行一个操作系统发行版的软件仓库,一个Nginx容器用来发布软件,另一个容器专门用来从源仓库做同步,这两个容器的镜像不太可能是一个团队开发的,但是他们一块儿工作才能提供一个微服务;这种情况下,不同的团队各自开发构建自己的容器镜像,在部署的时候组合成一个微服务对外提供服务

2.2副本复制器(RC)

通过监控运行中的Pod来保证集群中运行指定数目的Pod副本。少于指定数目,RC就会启动运行新的Pod副本;多于指定数目,RC就会杀死多余的Pod副本

2.3副本集(Replica Set,RS)

RS是新一代RC,提供同样的高可用能力,区别主要在于RS后来居上,能支持更多种类的匹配模式。副本集对象一般不单独使用,而是作为Deployment的理想状态参数使用

2.4部署(Deployment)

部署是一个比RS应用模式更广的API对象,支持动态扩展。可以创建一个新的服务,更新一个新的服务,也可以是滚动升级一个服务。滚动升级一个服务,实际是创建一个新的RS,然后逐渐将新RS中副本数增加到理想状态,将旧RS中的副本数减小到0的复合操作【逐步升级新得副本,剔除旧的副本】;

总结:RC、RS和Deployment只是保证了支撑服务的微服务Pod的数量

2.5服务(Service)

RC、RS和Deployment只是保证了支撑服务的微服务Pod的数量,但是没有解决如何访问这些服务的问题。一个Pod只是一个运行服务的实例,随时可能在一个节点上停止,在另一个节点以一个新的IP启动一个新的Pod,因此不能以确定的IP和端口号提供服务。要稳定地提供服务需要服务发现和负载均衡能力。服务发现完成的工作,是针对客户端访问的服务,找到对应的的后端服务实例。在K8s集群中,客户端需要访问的服务就是Service对象。

每个Service会对应一个集群内部有效的虚拟IP,集群内部通过虚拟IP访问一个服务。在K8s集群中微服务的负载均衡是由Kube-proxy实现的。Kube-proxy是K8s集群内部的负载均衡器。它是一个分布式代理服务器,在K8s的每个节点上都有一个;这一设计体现了它的伸缩性优势,需要访问服务的节点越多,提供负载均衡能力的Kube-proxy就越多,高可用节点也随之增多。与之相比,我们平时在服务器端做个反向代理做负载均衡,还要进一步解决反向代理的负载均衡和高可用问题。

3 PodIP、ClusterIP和外部IP

3.1 Pod IP

Kubernetes的最小部署单元是Pod。利用Flannel作为不同HOST之间容器互通技术时,由Flannel和etcd维护了一张节点间的路由表。Flannel的设计目的就是为集群中的所有节点重新规划IP地址的使用规则,从而使得不同节点上的容器能够获得“同属一个内网”且”不重复的”IP地址,并让属于不同节点上的容器能够直接通过内网IP通信。

每个Pod启动时,会自动创建一个镜像为gcr.io/google_containers/pause:0.8.0的容器,容器内部与外部的通信经由此容器代理,该容器的IP也可以称为Pod IP。

3.2 Cluster IP

Pod IP 地址是实际存在于某个网卡(可以是虚拟设备)上的,但Service Cluster IP就不一样了,没有网络设备为这个地址负责。它是由kube-proxy使用Iptables规则重新定向到其本地端口,再均衡到后端Pod的。

就拿上面我们提到的图像处理程序为例。当我们的Service被创建时,Kubernetes给它分配一个地址10.0.0.1。这个地址从我们启动API的service-cluster-ip-range参数(旧版本为portal_net参数)指定的地址池中分配,比如–service-cluster-ip-range=10.0.0.0/16。假设这个Service的端口是1234。集群内的所有kube-proxy都会注意到这个Service。当proxy发现一个新的service后,它会在本地节点打开一个任意端口,建相应的iptables规则,重定向服务的IP和port到这个新建的端口,开始接受到达这个服务的连接。

当一个客户端访问这个service时,这些iptable规则就开始起作用,客户端的流量被重定向到kube-proxy为这个service打开的端口上,kube-proxy随机选择一个后端pod来服务客户。这个流程如下图所示:

根据Kubernetes的网络模型,使用Service Cluster IP和Port访问Service的客户端可以坐落在任意代理节点上。外部要访问Service,我们就需要给Service外部访问IP。

3.3外部IP

Service对象在Cluster IP range池中分配到的IP只能在内部访问,如果服务作为一个应用程序内部的层次,还是很合适的。如果这个Service作为前端服务,准备为集群外的客户提供业务,我们就需要给这个服务提供公共IP了。

外部访问者是访问集群代理节点的访问者。为这些访问者提供服务,我们可以在定义Service时指定其spec.publicIPs,一般情况下publicIP 是代理节点的物理IP地址。和先前的Cluster IP range上分配到的虚拟的IP一样,kube-proxy同样会为这些publicIP提供Iptables 重定向规则,把流量转发到后端的Pod上。有了publicIP,我们就可以使用load balancer等常用的互联网技术来组织外部对服务的访问了。

spec.publicIPs在新的版本中标记为过时了,代替它的是spec.type=NodePort,这个类型的service,系统会给它在集群的各个代理节点上分配一个节点级别的端口,能访问到代理节点的客户端都能访问这个端口,从而访问到服务。

3.4 Endpoint地址保持

Pod的endpointd地址会随着pod的销毁和重新创建而发生改变,因为新的pod的ip地址和旧的pod的地址不同,service一旦创建,kubernetes会自动为它分配一个可用cluster ip,而且在service的整个生命周期内,它的cluster ip不会发生改变。解决endpoint地址不发生改变的方法:只需要service的name与service的cluster ip地址做一个dns域名映射就可以解决。

3.5 namespace(命名空间)

Namespace(命名空间)是kubernetes系统中的一个重要概念,namespace在很多情况下用于实现多租户的资源隔离。Namespace通过将集群内部的资源对象“分配”到不同的namespace中,形成逻辑上分组的不同项目、小组或用户组,便于不同的分组在共享使用整个集群的资源的同时还能被分别管理。如果不特别指明namespace,用户创建的pod、rc、service都将被系统创建到这个默认名为default的namespace中。当我们给每个租户创建一个namespace来实现多租户的资源隔离,还能结合kubernetes的资源配额管理,限定不同租户能占用的资源,例如cpu使用量,内存使用量等。

3.6 mysql-rc.yaml详解

apiVersion: V1

king: ReplicationController      ---副本控制器rc

metadata:

   name: mysql                   --- rc的名称,全局唯一

spec:

   replics :1                    --- pod副本期待数量

   selector:

      app: mysql               --- 符合目标的pod拥有此标签

template:                ---根据此模板创建pod的副本(实例)

   metadata:

      labels:

        app: mysql   --pod副本拥有的标签,对应rc的selector

   spec:

      containers:     -- pod内容器的定义部分

  • name: mysql   -- 容器的名称

image: mysql  -- 容器对应的docker image

ports:

- containerPort: 3306  -- 容器暴露的端口号

env:    -- 注入到容器内的环境变量

- name: MYSQL_ROOT_PASSWORD

  Value: “123456”

Kind属性:用来表示此资源对象的类型,比如这里是replication,表示这是一个rc,Spec一节中是rc的相关属性定义,比如spec.selector是rc的pod标签(label)选择器,即监控和管理拥有这些标签的pod实例,确保当前集群上始终有且仅有replicas哥pod实例在运行,这里我们设置replicas=1表示只能运行一个mysql pod实例。

3.7 mysql-svc.yaml

apiVersion: v1

kind: Service  --表明是kubernetes service

metadata:

   name: mysql  -- service的全局唯一名称

spec:

  ports:

- port: 3306   --service提供服务的端口号

  selector:

    app: mysql     -- services对应的pod拥有这里定义的标签

metadata.name是service的服务名(servicename)

port属性定义了service的端口

spec.selector确定了哪些pod副本(实例)对应到本地服务

3.8 myweb-rc.yaml

king: ReplicationController

metadata:

   name: myweb

spec:

   replicas: 5

   selector:

      app: myweb

   template:

     metadata:

        labels:

          app:myweb

   spec:

     containers:

       - name: myweb

         image:kubeguide/tomcat-app:v1

         ports:

         - containerPort: 8080

         env:

         - name: MYSQL_SERVICE_HOST

           value: ‘mysql’

         - name: MYSQL_SERVICE_PORT

           Value:  ‘3306’

该配置文件中的rc对应的tomcat容器里引用了MYSQL_SERVICE_HOST=mysql这个环境变量,而mysql是我们之前定义的mysql服务的服务名

3.9 myweb-svc.yaml

apiVersion: V1

kind: Service

metadata:

   name: myweb

spec:

   type: NodePort

ports:

  - port: 8080

    nodePort: 30001

 selector:

    app: myweb

该配置文件中的type=nodeport和nodeport=30001这两个属性表示,表明此service开启了nodeport方式的外网访问模式

猜你喜欢

转载自blog.csdn.net/wzf862187413/article/details/87803305
k8s