使用OpenShift的Machine Config Pool(MCP)来创建Infra节点

概要概述

可以通过在OpenShift (OCP)上设置专用的infra节点来将运维组件,例如默认路由器、内部注册表、监控和额外安装的日志记录器等,与应用程序Pod进行分离。

如果使用UPI进行安装,则可以通过仅使用“节点标签”来配置基础设施节点,或者可以创建专为基础设施节点用的“机器配置池(MCP)”的方法。

在OCP 4.2中,虽然只使用“节点标签”来设置的方法有点过时,但我认为创建专用的基础设施节点并将路由器、内部注册表、监控和日志移动到该节点可能是一个参考选项。

我在本次记录中提到了创建用于 infra node 的 “MCP” 并配置 infra node 的注意事项。

这篇文章中提到的OCP集群的前提配置是基于Qiita / OpenShift 4.10 Bare Metal UPI(iPXE)安装的OCP 4.10配置。

    • OCP 4.10をベアメタルのUPIでインストールしています。

 

    • nodeの構成はinfra node x3台です。

 

    (こちらの記事ではロギングはまだ入れていませんが、ロギングはここでインストールしています。)
[root@bastion-01 ~]# oc version
Client Version: 4.10.6
Server Version: 4.10.6
Kubernetes Version: v1.23.5+b0357ed
[root@bastion-01 ~]#
[root@bastion-01 ~]# oc get node
NAME        STATUS   ROLES    AGE    VERSION
infra-01    Ready    worker   2d1h   v1.23.5+b0357ed
infra-02    Ready    worker   2d1h   v1.23.5+b0357ed
infra-03    Ready    worker   2d     v1.23.5+b0357ed
master-01   Ready    master   2d1h   v1.23.5+b0357ed
master-02   Ready    master   2d1h   v1.23.5+b0357ed
master-03   Ready    master   2d1h   v1.23.5+b0357ed
worker-01   Ready    worker   2d     v1.23.5+b0357ed
worker-02   Ready    worker   2d     v1.23.5+b0357ed
[root@bastion-01 ~]#

请提供参考资料。

请提供相关资料。

请给出参考资料。

请提供可供参考的资料。

基础架构节点(infra node)的配置方法,以下的知识库(KB)是最佳,非常值得参考。基本上,我们根据该知识库中所述内容创建了基础架构节点专用的“MCP”。

    KB / Infrastructure Nodes in OpenShift 4

对于MCP(Microsoft认证专家计划)的概述,以下的博客非常易懂。

    Red Hat Blog / OpenShift Container Platform 4: How does Machine Config Pool work?

另外,OCP的文件如下所述。

    • OCP 4.10 Docs / インストール後の設定 / 5. インストール後のクラスタータスク / 5.4. 実稼働環境用のインフラストラクチャーマシンセットの作成

 

    • OCP 4.10 Docs / インストール後の設定 / 5. インストール後のクラスタータスク / 5.5. マシンセットリソースのインフラストラクチャーノードへの割り当て

 

    OCP 4.10 Docs / インストール後の設定 / 5. インストール後のクラスタータスク / 5.6. リソースのインフラストラクチャーマシンセットへの移行

基础设施节点的组成流程

对于UPI而言,在构建基础节点时,需要考虑以下步骤(请参考知识库)。

infra nodeの構成方法

(1) infra node専用の「MCP」を作成
(2) infra node専用の「MCP」を作成せず、infra node用のworker nodeにinfraの「ノードラベル」を「追加」して構成

運用コンポーネントのinfra nodeに移動

ルーター
OCP内部レジストリー
モニタリング
ロギング

アプリケーションPodをinfra nodeで稼働させない設定

(1) nodeSelectorのみを使用
(2) nodeSelectorとtaint/tolerationを使用

这次的政策

这次我们将使用MCP来配置基础设施节点。

    • 「infra nodeの構成方法」は「(1) infra node専用の「MCP」を作成」で構成します。

 

    「アプリケーションPodをinfra nodeで稼働させない設定」は「(1) nodeSelectorのみを使用」で実施します。

「机器配置」、「机器配置池」和「节点」

“MC”、”MCP”和”Node”之间的关系如下所示。

    • 「MC」と「MCP」との紐付けは、「MC」のラベル(machineconfiguration.openshift.io/role=master、machineconfiguration.openshift.io/role=worker)の値で紐づいています。

 

    「Node」と「MCP」との紐付けは、「Node」のノードラベル(node-role.kubernetes.io/master=””、node-role.kubernetes.io/worker=)で紐づいています。

我们将创建infra节点的”MCP”。

    • 「Node」にinfra node用のノードラベルを付与します。

 

    • infra node用の「MCP」は、既存のwoker node用のラベルを持った「MC」も全部読み込めるようにします。

 

    今後infra nodeだけに設定したい「MC」を作成した場合には、worker node用ののラベルを持った「MC」に加えて、infra node用のラベルを持った「MC」も両方読み込めるように「MCP」のmachineConfigSelectorの値を設定します。

基础设施节点的配置方法

创建一个专属于基础设施节点的”MCP”。

默认的配置如下所示。

默认情况下,存在用于主节点和工作节点的“机器配置池(MCP)”。

[root@bastion-01 mcp]# oc get mcp
NAME     CONFIG                                             UPDATED   UPDATING   DEGRADED   MACHINECOUNT   READYMACHINECOUNT   UPDATEDMACHINECOUNT   DEGRADEDMACHINECOUNT   AGE
master   rendered-master-954e86f747cb1bc813dc88a53adc068c   True      False      False      3              3                   3                     0                      40d
worker   rendered-worker-8062fb3f341ce6e926a1678cc33db7f3   True      False      False      5              5                   5                     0                      40d
[root@bastion-01 mcp]#

有多个包含特定要求的「Machine Config (MC)」,分别为主节点和工作节点设置。
上述的「MC」会自动创建为每个主节点和工作节点,分别称为rendered-master-xxxxx和rendered-worker-xxxx,并显示在主节点和工作节点的MCP的「CONFIG」列中。

