《开源容器云OpenShift:构建基于Kubernetes的企业应用云平台》一3.2 核心组件详解

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介:

本节书摘来自华章出版社《开源容器云OpenShift:构建基于Kubernetes的企业应用云平台》一书中的第3章,第3.2节,作者 陈耿 ,更多章节内容可以访问云栖社区“华章计算机”公众号查看

3.2 核心组件详解

OpenShift的核心组件及其之间的关联关系如图3-2所示。OpenShift在容器编排层使用了Kubernetes,所以OpenShift在架构上和Kubernetes十分接近。其内部的许多组件和概念是从Kubernetes衍生而来,但是也存在一些在容器编排层之上,OpenShift特有的组件和概念。下面将详细介绍OpenShift内部的核心组件和概念。
image

3.2.1 Master节点

在介绍Master节点前,我们先补充一些内容。OpenShift集群可以由一台或多台主机组成。这些主机可以是物理机或虚拟机,同时可以运行在私有云、公有云,或混合云上。在OpenShift的集群成员有两种角色。
Master节点:即主控节点。集群内的管理组件均运行于Master节点之上。Master节点负责管理和维护OpenShift集群的状态。
Node节点:即计算节点。集群内的容器实例均运行于Node节点之上。
如图3-2所示,在Master节点上运行了众多集群的服务组件:
API Server。负责提供集群的Web Console以及RESTful API服务。集群内的所有Node节点都会访问API Server更新各节点的状态及其上运行的容器的状态。
数据源(Data Store)。集群所有动态的状态信息都会存储在后端的一个etcd分布式数据库中。默认的etcd实例安装在Master节点上。如有需要,也可以将etcd节点部署在集群之外。
调度控制器(Scheduler)。调度控制器在容器部署时负责按照用户输入的要求寻找合适的计算节点。例如,在前面章节我们部署的Router组件需要占用计算节点主机的80、443及1936端口。部署Router时,调度控制器会寻找端口没有被占用的计算节点并分配给Router进行部署。除了端口外,用户还能指定如CPU、内存及标签匹配等多种调度条件。
复制控制器(Replication Controller)。对容器云而言,一个很重要的特性是异常自恢复。复制控制器负责监控当前容器实例的数量和用户部署指定的数量是否匹配。如果容器异常退出,复制控制器将会发现实际的容器实例数少于部署定义的数量,从而触发部署新的容器实例,以恢复原有的状态。

3.2.2 Node节点

在Node节点上没有这么多系统组件,其主要职责就是接收Master节点的指令,运行和维护Docker容器。
这里要指出的是,Master节点本身也是一个Node节点,只是在一般环境中会将其运行容器的功能关闭。但是在我们这个实验集群中,由于只有一个节点,所以这个Master节点也必须承担运行容器的责任。
通过执行oc get node命令可以查看系统中的所有节点。

[root@master ~]# oc get nodes
NAME                 STATUS    AGE
master.example.com   Ready     1d

查看集群信息需要集群管理员的权限,请先登录为system:admin。具体方法请查看之前的章节介绍。
可以看到,目前集群中只有一个节点,状态是Ready。通过oc describe node master.example.com命令查看节点的详细信息。

[root@master ~]# oc describe node master.example.com
Name:           master.example.com
Labels:         beta.kubernetes.io/arch=amd64
            beta.kubernetes.io/os=linux
            kubernetes.io/hostname=master.example.com
Taints:         <none>
CreationTimestamp:  Sat, 17 Sep 2016 18:24:40 -0400
Phase:          
Conditions:
  Type            Status  LastHeartbeatTime      LastTransitionTime      Reason   Message
  ----            ------  -----------------      ------------------      ------   -------
  OutOfDisk       False   Sat, 17 Sep 2016...    Sat, 17 Sep 2016...     KubeletHasSufficient...
  MemoryPressure  False   Sat, 17 Sep 2016...    Sat, 17 Sep 2016...     KubeletHasSufficient...
  Ready           True    Sat, 17 Sep 2016...    Sat, 17 Sep 2016...     KubeletReadykubelet...
