内容简介:Kubernetes 中的大部分概念如 Node、 Pod、 ReplicationController、 Service 等都可以看作一种“资源对象”, 几乎所有的资源对象都可以通过 Kubernetes 提供的 kubectl 工具(或者 API 编程调用) 执行 增、 删、 改、 查 等操作并将其保存 在 etcd 中持久化存储。几乎所有的控制命令都是发给 Master 的,一般来说 Master 会单独部署在一个虚拟机或 X86服务器上Master 的进程包括:
Kubernetes 中的大部分概念如 Node、 Pod、 ReplicationController、 Service 等都可以看作一种“资源对象”, 几乎所有的资源对象都可以通过 Kubernetes 提供的 kubectl 工具(或者 API 编程调用) 执行 增、 删、 改、 查 等操作并将其保存 在 etcd 中持久化存储。
Master
几乎所有的控制命令都是发给 Master 的,一般来说 Master 会单独部署在一个虚拟机或 X86服务器上
Master 的进程包括:
- Kubernetes API Server( kube- apiserver), 提供了 HTTP Rest 接口的关键服务进程, 是 Kubernetes 里所有资源的增、删、改、查等操作的唯一 入口,也是集群控制 的入口进程。
- Kubernetes Controller Manager( kube- controller- manager), Kubernetes 里所有资源对象的自动化控制中心, 可以理解为资源对象的“大总管”。
- Kubernetes Scheduler( kube- scheduler), 负责资源调度(Pod 调度)的程, 相当于公交公司的“ 调度室”。
其实 Master 节点上往往还启动了一个 etcd Server 进程, 因为 Kubernetes 里 的 所有 资源 对象 的 数据 全部 是 保存 在 etcd 中的。
Node
除了 Master,Kubernetes 集群中的其他机器被称为 Node 节点.
每个 Node 节点上都运行着以下一组关键进程。
- kubelet: 负责Pod 的创建 删除 启动 停止, 同时与 Master 节点密切协作, 实现集群管理的基本功能。
- kube- proxy: 实现 Kubernetes Service 的通信与负载均衡机制的重要组件。
- Docker Engine( dockerDocker 引擎, 负责本机的容器创建和管理工作。
查看节点
[root@centos ~]# kubectl get node NAME STATUS AGE 127.0.0.1 Ready 2d
查看节点详细信息,包括磁盘状态
[root@centos ~]# kubectl describe node 127.0.0.1 Name: 127.0.0.1 # 节点名称 Role: Labels: beta.kubernetes.io/arch=amd64 # 节点标签 beta.kubernetes.io/os=linux kubernetes.io/hostname=127.0.0.1 Taints: <none> CreationTimestamp: Fri, 02 Mar 2018 21:59:52 +0800 # 创建时间 Phase: Conditions: Type Status LastHeartbeatTime LastTransitionTime Reason Message ---- ------ ----------------- ------------------ ------ ------- OutOfDisk False Mon, 05 Mar 2018 10:24:15 +0800 Fri, 02 Mar 2018 21:59:52 +0800 KubeletHasSufficientDisk kubelet has sufficient disk space available # 磁盘信息 True 表示磁盘满了. MemoryPressure False Mon, 05 Mar 2018 10:24:15 +0800 Fri, 02 Mar 2018 21:59:52 +0800 KubeletHasSufficientMemory kubelet has sufficient memory available DiskPressure False Mon, 05 Mar 2018 10:24:15 +0800 Fri, 02 Mar 2018 21:59:52 +0800 KubeletHasNoDiskPressure kubelet has no disk pressure Ready True Mon, 05 Mar 2018 10:24:15 +0800 Sat, 03 Mar 2018 10:50:27 +0800 KubeletReady kubelet is posting ready status Addresses: 127.0.0.1,127.0.0.1,127.0.0.1 Capacity: alpha.kubernetes.io/nvidia-gpu: 0 cpu: 4 memory: 8002252Ki pods: 110 Allocatable: alpha.kubernetes.io/nvidia-gpu: 0 cpu: 4 memory: 8002252Ki pods: 110 System Info: Machine ID: 3ce150b846d1364ca00934cb4b7425e7 System UUID: 6648964A-8A37-49F8-AE2E-CD51D601E0A4 Boot ID: 6c79106a-2825-43e5-a49a-ce1837fed475 Kernel Version: 3.10.0-693.el7.x86_64 OS Image: CentOS Linux 7 (Core) Operating System: linux Architecture: amd64 Container Runtime Version: docker://1.12.6 Kubelet Version: v1.5.2 Kube-Proxy Version: v1.5.2 ExternalID: 127.0.0.1 Non-terminated Pods: (6 in total) Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits --------- ---- ------------ ---------- --------------- ------------- default mysql-j6vpx 0 (0%) 0 (0%) 0 (0%) 0 (0%) default myweb-cwhhl 0 (0%) 0 (0%) 0 (0%) 0 (0%) default myweb-ljwtl 0 (0%) 0 (0%) 0 (0%) 0 (0%) default myweb-n0vrj 0 (0%) 0 (0%) 0 (0%) 0 (0%) default myweb-rnjq9 0 (0%) 0 (0%) 0 (0%) 0 (0%) default myweb-sgfhs 0 (0%) 0 (0%) 0 (0%) 0 (0%) Allocated resources: (Total limits may be over 100 percent, i.e., overcommitted. CPU Requests CPU Limits Memory Requests Memory Limits ------------ ---------- --------------- ------------- 0 (0%) 0 (0%) 0 (0%) 0 (0%) No events.
Pod
Pod 是 kubernetes 中 最基本的单位,每个 Pod 都有一个根容器叫 Pause
为什么需要根容器?
- 一组容器作为一个 Pod,无法对整体进行简单的判断并作出行动,比如一个容器死了是整体都死了吗?因此需要一个无关的根容器来代表整个容器的状态.
- Pod 的多个业务容器共享 Pause 的 IP, 并共享容器挂载的卷,既解决了通信问题又解决了共享问题
kubernetes 中,每个Pod都分配了一个唯一的 IP, 称之为 Pod-IP, 不同 Pod 和其他 pod 是可以通信的
在 Kubernetes 里, 一个计算资源进行配额限定需要设定以下两个参数。
- Requests: 该资源的最小申请量,系统必须满足要求。
- Limits: 该资源最大允许使用的量, 不能被突破, 当容器试图使用超过这个量的资源时, 可能会被 Kubernetes Kill 并重启。
通常来说我们会把 Requests 的值设置为一个比较小的数值,符合容器平时的工作负载情况下的资源需求,而 Limit 设置为峰值负载情况下资源占用的最大量,比如下面这段,表明 MYSQL 容器申请至少0.25个 CPU 一级64MiB 内存,在运行过程中容器所使用的资源配额为0.5个 CPU 以及128MiB 内存:
spec: containers: - name: db image: mysql resources: requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m"
Label
一个 Label 是一个 key=value 的键值对,由用户自主设定, Label 可以附加到各种资源对象上,例如 Node、Pod、Service、RC 等,一个资源对象可以定义任意数量的 Label,同一个 Label 也可以被添加到任意数量的资源对象上去,Label 通常在资源对象定义时确定,也可以在对象创建后动态添加或删除。
Label 定义后,可以通过 Label Selector 查询和筛选拥有某些 Label 的资源对象。查询类似 SQL 的 where 查询条件:
- name = redis-slave 匹配name等于 redis-slave 的资源对象。
- env != production 匹配不具有标签 env=production 的资源对象, 比如 env=test 就满足此条件。
- name in (redis-slave,redis-master) 匹配所有包含 redis-slave 和 redis-master 的资源对象。
- name notin (php-frontend),匹配所有不具有标签 name=php-frontend 的资源对象
多个表达式可以组合实现,需要用”,” 分割,几个条件之间是 “AND” 的关系
name= redis- slave, env!= production name notin (php- frontend), env!= production
Label 选择器的使用场景:
- kube-controller 进程通过资源对象 RC 定义标签来筛选要监控的副本数量,实现自动控制流程。
- kube-proxy 进程通过 service 的标签选择器来选择对应的 Pod,自动建立每个 service 到对应 Pod的请求转发路由表,从而实现 service 的智能负载均衡机制。
- 通过对某些 Node 定义特定标签,并且在 Pod 定义文件中使用 NodeSelector 这种标签调度策略,kube-scheduler 进程可实现 Pod“定向调度”的特性。
多 label
RC
RC 定义了一个期望的场景,即声明某种 Pod 的副本数在任何时候都符合预期,其包括:
- 副本数
- 用于筛选的 Pod 和 标签选择器
- 当 Pod 副本数小于预期数量时,用于创建新 Pod 的模板
RC 提交到集群–Master Controller Manager 组件收到通知,定期巡检当前存活的目标 Pod,并确保目标 Pod 实力数量刚好等于此 RC 的预期值,如果多于 Pod 副本,就会停掉一些,否则会创建一些 Pod。
动态缩放rc
[root@centos ~]# kubectl get rc NAME DESIRED CURRENT READY AGE mysql 1 1 1 2d myweb 5 5 5 1d [root@centos ~]# kubectl scale rc mysql --replicas=3 replicationcontroller "mysql" scaled [root@centos ~]# kubectl get rc NAME DESIRED CURRENT READY AGE mysql 3 3 1 2d myweb 5 5 5 1d [root@centos ~]#
删除 RC 并不会影响通过该 RC 已经创建好的 Pod,为了删除所有 Pod,可以设置 replicas=0 然后更新该 RC,另外可以使用 stop 或 delete 删除 RC 和 RC 控制的全部 Pod。
Deployment
从 k8s 1.2引入的新概念, 与RC 相似度90%,目的是为了更好的解决 Pod 的编排问题。Deployment 在内部使用了 Replica Set 来实现目的。
Deployment 相对于 RC 的一个最大的升级就是随时知道当前 Pod “部署”的进度
Deployment 的场景:
- 创建一个 DP 对象来生成对应的 Replica Set 并完成 Pod 副本的创建过程。
- 检查 DP 的状态来看部署动作是否完成。
- 更新 DP 以创建新的 Pod(比如镜像升级)。
- 如果当前 DP 不稳定,回滚到一个早先的 DP 版本。
- 挂起或恢复一个 DP
例子,tomcat-deployment.yaml
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
然后在集群中创建 deployment
[root@centos ~]# kubectl create -f tomcat-dp.yaml deployment "frontend" created
然后查看
[root@centos ~]# kubectl get deployments NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE frontend 1 1 1 1 2m
其中
- DESIRED 为 Pod 副本数量的期望值,即定义的 Replica。
- CURRENT 为当前的 Replica 值,它会不断变化直到达到 DESIRED 值,表明整个部署过程完成。
- UP-TO-DATA 最新版本的 Pod 的副本数量,在滚动升级过程中,有多少个 Pod 副本已经升级成功了。
- AVAILABLE 当前集群中可用的 Pod 副本数量。
查看对应的 Replica Set
[root@centos ~]# kubectl get rs NAME DESIRED CURRENT READY AGE frontend-141477217 1 1 1 11m
查看 pods
[root@centos ~]# kubectl get pods NAME READY STATUS RESTARTS AGE frontend-141477217-jcckp 1/1 Running 0 12m
HPA
HPA = Horizontal Pod Autoscaler 意思是横向自动扩容。
通过手工执行 kubectl scale 效率低,不符合自动化、智能化的定位。HPA 通过追踪分析 RC 控制的所有目标 Pod 的负载变化情况,来确定是否需要针对性的调整目标 Pod 的副本数,这是 HPA 的实现原理。
HPA 的Pod 负载度量指标:
- CPUutilizationPercentage,目标 Pod 所有副本自身 CPU 利用率的平均值。
- 引用程序自定义的度量指标,比如服务在每秒内的请求数(TPS 或 QPS)
例子
apiVersion: autoscaling/v1 kind: HorizontalPodAutoscaler metadata: name:php-apache namespace: default spec: maxReplicas: 10 minReplicas: 1 scaleTargetRef: kind: Deployment name: php-apache targetCPUUtilizationPercentage: 90
命令方式实现
kubectl autoscale deployment php- apache --cpu- percent= 90 --min= 1 --max= 10
Service
之前的 Pod RC 都是为服务做“嫁衣”的
k8s 定义了一个服务的访问入口地址,前端通过这个入口访问其背后的一组由 Pod 副本组成的集群,service 与后端 Pod 通过 label selector 来实现对接。 而 RC 的作用是保证 service 的服务能能力和服务质量能够始终处于预期的标准。
每个 Pod 都会被分配一个单独的 IP 地址,而且每个 Pod 都提供一个独立的 endpoint 以被客户端访问,现在多个 Pod 组成的集群提供服务,一般是需要部署一个负载均衡器实现转发。在 k8s 中,node 上的 kube-proxy 就是一个软件负载均衡器,它负责把对 service 的请求转发到后端的某个 Pod 实例上,部署实现服务的负载均衡与会话保持机制,每个 service 分配一个全局唯一的虚拟 IP 地址,这个虚拟 IP 被称为 cluster IP,其在 service 的整个生命周期内是不变的。
apiVersion: v1 kind: Service metadata: name: tomcat-service spec: ports: - port: 8080 selector: tier: frontend
这里的标签与之前创建的 Tomcat 对应,查看暴露的地址和端口
[root@centos ~]# kubectl get endpoints NAME ENDPOINTS AGE kubernetes 192.168.10.115:6443 2d mysql 172.17.0.3:3306 3m tomcat-service 172.17.0.2:8080 37s
查看 service 的 cluster IP:
[root@centos ~]# kubectl get svc tomcat-service -o yaml
得到如下内容
apiVersion: v1 kind: Service metadata: creationTimestamp: 2018-03-05T06:46:41Z name: tomcat-service namespace: default resourceVersion: "256242" selfLink: /api/v1/namespaces/default/services/tomcat-service uid: f6544c3e-2040-11e8-b481-fa163eee21c2 spec: clusterIP: 10.254.1.165 ports: - port: 8080 protocol: TCP targetPort: 8080 selector: tier: frontend sessionAffinity: None type: ClusterIP status: loadBalancer: {}
其中 targetPort 属性用来确定提供该服务的容器暴露(EXPOSE)的端口,而 port 则定义 service 的虚拟端口,因为前面 Tomcat 没有指定 targetport,则默认与 port 相同。
多端口问题
其样例:
apiVersion: v1 kind: Service metadata: name: tomcat-service spec: ports: - port: 8080 name: service-port - port: 8005 name: shutdown-port selector: tier: frontend
为什么要给多端口命名,这就需要涉及 k8s 的服务发现了。
服务发现
首先,每个 k8s 中的 service 都有一个唯一的 cluster IP 以及唯一的名字,而名字是由开发者自定义的,部署的时候也没必要改变,所以完全可以固定在配置中。
早期 k8s 采用 linux 环境变量的方式解决问题。
这种方式不太方便,后来 k8s 通过 ADD-On 增值包的方式引入了 DNS 系统,把服务名作为 DNS 域名。
外部系统访问 service 的问题
采用nodeport 访问最为直接,但是 nodeport 无法解决例如负载均衡的问题,需要有一个 load balancer
Volume (存储卷)
k8s 的 volume 是 Pod 中能够给多容器访问的共享目录,与 docker 的 volume 类似,但不等价。首先,k8s 的 volume 定义在 Pod 上,然后被一个 Pod 里的多个容器挂载到具体的文件目录下,其次,k8s 的 volume 与 Pod 的生命周期相同,但是与容器的生命周期不相关。最后,k8s 支持多种类型的 volume,例如 ceph 等分布式文件系统。
k8s 的 volume 类型有:emptyDir(初始为空的,用来存放一些临时文件)、hostPath(主机文件或目录,存放日子等需要永久保存的文件)、gcePersistentDisk(谷歌公有云的永久磁盘,数据不会被删除,但是有限制条件)、awsElasticBlockStore(与前者类似)、NFS、其他类型的(iscsi等)。
Persistent volume
简称 PV,可以理解为 k8s 集群中的某个网络存储中对应的一块存储:
- PV 只能是网络存储,不属于任何 Node,但是可以在 Node 上访问。
- PV 并不是定义在 Pod 上,而是独立在 Pod 之外。
- PV 目前的类型有 GCE NFS RBD iSCSCI aswElasticBlockStore GlusterFS
Namespace
中文名命令空间,可以实现多租户的资源隔离,通过将集群内部的资源对象分配到不同的 namespace 中,形成逻辑上分组的不同项目、小组或用户组,便于不同分组在共享使用整个集群的资源的同时还能被分别管理。
默认会有一个 default 的 namespace。
[root@centos ~]# kubectl get namespaces NAME STATUS AGE default Active 2d kube-system Active 2d
如果不特别指明,则创建的 Pod RC service 都会被分配到 default 中。
定义 namespace,创建一个 namespace-demo.yaml 的文件
apiVersion: v1 kind: Namespace metadata: name: development
然后创建查看 namespace
[root@centos ~]# kubectl create -f namespace-demo.yaml namespace "development" created [root@centos ~]# kubectl get namespaces NAME STATUS AGE default Active 2d development Active 4s kube-system Active 2d
添加一个pod 的配置,直到其 namespace 为 development
apiVersion: v1 kind: Pod metadata: name: busybox namespace: development spec: containers: - image: busybox command: - sleep - "36000" name: busybox
创建
[root@centos ~]# kubectl create -f busybox.yaml pod "busybox" created
查看
[root@centos ~]# kubectl get pods NAME READY STATUS RESTARTS AGE frontend-141477217-jcckp 1/1 Running 0 1h mysql-7p27m 1/1 Running 0 42m myweb-0n7b9 1/1 Running 0 42m myweb-5dcff 1/1 Running 0 42m myweb-mbxk4 1/1 Running 0 42m myweb-md64b 1/1 Running 0 42m myweb-rkql9 1/1 Running 0 42m
直接查看不显示,需要加参数
[root@centos ~]# kubectl get pods --namespace=development NAME READY STATUS RESTARTS AGE busybox 1/1 Running 0 57s
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Python Machine Learning
Sebastian Raschka / Packt Publishing - ebooks Account / 2015-9 / USD 44.99
About This Book Leverage Python' s most powerful open-source libraries for deep learning, data wrangling, and data visualization Learn effective strategies and best practices to improve and opti......一起来看看 《Python Machine Learning》 这本书的介绍吧!