[root@bastion-01 mcp]# oc get mc
NAME                                               GENERATEDBYCONTROLLER                      IGNITIONVERSION   AGE
00-master                                          e6ba00b885558712d660a3704c071490d999de6f   3.2.0             40d
00-worker                                          e6ba00b885558712d660a3704c071490d999de6f   3.2.0             40d
01-master-container-runtime                        e6ba00b885558712d660a3704c071490d999de6f   3.2.0             40d
01-master-kubelet                                  e6ba00b885558712d660a3704c071490d999de6f   3.2.0             40d
01-worker-container-runtime                        e6ba00b885558712d660a3704c071490d999de6f   3.2.0             40d
01-worker-kubelet                                  e6ba00b885558712d660a3704c071490d999de6f   3.2.0             40d
99-master-chrony                                                                              3.2.0             40d
99-master-generated-registries                     e6ba00b885558712d660a3704c071490d999de6f   3.2.0             40d
99-master-ssh                                                                                 3.2.0             40d
99-worker-chrony                                                                              3.2.0             40d
99-worker-generated-registries                     e6ba00b885558712d660a3704c071490d999de6f   3.2.0             40d
99-worker-ssh                                                                                 3.2.0             40d
rendered-master-954e86f747cb1bc813dc88a53adc068c   e6ba00b885558712d660a3704c071490d999de6f   3.2.0             40d
rendered-worker-8062fb3f341ce6e926a1678cc33db7f3   e6ba00b885558712d660a3704c071490d999de6f   3.2.0             40d
[root@bastion-01 mcp]#

node与主节点和工作节点的MCP标签相关联,并且每个MCP都应用了所显示的渲染的MC。

默认的基础设施节点示例(仍然具有工作节点标签)

[root@bastion-01 ~]# oc describe node infra-01
Name:               infra-01
Roles:              worker
Labels:             beta.kubernetes.io/arch=amd64
                    beta.kubernetes.io/os=linux
                    kubernetes.io/arch=amd64
                    kubernetes.io/hostname=infra-01
                    kubernetes.io/os=linux
                    node-role.kubernetes.io/worker=
                    node.openshift.io/os_id=rhcos
Annotations:        machineconfiguration.openshift.io/controlPlaneTopology: HighlyAvailable
                    machineconfiguration.openshift.io/currentConfig: rendered-worker-8062fb3f341ce6e926a1678cc33db7f3
                    machineconfiguration.openshift.io/desiredConfig: rendered-worker-8062fb3f341ce6e926a1678cc33db7f3
                    machineconfiguration.openshift.io/reason:
                    machineconfiguration.openshift.io/state: Done
                    volumes.kubernetes.io/controller-managed-attach-detach: true
()

我们将从这里开始创建实际的基础设施节点MCP。

我将创建存放清单的目录。

[root@bastion-01 ~]# mkdir -p work/manifest/mcp
[root@bastion-01 ~]# cd work/manifest/mcp/
[root@bastion-01 mcp]#

我会为infra节点创建“MCP”的清单文件。

    • infra node専用のMCPを作成するので.spec.metadata.nameは、infraという名前にします。

 

    infra nodeは、worker用ののMCも、infra用のMCも読み込めるように、machineConfigSelectorを設定をします。
[root@bastion-01 mcp]# vi mcp-infra.yaml
[root@bastion-01 mcp]#
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfigPool
metadata:
  name: infra
spec:
  machineConfigSelector:
    matchExpressions:
      - {key: machineconfiguration.openshift.io/role, operator: In, values: [worker,infra]}
  nodeSelector:
    matchLabels:
      node-role.kubernetes.io/infra: ""

应用为Infra Node创建的”MCP”清单。

[root@bastion-01 mcp]# pwd
/root/work/manifest/mcp
[root@bastion-01 mcp]# ls -l
合計 4
-rw-r--r--. 1 root root 315  5月  9 20:33 mcp-infra.yaml
[root@bastion-01 mcp]#
[root@bastion-01 mcp]# oc apply -f mcp-infra.yaml
machineconfigpool.machineconfiguration.openshift.io/infra created
[root@bastion-01 mcp]#

确认已经创建了供基础设施节点使用的”MCP”。

[root@bastion-01 mcp]# oc get mcp
NAME     CONFIG                                             UPDATED   UPDATING   DEGRADED   MACHINECOUNT   READYMACHINECOUNT   UPDATEDMACHINECOUNT   DEGRADEDMACHINECOUNT   AGE
infra    rendered-infra-8062fb3f341ce6e926a1678cc33db7f3    True      False      False      0              0                   0                     0                      26s
master   rendered-master-954e86f747cb1bc813dc88a53adc068c   True      False      False      3              3                   3                     0                      40d
worker   rendered-worker-8062fb3f341ce6e926a1678cc33db7f3   True      False      False      5              5                   5                     0                      40d
[root@bastion-01 mcp]#

内容如下。

[root@bastion-01 mcp]# oc get mcp infra -o yaml
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfigPool
spec:
  (略)
  machineConfigSelector:
    matchExpressions:
    - key: machineconfiguration.openshift.io/role
      operator: In
      values:
      - worker
      - infra
  nodeSelector:
    matchLabels:
      node-role.kubernetes.io/infra: ""
(略)

为了将创建的用于基础架构的”MCP”和”Node”关联起来,从基础架构节点的节点标签中移除worker并添加infra。

给infra节点标签

[root@bastion-01 ~]# oc label node infra-01 node-role.kubernetes.io/infra=""
node/infra-01 labeled
[root@bastion-01 ~]# oc label node infra-02 node-role.kubernetes.io/infra=""
node/infra-02 labeled
[root@bastion-01 ~]# oc label node infra-03 node-role.kubernetes.io/infra=""
node/infra-03 labeled
[root@bastion-01 ~]#

删除工作节点标签。

[root@bastion-01 ~]# oc label node infra-01 node-role.kubernetes.io/worker-
node/infra-01 unlabeled
[root@bastion-01 ~]#
[root@bastion-01 ~]# oc label node infra-02 node-role.kubernetes.io/worker-
node/infra-02 unlabeled
[root@bastion-01 ~]#
[root@bastion-01 ~]# oc label node infra-03 node-role.kubernetes.io/worker-
node/infra-03 unlabeled
[root@bastion-01 ~]#

从 infra 节点中,infra 的节点标签已经添加,worker 的节点标签已被删除。

确认节点标签赋值