Addresses:      192.168.172.167,192.168.172.167
Capacity:
 alpha.kubernetes.io/nvidia-gpu:    0
cpu:                   1
memory:                1868664Ki
pods:                  110
Allocatable:
 alpha.kubernetes.io/nvidia-gpu:    0
cpu:                   1
memory:                1868664Ki
pods:                  110
System Info:
 Machine ID:            68b21a5dd46c4a34a8b7f66cd66b3b73
 System UUID:           564D2779-5B04-6978-470E-5796F8DF3ECB
 Boot ID:             0b3c164b-6d0b-4082-b5da-bac31b8f61a2
 Kernel Version:        3.10.0-327.el7.x86_64
 OS Image:            CentOS Linux 7 (Core)
 Operating System:      linux
 Architecture:          amd64
 Container Runtime Version: docker://1.10.3
Kubelet Version:         v1.3.0+52492b4
Kube-Proxy Version:        v1.3.0+52492b4
ExternalID:         master.example.com
......

从上面的输出可以看到该节点详细的系统信息、节点上运行的容器资源使用情况、网络地址等。

3.2.3 Project与Namespace

在Kubernetes中使用命名空间的概念来分隔资源。在同一个命名空间中,某一个对象的名称在其分类中必须是唯一的,但是分布在不同命名空间中的对象则可以同名。OpenShift中继承了Kubernetes命名空间的概念,而且在其之上定义了Project对象的概念。每一个Project会和一个Namespace相关联,甚至可以简单地认为,Project就是Namespace。所以在OpenShift中进行操作时,首先要确认当前执行的上下文是哪一个Project。
通过oc project命令可以查看用户当前所在的Project。

[root@master ~]# oc project 
Using project "default" on server "https://192.168.172.167:8443".

通过oc project 可以切换到指定的项目。现在请切换到上一章创建的helloworld-php项目,接下来我们会以这个项目为基础进行讲解。

[root@master ~]#  oc project hello-world-php
Now using project "hello-world-php" on server "https://192.168.172.167:8443".

3.2.4 Pod

在OpenShift上运行的容器会被一种叫Pod的对象所“包裹”,用户不会直接看到Docker容器本身。从技术上来说,Pod其实也是一种特殊的容器。执行oc get pods命令可以看到当前所在项目的Pod。

[root@master ~]# oc get pod
NAME                            READY     STATUS      RESTARTS   AGE
cakephp-mysql-example-1-build   0/1       Completed   0          1h
cakephp-mysql-example-1-u63y2   1/1       Running     0          1h
mysql-1-jovdm                   1/1       Running     0          1h

执行oc describe pod命令可以查看容器的详细信息,如Pod部署的Node节点名、所处的Project、IP地址等。

[root@master ~]#  oc describe pod mysql-1-jovdm 
Name:           mysql-1-jovdm
Namespace:      hello-world-php
Security Policy:    restricted
Node:           master.example.com/192.168.172.167
Start Time:     Sat, 17 Sep 2016 21:00:28 -0400
Labels:         deployment=mysql-1
deploymentconfig=mysql
name=mysql
Status:         Running
IP:         172.17.0.6
Controllers:        ReplicationController/mysql-1
……

用户可以近似认为实际部署的容器会运行在Pod内部。一个Pod内部可以运行一个或多个容器,运行在一个Pod内的多个容器共享这个Pod的网络及存储资源。从这个层面上,可以将Pod理解为一个虚拟主机,在这个虚拟主机中,用户可以运行一个或多个容器。虽然一个Pod内可以有多个容器,但是在绝大多数情况下,一个Pod内部只运行一个容器实例。Pod其实也是一个Docker容器,通过dockerps命令可以查看Pod的实例信息。
因为大多数情况下都是一个容器运行在一个Pod内,很多时候可以将Pod等同于我们所要运行的容器本身。

