简述

下面的主题提供了在使用OpenShift容器平台时将遇到的核心概念和对象的高级、体系结构信息。这些对象中的许多都来自于Kubernetes,它由OpenShift容器平台扩展,以提供一个功能更丰富的开发生命周期平台。

Containers and images (容器和镜像)

Containers (容器)

OpenShift容器平台应用程序的基本单元称为容器。Linux容器技术是一种轻量级的机制,用于隔离正在运行的进程,这样它们就只能与指定的资源进行交互。

许多应用程序实例可以在单个主机上的容器中运行,而不会对彼此的进程、文件、网络等进行可视性。通常,每个容器都提供单个服务(通常称为“微服务”),比如web服务器或数据库,尽管容器可以用于任意的工作负载。

多年来,Linux内核一直在整合容器技术的能力。最近,Docker项目为主机上的Linux容器开发了一个方便的管理界面。OpenShift容器平台和Kubernetes增加了在多主机安装中编排docker格式化的容器的能力。

虽然在使用OpenShift容器平台时,您不会直接与Docker CLI或service交互,但是理解它们的功能和术语对于理解它们在OpenShift容器平台中的角色以及您的应用程序在容器内的功能是很重要的。docker RPM可以作为RHEL 7的一部分,以及CentOS和Fedora,所以你可以单独从OpenShift容器平台进行试验。请参考这篇文章 Get Started with Docker Formatted Container Images on Red Hat Systems进行引导介绍。

Init Containers (初始化容器)

一个pod除了应用程序容器,还可以有init容器。初始化容器允许您重新组织设置脚本和绑定代码。一个初始化容器与一个常规容器不同,它总是运行到完成。每个初始化容器必须在下一次启动之前成功完成。

要了解更多信息,请参阅 Pods and Services.

Images (镜像)

OpenShift容器平台中的容器是基于docker格式的容器镜像的。镜像是一个二进制文件,它包含了运行单个容器的所有需求,以及描述其需求和功能的元数据。

你可以把它看作是一种包装技术。容器只能访问镜像中定义的资源,除非在创建容器时给容器额外的访问权限。将相同的镜像通过多个hosts部署到多个容器中,并在它们之间进行负载平衡,OpenShift容器平台可以为打包为镜像的服务提供冗余和水平扩展。

您可以直接使用Docker CLI来构建镜像,同样OpenShift容器平台也提供构建器镜像,通过将您的代码或配置添加到现有的镜像中,从而帮助创建新的镜像。

由于应用程序随着时间的推移而不断发展,一个单一的镜像名称实际上可以引用许多不同版本的“相同”镜像。每个不同的镜像都是通过它的散列(一个很长的十六进制数字,例如fd44297e2ddb050ec4f.)来表示的,它通常被简化为12个字符(例如fd44297e2ddb)。

Image Version Tag Policy(镜像版本标记策略)

除了版本号之外,Docker服务还允许应用标签(如v1、v2.1、GA或默认的latest版本),以进一步指定所需的镜像,因此您可以看到与centos(即latest标签)相同的镜像,centos:centos7或fd44297e2ddb。

不要为任何官方的OpenShift容器平台镜像使用latest 标签。这些是从**openshift3/.
latest**开始的镜像可以引用许多版本,比如3.4,或者3.5。

如何标记镜像影响更新策略。镜像标记的越具体,更新的频率将会更低。使用下面的步骤来确定您所选择的OpenShift容器平台镜像策略:

vX.Y
vX.Y 标签指向 X.Y.Z-<number>。例如,如果registry-console 镜像更新到v3.4,它指向最新的3.4.Z-<number> 标签, 比如 3.4.1-8.

X.Y.Z
类似于上面的例子是 vX.Y。 X.Y.Z 标记指向最新的 X.Y.Z-<number>。例如,3.4.1将指向3.4.1-8。

X.Y.Z-<number>
标签是唯一的,并且不会改变。当使用这个标签时,如果镜像被更新,镜像不会更新,将生成一个新的镜像。例如,3.4.1-8将始终指向3.4.1-8,即使镜像被更新。

Container Registries(容器注册表)

容器注册表是用于存储和检索docker格式的容器镜像的服务。注册表包含一个或多个镜像存储库的集合。每个镜像库包含一个或多个标记的镜像。Docker提供了自己的注册中心Docker Hub,你也可以使用私人或第三方注册中心。Red Hat为用户提供了一个在registry.access.redhat.com上注册。OpenShift容器平台还可以提供自己的内部注册表来管理定制容器镜像。

容器、镜像和注册表之间的关系如下图所示:
这里写图片描述

Pods and Services

Pods

OpenShift容器平台利用了Kubernetes的pod概念,它是一个或多个容器一起部署在一个主机上,以及可以定义、部署和管理的最小的计算单元。

Pods大致相当于一个机器实例(物理或虚拟)到一个容器。每个pod都分配了它自己的内部IP地址,因此拥有它的整个端口空间,并且容器内的容器可以共享它们的本地存储和网络。