[root@bastion-01 ~]# oc get node
NAME        STATUS   ROLES    AGE   VERSION
infra-01    Ready    infra    40d   v1.23.5+b0357ed
infra-02    Ready    infra    40d   v1.23.5+b0357ed
infra-03    Ready    infra    40d   v1.23.5+b0357ed
master-01   Ready    master   40d   v1.23.5+b0357ed
master-02   Ready    master   40d   v1.23.5+b0357ed
master-03   Ready    master   40d   v1.23.5+b0357ed
worker-01   Ready    worker   40d   v1.23.5+b0357ed
worker-02   Ready    worker   40d   v1.23.5+b0357ed
[root@bastion-01 ~]#

(仅供参考)

[root@bastion-01 ~]# oc get node infra-01 -o yaml | grep -A 8 labels
  labels:
    beta.kubernetes.io/arch: amd64
    beta.kubernetes.io/os: linux
    kubernetes.io/arch: amd64
    kubernetes.io/hostname: infra-01
    kubernetes.io/os: linux
    node-role.kubernetes.io/infra: ""
    node.openshift.io/os_id: rhcos
  name: infra-01
[root@bastion-01 ~]#

由于 infra 使用的 “MCP” 和 “Node” 相关联,所以 infra node 会自动应用 infra node 专用的 “MC”。
(通常情况下,如果有 “MC” 的更改,节点会自动重新启动并应用新的 “MCP” 的 “MC”。但是,这次 infra 和 worker 都只加载了相同的 “MC”,没有进行任何更改,所以似乎没有重新启动节点。)

infra节点应用infra的”MC”后,可以看到infra的”MCP”中的”MACHINECOUNT”变为3,表明MC已经被应用。

[root@bastion-01 ~]# oc get mcp
NAME     CONFIG                                             UPDATED   UPDATING   DEGRADED   MACHINECOUNT   READYMACHINECOUNT   UPDATEDMACHINECOUNT   DEGRADEDMACHINECOUNT   AGE
infra    rendered-infra-8062fb3f341ce6e926a1678cc33db7f3    True      False      False      3              3                   3                     0                      10m
master   rendered-master-954e86f747cb1bc813dc88a53adc068c   True      False      False      3              3                   3                     0                      40d
worker   rendered-worker-8062fb3f341ce6e926a1678cc33db7f3   True      False      False      2              2                   2                     0                      40d
[root@bastion-01 ~]#

将组件移动到基础节点的infra节点上

将以下运营组件移至基础结点。

    • ルーター

 

    • OCP内部レジストリー

 

    • モニタリング

 

    ロギング

移动通常按照以下文档中的步骤进行实施。

    OCP 4.10 Docs / インストール後の設定 / 5. インストール後のクラスタータスク / 5.6. リソースのインフラストラクチャーマシンセットへの移行

在这里,我们只需要将每个自定义资源的infra节点的nodeSelector进行设置即可。
(taint/tolaration等将在“不在infra节点上运行应用程序Pod的配置”部分进行考虑,所以在本节中只进行了nodeSelector的设置。)

如果想要创建一个专用于监控和记录的基础架构节点,请按照以下方式为节点添加节点标签。

在OCP 4.2中创建一个专用的Infra节点,并将路由器、内部注册表、监控和记录移动到该节点上。

路由器

    OCP 4.10 Docs / インストール後の設定 / 5. インストール後のクラスタータスク / 5.6. リソースのインフラストラクチャーマシンセットへの移行 / 5.6.1. ルーターの移動

首先,我们要确认路由器的Pod是在哪个节点上运行的。
在进行基础设施节点移动设置之前,这次Pod刚好是一开始就在基础设施节点上运行。

[root@bastion-01 ~]# oc get pod -n openshift-ingress -o wide
NAME                             READY   STATUS    RESTARTS   AGE   IP              NODE       NOMINATED NODE   READINESS GATES
router-default-d9585794b-4lm7z   1/1     Running   0          9d    172.16.100.18   infra-02   <none>           <none>
router-default-d9585794b-pvklp   1/1     Running   0          9d    172.16.100.17   infra-01   <none>           <none>
[root@bastion-01 ~]#

(补充) 运算符本身在主节点上运行。

[root@bastion-01 ~]# oc get pod -n openshift-ingress-operator -o wide
NAME                                READY   STATUS    RESTARTS   AGE   IP            NODE        NOMINATED NODE   READINESS GATES
ingress-operator-79fd869977-8clzt   2/2     Running   4          43d   10.130.0.12   master-02   <none>           <none>
[root@bastion-01 ~]#

在ingresscontroller资源中进行设置。

[root@bastion-01 ~]# oc get ingresscontroller -n openshift-ingress-operator
NAME      AGE
default   43d
[root@bastion-01 ~]#

默认情况下,没有nodeSelector的设置,它可以在任意的worker节点上运行。

[root@bastion-01 ~]# oc get ingresscontroller -n openshift-ingress-operator default -o yaml
spec:
  clientTLS:
    clientCA:
      name: ""
    clientCertificatePolicy: ""
  httpCompression: {}
  httpEmptyRequestsPolicy: Respond
  httpErrorCodePages:
    name: ""
  replicas: 2
  tuningOptions: {}
  unsupportedConfigOverrides: null
status:

在spec字段中添加一个nodeSelector,以引用infra标签,如下所示:

  spec:
    nodePlacement:
      nodeSelector:
        matchLabels:
          node-role.kubernetes.io/infra: ""

以下是实际命令。

[root@bastion-01 ~]# oc edit ingresscontroller default -n openshift-ingress-operator
ingresscontroller.operator.openshift.io/default edited
[root@bastion-01 ~]#
[root@bastion-01 ~]# oc get ingresscontroller -n openshift-ingress-operator default -o yaml
(略)
spec:
  clientTLS:
    clientCA:
      name: ""
    clientCertificatePolicy: ""
  httpCompression: {}
  httpEmptyRequestsPolicy: Respond
  httpErrorCodePages:
    name: ""
  nodePlacement:
    nodeSelector:
      matchLabels:
        node-role.kubernetes.io/infra: ""
  replicas: 2
  tuningOptions: {}
  unsupportedConfigOverrides: null
status:
(略)

Pod已被重新创建,并根据nodeSelector,在infra节点上运行。