[root@master ~]# dockerps |grep php
17c5e7154790        172.30.73.49:5000/hello-world-php/cakephp-mysql-example@sha256:e3f4705aac3e718c22e4d8d1bf12ab3041d0f417752289ea132e503cf5adc91d   "container-entrypoint"   About an hour ago   Up About an hour                        k8s_cakephp-mysql-example.9fcda1c6_cakephp-mysql-example-1-u63y2_hello-world-php_382e1e18-7d3c-11e6-a285-000c29df3ecb_ced53322
3eb08d061fa9        openshift/origin-pod:v1.3.0    "/pod"                   About an hour ago   Up About an hour   
……

上述代码是查找PHP的容器实例。一共有两个输出,一个是实际的PHP应用的容器实例,另一个是镜像类型为openshift/origin-pod:v1.3.0的容器,即Pod容器实例。
容器像盒子一样为应用提供一个独立的运行环境,但它并不是一个黑盒子。用户可以实时地查看容器的输出,也可以进入容器内部执行操作。
执行oc logs 命令,可以查看Pod的输出。

[root@master ~]# oc logs mysql-1-jovdm
---> 16:22:33     Processing MySQL configuration files ...
---> 16:22:33     Initializing database ...
……

执行ocrsh命令,可以进入容器内部执行命令进行调试。

[root@master ~]# ocrsh mysql-1-jovdm
sh-4.2$ hostname
mysql-1-jovdm
sh-4.2$ ps ax
     PID TTY      STAT   TIME COMMAND
1 ?Ssl    0:51 /opt/rh/rh-mysql56/root/usr/libexec/mysqld --default
43096 ?Ss     0:00 /bin/sh
43104 ?        R+     0:00 ps ax

oc logs及ocrsh是两个非常有用的命令,是排查容器相关问题的重要手段。

3.2.5 Service

容器是一个一个非持久化的对象。所有对容器的更改在容器销毁后默认都会丢失。同一个Docker镜像实例化形成容器后,会恢复到这个镜像定义的状态,并且获取一个新的IP地址。容器的这种特性在某些场景下非常难能可贵,但是每个新容器的IP地址都在不断变化,这对应用来说不是一件好事。拿前文部署的PHP和MySQL应用来说,后端MySQL容器在重启后IP地址改变了,就意味着必须更新PHP应用的数据库地址指向。如果不修改应用地址指向,就需要有一种机制使得前端的PHP应用总是能连接到后端的MySQL数据库。
为了克服容器变化引发的连接信息的变化,Kubernetes提供了一种叫Service(服务)的组件。当部署某个应用时,我们会为该应用创建一个Service对象。Service对象会与该应用的一个或多个Pod关联。同时每个Service会被分配到一个IP地址,这个IP地址是相对恒定的。通过访问这个IP地址及相应的端口,请求就会被转发到对应Pod的相应端口。这意味着,无论后端的Pod实例的数量或地址如何变化,前端的应用只需要访问Service的IP地址,就能连接到正确的后端容器实例。Service起到了代理的作用,在相互依赖的容器应用之间实现了解耦。
通过oc get svc命令,可以获取当前项目下所有Service对象的列表。

[root@master ~]# oc get svc
NAME                    CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
cakephp-mysql-example   172.30.1.84     <none>        8080/TCP   17h
mysql                   172.30.166.12   <none>        3306/TCP   17h

通过CakePHP的Service的IP地址加端口172.30.1.84:8080,可以访问到Cake-PHP的服务。

[root@master ~]# curl -q  172.30.1.84:8080

如果尝试ping一下Service的IP地址,结果是不会成功的。因为Service的IP地址是虚拟的IP地址,而且这个地址只有集群内的节点和容器可以识别。
除了通过IP地址访问Service所指向的服务外,还可以通过域名访问某一个Service。监听在Master上的集群内置DNS服务器会负责解析这个DNS请求。Service域名的格式是..svc.cluster.local。比如上面例子中的PHP应用的Service域名将会是cakephp-mysql-example.helloworld-ng.svc.cluster.local:8080。可以在Master节点上用ping检查域名解析。

