簡述
下面的主題提供了在使用OpenShift容器平臺時將遇到的核心概念和對象的高級、體系結構信息。這些對象中的許多都來自於Kubernetes,它由OpenShift容器平臺擴展,以提供一個功能更豐富的開發生命週期平臺。
Containers and images 是部署應用程序的構建塊。
Pods and services允許容器相互通信和代理連接。
Projects and users爲社區提供了組織和管理他們的內容的空間和手段。
Builds and image streams允許您構建工作鏡像並對新鏡像做出反應。
Deployments 增加了對軟件開發和部署生命週期的支持。
Routes 會向世界宣佈你的服務。
Templates允許根據定製的參數一次性創建多個對象
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訪問彼此。
爲了允許外部訪問服務,可以將外部集羣的externalIP 和ingressIP地址分配給服務。這些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[].nodePort 和 spec.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控制檯中也可以看到。
每個項目都有自己的一套:
對象 | 描述 |
---|---|
Objects | pods、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 <[email protected]>
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 默認的滾動策略可以在部署之間進行無時間的轉換。