[root@bastion-01 ~]# oc get pod -n openshift-ingress -o wide
NAME                              READY   STATUS    RESTARTS   AGE     IP              NODE       NOMINATED NODE   READINESS GATES
router-default-77448cc55f-gbg4q   1/1     Running   0          2m44s   172.16.100.18   infra-02   <none>           <none>
router-default-77448cc55f-v2tbz   1/1     Running   0          3m22s   172.16.100.19   infra-03   <none>           <none>
[root@bastion-01 ~]#

OCP内部注册表

    OCP 4.10 Docs / インストール後の設定 / 5. インストール後のクラスタータスク / 5.6. リソースのインフラストラクチャーマシンセットへの移行 / 5.6.2. デフォルトレジストリーの移行

首先,我们需要确认 OCP 内部注册表的 Pod 正在哪个节点上运行。
在进行 infra 节点移动设置之前,这一次,Pod 偶然地一直在 infra 节点上运行。

[root@bastion-01 ~]# oc get pods -n openshift-image-registry -o wide | grep image-registry
cluster-image-registry-operator-7cfd746b9b-7plxd   1/1     Running     0          23d     10.128.0.30     master-03   <none>           <none>
image-registry-646c7bdcfd-gbcnl                    1/1     Running     0          9d      10.128.2.7      infra-02    <none>           <none>
[root@bastion-01 ~]#

设置是在configs.imageregistry.operator.openshift.io资源中进行的。

改动之前

[root@bastion-01 ~]# oc get configs.imageregistry.operator.openshift.io
NAME      AGE
cluster   43d
[root@bastion-01 ~]#

默认情况下,没有设置nodeSelector,因此可以在任意的工作节点上运行。

[root@bastion-01 ~]# oc get configs.imageregistry.operator.openshift.io cluster -o yaml
apiVersion: imageregistry.operator.openshift.io/v1
kind: Config
(略)
spec:
  defaultRoute: true
  httpSecret: ada28eb2bc1bf31d8f826769f8c15a7896215438c2976fc92f89adfdc231d264c9bf0ca1068b32fcc6b4bc080d0bb7df3666b7398016ccd7ff59e317a3cce89a
  logLevel: Normal
  managementState: Managed
  observedConfig: null
  operatorLogLevel: Normal
  proxy: {}
  replicas: 1
  requests:
    read:
      maxWaitInQueue: 0s
    write:
      maxWaitInQueue: 0s
  rolloutStrategy: RollingUpdate
  storage:
    managementState: Unmanaged
    pvc:
      claim: image-registry-storage
  unsupportedConfigOverrides: null
status:
(略)

在spec部分中添加nodeSelector,以引用infra标签,如下所示。

spec:
  nodeSelector:
    node-role.kubernetes.io/infra: ""

实际的指令如下所示。

[root@bastion-01 ~]# oc edit configs.imageregistry.operator.openshift.io cluster
config.imageregistry.operator.openshift.io/cluster edited
[root@bastion-01 ~]#
[root@bastion-01 ~]# oc get configs.imageregistry.operator.openshift.io cluster -o yaml
apiVersion: imageregistry.operator.openshift.io/v1
kind: Config
metadata:
  (略)
spec:
  defaultRoute: true
  httpSecret: ada28eb2bc1bf31d8f826769f8c15a7896215438c2976fc92f89adfdc231d264c9bf0ca1068b32fcc6b4bc080d0bb7df3666b7398016ccd7ff59e317a3cce89a
  logLevel: Normal
  managementState: Managed
  nodeSelector:
    node-role.kubernetes.io/infra: ""
  observedConfig: null
  operatorLogLevel: Normal
  proxy: {}
  replicas: 1
  requests:
    read:
      maxWaitInQueue: 0s
    write:
      maxWaitInQueue: 0s
  rolloutStrategy: RollingUpdate
  storage:
    managementState: Unmanaged
    pvc:
      claim: image-registry-storage
  unsupportedConfigOverrides: null
status:
  (略)

Pod已被重新创建,并根据nodeSelector配置开始在基础设施节点上运行。

[root@bastion-01 ~]# oc get pods -n openshift-image-registry -o wide | grep image-registry
cluster-image-registry-operator-7cfd746b9b-7plxd   1/1     Running     0          23d     10.128.0.30     master-03   <none>           <none>
image-registry-66689994b6-tzvlb                    1/1     Running     0          103s    10.130.2.16     infra-03    <none>           <none>
[root@bastion-01 ~]#

监控

    OCP 4.10 Docs / インストール後の設定 / 5. インストール後のクラスタータスク / 5.6. リソースのインフラストラクチャーマシンセットへの移行 / 5.6.3. モニタリングソリューションの移動

在基础设施节点上运行组成默认监控的组件(Prometheus、Alertmanager、其他组件)。本次没有提及用户工作负载监控组件,但基本上是相同的。(由于打算稍后创建持久卷,所以在这里只是搬移。)

首先,我们需要确认监控Pod是在哪个节点上运行的。

    • operatorのPodはmaster nodeで稼働しています。

 

    • node-exporterはdaemonsetで全nodeで稼働しています。

 

    移動の対象となるモニタリングのそれ以外のPodは、infra node、worker nodeとまちまちで稼働しています。
