关于OKD(OpenShift)中组件资源介绍和命令行操作的一些笔记

傍晚时分,你坐在屋檐下,看着天慢慢地黑下去,心里寂寞而凄凉,感到自己的生命被剥夺了。当时我是个年轻人,但我害怕这样生活下去,衰老下去。在我看来,这是比死亡更可怕的事。——–王小波

写在前面


  • 因为参加考试,会陆续分享一些 OpenShift 的笔记
  • 博文内容为 openshift 常见 API 资源对象介绍,包括所特有的 Route,IS,DC,BC 等。
  • 学习环境为 openshift v3 的版本,有些旧
  • 这里如果专门学习 openshift ,建议学习 v4 版本
  • 理解不足小伙伴帮忙指正

傍晚时分,你坐在屋檐下,看着天慢慢地黑下去,心里寂寞而凄凉,感到自己的生命被剥夺了。当时我是个年轻人,但我害怕这样生活下去,衰老下去。在我看来,这是比死亡更可怕的事。——–王小波


核心组件

OpenShift的核心组件及其之间的关联关系如图所示。

在这里插入图片描述

OpenShift在容器编排层使用了Kubernetes,所以OpenShift在架构上和Kubernetes十分接近。其内部的许多组件和概念是从Kubernetes衍生而来,但是也存在一些在容器编排层之上,OpenShift特有的组件和概念。

  • Master节点:即主控节点。集群内的管理组件均运行于Master节点之上。Master节点负责管理和维护OpenShift集群的状态。
  • Node节点:即计算节点。集群内的容器实例均运行于Node节点之上。

Master节点

在Master节点上运行了众多集群的服务组件:

  • API Server。负责提供集群的Web Console以及RESTfulAPI服务。集群内的所有Node 节点都会访问API Server更新各节点的状态及其上运行的容器的状态。
  • 数据源(Data Store)。集群所有动态的状态信息都会存储在后端的一个etcd分布式数据库中。默认的etcd实例安装在Master节点上。如有需要,也可以将etcd节点部署在集群之外。
  • 调度控制器(Scheduler)。调度控制器在容器部署时负责按照用户输入的要求寻找合适的计算节点。
  • 控制器管理( Controller)。对容器云而言,一个很重要的特性是异常自恢复。

Node节点

在Node节点上没有这么多系统组件,其主要职责就是接收Master节点的指令,运行和维护Docker容器。

这里要指出的是,Master节点本身也是一个Node节点,只是在一般环境中会将其运行容器的功能关闭。下面的这个实验集群中,由于只有一个节点,所以这个Master节点也必须承担运行容器的责任。也作为一个 Node节点存在。

1
2
3
4
┌──[root@192.168.26.16]-[~/openshift-origin-server-v3.11.0-0cbc58b-linux-64bit]
└─$oc get nodes
NAME STATUS ROLES AGE VERSION
localhost Ready <none> 9h v1.11.0+d4cacc0

查看节点详细信息

1
2
3
4
5
6
7
8
9
10
11
┌──[root@192.168.26.16]-[~/openshift-origin-server-v3.11.0-0cbc58b-linux-64bit]
└─$oc describe nodes localhost
Name: localhost
Roles: <none>
Labels: beta.kubernetes.io/arch=amd64
beta.kubernetes.io/os=linux
kubernetes.io/hostname=localhost
Annotations: volumes.kubernetes.io/controller-managed-attach-detach=true
CreationTimestamp: Sat, 28 May 2022 16:25:29 +0800
Taints: <none>
Unschedulable: false

资源对象

在 OpenShift 中,一些独特的资源对象包括:

  • BuildConfig:该对象定义如何从源代码构建应用程序。
  • DeploymentConfig:该对象定义如何将应用程序部署到集群中。
  • ImageStream:该对象表示容器镜像的集合。
  • Route:该对象在主机名上公开服务,类似于 URL。
  • Template:该对象定义按特定顺序创建一组对象。

下面我们来看下这些 对象

Project 与 Namespace

Openshift 中每一个 Project 会和一个 Namespace 相关联,甚至可以简单地认为,Project 就是 Namespace。所以在 OpenShift 中进行操作时,首先要确认当前执行的上下文是哪一个 Project。

1
2
3
┌──[root@192.168.26.16]-[~/openshift-origin-server-v3.11.0-0cbc58b-linux-64bit]
└─$oc project
Using project "myproject" on server "https://127.0.0.1:8443".