Pods有一个生命周期; 它们被定义,然后它们被分配到一个节点上运行,然后运行到它们的容器(s)退出,或者由于其他原因被删除。Pods声明周期 取决于策略和退出编码,可以在退出后删除,也可以保留,以便访问它们的容器的日志。

OpenShift容器平台对待Pods基本上是不可变的;在运行时,不能对pod定义进行更改。OpenShift容器平台通过终止现有的pod来实现更改,并通过修改后的配置、基础镜像(s)或两者进行重新创建。Pods也被视为可消耗的,并且在重新创建时不维护状态。因此,Pods通常应该由更高级的controllers来管理,而不是由用户直接管理。

这里写图片描述每个OpenShift容器平台节点主机的推荐最大数量是110。

下面是一个提供长时间运行服务的pod的示例定义,它实际上是OpenShift容器平台基础结构的一部分:集成容器注册表。它展示了豆荚的许多特性,其中大多数都在其他主题中讨论过,因此只在这里简单地提到过:

Pods对象定义(YAML)

apiVersion: v1
kind: Pod
metadata:
  annotations: { ... }
  labels:                                
    deployment: docker-registry-1
    deploymentconfig: docker-registry
    docker-registry: default
  generateName: docker-registry-1-       
spec:
  containers:                            
  - env:                                 
    - name: OPENSHIFT_CA_DATA
      value: ...
    - name: OPENSHIFT_CERT_DATA
      value: ...
    - name: OPENSHIFT_INSECURE
      value: "false"
    - name: OPENSHIFT_KEY_DATA
      value: ...
    - name: OPENSHIFT_MASTER
      value: https://master.example.com:8443
    image: openshift/origin-docker-registry:v0.6.2 
    imagePullPolicy: IfNotPresent
    name: registry
    ports:                              
    - containerPort: 5000
      protocol: TCP
    resources: {}
    securityContext: { ... }            
    volumeMounts:                       
    - mountPath: /registry
      name: registry-storage
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: default-token-br6yz
      readOnly: true
  dnsPolicy: ClusterFirst
  imagePullSecrets:
  - name: default-dockercfg-at06w
  restartPolicy: Always
  serviceAccount: default               
  volumes:                              
  - emptyDir: {}
    name: registry-storage
  - name: default-token-br6yz
    secret:
      secretName: default-token-br6yz
  • labels 可以使用一个或多个标签对Pods进行“标记”,这样就可以在单个操作中选择和管理组的组。标签以键/值格式存储在元数据散列中。本例中的一个标签是docker-registry=default。

  • Pods必须在其命名空间中具有唯一的名称。pod定义可以使用generateName属性指定名称的基础,并且将自动添加随机字符以生成惟一的名称。

  • containers指定一组容器定义;在这种情况下(和大多数情况一样),只有一个。

  • env 可以指定环境变量,以便将必要的值传递给每个容器。

  • pod中的每个容器都由其自己的docker格式的容器镜像像实例化

  • 容器可以绑定到在pod的IP上可用的端口。

  • OpenShift容器平台定义了容器的security context,这些容器指定了是否允许它们作为特权容器运行,作为用户的选择运行,等等。缺省上下文是非常严格的,但是管理员可以根据需要修改它。

  • 容器指定在容器内装入外部存储卷的位置。在这种情况下,有一个存储注册表数据的卷,一个用于访问注册表需要的凭证,用于对OpenShift容器平台API发出请求。

  • 对OpenShift容器平台API发出请求的pod是一个常见的模式,其中有一个serviceAccount字段,用于指定在发出请求时应该对哪些服务帐户用户进行身份验证。这为定制的基础结构组件提供了细粒度的访问控制。

  • pod定义了可供使用的容器(s)的存储卷。在这种情况下,它为注册中心存储和包含服务帐户凭证的secret卷提供了一个临时卷。

这里写图片描述这个pod定义不包括在创建了pod之后自动打开的OpenShift容器平台和它的生命周期开始的属性。Kubernetes API文档有关于pod REST API对象属性的完整细节,Kubernetes pod文档有关于pod的功能和用途的详细信息。

Init Containers(初始化容器)

init容器是pod中的一个容器,在pod应用程序容器启动之前启。Init容器可以共享卷,执行网络操作,并在剩余的容器开始之前执行计算。Init容器还可以阻塞或延迟应用程序容器的启动,直到满足某些先决条件。

当一个pod开始时,在网络和卷初始化之后,初始化的容器将按顺序启动。每个init容器必须在调用next之前成功退出。如果一个init容器不能启动(由于运行时)或失败退出,则会根据pod restartPolicy进行重试。

  • Always-不断地重新启动,用一个指数延迟的延迟(10、20、40),直到重新启动。
  • Never -不要试图重新开始。pods马上就会失败并退出。
  • OnFailure - 尝试以指数延迟延迟(10、20、40)来重新启动,在5分钟内结束。

直到所有的init容器成功,一个pod才能完成。

有关一些init容器使用示例,请参阅Kubernetes文档。