[root@master ~]# pingcakephp-mysql-example.helloworld-ng.svc.cluster.local
PING cakephp-mysql-example.helloworld-ng.svc.cluster.local (172.30.1.84) 56(84) bytes of data.

如果发现内部域名解析失败,可以在/etc/resolve.conf中添加一条指向本机的域名服务器的记录。

nameserver 127.0.0.1

3.2.6 Router与Route

Service提供了一个通往后端Pod集群的稳定的入口,但是Service的IP地址只是集群内部的节点及容器可见。对于外部的应用或者用户来说,这个地址是不可达的。那么外面的用户想要访问Service指向的服务应该怎么办呢?OpenShift提供了Router(路由器)来解决这个问题。上一章中介绍了Router组件的部署。其实Router组件就是一个运行在容器内的Haproxy,是一个特殊定制的Haproxy。用户可以创建一种叫Route的对象,笔者称为路由规则。一个Route会与一个Service相关联,并且绑定一个域名。Route规则会被Router加载。当用户通过指定域名访问应用时,域名会被解析并指向Router所在的计算节点上。Router获取这个请求,然后根据Route规则定义转发给与这个域名对应的Service后端所关联的Pod容器实例。在上一章部署CakePHP应用时,我们将Route域名修改为php.apps.example.com。当访问域php.apps.example.com时,请求到达Router,并由其向后端分发。当Pod的数量或者状态变化时,OpenShift负责更新Router内的配置,确保请求总是能被正确路由到对应的Pod。
通过命令oc get routes,可以查看项目中的所有Route。

[root@master ~]# oc get route -n hello-world-php
NAME                  HOST/PORT              PATH   SERVICES   PORT   TERMINATION
cakephp-mysql-example php.apps.example.com   cakephp-mysql-example   <all>

经常会有用户混淆了Router和Service的作用。Router负责将集群外的请求转发到集群的容器。Service则负责把来自集群内部的请求转发到指定的容器中。一个是对外,一个是对内。

3.2.7 Persistent Storage

容器默认是非持久化的,所有的修改在容器销毁时都会丢失。但现实是传统的应用大多都是有状态的,因此要求某些容器内的数据必须持久化,容器云平台必须为容器提供持久化储存(persistent storage)。Docker本身提供了持久化卷挂载的能力。相对于单机容器的场景,在容器云集群的场景中,持久化的实现有更多细节需要考虑。OpenShift除了支持Docker持久化卷的挂载方式外,还提供了一种持久化供给模型,即Persistent Volume(持久化卷,PV)及Persistent Volume Claim(持久化卷请求,PVC)模型。在PV和PVC模型中,集群管理员会创建大量不同大小和不同特性的PV。用户在部署应用时,显式声明对持久化的需求,创建PVC。用户在PVC中定义所需存储的大小、访问方式(只读或可读可写;独占或共享)。OpenShift集群会自动寻找符合要求的PV与PVC自动对接。通过PV和PVC模型,OpenShift为用户提供了一种灵活的方式来消费存储资源。
OpenShift对持久化后端的支持比较广泛,除了NFS及iSCSI外,还支持如Ceph、GluterFS等的分布式储存,以及Amazon WebService和Google Compute Engine的云硬盘。关于存储相关的话题,在后续章节会有更详细的探讨。

3.2.8 Registry

OpenShift提供了一个内部的Docker镜像仓库(Registry),该镜像仓库用于存放用户通过内置的Source to Image镜像构建流程所产生的镜像。Registry组件默认以容器的方式提供,在上一章中,我们手工部署了Registry组件。
通过oc get pod -n default命令可以查看Registry容器的状态。

[root@master ~]# oc get pod -n default
NAME                      READY     STATUS    RESTARTS   AGE
docker-registry-1-xm3un   1/1       Running   1          7h
router-1-e95qa            1/1       Running   1          7h

通过oc get svc -n default命令可以查看Registry容器对应的Service信息。