查看所有的 项目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
┌──[root@192.168.26.16]-[~/openshift-origin-server-v3.11.0-0cbc58b-linux-64bit]
└─$oc get project
NAME DISPLAY NAME STATUS
default Active
kube-dns Active
kube-proxy Active
kube-public Active
kube-system Active
myproject My Project Active
openshift Active
openshift-apiserver Active
openshift-controller-manager Active
openshift-core-operators Active
openshift-infra Active
openshift-node Active
openshift-service-cert-signer Active
openshift-web-console Active
┌──[root@192.168.26.16]-[~/openshift-origin-server-v3.11.0-0cbc58b-linux-64bit]
└─$oc project kube-system
Now using project "kube-system" on server "https://127.0.0.1:8443".

Pod

在 Openshift 中,Pod 是最小的可部署单元。Pod 是一个或多个容器的集合,它们共享网络和存储资源,并在同一节点上运行。Pod 通常用于运行一个应用程序或一组相关的应用程序。

Pod 可以被视为一个逻辑主机,它可以包含一个或多个容器。这些容器共享相同的网络命名空间和存储卷。Pod 中的容器可以通过 localhost 相互通信,而不需要使用网络地址转换(NAT)。

在 Openshift 中,Pod 具有以下作用:

  • 提供一个抽象层,使应用程序可以独立于底层基础设施运行。
  • 管理容器的生命周期,包括启动、停止和重启容器。
  • 共享网络和存储资源,使容器之间可以相互通信和共享数据。
  • 提供一个稳定的 IP 地址和 DNS 名称,使其他应用程序可以轻松地访问 Pod 中的容器。

以下是一个 Pod 的示例定义:

1
2
3
4
5
6
7
8
9
10
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: nginx
ports:
- containerPort: 80

这个定义创建了一个名为 my-pod 的 Pod,其中包含一个名为 my-container 的容器。该容器使用 nginx 镜像,并将端口 80 暴露给其他容器和外部网络。

查看 Pod 列表

1
2
3
4
5
6
7
┌──[root@192.168.26.16]-[~/openshift-origin-server-v3.11.0-0cbc58b-linux-64bit]
└─$oc get pods
NAME READY STATUS RESTARTS AGE
kube-controller-manager-localhost 1/1 Running 1 9h
kube-scheduler-localhost 1/1 Running 1 9h
master-api-localhost 1/1 Running 2 9h
master-etcd-localhost 1/1 Running 0 9h

查看 pod 调度 IP位置

1
2
3
4
5
6
7
8
9
┌──[root@192.168.26.16]-[~/openshift-origin-server-v3.11.0-0cbc58b-linux-64bit]
└─$oc get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE
kube-controller-manager-localhost 1/1 Running 1 9h 192.168.26.16 localhost <none>
kube-scheduler-localhost 1/1 Running 1 9h 192.168.26.16 localhost <none>
master-api-localhost 1/1 Running 2 9h 192.168.26.16 localhost <none>
master-etcd-localhost 1/1 Running 0 9h 192.168.26.16 localhost <none>
┌──[root@192.168.26.16]-[~/openshift-origin-server-v3.11.0-0cbc58b-linux-64bit]
└─$

查看 Pod 详细信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
┌──[root@192.168.26.16]-[~/openshift-origin-server-v3.11.0-0cbc58b-linux-64bit]
└─$oc describe pods kube-controller-manager-localhost
Name: kube-controller-manager-localhost
Namespace: kube-system
Priority: 0
PriorityClassName: <none>
Node: localhost/192.168.26.16
Start Time: Sat, 28 May 2022 19:28:49 +0800
Labels: openshift.io/component=controllers
openshift.io/control-plane=true
Annotations: kubernetes.io/config.hash=9d8ef32be31e9a6172eb7ab20224f293
kubernetes.io/config.mirror=9d8ef32be31e9a6172eb7ab20224f293
kubernetes.io/config.seen=2022-05-28T08:24:21.737948444Z
kubernetes.io/config.source=file
Status: Running
IP: 192.168.26.16
Containers:
controllers:
Container ID: docker://004de0a22cf05668f1ffb6a2fe2c1ecf7d31f6a7dc985952a491d031a19caa97
Image: openshift/origin-hyperkube:v3.11
Image ID: docker-pullable://openshift/origin-hyperkube@sha256:9cd0f5d23216db62a3a1659e8d07b40721c221779928ce3ae58a1a5ed38e61e8

查看日志

