k8s基本架构
k8s
k8s是kubernetes的缩写,kubernetes是希腊语中领航员的意思。
对象
每个API对象都有3大类属性:元数据metadata、规范spec和状态status。
元数据metadata是用来标识API对象的,每个对象都至少有3个元数据:namespace,name和uid;除此以外还有各种各样的标签labels用来标识和匹配不同的对象。
对于具有 spec 的对象,你必须在创建对象时设置其内容,描述你希望对象所具有的特征: 期望状态(Desired State) 。
status 描述了对象的 当前状态(Current State),它是由 Kubernetes 系统和组件 设置并更新的。
pod
Pod 在其生命周期中只会被调度一次。 一旦 Pod 被调度(分派)到某个节点,Pod 会一直在该节点运行,直到 Pod 停止或者 被终止。
Pod重启策略,在Pod中的容器可能会由于异常等原因导致其终止退出,Kubernetes提供了重启策略以重启容器。重启策略对同一个Pod的所有容器起作用,容器的重启由Node上的kubelet执行。Pod支持三种重启策略,在配置文件中通过restartPolicy字段设置重启策略,这里的重启是指在Pod的宿主Node上进行本地重启,而不是调度到其它Node上。:
- Always:只要退出就会重启。
- OnFailure:只有在失败退出(exit code不等于0)时,才会重启。
- Never:只要退出,就不再重启
资源限制,Kubernetes通过cgroups限制容器的CPU和内存等计算资源,包括requests(请求,调度器保证调度到资源充足的Node上)和limits(上限)等:
apiVersion: v1
kind: Pod
metadata:
labels:
app: nginx
name: nginx
spec:
containers:
- image: nginx
name: nginx
resources:
requests:
cpu: "300m"
memory: "50Mi"
limits:
cpu: "500m"
memory: "128Mi"
健康检查,在Pod部署到Kubernetes集群中以后,为了确保Pod处于健康正常的运行状态,Kubernetes提供了两种探针,用于检测容器的状态:
- Liveness Probe :检查容器是否处于运行状态。如果检测失败,kubelet将会杀掉掉容器,并根据重启策略进行下一步的操作。如果容器没有提供Liveness Probe,则默认状态为 Success。
- ReadinessProbe :检查容器是否已经处于可接受服务请求的状态。如果Readiness Probe失败,端点控制器将会从服务端点(与Pod匹配的)中移除容器的IP地址。Readiness的默认值为Failure,如果一个容器未提供Readiness,则默认是Success。
kubelet在容器上周期性的执行探针以检测容器的健康状态,kubelet通过调用被容器实现的处理器来实现检测,在Kubernetes中有三类处理器:
- ExecAction :在容器中执行一个指定的命令。如果命令的退出状态为0,则判断认为是成功的;
- TCPSocketAction :在容器IP地址的特定端口上执行一个TCP检查,如果端口处于打开状态,则视为成功;
- HTTPGetAcction :在容器IP地址的特定端口和路径上执行一个HTTP Get请求使用container的IP地址和指定的端口以及请求的路径作为url,用户可以通过host参数设置请求的地址,通过scheme参数设置协议类型(HTTP、HTTPS)如果其响应代码在200~400之间,设为成功。
replicationcontroller
replicationcontroller已经过时了,新的replicaset作为替代,也不用直接创建replicaset,创建deployment会自动创建的。不过这里还是学一学。
ReplicationController的主要功能是保证Pod的数量、健康,弹性收缩等。但是Deployment除了有这些功能之外,还增加了回滚功能(当升级 pod 镜像或者相关参数的时候,如果有错误,可以回滚到上一个稳定版本),版本记录(每一次对 Deployment 的操作都能保存下来)。暂停和启动(升级的时候,能随时暂停和启动)。
apiVersion: v1
kind: ReplicationController
metadata:
name: nginx
spec:
replicas: 3
selector:
app: nginx
template:
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
其中spec.template是spec中必须填写的,它就是一个pod的配置。其中.spec.replicas表示这个pod需要维持几份。如果没有配置的话,它就是为1。比如上面那个例子,就保持3份nginx服务。
标签选择器在很多概念都是会使用到的,比如pod在哪个node上,ReplicationController作用在哪个pod上,service作用在哪个pod上,等等。tag标注的系统化也是k8s应用集群必要的设计之一。
service
Kubemetes 服务是一种为一 组功能相同的 pod 提供单一 不变的接入点的资源。 当服务存在时,它的 IP 地址和端口不会改变。 客户端通过 IP 地址和端口号建立连接,这些连接会被路由到提供该服务的任意一个 pod 上。 通过这种方式, 客户端不需要 知道每个单独的提供服务的pod的地址, 这样这些pod就可以在集群中随时被创建 或移除。
下面创建了一个名叫kubia的服务,它将在端口80接收请求并将连接路由到具有 标签选择器是app=kubia的pod的8080端口上。
apiVersion: v1
kind: Service
metadata:
name: kubia
spec:
ports:
- port: 80
targetPort: 8080
selector:
app: kubia
如果希望特定客户端产生的所有请求每次都指向同 一个 pod, 可以设置服务的 sessionAffinity 属性为 C巨entIP (而不是 None,None 是默认值), 如下面的代码清单所示。
apiVersion: v1
kind: Service
spec:
sessionAffinity: ClientIP
Kubernetes 仅仅支持两种形式的会话亲和性服务: None 和 Client工P。你或 许惊讶竞然不支持基于 cookie 的会话亲和性的选项,但是你要了解 Kubernetes 服务 不是在 HTTP 层面上工作。服务处理 TCP 和 UDP 包,并不关心其中的载荷内容。 因为 cookie 是 HTTP 协议中的一部分,服务并不知道它们,这就解释了为什么会话 亲和性不能基千 cookie。
服务发现:
- 通过环境变量发现服务:在 pod开始运行的时候, Kubem巳tes会初始化一系列的环境变量指向现在存在 的服务。 如果你创建的服务早于客户端pod的创建, pod上的进程可以根据环境变 量获得服务 的 IP 地址和端口号 。
- 通过 DNS 发现服务:运行在 pod 上的进程 DNS 查询都会被 Kubemetes 自身的 DNS 服 务器 响应, 该服务 器知道系统中运行的所有服务 。
将服务暴露给外部客户端:
- 将服务的类型设置成NodePort-每个集群节点都会在节点上打开一 个端口, 对于NodePort服务, 每个集群节点在节点本身(因此得名叫 NodePort)上打开一 个端口,并将在该端口上接收到的流量重定向到基础服务。 该服务仅在内部集群 IP 和端口上才可访间, 但也可通过所有节点上的专用端 口访问。
- 将服务的类型设置成LoadBalance, NodePort类型的一种扩展一—这使得 服务可以通过一个专用的负载均衡器来访问, 这是由Kubernetes中正在运行 的云基础设施提供的。 负载均衡器将流量重定向到跨所有节点的节点端口。 客户端通过负载均衡器的 IP 连接到服务。
- 创建一个Ingress资源, 这是一个完全不同的机制, 通过一个IP地址公开多 个服务——它运行在HTTP层(网络协议第7层)上, 因此可以提供比工作
在第4层的服务更多的功能。
挂载卷
Kubernetes 的卷是 pod 的一个组成部分, 因此像容器一样在 pod 的规范中就 定义了。 它们不是独立的 Kubernetes 对象, 也不能单独创建或删除。 pod 中的所 有容器都可以使用卷, 但必须先将它挂载在每个需要访问它的容器中。 在每个容器 中, 都可以在其文件系统的任意位置挂载卷。
可用的卷类型:
- emptyDir: 用于存储临时数据的简单空目录。
- hostPath:用于将目录从工作节点的文件系统挂载到pod中。
- gitRepo:通过检出Git仓库的内容来初始化的卷。
- nfs:挂载到pod中的NFS共享卷。
- gcePersistentDisk (Google 高效能型存储磁盘卷)、 awsElastic BlockStore (AmazonWeb 服务弹性块存储卷)、 azureDisk (Microsoft Azure 磁盘卷)一一用于挂载云服务商提供的特定存储类型。
- cinder、 cephfs、 iscsi、 flocker、 glusterfs、 quobyte、 rbd、 flexVolume 、 vsphere -Volume 、 photoPersistentDisk、 scaleIO 用于挂载其他类型的网络存储。
- configMap、 secret、 downwardAPI:用于将 Kubemetes 部分资源和集 群信息公开给 pod 的特殊类型的卷 。
- persistentVolumeClaim:一种使用预置或者动态配置的持久存储类 型(我们将在本 章 的最后 一 节对此展开讨论) 。
emptyDir:最简单 的卷 类型是 emptyDir 卷,所以作为 第一个例子让我们看看如何在 pod 中定义卷 。 顾名思义,卷从一个 空 目录开始,运行在 pod 内的应用程序可以写入它 需要 的任何文件 。因为卷的生存周期与 pod 的生存周期相 关联 ,所以 当删除 pod 时, 卷的内容就会丢失 。
hostPath:hostPath 卷指向节点文件系统上的特定文件或目录(请参见图 6.4)。 在同一 个节点上运行并在其 hostPath 卷中使用相同路径的 pod 可以看到相同的文件
deployment
Deployment是一 种更高阶资源,用于部署应用程序并以声明的方式升级应用, 而不是通过 ReplicationController 或 ReplicaSet 进行部署,它们都被认为是更底层的 概念。
当创建一个Deployment时, ReplicaSet 资源也会随之创建(最终会有更多的资源被创建)。 在第4章中, ReplicaSet 是新一代的 ReplicationController, 并推荐使用 它替代ReplicationController来复制和管理pod。 在使用Deployment时,实际的pod 是由 Deployment 的 Replicaset 创建和管理的, 而不是由 Deployment 直接创建和管理的。
apiVersion: app/v1beta1
kind: Deployment
metadata:
name: kubia
spec:
replicas: 3
template:
metadata:
name: kubia
labels:
app: kubia
spec:
containers:
- image: luksa/kubia:v1
name: nodejs
只需修改 Deployment 资源 中定义的 pod 模板, Kubemetes 会自动将实际的系统状态收敛为资源中定义的状态。 类似于将 ReplicationController 或 ReplicaSet 扩容或者缩容, 升级需要做的就是在部署的 pod 模板中修改镜像的 tag, Kubemetes 会收敛系统, 匹配期望的状态。