下面的示例概述了一个简单的pod,它有两个init容器。第一个init容器等待myservice,第二个等待mydb。一旦两个容器成功,pod就启动了。

样例Init容器Pod对象定义(YAML)

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
spec:
  containers:
  - name: myapp-container
    image: busybox
    command: ['sh', '-c', 'echo The app is running! && sleep 3600']
  initContainers:
  - name: init-myservice 
    image: busybox
    command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;']
  - name: init-mydb 
    image: busybox
    command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']
  • initContainers name:init-myservice 指定myservice容器。
  • initContainers name:init-mydb 指定mydb容器。

每个init容器都有一个应用程序容器的所有字段,除了readinessProbe之外。初始化容器必须退出,才能继续运行,不能定义是否准备就绪。

Init容器可以包括在容器上的activelineseconds和容器上的livenessProbe,以防止Init容器永远失败。活跃的最后期限包括初始化容器。

Services(服务)

Kubernetes服务是一个内部负载平衡器。它识别一组复制的Pods,以代理它接收到的连接。在服务保持一致的情况下,可以随意地从服务中添加或从服务中删除备份,从而使任何依赖于服务的服务在一致的地址中引用它。默认的服务clusterIP地址来自OpenShift容器平台内部网络,它们被用于允许pods访问彼此。

为了允许外部访问服务,可以将外部集群的externalIPingressIP地址分配给服务。这些externalIP也可以是虚拟IP地址,提供了对服务的高可用性访问。

服务被分配一个IP地址和端口,当被访问时,代理到一个适当的支持pod。一个服务使用标签选择器来查找所有运行的容器,这些容器在特定的端口上提供特定的网络服务。

与pods一样,服务是REST对象。下面的示例展示了上面定义的pod服务的定义:

服务对象定义(YAML)

apiVersion: v1
kind: Service
metadata:
  name: docker-registry      
spec:
  selector:                  
    docker-registry: default
  portalIP: 172.30.136.123   
  ports:
  - nodePort: 0
    port: 5000               
    protocol: TCP
    targetPort: 5000    
  • metadata name : 服务名称docker-registry还用于构造一个环境变量,该环境变量将被插入到相同名称空间中的其他pod中。最大的名称长度是63个字符。
  • selector docker-registry : 标签选择器识别所有带有docker-registry=default标签的pod,作为它的支持。
  • portalIP : 服务的虚拟IP,从一个内部IP池中自动分配。
  • ports port : 服务端口监听。
  • targetPort : 支持pod上服务转发连接的端口。

Kubernetes文档有更多关于服务的信息。

Service externalIPs

除了集群的内部IP地址外,用户还可以配置集群外部的IP地址。管理员负责确保流量到达一个具有该IP的节点。

externalIPs必须由集群管理员从ExternalIPNetworkCIDRs范围中选择配置到master-config.yaml 文件。当master-config.yaml更改了,主服务必须重新启动。

示例ExternalIPNetworkCIDR /etc/origin/master/master-config.yaml

networkConfig:
  ExternalIPNetworkCIDR: 172.47.0.0/24

服务externalIPs定义(JSON)

{
    "kind": "Service",
    "apiVersion": "v1",
    "metadata": {
        "name": "my-service"
    },
    "spec": {
        "selector": {
            "app": "MyApp"
        },
        "ports": [
            {
                "name": "http",
                "protocol": "TCP",
                "port": 80,
                "targetPort": 9376
            }
        ],
        "externalIPs" : [
            "80.11.12.10"         
        ]
    }
}
  • externalIPs : 端口被公开的外部IP地址列表。除了内部IP地址外)

Service ingressIPs

在非云集群中,外部地址可以从一个地址池中自动分配。这就消除了管理员手动分配它们的需要。

/etc/origin/master/master-config池配置。yaml文件。更改此文件后,重新启动主服务。

默认情况下,ingressIPNetworkCIDR设置为172.29.0.0/16。如果集群环境还没有使用这个私有范围,那么可以使用默认范围或者设置一个自定义范围。

这里写图片描述如果您使用的是 high availability,那么这个范围必须小于256个地址。

示例ingressIPNetworkCIDR /etc/origin/master/master-config.yaml

networkConfig:
  ingressIPNetworkCIDR: 172.29.0.0/16

Service NodePort

设置服务type=NodePort将从一个标记配置的范围分配一个端口(默认为:30000-32767),每个节点将把该端口(每个节点上的相同端口号)代理到您的服务中。

选择的端口将在服务配置中记录,在 spec.ports[*].nodePort.中。

要指定一个自定义端口,只需将端口号放到nodePort字段中。这个自定义端口号必须在节点端口的配置范围内。当master-config.yaml更改了,主服务必须重新启动。

示例servicesNodePortRange /etc/origin/master/master-config.yaml

kubernetesMasterConfig:
  servicesNodePortRange: ""

服务将在:spec.ports[].nodePortspec.clusterIp:spec.ports[].port 两个方面都可见