1
2
3
4
5
6
7
┌──[root@192.168.26.16]-[~/openshift-origin-server-v3.11.0-0cbc58b-linux-64bit]
└─$oc logs kube-scheduler-localhost
I0528 15:09:15.474701 1 server.go:126] Version: v1.11.0+d4cacc0
W0528 15:09:15.475558 1 authorization.go:47] Authorization is disabled
W0528 15:09:15.475582 1 authentication.go:55] Authentication is disabled
I0528 15:09:15.475593 1 insecure_serving.go:47] Serving healthz insecurely on [::]:10251
E0528 15:09:15.482479 1 reflector.go:136] k8s.io/client-go/informers/factory.go:130: Failed to list *v1beta1.StatefulSet: Get https://127.0.0.1:8443/apis/apps/v1beta1/statefulsets?limit=500&resourceVersion=0: dial tcp 127.0.0.1:8443: connect: connection refused
1
2
3
4
5
┌──[root@192.168.26.16]-[~/openshift-origin-server-v3.11.0-0cbc58b-linux-64bit]
└─$oc rsh master-api-localhost
sh-4.2# ls
anaconda-post.log bin dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
sh-4.2#

Service

在 Openshift 中,Service 是一种 Kubernetes 资源类型,用于定义一组 Pod 的访问方式。Service 可以将一组 Pod 封装成一个虚拟的服务,提供统一的入口地址,使得其他应用可以通过该地址访问到这组 Pod。

Service 的作用主要有以下几点:

  1. 提供稳定的入口地址:由于 Pod 的 IP 地址是动态分配的,而且 Pod 可能会被频繁地创建和销毁,因此直接使用 Pod 的 IP 地址来访问服务是不可靠的。Service 提供了一个稳定的入口地址,使得其他应用可以通过该地址访问到这组 Pod。
  2. 负载均衡:Service 可以将请求分发到一组 Pod 中的任意一个,从而实现负载均衡的效果。当某个 Pod 处理请求过多时,Service 会自动将请求分发到其他 Pod 上,从而保证整个服务的可用性。
  3. 服务发现:Service 可以通过 Kubernetes 的 DNS 服务,将服务的名称解析为对应的 IP 地址和端口号,从而实现服务发现的功能。其他应用可以通过服务名称来访问服务,而不需要知道具体的 IP 地址和端口号。

在 Openshift 中,可以通过 YAML 文件来定义 Service,例如:

1
2
3
4
5
6
7
8
9
10
11
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- name: http
port: 80
targetPort: 8080

上述 YAML 文件定义了一个名为 my-service 的 Service,它将标签为 app=my-app 的 Pod 封装成一个服务。该服务监听 80 端口,将请求转发到 Pod 的 8080 端口上。

查看指定命名空间的 Pod

1
2
3
4
5
6
7
8
┌──[root@192.168.26.16]-[~/openshift-origin-server-v3.11.0-0cbc58b-linux-64bit]
└─$oc get svc -n default
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
docker-registry ClusterIP 172.30.1.1 <none> 5000/TCP 9h
kubernetes ClusterIP 172.30.0.1 <none> 443/defaultTCP 9h
router ClusterIP 172.30.34.201 <none> 80/TCP,443/TCP,1936/TCP 9h
┌──[root@192.168.26.16]-[~/openshift-origin-server-v3.11.0-0cbc58b-linux-64bit]
└─$

无论后端的Pod实例的数量或地址如何变化,前端的应用只需要访问Service的IP地址,就能连接到正确的后端容器实例。Service起到了代理的作用,在相互依赖的容器应用之间实现了解耦。

1
2
3
4
5
6
┌──[root@192.168.26.16]-[~]
└─$curl 172.30.34.201
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
.......

除了通过IP地址访问Service所指向的服务外,还可以通过域名访问某一个Service。监听在Master上的集群内置DNS服务器会负责解析这个DNS请求。Service域名的格式是

<SERVICE NAME>.<PROJECT NAME>.svc.cluster.local

看一个解析 Demo

1
2
3
4
5
6
7
8
┌──[root@192.168.26.16]-[~]
└─$kubectl run testpod-1 -it --rm --image=yauritux/busybox-curl --image-pull-policy=IfNotPresent
If you don t see a command prompt, try pressing enter.
/home $ curl hello-openshift.myproject.svc.cluster.local:8080
Hello OpenShift!
/home $ exit
Session ended, resume using 'kubectl attach testpod-1-b4d55675f-54855 -c testpod-1 -i -t' command when the pod is running
deployment.apps "testpod-1" deleted

Router与Route

Service 提供了一个通往后端 Pod 集群的稳定的入口,但是 Service 的 IP 地址只是集群内部的节点及容器可见。对于外部的应用或者用户来说,这个地址是不可达的。那么外面的用户想要访问Service指向的服务应该怎么办呢?

