基础设施服务:dns很重要,以及服务注册,服务发现
k8s主要组成是master/node节点,要运行容器,必须先运行pod,pod也不会直接创建,而是先创建控制器(controller)
controller:可以想象成一张表,然后可以添加一个数据项,然后注册到apiserver,由schedler进行调度
service:service就是生成iptables规则,能够接收客户端请求,将流量通过负载均衡的方式分发给不同的pod
namespace:用来承载多租户或者多项目或多环境,只能创建在名称空间

master组成:
    kube-apiserver:是k8s是整个k8s系统的总线,所有的客户端组件都是通过apiserver协同的,数据都存在apiserver中,但是一般都会存储在ETCD中,
                    其实就是把etcd存储系统的k/v数据存储方案封装成为固定的格式.
    kube-scheduler:关注集群上的每个node的资源量,对pod进行合理调度,pod是k8s调度的最小单元,一个pod上可以运行多个容器,而这些容器必须要在一个node之上
    kube-controller-manager:其实这就是将k8s的各种控制器打包,例如route controller,service controller等,大部分决策都是由其决定的
    ETCD:基于raft协议的一个支持数据强一致的分布式k/v存储服务系统,如果一旦配置了ETCD,则apiserver会从有状态变为无状态(就是说数据会从apiserver
    转存到ETCD中),所以ETCD一般做3-5个节点的冗余
node组成:
    kubelet会注册监听apiserver的一些自己注册的重要的数据变动如容器集(pod)的增删改查,网络的增删改查等,基于https协议通信,而且要做双向认证.
        所以有三个标准的容器接口CNI(容器网络接口),VolumeCSI(容器存储接口),CRI(容器运行时接口)
    kube-proxy是一个代理服务组件,其实就是他生成的iptables规则,负责创建service,并把集群上的每一个service的定义转换为本地iptabels或ipvs规则,以便pod能被以负载均衡的方式调度docker等容器引擎,
        他们都是apiserver的客户端,只会与apiserver交互,表面上控制中心是apiserver而真正的控制中心是controller-mangager,实际上是apiserver
        控制controller-manager来与客户端交互.
而上方的api-server,schedler,controller-manager被称为控制平面,而kubelet,kube-proxy被称为数据平面

其他组件:
    ingress controller:就是对进入流量进行转发
    coredns:主要监听apiserver中的每一个service定义和分配的service地址,把他动态的添加为自己的解析记录,一般有三个记录,A记录,PTR记录,SRV记录(服务记录):一般作为服务注册和服务发现

k8s的基础工作逻辑:
    用户通过kubectl命令创建一个容器,这个时候会去找apiserver,apiserver接收到调度请求后会去找scheduler,而scheduler会选择一个最合适的node
    节点告知apiserver,api-server通知kubelet在哪一个node上创建该pod,kubelet调用docker创建该pod的同时会为该pod创建一个service(负载均衡器),而且可以对pod实
    现动态扩缩容,以及可以同operator创建有状态容器,例如mysql的主从复制等
    
k8s的组网模式有十多种:
    flannel:简单只构建了网络,没有网络策略
    calico:既构建了网络,又构建了网络策略,支持BGP协议
    canal:上面二者的整合版

容器之间的关系:
    紧密关系:pod同进同退,共享一组存储卷,只有那些如果没有lo接口,或者没有共享存储卷,就很难协同起来很好工作的容器,才能算的上是关系紧密的容器,除此之外的都是非紧密关系
        container to container
    非紧密关系:各自是各自的pod,需要借助网络插件,例如flannel等
        pod to pod:网络插件
        pod to service:iptables,ipvs规则
k8s的基本运行网络
    service网络:是一个10.96.0.0/12的子网,其实是一个虚假网络,没有出现在任何网络接口中,只出现在service中iptables规则当中,作为服务访问的端点使用的
                由kube-proxy进行管理的
    pod网络:会给每一个节点的pod分配一个子网,默认为10.244.0.0/16,最好适配网络插件的默认设定
    节点网络:主要用于各个node之间通信
    
