云原生CloudNative 2022-10-21

2022-10-20  本文已影响0人  9_SooHyun

云原生CloudNative

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

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

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

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

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

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

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 对象

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


service

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

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 控制器实现的,不同控制器会有不同的附加功能

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种方式

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]
kubectl get pods pod1
kubectl get pod pod1
kubectl get po pod1

在k8s部署资源

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

问题排查

上一篇 下一篇

猜你喜欢

热点阅读