在 k8s 中,提供了 Ingress 相关的API 资源对象来支持,在 Openshift 中 ,提供了 Route API 资源对象来支持,

OpenShift Router

OpenShift Router 是一个基于 HAProxy 的负载均衡器,它负责将外部流量路由到正确的服务。当一个外部用户请求访问 OpenShift 集群中的服务时,请求会先到达 OpenShift Router,然后 OpenShift Router 会根据请求的 URL 和其他信息将请求路由到正确的服务。OpenShift Router 还支持 SSL 终止和 WebSocket 等高级功能。

在 OpenShift 中,每个项目都有一个独立的 Router。这个 Router 会监听一个独立的 IP 地址,并将请求路由到该项目中的服务。如果需要将多个项目中的服务暴露给外部用户,可以使用 OpenShift Router 的 Edge 路由器,它可以将多个项目中的服务通过同一个 IP 地址暴露给外部用户。

OpenShift Route

OpenShift Route 是一种 OpenShift 对外暴露服务的方式,它定义了一个外部可访问的 URL,使得外部用户可以通过该 URL 访问到 OpenShift 集群中的服务。Route 可以将一个或多个服务暴露给外部用户,并支持多种负载均衡策略。

在 OpenShift 中,Route 是通过 YAML 文件定义的。下面是一个简单的 Route YAML 文件的例子:

1
2
3
4
5
6
7
8
9
10
11
apiVersion: route.openshift.io/v1
kind: Route
metadata:
name: example-route
spec:
to:
name: example-service
port:
targetPort: 8080
tls:
termination: edge

在这个 YAML 文件中,我们定义了一个名为 example-route 的 Route,它将 example-service 服务暴露给外部用户。tls 字段指定了 SSL 终止的方式,这里我们使用了 Edge 终止方式。这意味着 OpenShift Router 会在自己内部处理 SSL,而不是将 SSL 流量转发给后端服务。

查看集群路由信息

1
2
3
4
5
6
[root@master ~]# oc get route
NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD
docker-registry docker-registry-default.apps.lab.example.com docker-registry <all> passthrough None
nginx nginx-default.apps.lab.example.com nginx 80-tcp None
registry-console registry-console-default.apps.lab.example.com registry-console <all> passthrough None
[root@master ~]#

在 OpenShift 中,Router 和 Route 是两个重要的概念。Router 负责将外部流量路由到正确的服务,而 Route 则是一种 OpenShift 对外暴露服务的方式,它定义了一个外部可访问的 URL,使得外部用户可以通过该 URL 访问到 OpenShift 集群中的服务。

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

Persistent Storage(PV、PVC)

容器默认是非持久化的,所有的修改在容器销毁时都会丢失。但现实是传统的应用大多都是有状态的,因此要求某些容器内的数据必须持久化,容器云平台必须为容器提供持久化储存(persistent storage)

OpenShift 除了支持 Docker 持久化卷的挂载方式外,还提供了一种持久化供给模型,即 Persistent Volume(持久化卷,PV)及Persistent Volume Claim(持久化卷请求,PVC)模型

在PV和PVC模型中,集群管理员会创建大量不同大小和不同特性的PV。用户在部署应用时,显式声明对持久化的需求,创建PVC。用户在PVC中定义所需存储的大小、访问方式(只读或可读可写;独占或共享)。

OpenShift集群会自动寻找符合要求的PV与PVC自动对接。通过PV和PVC模型,OpenShift为用户提供了一种灵活的方式来消费存储资源。

在OpenShift中,PV代表持久卷,PVC代表持久卷声明。

持久卷(PV)是集群中由管理员或使用StorageClass动态提供的存储的一部分。它是集群中的资源,就像节点是集群资源一样。PV是卷插件,就像卷一样,但具有独立于使用PV的任何单个Pod的生命周期。此API对象捕获存储实现的详细信息,例如NFS,iSCSI或云提供商特定的存储系统。

持久卷声明(PVC)是用户请求存储的一种方式。它类似于Pod。Pod消耗节点资源,PVC消耗PV资源。Pod可以请求特定级别的资源(CPU和内存)。声明可以请求特定的大小和访问模式(例如,可以挂载一次读/写或多次只读)。

要创建 PV,您可以定义一个带有适当字段的YAML文件,例如容量,访问模式和要使用的存储后端。以下是YAML中PV定义的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: v1
kind: PersistentVolume
metadata:
name: my-pv
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
nfs:
path: /path/to/nfs
server: nfs.example.com