[root@master ~]# oc get svc -n default
NAME              CLUSTER-IP     EXTERNAL-IP   PORT(S)                   AGE
docker-registry   172.30.73.49   <none>        5000/TCP                  7h
kubernetes        172.30.0.1     <none>        443/TCP,53/UDP,53/TCP     9h
router            172.30.58.19   <none>        80/TCP,443/TCP,1936/TCP   7h

每当S2I完成镜像构建,就会向内部的镜像仓库推送构建完成的镜像。在上面的输出示例中,镜像仓库的访问点为172.30.73.49:5000。如果查看上一章CakePHP的S2I构建日志,就会看到最后有成功推送镜像的日志输出:Push successful。

[root@master ~]# oc logs cakephp-mysql-example-1-build -n hello-world-php
Cloning "https://github.com/openshift/cakephp-ex.git" ...
    Commit: 701d706b7f2b50ee972d0bf76990042f6c0cda5c (Merge pull request #42 from 
    bparees/recreate)
    Author: Ben Parees<bparees@users.noreply.github.com>
    Date:   Mon Aug 22 14:44:49 2016 -0400
---> Installing application source...
Pushing image 172.30.73.49:5000/hello-world-php/cakephp-mysql-example:latest ...
Pushed 0/10 layers, 1% complete
Pushed 1/10 layers, 50% complete
Pushed 2/10 layers, 50% complete
Pushed 3/10 layers, 50% complete
Pushed 4/10 layers, 50% complete
Pushed 5/10 layers, 50% complete
Pushed 6/10 layers, 61% complete
Pushed 7/10 layers, 71% complete
Pushed 7/10 layers, 78% complete
Pushed 8/10 layers, 85% complete
Pushed 8/10 layers, 91% complete
Pushed 8/10 layers, 97% complete
Pushed 9/10 layers, 99% complete
Pushed 10/10 layers, 100% complete
Push successful

一个常见的疑问是“是不是OpenShift用到的镜像都要存放到内置的仓库?”答案是否定的。内部的镜像仓库存放的只是S2I产生的镜像。其他镜像可以存放在集群外部的镜像仓库,如企业的镜像仓库或社区的镜像仓库。只要保证OpenShift的节点可以访问到这些镜像所在的镜像仓库即可。

3.2.9 Source to Image

前文多次提及Source to Image(S2I),因为S2I的确是OpenShit的一个重要功能。容器镜像是容器云的应用交付格式。容器镜像中包含了应用及其所依赖的运行环境。可以从社区或者第三方厂商获取基础的操作系统或者中间件的镜像。但是这些外部获取的操作系统或中间件的镜像并不包含企业内部开发和定制的应用。企业内部的开发人员必须自行基于外部的基础镜像构建包含企业自身开发的应用。这个镜像的构建过程是必须的,要么由企业的IT人员手工完成,要么使用某种工具实现自动化。
作为一个面向应用的平台,OpenShift提供了S2I的流程,使得企业内容器的构建变得标准化和自动化,从而提高了软件从开发到上线的效率。一个典型的S2I流程包含了以下几个步骤。
1)用户输入源代码仓库的地址。
2)用户选择S2I构建的基础镜像(又称为Builder镜像)。Builder镜像中包含了操作系统、编程语言、框架等应用所需的软件及配置。OpenShift默认提供了多种编程语言的Builder镜像,如Java、PHP、Ruby、Python、Perl等。用户也可以根据自身需求定制自己的Builder镜像,并发布到服务目录中供用户选用。
3)用户或系统触发S2I构建。OpenShift将实例化S2I构建执行器。
4)S2I构建执行器将从用户指定的代码仓库下载源代码。
5)S2I构建执行器实例化Builder镜像。代码将会被注入Builder镜像中。
6)Builder镜像将根据预定义的逻辑执行源代码的编译、构建并完成部署。
7)S2I构建执行器将完成操作的Builder镜像并生成新的Docker镜像。
8)S2I构建执行器将新的镜像推送到OpenShift内部的镜像仓库。
9)S2I构建执行器更新该次构建相关的Image Stream信息。
S2I构建完成后,根据用户定义的部署逻辑,OpenShift将把镜像实例化部署到集群中。
除了接受源代码仓库地址作为输入外,S2I还接受Dockerf?ile以及二进制文件作为构建的输入。用户甚至可以完全自定义构建逻辑来满足特殊的需求。

