美文网首页
云原生CloudNative 2022-10-21

云原生CloudNative 2022-10-21

作者: 9_SooHyun | 来源:发表于2022-10-20 15:23 被阅读0次

    云原生CloudNative

    关于云原生,网络上的释义有很多,但容器微服务这两个概念是它们的共性。换句话说,云原生就是指app的设计和开发就是面向容器和微服务的云环境的

    • 微服务:1.应用间通过restful api通信 2.应用可以独立部署、更新、扩缩容和重启
    • 容器化:微服务的最佳载体

    k8s架构

    k8s核心作用:服务自动扩缩容

    Kubernetes是容器编排调度引擎,可以看做云原生时代的操作系统,统一管理下层的基础设施,如计算资源、网络资源、存储资源等等

    kubernetes-overview

    k8s运行在node上,node包括 master节点 和 worker(Slave)节点两种
    因此K8S属于主从设备模型(Master-Slave架构),Master节点负责核心的调度、管理和运维,Slave节点则在执行用户的程序

    kubernetes-high-level-component-archtecture

    Master Node和Worker Node

    Master Node和Worker Node是分别安装了K8S的Master和Woker组件的实体服务器,每个Node都对应了一台实体服务器(虽然Master Node可以和其中一个Worker Node安装在同一台服务器,但是建议Master Node单独部署),所有Master Node和Worker Node组成了K8S集群,同一个集群可能存在多个Master Node和Worker Node

    • master node上包含API Server、Controller Manager、Scheduler Manager以及etcd(key-value db)四个主要组件,这四个组件组成k8s的控制平面control plane

      • kube-apiserver对外暴露了Kubernetes API,是control plane的前端。一般可以运行 kube-apiserver 的多个实例,并在这些实例之间平衡流量。The core of Kubernetes' control plane is the API server. The API server exposes an HTTP API that lets end users, different parts of your cluster, and external components communicate with one another. Eg, the kubectl command-line tools interact with the API server.

      • kube-scheduler,负责监视新创建的、未指定运行节点(node)的 Pods,选择合适的节点来运行这些pod(watches for newly created Pods with no assigned node, and selects a node for them to run on.)

      • Controller Manager runs controller processes,通过apiserver监控集群的公共状态,努力让当前状态current state对齐到期望状态 desired state

      • etcd,集群数据存储. Consistent and highly-available key value store used as Kubernetes' backing store for all cluster data.
        If your Kubernetes cluster uses etcd as its backing store, make sure you have a back up plan for those data.

    • Woker node
      当你部署容器或 pod 时,其实是在将它们部署到 worker 节点上运行。Worker 节点托管和运行一个或多个容器的资源

      worker node component(worker节点的组件)

      • kubelet,运行在集群中的每个node上面,保证容器都运行在pod中。kubelet 不会管理不是由 Kubernetes 创建的容器
      • kube-proxy,是集群中每个node上运行的网络代理

    Kubernetes上运行应用

    Kubernetes提供了多种资源对象,用户可以根据自己应用的特性加以选择。这些对象有:

    类别 名称
    资源对象 Pod、ReplicaSet、ReplicationController、Deployment、StatefulSet、DaemonSet、Job、CronJob、HorizontalPodAutoscaler
    配置对象 Node、Namespace、Service、Secret、ConfigMap、Ingress、Label、CustomResourceDefinition、 ServiceAccount
    存储对象 Volume、Persistent Volume
    策略对象 SecurityContext、ResourceQuota、LimitRange

    pod

    Kubernetes 中的逻辑而非物理的最小工作单位称为 pod
    Pod is a collection of containers that can run on a host

    • why we need pod instead of container?

    容器设计理念是一个容器只运行一个主进程,不同程序又要有依赖关系,于是在上层再抽象一个pod包装起来他们

    k8s利用pod处理多个container之间的关系。一个pod内的containers可以共享信息
    容器可以让你创建独立、隔离的工作单元,可以独立运行。但是要创建复杂的应用程序,比如 Web 服务器,你经常需要结合多个容器,然后在一个 pod 中一起运行和管理。这就是 pod 的设计目的 —— 一个 pod 允许你把多个容器,并指定它们如何组合在一起来创建应用程序。而这也进一步明确了 Docker 和 Kubernetes 之间的关系 —— 一个 Kubernetes pod 通常包含一个或多个 Docker 容器,所有的容器都作为一个单元来管理

    Pod的网络可以简单分为两类

    • pod网络和底层网络可以直接通信,和底层节点在同一个网络平面
    • pod网络在overlay,使用私有IP,默认仅在集群内相互通信

    ReplicationController和ReplicaSet

    ReplicationController和ReplicaSet是 Kubernetes 的另一关键功能,负责实际管理 pod 生命周期,可以启动和杀死pod。
    ReplicaSet ensures that a specified number of pod replicas are running at any given time. 它的主要作用就是保证一定数量的 Pod 能够在集群中正常运行,它会持续监听这些 Pod 的运行状态,在 Pod 发生故障重启数量减少时重新运行新的 Pod 副本。ReplicationController represents the configuration of a replication controller. 所有 ReplicaSet 对象的增删改查都是由 ReplicaSetController 控制器完成的

    Deployment

    Deployment enables declarative updates for Pods and ReplicaSets,经常会用来创建 ReplicaSetPod。每一个 Deployment 都对应集群中的一次部署,是非常常见的 Kubernetes 对象

    • why we need deployment and replicaset both?

    之所以有deployment和replicaset两个对象,是遵守Single responsibility principle即单一功能原则,认为对象应该仅具有一种单一功能的概念。
    deployment相比replicaset有版本的概念,而replicaset没有,所以可以方便地利用deployment进行版本更新和回滚
    另外,在具体实现版本更新的时候,K8S采用滚动更新,即再创建一个新的replicaset对象,用来管理新版本的多个pod,等新的replicaset的各个pod都ready后,才会把老的replicaset杀掉。这也是符合“不可变基础设施”的Cloud Native设计原则的


    service

    Kubernetes 中的 service 是一组逻辑上的 pod,是一个抽象概念

    • why we need service?

    Kubernetes Pod 是有生命周期的。它们可以被创建,而且销毁之后不会再启动。如果使用 Deployment 来运行应用程序,则它可以动态创建和销毁 Pod。
    每个 Pod 都有自己的 IP 地址,但是在 Deployment 中,在同一时刻运行的 Pod 集合可能与稍后运行该应用程序的 Pod 集合不同。
    这导致了一个问题: 如果一组 Pod(称为“后端”)为群集内的其他 Pod(称为“前端”)提供功能, 那么前端如何找出并跟踪要连接的 IP 地址,以便前端可以使用工作中的后端部分?service就解决这个问题

    service解决的是一组pod对集群内提供服务时的内部网络访问问题

    service使用labels(标签)来选择它所持有的pod集合。例如,一个service指定label=abc,那么所有具有abc label的pod都归属于该service,当该service需要扩展 pod 时,只需要同样打上abc label即可

    同时,Service这个对象有几种类型。ClusterIP 类型的服务通常用作本集群内部的互相通信;NodePort 类型的服务会在集群每个节点上开放同一个端口,对外提供服务;如果集群在公有云上部署或者有兼容的负载均衡支持的环境里运行,还可以使用 Loadbalancer 类型的服务,可以自动跟负载均衡设施打通,得到外部 IP 之类的支持。

    补充说明:K8S集群的网络管理和拓扑也有特别的设计,集群内的每一个Pod都有自己的IP(类似一个Pod就是一台服务器,然而事实上是多个Pod存在于一台物理/虚拟服务器上,只不过是K8S做了网络隔离),在K8S集群内部还有DNS等网络服务(一个K8S集群就如同管理了多区域的服务器,可以做复杂的网络拓扑)。

    总结:
    Service是K8S服务的核心,屏蔽了服务细节,统一对外暴露服务接口,真正做到了“微服务”
    举个例子,我们的一个服务A,部署了3个备份,也就是3个Pod;对于用户来说,只需要关注一个Service的入口就可以,而不需要操心究竟应该请求哪一个Pod。优势非常明显:一方面外部用户不需要感知因为Pod上服务的意外崩溃、K8S重新拉起Pod而造成的IP变更,外部用户也不需要感知因升级、变更服务带来的Pod替换而造成的IP变化,另一方面,Service还可以做流量负载均衡。

    Ingress

    Ingress 资源更近一步,可以在集群边缘为暴露出来的服务提供域名、rewrite、认证之类的更高级功能,Ingress 对象是由 ingress 控制器实现的,不同控制器会有不同的附加功能

    • why we need Ingress?

    Ingress 是对集群中服务的外部访问进行管理的 API 对象,典型的访问方式是 HTTP

    ingress vs service

    总结:Ingress负责集群内外通讯

    configmap和secret

    ConfigMap对象是一系列配置的集合,k8s会将这一集合注入到对应的Pod对象中,用于容器的启动。配置注入pod的方式一般有两种,一种是挂载存储卷,一种是传递变量。ConfigMap被引用之前必须存在,属于名称空间级别,不能跨名称空间使用,内容明文显示。ConfigMap内容修改后,对应的pod必须重启或者重新加载配置
    Secret类似于ConfigMap,是用Base64加密,密文显示,一般存放敏感数据。一般有两种创建方式,一种是使用kubectl create创建,一种是用Secret配置文件

    namespace

    namespace跟Pod没有直接关系,而是K8S另一个维度的对象
    或者说,前文提到的概念都是为了服务Pod的,而namespace则是为了服务(逻辑划分)整个K8S集群的。

    那么,namespace是什么呢?
    官方文档定义:

    Kubernetes 支持多个虚拟集群,它们底层依赖于同一个物理集群。 这些虚拟集群被称为名字空间

    namespace是为了把一个K8S集群划分为若干个资源不可共享的虚拟集群

    前文提到的所有k8s资源对象,都是在namespace下的;也有一些对象是不隶属于namespace的,而是在K8S集群内全局可见的,官方文档提到的可以通过命令来查看:

    # 位于名字空间中的资源
    kubectl api-resources --namespaced=true
    
    # 不在名字空间中的资源
    kubectl api-resources --namespaced=false
    

    容器登录管理

    主要有3种方式

    • 容器内部署sshd服务,直接ssh登上容器
    • 先登陆到容器所在的node,然后docker exec
    • 借助k8s,如kubecli或者k8s的webconsole

    One way to create a k8s object using a .yaml file is to use the kubectl apply command in the kubectl command-line interface, passing the .yaml file as an argument. Here's an Deployment-Creating example:

    kubectl apply -f https://k8s.io/examples/application/deployment.yaml
    

    For objects that have a spec, you have to set this when you create the object, providing a description of the characteristics you want the resource to have: its desired state.

    The status describes the current state of the object, supplied and updated by the Kubernetes system and its components

    references:
    https://jimmysong.io/kubernetes-handbook/
    https://kubernetes.io/docs/home/
    https://zhuanlan.zhihu.com/p/292081941

    如何使用kubectl命令行

    使用kubectl命令行工具可以直接和api server交互,创建各种资源对象

    总览-kubectl命令行pattern

    命令行的pattern为:

    kubectl [command] [resource_type] [resource_instance_name] [flags]
    
    • command
      create describe delete get
    • resource_type
      deployment, pod, etc. 注意,资源类型不区分大小写,单数/复数/缩写都是合法的:
    kubectl get pods pod1
    kubectl get pod pod1
    kubectl get po pod1
    
    • resource_instance_name
      具体的资源实例的名称
      注:如果要操作不同资源类型的资源实例,cmd pattern为kubectl comand type1/name1 type2/name2 ... [flags]
    • flags
      可选参数。如-n -s

    在k8s部署资源

    在k8s部署deployment、pod等资源相当简单,仅需两步:

    • 准备yaml配置文件
    • 执行kubectl create -f ${resource_yaml}(或者kubectl apply -f ${resource_yaml},更新也是一种创建)

    问题排查

    • 部署失败排查
      当pod起不来时,kubectl describe [resource_type] [resource_instance_name]
    • pod 已经running,但是提供的服务不符合预期
      这时需要进入pod内部查看container的日志
      • 查看pod内特定container打印到标准输出的日志 kubectl log ${pod_name} -c ${container_name}
      • 进入container内部查看容器落盘的日志 kubectl exec -it ${pod_name} -c ${container_name} [args]

    相关文章

      网友评论

          本文标题:云原生CloudNative 2022-10-21

          本文链接:https://www.haomeiwen.com/subject/uukmzrtx.html