要创建PVC,您可以定义一个带有适当字段的YAML文件,例如要使用的存储类别和要请求的存储量。以下是YAML中PVC定义的示例:

1
2
3
4
5
6
7
8
9
10
11
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: standard

也可以通过 storageClassName 来绑定 PV 和 PVC

当使用 storageClassName 绑定 PersistentVolume (PV) 和 PersistentVolumeClaim (PVC) 时,需要确保 PVC 中指定的 storageClassName 与 PV 中指定的 storageClassName 匹配。

以下是 storageClassName 为 slow 的 PV 的示例 YAML 文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: v1
kind: PersistentVolume
metadata:
name: my-pv
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: slow
nfs:
path: /path/to/nfs
server: nfs.example.com

以下是请求 storageClassName 为 slow 的 PVC 的示例 YAML 文件:

1
2
3
4
5
6
7
8
9
10
11
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: slow

注意,PV 和 PVC 中的 storageClassName 字段必须完全匹配。一旦创建了 PV 和 PVC,Kubernetes 将根据匹配的 storageClassName 自动将它们绑定在一起。

Registry

OpenShift中的 Registry 组件是一个容器镜像仓库,用于存储和管理应用程序的容器镜像。

它允许开发人员和管理员在OpenShift集群中共享和重用容器镜像,从而提高了应用程序的可移植性和可重复性。此外,Registry还提供了安全的身份验证和授权机制,以确保只有授权用户才能访问和使用镜像。

1
2
3
4
5
6
apiVersion: v1
kind: ImageStream
metadata:
name: my-image-stream
spec:
dockerImageRepository: registry.example.com/my-image

创建一个名为“my-image-stream”的ImageStream对象,它将使用“registry.example.com/my-image”作为Docker镜像仓库。您可以使用类似的代码来创建和管理其他类型的Registry对象,例如ImageStreamTag和ImageStreamImport。

在OpenShift中,与 Registry 相关的对象主要包括ImageStream、ImageStreamTag和ImageStreamImport。以下是每个对象的简要说明:

  • ImageStream:ImageStream是一个抽象对象,用于表示一个或多个容器镜像的流。它可以用来管理和共享容器镜像,并提供版本控制和回滚功能。您可以使用ImageStream来创建和管理容器镜像的流,以及将容器镜像推送到Registry中。
  • ImageStreamTag:ImageStreamTag是ImageStream的子对象,用于表示一个特定版本的容器镜像。它可以用来管理和共享容器镜像的版本,并提供版本控制和回滚功能。您可以使用ImageStreamTag来创建和管理容器镜像的版本,并将其推送到Registry中。
  • ImageStreamImport:ImageStreamImport是一个对象,用于将外部Registry中的容器镜像导入到OpenShift中的Registry中。它可以用来管理和共享外部Registry中的容器镜像,并提供版本控制和回滚功能。您可以使用ImageStreamImport来将外部Registry中的容器镜像导入到OpenShift中的Registry中,并将其用作ImageStream或ImageStreamTag的基础镜像。

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
[root@master ~]# oc get is -n default registry-console  -o yaml
apiVersion: image.openshift.io/v1
kind: ImageStream
metadata:
annotations:
description: Atomic Registry console
openshift.io/generated-by: OpenShiftNewApp
openshift.io/image.dockerRepositoryCheck: 2023-04-13T08:07:20Z
creationTimestamp: 2023-04-13T08:07:20Z
generation: 2
labels:
app: registry-console
createdBy: registry-console-template
name: registry-console
namespace: default
resourceVersion: "2189"
selfLink: /apis/image.openshift.io/v1/namespaces/default/imagestreams/registry-console
uid: 36dc8cb2-d9d2-11ed-8aa5-52540000fa0a
spec:
lookupPolicy:
local: false
tags:
- annotations: null
from:
kind: DockerImage
name: registry.lab.example.com/openshift3/registry-console:v3.9
generation: 2
importPolicy: {}
name: v3.9
referencePolicy:
type: Source
status:
dockerImageRepository: docker-registry.default.svc:5000/default/registry-console
tags:
- items:
- created: 2023-04-13T08:07:20Z
dockerImageReference: registry.lab.example.com/openshift3/registry-console@sha256:3d58299decdb25311155787373785d287ca68185483ab0a04cb9b672f100184d
generation: 2
image: sha256:3d58299decdb25311155787373785d287ca68185483ab0a04cb9b672f100184d
tag: v3.9
[root@master ~]#

