Kubernetes
每个微服务通过Docker进行发布,随着业务的发展,系统中遍布着各种各样的容器。于是容器的资源调度,部署运行,扩容缩容就是我们需要面临的问题。
基于 Kubernetes 作为容器集群的管理平台被广泛应用
Kubernetes架构
Kubernetes是用来管理容器集群的平台。但它不是直接来管理容器,而是把容器放在pod中,通过管理pod来管间接管理容器。
Master
我们通过 Master 对每个节点 Node 发送命令。简单来说,Master 就是管理者,Node 就是被管理者。
Node
Node可以是一台物理机或者是虚拟机。在Node上面可以运行多个Pod,Pod是Kubernetes管理的最小单位,同时每个pod可以包含多个容器。
Kubectl
通常我们都是通过 kubectl 对 Kubernetes 下命令的,它通过 APIServer 去调用各个进程来完成对 Node 的部署和控制。
API Server
- APIServer 的核心功能是对核心对象(例如:Pod,Service,RC)的增删改查操作,同时也是集群内模块之间数据交换的枢纽。
- 它包括了常用的 API,访问(权限)控制,注册,信息存储(etcd)等功能。在它的下面我们可以看到 Scheduler,它将待调度的 Pod 绑定到 Node 上,并将绑定信息写入 etcd 中。
- etcd 包含在 APIServer 中,用来存储资源信息
Controller Manager
Kubenetes是一套自动化运行的系统,那么就需要有一套管理规则来控制这套系统。Controller Manager 就是这个管理者,或者说是控制者。它包括 8 个 Controller,分别对应着副本,节点,资源,命名空间,服务等等。
Schedular
将待调度的pod绑定到Node上,并将绑定信息写入etcd。
kubelet
kubelet 用于处理 Master 下发到 Node 的任务(即 Scheduler 的调度任务),同时管理 Pod 及 Pod 中的容器。
服务部署
指令部署
kubectl run my-app --image=hub.kaikeba.com/library/myapp:v1 --port=80
yaml文件部署
kubectl create -f xxx.yml
deployment
apiVersion: apps/v1 # 1.9.0 之前的版本使用 apps/v1beta2,可通过命令kubectl api-versions 查看
kind: Deployment #指定创建资源的角色/类型
metadata: #资源的元数据/属性
name: nginx-deployment #资源的名字,在同一个namespace中必须唯一
spec:
replicas: 2 #副本数量2
selector: #定义标签选择器
matchLabels:
app: web-server
template: #这里Pod的定义
metadata:
labels: #Pod的label
app: web-server
spec: # 指定该资源的内容
containers:
- name: nginx #容器的名字
image: nginx:1.12.1 #容器的镜像地址
ports:
- containerPort: 80 #容器对外的端口
pod
apiVersion: v1
kind: Pod
metadata:
name: pod-redis
labels:
name: redis
spec:
containers:
- name: pod-redis
image: docker.io/redis
ports:
- containerPort: 80 #容器对外的端口
service
apiVersion: v1
kind: Service # 指明资源类型是 service
metadata:
name: httpd-svc # service 的名字是 httpd-svc
labels:
name: httpd-svc
spec:
ports: # 将 service 8080 端口映射到 pod 的 80 端口,使用 TCP 协议
- port: 8080
targetPort: 80
protocol: TCP
selector:
run: httpd # 指明哪些 label 的 pod 作为 service 的后端
API server
APIServer 的架构从上到下分为四层:
- **API 层:**主要以 REST 方式提供各种 API 接口,针对 Kubernetes 资源对象的 CRUD 和 Watch 等主要 API,还有健康检查、UI、日志、性能指标等运维监控相关的 API。
- **访问控制层:**负责身份鉴权,核准用户对资源的访问权限,设置访问逻辑(Admission Control)。
- **注册表层:**选择要访问的资源对象。PS:Kubernetes 把所有资源对象都保存在注册表(Registry)中,例如:Pod,Service,Deployment 等等。
- **etcd 数据库:**保存创建副本的信息。用来持久化 Kubernetes 资源对象的 Key-Value 数据库。
Controller Manager
Kubernetes 需要管理集群中的不同资源,所以针对不同的资源要建立不同的 Controller。
每个 Controller 通过监听机制获取 APIServer 中的事件(消息),它们通过 API Server 提供的(List-Watch)接口监控集群中的资源,并且调整资源的状态。
可以把它想象成一个尽职的管理者,随时管理和调整资源。比如 MySQL 所在的 Node 意外宕机了,Controller Manager 中的 Node Controller 会及时发现故障,并执行修复流程。
在部署了成百上千微服务的系统中,这个功能极大地协助了运维人员。从此可以看出,Controller Manager 是 Kubernetes 资源的管理者,是运维自动化的核心。
它分为 8 个 Controller,上面我们介绍了 Replication Controller,这里我们把其他几个都列出来,就不展开描述了。
Controller Manager 中不同的 Controller 负责对不同资源的监控和管理
Scheduler 与 kubelet
Scheduler 的作用是,将待调度的 Pod 按照算法和策略绑定到 Node 上,同时将信息保存在 etcd 中。
如果把 Scheduler 比作调度室,那么这三件事就是它需要关注的,待调度的 Pod、可用的 Node,调度算法和策略。
简单地说,就是通过调度算法/策略把 Pod 放到合适的 Node 中去。此时 Node 上的 kubelet 通过 APIServer 监听到 Scheduler 产生的 Pod 绑定事件,然后通过 Pod 的描述装载镜像文件,并且启动容器。
也就是说 Scheduler 负责思考,Pod 放在哪个 Node,然后将决策告诉 kubelet,kubelet 完成 Pod 在 Node 的加载工作。
说白了,Scheduler 是 boss,kubelet 是干活的工人,他们都通过 APIServer 进行信息交换。
Scheduler 与 kubelet 协同工作图
Service
服务部署使用K8s来进行部署,如何实现集群 ?
复制多个pod实现负载均衡即可
多个pod之间如何进行访问?
k8s提供了一个service资源对象,实现多个pod之间的请求转发。
在 Kubernetes 中的 Service 定义了一个服务的访问入口地址(IP+Port)。Pod 中的应用通过这个地址访问一个或者一组 Pod 副本。
Service 与后端 Pod 副本集群之间是通过 Label Selector 来实现连接的。Service 所访问的这一组 Pod 都会有同样的 Label,通过这样的方法知道这些 Pod 属于同一个组。(一般一组业务(pod)对应一个service)
通过 kubectl get svc 查看service资源对象
这里的cluster-ip是由kubernetes自动分配的。当一个pod需要访问其他的pod的时候就需要通过Service的Cluster-ip和Port。也就是说CLuster-ip和Pod是Kubernetes集群的内部地址,是提供给集群内的Pod之间访问使用的,外部系统是无法通过这个Cluster-ip来访问Kubernetes中的应用。
service如何实现对pod的负载均衡?
通过iptables ,默认是轮询。
KubeProxy
在Kubenetes集群上的每个Node上都会运行一个Kube-proxy服务进程,我们可以把这个进程看作Service的负载均衡器,其核心功能是将到Service的请求转发到后端的多个Pod上。
此外,Service 的 Cluster-IP 与 NodePort 是 kube-proxy 服务通过 iptables 的 NAT 转换实现的。kube-proxy 在运行过程中动态创建与 Service 相关的 iptables 规则。
由于 iptables 机制针对的是本地的 kube-proxy 端口,所以在每个 Node 上都要运行 kube-proxy 组件。
Ingress
Ingress 是一个反向代理服务,底层就是Nginx,是Kubernetes对nginx做了扩展开发;因此Ingress具有动态配置的的能力;
Ingress作用是对后端ServiceVIP提供反向代理服务;使得对外用户只有一个访问的入口,所有请求都必须经过INgress进行转发,转发给后端Service,然后由Service把请求转发给POD服务。
All in all
Kubernetes是用来管理容器集群的,Master作为管理者,包括API server ,Scheduler、Controller Manager。
Node作为副本部署的载体,包含多个Pod,每个Pod又包含多个容器(container)。用户通过kubectl 给Master中的APIServer下部署命令。
命令主体是以“.yaml”结尾的配置文件,包含副本的类型,副本个数,名称,端口,模版等信息。
APIServer 接受到请求以后,会分别进行以下操作:权限验证(包括特殊控制),取出需要创建的资源,保存副本信息到etcd。
APIServer 和 Controller Manager,Scheduler 以及 kubelete 之间通过 List-Watch 方式通信(事件发送与监听)。
Controller Manager 通过 etcd 获取需要创建资源的副本数,交由 Scheduler 进行策略分析。
最后 kubelet 负责最终的 Pod 创建和容器加载。部署好容器以后,通过 Service 进行访问,通过 cAdvisor 监控资源。
常用指令
查看某分支下的pod
kubectl get pod -n dev-core
查看pod内某个容器的日志
kubectl logs <容器名> -n dev-core
查看分支下的ingress
kubectl get ingress -n dev-core
部署指令
kubectl run myapp –image=镜像地址 –port=80 容器端口
以yaml文件部署
kubectl create -f xxx.yaml
查询资源对象:
- kubectl get pod
- kubectl get deployment
- kubectl get rs
- kubectl get pod -o wide
进入dev-core中pod的容器内部(前提是该pod中只有一个容器)
kubectl exec -it nvhl-pcis-elasticsearch-impl-546f4d649c-rpwsj-n dev-core -- /bin/bash
查看资源对象描述信息
kubectl describe pod/ContainerName -n dev-core