29.3 kubernetes相关概念
29.4 kubectl命令用法
29.3 kubernetes相关概念
kubernetes内部组件工作原理 http://dockone.io/article/5108
Master
Master是整个集群的控制中心,kubernetes的所有控制指令都是发给master,它负责具体的执行过程。一般我们会把master独 立于一台物理机或者一台虚拟机,它的重要性不言而喻。
- master上有这些关键的进程:
Kubernetes API Server
(kube-apiserver),提供了HTTP Rest接口关键服务进程,是所有资源增、删、改、查等操作的唯一入口,也是集群控制的入口
进程。Kubernetes Controller Manager
(kube-controlker-manager),是所有资源对象的自动化控制中心,可以理解为资源对象的大总管
。Kubernetes Scheduler
(kube-scheduler),负责资源调度(pod调度)的进程,相当于公交公司的“调度室
”。etcd Server
,kubernetes里所有资源对象的数据
都是存储在etcd中的。
Node
除了Master,Kubernetes集群中其他机器被称为Node,早期版本叫做Minion。Node可以是物理机也可以是虚拟机,每个 Node上会被分配一些工作负载(即,docker容器),当Node宕机后,其上面跑的应用会被转移到其他Node上。
- Node上有这些关键进程:
kubelet
:负责Pod对应容器的创建、启停等任务,同时与Master节点密切协作,实现集群管理的基本功能。kube-proxy
:实现Kubernetes Service的通信与负载均衡机制的重要组件。Docker Engine
(docker):Docker引擎,负责本机容器的创建和管理。
命令 | 含义 |
---|---|
kubectl get nodes | 查看集群中有多少个node |
kubectl describe node | 查看Node的详细信息 |
Pod
命令 | 含义 |
---|---|
kubectl get pods | 查看pod命令 |
docker ps | 查看容器命令 |
可以看到容器和pod是有对应关系的,在我们做过的实验中,每个pod对应两个容器,一个是Pause容器
,一个是rc里面定义的容器(实际上,每个pod里可以有多个应用容器)。这个Pause容器叫做“根容器”,只有当Pause容器“死亡”才会认为该 pod“死亡”。Pause容器的IP以及其挂载的Volume资源会共享给该pod下的其他容器。
pod定义示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
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_SERVICE_HOST value: 'mysql' - name: MYSQL_SERVICE_PORT value: '3306' |
每个pod都可以对其能使用的服务器上的硬件资源进行限制(CPU、内存)。CPU限定的最小单位是1/1000个cpu,用m表示, 如100m,就是0.1个cpu。内存限定的最小单位是字节,可以用Mi(兆) 表示,如128Mi就是128M。 在kubernetes里,一个计算资源进行配额限定需要设定两个参数:
1)requests
:该资源的最小申请量
2)Limits
:该资源允许的最大使用量。
资源限定示例:
1 2 3 4 5 6 7 8 9 10 11 |
spec: containers: - name: db image: mysql resources: requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m" |
Label
Label是一个键值对,其中键和值都由用户自定义,Label可以附加在各种资源对象上,如Node、Pod、Service、RC等。一个资源对象可以定义多个Label,同一个Label也可以被添加到任意数量的资源对象上。Label可以在定义对象时定义,也可以在对象创建完后动态添加或删除。
Label示例:"release":"stable", "environment":"dev", "tier":"backend"
等等。
RC
RC是kubernetes中核心概念之一,简单说它定义了一个期望的场景,即声明某种pod的副本数量在任意时刻都符合某个预期值,RC定义了如下几个部分:
1)pod期待的副本数
2)用于筛选目标pod的Label Selector
3)创建pod副本的模板(template)
RC一旦被提交到kubernetes集群后,Master节点上的Controller Manager组件就会接收到该通知,它会定期巡检集群中存活的pod,并确保pod数量符合RC的定义值。可以说通过RC,kubernetes实现了用户应用集群的高可用性,并且大大减少了管理员在传统IT环境中不得不做的诸多手工运维工作,比如编写主机监控脚本、应用监控脚本、故障恢复处理脚本等
RC工作流程(假如,集群中有3个Node):
1)RC定义2个pod副本
2)假设系统会在2个Node上(Node1和Node2)创建pod
3)如果Node2上的pod(pod2)意外终止,这很有可能是因为Node2宕机
4)则会创建一个新的pod,假设会在Node3上创建pod3,当然也有可能在Node1上创建pod3
命令 | 含义 |
---|---|
kubectl scale rc –replicas=n | RC中动态修改pod副本数量: |
kubectl delete rc | 删除RC(RC对应的pod也会被删除掉) |
1 2 3 4 5 6 |
[root@kun05 ~]# kubectl scale rc mysql --replicas=2 ##动态修改rc中pod的数量 [root@kun05 ~]# kubectl get pod NAME READY STATUS RESTARTS AGE mysql-cwz09 1/1 Running 0 25s mysql-x4rwx 1/1 Running 1 15h |
利用动态修改pod的副本数,可以实现应用的动态升级(滚动升级):
1)以新版本的镜像定义新的RC,但pod要和旧版本保持一致(由Label决定)
2)新版本每增加1个pod,旧版本就减少一个pod,始终保持固定的值
3)最终旧版本pod数为0,全部为新版本
Deployment
在1.2版本引入的概念,目的是为了解决pod编排问题,在内部使用了Replica Set,它和RC比较,相似度为90%以上,可以认为是RC的升级版
。 跟RC比较,最大的一个特点是可以知道pod部署的进度。
Deployment示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: frontend spec: replicas: 1 selector: matchLabels: tier: frontend matchExpressions: - {key: tier, operator: In, values: [frontend]} template: metadata: labels: app: app-demo tier: frontend spec: containers: - name: tomcat-demo image: tomcat imagePullPolicy: IfNotPresent ports: - containerPort: 8080 |
命令 | 含义 |
---|---|
kubectl create -f tomcat-deployment.yaml | 发布deployment |
kubectl get deployment | 查看deployment信息 |
HPA(Horizontail Pod Autoscaler)
在1.1版本,kubernetes官方发布了HPA,实现pod的动态扩容、缩容,它属于一种kubernetes的资源对象。它通过追踪分析RC控制的所有目标pod的负载变化情况,来决定是否需要针对性地调整目标Pod的副本数,这是HPA的实现原理。
pod负载度量指标:
1)CpuUtilizationPercentage
目标pod所有副本自身的cpu利用率平用均值。一个pod自身的cpu利用率=该pod当前cpu的使用量/pod Request值。如果某一个时刻,CPUUtilizationPercentage的值超过了80%,则判定当前的pod已经不够支撑业务,需要增加pod。
2)应用程序自定义的度量指标,比如服务每秒内的请求数
(TPS或QPS
)
HPA示例:
1 2 3 4 5 6 7 8 9 10 11 12 |
apiVerion: autosacling/v1 kind: HorizontalPodAutoscaler metadata: name: php-apache namespace: default spec: maxReplicas: 10 minReplicas: 1 scaleTargetRef: kind: Deployment name: php-apache targetCPUUtilizationPercentage: 90 |
说明:HPA控制的目标对象是一个名叫php-apache的Deployment里的pod副本,当cpu平均值超过90%时就会扩容,pod副本数控制范围是1-10.
除了以上的xml文件定义HPA外,也可以用命令行的方式来定义:
1 |
kubectl autoscale deployment php-apache --cpu-percent=90 --min=1 --max=10 |
Service
Service是kubernetes中最核心的资源对象之一,Service可以理解成是微服务架构中的一个“微服务”,pod、RC、Deployment都是为Service提供嫁衣的。
简单讲一个service本质上是一组pod组成的一个集群,前面我们说过service和pod之间是通过Label来串起来的,相同Service的pod的Label一样。
同一个service下的所有pod是通过kube-proxy实现负载均衡,而每个service都会分配一个全局唯一的虚拟ip,也叫做cluster ip。
在该service整个生命周期内,cluster ip是不会改变的,而在kubernetes中还有一个dns服务,它把service的name和cluster ip映射起来。
service示例:(文件名tomcat-service.yaml)
1 2 3 4 5 6 7 8 9 |
apiVersion: v1 kind: Service metadata: name: tomcat-service spec: ports: - port: 8080 selector: tier: frontend |
命令 | 含义 |
---|---|
kubectl create -f tomcat-service.yaml | 发布service |
kubectl get endpoints | 查看pod的IP地址以及端口 |
kubectl get svc -o yaml | 查看service分配的cluster ip |
多端口的service
1 2 3 4 5 6 7 8 9 10 11 12 |
apiVersion: v1 kind: Service metadata: name: tomcat-service spec: ports: - port: 8080 name: service-port - port: 8005 name: shutdown-port selector: tier: frontend |
对于cluster ip有如下限制:
1)Cluster ip无法被ping通,因为没有实体网络来响应
2)Cluster ip和Service port组成了一个具体的通信端口,单独的Cluster ip不具备TCP/IP通信基础,它们属于一个封闭的空间。
3)在kubernetes集群中,Node ip、pod ip、cluster ip之间的通信,采用的是kubernetes自己设计的一套编程方式的特殊路由规则。
要想直接和service通信,需要一个Nodeport,在service的yaml文件中定义:
1 2 3 4 5 6 7 8 9 10 |
apiVersion: v1 kind: Service metadata: name: tomcat-service spec: ports: - port: 8080 nodeport: 31002 selector: tier: frontend |
它实质上是把cluster ip的port映射到了node ip的nodeport上了
Volume(存储卷)
Volume是pod中能够被多个容器访问的共享目录,kubernetes中的volume和docker中的volume不一样,主要有以下几个方
面:
1)kubernetes的volume定义在pod上,然后被一个pod里的多个容器挂载到具体的目录下
2)kubernetes的volume与pod生命周期相同,但与容器的生命周期没关系,当容器终止或者重启时,volume中的数据并不会丢失
3)kubernetes支持多种类型的volume,如glusterfs,ceph等先进的分布式文件系统
只需要在定义pod的yaml配置文件中指定volume相关配置即可:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
template: metadata: labels: app: app-demo tier: frontend spec: volumes: - name: datavol emptyDir: {} containers: - name: tomcat-demo image: tomcat volumeMounts: - mountPath: /mydata-data name: datavol imagePullPolicy: IfNotPresent |
说明: volume名字是datavol,类型是emptyDir,将volume挂载到容器的/mydata-data目录下
volume的类型:
1)emptyDir
是在pod分配到node时创建的,初始内容为空,不需要关心它将会在宿主机(node)上的哪个目录下,因为这是kubernetes自动分配的一个目录,当pod从node上移除,emptyDir上的数据也会消失。所以,这种类型的volume不适合存储永久数据,适合存放临时文件
。
2)hostPath
hostPath指定宿主机(node)上的目录路径,然后pod里的容器挂载该共享目录。这样有一个问题,如果是多个node,虽然目录一样,但是数据不能做到一致,所以这个类型适合单个node
的情况。
配置示例:
1 2 3 4 |
volumes: - name: "persistent-storage" hostPath: path: "/data" |
3)gcePersistentDisk
使用Google公有云GCE提供的永久磁盘(PD)存储volume数据。毫无疑问,使用gcePersistentDisk的前提是kubernetes的node是基于GCE的。
配置示例:
1 2 3 4 5 |
volumes: - name: test-volume gcePersistentDisk: pdName: my-data-disk fsType: ext4 |
4)awsElasticBlockStore
与GCE类似,该类型使用亚马逊公有云提供的EBS Volume存储数据,使用它的前提是Node必须是aws EC2。
5)NFS
使用NFS作为volume载体。
示例:
1 2 3 4 5 |
volumes: - name: "NFS" NFS: server: ip地址 path: "/" |
6)其他类型
iscsi
flocker
glusterfs
rbd
gitRepo: 从git仓库clone一个git项目,以供pod使用
secret: 用于为pod提供加密的信息
persistent volume(PV)
PV可以理解成kubernetes集群中某个网络存储中对应的一块存储,它与volume类似,但有如下区别:
1)PV只能是网络存储,不属于任何Node,但可以在每个Node上访问到
2)PV并不是定义在pod上,而是独立于pod之外定义
3)PV目前只有几种类型:GCE Persistent Disk、NFS、RBD、iSCSCI、AWS ElasticBlockStore、GlusterFS
如下是NFS类型的PV定义:
1 2 3 4 5 6 7 8 9 10 11 12 |
apiVersion: v1 kind: PersistentVolume metadata: name: pv0003 spec: capacity: storage: 5Gi accessModes: - ReadWriteOnce nfs: path: /somepath server: ip |
其中accessModes
是一个重要的属性,目前有以下类型:ReadWriteOnce
: 读写权限,并且只能被单个Node挂载ReadOnlyMany
: 只读权限,允许被多个Node挂载ReadWriteMany
:读写权限,允许被多个Node挂载
如果某个pod想申请某种条件的PV,首先需要定义一个PersistentVolumeClaim(PVC)
对象:
1 2 3 4 5 6 7 8 9 10 |
kind: persistentVolumeClaim apiVersion: v1 metadata: name: myclaim spec: accessModes: - ReadWriteOnce resources: requests: storage: 8Gi |
然后在pod的vomume定义中引用上面的PVC:
1 2 3 4 |
volumes: - name: mypd persistentVolumeClaim: ClaimName: myclaim |
Namespace(命名空间)
当kubernetes集群中存在多租户的情况下,就需要有一种机制实现每个租户的资源隔离。而namespace的目的就是为了实现资源隔离。
定义namespace:
1 2 3 4 |
apiVersion: v1 kind: Namespace metadata: name: dev |
然后再定义pod,指定namespace
1 2 3 4 5 6 7 8 9 10 11 12 |
apiVersion: v1 kind: Pod metadata: name: busybox namespace: dev spec: containers: - image: busybox command: - sleep - "500" name: busybox |
命令 | 含义 |
---|---|
kubectl get ns | 查看集群所有的namespace |
kubectl create -f dev-namespace.yaml | 发布dev-namespace |
kubectl get pod –namespace= kubectl get pod -n | 查看某个namespace下的pod |
kubectl get pod –all-namespaces | 显示私有pod,包含namespace里面的pod |
29.4 kubectl命令用法
语法:kubectl [command] [TYPE] [NAME] [flags]
1 command
:子命令,用于操作Kubernetes集群资源对象的命令,如create, delete, describe, get, apply等
2 TYPE
:资源对象的类型,如pod, service, rc, deployment, node等,可以单数、复数以及简写(pod, pods, po/service,
services, svc)
3 NAME
:资源对象的名称,不指定则返回所有,如get pod 会返回所有pod, get pod nginx, 只返回nginx这个pod
4 flags
:kubectl子命令的可选参数,例如-n 指定namespace,-s 指定apiserver的URL
资源对象类型列表
可以用这个命令获取到:
1 |
kubectl explain |
名称 | 简写 |
---|---|
componentsstatuses | cs |
daemonsets | ds |
deployment | deploy |
events | ev |
endpoints | ep |
horizontalpodautoscalers | hpa |
ingresses | ing |
jobs | |
limitranges | limits |
nodes | no |
namspaces | ns |
pods | po |
persistentvolumes | pv |
persistentvolumeclaims | pvc |
resourcequotas | quota |
secrets | |
serviceaccounts | sa |
services | svc |
特殊用法:
1 2 3 |
kubectl get pods pod1 pod2 kubectl get pod/pod1 rc/rc1 kubectl create -f pod1.yaml -f rc1.yaml -f service1.yaml |
kubectl子命令
主要包括对资源的创建、删除、查看、修改、配置、运行等kubectl --help
可以查看所有子命令
kubectl参数kubectl options
可以查看支持的参数,例如–namespace指定所在namespace
kubectl输出格式
kubectl命令可以用多种格式对结果进行显示,输出格式通过-o参数指定:
-o支持的格式有
输出格式 | 说明 |
---|---|
custom-columns=<spec> | 根据自定义列名进行输出,逗号分隔 |
custom-columns-file=<filename> | 从文件中获取自定义列名进行输出 |
json | 以JSON格式显示结果 |
jsonpath=<template> | 输出jasonpath表达式定义的字段信息 |
jasonpath-file=<filename> | 输出jsonpath表达式定义的字段信息,来源于文件 |
name | 仅输出资源对象的名称 |
wide | 输出更多信息,比如会输出node名 |
yaml | 以yaml格式输出 |
举例:
1 2 3 4 |
kubectl get pod -o wide kubectl get pod -o yaml kubectl get pod -o custom-columns=NAME:.metadata.name,RESC:.metadata.resourceVersion kubectl get pod --sort-by=.metadata.name //按name排序 |
kubectl命令示例:
1)创建资源对象
根据yaml文件创建service和deployment
1 |
kubectl create -f my-service.yaml -f my-deploy.yaml |
也可以指定一个目录,这样可以一次性根据该目录下所有yaml或json文件定义资源
1 |
kubectl create -f <directory> |
2)查看资源对象
查看所有pod
1 |
kubectl get pods |
查看deployment和service
1 |
kubectl get deploy,svc |
3)描述资源对象
显示node的详细信息
1 |
kubectl describe nodes <node-name> |
显示pod的详细信息
1 |
kubectl describe pods/<pod-name> |
显示deployment管理的pod信息
1 |
kubectl describe pods <deployment-name> |
4)删除资源对象
基于yaml文件删除
1 |
kubectl delete -f pod.yaml |
删除所有包含某个label的pod和service
1 |
kubectl delete po,svc -l name=<lable-name> |
删除所有pod
1 |
kubectl delete po --all |
5)执行容器的命令
在pod中执行某个命令,如date
1 |
kubectl exec <pod-name> date //pod-name如果不加,默认会选择第一个pod |
指定pod的某个容器执行命令
1 |
kubectl exec <pod-name> date |
进入到pod的容器里
1 |
kubectl exec -it <pod-name> bash |
6)查看容器日志
1 |
kubectl logs <pod-name> |
可以动态查看,类似于tail -f
1 |
kubectl logs -f <pod-name> -c <container-name> |