容器就从一个开发者手里的小工具,一跃成为了云计算领域的绝对主角;而能够定义容器组织和管理规范的“容器编排”技术,则当仁不让地坐上了容器技术领域的“头把交椅”。这其中,最具代表性的容器编排工具,当属 Docker 公司的 Compose+Swarm 组合,以及 Google 与 RedHat 公司共同主导的 Kubernetes 项目。
Kubernetes 能给我提供路由网关、水平扩展、监控、备份、灾难恢复等一系列运维能力。 Docker 公司的 Compose+Swarm 项目也有这些功能。
Kubernetes 项目在 Borg 体系的指导下,体现出了一种独有的“先进性”与“完备性”
k8s的全局架构
Etcd:整个集群的持久化数据,则由 kube-apiserver 处理后保存在 Etcd 中。
master:控制节点,即 Master 节点,由三个紧密协作的独立组件组合而成,它们分别是负责 API 服务的 kube-apiserver、负责调度的 kube-scheduler,以及负责容器编排的 kube-controller-manager。
node:kubelet + networking+contianerRuntime+Volume Plugin + DevicePlugin+ LinuxOS
kubelet通过CRI与continaer Runtime交互,然后continaer Runtime通过OCI与底层LINUX os交互,即把CRI请求翻译成对linux操作系统的调用。
kubelet 还通过 gRPC 协议同一个叫作 Device Plugin 的插件进行交互。这个插件,是 Kubernetes 项目用来管理 GPU 等宿主机物理设备的主要组件
kubelet 的另一个重要功能,则是调用网络插件和存储插件为容器配置网络和持久化存储。这两个插件与 kubelet 进行交互的接口,分别是 CNI(Container Networking Interface)和 CSI(Container Storage Interface)
了解:
一切以服务为中心,一切围绕服务运转。
k8s可以自我扩展、自我诊断与维护,容易升级与扩容。
1.1 kubernetes入门
完备的分布式系统支撑平台,完备的集群管理能力;
包括多层次的安全防护和准入机制、多租户应用支撑能力、透明的服务注册和发现机制、内建智能负载均衡器、强大的故障发现和自我修复能力、服务滚动升级和在线扩容能力、可扩展的资源自动调度机制、以及多粒度的资源配额管理能力。同时拥有开发、测试、部署、运维监控各环节的管理工具。
简单了解k8s中的几个概念
服务(Service)
1)拥有一个唯一指定的名字,如mysql-server
2) 拥有一个虚拟IP和端口号
3)能够提供某种远程服务能力
4)被映射到提供了这种服务能力的一组容器应用上
service服务基于socket通信方式对外提供服务,k8s能让我们通过虚拟Ip+服务端口的连接到指定的service上,同时通过k8s内建的透明负载均衡和故障恢复机制,不管后端有多少服务进程,或者由于故障重新部署到别的机器,都不会影响我们对服务的正常调用。所以在k8s中,无需为了服务IP地地址的变化而变化。
Pod对象:
运行在节点(一个物理机或虚拟机)之上,一个节点上运行几百个Pod。
一个Pod包含多个容器,包括一个Pause容器和多个业务容器,Pause容器中有的网络栈和共享卷,被多个业务容器共享。所以他们之间的通信会更加高效,设计时可以将一组密切相关的服务进程放入同一个Pod中;
Pod与服务关联
1)每个Pod贴上一个标签,如给运行Mysql的Pod贴上name=mysql标签
2)给相应的service定义标签选择器,如mysql的标签选择器的选择条件为name=mysql,即该service作用于所有包含name=mysql Labe的Pod上
说明:只有提供服务的一组pod才会被映射成一个服务,并不是每个Pod和她里面运行的容器都能映射到一个service中。
集群管理
一个master节点 + 多个工作节点
master节点上运行着集群管理相关的一组进程,包括kube-apiserver\ kube-controller-manager\ kube-scheduler,实现集群的资源管理、pod调度、弹性伸缩、安全控制、系统监控行业纠错等管理功能。
node上k8s最小的管理单元是Pod,node上运行着k8s的kubelet、kube-proxy服务进程,负责pod的创建、启动、监控、重启、销毁等。
服务扩容和升级
k8s中,为需要扩容的服务所关联的Pod创建一个RC(replication controller),即可实现扩容与升级。
RC文件关键信息:
1)目标Pod的定义
2)目标pod需要运行的副本数量
3)要监控的目标Pod的标签(Label)
rc文件生效过程:k8s通过RC中定义的label筛选出对应的Pod实例,并实时监控其状态和数量,如果实例数量少于定义的副本数量,则会根据RC中的定义来创建一个新的Pod,然后将此Pod调度到合适的Node上启动运行,直到Pod实例的数量达到预定目标。
1.2为什么使用k8s
容器化技术的兴起,服务从单机走向集群已经是必然,k8s是被大众认可的docker分布式系统解决方案
k8s带来的好处:
1)职能更加清晰,架构师负责系统中服务组件的提炼,开发人员负责业务代码的开发,运维工程师负责k8s的部署和运维
2)拥抱微服务架构
3)服务迁移方便,可以从物理机中无缝迁移到公有云中,或者在服务高峰将部分服务对应的Pod副本放入公有云,提升系统吞吐量
4)横向扩容方便
1.3 k8s实现简单的java web应用
系统:Centos 7
1 环境准备
关闭防火墙:
systemctl disable firewalld
systemctl stop firewalld
安装k8s:
yum install -y etcd kubernetes
启动各种服务:etcd docker kube-apiserver等
systemctl start etcd
systemctl start docker
systemctl start kube-apiserver
systemctl start kube-controller-manager
systemctl start kube-scheduler
systemctl start kubelet
systemctl start kube-proxy
2 启动mysql服务
为mysql服务定义RC文件:mysql-rc.yaml,下面是完整内容和解释:
apiVersion: v1
kind: ReplicationController #副本控制器RC
metadata:
name: mysql #RC的名称,全局唯一
spec:
replicas: 1 #Pod副本的期待数量
selector:
app: mysql #符合目标的Pod拥有此标签
template: #根据此模板创建Pod的副本(实例)
metadata:
labels:
app: mysql #Pod副本拥有的标签,对应RC的Selector
spec:
containers: #Pod内容器的定义部分
- name: mysql #容器的名称
image: hub.c.163.com/library/mysql #容器对应的Docker image
ports:
- containerPort: 3306 #容器应用监听的端口号
env: #注入容器内的环境变量
- name: MYSQL_ROOT_PASSWORD
value: "123456"
在master节点使用kubectl命令将它发布到k8s集群中:
kubectl create -f mysql-rc.yaml
接下来使用kubectl命令查看刚刚创建的RC:
kubectl get rc
使用下面命令查看Pod的创建情况:
kubectl get pods
通过docker ps查看正在运行的容器,发现pod容器已创建并正常运行了,且多了一个pause容器,即Pod的根容器。
创建关联service的定义文件:mysql-svc.yaml
apiVersion: v1
kind: Service #表明是K8s Service
metadata:
name: mysql #Service的全局唯一名称
spec:
ports:
- port: 3306 #Service提供服务的端口号
selector: #Service对应的Pod拥有这里定义的标签
app: mysql
运行kubectl命令,创建service:
kubectrl create -f mysql-svc.yaml
查看创建的service: kubectrl get svc
注意到MySQL服务被分配到了一个值为10.254.152.247的Cluster IP地址,这是一个虚地址,随后,k8s集群中其他新创建的Pod就可以通过Service的Cluster IP+端口号3306来连接和访问它了。现在我们只需知道,根据Service的唯一名字,容器可以从环境变量中获取到Service对应的Cluster IP地址和端口,从而发起TCP/IP连接请求了。
3 启动tomcat服务
定义web的rc文件:myweb-rc.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: myweb
spec:
replicas: 5 #Pod副本期待数量为5
selector:
app: myweb
template:
metadata:
labels:
app: myweb
spec:
containers:
- name: myweb
image: docker.io/kubeguide/tomcat-app:v1
ports:
- containerPort: 8080
env:
- name: MYSQL_SERVICE_HOST
value: "mysql"
- name: MYSQL_SERVICE_PORT
value: "3306"
然后通过kubectl create命令完成RC的创建和验证工作:
kubectrl create -f myweb-rc.yaml
kubectrl get rc
kubectrl get pods
创建对应的Service,myweb-svc.yaml内容如下:
apiVersion: v1
kind: Service
metadata:
name: myweb
spec:
type: NodePort
ports:
- port: 8080 #虚拟端口,只能让k8s集群之内的客户端访问
nodePort: 30001 #节点实际的物理端口,可以让k8s集群之外的客户端访问
selector:
app: myweb
kubectrl create -f myweb-svc.yaml
kubectrl get services
在本机浏览器中输入http://10.0.0.73:30001/demo/来测试我们发的web应用。
运行在大规模集群中的各种任务之间,实际上存在着各种各样的关系。这些关系的处理,才是作业编排和管理系统最困难的地方。
比如:Web 应用与数据库之间的访问关系,一个负载均衡器和它的后端服务之间的代理关系,一个门户应用与授权组件之间的调用关系。
Kubernetes 项目最主要的设计思想是,从更宏观的角度,以统一的方式来定义任务之间的各种关系,并且为将来支持更多种类的关系留有余地。
按照这幅图的线索,我们从容器这个最基础的概念出发,首先遇到了容器间“紧密协作”关系的难题,于是就扩展到了 Pod;有了 Pod 之后,我们希望能一次启动多个应用的实例,这样就需要 Deployment 这个 Pod 的多实例管理器;而有了这样一组相同的 Pod 后,我们又需要通过一个固定的 IP 地址和端口以负载均衡的方式访问它,于是就有了 Service。
如果现在两个不同 Pod 之间不仅有“访问关系”,还要求在发起时加上授权信息。最典型的例子就是 Web 应用对数据库访问时需要 Credential(数据库的用户名和密码)信息。那么,在 Kubernetes 中这样的关系又如何处理呢?
Kubernetes 项目提供了一种叫作 Secret 的对象,它其实是一个保存在 Etcd 里的键值对数据。这样,你把 Credential 信息以 Secret 的方式存在 Etcd 里,Kubernetes 就会在你指定的 Pod(比如,Web 应用的 Pod)启动时,自动把 Secret 里的数据以 Volume 的方式挂载到容器里。这样,这个 Web 应用就可以访问数据库了。
Kubernetes 项目中,我们所推崇的使用方法是:
首先,通过一个“编排对象”,比如 Pod、Job、CronJob 等,来描述你试图管理的应用;
然后,再为它定义一些“服务对象”,比如 Service、Secret、Horizontal Pod Autoscaler(自动水平扩展器)等。这些对象,会负责具体的平台级功能。
参考:https://www.cnblogs.com/neutronman/p/8047547.html