[root@bastion-01 monitoring]# oc get pod -n openshift-monitoring -o wide
NAME                                          READY   STATUS    RESTARTS   AGE   IP              NODE        NOMINATED NODE   READINESS GATES
alertmanager-main-0                           6/6     Running   12         43d   10.131.0.12     infra-01    <none>           <none>
alertmanager-main-1                           6/6     Running   0          9d    10.131.2.10     worker-01   <none>           <none>
cluster-monitoring-operator-dbcdff999-j5h79   2/2     Running   4          43d   10.130.0.9      master-02   <none>           <none>
grafana-6667f4d5bd-4rz5n                      3/3     Running   0          9d    10.128.2.9      infra-02    <none>           <none>
kube-state-metrics-6977cbc464-zrq2b           3/3     Running   6          43d   10.131.0.11     infra-01    <none>           <none>
node-exporter-2nk6f                           2/2     Running   4          43d   172.16.100.15   master-02   <none>           <none>
node-exporter-2sz27                           2/2     Running   4          43d   172.16.100.16   master-03   <none>           <none>
node-exporter-9dwjq                           2/2     Running   10         43d   172.16.100.18   infra-02    <none>           <none>
node-exporter-9ws9c                           2/2     Running   10         43d   172.16.100.19   infra-03    <none>           <none>
node-exporter-9z76z                           2/2     Running   6          43d   172.16.100.23   worker-01   <none>           <none>
node-exporter-lvl5p                           2/2     Running   6          43d   172.16.100.14   master-01   <none>           <none>
node-exporter-mjvd4                           2/2     Running   4          43d   172.16.100.17   infra-01    <none>           <none>
node-exporter-rkwmj                           2/2     Running   6          43d   172.16.100.24   worker-02   <none>           <none>
openshift-state-metrics-6b498b7995-crfll      3/3     Running   6          43d   10.131.0.7      infra-01    <none>           <none>
prometheus-adapter-7c7548d778-bq56l           1/1     Running   0          9d    10.128.2.6      infra-02    <none>           <none>
prometheus-adapter-7c7548d778-xrmwj           1/1     Running   0          11d   10.131.0.57     infra-01    <none>           <none>
prometheus-k8s-0                              6/6     Running   12         43d   10.131.0.3      infra-01    <none>           <none>
prometheus-k8s-1                              6/6     Running   0          9d    10.131.2.11     worker-01   <none>           <none>
prometheus-operator-67f5c64764-krg5s          2/2     Running   0          23d   10.130.0.53     master-02   <none>           <none>
telemeter-client-74f7d775fb-wnfhz             3/3     Running   6          43d   10.131.0.6      infra-01    <none>           <none>
thanos-querier-84ddf75d5c-29rxz               6/6     Running   0          9d    10.128.2.8      infra-02    <none>           <none>
thanos-querier-84ddf75d5c-7gt8v               6/6     Running   12         43d   10.131.0.2      infra-01    <none>           <none>
[root@bastion-01 monitoring]#

设置使用ConfigMap进行。

前往用于创建清单文件的工作目录并创建用于配置监视的ConfigMap清单文件。
ConfigMap的名称设置为cluster-monitoring-config。
根据下面所示,在监视所有组件的部分中添加引用infra标签的nodeSelector。

[root@bastion-01 ~]# mkdir -p work/manifest/monitoring
[root@bastion-01 ~]# cd work/manifest/monitoring/
[root@bastion-01 monitoring]#
[root@bastion-01 monitoring]# vi cluster-monitoring-configmap.yaml
[root@bastion-01 monitoring]# cat cluster-monitoring-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: cluster-monitoring-config
  namespace: openshift-monitoring
data:
  config.yaml: |+
    alertmanagerMain:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
    prometheusK8s:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
    prometheusOperator:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
    grafana:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
    k8sPrometheusAdapter:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
    kubeStateMetrics:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
    telemeterClient:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
    openshiftStateMetrics:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
    thanosQuerier:
      nodeSelector:
        node-role.kubernetes.io/infra: ""

应用前述 ConfigMap 的清单文件。

[root@bastion-01 monitoring]# oc get cm -n openshift-monitoring cluster-monitoring-config
Error from server (NotFound): configmaps "cluster-monitoring-config" not found
[root@bastion-01 monitoring]#
[root@bastion-01 monitoring]#
[root@bastion-01 monitoring]# oc apply -f cluster-monitoring-configmap.yaml
configmap/cluster-monitoring-config created
[root@bastion-01 monitoring]#
[root@bastion-01 monitoring]# oc get cm -n openshift-monitoring cluster-monitoring-config
NAME                        DATA   AGE
cluster-monitoring-config   1      5s
[root@bastion-01 monitoring]#

Pod被重新创建,与监测相关的Pod根据nodeSelector的设定开始在基础设施节点上运行。

[root@bastion-01 monitoring]# oc get pod -n openshift-monitoring -o wide
NAME                                          READY   STATUS    RESTARTS   AGE     IP              NODE        NOMINATED NODE   READINESS GATES
alertmanager-main-0                           6/6     Running   0          2m46s   10.131.0.195    infra-01    <none>           <none>
alertmanager-main-1                           6/6     Running   0          3m18s   10.128.2.12     infra-02    <none>           <none>
cluster-monitoring-operator-dbcdff999-j5h79   2/2     Running   4          43d     10.130.0.9      master-02   <none>           <none>
grafana-d9b6fb97f-hswc9                       3/3     Running   0          3m19s   10.128.2.11     infra-02    <none>           <none>
kube-state-metrics-67784595cf-wd429           3/3     Running   0          3m21s   10.131.0.191    infra-01    <none>           <none>
node-exporter-2nk6f                           2/2     Running   4          43d     172.16.100.15   master-02   <none>           <none>
node-exporter-2sz27                           2/2     Running   4          43d     172.16.100.16   master-03   <none>           <none>
node-exporter-9dwjq                           2/2     Running   10         43d     172.16.100.18   infra-02    <none>           <none>
node-exporter-9ws9c                           2/2     Running   10         43d     172.16.100.19   infra-03    <none>           <none>
node-exporter-9z76z                           2/2     Running   6          43d     172.16.100.23   worker-01   <none>           <none>
node-exporter-lvl5p                           2/2     Running   6          43d     172.16.100.14   master-01   <none>           <none>
node-exporter-mjvd4                           2/2     Running   4          43d     172.16.100.17   infra-01    <none>           <none>
node-exporter-rkwmj                           2/2     Running   6          43d     172.16.100.24   worker-02   <none>           <none>
openshift-state-metrics-5977697c96-n8bpb      3/3     Running   0          3m21s   10.131.0.192    infra-01    <none>           <none>
prometheus-adapter-576d7d5d57-f68tw           1/1     Running   0          3m21s   10.128.2.13     infra-02    <none>           <none>
prometheus-adapter-576d7d5d57-jqf2f           1/1     Running   0          3m21s   10.130.2.17     infra-03    <none>           <none>
prometheus-k8s-0                              6/6     Running   0          2m56s   10.131.0.194    infra-01    <none>           <none>
prometheus-k8s-1                              6/6     Running   0          3m14s   10.128.2.15     infra-02    <none>           <none>
prometheus-operator-6b8cc99f77-6krtp          2/2     Running   0          3m29s   10.128.2.10     infra-02    <none>           <none>
telemeter-client-7966478b86-nz24b             3/3     Running   0          3m21s   10.131.0.193    infra-01    <none>           <none>
thanos-querier-5b4f5d7b56-lv9sh               6/6     Running   0          3m18s   10.130.2.18     infra-03    <none>           <none>
thanos-querier-5b4f5d7b56-svw8c               6/6     Running   0          3m18s   10.128.2.14     infra-02    <none>           <none>
[root@bastion-01 monitoring]#