Image Stream

Image Stream 是 Kubernetes 对象,用于在 OpenShift 中管理和跟踪容器镜像。它充当一个或多个容器镜像的指针,并提供一种管理和更新这些镜像的方式。

Image Stream 的主要目的是以更灵活和可扩展的方式管理容器镜像。您可以引用 Image Stream 而不是引用特定名称和标签的镜像,Image Stream 可以指向具有不同标签的多个镜像。这使您可以轻松地更新应用程序以使用镜像的新版本,而无需更改部署配置中的镜像引用。

Image Stream 还提供了一种自动构建和部署容器镜像的方式。通过设置引用 Image Stream 的 BuildConfig,您可以在向流中添加新镜像时自动触发新构建。

1
2
3
4
5
[root@master ~]# oc get imagestream
NAME DOCKER REPO TAGS UPDATED
nginx docker-registry.default.svc:5000/default/nginx latest 22 hours ago
registry-console docker-registry.default.svc:5000/default/registry-console v3.9 2 days ago
[root@master ~]#

要在 OpenShift 中创建一个 Image Stream,您可以使用 oc create 命令,后跟您想要创建的 Image Stream 的名称。以下是一个示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: image.openshift.io/v1
kind: ImageStream
metadata:
name: my-image-stream
spec:
tags:
- name: latest
from:
kind: DockerImage
name: my-registry.com/my-image:latest
- name: stable
from:
kind: DockerImage
name: my-registry.com/my-image:stable

在此示例中,Image Stream 的名称为 my-image-stream,它有两个标签:latest 和 stable。每个标签都指定了一个 from 字段,该字段指向注册表中的 Docker 镜像。每当使用这些标签之一将新镜像推送到注册表时,Image Stream 将自动更新以指向新镜像。

您还可以使用 oc import-image 命令从现有镜像创建 Image Stream。这将创建一个新的 Image Stream,其中包含指向指定镜像的单个标签。

BuildConfig && Build

BuildConfig

在 OpenShift 中,BuildConfig 是一个资源对象,用于定义如何从源代码构建 Docker 镜像。它指定了源代码位置、要使用的构建器镜像和输出镜像名称。

BuildConfig 资源由 OpenShift 构建系统用于在源代码更改时创建新的镜像。这允许在 OpenShift 中进行持续集成和交付应用程序。

要在 OpenShift 中创建 BuildConfig,可以使用 oc new-build 命令。以下是一个示例:

1
oc new-build --name=myapp https://github.com/myuser/myapp.git

此命令创建一个名为 myapp 的新 BuildConfig,该 BuildConfig 从指定的 GitHub 存储库构建源代码。

您还可以使用 YAML 文件创建 BuildConfig。以下是一个为 Node.js 应用程序创建 BuildConfig 的示例 YAML 文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
apiVersion: build.openshift.io/v1
kind: BuildConfig
metadata:
name: myapp
spec:
source:
git:
uri: https://github.com/myuser/myapp.git
contextDir: .
strategy:
type: Source
sourceStrategy:
from:
kind: ImageStreamTag
name: nodejs:latest
incremental: true
env:
- name: NODE_ENV
value: production
output:
to:
kind: ImageStreamTag
name: myapp:latest

此 YAML 文件指定了源代码位置、要使用的构建器镜像(在本例中为 nodejs:latest 镜像)和输出镜像名(myapp:latest)。

创建 BuildConfig 后,可以通过运行 oc start-build 命令开始构建。以下是一个示例:

1
oc start-build myapp

此命令启动 myapp BuildConfig 的新构建。

Build

在 Openshift 中,Build 的作用是将源代码转换为可执行镜像,是用于执行 Build 过程的资源对象。它使用 BuildConfig 中定义的配置信息来执行 Build 过程,并将源代码转换为可执行镜像。Build 过程可以在本地机器上或者在 Openshift 集群中的 Build Pod 上执行。

要创建 Build 资源对象,可以使用 oc start-build 命令,并指定 BuildConfig 的名称。以下是一个示例命令:

1
oc start-build myapp

这个命令将启动名为 myapp 的 Build 过程。可以使用 oc logs 命令查看 Build 过程的日志输出。

BuildConfig 和 Build 区别

BuildConfig 和 Build 的区别在于它们的作用和使用方式。

BuildConfig 用于定义 Build 的配置,而 Build 用于执行 Build 过程。在创建 Build 时,需要指定 BuildConfig 的名称,以便 Build 可以使用 BuildConfig 中定义的配置信息来执行 Build 过程。