pod之间的通信:
    同一节点:通过网桥的方式通信
    不同主机节点:如果通过叠加网络模型通信,因叠加网络的虚拟网卡是成对的,会将该网卡拆分成两半,一半在容器上,一半在物理网卡,当pod之间通信时
    会先到虚拟网桥(vbridge)然后到flannel隧道,然后给物理网卡发出,中间需要对数据包进行二次封装,二次封装是加上物理网卡的ip地址,所以会产生
    巨型帧,故需要调整MTU的大小。如果通过承载网络,就不会有隧道,而是通过内核路由转发,通过路由表查询,直接通过物理网卡进行通信
    
    pod到service通信:pod首先找到coredns解析servicename,得到IP地址后经过本地内核空间,访问service ip就可以与外部通信

    external client(外部客户端) to service:先进入节点网络,然后进入内核网络协议栈,找到对应的service,然后service将流量调度到pod,第二种是让pod直接共享
                                            节点的网络名称空间也就是桥接.
    辅助容器例如sidecar,daapter等:
    
    
pod创建及自动增减机制:kubelet会监视apiserver,而controller manager也会监视apiserver,当客户端请求创建一个deployment时,apiserver中就会有一个deployment数据项,
                这个时候deployment控制器就会监控apiserver中的deployment数据项,而deployment数据项中定义了需要创建的pod数量,类型(也就是pod模板)等,当
                apiserver发现自己没有这些pod时,deployment控制器就会请求apiserver创建这些pod,其实创建的是数据项并非真正的pod,因scheduler也监视着apiserver,此时
                schedler发现apiserver上有这些pod没有调度,于是就会选择一个合适的节点,并存回apiserver,此时kubelet发现apiserver中有跟自己相关的数据项,kubelet就会
                从数据项中的数据(pod数量,pod的类型(模板))拉取到本地运行成为pod,而kubeproxy会为pod创建service,并生成iptables规则,kubelet会随时监控pod的健康状态,
                一旦节点宕机了,apiserver会将其从自身数据项中删除,此时deployment控制器会也会发现数据项没了,会立即在向apiserver发出创建请求
    deployment:控制器一般包含如下信息
    
        replicas:指定运行的副本
    
        pod template:基于此模板创建pod
    
        label selector:标签选择器,主要用于关联各pod
    
api server简单理解:
    所提供的其实是一个restful风格的接口,把一切内部的概念都抽象为资源,而资源可以理解为一张表的定义,而资源有资源类型的概念
    pod deploment service等多个资源类型或理解为表,每个表都能存不同格式的数据项,每一个数据项被称为一个对象.
    
kubectl简单理解:
    其实调用kube API server的专用命令行客户端,kubectl真正创建对象的时候有三种方式:
        陈述式命令:直接在命令行中使命命令及其选项来实现
        命令式配置文件:通过命令的选项读取配置文件中加载配置数据
        声明式配置文件:通过声明式命令从配置文件中加载数据
        
应用类型:
        stateful(有状态应用)
        stateless(无状态应用)
        
kubeneters的资源分类:
    工作负载型(workload):就是为了运行应用的,例如pod
        deployment:是k8s中著名的无状态应用编排工具,而且提供了声明式配置,支持应用规模的自动扩缩容,滚动更新,金丝雀发布,蓝绿部署等
        daemonset:如果须在每个节点上运行有限的一个或多个应用的话就用daemonset,他也也是用来编排无状态应用的系统级应用,例如配置节点级日志节点采集器
        statefulset:提供了有状态应用的基本框架,距离完全达到用户期待的状态有很大差距
        operator:是statefulset的第二代,而具有专用性的资源
        job/cronjob:用来管理作业,不会长期运行,但是要确保其运行完毕,如果有周期性的就需要用cronjob来完成
        
    服务发现和负载均衡:
        service:
        ingress:
    配置和存储:
        configmap:用来向应用注入配置文件
        secret:用来向应用注入敏感信息,如密钥等
        PVC/PV:提供持久存储功能,可以借助pvc绑定到pv之上,从而为pod绑定外部存储空间
        downward API:注入环境信息
        
    作用域的级别的资源:
        名称空间级别(namespace):例如创建pod,必须要在某个名称空间内.防止pod的名字冲突等
        集群级别:例如namespace,node,clusterrole就是作用于整个集群
    
    元数据类型资源:
        limirange,...
        note:这些资源都各有规范,定义在资源群组内部,使用kubectl api-resources和kubectl api-version命令可以看到

k8s资源引用格式:
    <type>/<name>: pods/mypod, deployment/demoapp
    <type> <name>: pods mypod, deployment demoapp
    例如删除某个pod:kubectl delete pods mypod 或kubectl delete pods/mypod
    
