Kubernetes中有两种管理角色,Master和Node.
Master是Kubernetes集群的控制节点,所有对于Kubernetes的命令操作都需要在控制节点执行。Master一般运行如下进程:
kube-apiserver: Kubernetes API Server, 提供了HTTP Rest接口的关键服务进程,是所有资源增,删,改,查的入口,也是集群控制的入口进程,kubectl是直接与 API Server交互的,默认监听 6443端口。
kube-controller-manager: 每个资源一般都对应有一个控制器,而controller manager就是负责管理这些控制器的,它是自动化的循环控制器,是Kubernetes的核心控制守护进程。默认监听10252端口。
kube-scheduler : 负责将pod资源调度到合适的node 上。其本身提供了复杂丰富的调度算法,可以根据node 节点的性能,负载,数据位置等各种情况进行合理的调度。默认监听10251 端口。
etcd: 一个高可用的键值存储系统,Kubernetes使用它来存储各个资源的状态,从而实现了Restful的API。默认监听2379和2380端口(2379提供服务,2380用于集群节点通信)
除了Master节点,集群中的其它节点被称作Node节点,Node节点是业务应用实际的运行的平台,通过Master 调度不同的任务到Node节点上,以docker 的方式运行。当某个Node节点宕机时,其上的工作负载会被Master自动转移到其它Node节点上。
Node节点上运行着如下进程:
kubelet: Kubelet是在每个Node节点上运行agent,是Node节点上面最重要的模块,它负责维护和管理该Node上面的所有容器,但是Kubelet不会管理不是由Kubernetes创建的容器。本质上,它负责使Pod得运行状态与期望的状态一致。Kubelet会定时向Master汇报自己当前的自身信息,如操作系统,Docker版本,CPU,内存,pod运行状态等信息。
kube-proxy:该模块实现了Kubernetes中的服务发现和反向代理功能。反向代理支持TCP和UDP连接转发,默认基于Round Robin算法将客户端流量转发到与service对应的一组后端pod。服务发现方面,kube-proxy使用etcd的watch机制,监控集群中service和endpoint对象数据的动态变化,并且维护一个service到endpoint的映射关系,从而保证了后端pod的IP变化不会对访问者造成影响。
runtime: 这里一般使用docker 容器,Kubernetes也支持其他的容器。
1、通过在Master查看Node状态:
[root@node-1 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
node-1 Ready master 22h v1.10.2
node-2 Ready <none> 22h v1.10.2
node-3 Ready <none> 1h v1.10.2
2、查看Node的详细信息,如下命令会输出节点当前状态的详细信息,包括可用资源总量:
kubectl describe node node-2
Pod是Kubernetes中非常重要的基本单位。Pod是应用运行的载体,整个Kubernetes系统都是围绕着Pod展开的,比如如何部署运行Pod、如何保证Pod的数量、如何访问Pod等。Pod是一个或多个容器的集合。
在每一个Pod中都有一个特殊的Pause容器和一个或多个业务容器,Pause来源于pause-amd64镜像,Pause容器在Pod中具有非常重要的作用:
Kubernetes中所有的资源对象都可以采用YAML或者JSON格式的文件来定义,比如,我们可以定义如下的Pod对象:
apiVersion: v1
kind: Pod
metadata:
name: myweb
labels:
name: myweb
spec:
containers:
- name: myweb
image: kubeguide/tomcat-app:v1
ports:
- containerPort: 8080
env:
- name: MYSQL_SERVER_HOST
value: ‘mysql‘
- name: MYSQL_SERVER_PORT
value: ‘3306‘
2、Pod Volume可以使用分布式文件系统,将Pod Volume定义在Pod上,然后被各个容器挂载到自身的容器。目前Kubernetes支持多种文件存储。
3、我们还可以对pod使用的资源进行配额,一般是对CPU和内存的限制:
apiVersion: v1
kind: Pod
metadata:
name: mysql
labels:
name: mysql
spec:
containers:
- name: db
image: mysql
resources:
requests: # 最小资源申请量
memory: "64Mi" # 64M内存
cpu: "250m" # 0.25个CPU
limits: # 最大配额
memory: "128Mi" # 128M 内存
cpu: "500m" # 0.5个CPU
4、 Pod 常用操作:
kubectl create -f pod_file.yaml # 创建pod
kubectl describe pods POD_NAME # 查看pod详细信息
kubectl get pods # pods 列表
kubectl delete pod POD_NAME # 删除pod
kubectl replace pod_file.yaml # 更新pod
Label 是用户自定义的键值对,主要是用于标记资源对象,如Node,Pod,Service,RC等。一个资源可以定义任意数量的Label,同一个Label也可以被添加到任意数量的资源对象上去,Label 通常在资源对象定义时确定,也可以在对象创建后动态的添加或删除。
可以给资源对象绑定多个不同Label,来实现多维度的资源分组管理功能,一些常见的Label示例:
提示:Deployment,ReplicaSet,DaemonSet和Job等管理对象可以在Selector中使用基于集合的筛选条件定义。
Label Selector (标签选择器) ,主要用于对拥有某些Label的资源对象进行查询和筛选,类似SQL的查询机制。
Label Selector可以通过基于等式和集合的查询方式进行匹配查询,通过多个表达式的组合,从而实现复杂的条件选择,如:
name=mysql,env!=production
name notin (tomcat),env!=production
Replication Controller(RC)是Kubernetes中的另一个核心概念,Kubernetes中通过RC来保证应用能够持续运行,它会确保任何时间Kubernetes中都有指定数量的Pod处于运行状态。在此基础上,RC还提供了一些更高级的特性,比如滚动升级、升级回滚等。
RC在Kubernetes中定义了一个期望的场景,即声明某种pod副本数量在任意时刻符合某个预期的值,其定义的内容如下:
RC运行过程: 当我们定义了一个RC的YAML文件(或者调用kubectl命令)提交到Kubernets集群后,Master 上的Controller Manager组件就得到通知,定期巡检系统中当前存活的目标Pod,并确保目标Pod实例的数量刚好邓毅此RC的期望值。如果有过多的Pod副本在运行,系统就会停掉一些Pod,反之则会自动创建一些Pod。
通过修改RC数量,实现Pod的动态缩放:
kubectl scale rc myweb --replicas=10 # 将pod 扩展到10个
kubectl scale rc myweb --replicas=1 # 将pod 缩到 1个
使用RC可以进行动态平滑升级,保证业务始终在线。其具体实现方式:
kubectl rolling-update my-rcName-v1 -f my-rcName-v2-rc.yaml --update-period=10s
升级开始后,首先依据提供的定义文件创建V2版本的RC,然后每隔10s(--update-period=10s)逐步的增加V2版本的Pod副本数,逐步减少V1版本Pod的副本数。升级完成之后,删除V1版本的RC,保留V2版本的RC,及实现滚动升级。
升级过程中,发生了错误中途退出时,可以选择继续升级。Kubernetes能够智能的判断升级中断之前的状态,然后紧接着继续执行升级。当然,也可以进行回退,命令如下:
kubectl rolling-update my-rcName-v1 -f my-rcName-v2-rc.yaml --update-period=10s --rollback
replica set,可以被认为 是“升级版”的Replication Controller。replica set也是用于保证与label selector匹配的pod数量维持在期望状态。区别在于,replica set引入了对基于子集的selector查询条件,而Replication Controller仅支持基于值相等的selecto条件查询。replica set很少被单独使用,目前它多被Deployment用于进行pod的创建、更新与删除的编排机制。
Deployment主要职责同样是为了保证pod的数量和健康,90%的功能与Replication Controller完全一样,可以看做新一代的Replication Controller。Deployment内部使用了Replica Set来实现。
Deployment 相对于RC一个最大的升级是我们可以随时知道当前Pod "部署"的进度,和详细的运行状态。
具有以下使用场景:
创建Pod: 可以创建一个Deployment对象来生成对应的Replica Set,完成Pod副本的创建。
查看事件状态: 通过检查Deployment的状态来查看部署动作是否完成,如副本数量是否达到了预期的值。
升级:更新Deployment以创建新的Pod,同时还可以清理不再需要的旧版本ReplicaSet。
回滚: 如果当前的Pod不稳定或者有bug,可以回滚到一个早期的稳定版本。
暂停和恢复:可以随时暂停Deployment对象,修改对应的参数配置,之后再恢复Deployment继续发布。
Deployment的定义和Replica Set的定义几乎一样,仅仅是API版本和kind类型不同:
# 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
ports:
- containerPort: 80
# Replica Set的声明
apiVersion: v1
kind: ReplicaSet
metadata:
name: mysql
...
1、这里以上面的nginx为例,创建nginx:
[root@node-1 ~]# kubectl create -f nginx.yaml
deployment.apps "nginx-deployment" created
2、查看Deployment信息:
# 刚执行时,显示的AVAILABLE数量时0
[root@node-1 ~]# kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx-deployment 3 3 3 0 22s
# 1分钟后显示已经有3个可用nginx-deployment
[root@node-1 ~]# kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx-deployment 3 3 3 3 1m
# 查看pods
[root@node-1 ~]# kubectl get pods | grep nginx
nginx-deployment-666865b5dd-cfmfp 1/1 Running 0 11m
nginx-deployment-666865b5dd-nhxtv 1/1 Running 0 11m
nginx-deployment-666865b5dd-qj7sf 1/1 Running 0 11m
# 查看 rs
[root@node-1 ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-666865b5dd 3 3 3 25m
# 查看deployments的详细部署信息
[root@node-1 ~]# kubectl describe deployments
...
对于上述kubectl get deployments的输出,其含义:
使用kubectl describe deployments命令可以获取指定Deployment的详细状态
例如,我们要对当前的nginx-deployment进行升级或者回滚,可以使用如下两种方式。
1、若要对docker镜像进行更新,直接 set 镜像:
[root@node-1 ~]# kubectl set image deployment/nginx-deployment nginx=nginx:1.12.2
2、查看状态,可以发现在保证pod 可用的状态下,会平滑的替换旧的deployment对象,并且会记录此过程:
[root@node-1 ~]# kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx-deployment 3 4 1 3 3h
[root@node-1 ~]# kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx-deployment 3 4 2 3 3h
[root@node-1 ~]# kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx-deployment 3 3 3 3 4h
[root@node-1 ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-666865b5dd 0 0 0 4h
nginx-deployment-69647c4bc6 3 3 3 3m
[root@node-1 ~]# kubectl describe deployments # 会显示详细events事件
1、执行 edit命令修改Deployment配置,类似KVM的virsh edit 命令,修改后立即生效(如果没有修改,将不会发生任何变化):
[root@node-1 ~]# kubectl edit deployments/nginx-deployment
2、查看deployment状态:
[root@node-1 ~]# kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx-deployment 3 4 1 3 5h
[root@node-1 ~]# kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx-deployment 3 4 3 3 5h
[root@node-1 ~]# kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx-deployment 3 3 3 3 5h
3、一般常见的修改是修改镜像版本和参数。
1、执行回滚命令,到上一个版本:
[root@node-1 ~]# kubectl rollout undo deployment/nginx-deployment
2、使用如下命令,可以查看保存的deployment历史:
[root@node-1 ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-666865b5dd 0 0 0 5h
nginx-deployment-68dfb7c95b 3 3 3 27m
nginx-deployment-69647c4bc6 0 0 0 1h
Service是Kubernetes中的核心对象之一。Kubernetes中的Pod,RC,等资源对象最终都是为Service服务。
Service定义了一个服务访问的入口地址,前端应用Pod通过这个地址访问后端的Pod集群实例,Service通过Label Selector来实现与后端Pod集群的通讯。其中,RC的作用是保障集群中始终有可用的Pod集群,从而确保了服务质量。
Service的服务原理图:
在上图中,我们需要理解以下几点:
Service的Cluster IP和Endpoint属于Kubernetes集群内部的地址,无法在集群外部使用,一般会使用Flannel、Weave、Romana等第三方网络服务来实现Pod之间的通讯。这里涉及网络的部分我们会在后续的博文中单独讨论。
由于Cluster IP是一个内部地址,外部的node 节点无法直接访问到,当我们的外部用户需要访问这些服务时,需要在定义Service时添加NodePort的扩展。下面的文件定义了一个nginx服务添加外部NodePort的示例。
编辑service文件:
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
type: NodePort
ports:
- port: 80
nodePort: 30008 # 对外的用户访问端口,默认范围是30000-32767
selector:
app: nginx
当我们创建这个service后,所有的节点上都会有30008的端口映射,访问任意节点都会转发到对应的Pod集群中。
在Kubernetes中,Volume是能被Pod中多个容器访问的共享目录。由于Pod中的容器随时可能会被销毁或重建,对于一些需要数据共享或要持久化保存的数据,我们需要使用单独的存储空间,挂载到对应的Pod上。当容器终止时,Volume中的数据不会丢失。
Volume的定义格式:
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {} # 指定Volume类型
Kubernetes支持多种类型的Volume,下面会对一些常见的Volume做出说明。
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /test-pd
name: test-volume
volumes:
- name: test-volume
hostPath:
# directory location on host
path: /data
# this field is optional
type: Directory
volumes:
- name: nfs
nfs:
server: NFS-SERVER-IP # NFS 服务器地址
path: "/"
理解并管理五花八门的存储是一件让人头疼的事情,Kubernetes为了解决这些问题,对所有的网络存储进行了抽象,让我们在管理这些存储时不必考虑后端的实现细节,对于不同的网络存储统一使用一套相同的管理手段。
PersistentVolume为用户和管理员提供了一个API,它抽象了如何提供存储以及如何使用它的细节。 为此,引入两个新的API资源:PersistentVolume和PersistentVolumeClaim。
PersistentVolume(PV): 是管理员设置的单独的网络存储集群,它不属于任何节点,但是可以被每个节点访问。 PV是Volumes之类的卷插件,具有独立于的生命周期。 此API对象用于捕获存储实现的细节,如NFS,iSCSI,GlusterFS,CephFS或特定于云提供程序的存储系统。
PersistentVolumeClaim(PVC):是用户对存储的请求的定义。 它与pod相似。pods消耗节点资源,PVC消耗PV资源, Pods可以请求特定级别的资源(CPU和内存)。Claim可以配置特定的存储资源大小和访问模式(例如,多种不同的读写权限),并根据用户定义的需求去使用合适的Persistent Volume。
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv1
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
nfs:
path: /somepath
server: 10.2.2.2
accessModes有三种权限:
如果某个Pod想申请某种类型的PV,可以做如下定义:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: myclaim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
stroage: 8Gi
定义之后再Pod的Volume中引用上述PVC:
volumes:
- name: mypd
persistentVolumeClaim:
claimName: myclaim
PV是有状态的对象,有如下几种状态:
Namespace(命名空间)是Kubernetes中非常重要的概念,Namespace在很多情况下实现多租户的资源隔离,将集群中的不同资源对象分配到不同的Namespace中,形成逻辑上分组的不同项目,便于不同分组在使用集群资源的同时还能被分别管理。
Kubernetes在启动之后,默认会创建一个default的Namespace:
[root@node-1 ~]# kubectl get namespaces
NAME STATUS AGE
default Active 3d
当我们创建对象时,不指定namespace就会使用默认的default:
[root@node-1 ~]# kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
default mysql-fw2pj 1/1 Running 2 1d
default myweb-4jk8j 1/1 Running 2 1d
default myweb-68zfl 1/1 Running 2 1d
default myweb-bv8pt 1/1 Running 2 1d
default nginx-deployment-68dfb7c95b-6zcj4 1/1 Running 2 1d
default nginx-deployment-68dfb7c95b-g89nd 1/1 Running 3 1d
default nginx-deployment-68dfb7c95b-zvtkf 1/1 Running 2 1d
kube-system etcd-node-1 1/1 Running 7 3d
...
使用yaml文件定义一个名为deployment的Namespace:
apiVersion: v1
kind: Namespace
metadata:
name: deployment
当创建对象时,就可以指定这个资源对象属于哪个Namespace:
apiVersion: v1
kind: Pod
metadata:
name: myweb
namespace: development
当我们指定非默认的namespace之后,使用如下命令就只能查看默认区域的namespaces:
# kubectl get pods
查看所有namespace区域的对象要使用--all-namespaces参数:
# kubectl get pods --all-namespaces
#也可以指定namespaces:
# kubectl get pods --namespace=kube-system
HPA与之前介绍的RC,deployment一样,也是属于Kubernetes的一种资源对象。HPA通过追踪分析RC控制的所有目标Pod的负载变化情况,来确定是否需要针对性的调整目标Pod的副本数。HPA有以下两种方式来度量Pod的负载情况:
CPU的利用率百分比通常是度量的Pod CPU 1min内的平均值,使用Heapster扩展组件来得到这个值,这里定义一个简单的例子:
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: myweb
namespace: default
spec:
maxReplicas: 10
minReplicas: 2
scaleTargetRef:
kind: Deployment
name: myweb
targetCPUUtilizationPercentage: 90
当Pod 副本的CPU利用率超过90%时会触发自动扩容行为,且Pod数量最多不能超过10,最少不能低于2.
除此之外,也可以使用命令操作:
kubectl autoscale deployment myweb --cpu-percent=90 --min=1 --max=10
在Kubernetes系统中,Pod管理的对象如 RC,Deployment,DaemonSet 和Job 都是面向无状态的服务。对于无状态的服务我们可以任意销毁并在任意节点重建,但是在实际的应用中,很多服务是有状态的,特别是对于复杂的中间件集群,如Mysql集群,MongoDB集群,Zookeeper集群,etcd集群等,这些服务都有固定的网络标识,并有持久化的数据存储,这就需要使用StatefulSet对象。
StatefulSet具有以下特性:
参考资料:
https://kubernetes.io/docs/concepts/
https://www.cnblogs.com/zhenyuyaodidiao/p/6500720.html
《Kubernets权威指南》
原文地址:http://blog.51cto.com/tryingstuff/2119034