1. 了解 Kubernetes
1.1 Kubernetes是什么
Kubernetes
是谷歌十几年来大规模容器技术应用的重要成果,是谷歌严格保密十几年的秘密武器一一Borg
的一个开源版本。
通过简单阅读下列内容,对kubernetes
有个感性的认知:
Kubernetes
也是一个全新的基于容器技术的分布式架构领先方案,是容器云的优秀平台选型方案,已成为新一代的基于容器技术的PaaS
平台的重要底层框架,也是云原生技术生态圈的核心,服务网格(Service Mesh
)、无服务器架构(Serverless
)等新一代分布式架构框架及技术纷纷基于Kubernetes
实现。Kubernetes
提供了强大的自动化机制,系统后期的运维难度和运维成本大幅度降低。Kubernetes
是一个开放的开发平台,它不局限于任何一种语言,没有限定任何编程接口,所以不论是用Java、Go、C++
还是用Python
编写的服务,都可以被映射为Kubernetes
的Service
(服务),并通过标准的TCP
通信协议进行交互。Kubernetes
是一个完备的分布式系统支撑平台。Kubernetes
具有完备的集群管理能力,包括多层次的安全防护和准入机制、多租户应用支撑能力、透明的服务注册和服务发现机制、内建的智能负载均衡器、强大的故障发现和自我修复能力、服务滚动升级和在线扩容能力、可扩展的资源自动调度机制,以及多粒度的资源配额管理能力。Kubernetes
提供了完善的管理工具,这些工具涵盖了包括开发、部署测试、运维监控在内的各个环节。因此,Kubernetes
是一个全新的基于容器技术的分布式架构解决方案,并且是一个一站式的完备的分布式系统开发和支撑平台。
1.2 Kubernetes的基本知识
1.2.1 Service
在 Kubernetes
中,Service
是分布式集群架构的核心,一个 Service
对象拥有如下关键特征:
- 拥有唯一指定的名称(比如
mysql-server
); - 拥有一个虚拟
IP
地址(ClusterIP
地址)和端口号; - 能够提供某种远程服务能力;
- 能够将客户端对服务的访问请求转发到一组容器应用上。
每个服务进程都有一个独立的 Endpoint (IP+Port)
访问点,但 Kubernetes
能够让我们通过 Service (ClusterIP+Service Port)
连接指定的服务。更重要的是,这个 Service
本身一旦创建就不再变化,这意味着我们再也不用为 Kubernetes
集群中应用服务进程IP
地址变来变去的问题头疼了。
Kubernetes
设计了Pod
对象为容器提供了强大的隔离功能,我们有必要把 Service
提供服务的这组进程放入容器中进行隔离。Kubernetes
会给每个Pod
都贴上一个标签(Label
),例如MySQL Service
的标签选择器的选择条件为 name=mysql
,意为该 Service
要作用于所有包含 name=mysql
标签的 Pod
,这样一来,就巧妙解决了 Service
与Pod
的关联问题。
1.2.2 Pod
Pod
的概念:
- 首先,
Pod
运行在一个被称为节点(Node
)的环境中,这个节点既可以是物理机,也可以是私有云或者公有云中的一个虚拟机,在一个节点上能够运行多个Pod
; - 其次,在每个
Pod
中都运行着一个特殊的被称为Pause
的容器,其他容器则为业务容器,这些业务容器共享Pause
容器的网络栈和Volume
挂载卷,因此它们之间的通信和数据交换更为高效,在设计时我们可以充分利用这一特性将一组密切相关的服务进程放入同一个Pod
中; - 最后,需要注意的是,并不是每个
Pod
和它里面运行的容器都能被映射到一个Service
上,只有提供服务(无论是对内还是对外)的那组Pod
才会被映射为一个服务。
在集群管理方面,Kubernetes 将集群中的机器划分为一个 Master 和一些Node:
- 在
Master
上运行着集群管理相关的一些进程:kube-apiserver、kube- controller-manager
和kube-scheduler
,这些进程实现了整个集群的资源管理、Pod
调度、弹性伸缩、安全控制、系统监控和纠错等管理功能,并且都是自动完成的。 Node
作为集群中的工作节点,其上运行着真正的应用程序。在Node
上,Kubernetes
管理的最小运行单元是Pod
。在Node
上运行着Kubernetes
的kubelet
、kube-proxy
服务进程,这些服务进程负责Pod
的创建、启动、监控、重启、销毁,以及实现软件模式的负载均衡器。
2. 为什么要用 Kubernetes
使用Kubernetes
的理由:
- IT 行业从来都是由新技术驱动的。Kubernetes是软件领域近几年来最具创新的容器技术,涵盖了架构、研发、部署、运维等全系列软件开发流程,不仅对互联网公司的产品产生了极大影响,也对传统行业的 IT 技术产生了越来越强的冲击。
- 市面上几乎所有提供云基础设施的公司都以原生形式将 Kubernetes 作为底层平台。例如腾讯自研的 TKEx 容器平台的底层也使用了 Kubernetes 原生技术,服务于腾讯的各种业务系统,包括腾讯会议、腾讯课堂、QQ 及腾讯看点等,目前这些业务已运行的 Kubernetes集群规模达到几百万 CPU 核数。
3. 从一个简单的例子开始
需求:JSP
页面通过 JDBC
直接访问 MySQL
数据库并展示数据。
3.1 启动 MySQL 服务
3.1.1 Deployment定义文件
首先,为 MySQL
服务创建一个 Deployment
定义文件 mysql-deploy.yaml
,下面给出了该文件的完整内容和说明:
以上 YAML 定义文件中:
kind
属性用来表明此资源对象的类型,比如这里的属性值表示这是一个Deployment
;spec
部分是Deployment
的相关属性定义。比如:spec.selector
是Deployment
的Pod
选择器,符合条件的Pod
实例受到该Deployment
的管理,确保在当前集群中始终有且仅有replicas
个Pod
实例在运行(这里设置replicas=1
, 表示只能运行一个MySQL Pod
实例)。- 当在集群中运行的
Pod
数量少于replicas
时,Deployment
控制器会根据在spec.template
部分定义的Pod
模板生成一个新的Pod
实例,spec.template.metadata.labels
指定了该Pod
的标签,labels
必须匹配之前的spec.selector
。
创建好mysql-deploy.yaml
文件后,为了将它发布到 Kubernetes
集群中,我们在 Master
上运行如下命令:
接下来,运行 kubectl
命令查看刚刚创建的 Deployment
:
查看 Pod
的创建情况时,可以运行下面的命令:
可以看到一个名称为mysql-85f4b4cdf4-k97wh
的 Pod
实例,这是 Kubernetes
根据 mysql
这个 Deployment
的定义自动创建的 Pod
。
由于 Pod
的调度和创建需要花费一定的时间,比如需要确定调度到哪个节点上,而且下载 Pod
所需的容器镜像也需要一段时间,所以一开始Pod
的状态为 Pending
,在 Pod
成功创建启动完成后,其状态最终会更新为 Running
。
我们可以在 Kubernetes
节点的服务器上通过 docker ps
指令查看正在运行的容器,发现提供 MySQL
服务的 Pod
容器已创建且正常运行,并且 MySQL Pod
对应的容器多创建了一个 Pause
容器,该容器就是Pod
的根容器。
3.1.2 service定义文件
最后,创建一个与之关联的 Kubernetes Service--MySQL
的定义文件(文件名为 mysql-svc.yaml
),完整的内容和说明如下:
其中:
metadata.name
是Service
的服务名(ServiceName);spec.ports
属性定义了Service
的虚端口;spec. selector
确定了哪些Pod
副本(实例)对应本服务。
类似地,我们通过 kubectl create
命令创建 service
对象:
运行 kubectl get
命令,查看刚刚创建的 Service
对象:
可以发现,MySQL
服务被分配了一个值为 10.245.161.22
的 ClusterIP 地址
(在不同环境中分配的 IP
地址可能不同)。随后,在 Kubernetes
集群中新创建的其他 Pod 就可以通过 Service
的 ClusterIP
+端口号 3306
来连接和访问它了。
通常,ClusterIP
地址是在 Service
创建后由 Kubernetes
系统自动分配的,其他 Pod
无法预先知道某个 Service
的 ClusterIP
地址,因此需要一个服务发现机制来找到这个服务。为此,Kubernetes最初巧妙地使用了 Linux 环境变量(Environment Variable)来解决这个问题。根据 Service的唯一名称,容器可以从环境变量中获取Service对应的ClusterIP地址和端口号,从而发起TCP/IP 连接请求。
3.2 启动 Tomcat应用
3.2.1 Deployment定义文件
前面定义和启动了 MySQL
服务,接下来采用同样的步骤完成 Tomcat
应用的启动。首先,创建对应的 RC
文件 myweb--deploy.yaml
,内容如下:
注意:在 Tomcat
容器内,应用将使用环境变量 MYSQL_SERVICE_HOST
的值连接 MySQL
服务,但这里为什么没有注册该环境变量呢?这是因为 Kubernetes
会自动将已存在的 Service
对象以环境变量的形式展现在新生成的 Pod
中。其更安全、可靠的方法是使用服务的名称 mysql
,这就要求集群内的 DNS
服务(kube- dns
)正常运行。运行下面的命令,完成 Deployment
的创建和验证工作:
3.2.2 service定义文件
最后,创建对应的 Service
,以下是完整的 YAML
定义文件(myweb- svc.yaml
):
type: NodePort
和“nodePort:30001
”表明此 Service
开启了 NodePort
格式的外网访问模式。比如,在 Kubernetes
集群外,客户端的浏览器可以通过 30001
端口访问 myweb
(对应 8080
的虚端口,运行 kubectl create
命令进行创建:
运行 kubectl get命令,查看已创建的service:
3.3 通过浏览器访问网页
经过上面的流程,我们终于成功实现了 Kubernetes
上第 1 个例子的部署、搭建工作。现在一起来见证成果吧!在你的笔记本上打开浏览器,输入“http:/虚拟机 IP:30001/demo/”。
比如虚拟机 IP 为 192.168.18.131(可以通过 pa 命令进行查询),在浏览器里输入地址 http: /192.168.18.131:30001/demo/后,可以看到如图1.2 所示的网页界面