所以一般情况下,会有一个BuildConfig, 多个 Build

1
2
3
4
5
6
7
8
[root@master ~]# oc get build --all-namespaces
NAMESPACE NAME TYPE FROM STATUS STARTED DURATION
rome php-helloworld-1 Source Git@6d61e75 Complete 11 hours ago 1m13s
rome php-helloworld-2 Source Git@312b331 Complete 11 hours ago 9s
[root@master ~]# oc get buildconfig --all-namespaces
NAMESPACE NAME TYPE FROM LATEST
rome php-helloworld Source Git 2
[root@master ~]#

Deploy && DeploymentConfig

在 OpenShift 中,Deploy 和 DeploymentConfig 是用于管理应用程序部署的两个资源对象。它们的作用是确保应用程序在 OpenShift 集群中正确地部署和运行。

Deploy

Deploy 是一个 Kubernetes 资源对象,用于管理应用程序的部署。它定义了一个应用程序的副本数、容器镜像、容器端口等信息。在 OpenShift 中,Deploy 通常与 Service 和 Route 一起使用,以便将应用程序暴露给外部用户。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:latest
ports:
- containerPort: 8080

在这个示例中,Deploy 定义了一个名为 myapp 的应用程序,它将在 OpenShift 集群中运行 3 个副本。每个副本都使用 myapp:latest 镜像,并将容器端口 8080 暴露给其他容器和外部用户。

DeploymentConfig

DeploymentConfig 是 OpenShift 特有的资源对象,它是 Deploy 的扩展。与 Deploy 不同,DeploymentConfig 允许您定义应用程序的部署策略、升级策略、回滚策略等信息。这使得 DeploymentConfig 更加灵活和强大,适用于更复杂的应用程序部署场景。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
apiVersion: apps.openshift.io/v1
kind: DeploymentConfig
metadata:
name: myapp
spec:
replicas: 3
selector:
app: myapp
strategy:
type: Rolling
rollingParams:
updatePeriodSeconds: 1
intervalSeconds: 1
timeoutSeconds: 600
maxUnavailable: 25%
maxSurge: 25%
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:latest
ports:
- containerPort: 8080

在这个示例中,DeploymentConfig 定义了一个名为 myapp 的应用程序,它将在 OpenShift 集群中运行 3 个副本。与 Deploy 不同,DeploymentConfig 还定义了一个滚动升级策略,该策略允许您在不中断服务的情况下升级应用程序。此外,DeploymentConfig 还定义了容器的端口和镜像等信息。

Deploy && DeploymentConfig 区别

总的来说,Deploy 和 DeploymentConfig 都是用于管理应用程序部署的资源对象。它们的主要区别在于 DeploymentConfig 具有更多的部署和升级策略选项,适用于更复杂的应用程序部署场景。在实际使用中,您可以根据自己的需求选择使用哪个资源对象。

Deploy 和 DeploymentConfig 可以同时使用。在 OpenShift 中,可以使用 DeploymentConfig 来定义应用程序的部署策略,然后使用 Deploy 来管理应用程序的部署。Deploy 可以通过定义 DeploymentConfig 来创建

在创建 DeploymentConfig 时,可以指定 spec.strategy.typeRollingRecreate

  • 如果选择 Rolling 策略,则会自动创建 Deployment 和 ReplicationController。
  • 如果选择 Recreate 策略,则只会创建 Deployment。

以下是创建 DeploymentConfig 的示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: apps.openshift.io/v1
kind: DeploymentConfig
metadata:
name: myapp
spec:
replicas: 3
selector:
app: myapp
strategy:
type: Rolling
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:latest
ports:
- containerPort: 8080

Template

OpenShift 中的 Template 资源对象是一种定义一组可以轻松创建和管理的对象的方式。它本质上是创建一组相关对象的蓝图,例如一组服务、路由和部署。

模板可以使用 YAML 或 JSON 文件创建,并可以存储在 Git 存储库或直接存储在 OpenShift 中。要创建模板,可以使用 oc create 命令,后跟 -f 标志,然后是包含模板定义的 YAML 或 JSON 文件的路径。例如,如果您有一个名为 my-template.yaml 的文件在当前目录中,可以通过运行以下命令来创建模板:

1
oc create -f my-template.yaml

创建模板后,可以使用 oc new-app 命令和 –template 标志后跟模板名称来使用它创建一组相关对象。例如,如果您有一个名为 my-template 的模板,可以通过运行以下命令来基于该模板创建一组对象:

1
oc new-app --template=my-template