这里写图片描述设置一个nodePort是一个特权操作。

Service Proxy Mode(服务代理模式)

OpenShift容器平台有两种不同的服务路由基础设施。默认的实现完全是基于ip的,并且使用概率iptables重写规则来在端点之间分配传入的服务连接。旧的实现使用一个用户空间过程来接受传入的连接,然后在客户端和端点的一个端点之间代理通信。

基于ip的实现要高效得多,但它要求所有端点都能够接受连接;用户空间实现比较慢,但是可以尝试多个端点,直到找到一个有效的端点。如果您有良好的准备检查(或通常可靠的节点和pods),那么基于ip的服务代理是最佳选择。否则,您可以在安装时启用用户空间的代理,或者通过编辑节点配置文件来部署集群。

Labels(标签)

标签用于组织、组或选择API对象。例如,pods被标签“标记”,然后服务使用标签选择器来识别它们所代理的Pods。这使得服务可以引用组群,甚至可以将可能不同的容器作为相关实体对待。

大多数对象都可以在元数据中包含标签。因此,标签可以用来对任意相关的对象进行分组;例如,所有的pods、服务、复制控制器和特定应用程序的部署配置都可以被分组。

标签是简单的键/值对,如下面的例子:

labels:
  key1: value1
  key2: value2

Consider:

  • 一个由nginx容器组成的pod,带有标签role=webserver。
  • 一个由Apache httpd容器组成的pod,具有相同的标签 role=webserver。

定义为使用role=webserver标签的服务或复制控制器将这两个类作为同一组的一部分。

Kubernetes文档有更多关于标签的信息。

Endpoints(端点)

支持服务的服务器称为其端点,并且由具有与服务相同名称的类型Endpoints 的对象指定。当服务由pods支持时,服务规范中通常由标签选择器指定这些pods,而OpenShift容器平台会自动创建指向这些pods的端点对象。

在某些情况下,您可能想要创建一个服务,但它是由外部主机支持的,而不是在OpenShift容器平台集群中的pods。在这种情况下,您可以在服务中省去 selector 字段,并手动创建端点对象

请注意,OpenShift容器平台不会让大多数用户手动创建一个端点对象,该对象指向为pod和服务IP预留的网络块中的IP地址。只有集群管理员或其他允许在endpoints/restricted下创建资源的用户才能创建这样的端点对象。

Projects and Users(项目和用户)

Users(用户)

与OpenShift容器平台的交互是与用户相关联的。一个OpenShift容器平台用户对象表示一个参与者,通过向他们或他们的组添加角色,可以获得系统中的权限。

有几种类型的用户可以存在:

用户描述
Regular users这是大多数交互式的OpenShift容器平台用户将被表示的方式。在第一次登录时,系统会自动创建常规用
户,也可以通过API创建。常规用户用User对象表示。例如:joe alice
System users其中许多是在定义基础设施时自动创建的,主要目的是为了使基础设施能够安全地与API交互。它们包括
集群管理员(可以访问所有的内容)、每个节点用户、路由器和注册中心使用的用户以及其他各种各样的用
户。最后,还有一个匿名的系统用户,默认情况下使用的是未经过身份验证的请求。
例如:system:admin system:openshift-registry system:node:node1.example.com
Service accounts这些是与项目相关的特殊系统用户;有些是在项目第一次创建时自动创建的,而项目管理员可以为定义每
个项目内容的访问而创建更多的内容。服务帐户用ServiceAccount对象表示。
例如: system:serviceaccount:default:deployer system:serviceaccount:foo:builder



为了访问OpenShift容器平台,每个用户都必须以某种方式进行身份验证。没有身份验证或无效身份验证的API请求通过匿名系统用户的请求进行身份验证。一旦通过身份验证,策略将决定用户的权限。

Namespaces(命名空间)

Kubernetes命名空间为集群中的资源提供了一种机制。在OpenShift容器平台中,一个项目是Kubernetes命名空间,带有额外的注释。

命名空间提供了一个惟一的范围:

  • 命名资源以避免基本命名冲突。
  • 将管理权限委托给受信任的用户。
  • 限制社区资源消耗的能力。

系统中的大多数对象都是由命名空间限定的,但是有些对象是例外的,并且没有命名空间,包括节点和用户。

Kubernetes文档有关于名称空间的更多信息。

Projects(项目)

一个project是Kubernetes带有附加注释的命名空间,,并且是管理普通用户的资源的中心工具。一个project允许用户社区在与其他社区隔离的情况下组织和管理他们的内容。用户必须获得管理员的访问权限,或者如果允许创建项目,就可以自动访问他们自己的项目。

项目可以有单独的 name, displayName, 和 description

  • 强制name是项目的唯一标识符,在使用CLI工具或API时最可见。最大的名称长度是63个字符。
  • 可选的displayName是项目在web控制台中显示的方式(默认为名称)。
  • 可选的description可以是一个更详细的项目描述,并且在web控制台中也可以看到。

每个项目都有自己的一套:

对象描述
Objectspods、service、复制控制器等等。
Policies(策略)用户可以或不能在对象上执行操作的规则。
Constraints(约束)可以限制每种对象的配额。
Service accounts服务帐户自动在项目中指定访问对象。



集群管理员可以创建项目,并将该项目的管理权限委托给用户社区的任何成员。集群管理员还可以允许开发人员创建自己的项目


Builds and Image Streams(构建和镜像流)

Builds(构建)

构建是将输入参数转换为结果对象的过程。通常,该过程用于将输入参数或源代码转换为可运行的镜像。BuildConfig对象是整个构建过程的定义。

OpenShift容器平台利用Kubernetes,从构建镜像中创建docker格式的容器,并将其推到容器注册中心

构建对象具有共同的特征:构建的输入、完成构建过程的需要、记录构建过程、从成功构建中发布资源,以及发布构建的最终状态。构建利用资源限制,指定对资源的限制,例如CPU使用、内存使用和构建或pod执行时间。

OpenShift容器平台构建系统为基于构建API中指定的可选择类型的构建策略提供了可扩展的支持。有三种主要的构建策略:

默认情况下,Docker构建和S2I构建得到了支持。

构建的结果对象依赖于创建它的构建器。对于Docker和S2I构建,生成的对象是可运行的镜像。对于自定义构建,生成的对象是构建器镜像创建者指定的任何对象。

此外,Pipeline build 策略可以用于实现复杂的工作流:

  • continuous integration(持续集成)
  • continuous deployment(持续部署)

对于构建命令的列表,请参阅开发人员的指南

有关OpenShift容器平台如何利用Docker进行构建的更多信息,请参阅上游文档

Docker Build

Docker构建策略将调用Docker构建命令,因此它希望拥有一个Dockerfile和所有必需的构件来生成一个可运行的镜像。

Source-to-Image (S2I) Build

源到镜像(S2I)是一种用于构建可复制的、docker格式的容器镜像的工具。它通过向容器镜像中注入应用程序源并装配新镜像来生成可立即运行的镜像。新镜像合并了基本镜像(构建器)和构建源代码,并准备使用docker run命令。S2I支持增量构建,它重用以前下载的依赖项、以前构建的构件等。

S2I的优势包括以下内容:

优势描述
Image flexibility(镜像的灵活性)可以编写S2I脚本,将应用程序代码注入到几乎所有现有的docker格式的容器镜像中,
利用现有的生态系统。请注意,目前S2I依赖tar来注入应用程序源代码,因此镜像需要
能够处理被压缩的内容。
Speed(速度)使用S2I,组装过程可以执行大量复杂操作,而不需要在每个步骤中创建一个新层,从而
形成一个快速流程。另外,可以编写S2I脚本以重用存储在应用程序镜像的前一个版本中
的工件,而不是每次运行构建时都必须下载或构建它们。
Patchability(打补丁性能)S2I允许您始终如一地重新构建应用程序,如果底层镜像需要一个安全问题的补丁。
Operational efficiency
(运行效率)
通过限制构建操作,而不是像Dockerfile所允许的那样允许任意的操作,PaaS操作符
可以避免构建系统的意外或故意的滥用。
Operational security(运行安全)构建任意的Dockerfile会公开主机系统以使特权升级。这可能会被恶意用户利用,因为
整个Docker构建过程都是由Docker特权用户运行的。S2I限制作为根用户执行的操作,
并可以将脚本作为非根用户运行。
User efficiency
(最终用户的效率)
S2I阻止开发人员执行任意的yum install类型操作,在他们的应用程序构建过程中,这可
能会降低开发迭代的速度。
Ecosystem(生态系统)S2I鼓励一个共享的镜像生态系统,在这个生态系统中,您可以为您的应用程序使用最佳
实践。
Reproducibility(再生性)生成的镜像可以包括所有的输入,包括构建工具的特定版本和依赖项。这确保了镜像可以被精确地复制。

Custom Build

自定义构建策略允许开发人员定义一个负责整个构建过程的特定构建器镜像。使用您自己的构建器镜像可以定制您的构建过程。

一个自定义构建器镜像是一个简单的docker格式的容器镜像,嵌入了构建流程逻辑,例如用于构建rpm或基本镜像。在Docker Hub registry中,可以使用openshift/origin-custom-docker-builder 镜像作为自定义构建器镜像的示例实现。

Pipeline Build

管道构建策略允许开发人员为Jenkins管道插件定义一个Jenkins管道。构建可以由OpenShift容器平台启动、监控和管理,与任何其他构建类型一样。

管道工作流是在一个Jenkinsfile中定义的,要么直接嵌入到构建配置中,要么在Git存储库中提供,并由构建配置引用。

第一次项目使用管道策略定义构建配置时,OpenShift容器平台实例化一个Jenkins服务器来执行管道。后续的管道构建配置在项目中共享这个Jenkins服务器。

有关如何部署Jenkins服务器的更多细节,以及如何配置或禁用自动访问行为,请参阅Configuring Pipeline Execution

