摘要:在云栖TechDay34期:DockerCon2017最新的技术解读中,阿里云的容器服务团队技术专家谢瑶瑶做了题为《Kubernetes on Alibaba Cloud》的分享,主要介绍了Kubernetes的基本概念,如何在阿里云快速一键部署高可用安全的Kubernetes集群以及阿里云的Cloud Provider所提供的能力。
以下内容根据演讲嘉宾现场视频以及速记整理而成。
今天主要会分享三个方面的问题:
首先简单介绍一下Kubernetes。Kubernetes简称K8S,这是社区的一种叫法。Kubernetes是整个CaaS工作流中的一环,CaaS是什么呢?就是Container As A Service——容器即服务,下图中的右图是一个简化版的CaaS的架构图,从最底层是一个基础服务,其上层主要提供的是物理机、网络、存储等一些比较硬件化的基础设施。再往上一层会构建PaaS平台,PaaS平台里头主要交付的对象是一些虚拟机,或者逻辑的结构,比如逻辑的VPC网络、存储等,让你可以方便地一键去创建这些资源,而不需要再去机房里头自己去运维管理这些东西。然后在PaaS平台上面会构建一层容器平台,这一层中主要的交互单元就是容器。
对于容器服务来讲,在这一层的时候,就更不需要关心于底层的PaaS平台所具有的特性了,比如在创建应用的时候,不需要关心底层使用的虚拟机是什么,或者是否需要手动创建一个虚拟机网络以及存储,然后去构建并放置应用去运行,这个时候只需要首先声明应用,然后告诉它说我需要在这个CaaS平台里运行我的应用,然后其他的事情你就不用操心了。平台会主动地帮你去寻找最合适的机器以及最合适的环境,把应用布置上去,并帮你解决好应用的故障恢复,网络的访问情况,以及资源分配问题。Kubernetes的这个层次之上是上图绿色部分,它属于编排系统,可以很方便地把应用按照系统合适的方式分布到各个节点上去,然后由它来处理故障恢复、副本保证等资源调度问题。另外它还提供容器的生命周期管理,比如启停一个应用、当应用失败之后重新拉起,或者不需要这个应用后执行删除等操作。
接下来分享一下Kubernetes的一些基本的概念,一个比较核心的概念就是Pod,Pod是一组容器的统称,就是它把一组容器作为一个最基础的调度单元,这组容器会被协同调度到一起,比如说有两个属于同一个Pod的容器,那么它们会被调度到同一个节点,一起调度,一起Fail Over。Service是一组Pod的抽象,比如在创建应用的时候可能需要创建很多个Pod来同时对外界提供服务,那么这一组Pod是同一个层次的东西,具有同等的地位,在前面提供一个Services对这一组Pod做负载均衡,当访问这个Services的时候,就会从后端随意挑出一个Pod来为前端提供服务,相当于负载均衡的概念,不过Services是集群内部的,它的网络只会局限于集群内部。
另外一个是Deployment概念,这是一个描述性的概念,就是当描述一个应用的时候就需要声明这个应用需要达到的状态,比如需要它有三个副本一直运行,需要它在故障的时候能够自动拉起来。用Deployment来描述它,然后系统就会自动保证这些东西,一旦出现了不符合预期的情况,系统会自动把这个状态转化到正常,无论是通过重新创建一组Pod或者是拉起原来的Pod。在K8S里面还有一个另外比较重要的概念就是持久化卷,通常来讲容器在创建的时候是没有数据卷的,对于存储在容器中的数据,如果把容器删掉了,那么这个数据也就会丢失。K8S提供一个持久化卷的概念,就是在创建服务的时候,可以先创建出这个卷,然后把这个卷挂载到容器里头去。通过这样的方式,在删除容器时,持久化卷是不会被删除的,数据也就可以保留下来。
下图是K8S的架构示意图,这是一个典型的无状态、多Master的分布式架构图。K8S主要功能组件:Kubelet,相当于Agent,在每一个节点上提供一个守护进程的服务,上报节点状态、运行Controller等。aplserver是一个Master,它是无状态的,所有的数据都存在后端的一致性存储中。Scheduler负责调度所有的Pod,也就是应用,为应用找一个合适的位置并运行起来。
这里前端使用一个Load Balancer来提供一个高可用的负载均衡的服务,其中一个Master挂了之后,仍然会有其他的几个Master会提供服务,所以不用担心会有几个Master 挂掉了。
在使用K8S当中遇到的一个比较大的问题就是部署问题。众所周知K8S一直在业界被诟病的就是太难用了,组件太多,概念太多,导致无法理解。对于开发者来讲,不希望去操心如何把集群快速地部署起来,如何去理解底层的东西,只需在用到的时候能够部署一个集群出来,这是需要达到最终的目标,就是部署简单。
看一下现在比较流行的一些部署工具,Kubeup是最早期的一种部署工具,它支持多种的环境,CentOS、Ubuntu,J2EE以及AWS等等,但是目前没有办法直接在阿里云上面部署起来,需要一些手工的改动。Kargo的底层主要使用的是Ansible,适合对Ansible比较熟悉的人去部署使用。Kops与AWS等云厂商集成度比较高,所以在AWS下面比较好用。Kubeadm主要是K8S原生支持的,也是未来官方主推的一种方式,它的特点就是简单易用,但是目前还处在α阶段,还不支持HA。但是这并不妨碍我们去使用它部署出一个HA的K8S集群。
那么阿里云的选择是什么呢?ROS + Kubeadm,原因只有一个:简单。首先简单介绍一下ROS,ROS是阿里云的资源编排服务,它可以非常方便的在阿里云一键创建出来所需要的各种资源比如ECS、VPC网络、SLB以及其他资源等等,相关的文档大家可以去阿里云官网查看。
一键部署主要分为三个步骤:
主要的部署过程分为三个步骤:第一个是创建集群需要提供阿里云的KeyID跟KeySecret,首先需要设置这两个环境变量,然后需要从阿里云官方网站上下载一个脚本,执行一个node-type=Master命令,这个命令要在Master上执行,这样执行完了之后就在这台机器上初始化了一个Master了,然后它会返回一个Token和节点的IP。第二步再到node节点上面去把node-type改为node,然后带上KeyID跟KeySecre以及刚才返回的End Point和Token,就可以把这个结点加入到刚才创建的Master集群当中,如此反复,就可以把更多的节点加入到集群中去。当不想要某个节点的时候,还可以通过node-type = down的命令销毁掉这个节点。
注意的地方就是在创建集群的过程中一定要保证hostname的一致性,CP的规范是使用hostname作为校验ECS一致性的参数,所以一定要保证hostname与传给CP的值是一样的。另外一个是阿里云的安全组设置问题,安全组默认禁止了所有非VPC地址的访问,因此需要根据最小需求设置来开放安全组,CP使用了172.16以及172.19网段,需要把这两个网段开放出来,同时还需要开放30000到32768的主机端口,用来给Service提供服务。第三个比较重要的是CentOS默认的内核配置的问题,这个要求配置内核的net.bridge.bridge-nf-call-iptables=1参数,否则所有主机上网桥的数据流量都不会经过iptables规则的转化,从而导致服务没有办法互相访问。如果这些还没有办法解决问题,那可以祭出终极大杀器——tcpdump,然后抓包分析数据。
接下来介绍一下K8S的阿里巴巴Cloud Provider,阿里云的Cloud Provider支持如下的一些特性:比如在网络支持方面,支持VPC的网络、阿里云的SLB以及Ingress network;存储方面,支持NAS、OSS。支持跨Region的单集群部署方案,可以把集群部署在多个可用区,甚至多个Region上,这样当出现单可用区fail的时候,集群仍然是可用的,提供了一种高可用的方案。还可以在K8S上使用原生的ELK作为日志方案,也可以使用阿里云提供的Fluentd-pilot开源解决方案,这个可以和阿里云的日志服务提供完整的对接,也是非常不错的选择;然后监控方面也可以通过阿里云监控来监控node节点的状态,也可以选择使用原生的Heapster + inluxdb来做网络监控方案;在应用仓库方面,可以使用现在开源的Helm/tiller的方式。
然后我们来看一下我们的VPC网络支持,Kubernetes支持非常丰富的网络形态,如VXLAN、Calico以及VPC网络等,VXLAN主要是一种Overlay,它通过对IP层然数据进行二次封装,封装完了之后在通过宿主机的网络路由到对端主机之后,然后再进行解封装,解封装之后再放到主机的内核栈里头,处理这些协议然后解码出来,传到另外Container容器里的网络里头,这个过程涉及到了一个数据包的封装与解封装,所以它的性能会有稍微的损耗。
Calico网络是通过3层路由的方式实现的,它直接把网关指向了对端节点的主机IP,这样所有发送到对端节点上面的容器IP的数据包都可以直接先发到对端节点上,然后由对端节点直接路由给容器。这种方式的好处是没有数据包的额外封装,所以性能损耗非常小。但是它要求所有的主机之间是二层可达的,这个要求通常对于许多云厂商来说是无法满足的,但是自建机房一般是都可以用的。然后就是VPC网络,阿里云VPC的方案跟Calico非常类似,也是通过路由的方式,然后把一个节点的容器的数据包导到另一个节点上的容器中去,所以性能损耗非常小,推荐大家使用VPC网络,而且现在阿里云支持的K8S也是仅仅支持这一种网络。当然你也可以使用VXLAN网络,但是VPC网络会提供给你的更好的性能,而且它还提供租户隔离级别的网络环境,网段也可以自由划分,而且如果把多个交换机创建在不同的可用区之内,还可以提供一种可用区级别的Fail Over。
实践过程中比较多的问题都来自于客户想了解VPC网络的性能究竟如何。在这里通过几种不同的方案来测试了一下VPC性能,主要有netprof、iprof以及qprof,下图是得出来的结果。从这些结果来看,容器的VPC网络跟主机VPC网络差距是非常小的,性能损耗是几乎是没有的,当然不同的人在不同的环境下测出来的结果会有略微的差异,大家可以自己测试一下。
阿里云的CP还支持自己的LSB,前面提到的Service的访问范围只是在集群内部,如果想要从集群外部来访问集群内部所提供的服务,那就需要一个入口点。阿里云Load Balancer可以支持这样的功能,这个功能也集成到了阿里云的Cloud Provider中,使用的时候只需要在创建应用的yaml File中指定service 的type = Load Balancer,然后就可以创建一个阿里云Load Balancer,然后它会自动地把Load Balancer关联到后端应用服务器,然后提供给用户一个静态的IP外网接入口,这样就可以通过IP来访问到集群内部的服务了,并且还提供了HTTPS的支持,用户可以上传自己的证书来提供HTTPS服务,还可以自定义SLB的带宽、健康检查类型以及URL、收费类型等。
K8S的Service是集群范围内的,同时阿里云现在提供另一套解决方案就是使用Ingress。Ingress可以把外部的流量引入进来,那么这与上面提到的LSB有什么区别呢?其实LSB是一个四层的东西,在IP层做负载均衡,而Ingress支持七层的负载均衡,它可以提供一种简单的路由服务,比如把某个域名的url定向一个Service的后端,也可以提供一种简单的服务的Fanout,就是可以用一个域名来提供服务,并根据不同的URL来定位到后端不同服务上去。用户也可以使用多个域名来提供服务,这类似于虚拟主机路由的方式,不同的域名会被路由到不同的后端服务上去。
然后右边这个是一个简单的架构图,最上层是阿里云的SLB,阿里云的SLB它的流量会被定位到两个Ingress Controller Pod里头去,这两个是一个简单的Nginx实现,通过这个Nginx做7层负载均衡,然后把这些流量再定位到你的应用Pod里面。另外一个特点它支持丰富的Annotation,可以支持SSL,第三方授权,ORL的Rewrite白名单管理等等这些功能。
阿里云的Cloud Provider还支持各种存储,比如NAS存储、OSS存储等。NAS存储是由原生的K8S的NFS驱动支持的。在这里简单介绍一下KBS的Volume的使用机制,K8S的PV就是一个持久化的卷,这需要由集群管理员首先在集群中创建出来作为一个集群内的资源,如果应用方想要在应用中使用,要先创建一个PVC,并要宣称要使用集群的存储资源,然后K8S会从所有的集群Volume里面去挑选出最合适、最匹配的,把它们绑定起来,绑定就意味着你可以使用这个PVC了。对于应用来讲,需要在Pod里面去声明需要使用PVC,然后应用就和PVC绑定起来了,这样在创建应用的时候,K8S就会把这个挂载到应用Pod里去,这样就可以像写本地磁盘一样去写Persistent-Volume。
阿里云还支持多可用区,主要是为了实现可用区的Fail Over。让用户可以在多个可用区之中创建集群,即使其他可用区Fail了,服务仍然是可用的。
阿里云还提供跨Region的支持。可用区级别是在各个可用区之间的,而同一个Region下的各个可用区的网络是连通的,所以部署起来非常简单。但是各个Region之间的网络是不通的,需要通过阿里云的高速通道把各个Region的网络首先打通,然后再部署应用。那么这里有一些限制,就是默认情况下,跨Region的阿里云资源是无法通用的,就是说在Region里面只能使用这个Region的资源,所以通常建议在每一个Region里面创建相同的资源,比如说SLB,创建一个应用之后,把这些应用的Pod平铺调度到多个Region当中,然后在每个Region中创建出一个SLB,把它绑定到应用上去。这样的好处是什么呢?绑定到SLB,然后在最外端提供一个智能DNS解析,把流量分别导入到这两个Region中,这样做可以支持一种邻近用户路由,比如说在杭州有一个Region,一些用户也在杭州,那么就会把杭州的用户导到杭州的Pod节点上面去,这样它的用户响应速度是非常快的,然后欧洲的用户就可以全部导到欧洲的集群里面去,所以这个对邻近用户选择是非常有帮助的。下图展现的就是跨Region支持的细节图。
以下内容根据演讲嘉宾现场视频以及速记整理而成。
今天主要会分享三个方面的问题:
- Kubernetes的基本概念介绍
- 如何在阿里云快速一键部署高可用安全的Kubernetes集群
- Kubernetes在阿里巴巴的Cloud Provider,也就是云厂商的集成提供的一些能力
首先简单介绍一下Kubernetes。Kubernetes简称K8S,这是社区的一种叫法。Kubernetes是整个CaaS工作流中的一环,CaaS是什么呢?就是Container As A Service——容器即服务,下图中的右图是一个简化版的CaaS的架构图,从最底层是一个基础服务,其上层主要提供的是物理机、网络、存储等一些比较硬件化的基础设施。再往上一层会构建PaaS平台,PaaS平台里头主要交付的对象是一些虚拟机,或者逻辑的结构,比如逻辑的VPC网络、存储等,让你可以方便地一键去创建这些资源,而不需要再去机房里头自己去运维管理这些东西。然后在PaaS平台上面会构建一层容器平台,这一层中主要的交互单元就是容器。
![176b7cbce6ea004780b019541e18665a9c0073e0](https://i-blog.csdnimg.cn/blog_migrate/0afb97670b0cd2adaa6d9fe711574472.png)
接下来分享一下Kubernetes的一些基本的概念,一个比较核心的概念就是Pod,Pod是一组容器的统称,就是它把一组容器作为一个最基础的调度单元,这组容器会被协同调度到一起,比如说有两个属于同一个Pod的容器,那么它们会被调度到同一个节点,一起调度,一起Fail Over。Service是一组Pod的抽象,比如在创建应用的时候可能需要创建很多个Pod来同时对外界提供服务,那么这一组Pod是同一个层次的东西,具有同等的地位,在前面提供一个Services对这一组Pod做负载均衡,当访问这个Services的时候,就会从后端随意挑出一个Pod来为前端提供服务,相当于负载均衡的概念,不过Services是集群内部的,它的网络只会局限于集群内部。
另外一个是Deployment概念,这是一个描述性的概念,就是当描述一个应用的时候就需要声明这个应用需要达到的状态,比如需要它有三个副本一直运行,需要它在故障的时候能够自动拉起来。用Deployment来描述它,然后系统就会自动保证这些东西,一旦出现了不符合预期的情况,系统会自动把这个状态转化到正常,无论是通过重新创建一组Pod或者是拉起原来的Pod。在K8S里面还有一个另外比较重要的概念就是持久化卷,通常来讲容器在创建的时候是没有数据卷的,对于存储在容器中的数据,如果把容器删掉了,那么这个数据也就会丢失。K8S提供一个持久化卷的概念,就是在创建服务的时候,可以先创建出这个卷,然后把这个卷挂载到容器里头去。通过这样的方式,在删除容器时,持久化卷是不会被删除的,数据也就可以保留下来。
下图是K8S的架构示意图,这是一个典型的无状态、多Master的分布式架构图。K8S主要功能组件:Kubelet,相当于Agent,在每一个节点上提供一个守护进程的服务,上报节点状态、运行Controller等。aplserver是一个Master,它是无状态的,所有的数据都存在后端的一致性存储中。Scheduler负责调度所有的Pod,也就是应用,为应用找一个合适的位置并运行起来。
![aa5868d1fbe7d22c170fa5ca87fc7248bccc8634](https://i-blog.csdnimg.cn/blog_migrate/ec134f54e0060626bb46f72b655fc3a4.png)
在使用K8S当中遇到的一个比较大的问题就是部署问题。众所周知K8S一直在业界被诟病的就是太难用了,组件太多,概念太多,导致无法理解。对于开发者来讲,不希望去操心如何把集群快速地部署起来,如何去理解底层的东西,只需在用到的时候能够部署一个集群出来,这是需要达到最终的目标,就是部署简单。
![9c115afe0372e5c1c59223a5c08dec066dd03b9a](https://i-blog.csdnimg.cn/blog_migrate/9816f0d732baac689b835f5e185be4c7.png)
那么阿里云的选择是什么呢?ROS + Kubeadm,原因只有一个:简单。首先简单介绍一下ROS,ROS是阿里云的资源编排服务,它可以非常方便的在阿里云一键创建出来所需要的各种资源比如ECS、VPC网络、SLB以及其他资源等等,相关的文档大家可以去阿里云官网查看。
一键部署主要分为三个步骤:
- 进入到ROS的控制台,这里有一个Kubernetes for chinese版本的,然后去点击创建。
- 选一个创建的区域。
- 填写创建的集群名称,填写节点的密码,点击创建。
主要的部署过程分为三个步骤:第一个是创建集群需要提供阿里云的KeyID跟KeySecret,首先需要设置这两个环境变量,然后需要从阿里云官方网站上下载一个脚本,执行一个node-type=Master命令,这个命令要在Master上执行,这样执行完了之后就在这台机器上初始化了一个Master了,然后它会返回一个Token和节点的IP。第二步再到node节点上面去把node-type改为node,然后带上KeyID跟KeySecre以及刚才返回的End Point和Token,就可以把这个结点加入到刚才创建的Master集群当中,如此反复,就可以把更多的节点加入到集群中去。当不想要某个节点的时候,还可以通过node-type = down的命令销毁掉这个节点。
![fc833a1947a857c67c29bfa235326245e81bdf7b](https://i-blog.csdnimg.cn/blog_migrate/124b3cad32f2f4475b51ad64360eae9b.png)
![dd87e5b24c00016e6bc326fb0c6e3dc4867ae1fe](https://i-blog.csdnimg.cn/blog_migrate/4dc43a5a68f15b7bbd83fda86b109f12.png)
![d76fc612e999810b3cbc25cae0ff3535b6c0d427](https://i-blog.csdnimg.cn/blog_migrate/a479aea757831146ae4ff2a6bce0d1fa.png)
![cd6d19b535d3f195d396b26c5f369f5460419563](https://i-blog.csdnimg.cn/blog_migrate/bc3f335870e69983cf5ad279a382c7c0.png)
实践过程中比较多的问题都来自于客户想了解VPC网络的性能究竟如何。在这里通过几种不同的方案来测试了一下VPC性能,主要有netprof、iprof以及qprof,下图是得出来的结果。从这些结果来看,容器的VPC网络跟主机VPC网络差距是非常小的,性能损耗是几乎是没有的,当然不同的人在不同的环境下测出来的结果会有略微的差异,大家可以自己测试一下。
![54b06ae9bb8bb600891b0c0c9383c35280430c21](https://i-blog.csdnimg.cn/blog_migrate/b735b9b60f22ac740bb413c9c5c85460.png)
![5246c26d6a7e3fb2f449ed6102a5e1b7168bb5f5](https://i-blog.csdnimg.cn/blog_migrate/46ea3fbc0084812b85e8712df5d13e8a.png)
![74dda4f759751b9d9473a0e96333ddbcfa6e2cfc](https://i-blog.csdnimg.cn/blog_migrate/04677675e5708295c5bde20c7752d8c5.png)
阿里云的Cloud Provider还支持各种存储,比如NAS存储、OSS存储等。NAS存储是由原生的K8S的NFS驱动支持的。在这里简单介绍一下KBS的Volume的使用机制,K8S的PV就是一个持久化的卷,这需要由集群管理员首先在集群中创建出来作为一个集群内的资源,如果应用方想要在应用中使用,要先创建一个PVC,并要宣称要使用集群的存储资源,然后K8S会从所有的集群Volume里面去挑选出最合适、最匹配的,把它们绑定起来,绑定就意味着你可以使用这个PVC了。对于应用来讲,需要在Pod里面去声明需要使用PVC,然后应用就和PVC绑定起来了,这样在创建应用的时候,K8S就会把这个挂载到应用Pod里去,这样就可以像写本地磁盘一样去写Persistent-Volume。
![01caceef542b8cfcd890fad3ee54097d7858e437](https://i-blog.csdnimg.cn/blog_migrate/590c9de9922339f5d5e2133b333042b6.png)
![16fe626fbe9d99c294ef3310eefbb868b76be3ee](https://i-blog.csdnimg.cn/blog_migrate/3ad641cb7870021cfb16d4e89fa7f581.png)
![f4446ebe31521500796bb865065f90fc210a0b3b](https://i-blog.csdnimg.cn/blog_migrate/ac4f507b54de41117edf99bf74c9629a.png)