k8s的node:
    在k8s1.3版本之前node中的kubelet默认会每10秒向apiserver发送自己的心跳信息和所维持的镜像信息,当超过四个周期没收到node的心跳信息,就会把该node标记为notready状态,
    并将该node上运行的镜像重新调度到别的node
    在1.3版本之后引入了节点租约,也就是在kube-node-lease名称空间,这个名称空间保存了分布式锁,但是保存了更多的节点租约信息,如果一个节点的状态没发生变化的情况下
    ,只报告心跳而不会报告自己所维持的镜像信息,大大减少了心跳信息报文的大小,节约了网络带宽
    
资源标签和注解:
    pod又名容器集,其实就是共享ipc,uts,network名称空间的一组容器,下面会有一个pause基础容器,主要提供存储卷和名称空间,其他容器都是加入进来的
    pod的生命周期:pod的status称为pod的phase,又名pod的相位:
                                                        runing  运行
                                                        pending 挂起(主要原因是未调度成功,或仍处于下载镜像的过程当中)
                                                        succeeded pod运行完毕,成功终止,一但其中一个没有成功终止就会为faild状态
                                                        unknown apiserver无法正常获取到pod信息,有可能是无法与kubelet正常通信导致
                                                    pod内部容器的状态
                                                        crashloopbackoff 原因有很多种
                                                        error
                                                
pod的运行逻辑:
    sidecar容器:主要为容器提供辅助功能
    adapater容器(适配容器):如果一个pod内部的应用的数据输出格式与规定格式不兼容,那就通过适配容器为其转换格式为规定格式
    ammbassador容器(大使格式容器):如果主容器不方便对外联络,可以通过大使容器对外联络,例如redis
    pod启动之前首先串行启动init container(初始化容器)因初始化容器有一个或多个,当初始化完成后,该容器就退出,然后运行(main containers)主容器和上面三种容器并行启动,但是无法人为控制启动顺序
    然后构建两个钩子和三个探针
    但是在一个pod的运行过程中会有两个非常重要的钩子(hook),这些钩子的作用就是允许我们人为的去运行一些命令或程序做一些自定义功能
        post start hook:主容器刚刚启动完的钩子,一般在容器刚刚初始化完成之后做一些人为自定义操作,例如设置主机名
        pre  stop  hook:容器结束之前的钩子,就是在容器结束之前做一些人为自定义操作,例如清理缓存
    三个探针:其实就是传感器,主要用来做自定义健康状态检测的,因为pod处于健康状态不代表容器健康,而容器处于健康状态不代表进程处于健康状态,但是kubelet又探测不到,所以有了这三个探针
        startup probe:启动探针,防止因某些服务启动时间较长导致健康状态检测失败导致pod无限重启
        liveness probe:存活探针,用来判断容器是否存活
        readiness probe:就绪探针,用来判断容器进程是否就绪,可以执行服务,例如war包

pod的创建和删除过程:
    使用kubectl create一个pod发给apiserver,apiserver将其存在etcd当中,scheduler会检测到该pod处于未调度状态,因此scheduler会挑选一个node并和该pod建立绑定关系存回到etcd中,然后kubelet监视到与自己有关的
    pod需要创建,拿到该容器的配置并启动容器并且运行完以后在存回到apiserver,由apiserver存回到etcd中。(删除过程类似)
    

k8s的命令:
    kubectl get pods mypod -o yaml  以yaml格式输出mypod的详细配置信息
    kubectl create -f testpods.yaml 读取yaml格式文件内容创建pod
    kubectl logs mypod                查看pod中容器的日志,如果有多个容器要用-c命令指定容器
    kubectl describe pods mypod        查看mypod的详细信息,排错时至关重要
    kubectl exec -it mypod -- /bin/bash 进入pod中的容器中,如果一个pod中有多个容器,使用-c选项指定容器
    kubectl delete -f testpods.yaml    通过yaml文件删除资源
    kubectl apply -f testpods.yaml    创建一个资源,如果已经有了就不会创建,或者对已存在的进行修改
    
    
任务:把mysql运行为pod,设定好管理员密码,部署一个wordpress的pod,让其联系到mysql,开放到集群外部,加一个nginx做反代。

Logo

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

更多推荐