记录

    OCP 4.10 Docs / インストール後の設定 / 5. インストール後のクラスタータスク / 5.6. リソースのインフラストラクチャーマシンセットへの移行 / 5.6.4. OpenShift Logging リソースの移動

由于之前还没有记录,所以现在在这里引入日志记录。
日志记录的引入步骤如下。

    1. 部署OpenShift Elasticsearch Operator

 

    1. 部署Red Hat OpenShift Logging Operator

 

    创建日志实例(ClusterLogging资源),在此设置elasticsearch和kibana的nodeSlector。

这次我们在GUI中引入了Operator。由于Operator的引入程序如下所示,所以我将省略。

    OCP 4.10 Docs / Logging / 3. Installing the logging subsystem for Red Hat OpenShift / 3.1. Installing the logging subsystem for Red Hat OpenShift using the web console

完成OpenShift Elasticsearch Operator和Red Hat OpenShift Logging Operator的安装后,可以创建日志实例(ClusterLogging资源)。
切换到用于创建清单文件的工作目录,并创建清单文件。

创建群集日志记录实例时,还需要在nodeSelector中添加elasticsearch和kibana,使它们最初在infra节点上运行。

其他设置如下。

redundancyPolicyはSingleRedundancyとし、elasticsearchの{nodeCountは3としています。
PVは別途local-storage operatoでelasticsarch用のlocalvolumeリソースで作成する予定ですが、ここでは一旦PVは作成せずにインスタンスを作成しています。(RHCOSの内蔵ディスクが溢れるのでPVはすぐに作成する必要があるので本当はこの時点でlocalvolumeを作成してPVの設定もしてしまった方が良いと思います。)

[root@bastion-01 ~]# mkdir -p work/manifest/logging
[root@bastion-01 ~]# cd work/manifest/logging/
[root@bastion-01 logging]#
[root@bastion-01 logging]# vi clo-instance-5.4-no-pv.yaml
[root@bastion-01 logging]# cat clo-instance-5.4-no-pv.yaml
apiVersion: "logging.openshift.io/v1"
kind: "ClusterLogging"
metadata:
  name: "instance"
  namespace: "openshift-logging"
spec:
  managementState: "Managed"
  logStore:
    type: "elasticsearch"
    retentionPolicy:
      application:
        maxAge: 1d
      infra:
        maxAge: 1d
      audit:
        maxAge: 1d
    elasticsearch:
      nodeCount: 3
      nodeSelector:
        node-role.kubernetes.io/infra: ''
      storage: {}
      redundancyPolicy: "SingleRedundancy"
  visualization:
    type: "kibana"
    kibana:
      replicas: 1
      nodeSelector:
        node-role.kubernetes.io/infra: ''
  collection:
    logs:
      type: "fluentd"
      fluentd: {}

创建一个日志实例(集群日志资源)。

[root@bastion-01 logging]# oc apply -f clo-instance-5.4-no-pv.yaml
clusterlogging.logging.openshift.io/instance created
[root@bastion-01 logging]#
[root@bastion-01 logging]# oc get clusterlogging -n openshift-logging
NAME       MANAGEMENT STATE
instance   Managed
[root@bastion-01 logging]#

我要确认Pod正在哪个节点上运行。

    • collector(fluentd)以外のelasticsearchとkibanaのPodはinfra node上で稼働しています。

 

    (collector(fluentd)は、daemonsetとして、全node上で稼働しています。)
[root@bastion-01 logging]# oc get pod -n openshift-logging -o wide
NAME                                            READY   STATUS    RESTARTS   AGE   IP             NODE        NOMINATED NODE   READINESS GATES
cluster-logging-operator-665847fd47-4k8nk       1/1     Running   0          45m   10.131.0.105   infra-01    <none>           <none>
collector-44jz9                                 2/2     Running   0          20s   10.128.2.14    infra-02    <none>           <none>
collector-56t5f                                 2/2     Running   0          20s   10.131.2.7     worker-01   <none>           <none>
collector-75fc4                                 2/2     Running   0          20s   10.129.2.8     worker-02   <none>           <none>
collector-8xvrk                                 2/2     Running   0          26s   10.129.1.120   master-01   <none>           <none>
collector-dfg8g                                 2/2     Running   0          18s   10.130.2.15    infra-03    <none>           <none>
collector-nlg28                                 2/2     Running   0          25s   10.130.0.38    master-02   <none>           <none>
collector-qhx2x                                 2/2     Running   0          24s   10.131.0.111   infra-01    <none>           <none>
collector-tssdz                                 2/2     Running   0          27s   10.128.0.154   master-03   <none>           <none>
elasticsearch-cdm-hxg5zzyz-1-6c7cc986d5-r8vtk   1/2     Running   0          88s   10.128.2.12    infra-02    <none>           <none>
elasticsearch-cdm-hxg5zzyz-2-6c459cd687-dd8kr   1/2     Running   0          87s   10.131.0.109   infra-01    <none>           <none>
elasticsearch-cdm-hxg5zzyz-3-6c4c778db5-zttmd   1/2     Running   0          86s   10.130.2.14    infra-03    <none>           <none>
kibana-95cdccd9b-mbpvp                          2/2     Running   0          86s   10.130.2.13    infra-03    <none>           <none>
[root@bastion-01 logging]#

在这里,我们将省略在Kibana中创建索引模式以及公开日志存储根目录等内容。

不要在基础设施节点上运行应用程序Pod的配置。

我们创建了infra节点,并将运维组件放置在infra节点上运行。
接下来,我们需要进行配置,使应用程序Pod不在infra节点上运行。

在infra节点上不运行应用程序Pod的设置方法主要有以下两种。

    • (1) nodeSelectorのみを使用

 

    (2) nodeSelectorとtaint/tolerationを使用

可以选任何一种,但这次我们选择只使用「(1)仅使用nodeSelector」的方法。

只需使用nodeSelector。

(Note: This is a transliteration of the original phrase using pinyin, as it is not possible to directly input Chinese characters in this text-based format.)

本次,infra节点和worker节点分别具有“node-role.kubernetes.io/infra: “””和“node-role.kubernetes.io/worker: “””这两个节点标签,并且在oc get node的ROLES值中也分别显示为infra和worker。

(节点标签确认)

[root@bastion-01 ~]# oc get node
NAME        STATUS   ROLES    AGE   VERSION
infra-01    Ready    infra    40d   v1.23.5+b0357ed
infra-02    Ready    infra    40d   v1.23.5+b0357ed
infra-03    Ready    infra    40d   v1.23.5+b0357ed
master-01   Ready    master   40d   v1.23.5+b0357ed
master-02   Ready    master   40d   v1.23.5+b0357ed
master-03   Ready    master   40d   v1.23.5+b0357ed
worker-01   Ready    worker   40d   v1.23.5+b0357ed
worker-02   Ready    worker   40d   v1.23.5+b0357ed
[root@bastion-01 ~]#

参考:基础设施节点

[root@bastion-01 ~]# oc get node infra-01 -o yaml | grep -A 8 labels
  labels:
    beta.kubernetes.io/arch: amd64
    beta.kubernetes.io/os: linux
    kubernetes.io/arch: amd64
    kubernetes.io/hostname: infra-01
    kubernetes.io/os: linux
    node-role.kubernetes.io/infra: ""
    node.openshift.io/os_id: rhcos
  name: infra-01
[root@bastion-01 ~]#

(参考)工作节点

[root@bastion-01 ~]# oc get node worker-01 -o yaml | grep -A 8 labels
  labels:
    beta.kubernetes.io/arch: amd64
    beta.kubernetes.io/os: linux
    kubernetes.io/arch: amd64
    kubernetes.io/hostname: worker-01
    kubernetes.io/os: linux
    node-role.kubernetes.io/worker: ""
    node.openshift.io/os_id: rhcos
  name: worker-01
[root@bastion-01 ~]#

在运行应用程序Pod的项目(命名空间)中,将worker node的节点标签 “node-role.kubernetes.io/worker: “” ” 指定为nodeSelector。通过这个设置,当在为该应用程序Pod专用的项目(命名空间)部署Pod时,Pod将始终在该worker node上创建。

创建适用于应用程序Pod的项目。

[root@bastion-01 ~]# oc new-project test
Now using project "test" on server "https://api.cluster-01.example.local:6443".

You can add applications to this project with the 'new-app' command. For example, try:

    oc new-app rails-postgresql-example

to build a new example application in Ruby. Or use kubectl to deploy a simple Kubernetes application:

    kubectl create deployment hello-node --image=k8s.gcr.io/e2e-test-images/agnhost:2.33 -- /agnhost serve-hostname

[root@bastion-01 ~]#

将worker节点上分配的节点标签设置为openshift.io/node-selector的命名空间,适用于应用程序Pod。

[root@bastion-01 ~]# oc annotate namespace test openshift.io/node-selector=node-role.kubernetes.io/worker=
namespace/test annotated
[root@bastion-01 ~]#
[root@bastion-01 ~]# oc get ns test -o yaml
apiVersion: v1
kind: Namespace
metadata:
  annotations:
    openshift.io/description: ""
    openshift.io/display-name: ""
    openshift.io/node-selector: node-role.kubernetes.io/worker=
    openshift.io/requester: admin
    openshift.io/sa.scc.mcs: s0:c26,c20
    openshift.io/sa.scc.supplemental-groups: 1000690000/10000
    openshift.io/sa.scc.uid-range: 1000690000/10000
  creationTimestamp: "2022-06-02T06:29:55Z"
  labels:
    kubernetes.io/metadata.name: test
  name: test
  resourceVersion: "33443927"
  uid: 6471fde8-6ef0-4f29-b1f5-f6b227ea566d
spec:
  finalizers:
  - kubernetes
status:
  phase: Active
[root@bastion-01 ~]#

通过这样做,在这个项目(命名空间)中创建的Pod将不在基础设施节点上运行,而是在工作节点上运行。

如果没有创建专门用于基础设施节点的MCP。

如果您选择使用“infra节点的配置方法”来配置infra节点所需的worker节点并通过为infra节点添加“节点标签”来进行配置,而不创建专用于infra节点的“MCP”,那么还需要稍微做些调整。

在这种情况下,由于MCP只有主节点和工作节点的用途,为了将工作节点的MCP与基础设施节点关联起来,我们不会删除工作节点的节点标签。
(如果删除工作节点的节点标签,将无法进行OCP更新,因为没有相应的MCP来支持版本升级。)

[root@bastion-01 mcp]# oc get mcp
NAME     CONFIG                                             UPDATED   UPDATING   DEGRADED   MACHINECOUNT   READYMACHINECOUNT   UPDATEDMACHINECOUNT   DEGRADEDMACHINECOUNT   AGE
master   rendered-master-954e86f747cb1bc813dc88a53adc068c   True      False      False      3              3                   3                     0                      40d
worker   rendered-worker-8062fb3f341ce6e926a1678cc33db7f3   True      False      False      5              5                   5                     0                      40d
[root@bastion-01 mcp]#
[root@bastion-01 ~]# oc get node
NAME        STATUS   ROLES          AGE   VERSION
infra-01    Ready    infra,worker   63d   v1.23.5+b0357ed
infra-02    Ready    infra,worker   63d   v1.23.5+b0357ed
infra-03    Ready    infra,worker   63d   v1.23.5+b0357ed
master-01   Ready    master         63d   v1.23.5+b0357ed
master-02   Ready    master         63d   v1.23.5+b0357ed
master-03   Ready    master         63d   v1.23.5+b0357ed
worker-01   Ready    worker         63d   v1.23.5+b0357ed
worker-02   Ready    worker         63d   v1.23.5+b0357ed
[root@bastion-01 ~]#

在这种情况下,如果为应用程序Pod的项目(命名空间)指定”node-role.kubernetes.io/worker: “”,那么基础设施节点也可能会运行,因此要为应用程序Pod附加任意的节点标签。
实际上,可以是任何标签,如”app=”app-1″,但是如果将其设置成”node-role.kubernetes.io/app: “”,那么在oc get node的ROLES列中将显示出app,这样就更容易知道哪个节点是用于应用程序Pod的。

我想要在希望运行应用程序Pod的worker节点上,为节点添加标签node-role.kubernetes.io/app=””。

[root@bastion-01 ~]# oc label node worker-01 node-role.kubernetes.io/app=""
node/worker-01 labeled
[root@bastion-01 ~]# oc label node worker-02 node-role.kubernetes.io/app=""
node/worker-02 labeled
[root@bastion-01 ~]#

工人-01

[root@bastion-01 ~]# oc get node worker-01 -o yaml | grep -A 9 labels
  labels:
    beta.kubernetes.io/arch: amd64
    beta.kubernetes.io/os: linux
    kubernetes.io/arch: amd64
    kubernetes.io/hostname: worker-01
    kubernetes.io/os: linux
    node-role.kubernetes.io/app: ""
    node-role.kubernetes.io/worker: ""
    node.openshift.io/os_id: rhcos
  name: worker-01
[root@bastion-01 ~]#

在oc get node命令中,ROLES列显示了app这个角色。

[root@bastion-01 ~]# oc get node
NAME        STATUS   ROLES          AGE   VERSION
infra-01    Ready    infra,worker   63d   v1.23.5+b0357ed
infra-02    Ready    infra,worker   63d   v1.23.5+b0357ed
infra-03    Ready    infra,worker   63d   v1.23.5+b0357ed
master-01   Ready    master         63d   v1.23.5+b0357ed
master-02   Ready    master         63d   v1.23.5+b0357ed
master-03   Ready    master         63d   v1.23.5+b0357ed
worker-01   Ready    app,worker     63d   v1.23.5+b0357ed
worker-02   Ready    app,worker     63d   v1.23.5+b0357ed
[root@bastion-01 ~]#

只需一种选择,以下是对该句进行中文翻译的结果:
然后,在运行应用程序的项目(命名空间)中指定刚才给worker节点分配的节点标签作为nodeSelector。这样,在这个项目(命名空间)中创建的Pod将在指定的worker节点上运行。

[root@bastion-01 ~]# oc new-project test
Now using project "test" on server "https://api.cluster-01.example.local:6443".

You can add applications to this project with the 'new-app' command. For example, try:

    oc new-app rails-postgresql-example

to build a new example application in Ruby. Or use kubectl to deploy a simple Kubernetes application:

    kubectl create deployment hello-node --image=k8s.gcr.io/e2e-test-images/agnhost:2.33 -- /agnhost serve-hostname

[root@bastion-01 ~]#
[root@bastion-01 ~]# oc annotate namespace test openshift.io/node-selector=node-role.kubernetes.io/app=
namespace/test annotated
[root@bastion-01 ~]#
[root@bastion-01 ~]# oc get ns test -o yaml
apiVersion: v1
kind: Namespace
metadata:
  annotations:
    openshift.io/description: ""
    openshift.io/display-name: ""
    openshift.io/node-selector: node-role.kubernetes.io/app=
    openshift.io/requester: admin
    openshift.io/sa.scc.mcs: s0:c26,c5
    openshift.io/sa.scc.supplemental-groups: 1000660000/10000
    openshift.io/sa.scc.uid-range: 1000660000/10000
  creationTimestamp: "2022-05-09T12:10:37Z"
  labels:
    kubernetes.io/metadata.name: test
  name: test
  resourceVersion: "19316925"
  uid: 7de494d4-4974-4b69-8bbb-ab36b8c69b4c
spec:
  finalizers:
  - kubernetes
status:
  phase: Active
[root@bastion-01 ~]#

在考虑这种方法时,如果要添加新的工作节点或者在节点故障时重新安装RHCOS,就需要记得为应用程序Pod分配节点标签。

使用nodeSelector和taint/toleration来填充(补足) (2)。

这次虽然没做,但有一种在工作节点上运行应用程序Pod的方法是给infra节点添加taint。
为了给infra节点添加taint,当创建应用程序Pod时,它将在没有taint的工作节点上运行。
然而,为了实现在infra节点上运行,需要在基础设施的操作组件(路由器、OCP内部注册表、监控、日志记录)上指定toleration。

詳細信息可以在以下的知識庫中找到。

    KB / Infrastructure Nodes in OpenShift 4

我认为在OCP的文件中大概是以下这些的意思。

    • OCP 4.10 Docs / インストール後の設定 / 5. インストール後のクラスタータスク / 5.5. マシンセットリソースのインフラストラクチャーノードへの割り当て / 5.5.1. テイントおよび容認を使用したインフラストラクチャーノードのワークロードのバインディング

 

    • OCP 4.10 Docs / ネットワーク / 5. OPENSHIFT CONTAINER PLATFORM の INGRESS OPERATOR / 5.3. Ingress コントローラー設定パラメーター

 

    • OCP 4.10 Docs / モニタリング / 2. モニタリングスタックの設定 / 2.7. モニタリングコンポーネントへの容認 (toleration) の割り当て

 

    OCP 4.10 Docs / ロギング / 22. ロギングデプロイメントの設定 / 22.7. 容認を使用した OpenShift Logging Pod 配置の制御

大致上,以下是大多数情况的流程,但我会在监控方面举一些例子。

在 Infra 节点上设置 Taint。

[root@bastion-01 ~]# oc label node <infra node> node-role.kubernetes.io/infra=
[root@bastion-01 ~]# oc adm taint nodes -l node-role.kubernetes.io/infra infra=reserved:NoSchedule infra=reserved:NoExecute

运维组件可以在基础设施节点上设置节点选择器和容忍设置。

(例) 监控(cluster-monitoring-configmap.yaml)

apiVersion: v1
kind: ConfigMap
metadata:
  name: cluster-monitoring-config
  namespace: openshift-monitoring
data:
  config.yaml: |+
    alertmanagerMain:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
      tolerations:
      - key: infra
        value: reserved
        effect: NoSchedule
      - key: infra
        value: reserved
        effect: NoExecute
    prometheusK8s:
      (以下同様)

通过这种方式,应用程序Pod可以在不进行任何设置的情况下,在worker节点上通过基础设施节点的Taint设置而运行。

不论是只使用” (1) nodeSelector” ,还是同时使用 ” (2) nodeSelector和 taint/toleration” ,都可以。但就个人而言,我认为只使用” (1) nodeSelector” 更简单。

广告
将在 10 秒后关闭
bannerAds