这里写图片描述即使所有管道构建配置都被删除,Jenkins服务器也不会被自动删除。它必须由用户手动删除。

有关 Jenkins Pipelines的更多信息,请参阅 Jenkins文档

Image Streams

镜像流包含由标记标识的任意数量的docker格式化的容器镜像。它提供了一个关于相关镜像的单一虚拟视图,类似于一个镜像存储库,并且可能包含以下的镜像:

  • 在OpenShift容器平台的集成注册表中,它自己的镜像存储库
  • 其他镜像流
  • 外部注册中心的镜像存储库

镜像流可以用于在创建新镜像时自动执行操作。构建和部署可以通过分别执行构建或部署,在添加新镜像时接收通知并接收通知。对于一组精选的镜像,请参阅OpenShift镜像流和模板库

例如,如果一个部署正在使用某个镜像,并且创建了该镜像的新版本,那么可以自动执行部署。

这里写图片描述有关管理镜像和镜像流的详细信息,请参见开发人员指南

镜像流对象定义

apiVersion: v1
kind: ImageStream
metadata:
  annotations:
    openshift.io/generated-by: OpenShiftNewApp
  creationTimestamp: 2016-01-29T13:33:49Z
  generation: 1
  labels:
    app: ruby-sample-build
    template: application-template-stibuild
  name: origin-ruby-sample
  namespace: test
  resourceVersion: "633"
  selflink: /oapi/v1/namespaces/test/imagestreams/origin-ruby-sample
  uid: ee2b9405-c68c-11e5-8a99-525400f25e34
spec: {}
status:
  dockerImageRepository: 172.30.56.218:5000/test/origin-ruby-sample
  tags:
  - items:
    - created: 2016-01-29T13:40:11Z
      dockerImageReference: 172.30.56.218:5000/test/origin-ruby-sample@sha256:47463d94eb5c049b2d23b03a9530bf944f8f967a0fe79147dd6b9135bf7dd13d
      generation: 1
      image: sha256:47463d94eb5c049b2d23b03a9530bf944f8f967a0fe79147dd6b9135bf7dd13d
    tag: latest

Image Stream Image

一个镜像流镜像是一个虚拟资源,它允许您从一个特定的镜像流中检索一个被标记的镜像。它通常被缩写为isimage。它由两个部分组成,由一个at符号分隔:<image stream name>@<image name>。要引用上面的示例中的镜像,isimage看起来是这样的:

origin-ruby-sample@sha256:47463d94eb5c049b2d23b03a9530bf944f8f967a0fe79147dd6b9135bf7dd13d

用户未经允许在集群级别上阅读或列出镜像,仍然可以检索在他们有权使用该资源的项目中标记的镜像。

Image Stream Tag(镜像流标签)

镜像流标记是一个指向镜像流中的镜像的指针。它通常被缩写为istag。它可以引用任何本地或外部管理的镜像。它包含了一个镜像的历史,它被标记为一堆标签所指向的所有镜像。当一个新的或现有的镜像在特定的istag下被标记时,它就被放在历史堆栈的第一个位置。先前占据顶部位置的镜像将在第二个位置上可用。这允许简单的回滚,使标签再次指向历史镜像。

istag是由一个冒号分隔的两个部分组成的:<image stream name>:<tag>。Istag 在上面的示例中指向的image sha256:47463d94eb5c049b2d23b03a9530bf944f8f967a0fe79147dd6b9135bf7dd13d将会是origin-ruby-sample:latest

镜像流标签在其历史上有两个镜像

  tags:
  - items:
    - created: 2016-03-02T10:15:09Z
      dockerImageReference: 172.30.56.218:5000/test/origin-ruby-sample@sha256:909de62d1f609a717ec433cc25ca5cf00941545c83a01fb31527771e1fab3fc5
      generation: 2
      image: sha256:909de62d1f609a717ec433cc25ca5cf00941545c83a01fb31527771e1fab3fc5
    - created: 2016-01-29T13:40:11Z
      dockerImageReference: 172.30.56.218:5000/test/origin-ruby-sample@sha256:47463d94eb5c049b2d23b03a9530bf944f8f967a0fe79147dd6b9135bf7dd13d
      generation: 1
      image: sha256:47463d94eb5c049b2d23b03a9530bf944f8f967a0fe79147dd6b9135bf7dd13d
    tag: latest

Image Stream Mappings(镜像流映射)

当集成注册中心接收到一个新镜像时,它将创建并发送一个ImageStreamMapping 到OpenShift容器平台,提供镜像的命名空间(即:它的项目)、名称、标记和镜像元数据。

此信息用于创建新镜像(如果它还不存在),并将镜像标记为镜像流。OpenShift容器平台存储关于每个镜像的完整元数据,例如命令、入口点和环境变量。OpenShift容器平台中的镜像是不可变的,最大长度是63个字符。

这里写图片描述有关手动标记镜像的详细信息,请参见开发人员指南

下面的imagestreamMapping示例结果将被标记为test/origin-ruby-sample:latest:

镜像流映射对象定义

apiVersion: v1
kind: ImageStreamMapping
metadata:
  creationTimestamp: null
  name: origin-ruby-sample
  namespace: test
tag: latest
image:
  dockerImageLayers:
  - name: sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef
    size: 0
  - name: sha256:ee1dd2cb6df21971f4af6de0f1d7782b81fb63156801cfde2bb47b4247c23c29
    size: 196634330
  - name: sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef
    size: 0
  - name: sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef
    size: 0
  - name: sha256:ca062656bff07f18bff46be00f40cfbb069687ec124ac0aa038fd676cfaea092
    size: 177723024
  - name: sha256:63d529c59c92843c395befd065de516ee9ed4995549f8218eac6ff088bfa6b6e
    size: 55679776
  - name: sha256:92114219a04977b5563d7dff71ec4caa3a37a15b266ce42ee8f43dba9798c966
    size: 11939149
  dockerImageMetadata:
    Architecture: amd64
    Config:
      Cmd:
      - /usr/libexec/s2i/run
      Entrypoint:
      - container-entrypoint
      Env:
      - RACK_ENV=production
      - OPENSHIFT_BUILD_NAMESPACE=test
      - OPENSHIFT_BUILD_SOURCE=https://github.com/openshift/ruby-hello-world.git
      - EXAMPLE=sample-app
      - OPENSHIFT_BUILD_NAME=ruby-sample-build-1
      - PATH=/opt/app-root/src/bin:/opt/app-root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
      - STI_SCRIPTS_URL=image:///usr/libexec/s2i
      - STI_SCRIPTS_PATH=/usr/libexec/s2i
      - HOME=/opt/app-root/src
      - BASH_ENV=/opt/app-root/etc/scl_enable
      - ENV=/opt/app-root/etc/scl_enable
      - PROMPT_COMMAND=. /opt/app-root/etc/scl_enable
      - RUBY_VERSION=2.2
      ExposedPorts:
        8080/tcp: {}
      Labels:
        build-date: 2015-12-23
        io.k8s.description: Platform for building and running Ruby 2.2 applications
        io.k8s.display-name: 172.30.56.218:5000/test/origin-ruby-sample:latest
        io.openshift.build.commit.author: Ben Parees <bparees@users.noreply.github.com>
        io.openshift.build.commit.date: Wed Jan 20 10:14:27 2016 -0500
        io.openshift.build.commit.id: 00cadc392d39d5ef9117cbc8a31db0889eedd442
        io.openshift.build.commit.message: 'Merge pull request #51 from php-coder/fix_url_and_sti'
        io.openshift.build.commit.ref: master
        io.openshift.build.image: centos/ruby-22-centos7@sha256:3a335d7d8a452970c5b4054ad7118ff134b3a6b50a2bb6d0c07c746e8986b28e
        io.openshift.build.source-location: https://github.com/openshift/ruby-hello-world.git
        io.openshift.builder-base-version: 8d95148
        io.openshift.builder-version: 8847438ba06307f86ac877465eadc835201241df
        io.openshift.expose-services: 8080:http
        io.openshift.s2i.scripts-url: image:///usr/libexec/s2i
        io.openshift.tags: builder,ruby,ruby22
        io.s2i.scripts-url: image:///usr/libexec/s2i
        license: GPLv2
        name: CentOS Base Image
        vendor: CentOS
      User: "1001"
      WorkingDir: /opt/app-root/src
    Container: 86e9a4a3c760271671ab913616c51c9f3cea846ca524bf07c04a6f6c9e103a76
    ContainerConfig:
      AttachStdout: true
      Cmd:
      - /bin/sh
      - -c
      - tar -C /tmp -xf - && /usr/libexec/s2i/assemble
      Entrypoint:
      - container-entrypoint
      Env:
      - RACK_ENV=production
      - OPENSHIFT_BUILD_NAME=ruby-sample-build-1
      - OPENSHIFT_BUILD_NAMESPACE=test
      - OPENSHIFT_BUILD_SOURCE=https://github.com/openshift/ruby-hello-world.git
      - EXAMPLE=sample-app
      - PATH=/opt/app-root/src/bin:/opt/app-root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
      - STI_SCRIPTS_URL=image:///usr/libexec/s2i
      - STI_SCRIPTS_PATH=/usr/libexec/s2i
      - HOME=/opt/app-root/src
      - BASH_ENV=/opt/app-root/etc/scl_enable
      - ENV=/opt/app-root/etc/scl_enable
      - PROMPT_COMMAND=. /opt/app-root/etc/scl_enable
      - RUBY_VERSION=2.2
      ExposedPorts:
        8080/tcp: {}
      Hostname: ruby-sample-build-1-build
      Image: centos/ruby-22-centos7@sha256:3a335d7d8a452970c5b4054ad7118ff134b3a6b50a2bb6d0c07c746e8986b28e
      OpenStdin: true
      StdinOnce: true
      User: "1001"
      WorkingDir: /opt/app-root/src
    Created: 2016-01-29T13:40:00Z
    DockerVersion: 1.8.2.fc21
    Id: 9d7fd5e2d15495802028c569d544329f4286dcd1c9c085ff5699218dbaa69b43
    Parent: 57b08d979c86f4500dc8cad639c9518744c8dd39447c055a3517dc9c18d6fccd
    Size: 441976279
    apiVersion: "1.0"
    kind: DockerImage
  dockerImageMetadataVersion: "1.0"
  dockerImageReference: 172.30.56.218:5000/test/origin-ruby-sample@sha256:47463d94eb5c049b2d23b03a9530bf944f8f967a0fe79147dd6b9135bf7dd13d