3.2.10 开发及管理工具集

OpenShift提供了不同的工具集为开发和运维的用户提供良好的体验,也为持续集成和打通DevOps流程提供便利。例如,OpenShift提供了Eclipse插件,开发工程师可以在Eclipse中完成应用及服务的创建和部署、远程调试、实时日志查询等功能。

相关实践学习
通过workbench远程登录ECS,快速搭建Docker环境
本教程指导用户体验通过workbench远程登录ECS,完成搭建Docker环境的快速搭建,并使用Docker部署一个Nginx服务。
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。 &nbsp; &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
8天前
|
运维 Kubernetes 监控
构建高效自动化运维体系:基于Docker和Kubernetes的实践指南
【2月更文挑战第30天】 在当今快速发展的云计算时代,传统的IT运维模式已难以满足业务的敏捷性和稳定性需求。本文深入探讨了如何通过Docker容器化技术和Kubernetes集群管理工具构建一个高效、可靠的自动化运维体系。文章首先概述了容器化技术和微服务架构的基本概念,随后详细阐述了基于Docker的应用打包、部署流程,以及Kubernetes在自动化部署、扩展和管理容器化应用中的关键作用。最后,文中通过案例分析,展示了如何在实际场景中利用这些技术优化运维流程,提高系统的整体效率和可靠性。
|
24天前
|
IDE 开发工具 Windows
鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之RowSplit容器组件
鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之RowSplit容器组件
37 0
|
1月前
|
IDE API 开发工具
鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Counter容器组件
鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Counter容器组件
33 1
|
1月前
|
IDE 开发工具 Windows
鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之ColumnSplit容器组件
鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之ColumnSplit容器组件
31 0
|
1月前
|
IDE API 开发工具
鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Column容器组件
鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Column容器组件
42 0
|
2月前
|
存储 Kubernetes 监控
K8S核心组件介绍
K8S核心组件介绍
|
1月前
|
机器学习/深度学习 算法 数据可视化
基于Google Earth Engine云平台构建的多源遥感数据森林地上生物量AGB估算模型含生物量模型应用APP
基于Google Earth Engine云平台构建的多源遥感数据森林地上生物量AGB估算模型含生物量模型应用APP
78 0
|
2月前
|
存储 Kubernetes 监控
Kubernetes快速进阶与实战:构建可靠的容器化应用平台
Kubernetes快速进阶与实战:构建可靠的容器化应用平台
79 0
|
4天前
|
运维 Cloud Native 持续交付
云原生技术:构建灵活高效的云平台
随着云计算技术的快速发展,云原生技术作为一种全新的应用架构范式,正在逐渐成为企业数字化转型的关键。本文将介绍云原生技术的核心概念及其在构建灵活高效的云平台中的重要作用,以及云原生技术对企业业务的影响和意义。
|
9天前
|
Kubernetes 开发者 Docker
构建高效微服务架构:Docker与Kubernetes的完美搭档
【2月更文挑战第29天】在当今快速发展的软件开发领域,微服务架构已成为提高系统可维护性、扩展性和敏捷性的关键解决方案。本文将深入探讨如何利用Docker容器化技术和Kubernetes集群管理工具,共同构建一个既高效又可靠的微服务环境。我们将分析Docker和Kubernetes的核心功能,并展示它们如何协同工作以简化部署流程、增强服务发现机制以及实现无缝的服务伸缩。通过实际案例分析,本文旨在为开发者提供一套实用的微服务架构设计和实施指南。

相关产品

  • 容器服务Kubernetes版