容器编排技术

容器编排将部署、管理、弹性伸缩、容器网络管理都自动化处理,当需要管理成百上千个 containers 和主机时,企业将从容器编排中获得极大优势。容器编排为基于微服务的应用程序提供了一个理想的应用程序部署单元和自包含的执行环境,这使应用可以在同一硬件上,以微服务的形式运行多个独立的模块,对每个模块获得更好的控制和生命周期管理。
容器编排常用于自动化和管理任务,比如:

  • 资源调配和部署
  • 配置和调度
  • 资源分配
  • 容器可用性
  • 跨基础架构根据负载压力扩展或移除容器
  • 负载平衡和流量路由
  • 监控容器运行状况
  • 根据将要运行的容器配置应用
  • 保障容器之间交互的安全

常见容器编排技术框架

Kubernetes, Docker Swarm, Apache Mesos。本文针对Kubernetes(以下简称k8s)进行介绍。

k8s拓扑结构

请添加图片描述

基础设施节点(机器)

  • mastet节点:中心控制节点,其上运行api-server、scheduler、etcd、controller manager等进程,用户可通过api-server对整个集群进行管理,master节点自身是不运行其他pod的(默认行为),master节点允许多实例
  • work节点:pod运行的节点,真正”干活“的节点,其上运行若干pod,并由master节点统一调度

基础服务

  • docker:不解释,k8s基于容器技术实现了容器编排,docker是容器技术的实现方式之一
  • kublet:所有机器都要安装kublet,负责对当前节点进行控制
  • kube proxy:负责节点内的流量分发,kube proxy会被kublet拉起和停止,所以不需要对kube proxy单独进行控制

k8s概念

  • pod:k8s中的最小单元,一个pod中可以包含一个或多个container,一个pod中通常只运行一个应用
  • replicaset/deployment/daemonset/statefulset:负责创建和管理pod,他们每个都可以管理多个pod,其中使用较多的是deployment/daemonset/statefulset
    • deployment:最经典的pod管理方式,deployment会定义pod的基本信息,包括使用的镜像,端口映射,卷映射等,以及pod的副本数量,定义完成后,k8s会自动将pod创建在集群中,并且在pod死亡时自动创建新的pod,运行pod的节点是随机的,pod死亡后被重建时的节点也是随机的
    • daemonset:和deployment几乎相同,区别是daemonset在每个节点上只会创建一个pod实例,通常用于监控程序的运行
    • statefulset:和deployment相比,statefulset的pod名字是可以提前预知的,且statefulset可以与pvc配合用来生成动态的存储数据
  • service:相当于pod的抽象,为多个pod提供统一的出口服务。当一组相似的pod运行时(例如微服务中某个应用部署了多个副本),service可以为这组pod提供一负载均衡器,负责把流量分配到各个pod上
  • configmap/secrets:程序配置存储,secrets负责敏感数据存储*
  • volume:可装载磁盘文件存储
  • pv/pvc:超大磁盘存储抽象和分配机制
  • label/selector:负责对资源进行标记和筛选,k8s非常经典的设计
  • probe:探针,分为liveness探针和readness探针,用于探测pod是否存活和可读
  • job/cronjob:k8s内需要单次/多次执行的任务
  • namespace:k8s内的资源隔离机制

k8s网络

集群内通信

k8s依赖proxy实现节点内的流量控制,但在整个集群中,我们经常需要跨主机通讯,这时就需要安装额外的网络插件,常用的网络插件有flannel和calico,他们的区别这里不在细说。
如果我们使用kubeadm安装k8s,kubeadm默认会安装coredns用来实现dns解析,但是coredns默认是无法工作的,因为缺少插件无法实现跨主机通讯,当我们安装flannel或calico后,coredns就会自动恢复。
在k8s集群内,service可以负责对同一组内的pod实现负载均衡,但是service自身的ip地址是随机分配的,因此我们希望有一种dns机制,可以让我使用域名而非service自身的ip去访问某个service(我们有时也希望使用域名去访问某个具体的pod,例如在statefulset中,我们可以提前预知每个pod的名称,因此有时我们也希望使用statefulset中每个pod的名称去访问某个pod)。
在集群内部,我们如果需要访问某个service,可以使用service名称.svc.cluster.local来访问某个service,当使用statefulset时,我们可以使用
pod名称.service名称.svc.cluster.local去访问某个具体的pod。

服务暴露

k8s集群服务暴露方式有三种:
nodeport:此方式会在集群的所有节点上开启一端口,当流量从任意节点的此端口进入集群时,流量会被flannel/calico定向到service上,然后由kubeproxy分配到具体的pod中
ingress:使用此方式可以为集群配置统一的流量入口,ingress支持使用host/path的方式将流量分配到某个service上,ingress的实现方式之一便是ingress-nginx-controller,此种方式使用了nginx作为反向代理,并由ingress-controller动态的为nginx下发配置文件
loadbalance:此方式通常由云服务提供商提供,各个服务商的实现方式都不相同,使用方式要参考各个服务商的文档

k8s服务部署

  • 人机交互:k8s的命令行工具为kubectl,通常我们使用kubectl就可以实现对k8s集群的管理;此外,我们还可以使用k8s的api实现对k8s的管理
  • 服务配置:使用yml文件描述服务,然后使用kubectl将yml文件配置到集群中

总结

使用k8s让我们可以对服务器集群进行统一的管理和规划,能更合理、高效的使用集群资源。

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