点击关注公众号,k8s优秀车间主任及时送达
一、资源对象概括
Kubernetes资源对象可以分为两类:
(1)某种资源的对象,例如节点(Node)、Pod、服务、(Service)、存储卷(Volume)。
(2)与资源对象相关的事件与动作,例如标签(Label)、注解(Annotation)、命名空间(Namespace)、部署(Deployment)、HPA、PVC。
资源对象一般包括几个通用属性:版本、类别(Kind)、名称、标签、注解。
(1)版本信息有的时候会随着属性变化而变化。
(2)资源对象的名称是唯一性的。
(3)资源对象标签非常重要,主要用于实现不同的资源对象进行关联。
(4)注解通常用于实现资源对象属性的自定义扩展。
在Kubernetes中我们可以使用YAML或者JSON来进行格式声明(定义或者创建)。再通过kubectl工具进行管理或者(API编程调用)。
Kubernetes资源对象生命周期相应状态如下:
(1)Pending:Pod 已被 Kubernetes 系统接受,但有一个或者多个容器镜像尚未创建。等待时间包括调度 Pod 的时间和通过网络下载镜像的时间,这可能需要花点时间。
(2)Running:表示成功状态。
(3)Succeeded:Pod 中的所有容器都被成功终止,并且不会再重启。
(4)Failed:非正常停止状态。Pod 中的所有容器都已终止了,并且至少有一个容器是因为失败终止。也就是说,容器以非0状态退出或者被系统终止。
(5)Unknown:因为某些原因无法取得 Pod 的状态,通常是因为与 Pod 所在主机通信失败。
二、集群类
集群(Cluster)表示一个由Master和Node组成的Kubernetes集群。
1、Master是Kubernetes集群的控制节点,是整个集群的 "大脑" ,如果master发生宕机,整个集群就无法正常运行了,所以至少需要部署3台或者更多的高可用Master。
Kubernetes关键组件介绍如下:
(1)etcd保存整个集群的状态数据。
(2)API Server(kube-apiserver)提供资源唯一入口,并提供认证、授权、访问控制、API注册和发现等机制。
(3)kube-controller-manager 负责维护集群的状态,比如故障检测、自动扩展、滚动更新等。
(4)kube-scheduler 负责资源的调度,按照预定的调度策略将 Pod 调度到相应的机器上。
(5)kubelet 负责维持容器的生命周期,同时也负责 Volume(CVI)和网络(CNI)的管理。
(6)Container runtime 负责镜像管理以及 Pod 和容器的真正运行(CRI),默认的容器 运行时为 Docker。
(7)kube-proxy 负责为 Service 提供 cluster 内部的服务发现和负载均衡。
除了核心组件,还有一些推荐的Add-ons:
(1)kube-dns 负责为整个集群提供 DNS 服务。
(2)Ingress Controller 为服务提供外网入口。
(3)Heapster 提供资源监控。
(4)Dashboard 提供 GUI。
(5)Federation 提供跨可用区的集群。
(6)Fluentd-elasticsearch 提供集群日志采集、存储与查询。
2、Node是除Master节点外的服务器。Node可以是一台物理机也可以是一台虚拟机。Node属于Kubernetes工作负载的节点,每台Node都会被Master负载一些容器。每台Node都会在对应的Master注册自己,就会定期向Master汇总自己的资源信息,如系统的CPU和内存使用率情况等等。Node存在两种状态:Not Ready和Ready,Not Ready表示无法与Master进行通信,会被Master判定为"失联",就会被标记不可用(Not Ready),Ready反之。
$ kubectl get nodes #可以查看运行了多少个集群状态
$ kubectl describe node #查看某个node详细信息
通过上述命令会显示如下相关信息:
(1)Node的基本信息:名称、标签、创建时间等。
(2)Node当前运行的状态。
(3)Node的主机地址和主机名。
(4)Node可分配的资源数量。
(5)当前运行的Pod列表该要信息。
(6)已分配的资源使用概要信息。
(7)Node相关的Event信息。
在生产环境中,不可能每台Node都是资源充裕的或者健康的。所以这个时候即出现了一个特殊的标签——污点(Taint)和容忍(Toleration)。污点是让节点彻底拒绝Pod的调度,容忍是可以Pod短期存在Node节点上。
在Node中还有一个重要概念——命名空间。非常相似与网络中Vlan技术,在大白话说就等于分组,它们相互隔离着。在集群创建完成后,Master会自动创建两个命名空间,一个默认的(default)、一个是系统级的(kube-system)。在K8s中你如果不指定创建的Pod默认会分配到default空间。系统级存放着如网络组件、DNS组件、监控组件等等。
下面使用YAML创建命名空间格式:
apiVersion: v1
kind: Namespace #定义类型为命名空间
metadata:
name: development #定义命名空间名称
或者也可以直接使用kubectl创建如下:
$ kubectl create namespace #创建命名空间
$ kubectl get namespaces #查看当前所有命名空间
二、应用类
Kubernetes中属于应用类的概念和相应的资源对象类型很多。
1、Service指的是无状态服务,Service是一种可以访问Pod分组策略,Service通常使用Label Selector访问Pod组。
Service类型可以分为四种如下:
(1)ClusterIP:默认类型,Service具有一个全局唯一的虚拟ClusterIP地址,只要Service被创建就会被分配虚拟IP+服务端口号。ClusterIP内部访问的虚拟IP。
(2)NodePort:在ClusterIP基础上为Service在每台机器上绑定一个端口,这样就可以通过: NodePort来访问该服务。
(3)LoadBalancer:在NodePort的基础上,借助Cloud Provider创建一个外部负载均衡器,并将请求转发到NodePort。
(4)ExternalName:把集群外部的服务引入到集群内部来,在集群内部直接使用。没有任何类型代理被创建,这只有 Kubernetes 1.7或更高版本的kube-dns才支持。
2、Pod是Kubernetes集群运行服务部署的最小单位。
(1)为多进程之间的协作提供一个抽象模型,使用Pod作为基本的调度、复制等管理工作的最小单位,让多个应用程序能够一起有效的调度和伸缩。
(2)Pod与Pod之间共享容器Pause容器IP和共享容器挂载的Volume。
(3)在每个Pod都会被分配一个唯一标识的IP地址。Pod之间是通过TCP/IP协议。
Pod分为两种类型:
(1)自主式Pod:Pod一旦退出就不会在创建。
(2)控制器管理的Pod:Pod由控制器进行管理,会始终维持副本的数目。
或者:可在分为
(1)普通的Pod:一旦被创建,就会被放入etcd存储中,会随着Master 调度到某个具体的Node上并且绑定。
(2)静态Pod(Static Pod):静态Pod并不会存放在etcd中,只会存在某个具体的Node文件中,并且只能在该Node中运行。
下面我们使用YAML创建Pod案例:
apiVersion: v1
kind: Pod #定义类型
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: mypod
image: docker.io/nginx #定义部署镜像
ports:
- containerPort: 80 #定义放行端口
使用kubectl 创建Pod
$ kubectl run NAME --image=image [--env="key=value"] [--port=port] [--replicas=replicas] [--dry-run=bool] [--overrides=inline-json] [--command] -- [COMMAND] [args...]
$ kubectl run nginx --image=docker.io/nginx --port=80
3、Label与标签选择器
Label 是识别 Kubernetes 对象的标签,以 key/value 的方式附加到对象上(key 最长不 能超过 63 字节,value 可以为空,也可以是不超过 253 字节的字符串)。
Label 不提供唯一性,并且实际上经常是很多对象(如 Pods)都使用相同的 label 来标 志具体的应用。
一些常用的Label示例如下:
(1)版本标签:release:stable和release:canary。
(2)环境标签:environment:dev、environment:qa和environment:production。
(3)架构标签:tier:frontend、tier:backend和tier:middleware。
(4)分区标签:partition:customerA和partition:coustomerB。
(5)质量管控标签:track:daily和track:weekly。
Label 定义好后其他对象可以使用 Label Selector 来选择一组相同 label 的对象(比如 ReplicaSet 和 Service 用 label 来选择一组 Pod)。
等式,如 app=nginx 和 env!=production
集合,如 env in (production, qa)
多个 label(它们之间是 AND 关系),如 app=nginx,env=test
4、应用配置:
(1)Deployment:无状态服务建模。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3 #定义副本数目
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
•创建名为 nginx-deployment(由 .metadata.name 字段标明)的 Deployment。
•该 Deployment 创建三个(由 replicas 字段标明)Pod 副本。
•selector 字段定义 Deployment 如何查找要管理的 Pods。在这里,你选择在 Pod 模板中定义的标签(app: nginx)。不过,更复杂的选择规则是也可能的,只要 Pod 模板本身满足所给规则即可。
重要属性:
•replicas:Pod的副本数目。
•selector:目标Pod的标签选择器。
•template:用于自动创建新Pod副本的模板。
(2)StatefulSet:有状态集群的建模。
•稳定的、唯一的网络标识符。
•稳定的、持久的存储。
•有序的、优雅的部署和缩放。
•有序的、自动的滚动更新。
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
selector:
matchLabels:
app: nginx # 必须匹配 .spec.template.metadata.labels
serviceName: "nginx"
replicas: 3 # 默认值为 1
template:
metadata:
labels:
app: nginx # 必须匹配 .spec.selector.matchLabels
spec:
terminationGracePeriodSeconds: 10
containers:
- name: nginx
image: k8s.gcr.io/nginx-slim:0.8
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "my-storage-class"
resources:
requests:
storage: 1Gi
(3)Job:批处理应用的建模。
Job负责批量处理短暂的一次性任务 (short lived one-off tasks),即仅执行一次的任务,它保证批处理任务的一个或多个Pod成功结束。
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
metadata:
name: pi
spec:
containers:
- name: pi
image: perl
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
parallelism: 1
completions: 5
属性:
•completions:定义需要完成次数。
•parallelism:并行运行次数。
三、存储类
(1)Volume:Volume是Pod访问共享目录,和docker的卷类似。Volume和Pod的生命周期相同,但是与容器没有任何关联,Pod终止或者重启,数据是不会丢失的。
(2)emptyDir:临时目录,也是空的目录,有点像系统中的tmp临时文件,系统重启就会丢失。
(3)hostPath:在Pod主机上挂载主目录或文件,比如我们像Pod挂载一个文件,就可以进入Pod中直接使用了。
(4)PV和PVC:PV持久化卷,可以被理解为一个网络存储的一块卷,PVC而是用户存储需求,比如用户有要求CPU为3和内存大小为4G,这个时候就需要调用到PVC了,不然系统会随机调用Node节点。PVC和PV是一一对应的。
四、安全类
安全永远是一个很重要部件。在Kubernetes中就是一个关键领域,不可能每个用户都可以随便操作节点中的资源对象,所以必须提供访问认证。
基于角色(Role)的访问控制(RBAC)是一种基于组织中用户的角色来调节控制对 计算机或网络资源的访问的方法。
RBAC API 声明了四种 Kubernetes 对象:Role、ClusterRole、RoleBinding 和 ClusterRoleBinding。
RBAC 的 Role 或 ClusterRole 中包含一组代表相关权限的规则。这些权限是纯粹累加的(不存在拒绝某操作的规则)。
Role 总是用来在某个名字空间 内设置访问权限;在你创建 Role 时,你必须指定该 Role 所属的名字空间。
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""] # "" 标明 core API 组
resources: ["pods"]
verbs: ["get", "watch", "list"] #绑定Pod资源get、watch和list权限
ClusterRole 则是一个集群作用域的资源。这两种资源的名字不同(Role 和 ClusterRole)是因为 Kubernetes 对象要么是名字空间作用域的,要么是集群作用域的, 不可两者兼具。
ClusterRole 有若干用法。你可以用它来:
(1)定义对某名字空间域对象的访问权限,并将在各个名字空间内完成授权;
(2)为名字空间作用域的对象设置访问权限,并跨所有名字空间执行授权;
(3)为集群作用域的资源定义访问权限。,你必须指定该 Role 所属的名字空间。
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
# "namespace" 被忽略,因为 ClusterRoles 不受名字空间限制
name: secret-reader
rules:
- apiGroups: [""]
# 在 HTTP 层面,用来访问 Secret 对象的资源的名称为 "secrets"
resources: ["secrets"]
verbs: ["get", "watch", "list"]
用户授权使用RoleBinding与ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: pod-rolebinding
namespace: default
subjects:
- kind: User
name: Caden #角色授权读取default命名空间
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
在RoleBinding中使用subjects(目标主体)来表示要授权的对象,这是因为授权三类目标账号:Group(用户组)、User(某个具有用户)和Service Account(Pod应用所使用的账号)。