Deployments(部署)

Replication Controllers(复制控制器)

复制控制器确保一个特定的pod副本的数量在任何时候都在运行。如果pods退出或被删除,复制控制器就会对已定义的数字进行更多的实例化。同样地,如果有更多的运行超出了预期,那么它就会删除所需的数量,以匹配所定义的数量。

复制控制器配置包括:

  • 所需的副本数量(可以在运行时进行调整)。
  • 在创建一个复制的pod时使用的一个pod定义。
  • 用于标识托管的pod的选择器。

选择器是分配给由复制控制器管理的pod的一组标签。这些标签包含在复制控制器实例化的pod定义中。复制控制器使用选择器来确定已经运行了多少个pod的实例,以便根据需要进行调整。

复制控制器不执行基于负载或流量的自动伸缩,因为它也不跟踪。相反,这需要通过外部自动扩展器来调整其副本计数。

复制控制器是一个核心的Kubernetes对象,称为ReplicationController

下面是一个示例复制控制器定义:

apiVersion: v1
kind: ReplicationController
metadata:
  name: frontend-1
spec:
  replicas: 1  
  selector:    
    name: frontend
  template:    
    metadata:
      labels:  
        name: frontend 
    spec:
      containers:
      - image: openshift/hello-openshift
        name: helloworld
        ports:
        - containerPort: 8080
          protocol: TCP
      restartPolicy: Always
  • replicas: 要运行的pod的拷贝数。
  • selector: 要运行的pod的标签选择器。
  • template: 控制器创建的pod的模板。
  • labels: pod上的标签应该包括标签选择器的标签。
  • name:frontend 扩展任何参数后的最大名称长度是63个字符。

Jobs(作业)

作业类似于复制控制器,其目的是为了特定的原因创建pod。不同的是,复制控制器是为连续运行的pods设计的,而任务是一次性的。一份工作追踪任何成功的完成,当完成了指定的完成数量之后,工作本身就完成了。

下面的例子计算到2000 这个位置,打印出来,然后完成:

apiVersion: extensions/v1
kind: Job
metadata:
  name: pi
spec:
  selector:
    matchLabels:
      app: pi
  template:
    metadata:
      name: pi
      labels:
        app: pi
    spec:
      containers:
      - name: pi
        image: perl
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never

有关如何使用作业的更多信息,请参见job主题。

Deployments and Deployment Configurations(部署和部署配置)

在复制控制器的基础上,OpenShift容器平台使用部署的概念为软件开发和部署生命周期添加了扩展的支持。在最简单的情况下,部署只是创建一个新的复制控制器,并让它启动pods。不过,OpenShift容器平台部署也提供了从现有的镜像部署到新版本的能力,并定义了在创建复制控制器之前或之后运行的钩子。

OpenShift容器平台DeploymentConfiguration对象定义了以下部署的详细信息:

  • 复制控制器定义的元素。
  • 自动创建新部署的触发器。
  • 部署之间的转换策略。
  • 生命周期的钩子。

每当一个部署被触发,无论是手动还是自动地,部署人员都会管理部署(包括缩减旧的复制控制器,扩展新版本,并运行钩子)。部署pod在完成部署之后,将保持在不确定的时间内,以保留部署的日志。当一个部署被另一个取代时,将保留先前的复制控制器,以便在需要时启用简单的回滚。

或者关于如何创建和与部署进行交互的详细说明,请参阅 Deployments

下面是一个示例部署配置定义,其中有一些遗漏和调用:

apiVersion: v1
kind: DeploymentConfig
metadata:
  name: frontend
spec:
  replicas: 5
  selector:
    name: frontend
  template: { ... }
  triggers:
  - type: ConfigChange 
  - imageChangeParams:
      automatic: true
      containerNames:
      - helloworld
      from:
        kind: ImageStreamTag
        name: hello-openshift:latest
    type: ImageChange  
  strategy:
    type: Rolling      
  • type: ConfigChange       当复制控制器模板改变时,一个ConfigChange触发器就会创建一个新的部署。
  • type: ImageChange       在命名镜像流中可以看到一个新的版本的支持镜像,一个ImageChange触发器会创建一个新的部署。
  • type:Rolling       默认的滚动策略可以在部署之间进行无时间的转换。





Logo

开源、云原生的融合云平台

更多推荐