《OpenShift 4.x HOL教程汇总》
说明:本文已经在OpenShift 4.8环境中验证
文章目录
OpenShift集群的规模
单一的OpenShift集群可以运行数量非常可观的资源和对象。下表列出了从OpenShift 4.1到OpenShift 4.8各个版本支持的对象和资源的最高配置上限(可以看出基本没有变化)。根据Red Hat的说明,这些上限大都并非硬性限制,而是当环境没有出现性能差( Poor Performance)情况时的最高数量。例如每个node运行的pod数量其实是可以超过250个,只不过当所有node部署的pod都超过250个,而且还运行了2000个node,此时OpenShift集群会出现性能显著下降的情况。下表中的数量上限其实都是经过Red Hat测试验证过的,所以用户可以在项目中放心大规模部署OpenShift集群。不过这些数据使用的是样例应用,因此在实际项目中,能运行的对象规模还需要根据用户的应用情况进行评估。
在OpenShift中为了能合理地分配和使用对象和资源,我们可以对一个对象使用相关资源(可以是另一类对象,或着是诸如CPU、内存这样的系统资源)的数量进行控制和限制。资源限制主要针对以下三个层面:
- 限制多个项目使用的资源和对象的总数量
- 限制一个项目使用的资源和对象的数量
- 限制一个Pod和Container使用资源的数量
OpenShift使用以下对象实现资源使用限额:
- Quota:一种K8s对象,用来限制项目可以累计使用的资源总和。Quota分为限制单个项目的ResourceQuota(简称Quota)和多个项目的ClusterResourceQuota(简称ClusterQuota)。配额的资源可以是计算资源、存储资源和对象数量。
- LimitRange:一种K8s对象,用来限制一个项目中的Pod和Container缺省可以使用多少资源。
- Resource:非K8s对象,用来限制特定Container使用的资源。如果它比LimitRanges定义的缺省值高,则Container无法正常启动。
限制多个项目使用的资源和对象的总数量
可以用ClusterResourceQuota对象来限制租户消耗的资源总量,因为它可以使用基于项目的Annotation和Lable的Selector来实现跨多个项目限制资源使用的总配额(不像ResourceQuota仅与一个项目相关)。ClusterResourceQuota对象不属于任何一个项目,它属于整个集群。
- 设置本实验使用的用户标识。
$ export USER_ID=YOUR-USER-ID
- 用OpenShift集群管理员执行以下命令,为USER-ID用户创建clusterresourcequota,限制用户USER-ID下所有项目(假设该用户下面已有"USER-ID-xxx"、“USER-ID-yyy”、"USER-ID-zzz"三个项目,它们是通过annotation选出来的)使用的CPU和内存总量。
$ oc create clusterresourcequota ${USER_ID}-crq --project-annotation-selector openshift.io/requester=${USER_ID} --hard limits.cpu=20 --hard limits.memory=40Gi
- 执行以下命令,查看刚刚创建的ClusterResourceQuota对象。可以看到Namespace Selector中是和USER-ID用户相关的项目。
$ oc describe clusterquota ${USER_ID}-crq
Name: user1-crq
Created: 38 hours ago
Labels: <none>
Annotations: <none>
Namespace Selector: ["user1-xxx" "user1-yyy" "user1-zzz"]
Label Selector:
AnnotationSelector: map[openshift.io/requester:user1]
Resource Used Hard
-------- ---- ----
limits.cpu 17500m 20
limits.memory 41064Mi 45Gi
- 从OpenShift控制台的“管理员”视图进入“管理”的“资源配额”菜单,查看刚刚创建的ClusterResourceQuota对象。
限制一个项目使用的资源和对象的数量
可以用ResourceQuota对象来限制一个项目中能消耗的资源量,ResourceQuota对象属于一个特性项目。
- 用一般用户USER_ID新建一个项目。
$ oc new-project ${USER_ID}-resourcequota
- 用Openshift集群管理员执行以下命令,为USER_ID用户新建的项目创建一个ResourceQuota。
$ oc create resourcequota ${USER_ID}-quota --hard=cpu=10,memory=10G,pods=10,services=10,replicationcontrollers=10,resourcequotas=10,secrets=20,persistentvolumeclaims=10 -n ${USER_ID}-resourcequota
resourcequota/user1-quota created
- 用一般用户USER_ID查看新建的ResourceQuota对象,其中Hard一列是允许使用资源的最大值。
$ oc describe resourcequota ${USER_ID}-quota -n ${USER_ID}-resourcequota
Name: user1-quota
Namespace: user1-resourcequota
Resource Used Hard
-------- ---- ----
cpu 0 10
memory 0 10G
persistentvolumeclaims 0 10
pods 0 10
replicationcontrollers 0 10
resourcequotas 1 10
secrets 9 20
services 0 10
- 还可以用USER_ID用户进入OpenShift控制台的管理员视图的“管理”菜单,然后进入“资源配额”,确保当前是“USER-ID-resourcequota”项目,在列表中找到可以看到“user1-quota”(会列出所有ResourceQuota和ClusterResourceQuota对象),进入“”user1-quota可以看到当前资源使用情况。
- 我们在上面的“user1-quota”中限制了当前项目所能包含的相关资源总量。执行以下命令创建3个Pod对象(每个Pod的CPU分配“4000m”),确认此时会有错误提示,提示申请的CPU总量已经超过项目允许设置的最大值“10”。
$ oc run ruby-hello-world-1 --image=openshift/ruby-hello-world --limits=cpu=4000m,memory=400Mi --requests=cpu=4000m,memory=400Mi -n ${USER_ID}-resourcequota
$ oc run ruby-hello-world-2 --image=openshift/ruby-hello-world --limits=cpu=4000m,memory=400Mi --requests=cpu=4000m,memory=400Mi -n ${USER_ID}-resourcequota
$ oc run ruby-hello-world-3 --image=openshift/ruby-hello-world --limits=cpu=4000m,memory=400Mi --requests=cpu=4000m,memory=400Mi -n ${USER_ID}-resourcequota
Error from server (Forbidden): pods "ruby-hello-world-3" is forbidden: exceeded quota: user1-quota, requested: cpu=4, used: cpu=8, limited: cpu=10
限制一个Pod和Container使用资源的数量
可以通过2种方式可限制Pod和Container对使用资源的数量:
- OpenShift会为每个项目设置一个缺省的LimitRange对象来限制其下所有的Pod和Container缺省能用的资源量,LimitRange是该项目中为资源设置的缺省上限。
- 在Pod对象的YAML定义中的resources区域可定义该Pod和所含Container对象可以使用的资源量(包括:初始分配量 - request、最高分配量 - limit)。当针对Pod单独定义的使用资源超过了其所属项目为Pod定义的缺省能用资源的时候(或整个租户级别已经没有可用资源的时候),Pod就不能正常启动了。
通过设置项目级LimitRange,为该项目的Pod和Container设置缺省可用资源上限
LimitRange对象可对项目中的计算资源进行约束限制,这些资源包括:Pod,Container,Image,ImageStream和PVC。如果这些项目中的已有的资源已经超过了限制,则新的资源将无法创建。OpenShift会为每个项目设置一个缺省的LimitRange对象来限制其下所有的Pod和Container缺省能用的资源量,LimitRange是该项目中为资源设置的缺省上限。
- 我们可以通过以下命令查看自动创建的项目级LimitRange对象中定义的Pod和Container中对CPU和内存的使用配额限制,其中容器可以使用的最大CPU量为“4”个。
$ oc new-project ${USER_ID}-limitrange
$ oc get limitrange -n ${USER_ID}-limitrange
NAME CREATED AT
user1-limitrange-core-resource-limits 2020-02-22T06:51:32Z
$ oc describe limitrange ${USER_ID}-limitrange-core-resource-limits -n ${USER_ID}-limitrange
Name: user1-limitrange-core-resource-limits
Namespace: user1-limitrange
Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
---- -------- --- --- --------------- ------------- -----------------------
Container cpu - 4 50m 500m -
Container memory - 6Gi 256Mi 1536Mi -
Pod cpu - 4 - - -
Pod memory - 12Gi - - -
- 执行命令创建创建一个pod。
$ oc run ruby-hello-world --image=openshift/ruby-hello-world -n ${USER_ID}-limitrange
- 查看这个pod内部的Container的“Requests”和“Limits”。
$ oc describe pod/ruby-hello-world -n ${USER_ID}-limitrange
。。。
Containers:
ruby-hello-world:
Container ID: cri-o://93c17bd35af219f02be89ce2ba1985576407ced7bc508e8ab783dc2486d3b153
Image: openshift/ruby-hello-world
Image ID: docker.io/openshift/ruby-hello-world@sha256:f86a2ae290f30ee25810cd2f271668fb46d19dc1ec4e59f17b97ef2aa2ef98e7
Port: <none>
Host Port: <none>
State: Running
Started: Thu, 09 Sep 2021 14:24:37 +0000
Ready: True
Restart Count: 0
Limits:
cpu: 500m
memory: 1536Mi
Requests:
cpu: 50m
memory: 256Mi
。。。
- 可以根据以下内容修改项目缺省的LimitRange。
apiVersion: "v1"
kind: "LimitRange"
metadata:
name: "user1-limitrange-core-resource-limits"
spec:
limits:
- type: "Pod"
max:
cpu: "2"
memory: "1Gi"
min:
cpu: "200m"
memory: "60Mi"
- type: "Container"
max:
cpu: "2"
memory: "1Gi"
min:
cpu: "100m"
memory: "4Mi"
default:
cpu: "400m"
memory: "200Mi"
defaultRequest:
cpu: "200m"
memory: "100Mi"
maxLimitRequestRatio:
cpu: "10"
- 用一般USER-ID用户查看项目中的project-limitrange。
$ oc describe limits/${USER_ID}-limitrange-core-resource-limits -n ${USER_ID}-limitrange
Name: user1-limitrange-core-resource-limits
Namespace: user1-limitrange
Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
---- -------- --- --- --------------- ------------- -----------------------
Pod cpu 200m 2 - - -
Pod memory 60Mi 1Gi - - -
Container cpu 100m 2 200m 400m 10
Container memory 4Mi 1Gi 100Mi 200Mi -
- 进入USER-ID用户的“管理员”视图,然后进入“管理”菜单的LimitRanges项目。可以看到“user1-limitrange-core-resource-limits”,进入它可以看到设置的相关指标和上限。
针对每个Pod和Container设置可用资源
我们还可为每个Pod以及其中的Container进一步指定特定的使用资源上限。需要注意的是当针对Pod单独定义的使用资源超过了其所属项目为Pod定义的缺省能用资源的时候(或整个租户级别已经没有可用资源的时候),Pod是不能正常启动的。
- 执行命令创建一个Pod,申请的CPU资源是“5000m”,确认出现错误提示。
$ oc run ruby-hello-world --image=openshift/ruby-hello-world --limits=cpu=5000m,memory=400Mi --requests=cpu=5000m,memory=400Mi -n ${USER_ID}-limitrange
Error from server (Forbidden): pods "ruby-hello-world" is forbidden: [maximum cpu usage per Container is 4, but limit is 5, maximum cpu usage per Pod is 4, but limit is 5]
- 调整参数重新执行命令创建一个Pod,确认可以成功。
$ oc run ruby-hello-world --image=openshift/ruby-hello-world --limits=cpu=500m,memory=100Mi --requests=cpu=300m,memory=100Mi -n ${USER_ID}-limitrange
- 查看Running状态的Pod名称,再查看其内部名为ruby-hello-world的Container中指定的limists和requests配置。
$ oc get pod -n ${USER_ID}-limitrange
NAME READY STATUS RESTARTS AGE
ruby-hello-world 1/1 Running 0 59s
$ oc describe pod ruby-hello-world -n ${USER_ID}-limitrange
。。。
Containers:
ruby-hello-world:
Container ID: cri-o://c8e1886fc9133141fdc9ebae5a3df884ca32f4313c0e53cf68fc4f038ab6390a
Image: openshift/ruby-hello-world
Image ID: docker.io/openshift/ruby-hello-world@sha256:52384f1f4cc137335b59c25eb69273e766de7646c04c22f66648313f12f1828f
Port: <none>
Host Port: <none>
State: Running
Started: Fri, 21 Feb 2020 05:45:02 +0000
Ready: True
Restart Count: 0
Limits:
cpu: 500m
memory: 100Mi
Requests:
cpu: 300m
memory: 100Mi
Environment: <none>
。。。
一些场景说明
只声明容器的limit,而不声明request
- 创建内容如下的only-limit.yaml文件,其中只定义了Container的cpu limit。
apiVersion: v1
kind: Pod
metadata:
name: only-limit
spec:
containers:
- name: only-limit-2-ctr
image: openshift/hello-openshift
resources:
limits:
cpu: "1"
- 执行命令创建该对象。
$ oc apply -f only-limit.yaml -n ${USER_ID}-limit-project
- 查看名为only-limit的Pod中container的resources limit。可以看到此时系统已经自动将cpu的request和limit设为一样了,另外没有明确指定的memory也适用了上一节为该项目创建的LimitRange中定义的default limit和default request。
containers:
- image: openshift/hello-openshift
imagePullPolicy: Always
name: only-request-2-ctr
resources:
resources:
limits:
cpu: "1"
memory: 200Mi
requests:
cpu: "1"
memory: 100Mi
只声明容器的request,而不声明limit
- 创建内容如下的only-request.yaml文件,其中只定义了Container的cpu request。
apiVersion: v1
kind: Pod
metadata:
name: only-request
spec:
containers:
- name: only-request-2-ctr
image: openshift/hello-openshift
resources:
requests:
cpu: "0.3"
- 执行命令创建该对象。
$ oc apply -f only-request.yaml -n ${USER-ID}-limit-project
- 查看名为only-request的Pod中container的resources limit。可以看到此时系统已经自动将CPU和内存的limit设为limitrange中的default limit,而request的CPU为(1)步骤中定义的“0.3”(即300m),request的内存为default request中的内存量(100Mi)。
containers:
- image: openshift/hello-openshift
imagePullPolicy: Always
name: only-request-2-ctr
resources:
limits:
cpu: 400m
memory: 200Mi
requests:
cpu: 300m
memory: 100Mi
限制使用网络带宽
在OpenShift中还可对Constainer占用网络带宽进行限制。
- 创建测试项目。
$ oc new-project ${USER-ID}-limited-bandwidth
$ oc adm policy add-scc-to-user anyuid -z default
- 创建DeploymentConfig,其中对Pod的进出访问都限制了0.5M网络带宽。
apiVersion: apps.openshift.io/v1
kind: DeploymentConfig
metadata:
labels:
app: nginx
name: nginx
namespace: limited-bandwidth
spec:
replicas: 1
selector:
deploymentconfig: nginx
template:
metadata:
annotations:
kubernetes.io/egress-bandwidth: 0.5M
kubernetes.io/ingress-bandwidth: 0.5M
labels:
app: nginx
deploymentconfig: nginx
spec:
containers:
- image: nginx
name: nginx
- 查看状态为Running的Pod名称
$ oc get pod -n ${USER-ID}-limited-bandwidth
NAME READY STATUS RESTARTS AGE
nginx-1-deploy 0/1 Completed 0 12m
nginx-1-rcn7j 1/1 Running 0 11m
- 进入Pod,然后下载一个文件,观察下载速度已经被限流了。
$ oc rsh nginx-1-rcn7j -n ${USER-ID}-limited-bandwidth
# curl -LO https://mirror.openshift.com/pub/openshift-v4/clients/ocp/latest/openshift-install-linux.tar.gz
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 80.0M 0 400k 0 0 31848 0 0:43:54 0:00:12 0:43:42 59953
其它参考
https://docs.openshift.com/container-platform/4.3/applications/quotas/quotas-setting-per-project.html
https://docs.openshift.com/container-platform/3.11/admin_guide/limits.html
https://docs.openshift.com/container-platform/3.11/dev_guide/compute_resources.html
https://kubernetes.io/zh/docs/tasks/administer-cluster/manage-resources/cpu-default-namespace/