这将创建模板中定义的所有对象,例如服务、路由和部署,并将它们按照模板中指定的方式连接在一起。

假设您有一个简单的 Web 应用程序,由单个部署和服务组成。您可以通过创建一个名为 my-web-app-template.yaml 的 YAML 文件来为此应用程序定义一个模板,其内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
apiVersion: v1
kind: Template
metadata:
name: my-web-app
objects:
- kind: Deployment
apiVersion: apps/v1
metadata:
name: my-web-app
spec:
replicas: 1
selector:
matchLabels:
app: my-web-app
template:
metadata:
labels:
app: my-web-app
spec:
containers:
- name: my-web-app
image: my-web-app:latest
ports:
- containerPort: 8080
- kind: Service
apiVersion: v1
metadata:
name: my-web-app
spec:
selector:
app: my-web-app
ports:
- name: http
port: 80
targetPort: 8080

此模板为 Web 应用程序定义了一个部署和一个服务,其中部署运行名为 my-web-app:latest 的容器映像并公开端口 8080,服务公开端口 80 并将流量转发到部署。

1
oc new-app --template=my-web-app

要基于此模板创建一组对象,可以运行:

这将创建一个名为 my-web-app 的部署和服务,并按照模板中指定的方式将它们连接在一起。

Source to Image

“Source to Image” (S2I) 是 OpenShift 中的一个工具,它允许开发人员从他们的源代码构建可重现的 Docker 镜像。S2I 通过提供构建和运行容器应用程序的框架简化了构建镜像的过程。

S2I 的工作原理是将您的源代码与基础镜像结合起来创建一个新的镜像,该镜像可以在容器中运行。基础镜像为您的应用程序提供运行时环境,而源代码则提供应用程序代码。S2I 还允许您通过提供可以在构建过程中运行的脚本来自定义构建过程。

涉及的流程:

  1. 用户输入源代码仓库的地址。
  2. 用户选择S21构建的基础镜像(又称为Builder镜像)。Builder镜像中包含了操作系统、编程语言、框架等应用所需的软件及配置。OpenShift默认提供了多种编程语言的Builder镜像,如Java、PHP、Ruby、Python、Perl等。用户也可以根据自身需求定制自己的Builder镜像,并发布到服务目录中供用户选用。
  3. 用户或系统触发S2I构建。OpenShift将实例化S2I构建执行器。
  4. S2I 构建执行器将从用户指定的代码仓库下载源代码。
  5. S2I 构建执行器实例化Builder镜像。代码将会被注入Builder镜像中。
  6. Builder 镜像将根据预定义的逻辑执行源代码的编译、构建并完成部署。
  7. S2l 构建执行器将完成操作的Builder镜像并生成新的Docker镜像。
  8. S2 构建执行器将新的镜像推送到OpenShift内部的镜像仓库。
  9. S2I 构建执行器更新该次构建相关的Image Stream 信息。

S2I构建完成后,根据用户定义的部署逻辑,OpenShit将把镜像实例化部署到集群中。

要在 OpenShift 中创建 S2I 构建,您可以使用 oc new-app 命令和 --strategy=source 标志。这将创建一个新的构建配置,该配置使用 S2I 构建您的应用程序。然后,您可以将源代码推送到构建配置中,OpenShift 将自动为您构建一个新的镜像。

以下是使用 oc new-app 命令在 OpenShift 中创建 S2I 构建的示例:

1
oc new-app --name=myapp --strategy=source https://github.com/myuser/myapp.git

这将创建一个名为 myapp 的新构建配置,该配置使用 S2I 从位于 https://github.com/myuser/myapp.git 的源代码构建您的应用程序。

--strategy=source 标志在 oc new-app 命令中用于指定在 OpenShift 中创建新应用程序时要使用的构建策略。在这种情况下,使用了 source 策略,这意味着 OpenShift 将使用 Source-to-Image (S2I) 工具从源代码构建应用程序。

博文部分内容参考

© 文中涉及参考链接内容版权归原作者所有,如有侵权请告知,这是一个开源项目,如果你认可它,不要吝啬星星哦 :)


《OKD 3.9 DO280 Red Hat OpenShift Administration I》

《开源容器云OpenShift:构建基于Kubernetes的企业应用云平台》

https://docs.okd.io/latest/welcome/index.html


© 2018-2023 liruilonger@gmail.com, All rights reserved. 保持署名-非商用-相同方式共享(CC BY-NC-SA 4.0)

发布于

2023-01-27

更新于

2023-06-21

许可协议

评论
加载中,最新评论有1分钟缓存...
Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×