配置集群


OpenShift Container Platform 3.11

OpenShift Container Platform 3.11 安装和配置

摘要

OpenShift 安装和配置主题涵盖环境中安装和配置 OpenShift 的基础知识。将这些主题用于启动和运行 OpenShift 所需的一次性任务。

第 1 章 概述

本指南涵盖了安装后 OpenShift Container Platform 集群的更多配置选项。

第 2 章 设置 Registry

2.1. 内部 Registry 概述

2.1.1. 关于 Registry

OpenShift Container Platform 可以从源代码构建 容器镜像,部署并管理它们的生命周期。为此,OpenShift Container Platform 提供了一个内部集成的容器镜像 registry,可在 OpenShift Container Platform 环境中部署以在本地管理镜像。

2.1.2. 集成的或独立 registry

在初始安装完整 OpenShift Container Platform 集群期间,可能会在安装过程中自动部署 registry。如果没有,或者您要进一步自定义 registry 的配置,请参阅在现有集群中部署 registry。

虽然它可以部署为作为完整 OpenShift Container Platform 集群集成的一部分运行,但 OpenShift Container Platform registry 可以作为独立容器镜像 registry 单独安装。

要安装独立 registry,请遵循安装独立 Registry。此安装路径部署运行 registry 和专用 Web 控制台的一体化集群。

2.2. 在现有集群中部署 registry

2.2.1. 概述

如果集成的 registry 之前在 OpenShift Container Platform 集群的初始安装过程中没有被自动部署,或者如果不再成功运行,您需要在现有集群中重新部署它,请参阅以下部分来了解部署新 registry 的选项。

注意

如果您安装了 独立 registry,则不需要这个主题。

2.2.2. 设置 Registry 主机名

您可以为内部和外部引用配置 registry 的主机名和端口。通过这样做,镜像流将为镜像提供基于主机名的推送和拉取规格,允许使用镜像与对 registry 服务 IP 的更改进行隔离,并有可能允许镜像流及其引用在集群中可移植。

要设置从集群内部引用 registry 的主机名,请在 master 配置文件的 imagePolicyConfig 部分中设置 internalRegistryHostname。外部主机名通过在同一位置设置 externalRegistryHostname 值来控制。

镜像策略配置

imagePolicyConfig:
  internalRegistryHostname: docker-registry.default.svc.cluster.local:5000
  externalRegistryHostname: docker-registry.mycompany.com
Copy to Clipboard Toggle word wrap

registry 本身必须使用相同的内部主机名值进行配置。这可以通过在 registry 署配置中设置 REGISTRY_OPENSHIFT_SERVER_ADDR 环境变量或设置 registry 配置的 OpenShift 部分中的值来完成。

注意

如果您已经为 registry 启用了 TLS,服务器证书必须包含您希望引用 registry 的主机名。有关添加主机名到服务器证书的说明,请参阅保护registry

2.2.3. 部署 Registry

要部署集成的容器镜像 registry,请以具有集群管理员特权的用户身份使用 oc adm registry 命令。例如:

$ oc adm registry --config=/etc/origin/master/admin.kubeconfig \
1

    --service-account=registry \
2

    --images='registry.redhat.io/openshift3/ose-${component}:${version}' 
3
Copy to Clipboard Toggle word wrap
1
--config集群管理员 CLI 配置文件 的路径。
2
--service-account 是用于运行 registry pod 的服务帐户。
3
为 OpenShift Container Platform 拉取正确的镜像是必需的。${component}${version} 在安装过程中会被动态替换。

这将创建服务和部署配置,两者均称为 docker-registry。部署成功后,会使用类似于 docker-registry-1-cpty9 的名称创建 pod。

查看创建 registry 时可以指定的完整选项列表:

$ oc adm registry --help
Copy to Clipboard Toggle word wrap

--fs-group 的值需要是 registry 使用的 SCC 所允许的(通常为有限制的 SCC)。

2.2.4. 将 Registry 部署为 DaemonSet

使用 oc adm registry 命令将 registry 部署为带有 --daemonset 选项的 DaemonSet

DaemonSet 可确保在创建节点时,节点包含指定 pod 的副本。删除节点时,会收集 pod。

如需有关 DaemonSet 的更多信息,请参阅使用 Daemonsets

2.2.5. registry 计算资源

默认情况下,创建 registry 时没有设置计算资源请求或限值。对于生产环境,强烈建议更新 registry 的部署配置,以便为 registry 容器集设置资源请求和限值。否则,registry pod 将被视为 BestEffort pod

有关配置请求和限制的更多信息,请参阅计算资源

2.2.6. Registry 的存储

registry 存储容器镜像和元数据。如果您只是使用 registry 来部署 pod,它会使用一个在 pod 退出时销毁的临时卷。任何用户已构建或推送到 registry 的镜像都会消失。

本节列出了支持的 registry 存储驱动程序。如需更多信息,请参阅容器镜像 registry 文档

以下列表包括在 registry 配置文件中需要配置的存储驱动程序:

支持常规 registry 存储配置选项。如需更多信息,请参阅容器镜像 registry 文档

以下存储选项需要通过文件系统驱动程序配置:

注意

如需有关支持的持久性存储驱动程序的更多信息,请参阅配置持久性存储持久性存储示例

2.2.6.1. 产品使用

对于生产环境,请附加一个远程卷,或者 定义和使用您选择的持久性存储方法

例如,使用现有持久性卷声明:

$ oc set volume deploymentconfigs/docker-registry --add --name=registry-storage -t pvc \
     --claim-name=<pvc_name> --overwrite
Copy to Clipboard Toggle word wrap
重要

测试显示,使用 RHEL NFS 服务器作为容器镜像 registry 的存储后端会出现问题。这包括 OpenShift Container Registry 和 Quay。因此,不建议使用 RHEL NFS 服务器来备份核心服务使用的 PV。

市场上的其他 NFS 实现可能没有这些问题。如需了解更多与此问题相关的信息,请联络相关的 NFS 厂商。

2.2.6.1.1. 使用 Amazon S3 作为存储后端

还有一个选项,可以将 Amazon Simple Storage Service 存储与内部容器镜像 registry 搭配使用。它是一种安全云存储,可通过 AWS 管理控制台进行管理。要使用它,必须手动编辑注册表的配置文件并将其挂载到 registry Pod。但是,在开始配置之前,请查看上游的建议步骤

采用 默认 YAML 配置文件作为基础,并将 storage 部分中的 filesystem 条目替换为 s3 条目,如下方所示:生成的存储部分可能类似如下:

storage:
  cache:
    layerinfo: inmemory
  delete:
    enabled: true
  s3:
    accesskey: awsaccesskey 
1

    secretkey: awssecretkey 
2

    region: us-west-1
    regionendpoint: http://myobjects.local
    bucket: bucketname
    encrypt: true
    keyid: mykeyid
    secure: true
    v4auth: false
    chunksize: 5242880
    rootdirectory: /s3/object/name/prefix
Copy to Clipboard Toggle word wrap
1
使用您的 Amazon 访问密钥替换。
2
使用您的 Amazon secret 密钥替换。

所有 s3 配置选项都记录在上游 驱动程序参考文档中

覆盖 registry 配置将引导您完成将配置文件挂载到 pod 的其他步骤。

警告

当 registry 在 S3 存储后端上运行时,会报告问题

如果要使用您正在使用的集成 registry 不支持的 S3 区域,请参阅 S3 驱动程序配置

2.2.6.2. 非生产环境中的使用

对于非生产环境,您可以使用 --mount-host=<path> 选项为 registry 指定用于持久性存储的目录。然后,registry 卷在指定的 <path> 上创建为 host-mount。

重要

mount-host 选项可从 registry 容器所在的节点上挂载目录。如果扩展 docker-registry 部署配置,您的 registry Pod 和容器可能会在不同节点上运行,这可能会导致两个或多个 registry 容器,每个容器都有自己的本地存储。这会导致无法预测的行为,因为后续的拉取同一镜像的请求可能并不总是成功,具体取决于请求最终所针对的容器。

--mount-host 选项要求 registry 容器以特权模式运行。这在指定 --mount-host 时自动启用。但是,并非所有 pod 都默认允许运行特权容器。如果您仍然希望使用这个选项,请创建 registry 并指定它使用在安装过程中创建的 registry 服务帐户:

$ oc adm registry --service-account=registry \
    --config=/etc/origin/master/admin.kubeconfig \
    --images='registry.redhat.io/openshift3/ose-${component}:${version}' \ 
1

    --mount-host=<path>
Copy to Clipboard Toggle word wrap
1
为 OpenShift Container Platform 拉取正确的镜像是必需的。${component}${version} 在安装过程中会被动态替换。
重要

容器镜像 registry 容器集以用户 1001 身份运行。此用户必须能够写入主机目录。使用以下命令,您可能需要将目录所有权改为用户 ID 1001

$ sudo chown 1001:root <path>
Copy to Clipboard Toggle word wrap

2.2.7. 启用 Registry 控制台

OpenShift Container Platform 为集成的 registry 提供了一个基于 Web 的界面。此 registry 控制台是浏览和管理镜像的可选组件。它部署为作为容器集运行的无状态服务。

注意

如果将 OpenShift Container Platform 作为独立 registry 安装,则 registry 控制台在安装过程中会自动部署和保护。

重要

如果 Cockpit 已在运行,您需要先将其关闭,然后才能继续,以避免与 registry 控制台造成端口冲突(默认为 9090)。

2.2.7.1. 部署 Registry 控制台
重要

您必须首先 公开 registry

  1. default 项目中创建一个 passthrough 路由。下一步中创建 registry 控制台应用时,您将需要此设置。

    $ oc create route passthrough --service registry-console \
        --port registry-console \
        -n default
    Copy to Clipboard Toggle word wrap
  2. 部署 registry 控制台应用。将 <openshift_oauth_url> 替换为 OpenShift Container Platform OAuth 供应商的 URL,通常是 master。

    $ oc new-app -n default --template=registry-console \
        -p OPENSHIFT_OAUTH_PROVIDER_URL="https://<openshift_oauth_url>:8443" \
        -p REGISTRY_HOST=$(oc get route docker-registry -n default --template='{{ .spec.host }}') \
        -p COCKPIT_KUBE_URL=$(oc get route registry-console -n default --template='https://{{ .spec.host }}')
    Copy to Clipboard Toggle word wrap
    注意

    如果您试图登录到 registry 控制台时重定向 URL 错误,请使用 oc get oauthclients 检查 OAuth 客户端。

  3. 最后,使用 Web 浏览器使用路由 URI 查看控制台。
2.2.7.2. 保护 Registry 控制台

默认情况下,如果按照部署 registry 控制台中的步骤手动部署,registry 控制台会生成自签名 TLS 证书 。如需更多信息,请参阅 对 Registry 控制台进行故障排除

使用以下步骤将组织的签名证书添加为 secret 卷。假设您的证书在 oc 客户端主机上可用。

  1. 创建一个包含证书和密钥的 .cert 文件。使用以下内容格式化文件:

    • 服务器证书和中间证书颁发机构的一个或多个 BEGIN CERTIFICATE
    • 包含该密钥的 BEGIN PRIVATE KEY 或类似密钥的块。密钥不能加密

      例如:

      -----BEGIN CERTIFICATE-----
      MIIDUzCCAjugAwIBAgIJAPXW+CuNYS6QMA0GCSqGSIb3DQEBCwUAMD8xKTAnBgNV
      BAoMIGI0OGE2NGNkNmMwNTQ1YThhZTgxOTEzZDE5YmJjMmRjMRIwEAYDVQQDDAls
      ...
      -----END CERTIFICATE-----
      -----BEGIN CERTIFICATE-----
      MIIDUzCCAjugAwIBAgIJAPXW+CuNYS6QMA0GCSqGSIb3DQEBCwUAMD8xKTAnBgNV
      BAoMIGI0OGE2NGNkNmMwNTQ1YThhZTgxOTEzZDE5YmJjMmRjMRIwEAYDVQQDDAls
      ...
      -----END CERTIFICATE-----
      -----BEGIN PRIVATE KEY-----
      MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCyOJ5garOYw0sm
      8TBCDSqQ/H1awGMzDYdB11xuHHsxYS2VepPMzMzryHR137I4dGFLhvdTvJUH8lUS
      ...
      -----END PRIVATE KEY-----
      Copy to Clipboard Toggle word wrap
    • 安全 registry 应包含以下主题备用名称(SAN)列表:

      • 两个服务主机名:

        例如:

        docker-registry.default.svc.cluster.local
        docker-registry.default.svc
        Copy to Clipboard Toggle word wrap
      • 服务 IP 地址.

        例如:

        172.30.124.220
        Copy to Clipboard Toggle word wrap

        使用以下命令获取容器镜像 registry 服务 IP 地址:

        oc get service docker-registry --template='{{.spec.clusterIP}}'
        Copy to Clipboard Toggle word wrap
      • 公共主机名.

        例如:

        docker-registry-default.apps.example.com
        Copy to Clipboard Toggle word wrap

        使用以下命令获取容器镜像 registry 公共主机名:

        oc get route docker-registry --template '{{.spec.host}}'
        Copy to Clipboard Toggle word wrap

        例如,服务器证书应包含类似如下的 SAN 详情:

        X509v3 Subject Alternative Name:
                       DNS:docker-registry-public.openshift.com, DNS:docker-registry.default.svc, DNS:docker-registry.default.svc.cluster.local, DNS:172.30.2.98, IP Address:172.30.2.98
        Copy to Clipboard Toggle word wrap

        registry 控制台从 /etc/cockpit/ws-certs.d 目录中加载证书。它使用最后一个带有 .cert 扩展名的文件(按字母顺序排列)。因此,.cert 文件应至少包含以 OpenSSL 样式格式化的至少两个 PEM 块。

        如果没有找到证书,将使用 openssl 命令创建自签名证书,并存储在 0-self-signed.cert 文件中。

  2. 创建 secret:

    $ oc create secret generic console-secret \
        --from-file=/path/to/console.cert
    Copy to Clipboard Toggle word wrap
  3. 将 secret 添加到 registry-console 部署配置中:

    $ oc set volume dc/registry-console --add --type=secret \
        --secret-name=console-secret -m /etc/cockpit/ws-certs.d
    Copy to Clipboard Toggle word wrap

    这会触发 registry 控制台的新部署,使其包含您的签名证书。

2.2.7.3. 对 Registry 控制台进行故障排除
2.2.7.3.1. 调试模式

使用环境变量启用 registry 控制台调试模式。以下命令以 debug 模式重新部署 registry 控制台:

$ oc set env dc registry-console G_MESSAGES_DEBUG=cockpit-ws,cockpit-wrapper
Copy to Clipboard Toggle word wrap

启用调试模式允许在 registry 控制台的 pod 日志中显示更详细的日志。

2.2.7.3.2. 显示 SSL 证书路径

要检查 registry 控制台正在使用的证书,可以从控制台容器集内运行命令。

  1. 列出 default 项目中的 pod,并找到 registry 控制台的 pod 名称:

    $ oc get pods -n default
    NAME                       READY     STATUS    RESTARTS   AGE
    registry-console-1-rssrw   1/1       Running   0          1d
    Copy to Clipboard Toggle word wrap
  2. 使用上一命令中的容器集名称,获取 cockpit-ws 进程使用的证书路径。本例演示了使用自动生成的证书的控制台:

    $ oc exec registry-console-1-rssrw remotectl certificate
    certificate: /etc/cockpit/ws-certs.d/0-self-signed.cert
    Copy to Clipboard Toggle word wrap

2.3. 访问 Registry

2.3.1. 查看日志

要查看容器镜像 registry 的日志,请使用带有部署配置的 oc logs 命令:

$ oc logs dc/docker-registry
2015-05-01T19:48:36.300593110Z time="2015-05-01T19:48:36Z" level=info msg="version=v2.0.0+unknown"
2015-05-01T19:48:36.303294724Z time="2015-05-01T19:48:36Z" level=info msg="redis not configured" instance.id=9ed6c43d-23ee-453f-9a4b-031fea646002
2015-05-01T19:48:36.303422845Z time="2015-05-01T19:48:36Z" level=info msg="using inmemory layerinfo cache" instance.id=9ed6c43d-23ee-453f-9a4b-031fea646002
2015-05-01T19:48:36.303433991Z time="2015-05-01T19:48:36Z" level=info msg="Using OpenShift Auth handler"
2015-05-01T19:48:36.303439084Z time="2015-05-01T19:48:36Z" level=info msg="listening on :5000" instance.id=9ed6c43d-23ee-453f-9a4b-031fea646002
Copy to Clipboard Toggle word wrap

2.3.2. 文件存储

标签和镜像元数据存储在 OpenShift Container Platform 中,但 registry 将层和签名数据存储在挂载到位于 /registry 的 registry 容器中的卷中。因为 oc exec 不在特权容器上工作,若要查看 registry 的内容,您必须手动 SSH 到 registry pod 的容器所在的节点,然后在容器本身上运行 docker exec

  1. 列出当前的 pod 以查找容器镜像 registry 的 pod 名称:

    # oc get pods
    Copy to Clipboard Toggle word wrap

    然后,使用 oc describe 来查找运行容器的节点的主机名:

    # oc describe pod <pod_name>
    Copy to Clipboard Toggle word wrap
  2. 登录到所需的节点:

    # ssh node.example.com
    Copy to Clipboard Toggle word wrap
  3. 从节点主机上的默认项目中列出正在运行的容器,并确定容器镜像 registry 的容器 ID:

    # docker ps --filter=name=registry_docker-registry.*_default_
    Copy to Clipboard Toggle word wrap
  4. 使用 oc rsh 命令列出 registry 内容:

    # oc rsh dc/docker-registry find /registry
    /registry/docker
    /registry/docker/registry
    /registry/docker/registry/v2
    /registry/docker/registry/v2/blobs 
    1
    
    /registry/docker/registry/v2/blobs/sha256
    /registry/docker/registry/v2/blobs/sha256/ed
    /registry/docker/registry/v2/blobs/sha256/ed/ede17b139a271d6b1331ca3d83c648c24f92cece5f89d95ac6c34ce751111810
    /registry/docker/registry/v2/blobs/sha256/ed/ede17b139a271d6b1331ca3d83c648c24f92cece5f89d95ac6c34ce751111810/data 
    2
    
    /registry/docker/registry/v2/blobs/sha256/a3
    /registry/docker/registry/v2/blobs/sha256/a3/a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4
    /registry/docker/registry/v2/blobs/sha256/a3/a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4/data
    /registry/docker/registry/v2/blobs/sha256/f7
    /registry/docker/registry/v2/blobs/sha256/f7/f72a00a23f01987b42cb26f259582bb33502bdb0fcf5011e03c60577c4284845
    /registry/docker/registry/v2/blobs/sha256/f7/f72a00a23f01987b42cb26f259582bb33502bdb0fcf5011e03c60577c4284845/data
    /registry/docker/registry/v2/repositories 
    3
    
    /registry/docker/registry/v2/repositories/p1
    /registry/docker/registry/v2/repositories/p1/pause 
    4
    
    /registry/docker/registry/v2/repositories/p1/pause/_manifests
    /registry/docker/registry/v2/repositories/p1/pause/_manifests/revisions
    /registry/docker/registry/v2/repositories/p1/pause/_manifests/revisions/sha256
    /registry/docker/registry/v2/repositories/p1/pause/_manifests/revisions/sha256/e9a2ac6418981897b399d3709f1b4a6d2723cd38a4909215ce2752a5c068b1cf
    /registry/docker/registry/v2/repositories/p1/pause/_manifests/revisions/sha256/e9a2ac6418981897b399d3709f1b4a6d2723cd38a4909215ce2752a5c068b1cf/signatures 
    5
    
    /registry/docker/registry/v2/repositories/p1/pause/_manifests/revisions/sha256/e9a2ac6418981897b399d3709f1b4a6d2723cd38a4909215ce2752a5c068b1cf/signatures/sha256
    /registry/docker/registry/v2/repositories/p1/pause/_manifests/revisions/sha256/e9a2ac6418981897b399d3709f1b4a6d2723cd38a4909215ce2752a5c068b1cf/signatures/sha256/ede17b139a271d6b1331ca3d83c648c24f92cece5f89d95ac6c34ce751111810
    /registry/docker/registry/v2/repositories/p1/pause/_manifests/revisions/sha256/e9a2ac6418981897b399d3709f1b4a6d2723cd38a4909215ce2752a5c068b1cf/signatures/sha256/ede17b139a271d6b1331ca3d83c648c24f92cece5f89d95ac6c34ce751111810/link 
    6
    
    /registry/docker/registry/v2/repositories/p1/pause/_uploads 
    7
    
    /registry/docker/registry/v2/repositories/p1/pause/_layers 
    8
    
    /registry/docker/registry/v2/repositories/p1/pause/_layers/sha256
    /registry/docker/registry/v2/repositories/p1/pause/_layers/sha256/a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4
    /registry/docker/registry/v2/repositories/p1/pause/_layers/sha256/a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4/link 
    9
    
    /registry/docker/registry/v2/repositories/p1/pause/_layers/sha256/f72a00a23f01987b42cb26f259582bb33502bdb0fcf5011e03c60577c4284845
    /registry/docker/registry/v2/repositories/p1/pause/_layers/sha256/f72a00a23f01987b42cb26f259582bb33502bdb0fcf5011e03c60577c4284845/link
    Copy to Clipboard Toggle word wrap
    1
    此目录将所有层和签名存储为 blob。
    2
    此文件包含 blob 的内容。
    3
    此目录存储所有镜像存储库。
    4
    此目录适用于单个镜像存储库 p1/pause
    5
    此目录包含特定镜像清单修订版本的签名。
    6
    此文件包含返回到 blob(包含签名数据)的引用。
    7
    此目录包含目前为给定存储库上传和暂存的任何层。
    8
    此目录包含指向这个存储库引用的所有层的链接。
    9
    此文件包含对已通过镜像链接到该存储库的特定层的引用。

2.3.3. 直接访问 Registry

对于高级用途,您可以直接访问 registry 来调用 docker 命令。这可让您直接使用 docker pushdocker pull 等操作从集成的 registry 中推送镜像或从中提取镜像。为此,您必须使用 docker login 命令登录 registry。您可以执行的操作取决于您的用户权限,如以下各节所述。

2.3.3.1. 用户必备条件

要直接访问 registry,您使用的用户必须满足以下条件,具体取决于您的预期用途:

  • 对于任何直接访问,您必须有首选身份提供程序常规用户。普通用户可以生成登录到 registry 所需的访问令牌。系统用户(如 system:admin )无法获取访问令牌,因此无法直接访问 registry。

    例如,如果您使用 HTPASSWD 身份验证,您可以使用以下命令创建一个:

    # htpasswd /etc/origin/master/htpasswd <user_name>
    Copy to Clipboard Toggle word wrap
  • 若要调取镜像,例如使用 docker pull 命令,用户必须具有 registry-viewer 角色。添加此角色:

    $ oc policy add-role-to-user registry-viewer <user_name>
    Copy to Clipboard Toggle word wrap
  • 为了编写或推送镜像,例如使用 docker push 命令,用户必须具有 registry-editor 角色。添加此角色:

    $ oc policy add-role-to-user registry-editor <user_name>
    Copy to Clipboard Toggle word wrap

如需有关用户权限的更多信息,请参阅管理角色绑定

2.3.3.2. 登录到 Registry
注意

确保您的用户满足直接访问 registry 的先决条件

直接登录到 registry:

  1. 确保您以 普通用户身份 登录到 OpenShift Container Platform:

    $ oc login
    Copy to Clipboard Toggle word wrap
  2. 使用您的访问令牌登录到容器镜像registry:

    docker login -u openshift -p $(oc whoami -t) <registry_ip>:<port>
    Copy to Clipboard Toggle word wrap
注意

您可以为用户名传递任何值,令牌包含所有必要的信息。传递包含冒号的用户名将导致登录失败。

2.3.3.3. 推送和拉取镜像

登录 registry 后,您可以对 registry 执行 docker pulldocker push 操作。

重要

您可以抓取任意镜像,但是如果已添加了system:registry角色,则只能将镜像推送到您自己的registry中。

在以下示例中,我们使用:

Expand

组件

<registry_ip>

172.30.124.220

<port>

5000

<project>

openshift

<image>

busybox

<tag>

忽略 (默认为 latest)

  1. 抓取任意镜像:

    $ docker pull docker.io/busybox
    Copy to Clipboard Toggle word wrap
  2. 使用 <registry_ip>:<port>/<project>/<image> 格式标记(tag)新镜像。项目名称必须出现在这个 pull 规范中,以供OpenShift Container Platform 把这个镜像正确放置在 registry 中,并在以后正确访问 registry 中的这个镜像:

    $ docker tag docker.io/busybox 172.30.124.220:5000/openshift/busybox
    Copy to Clipboard Toggle word wrap
    注意

    您的常规用户必须具有指定项目的 system:image-builder 角色,该角色允许用户写入或推送镜像。否则,下一步中的 docker push 将失败。若要进行测试,您可以创建一个新项目来推送 busybox 镜像。

  3. 将新标记的镜像推送到registry:

    $ docker push 172.30.124.220:5000/openshift/busybox
    ...
    cf2616975b4a: Image successfully pushed
    Digest: sha256:3662dd821983bc4326bee12caec61367e7fb6f6a3ee547cbaff98f77403cab55
    Copy to Clipboard Toggle word wrap

2.3.4. 访问 Registry 指标

OpenShift Container Registry 为 Prometheus metrics 提供了一个端点。Prometheus是一个独立的开源系统监视和警报工具包。

metrics 可以通过registry端点的/extensions/v2/metrics路径获得。但是,必须先启用此路由;请参阅 Extended Registry Configuration 了解说明。

以下是指标查询的简单示例:

$ curl -s -u <user>:<secret> \ 
1

    http://172.30.30.30:5000/extensions/v2/metrics | grep openshift | head -n 10

# HELP openshift_build_info A metric with a constant '1' value labeled by major, minor, git commit & git version from which OpenShift was built.
# TYPE openshift_build_info gauge
openshift_build_info{gitCommit="67275e1",gitVersion="v3.6.0-alpha.1+67275e1-803",major="3",minor="6+"} 1
# HELP openshift_registry_request_duration_seconds Request latency summary in microseconds for each operation
# TYPE openshift_registry_request_duration_seconds summary
openshift_registry_request_duration_seconds{name="test/origin-pod",operation="blobstore.create",quantile="0.5"} 0
openshift_registry_request_duration_seconds{name="test/origin-pod",operation="blobstore.create",quantile="0.9"} 0
openshift_registry_request_duration_seconds{name="test/origin-pod",operation="blobstore.create",quantile="0.99"} 0
openshift_registry_request_duration_seconds_sum{name="test/origin-pod",operation="blobstore.create"} 0
openshift_registry_request_duration_seconds_count{name="test/origin-pod",operation="blobstore.create"} 5
Copy to Clipboard Toggle word wrap
1
<user> 可以是任意的,但 <secret> 必须与 registry 配置中指定的值匹配。

访问指标的另一种方法是使用集群角色。您仍然需要启用端点,但不需要指定 <secret>。配置文件中与指标数据相关的部分应如下所示:

openshift:
  version: 1.0
  metrics:
    enabled: true
...
Copy to Clipboard Toggle word wrap

如果您还没有角色来访问指标,则必须创建一个集群角色:

$ cat <<EOF |
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: prometheus-scraper
rules:
- apiGroups:
  - image.openshift.io
  resources:
  - registry/metrics
  verbs:
  - get
EOF
oc create -f -
Copy to Clipboard Toggle word wrap

要将此角色添加到用户,请运行以下命令:

$ oc adm policy add-cluster-role-to-user prometheus-scraper <username>
Copy to Clipboard Toggle word wrap

有关更高级查询和推荐的可视化工具,请参阅 上游 Prometheus 文档

2.4. 保护并公开 Registry

2.4.1. 概述

默认情况下,OpenShift Container Platform registry 在集群安装过程中是安全的,以便通过 TLS 提供流量。默认情况下还会创建一个 passthrough 路由,以将服务公开到外部。

如果出于任何原因您的 registry 没有被保护或公开,请参阅以下部分来了解如何手动操作。

2.4.2. 手动保护 Registry

手动保护 registry 以通过 TLS 提供流量:

  1. 部署 registry
  2. 获取 registry 的服务 IP 和端口:

    $ oc get svc/docker-registry
    NAME              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
    docker-registry   ClusterIP   172.30.82.152   <none>        5000/TCP   1d
    Copy to Clipboard Toggle word wrap
  3. 您可以使用现有服务器证书,或者创建对指定 CA 签名的指定 IP 和主机名有效的密钥和服务器证书。要为 registry 服务 IP 和 docker-registry.default.svc.cluster.local 主机名创建服务器证书,请在 Ansible 主机清单文件中列出的第一个 master 中运行以下命令,默认为 /etc/ansible/hosts

    $ oc adm ca create-server-cert \
        --signer-cert=/etc/origin/master/ca.crt \
        --signer-key=/etc/origin/master/ca.key \
        --signer-serial=/etc/origin/master/ca.serial.txt \
        --hostnames='docker-registry.default.svc.cluster.local,docker-registry.default.svc,172.30.124.220' \
        --cert=/etc/secrets/registry.crt \
        --key=/etc/secrets/registry.key
    Copy to Clipboard Toggle word wrap

    如果路由器将在 外部公开,请在 --hostnames 标志中添加公共路由主机名:

    --hostnames='mydocker-registry.example.com,docker-registry.default.svc.cluster.local,172.30.124.220 \
    Copy to Clipboard Toggle word wrap

    如需有关更新默认证书的更多详细信息,请参阅重新部署 Registry 和路由器 证书,以便可从外部访问该路由。

    注意

    oc adm ca create-server-cert 命令会生成一个有效期为两年的证书。这可以通过 --expire-days 选项进行修改,但出于安全原因,建议不要超过这个值。

  4. 为 registry 证书创建 secret:

    $ oc create secret generic registry-certificates \
        --from-file=/etc/secrets/registry.crt \
        --from-file=/etc/secrets/registry.key
    Copy to Clipboard Toggle word wrap
  5. 将该机密添加到 registry 容器集的服务帐户(包括 默认 服务帐户):

    $ oc secrets link registry registry-certificates
    $ oc secrets link default  registry-certificates
    Copy to Clipboard Toggle word wrap
    注意

    默认情况下,“将 secret 仅限于引用它们的服务帐户”的功能被禁用。这意味着,如果在主配置文件中将 serviceAccountConfig.limitSecretReferences 设置为 false(默认设置),则不需要将 secret 连接到一个特定的服务。

  6. 暂停 docker-registry 服务:

    $ oc rollout pause dc/docker-registry
    Copy to Clipboard Toggle word wrap
  7. 将 secret 卷添加到 registry 部署配置中:

    $ oc set volume dc/docker-registry --add --type=secret \
        --secret-name=registry-certificates -m /etc/secrets
    Copy to Clipboard Toggle word wrap
  8. 通过在 registry 部署配置中添加以下环境变量来启用 TLS:

    $ oc set env dc/docker-registry \
        REGISTRY_HTTP_TLS_CERTIFICATE=/etc/secrets/registry.crt \
        REGISTRY_HTTP_TLS_KEY=/etc/secrets/registry.key
    Copy to Clipboard Toggle word wrap

    如需更多信息,请参阅 Docker 文档中的配置 registry 部分

  9. 将 registry 的存活度探测使用从 HTTP 更新到 HTTPS:

    $ oc patch dc/docker-registry -p '{"spec": {"template": {"spec": {"containers":[{
        "name":"registry",
        "livenessProbe":  {"httpGet": {"scheme":"HTTPS"}}
      }]}}}}'
    Copy to Clipboard Toggle word wrap
  10. 如果您的 registry 最初部署在 OpenShift Container Platform 3.2 或更高版本上,请将用于 registry 的就绪度探测从 HTTP 更新到 HTTPS:

    $ oc patch dc/docker-registry -p '{"spec": {"template": {"spec": {"containers":[{
        "name":"registry",
        "readinessProbe":  {"httpGet": {"scheme":"HTTPS"}}
      }]}}}}'
    Copy to Clipboard Toggle word wrap
  11. 恢复 docker-registry 服务:

    $ oc rollout resume dc/docker-registry
    Copy to Clipboard Toggle word wrap
  12. 验证 registry 是否以 TLS 模式运行。等待最新的 docker-registry 部署完成,再验证 registry 容器的 Docker 日志。您应该找到 listening on :5000, tls 的条目。

    $ oc logs dc/docker-registry | grep tls
    time="2015-05-27T05:05:53Z" level=info msg="listening on :5000, tls" instance.id=deeba528-c478-41f5-b751-dc48e4935fc2
    Copy to Clipboard Toggle word wrap
  13. 将 CA 证书复制到 Docker 证书目录。这必须在集群的所有节点上完成:

    $ dcertsdir=/etc/docker/certs.d
    $ destdir_addr=$dcertsdir/172.30.124.220:5000
    $ destdir_name=$dcertsdir/docker-registry.default.svc.cluster.local:5000
    
    $ sudo mkdir -p $destdir_addr $destdir_name
    $ sudo cp ca.crt $destdir_addr    
    1
    
    $ sudo cp ca.crt $destdir_name
    Copy to Clipboard Toggle word wrap
    1
    ca.crt 文件是 master 上的 /etc/origin/master/ca.crt 的副本。
  14. 在使用身份验证时,一些 docker 版本还需要将集群配置为信任操作系统级别的证书。

    1. 复制证书:

      $ cp /etc/origin/master/ca.crt /etc/pki/ca-trust/source/anchors/myregistrydomain.com.crt
      Copy to Clipboard Toggle word wrap
    2. 运行:

      $ update-ca-trust enable
      Copy to Clipboard Toggle word wrap
  15. 只删除 /etc/sysconfig/docker 文件中的这个特定 registry 的 --insecure-registry 选项。然后,重新载入守护进程并重启 docker 服务来反映这个配置更改:

    $ sudo systemctl daemon-reload
    $ sudo systemctl restart docker
    Copy to Clipboard Toggle word wrap
  16. 验证 docker 客户端连接。运行 docker push 到 registry 或 registry 中的 docker pull 应该会成功。确保您已登录到 registry

    $ docker tag|push <registry/image> <internal_registry/project/image>
    Copy to Clipboard Toggle word wrap

    例如:

    $ docker pull busybox
    $ docker tag docker.io/busybox 172.30.124.220:5000/openshift/busybox
    $ docker push 172.30.124.220:5000/openshift/busybox
    ...
    cf2616975b4a: Image successfully pushed
    Digest: sha256:3662dd821983bc4326bee12caec61367e7fb6f6a3ee547cbaff98f77403cab55
    Copy to Clipboard Toggle word wrap

2.4.3. 手动公开安全 Registry

您可以通过首先保护 registry,然后使用路由公开它,而不是从 OpenShift Container Platform 集群内部登录到 OpenShift Container Platform registry。您可以使用路由地址从集群以外登陆到 registry,并使用路由主机进行镜像的 tag 和 push 操作。

  1. 以下每个先决条件步骤都会在典型的集群安装过程中默认执行。如果没有,请手动执行它们:

  2. 在初始集群安装过程中,默认为 registry 创建 passthrough 路由:

    1. 验证路由是否存在:

      $ oc get route/docker-registry -o yaml
      apiVersion: v1
      kind: Route
      metadata:
        name: docker-registry
      spec:
        host: <host> 
      1
      
        to:
          kind: Service
          name: docker-registry 
      2
      
        tls:
          termination: passthrough 
      3
      Copy to Clipboard Toggle word wrap
      1
      路由的主机。您必须能够通过 DNS 外部将此名称解析到路由器的 IP 地址。
      2
      registry 的服务名称。
      3
      将此路由指定为 passthrough 路由。
      注意

      也支持重新加密路由来公开安全 registry。

    2. 如果不存在,则通过 oc create route passthrough 命令创建路由,将 registry 指定为路由的服务。默认情况下,创建的路由的名称与服务名称相同:

      1. 获取 docker-registry 服务详情:

        $ oc get svc
        NAME              CLUSTER_IP       EXTERNAL_IP   PORT(S)                 SELECTOR                  AGE
        docker-registry   172.30.69.167    <none>        5000/TCP                docker-registry=default   4h
        kubernetes        172.30.0.1       <none>        443/TCP,53/UDP,53/TCP   <none>                    4h
        router            172.30.172.132   <none>        80/TCP                  router=router             4h
        Copy to Clipboard Toggle word wrap
      2. 创建路由:

        $ oc create route passthrough    \
            --service=docker-registry    \
        1
        
            --hostname=<host>
        route "docker-registry" created     
        2
        Copy to Clipboard Toggle word wrap
        1
        将 registry 指定为路由的服务。
        2
        路由名称与服务名称相同。
  3. 接下来,您必须信任主机系统上用于 registry 的证书,以允许主机推送和拉取镜像。引用的证书是在保护 registry 时创建的。

    $ sudo mkdir -p /etc/docker/certs.d/<host>
    $ sudo cp <ca_certificate_file> /etc/docker/certs.d/<host>
    $ sudo systemctl restart docker
    Copy to Clipboard Toggle word wrap
  4. 使用保护 registry 的信息,登录到 registry。但是,这一次指向路由中使用的主机名,而不是您的服务 IP。登录到安全且公开的 registry 时,请确保在 docker login 命令中指定 registry:

    # docker login -e user@company.com \
        -u f83j5h6 \
        -p Ju1PeM47R0B92Lk3AZp-bWJSck2F7aGCiZ66aFGZrs2 \
        <host>
    Copy to Clipboard Toggle word wrap
  5. 现在,您可以使用路由主机标记和推送镜像。例如,要在名为 test 的项目中标记和推送 busybox 镜像:

    $ oc get imagestreams -n test
    NAME      DOCKER REPO   TAGS      UPDATED
    
    $ docker pull busybox
    $ docker tag busybox <host>/test/busybox
    $ docker push <host>/test/busybox
    The push refers to a repository [<host>/test/busybox] (len: 1)
    8c2e06607696: Image already exists
    6ce2e90b0bc7: Image successfully pushed
    cf2616975b4a: Image successfully pushed
    Digest: sha256:6c7e676d76921031532d7d9c0394d0da7c2906f4cb4c049904c4031147d8ca31
    
    $ docker pull <host>/test/busybox
    latest: Pulling from <host>/test/busybox
    cf2616975b4a: Already exists
    6ce2e90b0bc7: Already exists
    8c2e06607696: Already exists
    Digest: sha256:6c7e676d76921031532d7d9c0394d0da7c2906f4cb4c049904c4031147d8ca31
    Status: Image is up to date for <host>/test/busybox:latest
    
    $ oc get imagestreams -n test
    NAME      DOCKER REPO                       TAGS      UPDATED
    busybox   172.30.11.215:5000/test/busybox   latest    2 seconds ago
    Copy to Clipboard Toggle word wrap
    注意

    您的镜像流将具有 registry 服务的 IP 地址和端口,而不是路由名称和端口。详情请参阅 oc get imagestreams

2.4.4. 手动公开 Non-Secure Registry

对于非生产环境的 OpenShift Container Platform,可以公开一个非安全的 registry,而不必通过安全 registry 来公开 registry。这允许您使用一个外部路由到 registry,而无需使用 SSL 证书。

警告

为外部访问非安全的 registry 只适用于非生产环境。

公开一个非安全的 registry:

  1. 公开 registry:

    # oc expose service docker-registry --hostname=<hostname> -n default
    Copy to Clipboard Toggle word wrap

    这会创建以下 JSON 文件:

    apiVersion: v1
    kind: Route
    metadata:
      creationTimestamp: null
      labels:
        docker-registry: default
      name: docker-registry
    spec:
      host: registry.example.com
      port:
        targetPort: "5000"
      to:
        kind: Service
        name: docker-registry
    status: {}
    Copy to Clipboard Toggle word wrap
  2. 验证路由是否已创建成功:

    # oc get route
    NAME              HOST/PORT                    PATH      SERVICE           LABELS                    INSECURE POLICY   TLS TERMINATION
    docker-registry   registry.example.com            docker-registry   docker-registry=default
    Copy to Clipboard Toggle word wrap
  3. 检查 registry 的健康状况:

    $ curl -v http://registry.example.com/healthz
    Copy to Clipboard Toggle word wrap

    预期为 HTTP 200/OK 消息。

    公开 registry 后,通过将端口号添加到 OPTIONS 条目来更新您的 /etc/sysconfig/docker 文件。例如:

    OPTIONS='--selinux-enabled --insecure-registry=172.30.0.0/16 --insecure-registry registry.example.com:80'
    Copy to Clipboard Toggle word wrap
    重要

    上面的选项应该添加到您要从其登录的客户端上。

    此外,确保 Docker 在客户端上运行。

登录到非安全且公开的 registry 时,请确保在 docker login 命令中指定 registry。例如:

# docker login -e user@company.com \
    -u f83j5h6 \
    -p Ju1PeM47R0B92Lk3AZp-bWJSck2F7aGCiZ66aFGZrs2 \
    <host>
Copy to Clipboard Toggle word wrap

2.5. 扩展 Registry 配置

2.5.1. 维护 Registry IP 地址

OpenShift Container Platform 使用其服务 IP 地址来引用集成的 registry,因此如果您决定删除并重新创建 docker-registry 服务,您可以通过安排在新服务中重复使用旧 IP 地址来确保完全透明转换。如果无法避免新的 IP 地址,您可以通过只重启 master 来最小化集群中断。

重新使用地址
要重新使用 IP 地址,您必须在删除旧 docker-registry 服务前保存其 IP 地址,并安排将新分配的 IP 地址替换为新 docker-registry 服务中保存的 IP 地址。
  1. 记录该服务的 clusterIP:

    $ oc get svc/docker-registry -o yaml | grep clusterIP:
    Copy to Clipboard Toggle word wrap
  2. 删除服务:

    $ oc delete svc/docker-registry dc/docker-registry
    Copy to Clipboard Toggle word wrap
  3. registry.yaml 中创建 registry 定义,将 <options> 替换为非生产环境使用部分中说明的第 3 步中使用的 :

    $ oc adm registry <options> -o yaml > registry.yaml
    Copy to Clipboard Toggle word wrap
  4. 编辑 registry.yaml,找到 Service,并将其 clusterIP 更改为第 1 步中记录的地址。
  5. 使用修改后的 registry.yaml 创建 registry:

    $ oc create -f registry.yaml
    Copy to Clipboard Toggle word wrap
重启 Master
如果您无法重新使用 IP 地址,则任何使用包含旧 IP 地址的 pull specification 的操作都将失败。要最小化集群中断,您必须重启 master:
# master-restart api
# master-restart controllers
Copy to Clipboard Toggle word wrap

这样可确保从缓存中清除包括旧 IP 地址的旧 registry URL。

注意

我们建议不要重启整个集群,因为这会对 pod 造成不必要的停机时间,实际上不会清除缓存。

2.5.2. 配置外部 registry 搜索列表

您可以使用 /etc/containers/registries.conf 文件创建 Docker Registry 列表来搜索容器镜像。

/etc/containers/registries.conf 文件是 OpenShift Container Platform 在用户使用镜像简短名称(如 myimage:latest )提取镜像时应对其搜索的 registry 服务器列表。您可以自定义搜索顺序,指定安全且不安全的 registry,并定义一个被阻断的 registry 列表。OpenShift Container Platform 不允许搜索或允许从被阻塞列表中的 registry 中拉取(pull)。

例如,如果用户想要拉取 myimage:latest 镜像,OpenShift Container Platform 会按照它们出现在列表中的顺序搜索 registry,直到找到 myimage:latest 镜像。

registry 搜索列表允许您策展一组可供 OpenShift Container Platform 用户下载的镜像和模板。您可以将这些镜像放在一个或多个 Docker registry 中,将 registry 添加到列表中,并将这些镜像拉取到集群中。

注意

使用 registry 搜索列表时,OpenShift Container Platform 不会从不在搜索列表中的 registry 中拉取镜像。

配置 registry 搜索列表:

  1. 编辑 /etc/containers/registries.conf 文件,根据需要添加或编辑以下参数:

    [registries.search] 
    1
    
    registries = ["reg1.example.com", "reg2.example.com"]
    
    [registries.insecure] 
    2
    
    registries = ["reg3.example.com"]
    
    [registries.block] 
    3
    
    registries = ['docker.io']
    Copy to Clipboard Toggle word wrap
    1
    指定用户可以使用 SSL/TLS 从中下载镜像的安全 registry。
    2
    指定用户可以在不使用 TLS 的情况下下载镜像的不安全 registry。
    3
    指定用户无法从中下载镜像的 registry。

2.5.3. 设置 Registry 主机名

您可以为内部和外部引用配置 registry 的主机名和端口。通过这样做,镜像流将为镜像提供基于主机名的推送和拉取规格,允许使用镜像与对 registry 服务 IP 的更改进行隔离,并有可能允许镜像流及其引用在集群中可移植。

要设置从集群内部引用 registry 的主机名,请在 master 配置文件的 imagePolicyConfig 部分中设置 internalRegistryHostname。外部主机名通过在同一位置设置 externalRegistryHostname 值来控制。

镜像策略配置

imagePolicyConfig:
  internalRegistryHostname: docker-registry.default.svc.cluster.local:5000
  externalRegistryHostname: docker-registry.mycompany.com
Copy to Clipboard Toggle word wrap

registry 本身必须使用相同的内部主机名值进行配置。这可以通过在 registry 署配置中设置 REGISTRY_OPENSHIFT_SERVER_ADDR 环境变量或设置 registry 配置的 OpenShift 部分中的值来完成。

注意

如果您已经为 registry 启用了 TLS,服务器证书必须包含您希望引用 registry 的主机名。有关添加主机名到服务器证书的说明,请参阅保护registry

2.5.4. 覆盖 Registry 配置

您可以使用自己的自定义配置覆盖集成 registry 的默认配置,默认覆盖正在运行的 registry 容器中的 /config.yml 中的默认配置。

注意

此文件中的上游配置选项也可使用环境变量覆盖。middleware 部分是一个例外,因为只有几个选项可以使用环境变量覆盖。了解如何覆盖特定的配置选项

要启用对 registry 配置文件的管理,并使用 ConfigMap 部署更新的配置:

  1. 部署 registry
  2. 根据需要在本地编辑 registry 配置文件。registry 中部署的初始 YAML 文件如下所示:查看支持的选项

    registry 配置文件

    version: 0.1
    log:
      level: debug
    http:
      addr: :5000
    storage:
      cache:
        blobdescriptor: inmemory
      filesystem:
        rootdirectory: /registry
      delete:
        enabled: true
    auth:
      openshift:
        realm: openshift
    middleware:
      registry:
        - name: openshift
      repository:
        - name: openshift
          options:
            acceptschema2: true
            pullthrough: true
            enforcequota: false
            projectcachettl: 1m
            blobrepositorycachettl: 10m
      storage:
        - name: openshift
    openshift:
      version: 1.0
      metrics:
        enabled: false
        secret: <secret>
    Copy to Clipboard Toggle word wrap

  3. 创建一个 ConfigMap,包含此目录中每个文件的内容:

    $ oc create configmap registry-config \
        --from-file=</path/to/custom/registry/config.yml>/
    Copy to Clipboard Toggle word wrap
  4. registry-config ConfigMap 作为卷添加到 registry 的部署配置中,以在 /etc/docker/registry/ 中挂载自定义配置文件:

    $ oc set volume dc/docker-registry --add --type=configmap \
        --configmap-name=registry-config -m /etc/docker/registry/
    Copy to Clipboard Toggle word wrap
  5. 通过在 registry 的部署配置中添加以下环境变量来更新 registry,以引用上一步中的配置路径:

    $ oc set env dc/docker-registry \
        REGISTRY_CONFIGURATION_PATH=/etc/docker/registry/config.yml
    Copy to Clipboard Toggle word wrap

这可以作为迭代过程执行,从而实现所需的配置。例如,在故障排除期间,可临时更新配置以将其置于 debug 模式。

更新现有配置:

警告

此流程将覆盖当前部署的 registry 配置。

  1. 编辑本地 registry 配置文件 config.yml
  2. 删除 registry-config configmap:

    $ oc delete configmap registry-config
    Copy to Clipboard Toggle word wrap
  3. 重新创建 configmap 以引用更新的配置文件:

    $ oc create configmap registry-config\
        --from-file=</path/to/custom/registry/config.yml>/
    Copy to Clipboard Toggle word wrap
  4. 重新部署 registry 以读取更新的配置:

    $ oc rollout latest docker-registry
    Copy to Clipboard Toggle word wrap
提示

在源代码控制存储库中维护配置文件。

2.5.5. registry 配置参考

上游 docker distribution 库中有许多配置选项。并非所有配置选项都受到支持或启用。覆盖 registry 配置时,请使用本节作为参考。

注意

此文件中的上游配置选项也可使用环境变量覆盖。但是,middleware 部分可能无法使用环境变量覆盖。了解如何覆盖特定的配置选项

2.5.5.1. Log

支持上游选项

例如:

log:
  level: debug
  formatter: text
  fields:
    service: registry
    environment: staging
Copy to Clipboard Toggle word wrap
2.5.5.2. Hook

不支持邮件 hook。

2.5.5.3. 存储

本节列出了支持的 registry 存储驱动程序。如需更多信息,请参阅容器镜像 registry 文档

以下列表包括在 registry 配置文件中需要配置的存储驱动程序:

支持常规 registry 存储配置选项。如需更多信息,请参阅容器镜像 registry 文档

以下存储选项需要通过文件系统驱动程序配置:

注意

如需有关支持的持久性存储驱动程序的更多信息,请参阅配置持久性存储持久性存储示例

常规存储配置选项

storage:
  delete:
    enabled: true 
1

  redirect:
    disable: false
  cache:
    blobdescriptor: inmemory
  maintenance:
    uploadpurging:
      enabled: true
      age: 168h
      interval: 24h
      dryrun: false
    readonly:
      enabled: false
Copy to Clipboard Toggle word wrap

1
此条目对于镜像修剪正常工作是必需的
2.5.5.4. Auth

不应更改 Auth 选项。openshift 扩展是唯一支持的选项。

auth:
  openshift:
    realm: openshift
Copy to Clipboard Toggle word wrap
2.5.5.5. Middleware

存储库 中间件扩展允许配置负责与 OpenShift Container Platform 和镜像代理交互的 OpenShift Container Platform 中间件。

middleware:
  registry:
    - name: openshift 
1

  repository:
    - name: openshift 
2

      options:
        acceptschema2: true 
3

        pullthrough: true 
4

        mirrorpullthrough: true 
5

        enforcequota: false 
6

        projectcachettl: 1m 
7

        blobrepositorycachettl: 10m 
8

  storage:
    - name: openshift 
9
Copy to Clipboard Toggle word wrap
1 2 9
这些条目是必需的。其存在可确保加载所需的组件。这些值不应更改。
3
允许您在推送到 registry 期间存储 清单模式 v2。详情请查看 下方
4
允许 registry 充当远程 Blob 的代理。详情请查看 下方
5
允许从远程 registry 提供 registry 缓存 Blob,以便稍后进行快速访问。镜像在第一次访问 Blob 时开始。如果禁用了 pullthrough,则选项无效。
6
防止 Blob 上传超过目标项目中定义的大小限制。
7
在 registry 中缓存的限制的过期超时。值越低,限制更改传播到 registry 所需的时间就会越短。但是,registry 会更频繁地从服务器查询限制,因此推送速度会较慢。
8
blob 和 repository 之间记住关联的过期超时。值越大,快速查找的几率更高,registry 操作效率越高。另一方面,内存使用会增加为用户提供服务的风险,因为用户不再获得访问该层的权限。
2.5.5.5.1. S3 驱动程序配置

如果要使用您正在使用的集成 registry 不支持的 S3 区域,您可以指定一个 regionendpoint 以避免 区域 验证错误。

有关使用 Amazon Simple Storage Service 存储的更多信息,请参阅 Amazon S3 作为存储后端

例如:

version: 0.1
log:
  level: debug
http:
  addr: :5000
storage:
  cache:
    blobdescriptor: inmemory
  delete:
    enabled: true
  s3:
    accesskey: BJKMSZBRESWJQXRWMAEQ
    secretkey: 5ah5I91SNXbeoUXXDasFtadRqOdy62JzlnOW1goS
    bucket: docker.myregistry.com
    region: eu-west-3
    regionendpoint: https://s3.eu-west-3.amazonaws.com
 auth:
  openshift:
    realm: openshift
middleware:
  registry:
    - name: openshift
  repository:
    - name: openshift
  storage:
    - name: openshift
Copy to Clipboard Toggle word wrap
注意

验证 regionregionendpoint 字段本身是否一致。否则,集成的 registry 将启动,但它无法读取或写入 S3 存储。

如果您使用与 Amazon S3 不同的 S3 存储,则 regionendpoint 也很有用。

2.5.5.5.2. CloudFront 中间件

可以添加 CloudFront 中间件扩展 以支持 AWS CloudFront CDN 存储供应商。CloudFront 中间件加快了镜像内容在国际间分发。Blob 分布到世界各地的几个边缘位置。客户端始终定向到延迟最低的边缘。

注意

CloudFront 中间件扩展 只能用于 S3 存储。它仅在 Blob 服务期间使用。因此,只有 Blob 下载可以加快,不能上传。

以下是带有 CloudFront 中间件的 S3 存储驱动程序的最小配置示例:

version: 0.1
log:
  level: debug
http:
  addr: :5000
storage:
  cache:
    blobdescriptor: inmemory
  delete:
    enabled: true
  s3: 
1

    accesskey: BJKMSZBRESWJQXRWMAEQ
    secretkey: 5ah5I91SNXbeoUXXDasFtadRqOdy62JzlnOW1goS
    region: us-east-1
    bucket: docker.myregistry.com
auth:
  openshift:
    realm: openshift
middleware:
  registry:
    - name: openshift
  repository:
    - name: openshift
  storage:
    - name: cloudfront 
2

      options:
        baseurl: https://jrpbyn0k5k88bi.cloudfront.net/ 
3

        privatekey: /etc/docker/cloudfront-ABCEDFGHIJKLMNOPQRST.pem 
4

        keypairid: ABCEDFGHIJKLMNOPQRST 
5

    - name: openshift
Copy to Clipboard Toggle word wrap
1
无论 CloudFront 中间件如何,S3 存储都必须以相同的方式进行配置。
2
OpenShift 中间件需要先列出 CloudFront 存储中间件。
3
CloudFront 基本 URL。在 AWS 管理控制台中,这被列为 CloudFront 发行版本的 Domain Name
4
AWS 私钥在文件系统中的位置。这不能与 Amazon EC2 密钥对混淆。请参阅 AWS 文档 为您的可信签名者创建 CloudFront 密钥对。文件需要作为 机密 挂载到 registry 容器集。
5
云前端密钥对的 ID。
2.5.5.5.3. 覆盖中间件配置选项

middleware 部分无法使用环境变量覆盖。但也有一些例外:例如:

middleware:
  repository:
    - name: openshift
      options:
        acceptschema2: true 
1

        pullthrough: true 
2

        mirrorpullthrough: true 
3

        enforcequota: false 
4

        projectcachettl: 1m 
5

        blobrepositorycachettl: 10m 
6
Copy to Clipboard Toggle word wrap
1
此配置选项可以被布尔值环境变量 REGISTRY_MIDDLEWARE_REPOSITORY_OPENSHIFT_ACCEPTSCHEMA2 覆盖,允许在清单放置请求时接受清单架构 v2。可识别的值为 truefalse (适用于以下所有其他布尔值变量)。
2
此配置选项可以被布尔值环境变量 REGISTRY_MIDDLEWARE_REPOSITORY_OPENSHIFT_PULLTHROUGH 覆盖,启用远程存储库的代理模式。
3
此配置选项可以被布尔值环境变量 REGISTRY_MIDDLEWARE_REPOSITORY_OPENSHIFT_MIRRORPULLTHROUGH 覆盖,它指示 registry 在提供远程 Blob 时在本地镜像 Blob。
4
此配置选项可以被布尔值环境变量 REGISTRY_MIDDLEWARE_REPOSITORY_OPENSHIFT_ENFORCEQUOTA 覆盖,允许开启或关闭配额执行。默认情况下,配额强制是禁用的。
5
可被环境变量 REGISTRY_MIDDLEWARE_REPOSITORY_OPENSHIFT_PROJECTCACHETTL 覆盖的配置选项,为项目配额对象指定驱除超时。它需要一个有效的持续时间字符串(如 2m)。如果为空,则获得默认超时。如果零(0m),则禁用缓存。
6
可被环境变量 REGISTRY_MIDDLEWARE_REPOSITORY_OPENSHIFT_BLOBREPOSITORYCACHETTL 覆盖的配置选项,为 blob 和包含存储库之间的关联指定驱除超时。值的格式与 projectcachettl 示例中的格式相同。
2.5.5.5.4. 镜像 Pullthrough

如果启用,registry 将尝试从远程 registry 获取请求的 blob,除非 blob 在本地存在。远程候选从存储在 镜像流 状态的 DockerImage 条目(客户端从中拉取)计算。此类条目中的所有唯一远程 registry 引用将依次尝试,直到找到 Blob。

只有存在拉取镜像的镜像流标签时才会进行 pullthrough。例如,如果拉取的镜像为 docker-registry.default.svc:5000/yourproject/yourimage:prod,则 registry 将在项目 yourproject 中查找名为 yourimage:prod 的镜像流标签。如果找到镜像,它将尝试使用该镜像流标签关联的 dockerImageReference 来拉取镜像。

在执行 pullthrough 时,registry 将使用与所引用镜像流标签关联的项目中找到的拉取凭据。此功能还允许您拉取驻留在 registry 上的镜像,它们没有凭证可以访问,只要您有权访问引用该镜像的镜像流标签。

您必须确保 registry 具有适当的证书来信任您针对的任何外部 registry。证书需要放置在 pod 上的 /etc/pki/tls/certs 目录中。您可以使用 配置映射secret 挂载证书。请注意,必须替换整个 /etc/pki/tls/certs 目录。您必须包含新证书,并在您挂载的 secret 或配置映射中替换系统证书。

请注意,默认情况下,镜像流标签使用引用策略类型 Source,这意味着镜像流引用被解析为镜像拉取规格时,使用的规格将指向镜像的来源。对于托管在外部 registry 上的镜像,这将是外部 registry,因此该资源将引用外部 registry 并拉取镜像。例如,registry.redhat.io/openshift3/jenkins-2-rhel7 和 pullthrough 将不适用。为确保引用镜像流的资源使用指向内部 Registry 的拉取规格,镜像流标签应使用引用策略类型 Local。有关参考政策的更多信息,

这个功能默认是开启的。不过,它可以通过配置选项来禁用。

默认情况下,除非禁用 mirrorpullthrough,否则通过这种方式提供的所有远程 Blob 都存储在本地以进行后续的快速访问。此镜像功能的缺点是增加存储的使用。

注意

当客户端尝试至少获取一个 blob 字节时,镜像开始。要在实际需要前将特定镜像预先放入集成的 registry 中,您可以运行以下命令:

$ oc get imagestreamtag/${IS}:${TAG} -o jsonpath='{ .image.dockerImageLayers[*].name }' | \
  xargs -n1 -I {} curl -H "Range: bytes=0-1" -u user:${TOKEN} \
  http://${REGISTRY_IP}:${PORT}/v2/default/mysql/blobs/{}
Copy to Clipboard Toggle word wrap
注意

此 OpenShift Container Platform 镜像功能不应与上游 registry 通过缓存功能拉取(pull) 混淆,后者是类似但不同的功能。

2.5.5.5.5. 清单架构 v2 支持

每一镜像具有一个清单,用于描述其 Blob、运行它的说明以及其他元数据。清单是经过版本控制的,每个版本具有不同的结构和字段,随着时间推移而发展。同一镜像可由多个清单版本表示。每个版本都有不同的摘要。

registry 目前支持 清单 v2 模式 1 (schema1)清单 v2 模式 2架构2)。前者已被淘汰,但将会延长支持时间。

默认配置是存储 schema2

您应注意与各种 Docker 客户端的兼容性问题:

  • 1.9 或更早版本的 Docker 客户端仅支持 schema1。此客户端拉取或推送的任何清单都将是这种传统架构。
  • 版本 1.10 的 Docker 客户端支持 schema1schema2。默认情况下,如果支持较新的架构,它会将后者推送到 registry。

存储具有 schema1 的镜像的 registry 将始终不动地将其返回到客户端。Schema2 将仅原封不动传输到较新的 Docker 客户端。对于较旧版本,它将自行转换为 schema1

这具有显著的后果。例如,通过较新的 Docker 客户端推送到 registry 的镜像无法被旧 Docker 通过其摘要拉取。这是因为存储的镜像的清单是 schema2,其摘要只能用于拉取此版本的清单。

旦您确信所有 registry 客户端都支持 schema2,就可以在 registry 中启用其支持。有关特定选项,请参见上述中间件配置参考

2.5.5.6. OpenShift

本节回顾针对特定于 OpenShift Container Platform 的功能的全局设置配置。在以后的发行版本中,Middleware 部分中与 openshift相关的设置将被弃用。

目前,本节允许您配置 registry 指标集合:

openshift:
  version: 1.0 
1

  server:
    addr: docker-registry.default.svc 
2

  metrics:
    enabled: false 
3

    secret: <secret> 
4

  requests:
    read:
      maxrunning: 10 
5

      maxinqueue: 10 
6

      maxwaitinqueue 2m 
7

    write:
      maxrunning: 10 
8

      maxinqueue: 10 
9

      maxwaitinqueue 2m 
10
Copy to Clipboard Toggle word wrap
1
指定本节配置版本的必填条目。唯一支持的值是 1.0
2
registry 的主机名。应设置为 master 上配置的相同值。它可以被环境变量 REGISTRY_OPENSHIFT_SERVER_ADDR 覆盖。
3
可以设置为 true 来启用指标集合。它可以被布尔值环境变量 REGISTRY_OPENSHIFT_METRICS_ENABLED 覆盖。
4
用于授权客户端请求的机密。指标客户端必须在 Authorization 标头中将它用作 bearer 令牌。它可以被环境变量 REGISTRY_OPENSHIFT_METRICS_SECRET 覆盖。
5
同时拉取请求的最大数量。它可以被环境变量 REGISTRY_OPENSHIFT_REQUESTS_READ_MAXRUNNING 覆盖。零表示无限制。
6
已排队拉取请求的最大数量。它可以被环境变量 REGISTRY_OPENSHIFT_REQUESTS_READ_MAXINQUEUE 覆盖。零表示无限制。
7
拉取请求在被拒绝前可在队列中等待的最长时间。它可以被环境变量 REGISTRY_OPENSHIFT_REQUESTS_READ_MAXWAITINQUEUE 覆盖。零表示无限制。
8
同时推送请求的最大数量。它可以被环境变量 REGISTRY_OPENSHIFT_REQUESTS_WRITE_MAXRUNNING 覆盖。零表示无限制。
9
最多排队的推送请求数.它可以被环境变量 REGISTRY_OPENSHIFT_REQUESTS_WRITE_MAXINQUEUE 覆盖。零表示无限制。
10
推送请求在被拒绝前可在队列中等待的最长时间。它可以被环境变量 REGISTRY_OPENSHIFT_REQUESTS_WRITE_MAXWAITINQUEUE 覆盖。零表示无限制。

有关使用信息,请参阅访问 Registry Metrics

2.5.5.7. 报告

报告不受支持。

2.5.5.8. HTTP

支持上游选项了解如何通过环境变量更改这些设置。应当仅更改 tls 部分。例如:

http:
  addr: :5000
  tls:
    certificate: /etc/secrets/registry.crt
    key: /etc/secrets/registry.key
Copy to Clipboard Toggle word wrap
2.5.5.9. 通知

支持上游选项REST API 参考 提供了更加全面的集成选项。

例如:

notifications:
  endpoints:
    - name: registry
      disabled: false
      url: https://url:port/path
      headers:
        Accept:
          - text/plain
      timeout: 500
      threshold: 5
      backoff: 1000
Copy to Clipboard Toggle word wrap
2.5.5.10. Redis

不支持 Redis。

2.5.5.11. Health

支持上游选项。registry 部署配置在 /healthz 上提供了一个集成健康检查。

2.5.5.12. Proxy

不应启用代理配置。此功能由 OpenShift Container Platform 存储库中间件扩展 pullthrough: true 提供。

2.5.5.13. Cache

集成 registry 会主动缓存数据,以减少对减慢外部资源的调用数量。有两个缓存:

  1. 用于缓存 Blob 元数据的存储缓存。此缓存没有过期时间,数据会一直存在,直到显式删除为止。
  2. 应用缓存包含 blob 和存储库之间的关联。此缓存中的数据具有过期时间。

要完全关闭缓存,您需要更改配置:

version: 0.1
log:
  level: debug
http:
  addr: :5000
storage:
  cache:
    blobdescriptor: "" 
1

openshift:
  version: 1.0
  cache:
    disabled: true 
2

    blobrepositoryttl: 10m
Copy to Clipboard Toggle word wrap
1
禁用存储后端中访问的元数据的缓存。如果没有此缓存,registry 服务器将持续访问元数据后端。
2
禁用包含 blob 和存储库关联的缓存。如果没有这个缓存,registry 服务器将持续从主 API 重新查询数据并重新计算关联。

2.6. 已知问题

2.6.1. 概述

以下是部署或使用集成 registry 时已知的问题。

2.6.2. 使用 Registry Pull-through 的并发构建

本地 docker-registry 部署会增加负载。默认情况下,它现在缓存 registry.redhat.io 的内容。来自为 STI 构建的 registry.redhat.io 的镜像现在存储在本地 registry 中。尝试拉取它们的结果从本地 docker-registry 中拉取。因此,在有些情况下,并发构建可能会造成拉取超时,构建可能会失败。要缓解此问题,请将 docker-registry 部署扩展到多个副本。检查构建器容器集日志中的超时。

当将扩展的 registry 与共享 NFS 卷搭配使用时,您可能会在推送镜像的过程中看到以下错误之一:

  • digest invalid: provided digest did not match uploaded content
  • blob upload unknown
  • blob upload invalid

当 Docker 尝试推送镜像时,内部 registry 服务将返回这些错误。其原因源自于跨节点的文件属性同步。使用默认循环负载平衡配置推送镜像时可能会出现的错误,如 NFS 客户端缓存、网络延迟和层大小等因素。

您可以执行以下步骤来最大程度减少此类故障的可能性:

  1. 确保 docker-registry 服务的 sessionAffinity 设置为 ClientIP:

    $ oc get svc/docker-registry --template='{{.spec.sessionAffinity}}'
    Copy to Clipboard Toggle word wrap

    这应该会返回 ClientIP,这是 OpenShift Container Platform 近期版本中的默认设置。如果没有,请修改它:

    $ oc patch svc/docker-registry -p '{"spec":{"sessionAffinity": "ClientIP"}}'
    Copy to Clipboard Toggle word wrap
  2. 确保 NFS 服务器上的 registry 卷的 NFS 导出行列出 no_wdelay 选项。no_wdelay 选项可防止服务器延迟写入,这极大提高了读写一致性,这是 Registry 的一项要求。
重要

测试显示,使用 RHEL NFS 服务器作为容器镜像 registry 的存储后端会出现问题。这包括 OpenShift Container Registry 和 Quay。因此,不建议使用 RHEL NFS 服务器来备份核心服务使用的 PV。

市场上的其他 NFS 实现可能没有这些问题。如需了解更多与此问题相关的信息,请联络相关的 NFS 厂商。

当拉取镜像推送到不同于从中拉取的镜像流时,会发生此错误。这是因为将构建的镜像重新标记到任意镜像流中:

$ oc tag srcimagestream:latest anyproject/pullimagestream:latest
Copy to Clipboard Toggle word wrap

然后,使用如下镜像引用从中提取:

internal.registry.url:5000/anyproject/pullimagestream:latest
Copy to Clipboard Toggle word wrap

在手动 Docker 拉取过程中,这会导致类似的错误:

Error: image anyproject/pullimagestream:latest not found
Copy to Clipboard Toggle word wrap

为防止这种情况,请完全避免标记内部管理的镜像,或者 手动 将构建的镜像重新推送到所需的命名空间。

当 registry 在 S3 存储后端上运行时,会报告问题。推送到容器镜像 registry 有时会失败,并显示以下错误:

Received unexpected HTTP status: 500 Internal Server Error
Copy to Clipboard Toggle word wrap

要进行调试,您需要 查看 registry 日志。在这里,查看推送失败时出现的类似的错误消息:

time="2016-03-30T15:01:21.22287816-04:00" level=error msg="unknown error completing upload: driver.Error{DriverName:\"s3\", Enclosed:(*url.Error)(0xc20901cea0)}" http.request.method=PUT
...
time="2016-03-30T15:01:21.493067808-04:00" level=error msg="response completed with error" err.code=UNKNOWN err.detail="s3: Put https://s3.amazonaws.com/oso-tsi-docker/registry/docker/registry/v2/blobs/sha256/ab/abe5af443833d60cf672e2ac57589410dddec060ed725d3e676f1865af63d2e2/data: EOF" err.message="unknown error" http.request.method=PUT
...
time="2016-04-02T07:01:46.056520049-04:00" level=error msg="error putting into main store: s3: The request signature we calculated does not match the signature you provided. Check your key and signing method." http.request.method=PUT
atest
Copy to Clipboard Toggle word wrap

如果您看到此类错误,请联系您的 Amazon S3 支持。您所在地区或您的特定存储桶可能有问题。

2.6.6. 镜像修剪失败

如果您在修剪镜像时遇到以下错误:

BLOB sha256:49638d540b2b62f3b01c388e9d8134c55493b1fa659ed84e97cb59b87a6b8e6c error deleting blob
Copy to Clipboard Toggle word wrap

您的 registry 日志 包含以下信息:

error deleting blob \"sha256:49638d540b2b62f3b01c388e9d8134c55493b1fa659ed84e97cb59b87a6b8e6c\": operation unsupported
Copy to Clipboard Toggle word wrap

这意味着您的 自定义配置文件 缺少 storage 部分中的强制条目,即 storage:delete:enabled 设置为 true。添加它们,重新部署 registry,再重复您的镜像修剪操作。

第 3 章 设置路由器

3.1. 路由器概述

3.1.1. 关于路由器

可以通过多种方式使 流量进入集群。最常见的方法是使用 OpenShift Container Platform router 作为 OpenShift Container Platform 安装中 services 的外部流量入口点。

OpenShift Container Platform 提供和支持以下路由器插件:

3.1.2. 路由器服务帐户

在部署 OpenShift Container Platform 集群前,您必须有一个路由器的服务帐户,该帐户会在集群安装过程中自动创建。此服务帐户具有 安全性上下文约束 (SCC)的权限,允许它指定主机端口。

3.1.2.1. 访问标签的权限

使用 命名空间标签 时,例如在创建 路由器分片 时,路由器的服务帐户必须具有 cluster-reader 权限。

$ oc adm policy add-cluster-role-to-user \
    cluster-reader \
    system:serviceaccount:default:router
Copy to Clipboard Toggle word wrap

服务帐户就位后,您可以继续安装默认的 HAProxy 路由器自定义 HAProxy 路由器

3.2. 使用默认 HAProxy 路由器

3.2.1. 概述

oc adm router 命令随管理员 CLI 一同提供,以简化在新安装中设置路由器的任务。oc adm router 命令创建服务和部署配置对象。使用 --service-account 选项指定路由器用于联系主控机的服务帐户。

路由器服务帐户 可以提前创建,或者通过 oc adm router --service-account 命令创建。

OpenShift Container Platform 组件之间的每种通信都受到 TLS 的保护,并使用各种证书和身份验证方法。可以提供 --default-certificate .pem 格式文件,或者由 oc adm router 命令创建文件。创建路由时,用户可以提供路由器在处理路由时使用的路由证书。

重要

删除路由器时,请确保也删除了部署配置、服务和机密。

路由器部署到特定的节点上。这使得集群管理员和外部网络管理器能够更轻松地协调哪个 IP 地址将运行路由器以及路由器将处理的流量。路由器通过使用 节点选择器 部署到特定的节点上。

重要

路由器默认使用主机网络,它们直接连接到主机上所有接口上的端口 80 和 443。将路由器限制为端口 80/443 可用且未被其他服务使用的主机,再使用 节点选择器调度程序配置 进行设置。例如,您可以通过专用基础架构节点来运行路由器等服务来达到此目的。

重要

建议将不同的 openshift-router 服务帐户与路由器分开。这可以通过 oc adm router 命令的 --service-account 标志来提供。

$ oc adm router --dry-run --service-account=router 
1
Copy to Clipboard Toggle word wrap
1
--service-accountopenshift-router 服务帐户 的名称。
重要

使用 oc adm router 创建的路由器 pod 具有默认的资源请求,节点必须满足这些请求才能部署路由器 pod。为提高基础架构组件的可靠性,默认资源请求用于在不使用资源请求的情况下增加 pod 以上的路由器容器集的 QoS 层。默认值表示部署基本路由器所需的已观察到最少资源,可以在路由器部署配置中编辑,并且您可能希望根据路由器负载来增加这些资源。

3.2.2. 创建路由器

如果路由器不存在,请运行以下命令来创建路由器:

$ oc adm router <router_name> --replicas=<number> --service-account=router --extended-logging=true
Copy to Clipboard Toggle word wrap

除非创建 高可用性 配置,否则 --replicas 通常为 1

--extended-logging=true 配置路由器,将 HAProxy 生成的日志转发到 syslog 容器。

查找路由器的主机 IP 地址:

$ oc get po <router-pod>  --template={{.status.hostIP}}
Copy to Clipboard Toggle word wrap

您还可以使用路由器分片来确保路由器被过滤到特定的命名空间或路由,或者在路由器创建后设置任何环境变量。本例中为每个分片创建一个路由器。

3.2.3. 其他基本路由器命令

检查默认路由器
名为 router 的默认路由器服务帐户会在集群安装过程中自动创建。验证此帐户是否已存在:
$ oc adm router --dry-run --service-account=router
Copy to Clipboard Toggle word wrap
查看默认路由器
查看创建的默认路由器会是什么样子:
$ oc adm router --dry-run -o yaml --service-account=router
Copy to Clipboard Toggle word wrap
将路由器配置为转发 HAProxy 日志
您可以将路由器配置为将 HAProxy 生成的日志转发到 rsyslog sidecar 容器。--extended-logging=true 参数附加 syslog 容器将 HAProxy 日志转发到标准输出。
$ oc adm router --extended-logging=true
Copy to Clipboard Toggle word wrap

以下示例是使用 --extended-logging=true 的路由器的配置:

$ oc get pod router-1-xhdb9 -o yaml
apiVersion: v1
kind: Pod
spec:
  containers:
  - env:

    ....

    - name: ROUTER_SYSLOG_ADDRESS 
1

      value: /var/lib/rsyslog/rsyslog.sock

    ....

 - command: 
2

   - /sbin/rsyslogd
   - -n
   - -i
   - /tmp/rsyslog.pid
   - -f
   - /etc/rsyslog/rsyslog.conf
   image: registry.redhat.io/openshift3/ose-haproxy-router:v3.11.188
   imagePullPolicy: IfNotPresent
   name: syslog
Copy to Clipboard Toggle word wrap
1
--extended-logging=true 参数为日志创建一个套接字文件。
2
--extended-logging=true 参数向路由器添加一个容器。在容器中,rsyslog 进程作为 /sbin/rsyslogd -n -i /tmp/rsyslog.pid -f /etc/rsyslog/rsyslog.conf 运行。

使用以下命令查看 HAProxy 日志:

$ oc set env dc/test-router ROUTER_LOG_LEVEL=info 
1

$ oc logs -f <pod-name> -c syslog 
2
Copy to Clipboard Toggle word wrap
1
将日志级别设置为 infodebug。默认值为 warning
2
指定要查看日志的路由器 pod 的名称。

HAProxy 日志的格式如下:

2020-04-14T03:05:36.629527+00:00 test-311-node-1 haproxy[43]: 10.0.151.166:59594 [14/Apr/2020:03:05:36.627] fe_no_sni~ be_secure:openshift-console:console/pod:console-b475748cb-t6qkq:console:10.128.0.5:8443 0/0/1/1/2 200 393 - - --NI 2/1/0/1/0 0/0 "HEAD / HTTP/1.1"
2020-04-14T03:05:36.633024+00:00 test-311-node-1 haproxy[43]: 10.0.151.166:59594 [14/Apr/2020:03:05:36.528] public_ssl be_no_sni/fe_no_sni 95/1/104 2793 -- 1/1/0/0/0 0/0
Copy to Clipboard Toggle word wrap
将路由器部署到标记的节点
将路由器部署到与指定 节点标签 匹配的任何节点上:
$ oc adm router <router_name> --replicas=<number> --selector=<label> \
    --service-account=router
Copy to Clipboard Toggle word wrap

例如,如果要创建一个名为 router 的路由器,并将其放置到带有 node-role.kubernetes.io/infra=true 标签的节点上:

$ oc adm router router --replicas=1 --selector='node-role.kubernetes.io/infra=true' \
  --service-account=router
Copy to Clipboard Toggle word wrap

在集群安装过程中,openshift_router_selectoropenshift_registry_selector Ansible 设置默认设置为 node-role.kubernetes.io/infra=true。只有在存在与 node-role.kubernetes.io/infra=true 标签匹配的节点时,才会自动部署默认路由器和 registry。

有关更新标签的详情,请参阅更新节点上的标签

根据调度程序策略,在不同的主机上创建多个实例。

使用不同的路由器镜像
使用其他路由器镜像并查看要使用的路由器配置:
$ oc adm router <router_name> -o <format> --images=<image> \
    --service-account=router
Copy to Clipboard Toggle word wrap

例如:

$ oc adm router region-west -o yaml --images=myrepo/somerouter:mytag \
    --service-account=router
Copy to Clipboard Toggle word wrap

3.2.4. 过滤到特定路由器的路由

使用 ROUTE_LABELS 环境变量,您可以过滤路由,使其仅供特定路由器使用。

例如,如果您有多个路由器和 100 个路由,您可以将标签附加到路由,以便一部分标签由一个路由器处理,而其余则由另一个路由器处理。

  1. 创建路由器 后,使用 ROUTE_LABELS 环境变量标记路由器:

    $ oc set env dc/<router=name>  ROUTE_LABELS="key=value"
    Copy to Clipboard Toggle word wrap
  2. 将标签添加到所需路由中:

    oc label route <route=name> key=value
    Copy to Clipboard Toggle word wrap
  3. 要验证标签是否已附加到路由,请检查路由配置:

    $ oc describe route/<route_name>
    Copy to Clipboard Toggle word wrap
设置最大并发连接数
默认情况下,路由器可以处理最多 20000 连接。您可以根据需要更改该限制。由于连接太少,健康检查无法正常工作,从而导致不必要的重启。您需要配置系统,以支持最大连接数。'sysctl fs.nr_open''sysctl fs.file-max' 中显示的限值必须足够大。否则,HAproxy 将不会启动。

创建路由器时,--max-connections= 选项会设置所需的限制:

$ oc adm router --max-connections=10000   ....
Copy to Clipboard Toggle word wrap

编辑路由器部署配置中的 ROUTER_MAX_CONNECTIONS 环境变量,以更改值。路由器容器集使用新值重启。如果 ROUTER_MAX_CONNECTIONS 不存在,则使用默认值 20000。

注意

连接包括 frontend 和 internal 后端。这表示两个连接。务必将 ROUTER_MAX_CONNECTIONS 设置为两倍,超过您要创建的连接数。

3.2.5. HAProxy Strict SNI

HAProxy strict-sni 可以通过路由器部署配置中的 ROUTER_STRICT_SNI 环境变量来控制。也可以使用 --strict-sni 命令行选项创建路由器时设置它。

$ oc adm router --strict-sni
Copy to Clipboard Toggle word wrap

3.2.6. TLS 密码套件

在创建路由器时使用 --ciphers 选项设置路由器密码套件

$ oc adm router --ciphers=modern   ....
Copy to Clipboard Toggle word wrap

值包括:modern, intermediate, 或 oldintermediate 为默认值。或者,可以提供一组":"分隔的密码。密码必须来自以下集合:

$ openssl ciphers
Copy to Clipboard Toggle word wrap

或者,将 ROUTER_CIPHERS 环境变量用于现有路由器。

3.2.7. 双向 TLS 身份验证

可以使用 mutual TLS 身份验证限制对路由器和后端服务的客户端访问。路由器将拒绝来自不在 通过身份验证 的集合中的客户端的请求。双向 TLS 身份验证是在客户端证书上实施的,可以根据签发证书的证书颁发机构(CA)控制,证书撤销列表和/或任何证书主题过滤器。在创建路由器时,使用 mutual tls 配置选项 --mutual-tls-auth, --mutual-tls-auth-ca, --mutual-tls-auth-crl--mutual-tls-auth-filter

$ oc adm router --mutual-tls-auth=required  \
                --mutual-tls-auth-ca=/local/path/to/cacerts.pem   ....
Copy to Clipboard Toggle word wrap

--mutual-tls-auth 的值是 required, optional, 或 nonenone 是默认值。--mutual-tls-auth-ca 值指定包含一个或多个 CA 证书的文件。路由器使用这些 CA 证书来验证客户端的证书。

可以使用 --mutual-tls-auth-crl 指定证书撤销列表,以处理证书(由有效认证机构签发)被撤销的情况。

$ oc adm router --mutual-tls-auth=required  \
     --mutual-tls-auth-ca=/local/path/to/cacerts.pem  \
     --mutual-tls-auth-filter='^/CN=my.org/ST=CA/C=US/O=Security/OU=OSE$'  \
     ....
Copy to Clipboard Toggle word wrap

--mutual-tls-auth-filter 值可用于根据证书主题进行精细的访问控制。该值是一个正则表达式,用于匹配证书的主题。

注意

上面的 mutual TLS 身份验证过滤器显示了一个限制性正则表达式(regex),包括在 ^$ 之间,这会完全准确匹配证书的主题。如果您决定使用限制较小的正则表达式,请注意这可能与您认为有效的任何 CA 颁发的证书匹配。建议您使用 --mutual-tls-auth-ca 选项,以便您更精细地控制发布的证书。

使用 --mutual-tls-auth=required 可确保您只允许经过身份验证的客户端访问后端资源。这意味着始终 需要 客户端来提供身份验证信息(提供一个客户端证书)。要使 mutual TLS 身份验证可选,请使用 --mutual-tls-auth=optional (或使用 none 禁用它,这是默认设置)。请注意,optional 意味着您 不需要 客户端提供任何身份验证信息,如果客户端提供任何身份验证信息,这会在 X-SSL* HTTP 标头中传递给后端。

$ oc adm router --mutual-tls-auth=optional  \
     --mutual-tls-auth-ca=/local/path/to/cacerts.pem  \
     ....
Copy to Clipboard Toggle word wrap

启用 mutual TLS 身份验证支持时(使用 --mutual-tls-auth 标志的 required 值或 optional 值),客户端身份验证信息将以 X-SSL* HTTP 标头的形式传递给后端。

X-SSL* HTTP 标头 X-SSL-Client-DN 示例:证书主题的完整可分辨名称(DN)。X-SSL-Client-NotBefore :客户端证书启动日期为 YYMMDDhhmmss[Z] 格式。X-SSL-Client-NotAfter :客户端证书结束日期,采用 YYMMDDhhmmss[Z] 格式。X-SSL-Client-SHA1 :客户端证书的 SHA-1 指纹。X-SSL-Client-DER :提供客户端证书的完整访问权限。包含以 base-64 格式编码的 DER 格式的客户端证书。

3.2.8. 高可用路由器

您可以使用 IP 故障切换在 OpenShift Container Platform 集群中设置高可用性路由器。此设置在不同节点上有多个副本,因此如果当前副本失败,故障切换软件可以切换到另一个副本。

3.2.9. 自定义路由器服务端口

您可以通过设置环境变量 ROUTER_SERVICE_HTTP_PORTROUTER_SERVICE_HTTPS_PORT 来自定义模板路由器绑定的服务端口。这可以通过创建模板路由器,然后编辑其部署配置来完成。

以下示例创建带有 0 个副本的路由器部署,并自定义路由器服务 HTTP 和 HTTPS 端口,然后相应地将其扩展(到 1 个副本)。

$ oc adm router --replicas=0 --ports='10080:10080,10443:10443' 
1

$ oc set env dc/router ROUTER_SERVICE_HTTP_PORT=10080  \
                   ROUTER_SERVICE_HTTPS_PORT=10443
$ oc scale dc/router --replicas=1
Copy to Clipboard Toggle word wrap
1
确保为使用容器网络模式 --host-network=false 的路由器正确设置公开端口。
重要

如果您确实自定义模板路由器服务端口,您还需要确保运行路由器 Pod 的节点在防火墙中打开这些自定义端口(通过 Ansible 或 iptables,或通过 firewall-cmd使用的任何其他自定义方式)。

以下是使用 iptables 打开自定义路由器服务端口的示例:

$ iptables -A OS_FIREWALL_ALLOW -p tcp --dport 10080 -j ACCEPT
$ iptables -A OS_FIREWALL_ALLOW -p tcp --dport 10443 -j ACCEPT
Copy to Clipboard Toggle word wrap

3.2.10. 使用多个路由器

管理员可以创建具有相同定义的多个路由器,为同一组路由提供服务。每个路由器将位于不同的节点,并且具有不同的 IP 地址。网络管理员需要获取到每个节点所需的流量。

可以分组多个路由器来在集群中分发路由负载,并将租户单独的租户分发到不同的路由器或 分片。组中的每个路由器或分片都根据路由器中的选择器接受路由。管理员可以使用 ROUTE_LABELS 在整个集群中创建分片。用户可以使用 NAMESPACE_LABELS 在命名空间(项目)上创建分片。

3.2.11. 在部署配置中添加 Node Selector

将特定路由器部署到特定的节点上需要两个步骤:

  1. 为所需节点添加 标签

    $ oc label node 10.254.254.28 "router=first"
    Copy to Clipboard Toggle word wrap
  2. 将节点选择器添加到路由器部署配置中:

    $ oc edit dc <deploymentConfigName>
    Copy to Clipboard Toggle word wrap

    使用与标签对应的键和值添加 template.spec.nodeSelector 字段:

    ...
      template:
        metadata:
          creationTimestamp: null
          labels:
            router: router1
        spec:
          nodeSelector:      
    1
    
            router: "first"
    ...
    Copy to Clipboard Toggle word wrap
    1
    键和值分别是 routerfirst,对应于 router=first 标签。

3.2.12. 使用路由器共享

路由器分片使用 NAMESPACE_LABELSROUTE_LABELS 来过滤路由器命名空间和路由。这可让您通过多个路由器部署分发路由的子集。通过使用非覆盖的子集,您可以有效地对一组路由进行分区。或者,您可以定义由重叠的路由子集组成的分片。

默认情况下,路由器从所有项目(命名空间)中选择所有路由。分片涉及将标签添加到路由或命名空间,以及向路由器添加标签选择器。每个路由器分片都由一组特定标签选择器或属于由特定标签选择器选择的命名空间来选择的路由组成。

注意

路由器服务帐户必须设置 [集群读取器] 权限,以允许访问其他命名空间中的标签。

路由器划分和 DNS

由于需要外部 DNS 服务器将请求路由到所需的分片,因此管理员负责为项目中的每个路由器创建单独的 DNS 条目。路由器不会将未知路由转发到另一个路由器。

考虑以下示例:

  • 路由器 A 驻留在主机 192.168.0.5 上,并且具有 *.foo.com 的路由。
  • 路由器 B 驻留在主机 192.168.1.9 上,并且具有 *.example.com 的路由。

单独的 DNS 条目必须将 *.foo.com 解析为托管 Router A 和 *.example.com 的节点:

  • *.foo.com A IN 192.168.0.5
  • *.example.com A IN 192.168.1.9

路由器分片示例

本节论述了使用命名空间和路由标签进行路由器分片。

图 3.1. 路由器划分基于命名空间标签

  1. 使用命名空间标签选择器配置路由器:

    $ oc set env dc/router NAMESPACE_LABELS="router=r1"
    Copy to Clipboard Toggle word wrap
  2. 由于该路由器在命名空间上有一个选择器,因此路由器将仅处理匹配的命名空间的路由。要使此选择器与命名空间匹配,请相应地标记命名空间:

    $ oc label namespace default "router=r1"
    Copy to Clipboard Toggle word wrap
  3. 现在,如果您在 default 命名空间中创建路由,该路由位于默认路由器中:

    $ oc create -f route1.yaml
    Copy to Clipboard Toggle word wrap
  4. 创建新项目(命名空间)并创建路由 route2

    $ oc new-project p1
    $ oc create -f route2.yaml
    Copy to Clipboard Toggle word wrap

    注意路由在路由器中不可用。

  5. 标签命名空间 p1 带有 router=r1

    $ oc label namespace p1 "router=r1"
    Copy to Clipboard Toggle word wrap

添加此标签使路由在路由器中可用。

示例

一个路由器部署 finops-router 使用标签选择器 NAMESPACE_LABELS="name in (finance, ops)" 配置,一个路由器部署 dev-router 使用标签选择器 NAMESPACE_LABELS="name=dev" 配置。

如果所有路由都位于标有 name=financename=opsname=dev 的命名空间 中,则此配置会在两个路由器部署之间有效分发您的路由。

在上面的场景中,分片成为分区的一种特殊情况,没有重叠的子集。路由在路由器分片之间划分。

路由选择标准适用于路由的分布方式。有可能在路由器部署之间具有重叠的路由子集。

示例

除了上例中的 finops-routerdev-router 外,您还有 devops-router,它使用标签选择器 NAMESPACE_LABELS="name in (dev, ops)" 配置。

标签为 name=devname=ops 的命名空间中的路由现在由两个不同的路由器部署服务。在这种情况下,您定义了重叠的路由子集,如 基于命名空间标签的路由器交换过程中所示。

另外,这可让您创建更复杂的路由规则,允许将优先级更高的流量转移到专用的 finops-router,同时将较低优先级的流量发送到 devops-router

基于路由标签的路由器划分

NAMESPACE_LABELS 允许过滤项目来服务并从这些项目中选择所有路由,但您可能希望根据与路由本身相关的其他标准对路由进行分区。ROUTE_LABELS 选择器允许您对路由本身进行分片。

示例

使用标签选择器 ROUTE_LABELS="mydeployment=prod" 配置路由器部署 prod-router,路由器部署 devtest-router 则配置了标签选择器 ROUTE_LABELS="mydeployment in(dev, test)"

此配置根据路由的标签(无论命名空间如何)在两个路由器部署之间路由。

这个示例假设您有要服务的所有路由,并带有标签 "mydeployment=<tag>"

3.2.12.1. 创建路由器分片

本节描述了路由器分片的高级示例。假设有 26 个路由,名为 a 到 z,且具有不同的标签:

路由上可能的标签

sla=high       geo=east     hw=modest     dept=finance
sla=medium     geo=west     hw=strong     dept=dev
sla=low                                   dept=ops
Copy to Clipboard Toggle word wrap

这些标签表达了包括服务级别协议、地理位置、硬件要求和部门在内的概念。路由最多可在每列中有一个标签。有些路由可能具有其他标签,或者根本没有标签。

Expand
名称SLA地域HW部门其他标签

a

high

东部

中等

finance

type=static

b

 

西部

 

type=dynamic

cde

 

中等

 

type=static

g 到 k

 

dev

 

l 到 s

high

 

中等

ops

 

t — z

 

西部

  

type=dynamic

以下是一个便捷脚本 mkshard,它演示了如何一起使用 oc adm routeroc set envoc scale 来创建路由器分片。

#!/bin/bash
# Usage: mkshard ID SELECTION-EXPRESSION
id=$1
sel="$2"
router=router-shard-$id           
1

oc adm router $router --replicas=0  
2

dc=dc/router-shard-$id            
3

oc set env   $dc ROUTE_LABELS="$sel"  
4

oc scale $dc --replicas=3         
5
Copy to Clipboard Toggle word wrap
1
创建的路由器具有名称 router-shard-<id>
2
暂时不要进行扩展。
3
路由器的部署配置。
4
使用 oc set env 设置选择表达式。选择表达式是 ROUTE_LABELS 环境变量的值。
5
向上扩展。

运行 mkshard 几次创建多个路由器:

Expand
路由器选择表达式Routes

router-shard-1

sla=high

a, l — s

router-shard-2

geo=west

b, t — z

router-shard-3

dept=dev

g 到 k

3.2.12.2. 修改路由器分片

由于路由器分片是基于标签的结构,因此您可以修改标签(通过 oc label)或选择表达式(通过 oc set env)。

本节扩展了创建路由器分片一节中启动的示例,演示了如何更改选择表达式。

以下是可修改现有路由器以使用新选择表达式的便捷脚本 modshard

#!/bin/bash
# Usage: modshard ID SELECTION-EXPRESSION...
id=$1
shift
router=router-shard-$id       
1

dc=dc/$router                 
2

oc scale $dc --replicas=0     
3

oc set env   $dc "$@"             
4

oc scale $dc --replicas=3     
5
Copy to Clipboard Toggle word wrap
1
修改后的路由器具有名称 router-shard-<id>
2
进行修改的部署配置。
3
缩减规模。
4
使用 oc set env 设置新的选择表达式。与创建路由器分片部分中的 mkshard 不同,在 modshard 中指定为非ID 参数的选择表达式必须包含环境变量名称及其值。
5
纵向扩展。
注意

modshard 中,如果 router-shard-<id>部署策略Rolling,则不需要 oc scale 命令。

例如,将 router-shard-3 的部门扩展到包含 opsdev

$ modshard 3 ROUTE_LABELS='dept in (dev, ops)'
Copy to Clipboard Toggle word wrap

结果是,router-shard-3 现在选择路由 g — s (g — kl — s 的组合)。

本例考虑了本例中只有三个部门,并指定了一个部门离开分片,从而得到与上例相同的结果:

$ modshard 3 ROUTE_LABELS='dept != finance'
Copy to Clipboard Toggle word wrap

这个示例指定了三个用逗号分开的功能,并只选择路由 b

$ modshard 3 ROUTE_LABELS='hw=strong,type=dynamic,geo=west'
Copy to Clipboard Toggle word wrap

与涉及路由标签的 ROUTE_LABELS 类似,您可以使用 NAMESPACE_LABELS 环境变量根据路由命名空间的标签选择路由。本例修改 router-shard-3 以提供命名空间具有标签 frequency=weekly 的路由:

$ modshard 3 NAMESPACE_LABELS='frequency=weekly'
Copy to Clipboard Toggle word wrap

最后一个示例组合了 ROUTE_LABELSNAMESPACE_LABELS,以选择带有标签 sla=low 的路由,其命名空间具有标签 frequency=weekly

$ modshard 3 \
    NAMESPACE_LABELS='frequency=weekly' \
    ROUTE_LABELS='sla=low'
Copy to Clipboard Toggle word wrap

3.2.13. 查找路由器的主机名

在公开服务时,用户可以使用来自外部用户用于访问应用的 DNS 名称相同的路由。外部网络的网络管理员必须确保主机名解析为已接受该路由的路由器的名称。用户可以使用指向此主机名的 CNAME 设置 DNS。但是,用户可能不知道路由器的主机名。当不知道时,集群管理员可以提供它。

在创建路由器时,集群管理员可以使用 --router-canonical-hostname 选项和路由器的规范主机名。例如:

# oc adm router myrouter --router-canonical-hostname="rtr.example.com"
Copy to Clipboard Toggle word wrap

这会在包含路由器主机名的路由器部署配置中创建 ROUTER_CANONICAL_HOSTNAME 环境变量。

对于已存在的路由器,集群管理员可以编辑路由器的部署配置,并添加 ROUTER_CANONICAL_HOSTNAME 环境变量:

spec:
  template:
    spec:
      containers:
        - env:
          - name: ROUTER_CANONICAL_HOSTNAME
            value: rtr.example.com
Copy to Clipboard Toggle word wrap

ROUTER_CANONICAL_HOSTNAME 值显示在接受该路由的所有路由器的路由状态中。每次重新载入路由器时,路由状态都会刷新。

当用户创建路由时,所有活跃的路由器都会评估路由,如果满足条件,则接受路由。当定义 ROUTER_CANONICAL_HOSTNAME 环境变量的路由器接受该路由时,路由器会将该值放在路由状态的 routerCanonicalHostname 字段中。用户可以检查路由状态,以确定路由器是否允许该路由,从列表中选择路由器,再查找要传给网络管理员的路由器的主机名。

status:
  ingress:
    conditions:
      lastTransitionTime: 2016-12-07T15:20:57Z
      status: "True"
      type: Admitted
      host: hello.in.mycloud.com
      routerCanonicalHostname: rtr.example.com
      routerName: myrouter
      wildcardPolicy: None
Copy to Clipboard Toggle word wrap

在可用时 oc describe 会包括主机名:

$ oc describe route/hello-route3
...
Requested Host: hello.in.mycloud.com exposed on router myroute (host rtr.example.com) 12 minutes ago
Copy to Clipboard Toggle word wrap

利用上述信息,用户可以要求 DNS 管理员将路由的主机 hello.in.mycloud.com 中的 CNAME 设置为路由器的规范主机名 rtr.example.com。这将导致指向 hello.in.mycloud.com 的任何流量到达用户的应用。

3.2.14. 自定义默认路由子域

您可以通过修改 master 配置文件(默认为 /etc/origin/master/master-config.yaml 文件)来自定义用作环境默认路由子域的后缀。没有指定主机名的路由会有一个使用该默认路由子域生成的路由。

以下示例演示了如何将配置的后缀设置为 v3.openshift.test

routingConfig:
  subdomain: v3.openshift.test
Copy to Clipboard Toggle word wrap
注意

如果 master 正在运行,这个更改需要重启。

运行上述配置的 OpenShift Container Platform master 时,对于名为 no-route-hostname 的示例路由(没有主机名添加到命名空间 mynamespace生成的主机名将是:

no-route-hostname-mynamespace.v3.openshift.test
Copy to Clipboard Toggle word wrap

3.2.15. 将路由主机名强制到自定义路由子域

如果管理员希望限制到特定路由子域的所有路由,他们可以将 --force-subdomain 选项传递给 oc adm router 命令。这会强制路由器覆盖路由中指定的任何主机名,并根据提供给 --force-subdomain 选项的模板生成一个主机名。

以下示例运行路由器,它使用自定义子域模板 ${name}-${namespace}.apps.example.com 来覆盖路由主机名。

$ oc adm router --force-subdomain='${name}-${namespace}.apps.example.com'
Copy to Clipboard Toggle word wrap

3.2.16. 使用通配符证书

不包含证书的 TLS 路由改为使用路由器的默认证书。在大多数情况下,此证书应由可信证书颁发机构提供,但为了方便起见,您可以使用 OpenShift Container Platform CA 创建证书。例如:

$ CA=/etc/origin/master
$ oc adm ca create-server-cert --signer-cert=$CA/ca.crt \
      --signer-key=$CA/ca.key --signer-serial=$CA/ca.serial.txt \
      --hostnames='*.cloudapps.example.com' \
      --cert=cloudapps.crt --key=cloudapps.key
Copy to Clipboard Toggle word wrap
注意

oc adm ca create-server-cert 命令会生成一个有效期为两年的证书。这可以通过 --expire-days 选项进行修改,但出于安全原因,建议不要超过这个值。

仅从 Ansible 主机清单文件中列出的第一个 master 运行 oc adm 命令,默认为 /etc/ansible/hosts

路由器预期证书和密钥在单个文件中采用 PEM 格式:

$ cat cloudapps.crt cloudapps.key $CA/ca.crt > cloudapps.router.pem
Copy to Clipboard Toggle word wrap

在这里您可以使用 --default-cert 标志:

$ oc adm router --default-cert=cloudapps.router.pem --service-account=router
Copy to Clipboard Toggle word wrap
注意

浏览器只考虑一个级别深度的子域有效通配符。因此在此示例中,证书对 a.cloudapps.example.com 有效,但不适用于 a.b.cloudapps.example.com

3.2.17. 手动重新部署证书

手动重新部署路由器证书:

  1. 检查包含默认路由器证书的 secret 是否已添加到路由器中:

    $ oc set volume dc/router
    
    deploymentconfigs/router
      secret/router-certs as server-certificate
        mounted at /etc/pki/tls/private
    Copy to Clipboard Toggle word wrap

    如果添加了证书,请跳过以下步骤并覆盖 secret。

  2. 确保为以下变量 DEFAULT_CERTIFICATE_DIR 设置了一个默认证书目录:

    $ oc set env dc/router --list
    
    DEFAULT_CERTIFICATE_DIR=/etc/pki/tls/private
    Copy to Clipboard Toggle word wrap

    如果没有,请使用以下命令创建该目录:

    $ oc set env dc/router DEFAULT_CERTIFICATE_DIR=/etc/pki/tls/private
    Copy to Clipboard Toggle word wrap
  3. 将证书导出到 PEM 格式:

    $ cat custom-router.key custom-router.crt custom-ca.crt > custom-router.crt
    Copy to Clipboard Toggle word wrap
  4. 覆盖或创建路由器证书 secret:

    如果证书 secret 添加到路由器,请覆盖该 secret。如果没有,请创建一个新 secret。

    要覆盖 secret,请运行以下命令:

    $ oc create secret generic router-certs --from-file=tls.crt=custom-router.crt --from-file=tls.key=custom-router.key --type=kubernetes.io/tls -o json --dry-run | oc replace -f -
    Copy to Clipboard Toggle word wrap

    要创建新 secret,请运行以下命令:

    $ oc create secret generic router-certs --from-file=tls.crt=custom-router.crt --from-file=tls.key=custom-router.key --type=kubernetes.io/tls
    
    $ oc set volume dc/router --add --mount-path=/etc/pki/tls/private --secret-name='router-certs' --name router-certs
    Copy to Clipboard Toggle word wrap
  5. 部署路由器。

    $ oc rollout latest dc/router
    Copy to Clipboard Toggle word wrap

3.2.18. 使用安全路由

目前,不支持密码保护的密钥文件。启动后,HAProxy 会提示输入密码,且无法自动执行此过程。要从密钥文件中删除密码短语,您可以运行以下命令:

# openssl rsa -in <passwordProtectedKey.key> -out <new.key>
Copy to Clipboard Toggle word wrap

以下是如何在流量代理到目的地之前使用发生在路由器上发生 TLS 终止的安全边缘终止路由的示例:安全边缘终止路由指定 TLS 证书和密钥信息。TLS 证书由路由器前端提供。

首先,启动一个路由器实例:

# oc adm router --replicas=1 --service-account=router
Copy to Clipboard Toggle word wrap

接下来,为我们边缘安全路由创建私钥、csr 和证书。有关如何执行此操作的说明将特定于您的证书颁发机构和提供商。有关名为 www.example.test 的域的简单自签名证书,请参考以下示例:

# sudo openssl genrsa -out example-test.key 2048
#
# sudo openssl req -new -key example-test.key -out example-test.csr  \
  -subj "/C=US/ST=CA/L=Mountain View/O=OS3/OU=Eng/CN=www.example.test"
#
# sudo openssl x509 -req -days 366 -in example-test.csr  \
      -signkey example-test.key -out example-test.crt
Copy to Clipboard Toggle word wrap

使用上述证书和密钥生成路由。

$ oc create route edge --service=my-service \
    --hostname=www.example.test \
    --key=example-test.key --cert=example-test.crt
route "my-service" created
Copy to Clipboard Toggle word wrap

看一下其定义。

$ oc get route/my-service -o yaml
apiVersion: v1
kind: Route
metadata:
  name:  my-service
spec:
  host: www.example.test
  to:
    kind: Service
    name: my-service
  tls:
    termination: edge
    key: |
      -----BEGIN PRIVATE KEY-----
      [...]
      -----END PRIVATE KEY-----
    certificate: |
      -----BEGIN CERTIFICATE-----
      [...]
      -----END CERTIFICATE-----
Copy to Clipboard Toggle word wrap

确保 www.example.test 的 DNS 条目指向您的路由器实例,并且到您的域的路由应可用。以下示例使用 curl 和本地解析器模拟 DNS 查找:

# routerip="4.1.1.1"  #  replace with IP address of one of your router instances.
# curl -k --resolve www.example.test:443:$routerip https://www.example.test/
Copy to Clipboard Toggle word wrap

3.2.19. 使用通配符路由(用于子域)

HAProxy 路由器支持通配符路由,这通过将 ROUTER_ALLOW_WILDCARD_ROUTES 环境变量设置为 true 来启用。具有 Subdomain 通配符策略且通过路由器准入检查的任何路由都将由 HAProxy 路由器提供服务。然后,HAProxy 路由器根据路由的通配符策略公开相关的服务(用于路由)。

重要

要更改路由的通配符策略,您必须删除路由并使用更新的通配符策略重新创建路由。仅编辑路由的 .yaml 文件中的路由通配符策略无法正常工作。

$ oc adm router --replicas=0 ...
$ oc set env dc/router ROUTER_ALLOW_WILDCARD_ROUTES=true
$ oc scale dc/router --replicas=1
Copy to Clipboard Toggle word wrap

了解如何为通配符路由配置 Web 控制台

使用安全通配符边缘终止路由

这个示例反映了在流量代理到目的地之前在路由器上发生的 TLS 终止。发送到子域 example.org(*.example.org )中的任何主机的流量将代理到公开的服务。

安全边缘终止路由指定 TLS 证书和密钥信息。TLS 证书由与子域(*.example.org)匹配的所有主机的路由器前端提供。

  1. 启动路由器实例:

    $ oc adm router --replicas=0 --service-account=router
    $ oc set env dc/router ROUTER_ALLOW_WILDCARD_ROUTES=true
    $ oc scale dc/router --replicas=1
    Copy to Clipboard Toggle word wrap
  2. 为边缘安全路由创建私钥、证书签名请求(CSR)和证书。

    有关如何执行此操作的说明特定于您的证书颁发机构和供应商。有关名为 *.example.test 的域的简单自签名证书,请查看以下示例:

    # sudo openssl genrsa -out example-test.key 2048
    #
    # sudo openssl req -new -key example-test.key -out example-test.csr  \
      -subj "/C=US/ST=CA/L=Mountain View/O=OS3/OU=Eng/CN=*.example.test"
    #
    # sudo openssl x509 -req -days 366 -in example-test.csr  \
          -signkey example-test.key -out example-test.crt
    Copy to Clipboard Toggle word wrap
  3. 使用上述证书和密钥生成通配符路由:

    $ cat > route.yaml  <<REOF
    apiVersion: v1
    kind: Route
    metadata:
      name:  my-service
    spec:
      host: www.example.test
      wildcardPolicy: Subdomain
      to:
        kind: Service
        name: my-service
      tls:
        termination: edge
        key: "$(perl -pe 's/\n/\\n/' example-test.key)"
        certificate: "$(perl -pe 's/\n/\\n/' example-test.cert)"
    REOF
    $ oc create -f route.yaml
    Copy to Clipboard Toggle word wrap

    确保 *.example.test 的 DNS 条目指向您的路由器实例,并且到域的路由可用。

    这个示例使用带有本地解析器的 curl 来模拟 DNS 查找:

    # routerip="4.1.1.1"  #  replace with IP address of one of your router instances.
    # curl -k --resolve www.example.test:443:$routerip https://www.example.test/
    # curl -k --resolve abc.example.test:443:$routerip https://abc.example.test/
    # curl -k --resolve anyname.example.test:443:$routerip https://anyname.example.test/
    Copy to Clipboard Toggle word wrap

对于允许通配符路由的路由器(ROUTER_ALLOW_WILDCARD_ROUTES 设置为 true),存在一些注意事项,即与通配符路由关联的子域的所有权。

在通配符路由之前,所有权基于针对任何其他声明赢得路由最旧的命名空间的主机名提出的声明。例如,如果路由 r1 比路由 r2 老,对于 主机名 one.example.test,命名空间 ns1 中的路由 r1(有一个 one.example.test 的声明)会优于命令空间 ns2 中具有相同声明的路由 r2

另外,其他命名空间中的路由也被允许声明非覆盖的主机名。例如,命名空间 ns1 中的路由 rone 可以声明 www.example.test,命名空间 d2 中的另一个路由 rtwo 可以声明 c3po.example.test

如果没有任何通配符路由声明同一子域(上例中的example.test ),则仍会出现这种情况。

但是,通配符路由需要声明子域中的所有主机名(以 \*.example.test格式的主机名)。通配符路由的声明会根据该子域的最旧路由(example.test)是否与通配符路由在同一命名空间中被允许或拒绝。最旧的路由可以是常规路由,也可以是通配符路由。

例如,如果已有一个路由 eldest 存在于 s1 命名空间中,声明一个名为 owner.example.test 的主机,如果稍后某个时间点上添加了一个新的通配符用来通配子域 (example.test) 中的路由,则通配路由的声明仅在与拥有的路由处于相同命名空间 (ns1)时才被允许。

以下示例演示了通配符路由的声明将成功或失败的各种情景。

在以下示例中,只要通配符路由未声明子域,允许通配符路由的路由器将允许对子域 example.test 中的主机进行非覆盖声明。

$ oc adm router ...
$ oc set env dc/router ROUTER_ALLOW_WILDCARD_ROUTES=true

$ oc project ns1
$ oc expose service myservice --hostname=owner.example.test
$ oc expose service myservice --hostname=aname.example.test
$ oc expose service myservice --hostname=bname.example.test

$ oc project ns2
$ oc expose service anotherservice --hostname=second.example.test
$ oc expose service anotherservice --hostname=cname.example.test

$ oc project otherns
$ oc expose service thirdservice --hostname=emmy.example.test
$ oc expose service thirdservice --hostname=webby.example.test
Copy to Clipboard Toggle word wrap

在以下示例中,允许通配符路由的路由器不允许 owner.example.testaname.example.test 的声明成功,因为拥有的命名空间是 ns1

$ oc adm router ...
$ oc set env dc/router ROUTER_ALLOW_WILDCARD_ROUTES=true

$ oc project ns1
$ oc expose service myservice --hostname=owner.example.test
$ oc expose service myservice --hostname=aname.example.test

$ oc project ns2
$ oc expose service secondservice --hostname=bname.example.test
$ oc expose service secondservice --hostname=cname.example.test

$ # Router will not allow this claim with a different path name `/p1` as
$ # namespace `ns1` has an older route claiming host `aname.example.test`.
$ oc expose service secondservice --hostname=aname.example.test --path="/p1"

$ # Router will not allow this claim as namespace `ns1` has an older route
$ # claiming host name `owner.example.test`.
$ oc expose service secondservice --hostname=owner.example.test

$ oc project otherns

$ # Router will not allow this claim as namespace `ns1` has an older route
$ # claiming host name `aname.example.test`.
$ oc expose service thirdservice --hostname=aname.example.test
Copy to Clipboard Toggle word wrap

在以下示例中,允许通配符路由的路由器将允许 '\*.example.test 声明成功,因为拥有的命名空间是 ns1,通配符路由属于同一命名空间。

$ oc adm router ...
$ oc set env dc/router ROUTER_ALLOW_WILDCARD_ROUTES=true

$ oc project ns1
$ oc expose service myservice --hostname=owner.example.test

$ # Reusing the route.yaml from the previous example.
$ # spec:
$ #   host: www.example.test
$ #   wildcardPolicy: Subdomain

$ oc create -f route.yaml   #  router will allow this claim.
Copy to Clipboard Toggle word wrap

在以下示例中,允许通配符路由的路由器不允许 '\*.example.test 声明成功,因为拥有的命名空间是 ns1,并且通配符路由属于另一个命名空间 cyclone

$ oc adm router ...
$ oc set env dc/router ROUTER_ALLOW_WILDCARD_ROUTES=true

$ oc project ns1
$ oc expose service myservice --hostname=owner.example.test

$ # Switch to a different namespace/project.
$ oc project cyclone

$ # Reusing the route.yaml from a prior example.
$ # spec:
$ #   host: www.example.test
$ #   wildcardPolicy: Subdomain

$ oc create -f route.yaml   #  router will deny (_NOT_ allow) this claim.
Copy to Clipboard Toggle word wrap

同样,当具有通配符路由的命名空间声明子域后,只有该命名空间中的路由才能声明同一子域中的任何主机。

在以下示例中,当命名空间 ns1 中带有通配符路由声明子域 example.test 的路由之后,只有命名空间 ns1 中的路由可以声明同一子域中的任何主机。

$ oc adm router ...
$ oc set env dc/router ROUTER_ALLOW_WILDCARD_ROUTES=true

$ oc project ns1
$ oc expose service myservice --hostname=owner.example.test

$ oc project otherns

$ # namespace `otherns` is allowed to claim for other.example.test
$ oc expose service otherservice --hostname=other.example.test

$ oc project ns1

$ # Reusing the route.yaml from the previous example.
$ # spec:
$ #   host: www.example.test
$ #   wildcardPolicy: Subdomain

$ oc create -f route.yaml   #  Router will allow this claim.

$ #  In addition, route in namespace otherns will lose its claim to host
$ #  `other.example.test` due to the wildcard route claiming the subdomain.

$ # namespace `ns1` is allowed to claim for deux.example.test
$ oc expose service mysecondservice --hostname=deux.example.test

$ # namespace `ns1` is allowed to claim for deux.example.test with path /p1
$ oc expose service mythirdservice --hostname=deux.example.test --path="/p1"

$ oc project otherns

$ # namespace `otherns` is not allowed to claim for deux.example.test
$ # with a different path '/otherpath'
$ oc expose service otherservice --hostname=deux.example.test --path="/otherpath"

$ # namespace `otherns` is not allowed to claim for owner.example.test
$ oc expose service yetanotherservice --hostname=owner.example.test

$ # namespace `otherns` is not allowed to claim for unclaimed.example.test
$ oc expose service yetanotherservice --hostname=unclaimed.example.test
Copy to Clipboard Toggle word wrap

在以下示例中,显示了不同的场景,其中删除所有者路由并在命名空间内和跨命名空间传递所有权。虽然命名空间 ns1 中存在声明主机 eldest.example.test 的路由,但该命名空间中的通配符路由可以声明子域 example.test。当删除主机 eldest.example.test 的路由时,下一个最旧的路由 senior.example.test 将成为最旧的路由,不会影响任何其他路由。删除主机 senior.example.test 的路由后,下一个最旧的路由 junior.example.test 将成为最旧路由并阻止通配符路由。

$ oc adm router ...
$ oc set env dc/router ROUTER_ALLOW_WILDCARD_ROUTES=true

$ oc project ns1
$ oc expose service myservice --hostname=eldest.example.test
$ oc expose service seniorservice --hostname=senior.example.test

$ oc project otherns

$ # namespace `otherns` is allowed to claim for other.example.test
$ oc expose service juniorservice --hostname=junior.example.test

$ oc project ns1

$ # Reusing the route.yaml from the previous example.
$ # spec:
$ #   host: www.example.test
$ #   wildcardPolicy: Subdomain

$ oc create -f route.yaml   #  Router will allow this claim.

$ #  In addition, route in namespace otherns will lose its claim to host
$ #  `junior.example.test` due to the wildcard route claiming the subdomain.

$ # namespace `ns1` is allowed to claim for dos.example.test
$ oc expose service mysecondservice --hostname=dos.example.test

$ # Delete route for host `eldest.example.test`, the next oldest route is
$ # the one claiming `senior.example.test`, so route claims are unaffacted.
$ oc delete route myservice

$ # Delete route for host `senior.example.test`, the next oldest route is
$ # the one claiming `junior.example.test` in another namespace, so claims
$ # for a wildcard route would be affected. The route for the host
$ # `dos.example.test` would be unaffected as there are no other wildcard
$ # claimants blocking it.
$ oc delete route seniorservice
Copy to Clipboard Toggle word wrap

3.2.20. 使用 Container Network Stack

OpenShift Container Platform 路由器在容器内运行,默认的行为是使用主机的网络堆栈(即,路由器容器运行的节点)。这个默认行为有利于性能,因为来自远程客户端的网络流量不需要通过用户空间获取多个跃点来访问目标服务和容器。

另外,这个默认行为可让路由器获取远程连接的实际源 IP 地址,而不是获取节点的 IP 地址。这可用于定义基于原始 IP、支持粘性会话和监控流量以及其他用途的入口规则。

此主机网络行为由 --host-network 路由器命令行选项控制,默认行为等同于使用 --host-network=true。如果要使用容器网络堆栈运行路由器,请在创建路由器时使用 --host-network=false 选项。例如:

$ oc adm router --service-account=router --host-network=false
Copy to Clipboard Toggle word wrap

在内部,这意味着路由器容器必须发布 80 和 443 端口,以便外部网络与路由器通信。

注意

使用容器网络堆栈运行意味着路由器将连接的源 IP 地址视为节点的 NATed IP 地址,而不是实际的远程 IP 地址。

注意

在使用多租户网络隔离的 OpenShift Container Platform 集群中,带有 --host-network=false 选项的非默认命名空间中的路由器将加载集群中的所有路由,但命名空间之间的路由会因为网络隔离而无法访问。使用 --host-network=true 选项时,路由会绕过容器网络,并且可以访问集群中的任何 pod。在这种情况下,如果需要隔离,则不要在命名空间间添加路由。

3.2.21. 使用动态配置管理器

您可以配置 HAProxy 路由器来支持动态配置管理器。

动态配置管理器带来某些类型的在线路由,无需 HAProxy 重新加载停机时间。它处理任何路由和端点生命周期事件,如路由和端点附加 |deletion|update

通过将 ROUTER_HAPROXY_CONFIG_MANAGER 环境变量设置为 true 来启用动态配置管理器:

$ oc set env dc/<router_name> ROUTER_HAPROXY_CONFIG_MANAGER='true'
Copy to Clipboard Toggle word wrap

如果动态配置管理器无法动态配置 HAProxy,它会重写配置并重新加载 HAProxy 进程。例如,如果新路由包含自定义注解,如自定义超时,或者路由需要自定义 TLS 配置。

动态配置内部使用 HAProxy 套接字和配置 API,以及预分配的路由和后端服务器池。预分配的路由池使用路由蓝图创建。默认蓝图集支持不安全的路由、边缘安全路由,无需任何自定义 TLS 配置和直通路由。

重要

重新加密 路由需要自定义 TLS 配置信息,因此需要额外的配置才能将其用于动态配置管理器。

通过设置 ROUTER_BLUEPRINT_ROUTE_NAMESPACE 以及可选的 ROUTER_BLUEPRINT_ROUTE_LABELS 环境变量来扩展动态配置管理器可以使用的蓝图。

蓝图路由命名空间中的所有路由或路由标签的路由作为与默认蓝图集类似的自定义蓝图处理。这包括使用自定义注解或路由的重新加密路由或自定义 TLS 配置的路由。

以下流程假定您已创建了三个路由对象:reencrypt-blueprint, annotated-edge-blueprint, 和 annotated-unsecured-blueprint。如需不同路由类型对象的示例,请参阅 Route Types

流程

  1. 创建一个新项目

    $ oc new-project namespace_name
    Copy to Clipboard Toggle word wrap
  2. 创建新路由。此方法公开现有的服务:

    $ oc create route edge edge_route_name --key=/path/to/key.pem \
          --cert=/path/to/cert.pem --service=<service> --port=8443
    Copy to Clipboard Toggle word wrap
  3. 标记路由:

    $ oc label route edge_route_name type=route_label_1
    Copy to Clipboard Toggle word wrap
  4. 创建与路由对象定义不同的路由 :所有都具有标签 type=route_label_1:

    $ oc create -f reencrypt-blueprint.yaml
    $ oc create -f annotated-edge-blueprint.yaml
    $ oc create -f annotated-unsecured-blueprint.json
    Copy to Clipboard Toggle word wrap

    您还可以从路由中删除标签,这会阻止它用作蓝图路由。例如,防止 annotated-unsecured-blueprint 用作蓝图路由:

    $ oc label route annotated-unsecured-blueprint type-
    Copy to Clipboard Toggle word wrap
  5. 创建用于蓝图池的新路由器:

    $ oc adm router
    Copy to Clipboard Toggle word wrap
  6. 为新路由器设置环境变量:

    $ oc set env dc/router ROUTER_HAPROXY_CONFIG_MANAGER=true      \
                           ROUTER_BLUEPRINT_ROUTE_NAMESPACE=namespace_name  \
                           ROUTER_BLUEPRINT_ROUTE_LABELS="type=route_label_1"
    Copy to Clipboard Toggle word wrap

    处理命名空间或带有 type=route_label_1 标签的项目 namespace_name 中的所有路由,并用作自定义蓝图。

    请注意,您还可以通过管理该命名空间 namespace_name 中的路由来添加、更新或删除蓝图。动态配置管理器会监视命名空间 namespace_name 中路由的更改,类似于路由器监视路由服务的方式。

  7. 预分配的路由和后端服务器的池大小可以通过 ROUTER_BLUEPRINT_ROUTE_POOL_SIZE 控制,默认为 10, 而 ROUTER_MAX_DYNAMIC_SERVERS 默认为 5 环境变量。您还可以控制动态配置管理器所做的更改的频率,即当重新编写 HAProxy 配置并重新加载 HAProxy 进程时。默认值为 1 小时或 3600 秒,或者当动态配置管理器用尽池空间时。COMMIT_INTERVAL 环境变量控制此设置:

    $ oc set env dc/router -c router ROUTER_BLUEPRINT_ROUTE_POOL_SIZE=20  \
          ROUTER_MAX_DYNAMIC_SERVERS=3 COMMIT_INTERVAL=6h
    Copy to Clipboard Toggle word wrap

    这个示例将每个蓝图路由的池大小增加到 20,将动态服务器的数量减少到 3,并将提交间隔增加到 6 小时。

3.2.22. 公开路由器指标

HAProxy 路由器指标 默认以 Prometheus 格式 公开或发布,供外部指标收集和聚合系统(如 Prometheus、statsd)使用。指标数据也可直接从 HAProxy 路由器 以自己的 HTML 格式获取,以便在浏览器或 CSV 下载中查看。这些指标包括 HAProxy 原生指标和一些控制器指标。

当您使用以下命令创建路由器时,OpenShift Container Platform 以 Prometheus 格式在 stats 端口(默认为 1936)上提供指标数据。

$ oc adm router --service-account=router
Copy to Clipboard Toggle word wrap
  • 要提取 Prometheus 格式的原始统计信息,请运行以下命令:

    curl <user>:<password>@<router_IP>:<STATS_PORT>
    Copy to Clipboard Toggle word wrap

    例如:

    $ curl admin:sLzdR6SgDJ@10.254.254.35:1936/metrics
    Copy to Clipboard Toggle word wrap

    您可以获取访问路由器服务注解中的指标所需的信息:

    $ oc edit service <router-name>
    
    apiVersion: v1
    kind: Service
    metadata:
      annotations:
        prometheus.io/port: "1936"
        prometheus.io/scrape: "true"
        prometheus.openshift.io/password: IImoDqON02
        prometheus.openshift.io/username: admin
    Copy to Clipboard Toggle word wrap

    prometheus.io/port 是 stats 端口,默认为 1936。您可能需要配置防火墙以允许访问。使用前面的用户名和密码来访问指标。路径是 /metrics

    $ curl <user>:<password>@<router_IP>:<STATS_PORT>
    for example:
    $ curl admin:sLzdR6SgDJ@10.254.254.35:1936/metrics
    ...
    # HELP haproxy_backend_connections_total Total number of connections.
    # TYPE haproxy_backend_connections_total gauge
    haproxy_backend_connections_total{backend="http",namespace="default",route="hello-route"} 0
    haproxy_backend_connections_total{backend="http",namespace="default",route="hello-route-alt"} 0
    haproxy_backend_connections_total{backend="http",namespace="default",route="hello-route01"} 0
    ...
    # HELP haproxy_exporter_server_threshold Number of servers tracked and the current threshold value.
    # TYPE haproxy_exporter_server_threshold gauge
    haproxy_exporter_server_threshold{type="current"} 11
    haproxy_exporter_server_threshold{type="limit"} 500
    ...
    # HELP haproxy_frontend_bytes_in_total Current total of incoming bytes.
    # TYPE haproxy_frontend_bytes_in_total gauge
    haproxy_frontend_bytes_in_total{frontend="fe_no_sni"} 0
    haproxy_frontend_bytes_in_total{frontend="fe_sni"} 0
    haproxy_frontend_bytes_in_total{frontend="public"} 119070
    ...
    # HELP haproxy_server_bytes_in_total Current total of incoming bytes.
    # TYPE haproxy_server_bytes_in_total gauge
    haproxy_server_bytes_in_total{namespace="",pod="",route="",server="fe_no_sni",service=""} 0
    haproxy_server_bytes_in_total{namespace="",pod="",route="",server="fe_sni",service=""} 0
    haproxy_server_bytes_in_total{namespace="default",pod="docker-registry-5-nk5fz",route="docker-registry",server="10.130.0.89:5000",service="docker-registry"} 0
    haproxy_server_bytes_in_total{namespace="default",pod="hello-rc-vkjqx",route="hello-route",server="10.130.0.90:8080",service="hello-svc-1"} 0
    ...
    Copy to Clipboard Toggle word wrap
  • 在浏览器中获取指标:

    1. 从路由器部署配置文件中删除以下 环境变量

      $ oc edit dc router
      
      - name: ROUTER_LISTEN_ADDR
        value: 0.0.0.0:1936
      - name: ROUTER_METRICS_TYPE
        value: haproxy
      Copy to Clipboard Toggle word wrap
    2. 对路由器就绪度探测进行补丁,以使用与存活度探测相同的路径,它现在由 haproxy 路由器提供:

      $ oc patch dc router -p '"spec": {"template": {"spec": {"containers": [{"name": "router","readinessProbe": {"httpGet": {"path": "/healthz"}}}]}}}'
      Copy to Clipboard Toggle word wrap
    3. 在浏览器中使用以下 URL 启动 stats 窗口,其中 STATS_PORT 值默认为 1936:

      http://admin:<Password>@<router_IP>:<STATS_PORT>
      Copy to Clipboard Toggle word wrap

      您可以通过在 URL 中添加 ;csv 来获得 CSV 格式的统计信息:

      例如:

      http://admin:<Password>@<router_IP>:1936;csv
      Copy to Clipboard Toggle word wrap

      获取路由器 IP、管理员名称和密码:

      oc describe pod <router_pod>
      Copy to Clipboard Toggle word wrap
  • 禁止指标收集:

    $ oc adm router --service-account=router --stats-port=0
    Copy to Clipboard Toggle word wrap

3.2.23. 大型集群的 ARP 缓存调优

在具有大量路由的 OpenShift Container Platform 集群中(超过 net.ipv4.neigh.default.gc_thresh3 的值 65536),您必须增加运行路由器 pod 的集群中每个节点上的 sysctl 变量默认值,以允许 ARP 缓存中更多条目。

当出现问题时,内核信息类似如下:

[ 1738.811139] net_ratelimit: 1045 callbacks suppressed
[ 1743.823136] net_ratelimit: 293 callbacks suppressed
Copy to Clipboard Toggle word wrap

当出现这个问题时,oc 命令可能会因为以下错误开始失败:

Unable to connect to the server: dial tcp: lookup <hostname> on <ip>:<port>: write udp <ip>:<port>-><ip>:<port>: write: invalid argument
Copy to Clipboard Toggle word wrap

要验证 IPv4 的 ARP 条目的实际数量,请运行以下内容:

# ip -4 neigh show nud all | wc -l
Copy to Clipboard Toggle word wrap

如果数字开始接近 net.ipv4.neigh.default.gc_thresh3 阈值,则增加值。运行以下命令来获取当前值:

# sysctl net.ipv4.neigh.default.gc_thresh1
net.ipv4.neigh.default.gc_thresh1 = 128
# sysctl net.ipv4.neigh.default.gc_thresh2
net.ipv4.neigh.default.gc_thresh2 = 512
# sysctl net.ipv4.neigh.default.gc_thresh3
net.ipv4.neigh.default.gc_thresh3 = 1024
Copy to Clipboard Toggle word wrap

以下 sysctl 将变量设置为 OpenShift Container Platform 当前默认值。

# sysctl net.ipv4.neigh.default.gc_thresh1=8192
# sysctl net.ipv4.neigh.default.gc_thresh2=32768
# sysctl net.ipv4.neigh.default.gc_thresh3=65536
Copy to Clipboard Toggle word wrap

要使这些设置永久生效,请查看本文档

3.2.24. 保护 DDoS Attacks

向默认 HAProxy 路由器镜像添加 超时 http-request,以防止部署遭受分布式拒绝服务(例如,slowloris)攻击:

# and the haproxy stats socket is available at /var/run/haproxy.stats
global
  stats socket ./haproxy.stats level admin

defaults
  option http-server-close
  mode http
  timeout http-request 5s
  timeout connect 5s 
1

  timeout server 10s
  timeout client 30s
Copy to Clipboard Toggle word wrap
1
超时 http-request 设置为 5 秒。HAProxy 为客户端 5 秒提供 * 以发送其整个 HTTP 请求。否则,HAProxy 会关闭连接并显示 *an 错误。

另外,当设置环境变量 ROUTER_SLOWLORIS_TIMEOUT 时,它会限制客户端发送整个 HTTP 请求所需的时间。否则,HAProxy 将关闭连接。

通过设置 环境变量,可以将信息捕获为路由器部署配置的一部分,不需要手动修改模板,而手动添加 HAProxy 设置要求您重新构建路由器 Pod 和维护路由器模板文件。

使用注解在 HAProxy 模板路由器中实施基本的 DDoS 保护,包括限制以下功能:

  • 并发 TCP 连接数
  • 客户端可以请求 TCP 连接的速率
  • 可以发出 HTTP 请求的速率

这些是在每个路由上启用的,因为应用可能有完全不同的流量模式。

Expand
表 3.1. HAProxy 模板路由器设置
设置描述

haproxy.router.openshift.io/rate-limit-connections

启用设置(例如,设置为 true )。

haproxy.router.openshift.io/rate-limit-connections.concurrent-tcp

此路由上相同 IP 地址可执行的并发 TCP 连接数。

haproxy.router.openshift.io/rate-limit-connections.rate-tcp

客户端 IP 可以打开的 TCP 连接数。

haproxy.router.openshift.io/rate-limit-connections.rate-http

客户端 IP 在 3 秒期间内可以进行的 HTTP 请求数。

3.2.25. 启用 HAProxy 线程

使用 --threads 标志启用线程处理。此标志指定 HAProxy 路由器将使用的线程数量。

3.3. 部署自定义 HAProxy 路由器

3.3.1. 概述

默认 HAProxy 路由器旨在满足大多数用户的需求。但是,它不会公开 HAProxy 的所有功能。因此,用户可能需要根据自己的需求修改路由器。

您可能需要在应用后端内实施新功能,或修改当前的操作。router 插件提供了进行此自定义所需的所有功能。

路由器容器集使用模板文件来创建所需的 HAProxy 配置文件。模板文件是 golang 模板。在处理模板时,路由器可以访问 OpenShift Container Platform 信息,包括路由器的部署配置、接受路由集和一些帮助程序功能。

当路由器 pod 启动时,并且每次重新加载时,它会创建一个 HAProxy 配置文件,然后启动 HAProxy。HAProxy 配置手册 描述了 HAProxy 的所有功能以及如何构建有效的配置文件。

configMap 可用于添加新模板到路由器 pod。通过这种方法,修改路由器部署配置,将 configMap 挂载为路由器 Pod 中的卷。TEMPLATE_FILE 环境变量设置为路由器 Pod 中模板文件的完整路径名称。

重要

无法保证在升级 OpenShift Container Platform 后路由器模板自定义仍然可以正常工作。

此外,路由器模板自定义必须应用到运行的路由器的模板版本。

或者,您也可以构建自定义路由器镜像,并在部署部分或所有路由器时使用它。不需要所有路由器来运行同一镜像。为此,请修改 haproxy-template.config 文件,再重新构建 路由器 镜像。新镜像推送到集群的 Docker 存储库,路由器的部署配置 image: 字段则使用新名称更新。更新集群时,需要重新构建并推送镜像。

在这两种情况下,路由器容器集都以模板文件开头。

3.3.2. 获取路由器配置模板

HAProxy 模板文件非常大且复杂。对于某些更改,修改现有模板可能比编写完整的替换版本更简单。您可以通过在 master 上运行并引用路由器 pod,从正在运行的路由器获取 haproxy-config.template 文件:

# oc get po
NAME                       READY     STATUS    RESTARTS   AGE
router-2-40fc3             1/1       Running   0          11d
# oc exec router-2-40fc3 cat haproxy-config.template > haproxy-config.template
# oc exec router-2-40fc3 cat haproxy.config > haproxy.config
Copy to Clipboard Toggle word wrap

另外,您可以登录到运行路由器的节点:

# docker run --rm --interactive=true --tty --entrypoint=cat \
    registry.redhat.io/openshift3/ose-haproxy-router:v{product-version} haproxy-config.template
Copy to Clipboard Toggle word wrap

镜像名称来自容器镜像

将此内容保存到文件中,以用作自定义模板的基础。保存的 haproxy.config 显示实际运行的内容。

3.3.3. 修改路由器配置模板

3.3.3.1. 背景信息

模板基于 golang 模板。它可以引用路由器部署配置中的任何环境变量、下面描述的任何配置信息,以及路由器提供的帮助程序功能。

模板文件的结构镜像生成的 HAProxy 配置文件。在处理模板时,所有未被 {{" something "}} 包括的内容会直接复制到配置文件。被 {{" something "}} 包括的内容会被评估。生成的文本(如果有)复制到配置文件。

3.3.3.2. Go 模板操作

define 操作命名将包含已处理模板的文件。

{{define "/var/lib/haproxy/conf/haproxy.config"}}pipeline{{end}}
Copy to Clipboard Toggle word wrap
Expand
表 3.2. 模板路由器功能
功能含义

processEndpointsForAlias(alias ServiceAliasConfig, svc ServiceUnit, action string) []Endpoint

返回有效端点列表。当操作为"shuffle"时,端点的顺序是随机的。

env(variable, default …​string) string

尝试从容器集获取 named 环境变量。如果未定义或为空,它将返回可选的第二个参数。否则,它将返回空字符串。

matchPattern(pattern, s string) bool

第一个参数是包含正则表达式的字符串,第二个参数是要测试的变量。返回一个布尔值,指示作为第一个参数提供的正则表达式是否与作为第二个参数提供的字符串匹配。

isInteger(s string) bool

确定给定变量是否为整数。

firstMatch(s string, allowedValues …​string) bool

将给定字符串与允许字符串的列表进行比较。通过列表向右返回第一个匹配扫描.

matchValues(s string, allowedValues …​string) bool

将给定字符串与允许字符串的列表进行比较。如果字符串为允许的值,则返回 "true",否则返回 false。

generateRouteRegexp(hostname, path string, wildcard bool) string

生成与路由主机(和路径)匹配的正则表达式。第一个参数是主机名,第二个参数是路径,第三个参数是通配符布尔值。

genCertificateHostName(hostname string, wildcard bool) string

生成用于服务/匹配证书的主机名。第一个参数是主机名,第二个参数是通配符布尔值。

isTrue(s string) bool

确定给定变量是否包含"true"。

这些功能由 HAProxy 模板路由器插件提供。

3.3.3.3. 路由器提供的信息

本节回顾路由器在模板中提供的 OpenShift Container Platform 信息。路由器配置参数是 HAProxy 路由器插件提供的一组数据。这些字段可由 (dot).Fieldname 访问。

路由器配置参数下方的表格根据各种字段的定义展开。特别是 .State 拥有一组可接受的路由。

Expand
表 3.3. 路由器配置参数
字段类型描述

WorkingDir

字符串

文件要写入的目录,默认为 /var/lib/containers/router

State

map[string](ServiceAliasConfig)

路由。

ServiceUnits

map[string]ServiceUnit

服务查找。

DefaultCertificate

字符串

以 pem 格式到默认证书的完整路径名称。

PeerEndpoints

[]Endpoint

对等。

StatsUser

字符串

公开统计数据的用户名(如果模板支持)。

StatsPassword

字符串

公开统计数据的密码(如果模板支持)。

StatsPort

int

公开统计信息的端口(如果模板支持)。

BindPorts

bool

路由器是否应绑定默认端口。

Expand
表 3.4. 路由器 ServiceAliasConfig(A Route)
字段类型描述

Name

字符串

路由特定于用户的名称。

Namespace

字符串

路由的命名空间。

Host

字符串

主机名。例如: www.example.com

Path

字符串

可选路径。例如: www.example.com/myservice,其中 myservice 是路径。

TLSTermination

routeapi.TLSTerminationType

此后端的终止策略;驱动映射文件和路由器配置。

Certificates

map[string]Certificate

用于保护此后端的证书。按证书 ID 的键。

Status

ServiceAliasConfigStatus

指明需要永久保留的配置状态。

PreferPort

字符串

指明用户要公开的端口。如果为空,将为服务选择一个端口。

InsecureEdgeTerminationPolicy

routeapi.InsecureEdgeTerminationPolicyType

指明到边缘终端路由的不安全连接所需的行为: none (或 disable), allow, 或 redirect

RoutingKeyName

字符串

用于模糊 cookie ID 的路由 + 命名空间名称的哈希值。

IsWildcard

bool

表示此服务单元需要通配符支持。

Annotations

map[string]string

附加到此路由的注解。

ServiceUnitNames

map[string]int32

支持此路由的服务集合,按服务名称键,并根据映射中其他条目的权重加上相应的权重。

ActiveServiceUnits

int

权重为非零的 ServiceUnitName 的数量。

ServiceAliasConfig 是服务的路由。由主机 + 路径唯一标识指定。默认模板使用 {{range $cfgIdx、$cfg := .State }} 迭代路由。在这样的 {{range}} 块中,模板可以使用 $cfg.Field 引用当前 ServiceAliasConfig 的任何字段。

Expand
表 3.5. Router ServiceUnit
字段类型描述

Name

字符串

对应于服务名称 + namespace 的名称。由 ServiceUnit 唯一标识。

EndpointTable

[]Endpoint

支持该服务的端点。这转换为路由器的最终后端实施。

ServiceUnit 是一种服务封装、支持该服务的端点,以及指向服务的路由。这是驱动创建路由器配置文件的数据

Expand
表 3.6. 路由器端点
字段类型

ID

字符串

IP

字符串

Port

字符串

TargetName

字符串

PortName

字符串

IdHash

字符串

NoHealthCheck

bool

Endpoint 是 Kubernetes 端点的内部表示。

Expand
表 3.7. Router Certificate, ServiceAliasConfigStatus
字段类型描述

Certificate

字符串

代表一个公钥/私钥对。它通过 ID 来标识,该 ID 将成为文件名。CA 证书将不会设置 PrivateKey

ServiceAliasConfigStatus

字符串

表示此配置所需的文件已持久保存到磁盘。有效值:"saved", ""。

Expand
表 3.8. 路由器证书类型
字段类型描述

ID

字符串

 

内容

字符串

证书。

PrivateKey

字符串

私钥。

Expand
表 3.9. 路由器 TLSTerminationType
字段类型描述

TLSTerminationType

字符串

指定安全通信将停止的位置。

InsecureEdgeTerminationPolicyType

字符串

表示路由不安全连接所需的行为。虽然每个路由器可能会对要公开的端口做出自己的决定,但通常这是端口 80。

TLSTerminationTypeInsecureEdgeTerminationPolicyType 指定安全通信将停止的位置。

Expand
表 3.10. 路由器 TLSTerminationType 值
常数含义

TLSTerminationEdge

edge

终止边缘路由器上的加密。

TLSTerminationPassthrough

passthrough

目的地终止加密,目的地负责解密流量。

TLSTerminationReencrypt

reencrypt

在边缘路由器中终止加密,并使用目的地提供的新证书重新加密。

Expand
表 3.11. Router InsecureEdgeTerminationPolicyType Values
类型含义

Allow

流量发送到不安全端口(默认)上的服务器。

Disable

不安全的端口不允许流量。

Redirect

客户端重定向到安全端口。

None ("") 与 Disable 相同。

3.3.3.4. 注解

每个路由都可以附加注解。每个注释仅是一个名称和一个值。

apiVersion: v1
kind: Route
metadata:
  annotations:
    haproxy.router.openshift.io/timeout: 5500ms
[...]
Copy to Clipboard Toggle word wrap

名称可以是与现有 Annotations 没有冲突的任何内容。值是任意字符串。字符串可以具有多个令牌,用空格分开。例如,aa bb cc.该模板使用 {{index}} 来提取注释的值。例如:

{{$balanceAlgo := index $cfg.Annotations "haproxy.router.openshift.io/balance"}}
Copy to Clipboard Toggle word wrap

这是如何将其用于相互客户端授权的示例。

{{ with $cnList := index $cfg.Annotations "whiteListCertCommonName" }}
  {{   if ne $cnList "" }}
    acl test ssl_c_s_dn(CN) -m str {{ $cnList }}
    http-request deny if !test
  {{   end }}
{{ end }}
Copy to Clipboard Toggle word wrap

然后,您可以使用此命令处理列入白名单的 CN。

$ oc annotate route <route-name> --overwrite whiteListCertCommonName="CN1 CN2 CN3"
Copy to Clipboard Toggle word wrap

如需更多信息,请参阅特定于路由的注解

3.3.3.5. 环境变量

该模板可以使用路由器 pod 中存在的任何环境变量。环境变量可以在部署配置中设置。可以添加新的环境变量。

它们由 env 函数引用:

{{env "ROUTER_MAX_CONNECTIONS" "20000"}}
Copy to Clipboard Toggle word wrap

第一个字符串是 变量,第二个字符串是变量缺失或 nil 时的默认值。当 ROUTER_MAX_CONNECTIONS 未设置或为 nil 时,则使用 20000。环境变量是一个映射,其中键是环境变量名称,内容是 变量的值。

如需更多信息,请参阅特定于路由的环境变量

3.3.3.6. 用法示例

以下是基于 HAProxy 模板文件的简单模板:

从注释开始:

{{/*
  Here is a small example of how to work with templates
  taken from the HAProxy template file.
*/}}
Copy to Clipboard Toggle word wrap

模板可以创建任意数量的输出文件。使用定义结构来创建输出文件。文件名指定为要定义的参数,定义块内直到匹配端的所有内容都会被写入为该文件的内容。

{{ define "/var/lib/haproxy/conf/haproxy.config" }}
global
{{ end }}
Copy to Clipboard Toggle word wrap

上方会将 global 复制到 /var/lib/haproxy/conf/haproxy.config 文件,然后关闭该文件。

根据环境变量设置日志记录。

{{ with (env "ROUTER_SYSLOG_ADDRESS" "") }}
  log {{.}} {{env "ROUTER_LOG_FACILITY" "local1"}} {{env "ROUTER_LOG_LEVEL" "warning"}}
{{ end }}
Copy to Clipboard Toggle word wrap

env 函数提取环境变量的值。如果未定义环境变量或 nil,则返回第二个参数。

通过,使用 将 块中的 "."(dot)值设置为作为使用 的参数提供的任何值。with 操作测试点为 nil。如果没有 nil,则会处理到最后。在上面,假设 ROUTER_SYSLOG_ADDRESS 包含 /var/log/msgROUTER_LOG_FACILITY 未定义,并且 ROUTER_LOG_LEVEL 包含 info。以下命令将复制到输出文件中:

  log /var/log/msg local1 info
Copy to Clipboard Toggle word wrap

每个接受的路由最终都会在配置文件中生成行。使用 范围 来进入接受的路由:

{{ range $cfgIdx, $cfg := .State }}
  backend be_http_{{$cfgIdx}}
{{end}}
Copy to Clipboard Toggle word wrap

.StateServiceAliasConfig 的映射,其中键是路由名称. 范围 步骤通过映射,每个传递都使用 设置 $cfgIdx,并将 $cfg 设置为指向描述路由的 ServiceAliasConfig。如果有两个路由名为 myrouteheroute,则上述命令会将以下内容复制到输出文件中:

  backend be_http_myroute
  backend be_http_hisroute
Copy to Clipboard Toggle word wrap

Route Annotations、$cfg.Annotations 也是注解名称作为键的映射,内容字符串作为值。路由可以根据需要拥有更多注解,其使用由模板作者定义。用户将注解代码到路由中,模板作者则自定义 HAProxy 模板来处理注解。

常见用法是索引注解以获取值。

{{$balanceAlgo := index $cfg.Annotations "haproxy.router.openshift.io/balance"}}
Copy to Clipboard Toggle word wrap

索引提取给定注解的值(若有)。因此,$balanceAlgo 将包含与注解或 nil 关联的字符串。如上所示,您可以测试非空字符串,并使用 with 结构对其执行操作。

{{ with $balanceAlgo }}
  balance $balanceAlgo
{{ end }}
Copy to Clipboard Toggle word wrap

此处,如果 $balanceAlgo 不是 nil平衡 $balanceAlgo 将复制到输出文件中。

在第二个示例中,您想要根据注释中设置的超时值设置服务器超时。

$value := index $cfg.Annotations "haproxy.router.openshift.io/timeout"
Copy to Clipboard Toggle word wrap

现在 $value 会被评估,以确保它包含正确构建的字符串。matchPattern 函数接受正则表达式,如果参数满足表达式要求,则返回 true

matchPattern "[1-9][0-9]*(us\|ms\|s\|m\|h\|d)?" $value
Copy to Clipboard Toggle word wrap

这会接受 5000ms,但不接受 7y。结果可用于测试。

{{if (matchPattern "[1-9][0-9]*(us\|ms\|s\|m\|h\|d)?" $value) }}
  timeout server  {{$value}}
{{ end }}
Copy to Clipboard Toggle word wrap

它还可用于匹配令牌:

matchPattern "roundrobin|leastconn|source" $balanceAlgo
Copy to Clipboard Toggle word wrap

另外,也可以使用 matchValues 来匹配令牌:

matchValues $balanceAlgo "roundrobin" "leastconn" "source"
Copy to Clipboard Toggle word wrap

3.3.4. 使用 ConfigMap 替换路由器配置模板

您可以使用 ConfigMap 来自定义路由器实例,而无需重新构建路由器镜像。可以修改 haproxy-config.templatereload-haproxy 和其他脚本,以及创建和修改路由器环境变量。

  1. 复制您要修改的 haproxy-config.template如上所述根据需要进行修改。
  2. 创建 ConfigMap:

    $ oc create configmap customrouter --from-file=haproxy-config.template
    Copy to Clipboard Toggle word wrap

    customrouter ConfigMap 现在包含修改后的 haproxy-config.template 文件的副本。

  3. 修改路由器部署配置,将 ConfigMap 挂载为文件,并将 TEMPLATE_FILE 环境变量指向该文件。这可以通过 oc set envoc set volume 命令完成,或者通过编辑路由器部署配置来完成。

    使用 oc 命令
    $ oc set volume dc/router --add --overwrite \
        --name=config-volume \
        --mount-path=/var/lib/haproxy/conf/custom \
        --source='{"configMap": { "name": "customrouter"}}'
    $ oc set env dc/router \
        TEMPLATE_FILE=/var/lib/haproxy/conf/custom/haproxy-config.template
    Copy to Clipboard Toggle word wrap
    编辑路由器部署配置

    使用 oc edit dc router,使用文本编辑器编辑路由器部署配置。

    ...
            - name: STATS_USERNAME
              value: admin
            - name: TEMPLATE_FILE  
    1
    
              value: /var/lib/haproxy/conf/custom/haproxy-config.template
            image: openshift/origin-haproxy-routerp
    ...
            terminationMessagePath: /dev/termination-log
            volumeMounts: 
    2
    
            - mountPath: /var/lib/haproxy/conf/custom
              name: config-volume
          dnsPolicy: ClusterFirst
    ...
          terminationGracePeriodSeconds: 30
          volumes: 
    3
    
          - configMap:
              name: customrouter
            name: config-volume
    ...
    Copy to Clipboard Toggle word wrap
    1
    spec.container.env 字段中,添加 TEMPLATE_FILE 环境变量以指向挂载的 haproxy-config.template 文件。
    2
    添加 spec.container.volumeMounts 字段以创建挂载点。
    3
    添加新的 spec.volumes 字段来引用 ConfigMap。

    保存更改并退出编辑器。这将重新启动路由器。

3.3.5. 使用粘滞表

以下示例自定义可在高可用性路由设置中使用,以使用在对等点间同步的粘滞表。

添加 Peer 部分

要在对等点间同步粘滞位,您必须在 HAProxy 配置中定义对等部分。本节决定了 HAProxy 如何识别并连接到同级服务器。插件在 .PeerEndpoints 变量下向模板提供数据,以便您可以轻松地识别路由器服务的成员。您可以通过添加以下内容,将 peer 部分添加到路由器镜像中的 haproxy-config.template 文件中:

{{ if (len .PeerEndpoints) gt 0 }}
peers openshift_peers
  {{ range $endpointID, $endpoint := .PeerEndpoints }}
    peer {{$endpoint.TargetName}} {{$endpoint.IP}}:1937
  {{ end }}
{{ end }}
Copy to Clipboard Toggle word wrap

更改重新加载脚本

使用粘滞位时,您可以选择告知 HAProxy 在 peer 部分中应考虑本地主机的名称。在创建端点时,插件会尝试将 TargetName 设置为端点的 TargetRef.Name 的值。如果没有设置 TargetRef,它会将 TargetName 设置为 IP 地址。TargetRef.Name 与 Kubernetes 主机名对应,因此您可以将 -L 选项添加到 reload-haproxy 脚本中,以标识 peer 部分中的本地主机。

peer_name=$HOSTNAME 
1


if [ -n "$old_pid" ]; then
  /usr/sbin/haproxy -f $config_file -p $pid_file -L $peer_name -sf $old_pid
else
  /usr/sbin/haproxy -f $config_file -p $pid_file -L $peer_name
fi
Copy to Clipboard Toggle word wrap
1
必须与 peer 部分中使用的端点目标名称匹配。

修改后端

最后,若要在后端使用 stick-tables,您可以修改 HAProxy 配置以使用 stick-tables 和 peer 设置。以下是将 TCP 连接的现有后端更改为使用 stick-table 的示例:

            {{ if eq $cfg.TLSTermination "passthrough" }}
backend be_tcp_{{$cfgIdx}}
  balance leastconn
  timeout check 5000ms
  stick-table type ip size 1m expire 5m{{ if (len $.PeerEndpoints) gt 0 }} peers openshift_peers {{ end }}
  stick on src
                {{ range $endpointID, $endpoint := $serviceUnit.EndpointTable }}
  server {{$endpointID}} {{$endpoint.IP}}:{{$endpoint.Port}} check inter 5000ms
                {{ end }}
            {{ end }}
Copy to Clipboard Toggle word wrap

在修改后,您可以重建路由器

3.3.6. 重建路由器

若要重建路由器,您需要复制正在运行的路由器上存在的多个文件。创建一个工作目录并从路由器复制文件:

# mkdir - myrouter/conf
# cd myrouter
# oc get po
NAME                       READY     STATUS    RESTARTS   AGE
router-2-40fc3             1/1       Running   0          11d
# oc exec router-2-40fc3 cat haproxy-config.template > conf/haproxy-config.template
# oc exec router-2-40fc3 cat error-page-503.http > conf/error-page-503.http
# oc exec router-2-40fc3 cat default_pub_keys.pem > conf/default_pub_keys.pem
# oc exec router-2-40fc3 cat ../Dockerfile > Dockerfile
# oc exec router-2-40fc3 cat ../reload-haproxy > reload-haproxy
Copy to Clipboard Toggle word wrap

您可以编辑或替换其中任何一个文件。但是,conf/haproxy-config.templatereload-haproxy 最有可能被修改。

更新文件后:

# docker build -t openshift/origin-haproxy-router-myversion .
# docker tag openshift/origin-haproxy-router-myversion 172.30.243.98:5000/openshift/haproxy-router-myversion 
1

# docker push 172.30.243.98:5000/openshift/origin-haproxy-router-pc:latest 
2
Copy to Clipboard Toggle word wrap
1
使用存储库标记 version。在本例中,存储库是 172.30.243.98:5000
2
将标记的版本推送到存储库。可能需要先 docker login 存储库。

要使用新路由器,请通过更改 image: 字符串或将 --images=<repo>/<image>:<tag> 标志添加到 oc adm router 命令来编辑路由器部署配置。

调试更改时,设置 imagePullPolicy:Always 在部署配置中,强制在每次 pod 创建时拉取镜像。调试完成后,您可以将其改回到 imagePullPolicy:IfNotPresent 以避免每次 pod 启动时都拉取。

3.4. 将 HAProxy 路由器配置为使用 PROXY 协议

3.4.1. 概述

默认情况下,HAProxy 路由器要求进入到不安全、边缘和重新加密路由的连接才能使用 HTTP。但是,您可以使用 PROXY 协议 将路由器配置为预期传入请求。本节论述了如何将 HAProxy 路由器和外部负载均衡器配置为使用 PROXY 协议。

3.4.2. 为什么使用 PROXY 协议?

当代理服务器或负载平衡器等中间服务转发 HTTP 请求时,它会将连接的源地址附加到请求的"Forwarded"标头,从而将此信息提供给后续请求,以及最终将请求转发到的后端服务。但是,如果连接被加密,则无法修改"Forwarded"标头。在这种情况下,HTTP 标头无法在转发请求时准确传达原始源地址。

为了解决这个问题,一些负载均衡器使用 PROXY 协议封装 HTTP 请求,作为只转发 HTTP 的替代选择。封装使负载平衡器能够在不修改转发请求本身的情况下向请求添加信息。特别是,这意味着负载均衡器即使在转发加密的连接时也能通信源地址。

HAProxy 路由器可以配置为接受 PROXY 协议并解封 HTTP 请求。由于路由器终止对边缘和再加密路由的加密,因此路由器随后可以更新请求中的 "Forwarded" HTTP 标头(及相关的 HTTP 标头),附加使用 PROXY 协议通信的任何源地址。

警告

PROXY 协议和 HTTP 不兼容,不可混合。如果您在路由器前面使用负载均衡器,则必须使用 PROXY 协议或 HTTP。将一个协议配置为使用一个协议,另一个协议使用其他协议会导致路由失败。

3.4.3. 使用 PROXY 协议

默认情况下,HAProxy 路由器不使用 PROXY 协议。可以使用 ROUTER_USE_PROXY_PROTOCOL 环境变量配置路由器,以预期传入连接的 PROXY 协议:

启用 PROXY 协议

$ oc set env dc/router ROUTER_USE_PROXY_PROTOCOL=true
Copy to Clipboard Toggle word wrap

将变量设置为 trueTRUE 以外的任何值,以禁用 PROXY 协议:

禁用 PROXY 协议

$ oc set env dc/router ROUTER_USE_PROXY_PROTOCOL=false
Copy to Clipboard Toggle word wrap

如果您在路由器中启用 PROXY 协议,则必须将路由器前面的负载均衡器配置为使用 PROXY 协议。以下是配置 Amazon Elastic Load Balancer(ELB)服务以使用 PROXY 协议的示例。本例假定 ELB 将端口 80(HTTP)、443(HTTPS)和 5000(镜像注册表)转发到一个或多个 EC2 实例上运行的路由器。

将 Amazon ELB 配置为使用 PROXY 协议

  1. 要简化后续步骤,首先设置一些 shell 变量:

    $ lb='infra-lb' 
    1
    
    $ instances=( 'i-079b4096c654f563c' ) 
    2
    
    $ secgroups=( 'sg-e1760186' ) 
    3
    
    $ subnets=( 'subnet-cf57c596' ) 
    4
    Copy to Clipboard Toggle word wrap
    1
    您的 ELB 的名称。
    2
    运行路由器的实例。
    3
    此 ELB 的安全组或组。
    4
    此 ELB 的子网。
  2. 接下来,使用适当的监听程序、安全组和子网创建 ELB。

    注意

    您必须将所有监听程序配置为使用 TCP 协议,而不是 HTTP 协议。

    $ aws elb create-load-balancer --load-balancer-name "$lb" \
       --listeners \
        'Protocol=TCP,LoadBalancerPort=80,InstanceProtocol=TCP,InstancePort=80' \
        'Protocol=TCP,LoadBalancerPort=443,InstanceProtocol=TCP,InstancePort=443' \
        'Protocol=TCP,LoadBalancerPort=5000,InstanceProtocol=TCP,InstancePort=5000' \
       --security-groups $secgroups \
       --subnets $subnets
    {
        "DNSName": "infra-lb-2006263232.us-east-1.elb.amazonaws.com"
    }
    Copy to Clipboard Toggle word wrap
  3. 使用 ELB 注册路由器实例或实例:

    $ aws elb register-instances-with-load-balancer --load-balancer-name "$lb" \
       --instances $instances
    {
        "Instances": [
            {
                "InstanceId": "i-079b4096c654f563c"
            }
        ]
    }
    Copy to Clipboard Toggle word wrap
  4. 配置 ELB 的健康检查:

    $ aws elb configure-health-check --load-balancer-name "$lb" \
       --health-check 'Target=HTTP:1936/healthz,Interval=30,UnhealthyThreshold=2,HealthyThreshold=2,Timeout=5'
    {
        "HealthCheck": {
            "HealthyThreshold": 2,
            "Interval": 30,
            "Target": "HTTP:1936/healthz",
            "Timeout": 5,
            "UnhealthyThreshold": 2
        }
    }
    Copy to Clipboard Toggle word wrap
  5. 最后,创建一个启用了 ProxyProtocol 属性的负载均衡器策略,并在 ELB 的 TCP 端口 80 和 443 中配置它:

    $ aws elb create-load-balancer-policy --load-balancer-name "$lb" \
       --policy-name "${lb}-ProxyProtocol-policy" \
       --policy-type-name 'ProxyProtocolPolicyType' \
       --policy-attributes 'AttributeName=ProxyProtocol,AttributeValue=true'
    $ for port in 80 443
      do
        aws elb set-load-balancer-policies-for-backend-server \
         --load-balancer-name "$lb" \
         --instance-port "$port" \
         --policy-names "${lb}-ProxyProtocol-policy"
      done
    Copy to Clipboard Toggle word wrap

验证配置

您可以按如下所示检查负载均衡器以验证配置是否正确:

$ aws elb describe-load-balancers --load-balancer-name "$lb" |
    jq '.LoadBalancerDescriptions| [.[]|.ListenerDescriptions]'
[
  [
    {
      "Listener": {
        "InstancePort": 80,
        "LoadBalancerPort": 80,
        "Protocol": "TCP",
        "InstanceProtocol": "TCP"
      },
      "PolicyNames": ["infra-lb-ProxyProtocol-policy"] 
1

    },
    {
      "Listener": {
        "InstancePort": 443,
        "LoadBalancerPort": 443,
        "Protocol": "TCP",
        "InstanceProtocol": "TCP"
      },
      "PolicyNames": ["infra-lb-ProxyProtocol-policy"] 
2

    },
    {
      "Listener": {
        "InstancePort": 5000,
        "LoadBalancerPort": 5000,
        "Protocol": "TCP",
        "InstanceProtocol": "TCP"
      },
      "PolicyNames": [] 
3

    }
  ]
]
Copy to Clipboard Toggle word wrap
1
TCP 端口 80 的监听器应具有使用 PROXY 协议的策略。
2
TCP 端口 443 的监听程序应具有相同的策略。
3
TCP 端口 5000 的监听程序 不应 具有该策略。

或者,如果您已经配置了 ELB,但没有配置为使用 PROXY 协议,则需要更改 TCP 端口 80 的现有监听程序以使用 TCP 协议而不是 HTTP(TCP 端口 443 应已使用 TCP 协议):

$ aws elb delete-load-balancer-listeners --load-balancer-name "$lb" \
   --load-balancer-ports 80
$ aws elb create-load-balancer-listeners --load-balancer-name "$lb" \
   --listeners 'Protocol=TCP,LoadBalancerPort=80,InstanceProtocol=TCP,InstancePort=80'
Copy to Clipboard Toggle word wrap

验证协议更新

验证协议是否已更新,如下所示:

$ aws elb describe-load-balancers --load-balancer-name "$lb" |
   jq '[.LoadBalancerDescriptions[]|.ListenerDescriptions]'
[
  [
    {
      "Listener": {
        "InstancePort": 443,
        "LoadBalancerPort": 443,
        "Protocol": "TCP",
        "InstanceProtocol": "TCP"
      },
      "PolicyNames": []
    },
    {
      "Listener": {
        "InstancePort": 5000,
        "LoadBalancerPort": 5000,
        "Protocol": "TCP",
        "InstanceProtocol": "TCP"
      },
      "PolicyNames": []
    },
    {
      "Listener": {
        "InstancePort": 80,
        "LoadBalancerPort": 80,
        "Protocol": "TCP", 
1

        "InstanceProtocol": "TCP"
      },
      "PolicyNames": []
    }
  ]
]
Copy to Clipboard Toggle word wrap
1
所有监听器(包括 TCP 端口 80 的监听器)都应使用 TCP 协议。

然后,创建一个负载均衡器策略,并将其添加到 ELB 中,如上一步第 5 步所述。

第 4 章 部署 Red Hat CloudForms

4.1.1. 简介

OpenShift Container Platform 安装程序包括 Ansible 角色 openshift-management, 以及用于在 OpenShift Container Platform 上部署 Red Hat CloudForms 4.6(CloudForms Management Engine 5.9 或 CFME)的 playbook。

警告

当前实施与 Red Hat CloudForms 4.5 的技术预览部署过程不兼容,如 OpenShift Container Platform 3.6 文档 中所述。

在 OpenShift Container Platform 上部署 Red Hat CloudForms 时,需要做出两个主要决策:

  1. 您是否想要外部或容器化(也称为 podified)PostgreSQL 数据库?
  2. 哪个存储类将支持您的持久性卷(PV)?

对于第一个决定,您可以使用两种方式之一部署 Red Hat CloudForms,具体取决于 Red Hat CloudForms 使用的 PostgreSQL 数据库的位置:

Expand
Deployment Variant描述

完全容器化

所有应用程序服务和 PostgreSQL 数据库都作为 pod 在 OpenShift Container Platform 上运行。

外部数据库

应用程序使用外部托管的 PostgreSQL 数据库服务器,所有其他服务则作为 pod 在 OpenShift Container Platform 上运行。

对于第二个决定,openshift-management 角色提供了覆盖许多默认部署参数的自定义选项。这包括以下存储类选项来支持 PV:

Expand
Storage class描述

NFS(默认)

本地,在集群上

NFS 外部

NFS(如存储设备)

云供应商

使用云供应商(Google Cloud Engine、Amazon Web Services 或 Microsoft Azure)的自动存储置备。

预配置(高级)

假设您提前创建了所有内容

本指南的主题包括:在 OpenShift Container Platform 上运行 Red Hat CloudForms 的要求、可用配置变量的说明,以及在初始 OpenShift Container Platform 安装期间或置备集群之后运行安装程序的说明。

 
下表中列出了默认要求。可以通过 自定义模板参数 来覆盖它们。

重要

如果无法满足这些要求,应用性能将会受到影响,甚至可能无法部署。

Expand
表 4.1. 默认要求
要求描述自定义参数

应用程序内存

≥ 4.0 Gi

应用程序所需的最小内存

APPLICATION_MEM_REQ

应用程序存储

≥ 5.0 Gi

应用程序所需的最小 PV 大小

APPLICATION_VOLUME_CAPACITY

PostgreSQL 内存

≥ 6.0 Gi

数据库所需的最小内存

POSTGRESQL_MEM_REQ

PostgreSQL 存储

≥ 15.0 Gi

数据库所需的最小 PV 大小

DATABASE_VOLUME_CAPACITY

集群主机

≥ 3

集群中的主机数量

N/A

满足这些要求:

  • 您必须具有几个集群节点。
  • 您的集群节点必须具有大量可用内存。
  • 您必须有多个 GiB 的可用存储,无论是本地还是云供应商。
  • 可以通过为模板参数提供覆盖值来更改 PV 大小。

4.3. 配置角色变量

4.3.1. 概述

以下小节描述了 Ansible 清单文件中可能使用的角色变量,用于控制 运行安装程序 时红帽 CloudForms 安装的行为。

4.3.2. 常规变量

Expand
变量必填默认描述

openshift_management_install_management

false

布尔值,设置为 true 以安装应用程序。

openshift_management_app_template

cfme-template

要安装的红帽 CloudForms 的部署变体。为容器化数据库设置 cfme-template,或为外部数据库设置 cfme-template-ext-db

openshift_management_project

openshift-management

红帽 CloudForms 安装的命名空间(项目)

openshift_management_project_description

CloudForms Management Engine

命名空间(项目)描述。

openshift_management_username

admin

默认管理用户名。更改此值不会更改用户名;只有在您更改了名称并运行集成脚本(如 添加容器提供程序的脚本)时,才会更改此值。

openshift_management_password

smartvm

默认管理密码。更改此值不会更改密码;只有在您更改了密码并且正在运行集成脚本(如用于 添加容器提供程序的脚本)时,才会更改此值。

4.3.3. 自定义模板参数

您可以使用 openshift_management_template_parameters Ansible 角色变量来指定要在应用程序或 PV 模板中覆盖的任何模板参数。

例如,如果要降低 PostgreSQL pod 的内存要求,您可以设置以下内容:

openshift_management_template_parameters={'POSTGRESQL_MEM_REQ': '1Gi'}
Copy to Clipboard Toggle word wrap

处理红帽 CloudForms 模板后,1Gi 将用于 POSTGRESQL_MEM_REQ 模板参数的值。

并非所有模板参数都存在于 两种 模板变体中(容器化或外部数据库)。例如,虽然 podified 数据库模板具有 POSTGRESQL_MEM_REQ 参数,但外部 db 模板中没有这样的参数,因为不需要此信息,因为没有要求 pod 的数据库。

因此,如果您要覆盖模板参数,请非常小心。包含模板中未定义的参数将导致错误。如果在 Ensure the Management App is created 任务期间收到错误,请在再次运行安装程序前先运行 卸载脚本

4.3.4. 数据库变量

4.3.4.1. 容器化(pod)数据库

cfme-template.yaml 文件中任何 POSTGRES _* 或DATABASE_* 模板参数都可以通过清单文件中的 openshift_management_template_parameters 哈希进行自定义。

4.3.4.2. 外部数据库

cfme-template-ext-db.yaml 文件中的任何 POSTGRES _*DATABASE_* 模板参数都可以通过清单文件中的 openshift_management_template_parameters 哈希进行自定义。

外部 PostgreSQL 数据库要求您提供数据库连接参数。您必须在清单中的 openshift_management_template_parameters 参数中设置所需的连接密钥。以下键是必需的:

  • DATABASE_USER
  • DATABASE_PASSWORD
  • DATABASE_IP
  • DATABASE_PORT (大多数 PostgreSQL 服务器在端口 5432上运行)
  • DATABASE_NAME
注意

确保您的外部数据库正在运行 PostgreSQL 9.5,或者您可能无法成功部署 CloudForms 应用。

您的清单将包含类似如下的行:

[OSEv3:vars]
openshift_management_app_template=cfme-template-ext-db 
1

openshift_management_template_parameters={'DATABASE_USER': 'root', 'DATABASE_PASSWORD': 'mypassword', 'DATABASE_IP': '10.10.10.10', 'DATABASE_PORT': '5432', 'DATABASE_NAME': 'cfme'}
Copy to Clipboard Toggle word wrap
1
openshift_management_app_template 参数设置为 cfme-template-ext-db

4.3.5. 存储类变量

Expand
变量必填默认描述

openshift_management_storage_class

nfs

要使用的存储类型。选项包括 nfsnfs_externalpreconfiguredcloudprovider

openshift_management_storage_nfs_external_hostname

false

如果您使用的是外部 NFS 服务器,如 NetApp 设备,则必须在此处设置主机名。如果没有使用外部 NFS,则该值保留为 false。另外,外部 NFS 要求您创建将支持应用程序 PV 的 NFS 导出以及数据库 PV(可选)。

openshift_management_storage_nfs_base_dir

/exports/

如果您使用外部 NFS,则可以在此处将基本路径设置为导出位置。对于本地 NFS,如果您要更改用于本地 NFS 导出的默认路径,您还可以更改此值。

openshift_management_storage_nfs_local_hostname

false

如果您的清单中没有 [nfs] 组,或者只想手动定义集群中的本地 NFS 主机,请将这个参数设置为首选 NFS 服务器的主机名。服务器必须是 OpenShift Container Platform 集群的一部分。

4.3.5.1. NFS(默认)

NFS 存储类最适合概念验证和测试部署。它也是部署的默认存储类。选择时不需要额外的配置。

此存储类将集群主机上的 NFS(默认为清单文件中的第一个 master)配置为支持所需的 PV。应用需要一个 PV,而数据库(可能外部托管)可能需要一秒钟。Red Hat CloudForms 应用所需的最小 PV 大小为 5GiB,PostgreSQL 数据库为 15GiB(如果专用于 NFS,则为卷或分区上的最小可用空间为 20GiB)。

自定义通过以下角色变量提供:

  • openshift_management_storage_nfs_base_dir
  • openshift_management_storage_nfs_local_hostname
4.3.5.2. NFS 外部

外部 NFS 依靠预先配置的 NFS 服务器为所需的 PV 提供导出。对于外部 NFS,您必须有一个 cfme-app 和可选的一个 cfme-db (容器化数据库)导出。

配置通过以下角色变量提供:

  • openshift_management_storage_nfs_external_hostname
  • openshift_management_storage_nfs_base_dir

openshift_management_storage_nfs_external_hostname 参数必须设置为外部 NFS 服务器的主机名或 IP。

如果 /exports 不是您的导出的父目录,则必须通过 openshift_management_storage_nfs_base_dir 参数设置基础目录。

例如,如果您的服务器导出为 /exports/hosted/prod/cfme-app,则必须设置 openshift_management_storage_nfs_base_dir=/exports/hosted/prod

4.3.5.3. 云供应商

如果您要将 OpenShift Container Platform 云供应商集成用于存储类,Red Hat CloudForms 也可以使用云供应商存储来支持其所需的 PV。要使此功能正常工作,您必须已配置了 openshift_cloudprovider_kind 变量(用于 AWS 或 GCE),以及特定于您所选云供应商的所有关联参数。

当使用此存储类创建应用程序时,需要使用配置的云供应商存储集成自动置备所需的 PV。

没有额外的变量可用于配置此存储类的行为。

4.3.5.4. 预配置(高级)

预配置 存储类意味着您准确知道您的操作,并且所有存储要求都已提前处理。通常,这意味着您已创建了正确大小的 PV。安装程序不会进行任何操作来修改任何存储设置。

没有额外的变量可用于配置此存储类的行为。

4.4. 运行安装程序

您可以选择在初始 OpenShift Container Platform 安装过程中或置备集群后部署 Red Hat CloudForms:

  1. 确定在清单文件 [OSEv3:vars] 部分下的清单文件中将 openshift_management_install_management 设置为 true

    [OSEv3:vars]
    openshift_management_install_management=true
    Copy to Clipboard Toggle word wrap
  2. 在清单文件中设置任何其他红帽 CloudForms 角色变量,如 配置角色变量 中所述。清单文件示例中提供了有助于执行此操作 的资源。
  3. 根据是否已置备 OpenShift Container Platform,选择要运行的 playbook:

    1. 如果要在安装 OpenShift Container Platform 集群的同时安装 Red Hat CloudForms,请调用标准 config.yml playbook,如 运行安装 Playbook 所述以开始 OpenShift Container Platform 集群和 Red Hat CloudForms 安装。
    2. 如果要在已置备的 OpenShift Container Platform 集群上安装 Red Hat CloudForms,请切换到 playbook 目录,并直接调用 Red Hat CloudForms playbook 开始安装:

      $ cd /usr/share/ansible/openshift-ansible
      $ ansible-playbook -v [-i /path/to/inventory] \
          playbooks/openshift-management/config.yml
      Copy to Clipboard Toggle word wrap

4.4.2. 清单文件示例

以下小节演示了在 OpenShift Container Platform 中显示 Red Hat CloudForms 的各种配置的清单文件示例片段,可帮助您开始。

注意

如需完整的变量描述,请参阅配置角色变量

4.4.2.1. 所有默认值

本例最简单的方法是使用所有默认值和选项。这将实现完全容器化(指定)红帽 CloudForms 安装。所有应用程序组件以及 PostgreSQL 数据库都是在 OpenShift Container Platform 中创建的:

[OSEv3:vars]
openshift_management_app_template=cfme-template
Copy to Clipboard Toggle word wrap
4.4.2.2. 外部 NFS 存储

如前例所示,除了在集群中使用本地 NFS 服务外,它使用的是现有的外部 NFS 服务器(如存储设备)。请注意两个新参数:

[OSEv3:vars]
openshift_management_app_template=cfme-template
openshift_management_storage_class=nfs_external 
1

openshift_management_storage_nfs_external_hostname=nfs.example.com 
2
Copy to Clipboard Toggle word wrap
1
将设置为 nfs_external
2
设置为 NFS 服务器的主机名。

如果外部 NFS 主机在不同的父目录下导出目录,如 /exports/hosted/prod,请添加以下额外变量:

openshift_management_storage_nfs_base_dir=/exports/hosted/prod
Copy to Clipboard Toggle word wrap
4.4.2.3. 覆盖 PV 大小

这个示例覆盖持久性卷(PV)大小。PV 大小必须通过 openshift_management_template_parameters 设置,这样可确保应用程序和数据库能够在创建的 PV 上发出声明,而无需相互干扰:

[OSEv3:vars]
openshift_management_app_template=cfme-template
openshift_management_template_parameters={'APPLICATION_VOLUME_CAPACITY': '10Gi', 'DATABASE_VOLUME_CAPACITY': '25Gi'}
Copy to Clipboard Toggle word wrap
4.4.2.4. 覆盖内存要求

在测试或概念验证安装中,您可能需要降低应用程序和数据库内存要求,以符合您的容量。请注意,减少内存限值可能会导致性能降低或完全失败来初始化应用程序:

[OSEv3:vars]
openshift_management_app_template=cfme-template
openshift_management_template_parameters={'APPLICATION_MEM_REQ': '3000Mi', 'POSTGRESQL_MEM_REQ': '1Gi', 'ANSIBLE_MEM_REQ': '512Mi'}
Copy to Clipboard Toggle word wrap

本例指示安装程序处理应用程序模板,参数 APPLICATION_MEM_REQ 设置为 3000MiPOSTGRESQL_MEM_REQ 设置为 1GiANSIBLE_MEM_REQ 设置为 512Mi

这些参数可以和上一示例 覆盖 PV Sizes 中显示的参数结合使用。

4.4.2.5. 外部 PostgreSQL 数据库

要使用外部数据库,您必须将 openshift_management_app_template 参数值改为 cfme-template-ext-db

此外,必须使用 openshift_management_template_parameters 变量提供数据库连接信息。如需了解更多详细信息,请参阅配置角色变量

[OSEv3:vars]
openshift_management_app_template=cfme-template-ext-db
openshift_management_template_parameters={'DATABASE_USER': 'root', 'DATABASE_PASSWORD': 'mypassword', 'DATABASE_IP': '10.10.10.10', 'DATABASE_PORT': '5432', 'DATABASE_NAME': 'cfme'}
Copy to Clipboard Toggle word wrap
重要

确保您正在运行 PostgreSQL 9.5,或者您可能无法成功部署应用。

4.5. 启用容器提供程序集成

4.5.1. 添加单一容器提供程序

在 OpenShift Container Platform 上部署 Red Hat CloudForms 后,如 运行安装程序 所述,有两种方法可用于启用容器供应商集成。您可以将 OpenShift Container Platform 手动添加为容器供应商,也可以尝试使用此角色中包含的 playbook。

4.5.1.1. 手动添加

有关将 OpenShift Container Platform 集群手动添加为容器供应商的步骤,请参阅以下 Red Hat CloudForms 文档:

4.5.1.2. 自动添加

可以使用此角色中包含的 playbook 来完成自动化容器提供程序集成。

此 playbook:

  1. 收集所需的身份验证 secret。
  2. 查找指向红帽 CloudForms 应用程序和集群 API 的公共路由。
  3. 发出 REST 调用,以将 OpenShift Container Platform 集群添加为容器供应商。

进入 playbook 目录并运行容器供应商 playbook:

$ cd /usr/share/ansible/openshift-ansible
$ ansible-playbook -v [-i /path/to/inventory] \
    openshift-management/add_container_provider.yml
Copy to Clipboard Toggle word wrap

4.5.2. 多个容器供应商

除了提供 playbook 以将当前 OpenShift Container Platform 集群集成到 Red Hat CloudForms 部署中,此角色包含一个脚本,允许您在任何任意红帽 CloudForms 服务器中添加多个容器平台作为容器供应商。容器平台可以是 OpenShift Container Platform 或 OpenShift Origin。

在运行 playbook 时,使用多个提供程序脚本需要在 CLI 上手动配置和设置 EXTRA_VARS 参数。

4.5.2.1. 准备脚本

要准备多个供应商脚本,请完成以下手动配置:

  1. 复制 /usr/share/ansible/openshift-ansible/roles/openshift_management/files/examples/container_providers.yml 示例,如 /tmp/cp.yml。您将修改此文件。
  2. 如果您更改了红帽 CloudForms 名称或密码,请更新您复制的 container_providers.yml 文件中的 management_server 键中的 hostname、user password 参数。
  3. 填写您要添加为容器供应商的每个容器平台集群的 container_providers 键下的条目。

    1. 必须配置以下参数:

      • auth_key - 这是具有 cluster-admin 权限的服务帐户的令牌。
      • hostname - 这是指向集群 API 的主机名。每个容器提供程序必须具有唯一的主机名。
      • name - 这是要在红帽 CloudForms 服务器容器提供程序概览页面中显示的集群名称。这必须是唯一的。
      提示

      从集群中获取 auth_key bearer 令牌:

      $ oc serviceaccounts get-token -n management-infra management-admin
      Copy to Clipboard Toggle word wrap
    2. 可选择性地配置以下参数:

      • port - 如果您的容器平台集群在 8443 之外的端口上运行 API,则更新此密钥。
      • endpoint - 您可以启用 SSL验证(verify_ssl),或将验证设置更改为 ssl-with-validation。目前不支持自定义可信 CA 证书。
4.5.2.1.1. 示例

例如,请考虑以下情况:

  • 您可以将 container_providers.yml 文件复制到 /tmp/cp.yml
  • 您需要添加两个 OpenShift Container Platform 集群。
  • 您的红帽 CloudForms 服务器在 mgmt.example.com上运行

在这种情况下,您将自定义 /tmp/cp.yml,如下所示:

container_providers:
  - connection_configurations:
      - authentication: {auth_key: "<token>", authtype: bearer, type: AuthToken} 
1

        endpoint: {role: default, security_protocol: ssl-without-validation, verify_ssl: 0}
    hostname: "<provider_hostname1>"
    name: <display_name1>
    port: 8443
    type: "ManageIQ::Providers::Openshift::ContainerManager"
  - connection_configurations:
      - authentication: {auth_key: "<token>", authtype: bearer, type: AuthToken} 
2

        endpoint: {role: default, security_protocol: ssl-without-validation, verify_ssl: 0}
    hostname: "<provider_hostname2>"
    name: <display_name2>
    port: 8443
    type: "ManageIQ::Providers::Openshift::ContainerManager"
management_server:
  hostname: "<hostname>"
  user: <user_name>
  password: <password>
Copy to Clipboard Toggle word wrap
1 2
<token> 替换为此集群的管理令牌。
4.5.2.2. 运行 Playbook

要运行 multi-providers 集成脚本,您必须提供容器提供程序配置文件的路径,作为 ansible-playbook 命令的 EXTRA_VARS 参数。使用 -e (或 --extra-vars)参数将 container_providers_config 设置为配置文件路径。进入 playbook 目录并运行 playbook:

$ cd /usr/share/ansible/openshift-ansible
$ ansible-playbook -v [-i /path/to/inventory] \
    -e container_providers_config=/tmp/cp.yml \
    playbooks/openshift-management/add_many_container_providers.yml
Copy to Clipboard Toggle word wrap

playbook 完成后,您应在红帽 CloudForms 服务中找到两个新的容器提供程序。导航到 Compute → Containers → Providers 页面,查看概述。

4.5.3. 刷新供应商

添加单个或多个容器提供程序后,必须在红帽 CloudForms 中刷新新的提供程序,以获取关于容器提供程序和所管理容器的所有最新数据。这涉及导航到红帽 CloudForms Web 控制台中的各个提供程序,然后单击每个控制台的刷新按钮。

有关步骤,请参阅以下 Red Hat CloudForms 文档:

4.6. 卸载 Red Hat CloudForms

4.6.1. 运行卸载 Playbook

要从 OpenShift Container Platform 卸载并删除部署的 Red Hat CloudForms 安装,请切换到 playbook 目录并运行 uninstall.yml playbook:

$ cd /usr/share/ansible/openshift-ansible
$ ansible-playbook -v [-i /path/to/inventory] \
    playbooks/openshift-management/uninstall.yml
Copy to Clipboard Toggle word wrap
重要

NFS 导出定义和数据不会自动删除。在尝试初始化新部署之前,您必须手动从旧应用或数据库部署中清除任何数据。

4.6.2. 故障排除

无法擦除旧的 PostgreSQL 数据可能会导致级联错误,从而导致 postgresql pod 进入 crashloopbackoff 状态。这会阻止 cfme pod 启动。crashloopbackoff 的原因是,之前部署期间创建的数据库 NFS 导出的文件权限不正确。

要继续,请从 PostgreSQL 导出中删除所有数据,并删除 pod(而不是部署器 Pod)。例如,如果您有以下 pod:

$ oc get pods
NAME                 READY     STATUS             RESTARTS   AGE
httpd-1-cx7fk        1/1       Running            1          21h
cfme-0               0/1       Running            1          21h
memcached-1-vkc7p    1/1       Running            1          21h
postgresql-1-deploy  1/1       Running            1          21h
postgresql-1-6w2t4   0/1       CrashLoopBackOff   1          21h
Copy to Clipboard Toggle word wrap

然后,您将:

  1. 从数据库 NFS 导出中删除数据。
  2. 运行:

    $ oc delete postgresql-1-6w2t4
    Copy to Clipboard Toggle word wrap

PostgreSQL 部署器容器集将尝试扩展新的 postgresql 容器集,以取代您删除的容器集。在 postgresql 容器集运行后,cfme 容器集将停止阻止并开始应用初始化。

第 5 章 Prometheus Cluster Monitoring

5.1. 概述

OpenShift Container Platform 附带一个预先配置和自我更新的监控堆栈,它基于 Prometheus 开源项目及其更广泛的生态系统。它提供对集群组件的监控,并附带一组警报,以便立即通知集群管理员任何出现的问题,以及一组 Grafana 仪表板。

上图中突出显示,监控堆栈的核心是 OpenShift Container Platform Cluster Monitoring Operator(CMO),它监视部署的监控组件和资源,并确保它们始终保持最新状态。

Prometheus Operator (PO) 可以创建、配置和管理 Prometheus 和 Alertmanager 实例。还能根据熟悉的 Kubernetes 标签查询来自动生成监控目标配置。

除了 Prometheus 和 Alertmanager 外,OpenShift Container Platform 监控还包括 node-exporterkube-state-metrics。node-exporter 是部署在每个节点上的代理,用于收集有关它的指标。kube-state-metrics 导出器代理将 Kubernetes 对象转换为 Prometheus 可使用的指标。

作为集群监控的一部分监控的目标有:

  • Prometheus 本身
  • Prometheus-Operator
  • cluster-monitoring-operator
  • Alertmanager 集群实例
  • Kubernetes apiserver
  • kubelet(kubelet 为每个容器指标嵌入 cAdvisor)
  • kube-controllers
  • kube-state-metrics
  • node-exporter
  • etcd(如果启用了 etcd 监控)

所有这些组件都会自动更新。

如需有关 OpenShift Container Platform Cluster Monitoring Operator 的更多信息,请参阅 Cluster Monitoring Operator GitHub 项目。

注意

为了能够提供具有保证兼容性的更新,OpenShift Container Platform 监控堆栈的可配置性仅限于明确可用的选项。

5.2. 配置 OpenShift Container Platform 集群监控

OpenShift Container Platform Ansible openshift_cluster_monitoring_operator 角色使用清单文件中的变量配置和部署 Cluster Monitoring Operator。

Expand
表 5.1. Ansible 变量
变量描述

openshift_cluster_monitoring_operator_install

如果为 true,部署 Cluster Monitoring Operator。否则,取消部署。默认将此变量设置为 true

openshift_cluster_monitoring_operator_prometheus_storage_capacity

每个 Prometheus 实例的持久性卷声明大小。只有在 openshift_cluster_monitoring_operator_prometheus_storage_enabled 被设置为 true 时才会应用这个变量。默认值为 50Gi

openshift_cluster_monitoring_operator_alertmanager_storage_capacity

每个 Alertmanager 实例的持久性卷声明大小。只有在 openshift_cluster_monitoring_operator_alertmanager_storage_enabled 被设置为 true 时才会应用这个变量。默认值为 2Gi

openshift_cluster_monitoring_operator_node_selector

设置为所需的现有 节点选择器,以确保 pod 放置到具有特定标签的节点上。默认为 node-role.kubernetes.io/infra=true

openshift_cluster_monitoring_operator_alertmanager_config

配置 Alertmanager。

openshift_cluster_monitoring_operator_prometheus_storage_enabled

启用 Prometheus 时间序列数据的持久性存储。默认将此变量设置为 false

openshift_cluster_monitoring_operator_alertmanager_storage_enabled

启用 Alertmanager 通知和静默的持久性存储。默认将此变量设置为 false

openshift_cluster_monitoring_operator_prometheus_storage_class_name

如果启用了 openshift_cluster_monitoring_operator_prometheus_storage_enabled 选项,请设置特定的 StorageClass 以确保 pod 被配置为使用该 storageclassPVC。默认值为 none,它应用默认存储类名称。

openshift_cluster_monitoring_operator_alertmanager_storage_class_name

如果启用了 openshift_cluster_monitoring_operator_alertmanager_storage_enabled 选项,请设置特定的 StorageClass 以确保 pod 被配置为使用该 storageclassPVC。默认值为 none,它应用默认存储类名称。

5.2.1. 监控先决条件

监控堆栈会带来额外的资源需求。详情请查看计算资源建议

5.2.2. 安装监控堆栈

监控堆栈默认安装有 OpenShift Container Platform。您可以防止安装它。为此,请在 Ansible 清单文件中将此变量设置为 false

openshift_cluster_monitoring_operator_install

您可以通过运行以下命令完成:

$ ansible-playbook [-i </path/to/inventory>] <OPENSHIFT_ANSIBLE_DIR>/playbooks/openshift-monitoring/config.yml \
   -e openshift_cluster_monitoring_operator_install=False
Copy to Clipboard Toggle word wrap

Ansible 目录的常用路径是 /usr/share/ansible/openshift-ansible/。在本例中,配置文件的路径为 /usr/share/ansible/openshift-ansible/playbooks/openshift-monitoring/config.yml

5.2.3. 持久性存储

使用持久性存储运行集群监控意味着您的指标存储在 持久性卷中,并可在 Pod 重新启动或重新创建后保留。如果您需要预防指标或警报数据丢失,这是理想方案。在生产环境中,强烈建议您使用块存储技术配置永久存储。

5.2.3.1. 启用持久性存储

默认情况下,对于 Prometheus 时间序列数据和 Alertmanager 通知和静默禁用持久性存储。您可以将集群配置为永久存储其中任何一个或两者。

  • 要启用 Prometheus 时间序列数据的持久性存储,请在 Ansible 清单文件中将此变量设置为 true

    openshift_cluster_monitoring_operator_prometheus_storage_enabled

  • 要启用 Alertmanager 通知和静默的持久性存储,请在 Ansible 清单文件中将此变量设置为 true

    openshift_cluster_monitoring_operator_alertmanager_storage_enabled

5.2.3.2. 确定需要多少存储

您需要的存储量取决于 Pod 的数目。管理员负责投入足够的存储来确保磁盘未满。如需有关持久性存储的系统要求的信息,请参阅 Cluster Monitoring Operator 的容量规划

5.2.3.3. 设置持久性存储大小

要为 Prometheus 和 Alertmanager 指定持久性卷声明的大小,请更改这些 Ansible 变量:

  • openshift_cluster_monitoring_operator_prometheus_storage_capacity (default:50Gi)
  • openshift_cluster_monitoring_operator_alertmanager_storage_capacity (default:2Gi)

只有将其对应的 storage_enabled 变量设置为 true 时,每个变量才会生效。

5.2.3.4. 分配充足的持久性卷

除非使用动态置备的存储,否则您需要确保 PVC 准备好声明持久性卷(PV),每个副本一个 PV。Prometheus 有两个副本,Alertmanager 有三个副本,它们相当于五个 PV。

5.2.3.5. 启用动态置备的存储

您可以使用动态置备的存储,而不是静态置备的存储。详情请参阅动态卷置备

要为 Prometheus 和 Alertmanager 启用动态存储,请在 Ansible 清单文件中将以下参数设置为 true

  • openshift_cluster_monitoring_operator_prometheus_storage_enabled (Default: false)
  • openshift_cluster_monitoring_operator_alertmanager_storage_enabled (Default: false)

启用动态存储后,您还可以在 Ansible 清单文件中为每个组件设置存储类

  • openshift_cluster_monitoring_operator_prometheus_storage_class_name (default: "")
  • openshift_cluster_monitoring_operator_alertmanager_storage_class_name (default: "")

只有将其对应的 storage_enabled 变量设置为 true 时,每个变量才会生效。

5.2.4. 支持的配置

配置 OpenShift Container Platform Monitoring 的支持方法是使用本指南中介绍的选项进行配置。除了这些明确的配置选项外,还可以将其他配置注入到堆栈中。但不受支持,因为配置范例可能会在 Prometheus 发行版本间有所变化,只有在控制了所有可能的配置时,才能安全地应对这样的情况。

明确不支持的情形包括:

  • openshift-monitoring 命名空间中创建额外的 ServiceMonitor 对象,从而扩展集群监控 Prometheus 实例提取的目标。这可能导致无法考量的冲突和负载差异,因此 Prometheus 设置可能会不稳定。
  • 创建额外的 ConfigMap 对象,导致集群监控 Prometheus 实例包含额外的警报和记录规则。请注意,如果应用此行为,这个行为会导致行为中断,因为 Prometheus 2.0 将附带新的规则文件语法。

5.3. 配置 Alertmanager

Alertmanager 管理传入的警报;这包括银级、禁止、聚合和通过电子邮件、PagerDuty 和 HipChat 等方法发送通知。

OpenShift Container Platform Monitoring Alertmanager 集群的默认配置是:

  global:
    resolve_timeout: 5m
  route:
    group_wait: 30s
    group_interval: 5m
    repeat_interval: 12h
    receiver: default
    routes:
    - match:
        alertname: DeadMansSwitch
      repeat_interval: 5m
      receiver: deadmansswitch
  receivers:
  - name: default
  - name: deadmansswitch
Copy to Clipboard Toggle word wrap

可以使用 openshift_cluster_monitoring_operator 角色中的 Ansible 变量 openshift_cluster_monitoring_operator_alertmanager_config 覆盖此配置。

以下示例将 PagerDuty 配置为通知。如需了解如何检索 service_key,请参阅 Alertmanager 的 PagerDuty 文档。

openshift_cluster_monitoring_operator_alertmanager_config: |+
  global:
    resolve_timeout: 5m
  route:
    group_wait: 30s
    group_interval: 5m
    repeat_interval: 12h
    receiver: default
    routes:
    - match:
        alertname: DeadMansSwitch
      repeat_interval: 5m
      receiver: deadmansswitch
    - match:
        service: example-app
      routes:
      - match:
          severity: critical
        receiver: team-frontend-page
  receivers:
  - name: default
  - name: deadmansswitch
  - name: team-frontend-page
    pagerduty_configs:
    - service_key: "<key>"
Copy to Clipboard Toggle word wrap

子路由仅匹配严重性为 critical 的警报,并使用名为 team-frontend-page 的接收器发送它们。如名称所示,对于关键警报,应传出某人。参阅 Alertmanager 配置来配置通过不同警报接收器发送警报。

5.3.1. 死人开关

OpenShift Container Platform Monitoring 附带了一个 死人开关,用于确保监控基础架构的可用性。

死人开关是始终触发的简单 Prometheus 警报规则。Alertmanager 持续向支持此功能的通知提供程序发送死人交换机的通知。这也可确保 Alertmanager 和通知提供程序之间的通信正常工作。

PagerDuty 支持这种机制,以在监控系统本身停机时发出警报。如需更多信息,请参阅下面的死人开关 PagerDuty

5.3.2. 分组警报

在警报针对 Alertmanager 触发后,必须将其配置为了解如何在逻辑上分组它们。

在本例中,添加了一个新的路由来反映 frontend 团队的警报路由。

流程

  1. 添加新路由。可以在原始路由下添加多个路由,通常用于定义通知的接收方。以下示例使用匹配器来确保只使用来自服务 example-app 的警报:

    global:
      resolve_timeout: 5m
    route:
      group_wait: 30s
      group_interval: 5m
      repeat_interval: 12h
      receiver: default
      routes:
      - match:
          alertname: DeadMansSwitch
        repeat_interval: 5m
        receiver: deadmansswitch
      - match:
          service: example-app
        routes:
        - match:
            severity: critical
          receiver: team-frontend-page
    receivers:
    - name: default
    - name: deadmansswitch
    Copy to Clipboard Toggle word wrap

    子路由仅匹配严重性为 critical 的警报,并使用名为 team-frontend-page 的接收器发送它们。如名称所示,对于关键警报,应传出某人。

5.3.3. 死人开关 PagerDuty

PagerDuty 通过名为 死人开关 的集成来支持此机制。只需将 PagerDuty 配置添加到默认的 deadmanswitch 接收器。使用上述流程添加此配置。

如果死人开关警报静默 15 分钟,将死人开关配置为页面运算符。使用默认的 Alertmanager 配置时,死人开关警报每五分钟重复一次。如果死人开关在 15 分钟后触发,这表明通知失败至少两次。

了解如何 为 PagerDuty 配置死人开关

5.3.4. 警报规则

OpenShift Container Platform Cluster Monitoring 附带了以下默认配置的警报规则。目前无法添加自定义警报规则。

有些警报规则的名称相同。这是有意设计的。它们会警告同一事件,它们具有不同的阈值,或严重性不同。在禁止规则中,触发较高的严重性时会禁止较低严重性。

有关警报规则的详情,请查看配置文件

Expand
警报重要性描述

ClusterMonitoringOperatorErrors

critical

Cluster Monitoring Operator 会出现 X% 错误。

AlertmanagerDown

critical

Alertmanager 已从 Prometheus 目标发现中消失。

ClusterMonitoringOperatorDown

critical

ClusterMonitoringOperator 已从 Prometheus 目标发现中消失。

KubeAPIDown

critical

KubeAPI 已从 Prometheus 目标发现中消失。

KubeControllerManagerDown

critical

kubecontrollermanager 已从 Prometheus 目标发现中消失。

KubeSchedulerDown

critical

kubescheduler 已从 Prometheus 目标发现中消失。

KubeStateMetricsDown

critical

kubeStateMetrics 已从 Prometheus 目标发现中消失。

KubeletDown

critical

kubelet 已从 Prometheus 目标发现中消失。

NodeExporterDown

critical

NodeExporter 已从 Prometheus 目标发现中消失。

PrometheusDown

critical

Prometheus 已从 Prometheus 目标发现中消失。

PrometheusOperatorDown

critical

PrometheusOperator 已从 Prometheus 目标发现中消失。

KubePodCrashLooping

critical

Namespace/Pod (Container) 重启 times / second

KubePodNotReady

critical

Namespace/Pod 未就绪。

KubeDeploymentGenerationMismatch

critical

部署 Namespace/Deployment 生成不匹配

KubeDeploymentReplicasMismatch

critical

部署 Namespace/Deployment 副本不匹配

KubeStatefulSetReplicasMismatch

critical

StatefulSet Namespace/StatefulSet 副本不匹配

KubeStatefulSetGenerationMismatch

critical

StatefulSet Namespace/StatefulSet 生成不匹配

KubeDaemonSetRolloutStuck

critical

只有调度并准备好用于守护进程设置 Namespace/DaemonSet 的所需 pod 的 X%

KubeDaemonSetNotScheduled

warning

没有调度 daemonset Namespace/DaemonSet 的 pod。

KubeDaemonSetMisScheduled

warning

许多 daemonset Namespace/DaemonSet 的 pod 在不应该运行的位置运行。

KubeCronJobRunning

warning

CronJob Namespace/CronJob 需要 1h 以上才能完成。

KubeJobCompletion

warning

Job Namespaces/Job 需要超过 1h 的时间才能完成。

KubeJobFailed

warning

Job Namespaces/Job 无法完成。

KubeCPUOvercommit

warning

Pod 上过量使用的 CPU 资源请求无法容忍节点失败。

KubeMemOvercommit

warning

Pod 上过量使用的内存资源请求,无法容忍节点失败。

KubeCPUOvercommit

warning

命名空间上过量使用的 CPU 资源请求配额。

KubeMemOvercommit

warning

命名空间上过量使用的内存资源请求配额。

alerKubeQuotaExceeded

warning

命名空间 Namespace 中的 X% 的资源已使用。

KubePersistentVolumeUsageCritical

critical

命名空间 Namespace 中的 PersistentVolumeClaim 声明的持久性卷有 X% free。

KubePersistentVolumeFullInFourDays

critical

根据最近的抽样,命名空间 Namespace 中的 PersistentVolumeClaim 声明的持久性卷应该在四天内填满。X 字节当前可用。

KubeNodeNotReady

warning

节点 已就绪一小时以上

KubeVersionMismatch

warning

运行 X 种不同版本的 Kubernetes 组件。

KubeClientErrors

warning

Kubernetes API 服务器客户端的 'Job/Instance' 正在遇到 X% 错误。

KubeClientErrors

warning

Kubernetes API 服务器客户端的 'Job/Instance' 正在遇到 X 错误/ sec'。

KubeletTooManyPods

warning

kubelet 实例正在运行 X pod,接近 110。

KubeAPILatencyHigh

warning

API 服务器具有 99% 的 Verb 资源 延迟 X 秒。

KubeAPILatencyHigh

critical

API 服务器具有 99% 的 Verb 资源 延迟 X 秒。

KubeAPIErrorsHigh

critical

API 服务器针对 X% 的请求出错。

KubeAPIErrorsHigh

warning

API 服务器针对 X% 的请求出错。

KubeClientCertificateExpiration

warning

Kubernetes API 证书将在不到 7 天后过期。

KubeClientCertificateExpiration

critical

Kubernetes API 证书将在不到 1 天后过期。

AlertmanagerConfigInconsistent

critical

Summary:配置不同步.描述:Alertmanager 集群 服务 的实例配置不同步。

AlertmanagerFailedReload

warning

Summary:Alertmanager 的配置重新加载失败。描述:重新加载 Alertmanager 的配置对于 Namespace/Pod 失败。

TargetDown

warning

Summary:目标已停机。描述:X% 的作业 目标为 down。

DeadMansSwitch

none

Summary:通知 DeadMansSwitch.描述:这是一个 DeadMansSwitch,可确保整个 Alerting 管道正常工作。

NodeDiskRunningFull

warning

node-exporter Namespace/Pod 的设备设备在接下来 24 小时内完全运行。

NodeDiskRunningFull

critical

node-exporter Namespace/Pod 的设备设备在接下来 2 小时内完全运行。

PrometheusConfigReloadFailed

warning

Summary:重新载入 Prometheus 配置失败。描述:为 Namespace/Pod 重新载入 Prometheus 配置失败

PrometheusNotificationQueueRunningFull

warning

Summary:Prometheus 的警报通知队列已满运行。描述:Prometheus 的警报通知队列已完全针对 Namespace/Pod 运行

PrometheusErrorSendingAlerts

warning

Summary:从 Prometheus 发送警报时出错。描述:将警报从 Prometheus Namespace/Pod 发送到 Alertmanager 时出错

PrometheusErrorSendingAlerts

critical

Summary:从 Prometheus 发送警报时出错。描述:将警报从 Prometheus Namespace/Pod 发送到 Alertmanager 时出错

PrometheusNotConnectedToAlertmanagers

warning

Summary:Prometheus 没有连接到任何 Alertmanager。描述:Prometheus Namespace/Pod 没有连接到任何 Alertmanager

PrometheusTSDBReloadsFailing

warning

Summary:Prometheus 在从磁盘重新载入数据块时遇到问题。描述:在过去四个小时内,实例中的作业X 重新加载失败。

PrometheusTSDBCompactionsFailing

warning

Summary:Prometheus 在压缩示例块时遇到问题。描述:实例作业过去四小时内出现 X 紧凑故障。

PrometheusTSDBWALCorruptions

warning

Summary:Prometheus write-ahead 日志已被损坏。描述:Instance 中的 作业 具有损坏的 write-ahead 日志(WAL)。

PrometheusNotIngestingSamples

warning

Summary:Prometheus 不捕获示例。描述:Prometheus Namespace/Pod 不嵌套示例。

PrometheusTargetScrapesDuplicate

warning

Summary:Prometheus 有许多示例被拒绝。描述:Namespace/Pod 因为时间戳重复但不同的值而拒绝多个示例

EtcdInsufficientMembers

critical

Etcd 集群 "Job": insufficient members (X).

EtcdNoLeader

critical

Etcd 集群 "Job": member Instance 没有 leader。

EtcdHighNumberOfLeaderChanges

warning

Etcd 集群 "Job": 实例 Instance 在过去一小时内看到 X leader 改变。

EtcdHighNumberOfFailedGRPCRequests

warning

Etcd 集群 "Job":X% 的 GRPC_Method 请求在 etcd 实例 Instance 上失败。

EtcdHighNumberOfFailedGRPCRequests

critical

Etcd 集群 "Job":X% 的 GRPC_Method 请求在 etcd 实例 Instance 上失败。

EtcdGRPCRequestsSlow

critical

Etcd 集群 "Job": 到 GRPC_Method 的 gRPC 请求在 X_s on etcd instance _Instance

EtcdMemberCommunicationSlow

warning

Etcd 集群 "Job": 成员与 To 通信正在 X_s on etcd instance _Instance

EtcdHighNumberOfFailedProposals

warning

Etcd 集群 "Job":X 提议在 etcd 实例 Instance 的最后一小时内失败。

EtcdHighFsyncDurations

warning

Etcd 集群 "Job":99th percentile fync durations 是 X_s on etcd instance _Instance

EtcdHighCommitDurations

warning

Etcd 集群 "Job":99 percentile 的提交持续时间为 X_s on etcd instance _Instance

FdExhaustionClose

warning

Job instance Instance 很快会耗尽其文件描述符

FdExhaustionClose

critical

Job instance Instance 很快会耗尽其文件描述符

5.4. 配置 etcd 监控

如果 etcd 服务没有正确运行,则整个 OpenShift Container Platform 集群的成功操作将处于危险之中。因此,最好为 etcd 配置监控。

按照以下步骤配置 etcd 监控 :

流程

  1. 验证监控堆栈是否正在运行:

    $ oc -n openshift-monitoring get pods
    NAME                                           READY     STATUS              RESTARTS   AGE
    alertmanager-main-0                            3/3       Running             0          34m
    alertmanager-main-1                            3/3       Running             0          33m
    alertmanager-main-2                            3/3       Running             0          33m
    cluster-monitoring-operator-67b8797d79-sphxj   1/1       Running             0          36m
    grafana-c66997f-pxrf7                          2/2       Running             0          37s
    kube-state-metrics-7449d589bc-rt4mq            3/3       Running             0          33m
    node-exporter-5tt4f                            2/2       Running             0          33m
    node-exporter-b2mrp                            2/2       Running             0          33m
    node-exporter-fd52p                            2/2       Running             0          33m
    node-exporter-hfqgv                            2/2       Running             0          33m
    prometheus-k8s-0                               4/4       Running             1          35m
    prometheus-k8s-1                               0/4       ContainerCreating   0          21s
    prometheus-operator-6c9fddd47f-9jfgk           1/1       Running             0          36m
    Copy to Clipboard Toggle word wrap
  2. 打开集群监控堆栈的配置文件:

    $ oc -n openshift-monitoring edit configmap cluster-monitoring-config
    Copy to Clipboard Toggle word wrap
  3. config.yaml: |+ 下,添加 etcd 部分。

    1. 如果在 master 节点上运行静态 pod 的 etcd,您可以使用选择器指定 etcd 节点:

      ...
      data:
        config.yaml: |+
          ...
          etcd:
            targets:
              selector:
                openshift.io/component: etcd
                openshift.io/control-plane: "true"
      Copy to Clipboard Toggle word wrap
    2. 如果在单独的主机上运行 etcd,则需要使用 IP 地址指定节点:

      ...
      data:
        config.yaml: |+
          ...
          etcd:
            targets:
             ips:
             - "127.0.0.1"
             - "127.0.0.2"
             - "127.0.0.3"
      Copy to Clipboard Toggle word wrap

      如果 etcd 节点的 IP 地址有变化,您必须更新此列表。

  4. 验证 etcd 服务监控器现在是否正在运行:

    $ oc -n openshift-monitoring get servicemonitor
    NAME                  AGE
    alertmanager          35m
    etcd                  1m 
    1
    
    kube-apiserver        36m
    kube-controllers      36m
    kube-state-metrics    34m
    kubelet               36m
    node-exporter         34m
    prometheus            36m
    prometheus-operator   37m
    Copy to Clipboard Toggle word wrap
    1
    etcd 服务监控器。

    etcd 服务监控器最多可能需要一分钟才能启动。

  5. 现在,您可以进入 Web 界面来查看有关 etcd 监控状态的更多信息。

    1. 要获取 URL,请运行:

      $ oc -n openshift-monitoring get routes
      NAME                HOST/PORT                                                                           PATH      SERVICES            PORT      TERMINATION   WILDCARD
      ...
      prometheus-k8s      prometheus-k8s-openshift-monitoring.apps.msvistun.origin-gce.dev.openshift.com                prometheus-k8s      web       reencrypt     None
      Copy to Clipboard Toggle word wrap
    2. 使用 https,导航到为 prometheus-k8s 列出的 URL。登录。
  6. 确保该用户属于 cluster-monitoring-view 角色。此角色提供查看集群监控 UI 的访问权限。

    例如,要将用户 developer 添加到 cluster-monitoring-view 角色中,请运行:

    $ oc adm policy add-cluster-role-to-user cluster-monitoring-view developer
    Copy to Clipboard Toggle word wrap
  7. 在 Web 界面中,以属于 cluster-monitoring-view 角色的用户身份登录。
  8. 单击 Status,然后单击 Targets。如果您看到 etcd 条目,则会监控 etcd

  9. 虽然 etcd 被监控,但 Prometheus 还无法通过 etcd 进行身份验证,因此无法收集指标数据。

    针对 etcd 配置 Prometheus 身份验证:

    1. /etc/etcd/ca/ca.crt/etc/etcd/ca/ca.key 凭证文件从 master 节点复制到本地机器:

      $ ssh -i gcp-dev/ssh-privatekey cloud-user@35.237.54.213
      Copy to Clipboard Toggle word wrap
    2. 创建包含以下内容的 openssl.cnf 文件:

      [ req ]
      req_extensions = v3_req
      distinguished_name = req_distinguished_name
      [ req_distinguished_name ]
      [ v3_req ]
      basicConstraints = CA:FALSE
      keyUsage = nonRepudiation, keyEncipherment, digitalSignature
      extendedKeyUsage=serverAuth, clientAuth
      Copy to Clipboard Toggle word wrap
    3. 生成 etcd.key 私钥文件:

      $ openssl genrsa -out etcd.key 2048
      Copy to Clipboard Toggle word wrap
    4. 生成 etcd.csr 证书签名请求文件:

      $ openssl req -new -key etcd.key -out etcd.csr -subj "/CN=etcd" -config openssl.cnf
      Copy to Clipboard Toggle word wrap
    5. 生成 etcd.crt 证书文件:

      $ openssl x509 -req -in etcd.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out etcd.crt -days 365 -extensions v3_req -extfile openssl.cnf
      Copy to Clipboard Toggle word wrap
    6. 将凭证置于 OpenShift Container Platform 使用的格式:

      $ cat <<-EOF > etcd-cert-secret.yaml
      apiVersion: v1
      data:
        etcd-client-ca.crt: "$(cat ca.crt | base64 --wrap=0)"
        etcd-client.crt: "$(cat etcd.crt | base64 --wrap=0)"
        etcd-client.key: "$(cat etcd.key | base64 --wrap=0)"
      kind: Secret
      metadata:
        name: kube-etcd-client-certs
        namespace: openshift-monitoring
      type: Opaque
      EOF
      Copy to Clipboard Toggle word wrap

      这会创建 etcd-cert-secret.yaml 文件

    7. 将凭证文件应用到集群:

      $ oc apply -f etcd-cert-secret.yaml
      Copy to Clipboard Toggle word wrap
  10. 现在您已配置了身份验证,请再次访问 Web 界面的 Targets 页面。验证 etcd 现在是否正确监控。可能需要几分钟后更改才会生效。

  11. 如果您希望在更新 OpenShift Container Platform 时自动更新 etcd 监控,请将 Ansible 清单文件中的这个变量设置为 true

    openshift_cluster_monitoring_operator_etcd_enabled=true
    Copy to Clipboard Toggle word wrap

    如果您在单独的主机上运行 etcd,请按照 IP 地址使用此 Ansible 变量指定节点:

    openshift_cluster_monitoring_operator_etcd_hosts=[<address1>, <address2>, ...]
    Copy to Clipboard Toggle word wrap

    如果 etcd 节点的 IP 地址改变,您必须更新此列表。

5.5. 访问 Prometheus、Alertmanager 和 Grafana。

OpenShift Container Platform Monitoring 附带了一个用于集群监控的 Prometheus 实例和一个中央 Alertmanager 集群。除了 Prometheus 和 Alertmanager 外,OpenShift Container Platform Monitoring 还包含一个 Grafana 实例,以及用于集群监控故障排除的预构建仪表板。由监控堆栈提供的 Grafana 实例及其仪表板是只读的。

获取用于访问 Prometheus、Alertmanager 和 Grafana Web UI 的地址:

流程

  1. 运行以下命令:

    $ oc -n openshift-monitoring get routes
    NAME                HOST/PORT
    alertmanager-main   alertmanager-main-openshift-monitoring.apps._url_.openshift.com
    grafana             grafana-openshift-monitoring.apps._url_.openshift.com
    prometheus-k8s      prometheus-k8s-openshift-monitoring.apps._url_.openshift.com
    Copy to Clipboard Toggle word wrap

    确保将 https:// 添加到这些地址。您无法使用未加密的连接访问 Web UI。

  2. 根据 OpenShift Container Platform 身份进行身份验证,并使用与 OpenShift Container Platform 其他位置相同的凭证或验证方式。您必须使用具有所有命名空间的读取访问权限的角色,如 cluster-monitoring-view 集群角色。

第 6 章 访问并配置 Red Hat Registry

6.1. 启用身份验证的 Red Hat Registry

Red Hat Container Catalog (registry.access.redhat.com)是一个托管的镜像 registry,通过它可以获得所需的容器镜像。OpenShift Container Platform 3.11 Red Hat Container Catalog 从 registry.access.redhat.com 移到 registry.redhat.io

新的 registry(Registry.redhat.io)需要进行身份验证才能访问OpenShift Container Platform上的镜像及内容。当迁移到新registry后,现有的registry仍将在一段时间内可用。

注意

OpenShift Container Platform从Registry.redhat.io中提取(pull)镜像,因此需要配置集群以使用它。

新registry使用标准的OAuth机制进行身份验证:

  • 身份验证令牌。令牌(token)是服务帐户,由管理员生成。系统可以使用它们与容器镜像registry进行身份验证。服务帐户不受用户帐户更改的影响,因此使用令牌进行身份验证是一个可靠且具有弹性的方法。这是生产环境集群中唯一受支持的身份验证选项。
  • Web用户名和密码。这是用于登录到诸如access.redhat.com之类的资源的标准凭据集。虽然可以在OpenShift Container Platform上使用此身份验证方法,但在生产环境部署中不支持此方法。此身份验证方法应该只限于在OpenShift Container Platform之外的独立项目中使用。

您可以在 docker login 中使用您的凭证(用户名和密码,或身份验证令牌)来访问新 registry 中的内容。

所有镜像流均指向新的registry。由于新 registry 需要进行身份验证才能访问,因此 OpenShift 命名空间中有一个名为 imagestreamsecret 的新机密。

您需要将凭据放在两个位置:

  • OpenShift 命名空间 。您的凭据必须存在于 OpenShift 命名空间中,以便 OpenShift 命名空间中的镜像流可以导入。
  • 您的主机。您的凭据必须存在于主机上,因为在抓取(pull)镜像时,Kubernetes会使用主机中的凭据。

访问新 registry:

  • 验证镜像导入 secret( imagestreamsecret )是否位于 OpenShift 命名空间中。该 secret 具有允许您访问新 registry 的凭证。
  • 验证所有集群节点都有一个 /var/lib/origin/.docker/config.json,可以从 master 中复制,供您访问红帽 registry。

6.1.1. 创建用户帐户

如果您是有权使用红帽产品的红帽客户,则拥有具有适用用户凭证的帐户。这些是您用于登录到红帽客户门户的用户名和密码。

如果您没有帐户,可以通过注册以下选项之一获取免费帐户:

如果您的组织管理共享帐户,则必须创建令牌。管理员可以创建、查看和删除与组织关联的所有令牌。

先决条件

  • 用户凭证

流程

要创建令牌以完成 docker login,请执行以下操作 :

  1. 导航到 registry.redhat.io
  2. 使用您的红帽网络(RHN)用户名和密码登录。
  3. 出现提示时接受条款.

    • 如果未立即提示您接受条款,则在继续以下步骤时会提示您。
  4. Registry Service Accounts 页面中点 Create Service Account

    1. 为服务帐户提供名称。它将带有一个随机字符串。
    2. 输入描述。
    3. 单击 create。
  5. 切回到您的服务帐户。
  6. 点您创建的服务帐户。
  7. 复制用户名,包括前缀字符串。
  8. 复制令牌。

6.1.3. 管理用于安装和升级的 registry 凭证

您还可以在安装过程中使用 Ansible 安装程序管理 registry 凭据。

这将设置以下内容:

  • OpenShift 命名空间中的 imagestreamsecret
  • 所有节点上的凭据。

当您将 registry.redhat.io 的默认值用于 openshift_examples_registryurloreg_url 时,Ansible 安装程序将需要凭证。

先决条件

  • 用户凭证
  • 服务帐户
  • 服务帐户令牌

流程

要在安装过程中使用 Ansible 安装程序管理 registry 凭证:

  • 在安装或升级过程中,指定安装程序清单中的 oreg_auth_useroreg_auth_password 变量。
注意

如果您已创建了令牌,请将 oreg_auth_password 设置为令牌的值。

需要访问其他经过身份验证的 registry 的集群可以通过设置 openshift_additional_registry_credentials 来配置 registry 列表。每个 registry 都需要主机和密码值,您可以通过设置用户来指定用户名。默认情况下,通过尝试检查指定 registry 上的镜像 openshift3/ose-pod 来验证指定的凭证。

要指定备用镜像,请执行以下操作:

  • 设置 test_image
  • 通过将 test_login 设置为 False 来禁用凭据验证。

如果 registry 不安全,则将 tls_verify 设置为 False。

此列表中的所有凭据都将在 OpenShift 命名空间中创建 imagestreamsecret,并部署到所有节点的凭据。

例如:

openshift_additional_registry_credentials=[{'host':'registry.example.com','user':'name','password':'pass1','test_login':'False'},{'host':'registry2.example.com','password':'token12345','tls_verify':'False','test_image':'mongodb/mongodb'}]
Copy to Clipboard Toggle word wrap

6.1.4. 在 Red Hat Registry 中使用服务帐户

在为 Red Hat Registry 创建服务帐户和生成的令牌后,您可以执行其他任务。

注意

本节提供了手动步骤,可以通过提供 管理 registry Credentials for Installation 和 Upgrade 部分中概述的清单变量来自动执行这些步骤。

先决条件

  • 用户凭证
  • 服务帐户
  • 服务帐户令牌

流程

Registry Service Accounts 页面中点击您的帐户名称。在这里,您可以执行以下任务:

  • Token Information 选项卡中,您可以查看您的用户名(您提供的带有随机字符串的名称)和密码(令牌)。在此选项卡中,您可以重新生成令牌。
  • OpenShift Secret 选项卡中,您可以:

    1. 单击选项卡中的链接,以下载该机密。
    2. 将 secret 提交到集群:

      # oc create -f <account-name>-secret.yml --namespace=openshift
      Copy to Clipboard Toggle word wrap
    3. 使用 imagePullSecrets 字段在 Kubernetes pod 配置中添加对 secret 的引用来更新 Kubernetes 配置,例如:

      apiVersion: v1
      kind: Pod
      metadata:
        name: somepod
        namespace: all
        spec:
          containers:
            - name: web
            image: registry.redhat.io/REPONAME
      
          imagePullSecrets:
            - name: <numerical-string-account-name>-pull-secret
      Copy to Clipboard Toggle word wrap
  • Docker Login 选项卡中,您可以运行 docker login。例如:

    # docker login -u='<numerical-string|account-name>'
      -p=<token>
    Copy to Clipboard Toggle word wrap

    成功登录后,将 ~/.docker/config.json 复制到 /var/lib/origin/.docker/config.json,然后重新启动节点。

    # cp -r ~/.docker /var/lib/origin/
      systemctl restart atomic-openshift-node
    Copy to Clipboard Toggle word wrap
  • Docker Configuration 选项卡中,您可以:

    1. 单击选项卡中的链接,下载凭据配置。
    2. 通过将文件放入 Docker 配置目录中,将配置写入到磁盘。这将覆盖现有的凭据。例如:

      # mv <account-name>-auth.json ~/.docker/config.json
      Copy to Clipboard Toggle word wrap

第 7 章 Master 和节点配置

7.1. 安装后自定义 master 和节点配置

openshift start 命令(用于 master 服务器)和 Hyperkube 命令(用于节点服务器)采用一组有限的参数,足以在开发或实验环境中启动服务器。但是,这些参数不足以描述和控制生产环境中所需的整套配置和安全选项。

您必须在 master 配置文件(/etc/origin/master/master-config.yaml) 和 节点配置映射中提供这些选项。这些文件定义了选项,包括覆盖默认插件、连接到 etcd、自动创建服务帐户、构建镜像名称、自定义项目请求、配置卷插件等。

本节介绍了自定义 OpenShift Container Platform master 和节点主机的可用选项,并演示了如何在安装后更改配置。

在不使用默认值的情况下,将完全指定这些文件。因此,一个空值表示您要使用该参数的空值启动。这样可以轻松地说明您配置的确切原因,但也难以记住要指定的所有选项。为此,可以使用 --write-config 选项创建配置文件,然后与 --config 选项一起使用。

7.2. 安装依赖项

生产环境应该使用标准 集群安装 过程进行安装。在生产环境中,最好将 多个 master 用于 高可用性 (HA)。建议使用三个 master 的集群架构,并且推荐使用 HAproxy

Important

如果在 master 主机上 安装 etcd,则必须将集群配置为使用至少三个 master,因为 etcd 无法决定哪个是权威的。成功运行两个 master 的唯一方法是在 master 以外的主机上安装 etcd。

7.3. 配置主控机和节点

配置 master 和节点配置文件的方法必须与用于安装 OpenShift Container Platform 集群的方法匹配。如果您遵循标准 集群安装 过程,请在 Ansible 清单文件中进行配置更改。

7.4. 使用 Ansible 进行配置更改

对于本节,假设您熟悉 Ansible。

只有一部分可用的主机配置选项会 公开给 Ansible。安装 OpenShift Container Platform 后,Ansible 会使用一些替换的值创建一个清单文件。修改此清单文件并重新运行 Ansible 安装程序 playbook 是为了自定义 OpenShift Container Platform 集群。

虽然 OpenShift Container Platform 支持使用 Ansible playbook 和清单文件进行集群安装,但您也可以使用其他管理工具,如 PuppetChefSalt

使用案例:将集群配置为使用 HTPasswd 身份验证

注意
  • 此用例假定您已为 playbook 中引用的所有节点设置了 SSH 密钥
  • htpasswd 工具程序位于 httpd-tools 软件包中:

    # yum install httpd-tools
    Copy to Clipboard Toggle word wrap

修改 Ansible 清单并进行配置更改:

  1. 打开 ./hosts 清单文件。
  2. 在文件的 [OSEv3:vars] 部分添加以下新变量:

    # htpasswd auth
    openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true', 'challenge': 'true', 'kind': 'HTPasswdPasswordIdentityProvider'}]
    # Defining htpasswd users
    #openshift_master_htpasswd_users={'<name>': '<hashed-password>', '<name>': '<hashed-password>'}
    # or
    #openshift_master_htpasswd_file=/etc/origin/master/htpasswd
    Copy to Clipboard Toggle word wrap

    对于 HTPasswd 身份验证,openshift_master_identity_providers 变量启用身份验证类型。您可以使用 HTPasswd 配置三个不同的身份验证选项:

    • 如果主机上已配置了 /etc/origin/master/htpasswd,则仅指定 openshift_master _identity_providers
    • 指定 openshift_master_identity_providersopenshift_master_htpasswd_file 将本地 htpasswd 文件复制到主机。
    • 指定 openshift_master_identity_providersopenshift_master_htpasswd_users,以在主机上生成新的 htpasswd 文件。

    由于 OpenShift Container Platform 需要哈希密码来配置 HTPasswd 身份验证,因此您可以使用 htpasswd 命令(如以下小结所述)为用户生成哈希密码,或使用用户和相关哈希密码创建平面文件。

    以下示例将身份验证方法从默认 拒绝所有 设置到 htpasswd,并使用指定的文件为 jsmithblob 用户可以生成用户 ID 和密码

    # htpasswd auth
    openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true', 'challenge': 'true', 'kind': 'HTPasswdPasswordIdentityProvider'}]
    # Defining htpasswd users
    openshift_master_htpasswd_users={'jsmith': '$apr1$wIwXkFLI$bAygtKGmPOqaJftB', 'bloblaw': '7IRJ$2ODmeLoxf4I6sUEKfiA$2aDJqLJe'}
    # or
    #openshift_master_htpasswd_file=/etc/origin/master/htpasswd
    Copy to Clipboard Toggle word wrap
  3. 重新运行 ansible playbook 以使这些修改生效:

    $ ansible-playbook -b -i ./hosts ~/src/openshift-ansible/playbooks/deploy_cluster.yml
    Copy to Clipboard Toggle word wrap

    playbook 更新配置,并重启 OpenShift Container Platform master 服务以应用更改。

您现在已使用 Ansible 修改了 master 和节点配置文件,但这只是一个简单的用例。从此处您可以看到哪些 master节点配置选项 公开给 Ansible,并自定义您自己的 Ansible 清单。

7.4.1. 使用 htpasswd 命令

要将 OpenShift Container Platform 集群配置为使用 HTPasswd 身份验证,您至少需要一个带有哈希密码的用户才能包含在 清单文件中

您可以:

创建用户和散列密码:

  1. 运行以下命令来添加指定用户:

    $ htpasswd -n <user_name>
    Copy to Clipboard Toggle word wrap
    注意

    您可以包含 -b 选项,用于在命令行中提供密码:

    $ htpasswd -nb <user_name> <password>
    Copy to Clipboard Toggle word wrap
  2. 输入并确认用户的明文密码。

    例如:

    $ htpasswd -n myuser
    New password:
    Re-type new password:
    myuser:$apr1$vdW.cI3j$WSKIOzUPs6Q
    Copy to Clipboard Toggle word wrap

    该命令将生成散列版本的密码。

然后您可以在配置 HTPasswd 身份验证时使用哈希密码。hashed 密码是字符串,位于 : 后面。在上例中,请输入:

openshift_master_htpasswd_users={'myuser': '$apr1$wIwXkFLI$bAygtISk2eKGmqaJftB'}
Copy to Clipboard Toggle word wrap

创建带有用户名和散列密码的平面文件:

  1. 执行以下命令:

    $ htpasswd -c /etc/origin/master/htpasswd <user_name>
    Copy to Clipboard Toggle word wrap
    注意

    您可以包含 -b 选项,用于在命令行中提供密码:

    $ htpasswd -c -b <user_name> <password>
    Copy to Clipboard Toggle word wrap
  2. 输入并确认用户的明文密码。

    例如:

    htpasswd -c /etc/origin/master/htpasswd user1
    New password:
    Re-type new password:
    Adding password for user user1
    Copy to Clipboard Toggle word wrap

    命令会生成一个文件,其中包含用户名以及用户密码的散列版本。

然后,您可以在配置 HTPasswd 身份验证时使用密码文件。

注意

如需有关 htpasswd 命令的更多信息,请参阅 HTPasswd 身份提供程序

7.5. 进行手动配置更改

使用案例:配置集群以使用 HTPasswd 身份验证

手动修改配置文件:

  1. 打开您要修改的配置文件,本例中为 /etc/origin/master/master-config.yaml 文件:
  2. 将以下新变量添加到文件的 identityProviders 小节中:

    oauthConfig:
      ...
      identityProviders:
      - name: my_htpasswd_provider
        challenge: true
        login: true
        mappingMethod: claim
        provider:
          apiVersion: v1
          kind: HTPasswdPasswordIdentityProvider
          file: /etc/origin/master/htpasswd
    Copy to Clipboard Toggle word wrap
  3. 保存您的更改并关闭该文件。
  4. 重启 master 以使更改生效:

    # master-restart api
    # master-restart controllers
    Copy to Clipboard Toggle word wrap

您现在已手动修改 master 和节点配置文件,但这只是一个简单的用例。在这里,您可以通过进行进一步的修改来查看所有 master节点配置选项,并进一步自定义自己的集群。

注意

要修改集群中的节点,请根据需要更新节点配置映射。不要手动编辑 node-config.yaml 文件。

7.6. 主配置文件

本节介绍了 master-config.yaml 文件中提到的参数。

您可以 创建新的 master 配置文件 来查看已安装 OpenShift Container Platform 版本的有效选项。

重要

每当修改 master-config.yaml 文件时,您必须重启 master 才能使更改生效。请参阅重启 OpenShift Container Platform 服务

7.6.1. 准入控制配置

Expand
表 7.1. 准入控制配置参数
参数名称描述

AdmissionConfig

包含 准入插件 配置。OpenShift Container Platform 具有可在创建或修改 API 对象时触发的准入控制器插件的可配置列表。此选项允许您覆盖默认插件列表;例如,禁用一些插件、添加其他插件、更改顺序以及指定配置。插件及其配置列表都可从 Ansible 控制。

APIServerArguments

键值对将直接传递给与 API 服务器的命令行参数匹配的 Kube API 服务器。它们不会被迁移,但如果您引用了不存在服务器的值,则不会启动。这些值可能会覆盖 KubernetesMasterConfig 中的其他设置,这可能会导致无效的配置。使用带有 event-ttl 值的 APIServerArguments 将事件存储在 etcd 中。默认值为 2h,但可将其设置为 less 以防止内存增长:

apiServerArguments:
  event-ttl:
  - "15m"
Copy to Clipboard Toggle word wrap

控制器参数

键值对将直接传递给与控制器管理器的命令行参数匹配的 Kube 控制器管理器。它们不会被迁移,但如果您引用了不存在服务器的值,则不会启动。这些值可能会覆盖 KubernetesMasterConfig 中的其他设置,这可能会导致无效的配置。

DefaultAdmissionConfig

用于启用或禁用各种准入插件。当此类型作为 pluginConfig 下的 configuration 对象以及准入插件支持时,这会导致启用 默认的 准入插件。

PluginConfig

允许为每个准入插件指定配置文件。

PluginOrderOverride

master 上将安装的准入插件名称列表。订购非常显著。如果为空,则使用默认插件列表。

SchedulerArguments

键值对将直接传递给与调度程序的命令行参数匹配的 Kube 调度程序。它们不会被迁移,但如果您引用了不存在服务器的值,则不会启动。这些值可能会覆盖 KubernetesMasterConfig 中的其他设置,这可能会导致无效的配置。

7.6.2. 资产配置

Expand
表 7.2. 资产配置参数
参数名称描述

AssetConfig

如果存在,则资产服务器会根据定义的参数启动。例如:

assetConfig:
  logoutURL: ""
  masterPublicURL: https://master.ose32.example.com:8443
  publicURL: https://master.ose32.example.com:8443/console/
  servingInfo:
    bindAddress: 0.0.0.0:8443
    bindNetwork: tcp4
    certFile: master.server.crt
    clientCA: ""
    keyFile: master.server.key
    maxRequestsInFlight: 0
    requestTimeoutSeconds: 0
Copy to Clipboard Toggle word wrap

corsAllowedOrigins

要使用其他主机名从 web 应用访问 API 服务器,您必须通过将配置字段中的 corsAllowedOrigins 指定 corsAllowedOrigins 或在 openshift start 中指定 --cors-allowed-origins 选项来列入主机名。不会对值进行固定或转义。如需示例用法,请参阅 Web 控制台

DisabledFeatures

不应启动的功能列表。您可能想将其设置为 null。不太可能每个人都希望手动禁用功能,不建议这样做。

扩展

从子上下文下资产服务器文件系统提供服务的文件。

扩展开发

当设置为 true 时,告诉资产服务器为每个请求重新载入扩展脚本和样式表,而不是只在启动时使用。它使您可以开发扩展,无需每次更改重启服务器。

ExtensionProperties

key-(string)和 value-(字符串)对,这些对将注入到全局变量 OPENSHIFT_EXTENSION_PROPERTIES 下。

ExtensionScripts

Web 控制台加载时,资产服务器文件中的文件路径作为脚本加载。

ExtensionStylesheets

Web 控制台加载时,资产服务器上的文件路径以作为风格的表加载。

LoggingPublicURL

用于日志记录的公共端点(可选)。

LogoutURL

在登出 Web 控制台后将 Web 浏览器重定向到的一个可选的绝对 URL。如果未指定,则会显示内置注销页面。

MasterPublicURL

Web 控制台如何访问 OpenShift Container Platform 服务器。

MetricsPublicURL

指标的公共端点(可选)。

PublicURL

资产服务器的 URL。

7.6.3. 认证和授权配置

Expand
表 7.3. 认证和授权参数
参数名称描述

authConfig

包含身份验证和授权配置选项。

AuthenticationCacheSize

指明应缓存多少个验证结果。如果为 0,则使用默认的缓存大小。

AuthorizationCacheTTL

表示应缓存授权结果的时长。它接受有效的持续时间字符串(例如:"5m").如果为空,则获得默认超时。如果为 0 (例如"0m"), 禁用缓存。

7.6.4. Controller 配置

Expand
表 7.4. 控制器配置参数
参数名称描述

Controllers

应该启动的控制器列表。如果设置为 none,则不会自动启动任何控制器。默认值为 *,它将启动所有控制器。当使用 * 时,您可以通过在其名称前加上 - 来排除控制器。此时无法识别其他值。

ControllerLeaseTTL

启用控制器选择,指示 master 在控制器启动并在该值定义的秒数内尝试获取租期。将此值设置为非负值会强制 pauseControllers=true。这个值默认为 off(0 或 omitted),控制器选择可以使用 -1 来禁用控制器选择。

PauseControllers

指示 master 不会自动启动控制器,而是等待接收通知到服务器,然后再启动它们。

7.6.5. etcd 配置

Expand
表 7.5. etcd 配置参数
参数名称描述

Address

advertised host:port 用于客户端连接到 etcd。

etcdClientInfo

包含有关如何连接到 etcd 的信息。指定 etcd 是否作为嵌入式或非嵌入运行,以及主机。其余的配置由 Ansible 清单处理。例如:

etcdClientInfo:
  ca: ca.crt
  certFile: master.etcd-client.crt
  keyFile: master.etcd-client.key
  urls:
  - https://m1.aos.example.com:4001
Copy to Clipboard Toggle word wrap

etcdConfig

如果存在,etcd 会根据定义的参数启动。例如:

etcdConfig:
  address: master.ose32.example.com:4001
  peerAddress: master.ose32.example.com:7001
  peerServingInfo:
    bindAddress: 0.0.0.0:7001
    certFile: etcd.server.crt
    clientCA: ca.crt
    keyFile: etcd.server.key
  servingInfo:
    bindAddress: 0.0.0.0:4001
    certFile: etcd.server.crt
    clientCA: ca.crt
    keyFile: etcd.server.key
  storageDirectory: /var/lib/origin/openshift.local.etcd
Copy to Clipboard Toggle word wrap

etcdStorageConfig

包含 API 资源如何在 etcd 中存储的信息。这些值只有在 etcd 是集群的后备存储时才相关。

KubernetesStoragePrefix

etcd 中的路径,Kubernetes 资源将在其下作为根(root) 。如果更改,这个值将意味着 etcd 中的现有对象将不再存在。默认值为 kubernetes.io

KubernetesStorageVersion

etcd 中的 Kubernetes 资源应该被序列化为的 API 版本。当从 etcd 读取的集群的所有客户端都有相应的代码才能读取新版本时,这个值不应该为高级。

OpenShiftStoragePrefix

OpenShift Container Platform 资源根到的 etcd 中的路径。如果更改,这个值将意味着 etcd 中的现有对象将不再存在。默认值为 openshift.io

OpenShiftStorageVersion

etcd 中 OS 资源的 API 版本应序列化为。当从 etcd 读取的集群的所有客户端都有相应的代码才能读取新版本时,这个值不应该为高级。

PeerAddress

etcd 的对等点连接的广告 host:port。

PeerServingInfo

描述如何开始为 etcd peer 提供服务。

ServingInfo

描述如何开始服务。例如:

servingInfo:
  bindAddress: 0.0.0.0:8443
  bindNetwork: tcp4
  certFile: master.server.crt
  clientCA: ca.crt
  keyFile: master.server.key
  maxRequestsInFlight: 500
  requestTimeoutSeconds: 3600
Copy to Clipboard Toggle word wrap

StorageDir

etcd 存储目录的路径。

7.6.6. 授权配置

Expand
表 7.6. 授予配置参数
参数名称描述

GrantConfig

描述如何处理补贴。

GrantHandlerAuto

自动批准客户端授权请求。

GrantHandlerDeny

自动拒绝客户端授权请求。

GrantHandlerPrompt

提示用户批准新的客户端授权请求。

Method

决定在 OAuth 客户端请求授权时使用的默认策略。只有特定的 OAuth 客户端不提供自己策略,则使用这种方法。有效的授权处理方法有:

  • auto:始终批准授权请求,对受信任的客户端很有用
  • prompt: 提示用户输入授权请求的批准,对第三方客户端很有用
  • deny:始终拒绝授权请求,对黑名单的客户端很有用

7.6.7. 镜像配置

Expand
表 7.7. 镜像配置参数
参数名称描述

Format

为系统组件构建的名称格式。

Latest

决定是否将从 registry 中拉取 latest 标签。

7.6.8. 镜像策略配置

Expand
表 7.8. 镜像策略配置参数
参数名称描述

DisableScheduledImport

允许禁用镜像的调度后台导入。

MaxImagesBulkImportedPerRepository

控制用户执行 Docker 存储库批量导入时导入的镜像数量。此数字默认为 5,以防止用户意外导入大量镜像。设置 -1 代表没有限制。

MaxScheduledImageImportsPerMinute

每分钟将在后台导入的最大调度镜像流数。默认值为 60。

ScheduledImageImportMinimumIntervalSeconds

针对上游存储库检查调度后台导入的镜像流时可达最少的秒数。默认值为 15 分钟。

AllowedRegistriesForImport

限制普通用户可从中导入镜像的 Docker docker。将此列表设置为您信任包含有效 Docker 镜像且希望应用程序能够从中导入的 registry。有权通过 API 创建镜像或 ImageStreamMappings 的用户不受此策略的影响 - 通常只有管理员或系统集成将具有这些权限。

AdditionalTrustedCA

指定到 PEM 编码文件的文件路径,它列出了在镜像流导入期间应被信任的额外证书颁发机构。此文件需要可以被 API 服务器进程访问。根据集群安装的方式,这可能需要将文件挂载到 API 服务器 pod 中。

InternalRegistryHostname

设置默认内部镜像 registry 的主机名。该值必须采用 hostname[:port] 格式。为实现向后兼容,用户仍然可以使用 OPENSHIFT_DEFAULT_REGISTRY 环境变量,但此设置会覆盖环境变量。当设定此参数时,内部 registry 还需要设置其主机名。如需了解更多详细信息,请参阅设置 registry 主机名

ExternalRegistryHostname

ExternalRegistryHostname 设置默认外部镜像 registry 的主机名。只有在镜像 registry 对外公开时才应设置外部主机名。该值用于 ImageStreams 中的 publicDockerImageRepository 字段。该值必须采用 hostname[:port] 格式。

7.6.9. Kubernetes 的主配置

Expand
表 7.9. Kubernetes 主配置参数
参数名称描述

APILevels

应该在启动时启用的 API 级别的列表 v1 作为示例。

DisabledAPIGroupVersions

组映射到应禁用的版本(或 *)的映射。

KubeletClientInfo

包含有关如何连接到 kubelet 的信息。

KubernetesMasterConfig

包含如何连接到 kubelet 的 KubernetesMasterConfig 的信息。如果存在,则使用此流程启动 kubernetes master。

MasterCount

应正在运行的预期 master 数量。这个值默认为 1,可以被设置为正整数,或者设置为 -1,这表示这是集群的一部分。

MasterIP

Kubernetes 资源的公共 IP 地址。如果为空,来自 net.InterfaceAddrs 的第一个结果将被使用。

MasterKubeConfig

描述如何将此节点连接到 master 的 .kubeconfig 文件的文件名。

PodEvictionTimeout

控制删除失败节点上的 pod 的宽限期。它需要有效的持续时间字符串。如果为空,您会收到默认的 pod 驱除超时。默认值为 5m0s

ProxyClientInfo

指定代理到 pod 时使用的客户端证书/密钥。例如:

  proxyClientInfo:
    certFile: master.proxy-client.crt
    keyFile: master.proxy-client.key
Copy to Clipboard Toggle word wrap

ServicesNodePortRange

用于分配主机上服务公共端口的范围。默认 30000-32767。

ServicesSubnet

用于分配服务 IP 的子网。

StaticNodeNames

静态已知的节点列表。

7.6.10. 网络配置

仔细选择以下参数中的 CIDR,因为 IPv4 地址空间由节点的所有用户共享。OpenShift Container Platform 为自己的使用保留 IPv4 地址空间中的 CIDR,并为外部用户和集群间共享的地址保留来自 IPv4 地址空间的 CIDR。

Expand
表 7.10. 网络配置参数
参数名称描述

ClusterNetworkCIDR

指定全局覆盖网络的 L3 空间的 CIDR 字符串。这为集群网络的内部使用保留。

externalIPNetworkCIDRs

控制服务外部 IP 字段可接受哪些值。如果为空,则不能设置 externalIP。它可以包含检查访问的 CIDR 列表。如果 CIDR 的前缀为 !,则该 CIDR 中的 IP 将被拒绝。首先应用拒绝,然后针对其中一个允许的 CIDR 检查的 IP。为了安全起见,您必须确保此范围不会与节点、Pod 或服务 CIDR 重叠。

HostSubnetLength

分配给每一主机子网的位数。例如,8 表示主机上的 /24 网络。

ingressIPNetworkCIDR

控制为裸机上的类型为 LoadBalancer 的服务分配入口 IP 的范围。它可以包含从其中分配的一个 CIDR。默认情况下,配置了 172.46.0.0/16。为安全起见,您应该确保此范围与为外部 IP、节点、Pod 或服务保留的 CIDR 重叠。

HostSubnetLength

分配给每一主机子网的位数。例如,8 表示主机上的 /24 网络。

NetworkConfig

传递给 compiled-in-network 的插件。此处的许多选项可以在 Ansible 清单中控制。

  • NetworkPluginName (字符串)
  • ClusterNetworkCIDR (字符串)
  • hostSubnetLength (无符号整数)
  • ServiceNetworkCIDR (字符串)
  • externalIPNetworkCIDRs (字符串数组):控制服务外部 IP 字段可以接受哪些值。如果为空,则不能设置外部 IP。它可以包含检查访问的 CIDR 列表。如果 CIDR 的前缀为 !,则该 CIDR 中的 IP 会拒绝。首先应用拒绝,然后针对其中一个允许的 CIDR 检查 IP。为了安全起见,您应该确保此范围与节点、Pod 或服务 CIDR 不重叠。

例如:

networkConfig:
  clusterNetworks
  - cidr: 10.3.0.0/16
    hostSubnetLength: 8
  networkPluginName: example/openshift-ovs-subnet
# serviceNetworkCIDR must match kubernetesMasterConfig.servicesSubnet
  serviceNetworkCIDR: 179.29.0.0/16
Copy to Clipboard Toggle word wrap

NetworkPluginName

要使用的网络插件的名称。

ServiceNetwork

用于指定服务网络的 CIDR 字符串。

7.6.11. OAuth 身份验证配置

Expand
表 7.11. OAuth 配置参数
参数名称描述

AlwaysShowProviderSelection

强制供应商选择页面,即使只有一个提供程序,也要呈现。

AssetPublicURL

用于构建有效客户端重定向 URL 用于外部访问。

Error

一个包含 go 模板的文件路径,用于在身份验证期间呈现错误页面,或授权流(如果没有指定),则会使用默认错误页面。

IdentityProviders

订购用户以识别自身的方式列表。

Login

包含用来呈现登录页面的 go 模板的文件路径。如果未指定,则使用默认登录页面。

MasterCA

用于验证到 MasterURL 的 TLS 连接的 CA。

MasterPublicURL

用于构建有效客户端重定向 URL 用于外部访问。

MasterURL

用于让服务器对服务器调用来交换访问令牌的授权代码。

OAuthConfig

如果存在,/oauth 端点会根据定义的参数启动。例如:

oauthConfig:
  assetPublicURL: https://master.ose32.example.com:8443/console/
  grantConfig:
    method: auto
  identityProviders:
  - challenge: true
    login: true
    mappingMethod: claim
    name: htpasswd_all
    provider:
      apiVersion: v1
      kind: HTPasswdPasswordIdentityProvider
      file: /etc/origin/openshift-passwd
  masterCA: ca.crt
  masterPublicURL: https://master.ose32.example.com:8443
  masterURL: https://master.ose32.example.com:8443
  sessionConfig:
    sessionMaxAgeSeconds: 3600
    sessionName: ssn
    sessionSecretsFile: /etc/origin/master/session-secrets.yaml
  tokenConfig:
    accessTokenMaxAgeSeconds: 86400
    authorizeTokenMaxAgeSeconds: 500
Copy to Clipboard Toggle word wrap

OAuthTemplates

允许自定义登录页面等页面。

ProviderSelection

包含用来呈现提供程序选择页面的 go 模板的文件路径。如果未指定,则使用默认供应商选择页面。

SessionConfig

包含有关配置会话的信息。

Templates

允许您自定义登录页面等页面。

TokenConfig

包含授权和访问令牌的选项。

7.6.12. 项目配置

Expand
表 7.12. 项目配置参数
参数名称描述

DefaultNodeSelector

包含默认项目节点选择器。

ProjectConfig

包含有关项目创建和默认值的信息:

  • defaultNodeSelector (字符串):包含默认项目节点选择器。
  • projectRequestMessage (字符串):当用户无法通过 projectrequest API 端点请求一个项目时,向用户显示的字符串。
  • ProjectRequestTemplate (字符串):响应 projectrequest 以创建项目时使用的模板。采用 <namespace>/<template> 格式。它是可选的;如果没有指定,则使用默认模板。
  • SecurityAllocator:控制为项目自动分配 UID 和 MCS 标签。如果为 nil,则禁用分配:

    • mcsAllocatorRange (字符串):定义将分配给命名空间的 MCS 类别范围。格式为 <prefix>/<numberOfLabels>[,<maxCategory>]。默认值为 s0/2,并从 c0 → c1023 分配,这表示总计有 535k 标签。如果此值在启动后改变,新项目可能会接收已经分配给其他项目的标签。前缀可以是任何有效的 SELinux 术语集合(包括 user、role 和 type)。但是,使用默认前缀可让服务器自动设置它们。例如,s0:/2 分配 s0:c0,c0 到 s0:c511,c511 的标签,而 s0:/2,512 会将标签从 s0:c0,c0,c0 分配给 s0:c511,c511,511。
    • mcsLabelsPerProject (整数):定义每个项目要保留的标签数。默认值是 5,用于匹配默认 UID 和 MCS 范围。
    • uidAllocatorRange (字符串):定义自动分配给项目的 Unix 用户 ID(UID),以及每个命名空间获取的块的大小。例如,1000-1999/10 将为每个命名空间分配十个 UID,并能够在用尽空间前分配最多 100 个块。默认值为在 10k 块中分配 10 亿到 20 亿的块,这是用户命名空间启动时为容器镜像的预期范围范围。

ProjectRequestMessage

当用户无法通过项目请求 API 端点来请求项目时向用户显示的字符串。

ProjectRequestTemplate

响应 projectrequest 以创建项目时使用的模板。它采用 namespace/template 格式,它是可选的。如果没有指定,则使用默认模板。

7.6.13. 调度程序配置

Expand
表 7.13. 调度程序配置参数
参数名称描述

SchedulerConfigFile

指向描述如何设置调度程序的文件。如果为空,您可以获得默认的调度规则

7.6.14. 安全分配器配置

Expand
表 7.14. 安全分配器参数
参数名称描述

MCSAllocatorRange

定义将分配给命名空间的 MCS 类别范围。格式为 <prefix>/<numberOfLabels>[,<maxCategory>]。默认值为 s0/2,并从 c0 到 c1023 分配,这表示有总计 535k 个标签(1024 选择 2 ~ 535k)。如果此值在启动后改变,新项目可能会接收已经分配给其他项目的标签。前缀可以是任何有效的 SELinux 术语集合(包括 user、role 和 type),虽然它们保留为默认值,但允许服务器自动设置它们。

SecurityAllocator

控制为项目自动分配 UID 和 MCS 标签。如果为 nil,则禁用分配。

UIDAllocatorRange

定义会自动分配给项目的 Unix 用户 ID(UID),以及每个命名空间获取的块的大小。例如,1000-1999/10 将根据每个命名空间分配十个 UID,并在用尽空间前分配最多 100 个块。默认值为在 10k 块中分配 10 亿到 20 亿的块(这是在用户命名空间启动后使用范围容器镜像的预期大小)。

7.6.15. 服务帐户配置

Expand
表 7.15. 服务帐户配置参数
参数名称描述

LimitSecretReferences

控制是否允许服务帐户在没有显式引用命名空间中引用任何 secret。

ManagedNames

在每个命名空间中创建的服务帐户名称列表。如果没有指定名称,则不会启动 ServiceAccountsController

MasterCA

用于验证 TLS 连接到主主机的 CA。服务帐户控制器会自动将此文件的内容注入到 pod 中,以便它们能够验证与主控机的连接。

PrivateKeyFile

包含 PEM 编码私有 RSA 密钥的文件,用于签署服务帐户令牌。如果没有指定私钥,则不会启动服务帐户 TokensController

PublicKeyFiles

文件列表,各自包含 PEM 编码的公共 RSA 密钥。如果有任何文件包含私钥,则使用密钥的公钥部分。公钥列表用于验证所提供的服务帐户令牌。每个密钥按顺序尝试,直到列表耗尽或验证成功为止。如果没有指定密钥,则不会使用服务帐户身份验证。

ServiceAccountConfig

包含与服务帐户相关的选项:

  • LimitSecretReferences (boolean):控制是否允许服务帐户在没有显式引用命名空间中引用任何 secret。
  • ManagedNames (字符串):在每个命名空间中创建的服务帐户名称列表。如果没有指定名称,则不会启动 ServiceAccountsController
  • MasterCA (字符串):用于验证 TLS 连接到主设备的证书颁发机构。服务帐户控制器会自动将此文件的内容注入到 pod 中,以便它们能够验证与主控机的连接。
  • privateKeyFile (字符串):包含 PEM 编码的私有 RSA 密钥,用于签署服务帐户令牌。如果没有指定私钥,则不会启动服务帐户 TokensController
  • publicKeyFiles (字符串):文件列表,各自包含 PEM 编码的公共 RSA 密钥。如果有任何文件包含私钥,OpenShift Container Platform 将使用密钥的公钥部分。公钥列表用于验证服务帐户令牌 ; 每个密钥按顺序尝试,直到列表耗尽或验证成功为止。如果没有指定密钥,则无法使用服务帐户身份验证。

7.6.16. 服务信息配置

Expand
表 7.16. 服务信息配置参数
参数名称描述

AllowRecursiveQueries

允许主服务器上的 DNS 服务器以递归方式应答查询。请注意,打开解析器可用于 DNS 模糊攻击,并且主 DNS 不应该被公共网络访问。

BindAddress

要服务的 ip:port

BindNetwork

控制导入镜像的限值和行为。

CertFile

包含 PEM 编码证书的文件。

CertInfo

用于提供安全流量的 TLS 证书信息。

ClientCA

您识别传入客户端证书的所有签名人的证书捆绑包。

dnsConfig

如果存在,则根据定义的参数启动 DNS 服务器。例如:

dnsConfig:
  bindAddress: 0.0.0.0:8053
  bindNetwork: tcp4
Copy to Clipboard Toggle word wrap

DNSDomain

包含域后缀。

DNSIP

包含 IP。

KeyFile

包含由 CertFile 指定的证书的 PEM 编码私钥的文件。

MasterClientConnectionOverrides

为用于连接 master 的客户端连接提供覆盖。这个参数不被支持。要设置 QPS 和 burst 值,请参阅设置节点 QPS 和 Burst 值

MaxRequestsInFlight

允许到服务器的并发请求数。如果零,则不限制。

NamedCertificates

用于保护到特定主机名请求的证书列表。

RequestTimeoutSecond

请求超时前的秒数。默认值为 60 分钟。如果 -1,请求没有限制。

ServingInfo

资产的 HTTP 服务信息。

7.6.17. 卷配置

Expand
表 7.17. 卷配置参数
参数名称描述

DynamicProvisioningEnabled

启用或禁用动态置备的布尔值。默认为 true

FSGroup

为每个 FSGroup 在每个节点上启用 本地存储配额。目前,这仅适用于 emptyDir 卷,如果底层 volumeDirectory 位于 XFS 文件系统中。

MasterVolumeConfig

包含用于在 master 节点上配置卷插件的选项。

NodeVolumeConfig

包含用于在节点上配置卷的选项。

VolumeConfig

包含用于在节点中配置卷插件的选项:

  • DynamicProvisioningEnabled (布尔值):默认值为 true,并在 false 时关闭动态置备。

VolumeDirectory

卷所在的目录。使用 openshift_node_group_data_dir 参数更改此值。

7.6.18. 基本审计

审计提供一组安全相关的按时间排序的记录,记录各个用户、管理员或其他系统组件影响系统的一系列活动。

审计在 API 服务器级别运作,记录所有传入到服务器的请求。每个审计日志包含两个条目:

  1. 请求行中包含:

    1. 用于匹配响应行的唯一 ID(参见 #2)
    2. 请求的源 IP
    3. 被调用的 HTTP 方法
    4. 调用该操作的原始用户
    5. 操作的模拟用户(self 表示自己)
    6. 操作的模拟组(lookup 表示用户的组)
    7. 请求的命名空间或 <none>
    8. 请求的 URI
  2. 响应行中包括:

    1. #1 中的唯一 ID
    2. 响应代码

用户 admin 询问 pod 列表的输出示例:

AUDIT: id="5c3b8227-4af9-4322-8a71-542231c3887b" ip="127.0.0.1" method="GET" user="admin" as="<self>" asgroups="<lookup>" namespace="default" uri="/api/v1/namespaces/default/pods"
AUDIT: id="5c3b8227-4af9-4322-8a71-542231c3887b" response="200"
Copy to Clipboard Toggle word wrap
7.6.18.1. 启用基本审计

以下流程在安装后启用基本审计。

注意

高级审计必须在安装过程中启用。

  1. 编辑所有 master 节点上的 /etc/origin/master/master-config.yaml 文件,如下例所示:

    auditConfig:
      auditFilePath: "/var/log/origin/audit-ocp.log"
      enabled: true
      maximumFileRetentionDays: 14
      maximumFileSizeMegabytes: 500
      maximumRetainedFiles: 15
    Copy to Clipboard Toggle word wrap
  2. 重启集群中的 API pod。

    # /usr/local/bin/master-restart api
    Copy to Clipboard Toggle word wrap

要在安装过程中启用基本审计,请在清单文件中添加以下变量声明。根据情况调整值。

openshift_master_audit_config={"enabled": true, "auditFilePath": "/var/lib/origin/openpaas-oscp-audit.log", "maximumFileRetentionDays": 14, "maximumFileSizeMegabytes": 500, "maximumRetainedFiles": 5}
Copy to Clipboard Toggle word wrap

审计配置采用以下参数:

Expand
表 7.18. Audit 配置参数
参数名称描述

enabled

启用或禁用审计日志的布尔值。默认为 false

auditFilePath

请求应记录到的文件路径。如果没有设置,日志会被输出到 master 日志中。

maximumFileRetentionDays

根据文件名中编码的时间戳,指定用于保留旧审计日志文件的最大天数。

maximumRetainedFiles

指定要保留的旧审计日志文件的最大数量。

maximumFileSizeMegabytes

在轮转日志文件前,指定日志文件的最大大小(以 MB 为单位)。默认值为 100MB。

Audit 配置示例

auditConfig:
  auditFilePath: "/var/log/origin/audit-ocp.log"
  enabled: true
  maximumFileRetentionDays: 14
  maximumFileSizeMegabytes: 500
  maximumRetainedFiles: 15
Copy to Clipboard Toggle word wrap

当您定义 auditFilePath 参数时,如果该目录不存在,则会创建该目录。

7.6.19. 高级审计

高级审计功能对 基本审计功能 进行了一些改进,包括精细的事件过滤和多个输出后端。

要启用高级审计功能,您可以创建一个审计策略文件,并在 openshift_master_audit_configopenshift_master_audit_policyfile 参数中指定以下值:

openshift_master_audit_config={"enabled": true, "auditFilePath": "/var/log/origin/audit-ocp.log", "maximumFileRetentionDays": 14, "maximumFileSizeMegabytes": 500, "maximumRetainedFiles": 5, "policyFile": "/etc/origin/master/adv-audit.yaml", "logFormat":"json"}
openshift_master_audit_policyfile="/<path>/adv-audit.yaml"
Copy to Clipboard Toggle word wrap
重要

您必须在安装集群前创建 adv-audit.yaml 文件,并指定其在集群清单文件中的位置。

下表包含您可以使用的附加选项。

Expand
表 7.19. 高级审计配置参数
参数名称描述

policyFile

定义审计策略配置的文件的路径。

policyConfiguration

嵌入式审计策略配置。

logFormat

指定保存的审计日志的格式。允许的值是 legacy (基本审计中使用的格式)和 json

webHookKubeConfig

定义审计 Webhook 配置的 .kubeconfig 格式文件的路径,事件发送到其中。

webHookMode

指定发送审计事件的策略。允许的值是 block (块处理另一个事件,直到之前已完全处理)和 batch (以批处理的形式缓冲事件并交付)。

重要

要启用高级审计功能,您必须提供 policyFile policyConfiguration 描述审计规则:

Audit 策略配置示例

apiVersion: audit.k8s.io/v1beta1
kind: Policy
rules:

  # Do not log watch requests by the "system:kube-proxy" on endpoints or services
  - level: None 
1

    users: ["system:kube-proxy"] 
2

    verbs: ["watch"] 
3

    resources: 
4

    - group: ""
      resources: ["endpoints", "services"]

  # Do not log authenticated requests to certain non-resource URL paths.
  - level: None
    userGroups: ["system:authenticated"] 
5

    nonResourceURLs: 
6

    - "/api*" # Wildcard matching.
    - "/version"

  # Log the request body of configmap changes in kube-system.
  - level: Request
    resources:
    - group: "" # core API group
      resources: ["configmaps"]
    # This rule only applies to resources in the "kube-system" namespace.
    # The empty string "" can be used to select non-namespaced resources.
    namespaces: ["kube-system"] 
7


  # Log configmap and secret changes in all other namespaces at the metadata level.
  - level: Metadata
    resources:
    - group: "" # core API group
      resources: ["secrets", "configmaps"]

  # Log all other resources in core and extensions at the request level.
  - level: Request
    resources:
    - group: "" # core API group
    - group: "extensions" # Version of group should NOT be included.

  # A catch-all rule to log all other requests at the Metadata level.
  - level: Metadata 
8


  # Log login failures from the web console or CLI. Review the logs and refine your policies.
  - level: Metadata
    nonResourceURLs:
    - /login* 
9

    - /oauth* 
10
Copy to Clipboard Toggle word wrap

1 8
每个事件都可以记录四个可能级别:
  • None - 不记录与此规则匹配的日志事件。
  • Metadata - 日志请求元数据(请求用户、时间戳、资源、操作等),但不请求或响应正文。这与基本审计中使用的级别相同。
  • Request - 日志记录事件元数据和请求正文,但不包括响应的正文。
  • RequestResponse - 日志记录事件元数据、请求和响应正文。
2
适用于规则的用户列表。一个空列表表示每个用户。
3
此规则应用到的操作动词列表。一个空列表表示每个动词。这是与 API 请求关联的 Kubernetes 动词(包括 get, list, watch, create, update, patch, delete, deletecollection, 和 proxy)。
4
适用于该规则的资源列表。一个空列表表示每个资源。每个资源都被指定为分配给的组(例如,Kubernetes 核心 API、批处理、build.openshift.io 等)的空项,以及该组中的资源列表。
5
适用于该规则的组列表。一个空列表表示每个组。
6
规则应用到的非资源 URL 列表。
7
适用于规则的命名空间列表。一个空列表表示每个命名空间。
9
Web 控制台使用的端点。
10
CLI 使用的端点。

如需有关高级审计的更多信息,请参阅 Kubernetes 文档

7.6.20. 为 etcd 指定 TLS 密码

您可以指定在 master 和 etcd 服务器之间的通信时使用的 支持的 TLS 密码

  1. 在每个 etcd 节点上,升级 etcd:

    # yum update etcd iptables-services
    Copy to Clipboard Toggle word wrap
  2. 确认 etcd 版本为 3.2.22 或更高版本:

    # etcd --version
    etcd Version: 3.2.22
    Copy to Clipboard Toggle word wrap
  3. 在每个 master 主机上,指定在 /etc/origin/master/master-config.yaml 文件中启用的密码:

    servingInfo:
      ...
      minTLSVersion: VersionTLS12
      cipherSuites:
      - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
      - TLS_RSA_WITH_AES_256_CBC_SHA
      - TLS_RSA_WITH_AES_128_CBC_SHA
    ...
    Copy to Clipboard Toggle word wrap
  4. 在每个 master 主机上,重启 master 服务:

    # master-restart api
    # master-restart controllers
    Copy to Clipboard Toggle word wrap
  5. 确认应用了密码。例如,对于 TLSv1.2 密码 ECDHE-RSA-AES128-GCM-SHA256,请运行以下命令:

    # openssl s_client -connect etcd1.example.com:2379 
    1
    
    CONNECTED(00000003)
    depth=0 CN = etcd1.example.com
    verify error:num=20:unable to get local issuer certificate
    verify return:1
    depth=0 CN = etcd1.example.com
    verify error:num=21:unable to verify the first certificate
    verify return:1
    139905367488400:error:14094412:SSL routines:ssl3_read_bytes:sslv3 alert bad certificate:s3_pkt.c:1493:SSL alert number 42
    139905367488400:error:140790E5:SSL routines:ssl23_write:ssl handshake failure:s23_lib.c:177:
    ---
    Certificate chain
     0 s:/CN=etcd1.example.com
       i:/CN=etcd-signer@1529635004
    ---
    Server certificate
    -----BEGIN CERTIFICATE-----
    MIIEkjCCAnqgAwIBAgIBATANBgkqhkiG9w0BAQsFADAhMR8wHQYDVQQDDBZldGNk
    ........
    ....
    eif87qttt0Sl1vS8DG1KQO1oOBlNkg==
    -----END CERTIFICATE-----
    subject=/CN=etcd1.example.com
    issuer=/CN=etcd-signer@1529635004
    ---
    Acceptable client certificate CA names
    /CN=etcd-signer@1529635004
    Client Certificate Types: RSA sign, ECDSA sign
    Requested Signature Algorithms: RSA+SHA256:ECDSA+SHA256:RSA+SHA384:ECDSA+SHA384:RSA+SHA1:ECDSA+SHA1
    Shared Requested Signature Algorithms: RSA+SHA256:ECDSA+SHA256:RSA+SHA384:ECDSA+SHA384:RSA+SHA1:ECDSA+SHA1
    Peer signing digest: SHA384
    Server Temp Key: ECDH, P-256, 256 bits
    ---
    SSL handshake has read 1666 bytes and written 138 bytes
    ---
    New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
    Server public key is 2048 bit
    Secure Renegotiation IS supported
    Compression: NONE
    Expansion: NONE
    No ALPN negotiated
    SSL-Session:
        Protocol  : TLSv1.2
        Cipher    : ECDHE-RSA-AES128-GCM-SHA256
        Session-ID:
        Session-ID-ctx:
        Master-Key: 1EFA00A91EE5FC5EDDCFC67C8ECD060D44FD3EB23D834EDED929E4B74536F273C0F9299935E5504B562CD56E76ED208D
        Key-Arg   : None
        Krb5 Principal: None
        PSK identity: None
        PSK identity hint: None
        Start Time: 1529651744
        Timeout   : 300 (sec)
        Verify return code: 21 (unable to verify the first certificate)
    Copy to Clipboard Toggle word wrap
    1
    etcd1.example.com 是 etcd 主机的名称。

7.7. 节点配置文件

在安装过程中,OpenShift Container Platform 为每类节点组在 openshift-node 项目中创建一个 configmap:

  • node-config-master
  • node-config-infra
  • node-config-compute
  • node-config-all-in-one
  • node-config-master-infra

若要对现有节点进行配置更改,请编辑相应的配置映射。各个节点上的 同步 pod 监视配置映射的变化。在安装过程中,使用 sync Daemonsets 和一个 /etc/origin/node/node-config.yaml 文件(节点的配置参数所在的文件)创建的同步 pod 被添加到每个节点。当同步 pod 检测到配置映射更改时,它会在该节点组的所有节点上更新 node-config.yaml,并在适当的节点上重启 atomic-openshift-node.service

$ oc get cm -n openshift-node
Copy to Clipboard Toggle word wrap

输出示例

NAME                       DATA      AGE
node-config-all-in-one     1         1d
node-config-compute        1         1d
node-config-infra          1         1d
node-config-master         1         1d
node-config-master-infra   1         1d
Copy to Clipboard Toggle word wrap

node-config-compute 组的配置映射示例

apiVersion: v1
authConfig:      
1

  authenticationCacheSize: 1000
  authenticationCacheTTL: 5m
  authorizationCacheSize: 1000
  authorizationCacheTTL: 5m
dnsBindAddress: 127.0.0.1:53
dnsDomain: cluster.local
dnsIP: 0.0.0.0               
2

dnsNameservers: null
dnsRecursiveResolvConf: /etc/origin/node/resolv.conf
dockerConfig:
  dockerShimRootDirectory: /var/lib/dockershim
  dockerShimSocket: /var/run/dockershim.sock
  execHandlerName: native
enableUnidling: true
imageConfig:
  format: registry.reg-aws.openshift.com/openshift3/ose-${component}:${version}
  latest: false
iptablesSyncPeriod: 30s
kind: NodeConfig
kubeletArguments: 
3

  bootstrap-kubeconfig:
  - /etc/origin/node/bootstrap.kubeconfig
  cert-dir:
  - /etc/origin/node/certificates
  cloud-config:
  - /etc/origin/cloudprovider/aws.conf
  cloud-provider:
  - aws
  enable-controller-attach-detach:
  - 'true'
  feature-gates:
  - RotateKubeletClientCertificate=true,RotateKubeletServerCertificate=true
  node-labels:
  - node-role.kubernetes.io/compute=true
  pod-manifest-path:
  - /etc/origin/node/pods  
4

  rotate-certificates:
  - 'true'
masterClientConnectionOverrides:
  acceptContentTypes: application/vnd.kubernetes.protobuf,application/json
  burst: 40
  contentType: application/vnd.kubernetes.protobuf
  qps: 20
masterKubeConfig: node.kubeconfig
networkConfig:   
5

  mtu: 8951
  networkPluginName: redhat/openshift-ovs-subnet  
6

servingInfo:                   
7

  bindAddress: 0.0.0.0:10250
  bindNetwork: tcp4
  clientCA: client-ca.crt 
8

volumeConfig:
  localQuota:
    perFSGroup: null
volumeDirectory: /var/lib/origin/openshift.local.volumes
Copy to Clipboard Toggle word wrap

1
身份验证和授权配置选项.
2
附加到 pod 的 /etc/resolv.conf 的 IP 地址。
3
直接传递给与 Kubelet 命令行参数匹配的 Kubelet 的键值对。
4
pod 清单文件或目录的路径。目录必须包含一个或多个清单文件。OpenShift 容器平台使用清单文件在节点上创建 pod。
5
节点上的 pod 网络设置。
6
软件定义型网络(SDN)插件.为 ovs-subnet 插件设置为 redhat/openshift-ovs-subnet,为 ovs-multitenant 插件设置为 redhat/openshift-ovs-multitenant,为 ovs-networkpolicy 插件设置为 redhat/openshift-ovs-networkpolicy
7
节点的证书信息。
8
可选:PEM 编码的证书捆绑包。如果设置,则必须根据指定文件中的证书颁发机构显示并验证有效的客户端证书,然后才能检查请求标头中的用户名。
注意

不要手动修改 /etc/origin/node/node-config.yaml 文件。

节点配置文件决定了节点的资源。如需更多信息,请参阅 Cluster Administrator 指南中的 Allocating node resources 部分

7.7.1. Pod 和节点配置

Expand
表 7.20. Pod 和节点配置参数
参数名称描述

NodeConfig

完全指定的配置启动 OpenShift Container Platform 节点。

NodeName

用于标识集群中的这个特定节点的值。如果可能,则这应该是您的完全限定主机名。如果您要描述一组静态节点到 master 节点,则这个值必须与列表中的其中一个值匹配。

7.7.2. Docker 配置

Expand
表 7.21. Docker 配置参数
参数名称描述

AllowDisabledDocker

如果为 true,kubelet 将忽略 Docker 的错误。这意味着,节点可以在没有启动 docker 的机器上启动。

DockerConfig

保留 Docker 相关配置选项

ExecHandlerName

在容器中执行命令的处理程序。

7.7.3. 本地存储配置

您可以使用 XFS quota 子系统 基于 emptyDir 卷(如 secret 和配置映射)限制 emptyDir 卷和卷的大小。

要限制 XFS 文件系统中的 emptyDir 卷大小,使用 openshift-node 项目中的 node-config-compute 配置映射为每个唯一 FSGroup 配置本地卷配额。

apiVersion: kubelet.config.openshift.io/v1
kind: VolumeConfig
  localQuota: 
1

    perFSGroup: 1Gi 
2
Copy to Clipboard Toggle word wrap
1
包含控制节点上本地卷配额的选项。
2
将此值设置为代表每个 [FSGroup] 的资源数量,每个节点(如 1Gi512Mi 等)。要求 volumeDirectory 位于通过 grpquota 选项挂载的 XFS 文件系统上。匹配的安全性上下文约束 fsGroup 类型 必须设为 MustRunAs

如果没有指定 FSGroup,这表示请求与 RunAsAny 的 SCC 匹配,则会跳过配额应用程序。

注意

不要直接编辑 /etc/origin/node/volume-config.yaml 文件。该文件从 node-config-compute 配置映射创建。使用 node-config-compute 配置映射在 volume-config.yaml 文件中创建或编辑 paramaters。

kubelet 与 API 服务器进行交互的频率取决于 qps 和 burst 值。如果每个节点上运行的 pod 有限,默认值就足够了。如果节点上有足够 CPU 和内存资源,可以在 /etc/origin/node/node-config.yaml 文件中调整 qps 和 burst 值:

kubeletArguments:
  kube-api-qps:
  - "20"
  kube-api-burst:
  - "40"
Copy to Clipboard Toggle word wrap
注意

以上 qps 和 burst 值是 OpenShift Container Platform 的默认值。

Expand
表 7.22. QPS 和 Burst 配置参数
参数名称描述

kube-api-qps

Kubelet 与 APIServer 通信的 QPS 速率。默认值为 20

kube-api-burst

Kubelet 与 APIServer 通信的突发率。默认值为 40

ExecHandlerName

在容器中执行命令的处理程序。

然后,重启 OpenShift Container Platform 节点服务

7.7.5. 使用 Docker 1.9+ 并行镜像拉取(pull)

如果使用 Docker 1.9+,您可能需要考虑启用并行镜像拉取,因为默认值是一次拉取镜像。

注意

Docker 1.9 之前的数据损坏潜在的问题。但是,从 1.9 开始,崩溃问题已解决,它可以安全地切换到并行拉取。

kubeletArguments:
  serialize-image-pulls:
  - "false" 
1
Copy to Clipboard Toggle word wrap
1
更改为 true 以禁用并行拉取。这是默认配置。

7.8. 密码和其他敏感数据

对于一些身份验证配置,需要一个 LDAP bindPassword 或 OAuth clientSecret 值。这些值不是直接在主配置文件中指定,而是以环境变量、外部文件或加密文件形式提供。

环境变量示例

  bindPassword:
    env: BIND_PASSWORD_ENV_VAR_NAME
Copy to Clipboard Toggle word wrap

外部文件示例

  bindPassword:
    file: bindPassword.txt
Copy to Clipboard Toggle word wrap

加密的外部文件示例

  bindPassword:
    file: bindPassword.encrypted
    keyFile: bindPassword.key
Copy to Clipboard Toggle word wrap

为以上示例创建加密的文件和密钥文件:

$ oc adm ca encrypt --genkey=bindPassword.key --out=bindPassword.encrypted
> Data to encrypt: B1ndPass0rd!
Copy to Clipboard Toggle word wrap

仅从 Ansible 主机清单文件中列出的第一个 master 运行 oc adm 命令,默认为 /etc/ansible/hosts

警告

加密的数据仅像解密密钥一样安全。请小心谨慎,以限制文件系统权限和对密钥文件的访问。

7.9. 创建新配置文件

从头开始定义 OpenShift Container Platform 配置时,请先创建新的配置文件。

对于 master 主机配置文件,使用 openshift start 命令和 --write-config 选项来写入配置文件。对于节点主机,使用 oc adm create-node-config 命令写入配置文件。

以下命令将相关的启动配置文件、证书文件和任何其他必要的文件写入指定的 --write-config--node-dir 目录。

生成的证书文件在两年内有效,而证书颁发机构(CA)证书在五年内有效。这可以通过 --expire-days--signer-expire-days 选项进行修改,但为了安全起见,建议您不要使其大于这些值。

在指定目录中为一体化服务器(master 和一个节点)创建配置文件:

$ openshift start --write-config=/openshift.local.config
Copy to Clipboard Toggle word wrap

要在指定目录中创建 master 配置文件和其他所需的文件:

$ openshift start master --write-config=/openshift.local.config/master
Copy to Clipboard Toggle word wrap

在指定目录中创建节点配置文件和其他相关文件:

$ oc adm create-node-config \
    --node-dir=/openshift.local.config/node-<node_hostname> \
    --node=<node_hostname> \
    --hostnames=<node_hostname>,<ip_address> \
    --certificate-authority="/path/to/ca.crt" \
    --signer-cert="/path/to/ca.crt" \
    --signer-key="/path/to/ca.key"
    --signer-serial="/path/to/ca.serial.txt"
    --node-client-certificate-authority="/path/to/ca.crt"
Copy to Clipboard Toggle word wrap

在创建节点配置文件时,--hostnames 选项接受以逗号分隔的每个主机名或 IP 地址列表,用于有效服务器证书。

7.10. 使用配置文件启动服务器

将主控机和节点配置文件修改为您的规格后,您可以在启动服务器时将它们指定为参数来使用。如果您指定配置文件,则您传递的其他命令行选项都不会被遵守。

注意

要修改集群中的节点,请根据需要更新节点配置映射。不要手动编辑 node-config.yaml 文件。

  1. 使用 master 配置文件启动 master 服务器:

    $ openshift start master \
        --config=/openshift.local.config/master/master-config.yaml
    Copy to Clipboard Toggle word wrap
  2. 使用节点配置文件和 node.kubeconfig 文件启动网络代理和 SDN 插件:

    $ openshift start network \
        --config=/openshift.local.config/node-<node_hostname>/node-config.yaml \
        --kubeconfig=/openshift.local.config/node-<node_hostname>/node.kubeconfig
    Copy to Clipboard Toggle word wrap
  3. 使用节点配置文件启动节点服务器:

    $ hyperkube kubelet \
        $(/usr/bin/openshift-node-config \
        --config=/openshift.local.config/node-<node_hostname>/node-config.yaml)
    Copy to Clipboard Toggle word wrap

7.11. 查看 Master 和节点日志

OpenShift Container Platform 使用 systemd-journald.service 作为节点和名为 master-logs 的脚本,为 master 收集调试的日志消息。

注意

web 控制台中显示的行的数量在 5000 中被硬编码,且无法更改。要查看整个日志,可使用 CLI。

日志记录根据 Kubernetes 日志记录惯例使用五个日志消息,如下所示:

Expand
表 7.23. 日志级别选项
选项描述

0

仅限错误和警告

2

普通信息

4

调试级别信息

6

API 级调试信息(请求/响应)

8

正文级别 API 调试信息

您可以根据需要 更改独立于 master 或节点的日志级别

查看节点日志

要查看节点系统的日志,请运行以下命令:

# journalctl -r -u <journal_name>
Copy to Clipboard Toggle word wrap

使用 -r 选项显示最新的条目。

查看 master 日志

要查看 master 组件的日志,请运行以下命令:

# /usr/local/bin/master-logs <component> <container>
Copy to Clipboard Toggle word wrap

例如:

# /usr/local/bin/master-logs controllers controllers
# /usr/local/bin/master-logs api api
# /usr/local/bin/master-logs etcd etcd
Copy to Clipboard Toggle word wrap

将 master 日志重定向到文件

要将 master 日志的输出重定向到文件,请运行以下命令:

master-logs api api 2> file
Copy to Clipboard Toggle word wrap

7.11.1. 配置日志记录级别

您可以通过在 master 或 /etc/sysconfig/atomic-openshift-node 文件中的 /etc/origin/master/master.env 文件中设置 DEBUG_LOGLEVEL 选项来控制哪些 INFO 信息。将日志配置为收集所有信息可能会导致大型日志被解释,并可能会占用过量空间。仅在需要调试集群时收集所有消息。

注意

不论日志配置是什么,日志中会出现带有 FATAL、ERROR、WARNING 和一些 INFO 严重性的消息。

更改日志记录级别:

  1. 编辑 master 或 /etc/sysconfig/atomic-openshift-node 文件的 /etc/origin/master/master.env 文件。
  2. DEBUG_LOGLEVEL 字段中,输入 Log Level Options 表中的值。

    例如:

    DEBUG_LOGLEVEL=4
    Copy to Clipboard Toggle word wrap
  3. 根据需要重启 master 或节点主机。请参阅重启 OpenShift Container Platform 服务

重启后,所有新日志消息均符合新设置。旧的消息不会更改。

注意

可以使用标准集群安装过程来设置默认日志级别。如需更多信息,请参阅 集群变量

以下示例是不同日志级别重定向的主日志文件的摘录。已从这些示例中删除系统信息。

loglevel=2 的 master-logs api api 2> 文件 输出摘录

W1022 15:08:09.787705       1 server.go:79] Unable to keep dnsmasq up to date, 0.0.0.0:8053 must point to port 53
I1022 15:08:09.787894       1 logs.go:49] skydns: ready for queries on cluster.local. for tcp4://0.0.0.0:8053 [rcache 0]
I1022 15:08:09.787913       1 logs.go:49] skydns: ready for queries on cluster.local. for udp4://0.0.0.0:8053 [rcache 0]
I1022 15:08:09.889022       1 dns_server.go:63] DNS listening at 0.0.0.0:8053
I1022 15:08:09.893156       1 feature_gate.go:190] feature gates: map[AdvancedAuditing:true]
I1022 15:08:09.893500       1 master.go:431] Starting OAuth2 API at /oauth
I1022 15:08:09.914759       1 master.go:431] Starting OAuth2 API at /oauth
I1022 15:08:09.942349       1 master.go:431] Starting OAuth2 API at /oauth
W1022 15:08:09.977088       1 swagger.go:38] No API exists for predefined swagger description /oapi/v1
W1022 15:08:09.977176       1 swagger.go:38] No API exists for predefined swagger description /api/v1
[restful] 2018/10/22 15:08:09 log.go:33: [restful/swagger] listing is available at https://openshift.com:443/swaggerapi
[restful] 2018/10/22 15:08:09 log.go:33: [restful/swagger] https://openshift.com:443/swaggerui/ is mapped to folder /swagger-ui/
I1022 15:08:10.231405       1 master.go:431] Starting OAuth2 API at /oauth
W1022 15:08:10.259523       1 swagger.go:38] No API exists for predefined swagger description /oapi/v1
W1022 15:08:10.259555       1 swagger.go:38] No API exists for predefined swagger description /api/v1
I1022 15:08:23.895493       1 logs.go:49] http: TLS handshake error from 10.10.94.10:46322: EOF
I1022 15:08:24.449577       1 crdregistration_controller.go:110] Starting crd-autoregister controller
I1022 15:08:24.449916       1 controller_utils.go:1019] Waiting for caches to sync for crd-autoregister controller
I1022 15:08:24.496147       1 logs.go:49] http: TLS handshake error from 127.0.0.1:39140: EOF
I1022 15:08:24.821198       1 cache.go:39] Caches are synced for APIServiceRegistrationController controller
I1022 15:08:24.833022       1 cache.go:39] Caches are synced for AvailableConditionController controller
I1022 15:08:24.865087       1 controller.go:537] quota admission added evaluator for: { events}
I1022 15:08:24.865393       1 logs.go:49] http: TLS handshake error from 127.0.0.1:39162: read tcp4 127.0.0.1:443->127.0.0.1:39162: read: connection reset by peer
I1022 15:08:24.966917       1 controller_utils.go:1026] Caches are synced for crd-autoregister controller
I1022 15:08:24.967961       1 autoregister_controller.go:136] Starting autoregister controller
I1022 15:08:24.967977       1 cache.go:32] Waiting for caches to sync for autoregister controller
I1022 15:08:25.015924       1 controller.go:537] quota admission added evaluator for: { serviceaccounts}
I1022 15:08:25.077984       1 cache.go:39] Caches are synced for autoregister controller
W1022 15:08:25.304265       1 lease_endpoint_reconciler.go:176] Resetting endpoints for master service "kubernetes" to [10.10.94.10]
E1022 15:08:25.472536       1 memcache.go:153] couldn't get resource list for servicecatalog.k8s.io/v1beta1: the server could not find the requested resource
E1022 15:08:25.550888       1 memcache.go:153] couldn't get resource list for servicecatalog.k8s.io/v1beta1: the server could not find the requested resource
I1022 15:08:29.480691       1 healthz.go:72] /healthz/log check
I1022 15:08:30.981999       1 controller.go:105] OpenAPI AggregationController: Processing item v1beta1.servicecatalog.k8s.io
E1022 15:08:30.990914       1 controller.go:111] loading OpenAPI spec for "v1beta1.servicecatalog.k8s.io" failed with: OpenAPI spec does not exists
I1022 15:08:30.990965       1 controller.go:119] OpenAPI AggregationController: action for item v1beta1.servicecatalog.k8s.io: Rate Limited Requeue.
I1022 15:08:31.530473       1 trace.go:76] Trace[1253590531]: "Get /api/v1/namespaces/openshift-infra/serviceaccounts/serviceaccount-controller" (started: 2018-10-22 15:08:30.868387562 +0000 UTC m=+24.277041043) (total time: 661.981642ms):
Trace[1253590531]: [661.903178ms] [661.89217ms] About to write a response
I1022 15:08:31.531366       1 trace.go:76] Trace[83808472]: "Get /api/v1/namespaces/aws-sb/secrets/aws-servicebroker" (started: 2018-10-22 15:08:30.831296749 +0000 UTC m=+24.239950203) (total time: 700.049245ms):
Copy to Clipboard Toggle word wrap

loglevel=4 的 master-logs api api 2> 文件 输出摘录

I1022 15:08:09.746980       1 plugins.go:149] Loaded 1 admission controller(s) successfully in the following order: AlwaysDeny.
I1022 15:08:09.747597       1 plugins.go:149] Loaded 1 admission controller(s) successfully in the following order: ResourceQuota.
I1022 15:08:09.748038       1 plugins.go:149] Loaded 1 admission controller(s) successfully in the following order: openshift.io/ClusterResourceQuota.
I1022 15:08:09.786771       1 start_master.go:458] Starting master on 0.0.0.0:443 (v3.10.45)
I1022 15:08:09.786798       1 start_master.go:459] Public master address is https://openshift.com:443
I1022 15:08:09.786844       1 start_master.go:463] Using images from "registry.access.redhat.com/openshift3/ose-<component>:v3.10.45"
W1022 15:08:09.787046       1 dns_server.go:37] Binding DNS on port 8053 instead of 53, which may not be resolvable from all clients
W1022 15:08:09.787705       1 server.go:79] Unable to keep dnsmasq up to date, 0.0.0.0:8053 must point to port 53
I1022 15:08:09.787894       1 logs.go:49] skydns: ready for queries on cluster.local. for tcp4://0.0.0.0:8053 [rcache 0]
I1022 15:08:09.787913       1 logs.go:49] skydns: ready for queries on cluster.local. for udp4://0.0.0.0:8053 [rcache 0]
I1022 15:08:09.889022       1 dns_server.go:63] DNS listening at 0.0.0.0:8053
I1022 15:08:09.893156       1 feature_gate.go:190] feature gates: map[AdvancedAuditing:true]
I1022 15:08:09.893500       1 master.go:431] Starting OAuth2 API at /oauth
I1022 15:08:09.914759       1 master.go:431] Starting OAuth2 API at /oauth
I1022 15:08:09.942349       1 master.go:431] Starting OAuth2 API at /oauth
W1022 15:08:09.977088       1 swagger.go:38] No API exists for predefined swagger description /oapi/v1
W1022 15:08:09.977176       1 swagger.go:38] No API exists for predefined swagger description /api/v1
[restful] 2018/10/22 15:08:09 log.go:33: [restful/swagger] listing is available at https://openshift.com:443/swaggerapi
[restful] 2018/10/22 15:08:09 log.go:33: [restful/swagger] https://openshift.com:443/swaggerui/ is mapped to folder /swagger-ui/
I1022 15:08:10.231405       1 master.go:431] Starting OAuth2 API at /oauth
W1022 15:08:10.259523       1 swagger.go:38] No API exists for predefined swagger description /oapi/v1
W1022 15:08:10.259555       1 swagger.go:38] No API exists for predefined swagger description /api/v1
[restful] 2018/10/22 15:08:10 log.go:33: [restful/swagger] listing is available at https://openshift.com:443/swaggerapi
[restful] 2018/10/22 15:08:10 log.go:33: [restful/swagger] https://openshift.com:443/swaggerui/ is mapped to folder /swagger-ui/
I1022 15:08:10.444303       1 master.go:431] Starting OAuth2 API at /oauth
W1022 15:08:10.492409       1 swagger.go:38] No API exists for predefined swagger description /oapi/v1
W1022 15:08:10.492507       1 swagger.go:38] No API exists for predefined swagger description /api/v1
[restful] 2018/10/22 15:08:10 log.go:33: [restful/swagger] listing is available at https://openshift.com:443/swaggerapi
[restful] 2018/10/22 15:08:10 log.go:33: [restful/swagger] https://openshift.com:443/swaggerui/ is mapped to folder /swagger-ui/
I1022 15:08:10.774824       1 master.go:431] Starting OAuth2 API at /oauth
I1022 15:08:23.808685       1 logs.go:49] http: TLS handshake error from 10.128.0.11:39206: EOF
I1022 15:08:23.815311       1 logs.go:49] http: TLS handshake error from 10.128.0.14:53054: EOF
I1022 15:08:23.822286       1 customresource_discovery_controller.go:174] Starting DiscoveryController
I1022 15:08:23.822349       1 naming_controller.go:276] Starting NamingConditionController
I1022 15:08:23.822705       1 logs.go:49] http: TLS handshake error from 10.128.0.14:53056: EOF
+24.277041043) (total time: 661.981642ms):
Trace[1253590531]: [661.903178ms] [661.89217ms] About to write a response
I1022 15:08:31.531366       1 trace.go:76] Trace[83808472]: "Get /api/v1/namespaces/aws-sb/secrets/aws-servicebroker" (started: 2018-10-22 15:08:30.831296749 +0000 UTC m=+24.239950203) (total time: 700.049245ms):
Trace[83808472]: [700.049245ms] [700.04027ms] END
I1022 15:08:31.531695       1 trace.go:76] Trace[1916801734]: "Get /api/v1/namespaces/aws-sb/secrets/aws-servicebroker" (started: 2018-10-22 15:08:31.031163449 +0000 UTC m=+24.439816907) (total time: 500.514208ms):
Trace[1916801734]: [500.514208ms] [500.505008ms] END
I1022 15:08:44.675371       1 healthz.go:72] /healthz/log check
I1022 15:08:46.589759       1 controller.go:537] quota admission added evaluator for: { endpoints}
I1022 15:08:46.621270       1 controller.go:537] quota admission added evaluator for: { endpoints}
I1022 15:08:57.159494       1 healthz.go:72] /healthz/log check
I1022 15:09:07.161315       1 healthz.go:72] /healthz/log check
I1022 15:09:16.297982       1 trace.go:76] Trace[2001108522]: "GuaranteedUpdate etcd3: *core.Node" (started: 2018-10-22 15:09:15.139820419 +0000 UTC m=+68.548473981) (total time: 1.158128974s):
Trace[2001108522]: [1.158012755s] [1.156496534s] Transaction committed
I1022 15:09:16.298165       1 trace.go:76] Trace[1124283912]: "Patch /api/v1/nodes/master-0.com/status" (started: 2018-10-22 15:09:15.139695483 +0000 UTC m=+68.548348970) (total time: 1.158434318s):
Trace[1124283912]: [1.158328853s] [1.15713683s] Object stored in database
I1022 15:09:16.298761       1 trace.go:76] Trace[24963576]: "GuaranteedUpdate etcd3: *core.Node" (started: 2018-10-22 15:09:15.13159057 +0000 UTC m=+68.540244112) (total time: 1.167151224s):
Trace[24963576]: [1.167106144s] [1.165570379s] Transaction committed
I1022 15:09:16.298882       1 trace.go:76] Trace[222129183]: "Patch /api/v1/nodes/node-0.com/status" (started: 2018-10-22 15:09:15.131269234 +0000 UTC m=+68.539922722) (total time: 1.167595526s):
Trace[222129183]: [1.167517296s] [1.166135605s] Object stored in database
Copy to Clipboard Toggle word wrap

loglevel=8 中的 master-logs api api 2> 文件 输出摘录

1022 15:11:58.829357       1 plugins.go:84] Registered admission plugin "NamespaceLifecycle"
I1022 15:11:58.839967       1 plugins.go:84] Registered admission plugin "Initializers"
I1022 15:11:58.839994       1 plugins.go:84] Registered admission plugin "ValidatingAdmissionWebhook"
I1022 15:11:58.840012       1 plugins.go:84] Registered admission plugin "MutatingAdmissionWebhook"
I1022 15:11:58.840025       1 plugins.go:84] Registered admission plugin "AlwaysAdmit"
I1022 15:11:58.840082       1 plugins.go:84] Registered admission plugin "AlwaysPullImages"
I1022 15:11:58.840105       1 plugins.go:84] Registered admission plugin "LimitPodHardAntiAffinityTopology"
I1022 15:11:58.840126       1 plugins.go:84] Registered admission plugin "DefaultTolerationSeconds"
I1022 15:11:58.840146       1 plugins.go:84] Registered admission plugin "AlwaysDeny"
I1022 15:11:58.840176       1 plugins.go:84] Registered admission plugin "EventRateLimit"
I1022 15:11:59.850825       1 feature_gate.go:190] feature gates: map[AdvancedAuditing:true]
I1022 15:11:59.859108       1 register.go:154] Admission plugin AlwaysAdmit is not enabled.  It will not be started.
I1022 15:11:59.859284       1 plugins.go:149] Loaded 1 admission controller(s) successfully in the following order: AlwaysAdmit.
I1022 15:11:59.859809       1 register.go:154] Admission plugin NamespaceAutoProvision is not enabled.  It will not be started.
I1022 15:11:59.859939       1 plugins.go:149] Loaded 1 admission controller(s) successfully in the following order: NamespaceAutoProvision.
I1022 15:11:59.860594       1 register.go:154] Admission plugin NamespaceExists is not enabled.  It will not be started.
I1022 15:11:59.860778       1 plugins.go:149] Loaded 1 admission controller(s) successfully in the following order: NamespaceExists.
I1022 15:11:59.863999       1 plugins.go:149] Loaded 1 admission controller(s) successfully in the following order: NamespaceLifecycle.
I1022 15:11:59.864626       1 register.go:154] Admission plugin EventRateLimit is not enabled.  It will not be started.
I1022 15:11:59.864768       1 plugins.go:149] Loaded 1 admission controller(s) successfully in the following order: EventRateLimit.
I1022 15:11:59.865259       1 register.go:154] Admission plugin ProjectRequestLimit is not enabled.  It will not be started.
I1022 15:11:59.865376       1 plugins.go:149] Loaded 1 admission controller(s) successfully in the following order: ProjectRequestLimit.
I1022 15:11:59.866126       1 plugins.go:149] Loaded 1 admission controller(s) successfully in the following order: OriginNamespaceLifecycle.
I1022 15:11:59.866709       1 register.go:154] Admission plugin openshift.io/RestrictSubjectBindings is not enabled.  It will not be started.
I1022 15:11:59.866761       1 plugins.go:149] Loaded 1 admission controller(s) successfully in the following order: openshift.io/RestrictSubjectBindings.
I1022 15:11:59.867304       1 plugins.go:149] Loaded 1 admission controller(s) successfully in the following order: openshift.io/JenkinsBootstrapper.
I1022 15:11:59.867823       1 plugins.go:149] Loaded 1 admission controller(s) successfully in the following order: openshift.io/BuildConfigSecretInjector.
I1022 15:12:00.015273       1 master_config.go:476] Initializing cache sizes based on 0MB limit
I1022 15:12:00.015896       1 master_config.go:539] Using the lease endpoint reconciler with TTL=15s and interval=10s
I1022 15:12:00.018396       1 storage_factory.go:285] storing { apiServerIPInfo} in v1, reading as __internal from storagebackend.Config{Type:"etcd3", Prefix:"kubernetes.io", ServerList:[]string{"https://master-0.com:2379"}, KeyFile:"/etc/origin/master/master.etcd-client.key", CertFile:"/etc/origin/master/master.etcd-client.crt", CAFile:"/etc/origin/master/master.etcd-ca.crt", Quorum:true, Paging:true, DeserializationCacheSize:0, Codec:runtime.Codec(nil), Transformer:value.Transformer(nil), CompactionInterval:300000000000, CountMetricPollPeriod:60000000000}
I1022 15:12:00.037710       1 storage_factory.go:285] storing { endpoints} in v1, reading as __internal from storagebackend.Config{Type:"etcd3", Prefix:"kubernetes.io", ServerList:[]string{"https://master-0.com:2379"}, KeyFile:"/etc/origin/master/master.etcd-client.key", CertFile:"/etc/origin/master/master.etcd-client.crt", CAFile:"/etc/origin/master/master.etcd-ca.crt", Quorum:true, Paging:true, DeserializationCacheSize:0, Codec:runtime.Codec(nil), Transformer:value.Transformer(nil), CompactionInterval:300000000000, CountMetricPollPeriod:60000000000}
I1022 15:12:00.054112       1 compact.go:54] compactor already exists for endpoints [https://master-0.com:2379]
I1022 15:12:00.054678       1 start_master.go:458] Starting master on 0.0.0.0:443 (v3.10.45)
I1022 15:12:00.054755       1 start_master.go:459] Public master address is https://openshift.com:443
I1022 15:12:00.054837       1 start_master.go:463] Using images from "registry.access.redhat.com/openshift3/ose-<component>:v3.10.45"
W1022 15:12:00.056957       1 dns_server.go:37] Binding DNS on port 8053 instead of 53, which may not be resolvable from all clients
W1022 15:12:00.065497       1 server.go:79] Unable to keep dnsmasq up to date, 0.0.0.0:8053 must point to port 53
I1022 15:12:00.066061       1 logs.go:49] skydns: ready for queries on cluster.local. for tcp4://0.0.0.0:8053 [rcache 0]
I1022 15:12:00.066265       1 logs.go:49] skydns: ready for queries on cluster.local. for udp4://0.0.0.0:8053 [rcache 0]
I1022 15:12:00.158725       1 dns_server.go:63] DNS listening at 0.0.0.0:8053
I1022 15:12:00.167910       1 htpasswd.go:118] Loading htpasswd file /etc/origin/master/htpasswd...
I1022 15:12:00.168182       1 htpasswd.go:118] Loading htpasswd file /etc/origin/master/htpasswd...
I1022 15:12:00.231233       1 storage_factory.go:285] storing {apps.openshift.io deploymentconfigs} in apps.openshift.io/v1, reading as apps.openshift.io/__internal from storagebackend.Config{Type:"etcd3", Prefix:"openshift.io", ServerList:[]string{"https://master-0.com:2379"}, KeyFile:"/etc/origin/master/master.etcd-client.key", CertFile:"/etc/origin/master/master.etcd-client.crt", CAFile:"/etc/origin/master/master.etcd-ca.crt", Quorum:true, Paging:true, DeserializationCacheSize:0, Codec:runtime.Codec(nil), Transformer:value.Transformer(nil), CompactionInterval:300000000000, CountMetricPollPeriod:60000000000}
I1022 15:12:00.248136       1 compact.go:54] compactor already exists for endpoints [https://master-0.com:2379]
I1022 15:12:00.248697       1 store.go:1391] Monitoring deploymentconfigs.apps.openshift.io count at <storage-prefix>//deploymentconfigs
W1022 15:12:00.256861       1 swagger.go:38] No API exists for predefined swagger description /oapi/v1
W1022 15:12:00.258106       1 swagger.go:38] No API exists for predefined swagger description /api/v1
Copy to Clipboard Toggle word wrap

7.12. 重启 master 和节点服务

要应用 master 或节点配置更改,您必须重启相应的服务。

要重新载入 master 配置更改,请使用 master-restart 命令重启在 control plane 静态 pod 中运行的主服务:

# master-restart api
# master-restart controllers
Copy to Clipboard Toggle word wrap

要重新载入节点配置更改,重启节点主机上的节点服务:

# systemctl restart atomic-openshift-node
Copy to Clipboard Toggle word wrap

第 8 章 OpenShift Ansible Broker 配置

8.1. 概述

当在集群中部署 OpenShift Ansible 代理 (OAB)时,其行为主要由代理在启动时加载的配置文件决定。代理的配置作为 ConfigMap 对象存储在代理的命名空间中(默认为openshift-ansible-service-broker )。

OpenShift Ansible Broker 配置文件示例

registry: 
1

  - type: dockerhub
    name: docker
    url: https://registry.hub.docker.com
    org: <dockerhub_org>
    fail_on_error: false
  - type: rhcc
    name: rhcc
    url: https://registry.redhat.io
    fail_on_error: true
    white_list:
      - "^foo.*-apb$"
      - ".*-apb$"
    black_list:
      - "bar.*-apb$"
      - "^my-apb$"
  - type: local_openshift
    name: lo
    namespaces:
      - openshift
    white_list:
      - ".*-apb$"
dao: 
2

  etcd_host: localhost
  etcd_port: 2379
log: 
3

  logfile: /var/log/ansible-service-broker/asb.log
  stdout: true
  level: debug
  color: true
openshift: 
4

  host: ""
  ca_file: ""
  bearer_token_file: ""
  image_pull_policy: IfNotPresent
  sandbox_role: "edit"
  keep_namespace: false
  keep_namespace_on_error: true
broker: 
5

  bootstrap_on_startup: true
  dev_broker: true
  launch_apb_on_bind: false
  recovery: true
  output_request: true
  ssl_cert_key: /path/to/key
  ssl_cert: /path/to/cert
  refresh_interval: "600s"
  auth:
    - type: basic
      enabled: true
secrets: 
6

  - title: Database credentials
    secret: db_creds
    apb_name: dh-rhscl-postgresql-apb
Copy to Clipboard Toggle word wrap

1
详情请参阅 Registry 配置
2
详情请参阅 DAO 配置
3
详情请参阅日志配置
4
有关详细信息,请参阅 OpenShift 配置
5
详情请参阅 Broker 配置
6
详情请参阅 Secret 配置

在配置 Automation Broker 前,您必须在 OpenShift Container Platform 集群的所有节点上运行以下命令,才能使用 Red Hat Partner Connect:

$ docker --config=/var/lib/origin/.docker login -u <registry-user> -p <registry-password> registry.connect.redhat.com
Copy to Clipboard Toggle word wrap

8.3. 修改 OpenShift Ansible Broker 配置

在部署后修改 OAB 的默认代理配置:

  1. 以具有 cluster-admin 权限的用户身份编辑 OAB 命名空间中的 broker-config ConfigMap 对象:

    $ oc edit configmap broker-config -n openshift-ansible-service-broker
    Copy to Clipboard Toggle word wrap
  2. 保存任何更新后,请重新部署 OAB 的部署配置以使更改生效:

    $ oc rollout latest dc/asb -n openshift-ansible-service-broker
    Copy to Clipboard Toggle word wrap

8.4. Registry 配置

registry 部分允许您定义代理应该用于 APB 的 registry。

Expand
表 8.1. registry 部分配置选项
字段描述必填

name

registry 的名称。代理用来识别来自此 registry 的 APB。

Y

user

用于向 registry 进行身份验证的用户名。当 auth_type 被设置为 secretfile 时,不使用。

N

pass

用于向 registry 进行身份验证的密码。当 auth_type 被设置为 secretfile 时,不使用。

N

auth_type

如果没有通过 userpass 在代理配置中定义,代理应如何读取 registry 凭证可以是 secret (在代理命名空间中使用 secret) 或 file (使用挂载的文件系统)。

N

auth_name

存储应读取的 registry 凭证的机密或文件的名称。将 auth_type 设置为 secret 时使用。

N,仅当 auth_type 设置为 secretfile 时才需要。

org

镜像中包含的命名空间或机构。

N

type

registry 的类型。可用的适配器有 mockrhccopenshiftdockerhublocal_openshift

Y

命名空间

用于配置 local_openshift registry 类型的命名空间列表。默认情况下,用户应使用 openshift

N

url

用于检索镜像信息的 URL。适用于 RHCC 的广泛使用,而 dockerhub 类型则使用硬编码 URL。

N

fail_on_error

此 registry 失败,如果失败 bootstrap 请求。将停止执行其他 registry 加载。

N

white_list

用于定义应允许哪些镜像名称的正则表达式列表。必须有一个白名单,才能将 APB 添加到目录中。如果要检索 registry 中的所有 APB,您可以使用的最宽松的正则表达式为 .*-apb$。如需了解更多详细信息,请参阅 APB 过滤

N

black_list

用于定义应不允许哪些镜像名称的正则表达式列表。如需了解更多详细信息,请参阅 APB 过滤

N

images

要与 OpenShift Container Registry 搭配使用的镜像列表。

N

8.4.1. 生产或开发

一个生产环境代理配置设计为指向可信容器分发 registry,如 Red Hat Container Catalog(RHCC):

registry:
  - name: rhcc
    type: rhcc
    url: https://registry.redhat.io
    tag: v3.11
    white_list:
      - ".*-apb$"
  - type: local_openshift
    name: localregistry
    namespaces:
      - openshift
    white_list: []
Copy to Clipboard Toggle word wrap

但是,开发 代理配置主要供使用代理的开发人员使用。要启用开发人员设置,将 registry 名称设置为 dev,并将 broker 部分中的 dev_broker 字段设置为 true

registry:
  name: dev
Copy to Clipboard Toggle word wrap
broker:
  dev_broker: true
Copy to Clipboard Toggle word wrap

8.4.2. 存储 registry 凭证

代理配置决定了代理应该如何读取任何 registry 凭证。它们可以从 registry 中的 userpass 值读取,例如:

registry:
  - name: isv
    type: openshift
    url: https://registry.connect.redhat.com
    user: <user>
    pass: <password>
Copy to Clipboard Toggle word wrap

如果要确保这些凭据不可公开访问,registry 部分中的 auth_type 字段可以设置为 secretfile 类型。secret 类型将 registry 配置为使用代理命名空间中的 secret,而 file 类型将 registry 配置为使用已挂载为卷的 secret。

使用 secretfile 类型 :

  1. 关联的机密应定义值用户名密码。在使用 secret 时,您必须确保 openshift-ansible-service-broker 命名空间存在,因为这是从中读取 secret 的位置。

    例如,创建一个 reg-creds.yaml 文件:

    $ cat reg-creds.yaml
    ---
    username: <user_name>
    password: <password>
    Copy to Clipboard Toggle word wrap
  2. openshift-ansible-service-broker 命名空间中的此文件创建 secret:

    $ oc create secret generic \
        registry-credentials-secret \
        --from-file reg-creds.yaml \
        -n openshift-ansible-service-broker
    Copy to Clipboard Toggle word wrap
  3. 选择是否要使用 secretfile 类型 :

    • 使用 secret 类型:

      1. 在代理配置中,将 auth_type 设置为 secretauth_name 设置为 secret 的名称:

        registry:
          - name: isv
            type: openshift
            url: https://registry.connect.redhat.com
            auth_type: secret
            auth_name: registry-credentials-secret
        Copy to Clipboard Toggle word wrap
      2. 设置 secret 所在的命名空间:

        openshift:
          namespace: openshift-ansible-service-broker
        Copy to Clipboard Toggle word wrap
    • 使用 file 类型:

      1. 编辑 asb 部署配置,将文件挂载到 /tmp/registry-credentials/reg-creds.yaml 中:

        $ oc edit dc/asb -n openshift-ansible-service-broker
        Copy to Clipboard Toggle word wrap

        containers.volumeMounts 部分添加:

        volumeMounts:
          - mountPath: /tmp/registry-credentials
            name: reg-auth
        Copy to Clipboard Toggle word wrap

        volumes 部分,添加:

            volumes:
              - name: reg-auth
                secret:
                  defaultMode: 420
                  secretName: registry-credentials-secret
        Copy to Clipboard Toggle word wrap
      2. 在代理配置中,将 auth_type 设置为 file,并将 auth_type 设置为文件的位置:

        registry:
          - name: isv
            type: openshift
            url: https://registry.connect.redhat.com
            auth_type: file
            auth_name: /tmp/registry-credentials/reg-creds.yaml
        Copy to Clipboard Toggle word wrap

8.4.3. APB 过滤

APB 可使用 white_listblack_list 参数的组合(根据代理配置中的 registry)组合来筛选其镜像名称。

这两者都是可选的正则表达式列表,这些表达式将在给定 registry 的总发现的 APB 中运行,以确定匹配项。

Expand
表 8.2. APB 过滤器行为
存在允许阻塞

只有白名单

匹配列表中的正则表达式。

任何不匹配的 APB。

只有黑名单

所有不匹配的 APB。

与列表中正则表达式匹配的 APB。

两者都存在

匹配白名单中的正则表达式,当不在黑名单中。

与黑名单中的正则表达式匹配的 APB。

没有来自 registry 的 APB。

来自该 registry 的所有 APB。

例如:

仅有白名单

white_list:
  - "foo.*-apb$"
  - "^my-apb$"
Copy to Clipboard Toggle word wrap

对于 foo.*-apb$ 的任何匹配,在这种情况下,仅允许使用 my-apb。所有其他 APB 都会被拒绝。

仅有黑名单

black_list:
  - "bar.*-apb$"
  - "^foobar-apb$"
Copy to Clipboard Toggle word wrap

任何与 bar.*-apb$ 以及本例中只有 foobar-apb 的匹配都会被阻断。所有其他 APB 都将被允许。

白名单和黑名单

white_list:
  - "foo.*-apb$"
  - "^my-apb$"
black_list:
  - "^foo-rootkit-apb$"
Copy to Clipboard Toggle word wrap

此处,foo-rootkit-apb 由黑名单明确阻止,尽管白名单匹配会被覆盖。

否则,只允许与 foo.*-apb$my-apb 匹配的通过。

代理配置 registry 示例部分:

registry:
  - type: dockerhub
    name: dockerhub
    url: https://registry.hub.docker.com
    user: <user>
    pass: <password>
    org: <org>
    white_list:
      - "foo.*-apb$"
      - "^my-apb$"
    black_list:
      - "bar.*-apb$"
      - "^foobar-apb$"
Copy to Clipboard Toggle word wrap

8.4.4. 模拟 Registry

模拟 registry 有助于读取本地 APB 规格。这使用的是本地 spec 列表,而不是通过 registry 搜索镜像规格。将 registry 的名称设置为 mock 以使用模拟 registry。

registry:
  - name: mock
    type: mock
Copy to Clipboard Toggle word wrap

8.4.5. Dockerhub Registry

dockerhub 类型允许您从 DockerHub 中的特定机构加载 APB。例如,ansibleplaybookbundle 组织。

registry:
  - name: dockerhub
    type: dockerhub
    org: ansibleplaybookbundle
    user: <user>
    pass: <password>
    white_list:
      - ".*-apb$"
Copy to Clipboard Toggle word wrap

8.4.6. Ansible Galaxy Registry

galaxy 类型允许您使用 Ansible Galaxy 的 APB 角色。您还可以选择指定机构。

registry:
  - name: galaxy
    type: galaxy
    # Optional:
    # org: ansibleplaybookbundle
    runner: docker.io/ansibleplaybookbundle/apb-base:latest
    white_list:
      - ".*$"
Copy to Clipboard Toggle word wrap

8.4.7. 本地 OpenShift Container Registry

通过使用 local_openshift 类型,您可以从 OpenShift Container Platform 集群内部的 OpenShift Container Registry 加载 APB。您可以配置您要在其中查找公布的 APB 的命名空间。

registry:
  - type: local_openshift
    name: lo
    namespaces:
      - openshift
    white_list:
      - ".*-apb$"
Copy to Clipboard Toggle word wrap

8.4.8. Red Hat Container Catalog Registry

使用 rhcc 类型将允许您加载发布到 Red Hat Container Catalog (RHCC)registry 中的 APB。

registry:
  - name: rhcc
    type: rhcc
    url: https://registry.redhat.io
    white_list:
      - ".*-apb$"
Copy to Clipboard Toggle word wrap

8.4.9. Red Hat Partner Connect Registry

Red Hat Container Catalog 中的第三方镜像是从 Red Hat 合作伙伴 Connect Registry 提供的,地址为 https://registry.connect.redhat.compartner_rhcc 类型允许代理从合作伙伴注册表引导,以检索 APB 列表并加载其 spec。合作伙伴 Registry 需要身份验证才能使用有效的红帽客户门户网站用户名和密码拉取镜像。

registry:
  - name: partner_reg
    type: partner_rhcc
    url:  https://registry.connect.redhat.com
    user: <registry_user>
    pass: <registry_password>
    white_list:
      - ".*-apb$"
Copy to Clipboard Toggle word wrap

由于合作伙伴 registry 需要身份验证,因此还需要以下手动步骤来配置代理以使用合作伙伴 Registry URL:

  1. 在 OpenShift Container Platform 集群的所有节点上运行以下命令:

    # docker --config=/var/lib/origin/.docker \
        login -u <registry_user> -p <registry_password> \
        registry.connect.redhat.com
    Copy to Clipboard Toggle word wrap

8.4.10. Helm Chart Registry

使用 helm 类型时,您可以使用 Helm Chart 仓库中的 Helm Chart。

registry:
  - name: stable
    type: helm
    url: "https://kubernetes-charts.storage.googleapis.com"
    runner: "docker.io/automationbroker/helm-runner:latest"
    white_list:
      - ".*"
Copy to Clipboard Toggle word wrap
注意

stable 存储库中的许多 Helm chart 不适用于 OpenShift Container Platform,如果使用它们,则会失败。

8.4.11. API V2 Docker Registry

通过使用 apiv2 类型,您可以使用 Docker Registry HTTP API V2 协议的 docker registry 中的镜像。

registry:
  - name: <registry_name>
    type: apiv2
    url:  <registry_url>
    user: <registry-user>
    pass: <registry-password>
    white_list:
      - ".*-apb$"
Copy to Clipboard Toggle word wrap

如果 registry 需要身份验证来拉取镜像,这可以通过在现有集群的每个节点中运行以下命令来实现:

$ docker --config=/var/lib/origin/.docker login -u <registry-user> -p <registry-password> <registry_url>
Copy to Clipboard Toggle word wrap

8.4.12. Quay Docker Registry

使用 quay 类型可以加载发布到 CoreOS Quay Registry 的 APB。如果提供了身份验证令牌,则将加载令牌配置为访问的专用存储库。指定机构中的公共存储库不需要令牌来加载。

registry:
  - name: quay_reg
    type: quay
    url:  https://quay.io
    token: <for_private_repos>
    org: <your_org>
    white_list:
      - ".*-apb$"
Copy to Clipboard Toggle word wrap

如果 Quay registry 需要身份验证来拉取镜像,这可通过在现有集群的每个节点中运行以下命令来实现:

$ docker --config=/var/lib/origin/.docker login -u <registry-user> -p <registry-password> quay.io
Copy to Clipboard Toggle word wrap

8.4.13. 多个 registry

您可以使用多个 registry 将 APB 分开到逻辑机构中,并从同一代理管理它们。registry 必须具有唯一的非空名称。如果没有唯一名称,则服务代理将失败,并显示出错信息警报。

registry:
  - name: dockerhub
    type: dockerhub
    org: ansibleplaybookbundle
    user: <user>
    pass: <password>
    white_list:
      - ".*-apb$"
  - name: rhcc
    type: rhcc
    url: <rhcc_url>
    white_list:
      - ".*-apb$"
Copy to Clipboard Toggle word wrap

8.5. 代理身份验证

代理支持身份验证,这意味着连接到代理时,调用者必须提供每个请求的 Basic Auth 或 Bearer Auth 凭证。使用 curl,它像提供一样简单:

-u <user_name>:<password>
Copy to Clipboard Toggle word wrap

或者

-h "Authorization: bearer <token>
Copy to Clipboard Toggle word wrap

至命令。服务目录必须配置有包含用户名和密码组合的 secret 或 bearer 令牌的 secret。

8.5.1. 基本验证

要启用 Basic Auth 使用,在代理配置中设置以下内容:

broker:
   ...
   auth:
     - type: basic 
1

       enabled: true 
2
Copy to Clipboard Toggle word wrap
1
type 字段指定要使用的身份验证类型。
2
enable 字段允许您禁用特定的验证类型。这样,您只需要删除 auth 的整个部分才能禁用它。
8.5.1.1. 部署模板和 Secret

通常,代理是使用部署模板中的 ConfigMap 进行配置。您提供身份验证配置的方式与文件配置文件中相同。

以下是部署模板的示例:

auth:
  - type: basic
    enabled: ${ENABLE_BASIC_AUTH}
Copy to Clipboard Toggle word wrap

Basic Auth 的另一个部分是用于向代理进行身份验证的用户名和密码。虽然基本 Auth 实施可以由不同的后端服务提供支持,但当前支持的一个 secret 由 secret 提供支持。secret 必须通过卷挂载(在 /var/run/asb_auth 位置)注入 pod。这是代理读取用户名和密码的位置。

部署模板 中,必须指定 secret。例如:

- apiVersion: v1
  kind: Secret
  metadata:
    name: asb-auth-secret
    namespace: openshift-ansible-service-broker
  data:
    username: ${BROKER_USER}
    password: ${BROKER_PASS}
Copy to Clipboard Toggle word wrap

secret 必须包含用户名和密码。值必须采用 base64 编码。为这些条目生成值的最简单方法是使用 echobase64 命令:

$ echo -n admin | base64 
1

YWRtaW4=
Copy to Clipboard Toggle word wrap
1
n 选项非常重要。

此 secret 现在必须通过卷挂载传递给 pod。这在部署模板中也配置:

spec:
  serviceAccount: asb
  containers:
  - image: ${BROKER_IMAGE}
    name: asb
    imagePullPolicy: IfNotPresent
    volumeMounts:
      ...
      - name: asb-auth-volume
        mountPath: /var/run/asb-auth
Copy to Clipboard Toggle word wrap

然后,在 volumes 部分挂载 secret:

volumes:
  ...
  - name: asb-auth-volume
    secret:
      secretName: asb-auth-secret
Copy to Clipboard Toggle word wrap

上述命令将创建一个位于 /var/run/asb-auth 的卷挂载。此卷将有两个文件:由 asb-auth-secret 机密写入的用户名和密码。

8.5.1.2. 配置服务目录和代理通信

现在,代理配置为使用 Basic Auth,您必须告诉服务目录如何与代理通信。这通过代理资源的 authInfo 部分来完成。

以下是在服务目录中 创建代理 资源的示例。spec 告知服务目录代理正在侦听的 URL。authInfo 告诉它读取哪个 secret 获取身份验证信息。

apiVersion: servicecatalog.k8s.io/v1alpha1
kind: Broker
metadata:
  name: ansible-service-broker
spec:
  url: https://asb-1338-openshift-ansible-service-broker.172.17.0.1.nip.io
  authInfo:
    basicAuthSecret:
      namespace: openshift-ansible-service-broker
      name: asb-auth-secret
Copy to Clipboard Toggle word wrap

从服务目录的 v0.0.17 开始,代理资源配置更改:

apiVersion: servicecatalog.k8s.io/v1alpha1
kind: ServiceBroker
metadata:
  name: ansible-service-broker
spec:
  url: https://asb-1338-openshift-ansible-service-broker.172.17.0.1.nip.io
  authInfo:
    basic:
      secretRef:
        namespace: openshift-ansible-service-broker
        name: asb-auth-secret
Copy to Clipboard Toggle word wrap

8.5.2. Bearer Auth

默认情况下,如果没有指定身份验证,代理将使用 bearer 令牌身份验证(Bearer Auth)。Bearer Auth 使用 Kubernetes apiserver 库的委托身份验证。

配置通过 Kubernetes RBAC 角色和角色绑定授予对 URL 前缀的访问权限。代理添加了配置选项 cluster_url 以指定 url_prefix。这个值默认为 openshift-ansible-service-broker

集群角色示例

- apiVersion: authorization.k8s.io/v1
  kind: ClusterRole
  metadata:
    name: access-asb-role
  rules:
  - nonResourceURLs: ["/ansible-service-broker", "/ansible-service-broker/*"]
    verbs: ["get", "post", "put", "patch", "delete"]
Copy to Clipboard Toggle word wrap

8.5.2.1. 部署模板和 Secret

以下是创建服务目录可以使用的 secret 的示例。本例假定角色 access-asb-role 已创建。来自部署模板

- apiVersion: v1
  kind: ServiceAccount
  metadata:
    name: ansibleservicebroker-client
    namespace: openshift-ansible-service-broker

- apiVersion: authorization.openshift.io/v1
  kind: ClusterRoleBinding
  metadata:
    name: ansibleservicebroker-client
  subjects:
  - kind: ServiceAccount
    name: ansibleservicebroker-client
    namespace: openshift-ansible-service-broker
  roleRef:
    kind: ClusterRole
    name: access-asb-role

- apiVersion: v1
  kind: Secret
  metadata:
    name: ansibleservicebroker-client
    annotations:
      kubernetes.io/service-account.name: ansibleservicebroker-client
  type: kubernetes.io/service-account-token
Copy to Clipboard Toggle word wrap

上例中会创建一个服务帐户,授予 access-asb-role 的访问权限,并为该服务帐户令牌创建 secret

8.5.2.2. 配置服务目录和代理通信

现在,代理配置为使用 Bearer Auth 令牌,您必须告知服务目录如何与代理通信。这通过 代理 资源的 authInfo 部分来完成。

以下是在服务目录中 创建代理 资源的示例。spec 告知服务目录代理正在侦听的 URL。authInfo 告诉它读取哪个 secret 获取身份验证信息。

apiVersion: servicecatalog.k8s.io/v1alpha1
kind: ServiceBroker
metadata:
  name: ansible-service-broker
spec:
  url: https://asb.openshift-ansible-service-broker.svc:1338${BROKER_URL_PREFIX}/
  authInfo:
    bearer:
      secretRef:
        kind: Secret
        namespace: openshift-ansible-service-broker
        name: ansibleservicebroker-client
Copy to Clipboard Toggle word wrap

8.6. DAO 配置

Expand
字段描述必填

etcd_host

etcd 主机的 URL。

Y

etcd_port

etcd_host 通信时使用的端口。

Y

8.7. 日志配置

Expand
字段描述必填

logfile

写入代理日志的位置。

Y

stdout

将日志写入 stdout。

Y

level

日志输出的级别。

Y

color

颜色日志。

Y

8.8. OpenShift 配置

Expand
字段描述必填

主机

OpenShift Container Platform 主机。

N

ca_file

证书颁发机构文件的位置。

N

bearer_token_file

要使用的 bearer 令牌的位置。

N

image_pull_policy

拉取镜像的时间。

Y

namespace

代理部署到的命名空间。诸如通过 secret 传递参数值等事项非常重要。

Y

sandbox_role

为 APB 沙盒环境提供的角色。

Y

keep_namespace

始终在执行 APB 后保留命名空间。

N

keep_namespace_on_error

在 APB 执行出错后保留命名空间。

N

8.9. 代理配置

broker 部分告诉代理应该启用和禁用功能。它还将告知代理在磁盘上查找要启用完整功能的文件。

Expand
字段描述默认值必填

dev_broker

允许访问开发路由。

false

N

launch_apb_on_bind

允许绑定为 no-op。

false

N

bootstrap_on_startup

允许代理在启动时尝试 bootstrap 本身。将从配置的 registry 中检索 APB。

false

N

recovery

允许代理通过处理 etcd 中记录的待处理作业来尝试恢复其自身。

false

N

output_request

允许代理输出对日志文件的请求,以便更轻松地调试。

false

N

ssl_cert_key

告知代理在哪里查找 TLS 密钥文件。如果没有设置,API 服务器将尝试创建一个。

""

N

ssl_cert

告知代理在哪里查找 TLS .crt 文件。如果没有设置,API 服务器将尝试创建一个。

""

N

refresh_interval

查询新镜像规格的 registry 的时间间隔。

"600s"

N

auto_escalate

允许代理在运行 APB 时升级用户的权限。

false

N

cluster_url

为代理预期的 URL 设置前缀。

openshift-ansible-service-broker

N

注意

async bind 和 unbind 是一个实验性功能,不受支持或默认启用。如果没有 async 绑定,将 launch_apb_on_bind 设置为 true 可能会导致 bind 操作超时,并会重试。代理会使用 "409 Conflicts" 处理这个问题,因为它使用不同的参数使用相同的绑定请求。

8.10. secret 配置

secrets 部分会在代理的命名空间和代理运行的 APB 中创建 secret 间的关联。代理使用这些规则将 secret 挂载到运行的 APB 中,允许用户使用 secret 传递参数,而无需将它们公开给目录或用户。

部分是每个条目具有以下结构的列表:

Expand
字段描述必填

title

规则的标题。这仅用于显示和输出目的。

Y

apb_name

与指定 secret 关联的 APB 名称。这是完全限定名称( <registry_name>-<image_name>)。

Y

secret

要从中拉取参数的 secret 名称。

Y

您可以下载并使用 create_broker_secret.py 文件来创建和格式化这个配置部分。

secrets:
- title: Database credentials
  secret: db_creds
  apb_name: dh-rhscl-postgresql-apb
Copy to Clipboard Toggle word wrap

8.11. 在代理后面运行

在代理 OpenShift Container Platform 集群内运行 OAB 时,务必要了解其核心概念,并在用于外部网络访问的代理上下文中考虑它们。

作为概述,代理本身作为集群中的 pod 运行。它具有外部网络访问权限的要求,具体取决于其 registry 的配置方式。

8.11.1. registry Adapter Whitelists

代理配置的 registry 适配器必须能够与外部 registry 通信,才能成功引导并加载远程 APB 清单。这些请求可以通过代理进行,但代理必须确保可以访问所需的远程主机。

需要白名单的主机示例:

Expand
registry Adapter Type将主机列入白名单

rhcc

registry.redhat.io,access.redhat.com

dockerhub

docker.io

8.11.2. 使用 Ansible 配置代理成为代理

如果在初始安装过程中,您可以将 OpenShift Container Platform 集群配置为在代理后运行(请参阅" 配置全局代理选项"),当部署 OAB 时:

  • 自动继承这些集群范围的代理设置,
  • 生成所需的 NO_PROXY 列表,包括 cidr 字段和 serviceNetworkCIDR,

不需要进一步配置。

8.11.3. 手动配置代理成为代理

如果在初始安装过程中或部署代理前没有配置集群的全局代理选项,或者修改了全局代理设置,则必须手动配置代理以便通过代理进行外部访问:

  1. 在尝试在代理后面运行 OAB 之前,请参阅使用 HTTP Proxies 工作,并确保集群进行相应配置,以便在代理后面运行。

    特别是,集群必须配置为 代理内部集群请求。这通常配置有 NO_PROXY 设置:

    .cluster.local,.svc,<serviceNetworkCIDR_value>,<master_IP>,<master_domain>,.default
    Copy to Clipboard Toggle word wrap

    除了任何其他所需的 NO_PROXY 设置之外。如需了解更多详细信息,请参阅配置 NO_PROXY

    注意

    部署未指定版本的 或 v1 APBs 还必须将 172.30.0.1 添加到其 NO_PROXY 列表中。v2 之前的 APB 通过 exec HTTP 请求从运行 APB pod 中提取凭证,而不是通过 secret 交换。除非在 OpenShift Container Platform 3.9 之前运行带有实验代理支持的代理,否则您可能不必担心。

  2. 以具有 cluster-admin 权限的用户身份登录代理的 DeploymentConfig

    $ oc edit dc/asb -n openshift-ansible-service-broker
    Copy to Clipboard Toggle word wrap
  3. 设置以下环境变量:

    • HTTP_PROXY
    • HTTPS_PROXY
    • NO_PROXY
    注意

    如需更多信息,请参阅在 Pod 中设置代理环境变量

  4. 保存任何更新后,请重新部署 OAB 的部署配置以使更改生效:

    $ oc rollout latest dc/asb -n openshift-ansible-service-broker
    Copy to Clipboard Toggle word wrap

8.11.4. 在 Pod 中设置代理环境变量

APB pod 本身还需要通过代理进行外部访问。如果代理识别具有代理配置,它会将这些环境变量透明地应用到它生成的 APB pod。只要 APB 中使用的模块通过环境变量处理代理配置,APB 也将使用这些设置来执行其工作。

最后,APB 生成的服务可能还需要通过代理访问外部网络。如果在其自己的执行环境中识别这些环境变量,则必须明确编写 APB 来设置这些环境变量,或者集群操作员必须手动修改所需的服务才能将其注入其环境中。

第 9 章 将主机添加到现有集群

9.1. 添加主机

您可以通过运行 scaleup.yml playbook 添加新主机到集群。此 playbook 查询 master,为新主机生成和发布新证书,然后仅在新主机上运行配置 playbook。在运行 scaleup.yml playbook 之前,请完成所有必备的主机准备步骤。

重要

scaleup.yml playbook 仅配置新主机。它不会更新 master 服务的 NO_PROXY,也不会重启 master 服务。

您必须有一个现有的清单文件,如 /etc/ansible/hosts,它代表当前集群配置,才能运行 scaleup.yml playbook。如果您之前使用 atomic-openshift-installer 命令来运行安装,您可以检查 ~/.config/openshift/hosts 查找安装程序生成的最后一个清单文件,并将该文件用作清单文件。您可以根据需要修改此文件。然后,在运行 ansible-playbook 时,您必须使用 -i 指定文件位置。

重要

有关推荐的最大节点数,请参阅集群最大值部分。

流程
  1. 通过更新 openshift-ansible 软件包来确保您有最新的 playbook:

    # yum update openshift-ansible
    Copy to Clipboard Toggle word wrap
  2. 编辑 /etc/ansible/hosts 文件,并将 new_<host_type> 添加到 [OSEv3:children] 部分。例如,要添加新节点主机,请添加 new_nodes

    [OSEv3:children]
    masters
    nodes
    new_nodes
    Copy to Clipboard Toggle word wrap

    若要添加新的 master 主机,可添加 new_masters

  3. 创建一个 [new_<host_type>] 部分来为新主机指定主机信息。将此部分格式化为现有部分,如下例所示:

    [nodes]
    master[1:3].example.com
    node1.example.com openshift_node_group_name='node-config-compute'
    node2.example.com openshift_node_group_name='node-config-compute'
    infra-node1.example.com openshift_node_group_name='node-config-infra'
    infra-node2.example.com openshift_node_group_name='node-config-infra'
    
    [new_nodes]
    node3.example.com openshift_node_group_name='node-config-infra'
    Copy to Clipboard Toggle word wrap

    如需了解更多选项,请参阅配置主机变量

    在添加新 master 时,将主机添加到 [new_masters] 部分和 [new_nodes] 部分,以确保新 master 主机是 OpenShift SDN 的一部分:

    [masters]
    master[1:2].example.com
    
    [new_masters]
    master3.example.com
    
    [nodes]
    master[1:2].example.com
    node1.example.com openshift_node_group_name='node-config-compute'
    node2.example.com openshift_node_group_name='node-config-compute'
    infra-node1.example.com openshift_node_group_name='node-config-infra'
    infra-node2.example.com openshift_node_group_name='node-config-infra'
    
    [new_nodes]
    master3.example.com
    Copy to Clipboard Toggle word wrap
    重要

    如果您使用 node-role.kubernetes.io/infra=true 标签标记 master 主机,且没有其他专用基础架构节点,还必须通过向条目中添加 openshift_schedulable=true 明确将该主机标记为可以调度。否则,registry 和路由器 Pod 将无法放置到任何节点。

  4. 更改到 playbook 目录,再运行 openshift_node_group.yml playbook。如果您的清单文件位于 /etc/ansible/hosts 默认以外的位置,请使用 -i 选项指定位置:

    $ cd /usr/share/ansible/openshift-ansible
    $ ansible-playbook [-i /path/to/file] \
      playbooks/openshift-master/openshift_node_group.yml
    Copy to Clipboard Toggle word wrap

    这会为新节点组创建 ConfigMap,并最终为主机上的节点配置文件。

    注意

    运行 openshift_node_group.yaml playbook 只会更新新节点。无法运行它来更新集群中的现有节点。

  5. 运行 scaleup.yml playbook。如果您的清单文件位于默认 /etc/ansible/hosts 以外的位置,请使用 -i 选项指定位置。

    • 对于额外的节点:

      $ ansible-playbook [-i /path/to/file] \
          playbooks/openshift-node/scaleup.yml
      Copy to Clipboard Toggle word wrap
    • 对于额外的 master:

      $ ansible-playbook [-i /path/to/file] \
          playbooks/openshift-master/scaleup.yml
      Copy to Clipboard Toggle word wrap
  6. 如果您在集群中部署了 EFK 堆栈,请将节点标签设置为 logging-infra-fluentd=true

    # oc label node/new-node.example.com logging-infra-fluentd=true
    Copy to Clipboard Toggle word wrap
  7. 在 playbook 运行后,验证安装
  8. 将您在 [new_<host_type>] 部分定义的任何主机移动到它们的相应部分。通过移动这些主机,后续的 playbook 运行使用此清单文件正确处理节点。您可以保留空 [new_<host_type>] 部分。例如,添加新节点时:

    [nodes]
    master[1:3].example.com
    node1.example.com openshift_node_group_name='node-config-compute'
    node2.example.com openshift_node_group_name='node-config-compute'
    node3.example.com openshift_node_group_name='node-config-compute'
    infra-node1.example.com openshift_node_group_name='node-config-infra'
    infra-node2.example.com openshift_node_group_name='node-config-infra'
    
    [new_nodes]
    Copy to Clipboard Toggle word wrap

9.2. 在现有集群中添加 etcd 主机

您可以通过运行 etcd 扩展 playbook 来在集群中添加新的 etcd 主机。此 playbook 查询 master,为新主机生成并分发新证书,然后仅在新主机上运行配置 playbook。在运行 etcd scaleup.yml playbook 前,请完成所有预备 主机准备步骤

警告

这些步骤会将 Ansible 清单中的设置与集群同步。确保 Ansible 清单中显示了任何本地更改。

将 etcd 主机添加到现有集群中:

  1. 通过更新 openshift-ansible 软件包来确保您有最新的 playbook:

    # yum update openshift-ansible
    Copy to Clipboard Toggle word wrap
  2. 编辑 /etc/ansible/hosts 文件,将 new_<host_type> 添加到 [OSEv3: Child] 组,并在 new_<host_type> 组下添加主机。例如,要添加新的 etcd,请添加 new_etcd

    [OSEv3:children]
    masters
    nodes
    etcd
    new_etcd
    
    [etcd]
    etcd1.example.com
    etcd2.example.com
    
    [new_etcd]
    etcd3.example.com
    Copy to Clipboard Toggle word wrap
  3. 更改到 playbook 目录,再运行 openshift_node_group.yml playbook。如果您的清单文件位于 /etc/ansible/hosts 默认以外的位置,请使用 -i 选项指定位置:

    $ cd /usr/share/ansible/openshift-ansible
    $ ansible-playbook [-i /path/to/file] \
      playbooks/openshift-master/openshift_node_group.yml
    Copy to Clipboard Toggle word wrap

    这会为新节点组创建 ConfigMap,并最终为主机上的节点配置文件。

    注意

    运行 openshift_node_group.yaml playbook 只会更新新节点。无法运行它来更新集群中的现有节点。

  4. 运行 etcd scaleup.yml playbook。如果您的清单文件位于 /etc/ansible/hosts 默认以外的位置,请使用 -i 选项指定位置:

    $ ansible-playbook [-i /path/to/file] \
      playbooks/openshift-etcd/scaleup.yml
    Copy to Clipboard Toggle word wrap
  5. playbook 成功完成后,验证安装

9.3. 将现有的 master 替换为 etcd colocated

在将机器迁移到不同的数据中心以及分配给它的网络和 IP 将改变时,请按照以下步骤操作。

  1. 备份主 etcdmaster 节点。

    重要

    确保您备份 /etc/etcd/ 目录,如 etcd 备份 说明中所述。

  2. 在需要替换 master 时,置备任意数量的新机器。
  3. 添加或扩展集群。例如,如果要添加 3 个带有 etcd 在一起的 master,扩展 3 个 master 节点。
重要

在 OpenShift Container Platform 版本 3.11 的初始发行版本中,scaleup.yml playbook 不会扩展 etcd。这个问题已在 OpenShift Container Platform 3.11.59 及更高版本中解决。

  1. 添加 master。在这一流程的第 3 步,在 [new_masters][new_nodes] 中添加新数据中心的主机,运行 openshift_node_group.yml playbook,并运行 master scaleup.yml playbook。
  2. 将相同的主机放在 etcd 部分中,运行 openshift_node_group.yml playbook,并运行 etcd scaleup.yml playbook。
  3. 验证主机是否已添加:

    # oc get nodes
    Copy to Clipboard Toggle word wrap
  4. 验证 master 主机 IP 是否已添加:

    # oc get ep kubernetes
    Copy to Clipboard Toggle word wrap
  5. 验证已添加了 etcd。ETCDCTL_API 的值取决于所使用的版本:

    # source /etc/etcd/etcd.conf
    # ETCDCTL_API=2 etcdctl --cert-file=$ETCD_PEER_CERT_FILE --key-file=$ETCD_PEER_KEY_FILE \
      --ca-file=/etc/etcd/ca.crt --endpoints=$ETCD_LISTEN_CLIENT_URLS member list
    Copy to Clipboard Toggle word wrap
  6. /etc/origin/master/ca.serial.txt/etc/origin/master 目录复制到清单文件中最先列出的新 master 主机。默认情况下,这是 /etc/ansible/hosts

    1. 删除 etcd 主机。
  7. /etc/etcd/ca 目录复制到清单文件中第一个列出的新 etcd 主机中。默认情况下,这是 /etc/ansible/hosts
  8. master-config.yaml 文件中删除旧的 etcd 客户端:

    # grep etcdClientInfo -A 11 /etc/origin/master/master-config.yaml
    Copy to Clipboard Toggle word wrap
  9. 重启 master:

    # master-restart api
    # master-restart controllers
    Copy to Clipboard Toggle word wrap
  10. 从集群中删除旧的 etcd 成员。ETCDCTL_API 的值取决于所使用的版本:

    # source /etc/etcd/etcd.conf
    # ETCDCTL_API=2 etcdctl --cert-file=$ETCD_PEER_CERT_FILE --key-file=$ETCD_PEER_KEY_FILE \
      --ca-file=/etc/etcd/ca.crt --endpoints=$ETCD_LISTEN_CLIENT_URLS member list
    Copy to Clipboard Toggle word wrap
  11. 获取以上命令的输出中的 ID,并使用 ID 删除旧的成员:

    # etcdctl --cert-file=$ETCD_PEER_CERT_FILE --key-file=$ETCD_PEER_KEY_FILE \
      --ca-file=/etc/etcd/ca.crt --endpoints=$ETCD_LISTEN_CLIENT_URL member remove 1609b5a3a078c227
    Copy to Clipboard Toggle word wrap
  12. 通过删除 etcd pod 定义来停止旧 etcd 主机上的 etcd 服务:

    # mkdir -p /etc/origin/node/pods-stopped
    # mv /etc/origin/node/pods/* /etc/origin/node/pods-stopped/
    Copy to Clipboard Toggle word wrap
    1. 通过将定义文件从静态 pod dir /etc/origin/node/pods 中移出,关闭旧的 master API 和控制器服务:

      # mkdir -p /etc/origin/node/pods/disabled
      # mv /etc/origin/node/pods/controller.yaml /etc/origin/node/pods/disabled/:
      Copy to Clipboard Toggle word wrap
    2. 从 HA 代理配置中删除 master 节点,该配置在原生安装过程中默认作为负载均衡器安装。
    3. 弃用机器。
  13. 通过删除 pod 定义并重启主机来停止 master 上的节点服务:

    # mkdir -p /etc/origin/node/pods-stopped
    # mv /etc/origin/node/pods/* /etc/origin/node/pods-stopped/
    # reboot
    Copy to Clipboard Toggle word wrap
  14. 删除节点资源:

    # oc delete node
    Copy to Clipboard Toggle word wrap

9.4. 迁移节点

您可以单独对节点进行迁移,或以组的形式迁移节点(例如 2 个、5 个 10 个为一组等),具体取决于您对节点的服务运行和扩展的方式。

  1. 要迁移节点,在新的数据中心中置备节点使用的虚拟机。
  2. 要添加新节点,请扩展基础架构。确保正确设置新节点的标签,并将您的新 API 服务器添加到负载均衡器中,并成功提供流量。
  3. 评估和缩减。

    1. 在旧数据中心将当前节点标记为未调度
    2. 撤离节点,以便其上的 pod 调度到其他节点。
    3. 验证撤离的服务在新节点上运行。
  4. 删除节点。

    1. 验证节点为空,且没有运行任何进程。
    2. 停止服务或删除节点。

第 10 章 添加默认镜像流和模板

10.1. 概述

如果您在有 x86_64 架构的服务器上安装了 OpenShift Container Platform,您的集群包含了红帽提供的 镜像流和模板 组,以便开发人员轻松创建新应用程序。默认情况下,集群安装过程会在 openshift 项目中创建这些集合,它是所有用户具有查看访问权限的默认全局项目。

如果您在使用 IBM POWER 架构的服务器上安装 OpenShift Container Platform,您可以 在集群中添加 镜像流和模板

10.2. 按订阅类型提供

根据您的红帽帐户上的活跃订阅,红帽提供了以下镜像流和模板集并被红帽支持。请联系红帽销售代表了解更多详情。

10.2.1. OpenShift Container Platform 订阅

带有一个活跃的 OpenShift Container Platform 订阅,并提供支持了镜像流和模板的核心集合。这包括以下技术:

Expand
类型技术

语言和框架

数据库

中间件服务

其他服务

10.2.2. xPaaS 中间件附加订阅

xPaaS 中间件镜像支持由 xPaaS 中间件附加组件订阅提供,它是每个 xPaaS 产品的独立订阅。如果您的帐户上已有相关的订阅,则会为以下技术提供镜像流和模板支持:

10.3. 开始前

在考虑执行本主题中的任务前,请通过执行以下操作之一确认这些镜像流和模板已在 OpenShift Container Platform 集群中注册:

  • 登录 Web 控制台,再点 Add to Project
  • 使用 CLI 列出 openshift 项目:

    $ oc get is -n openshift
    $ oc get templates -n openshift
    Copy to Clipboard Toggle word wrap

如果删除或更改了默认镜像流和模板,可以根据这里的内容自行创建默认对象。否则,不需要以下说明。

10.4. 先决条件

在创建默认镜像流和模板之前:

  • 必须在 OpenShift Container Platform 安装中部署集成的容器镜像 registry 服务。
  • 您必须使用 cluster-admin 特权运行 oc create 命令,因为它们在默认的 openshift 项目 上运行。
  • 您必须已安装了 openshift-ansible RPM 软件包。具体步骤请参阅 软件先决条件
  • 对于 IBM POWER8 或 IBM POWER9 服务器中的内部安装,在 openshift 命名空间中为 registry.redhat.io 创建 secret
  • 为包含镜像流和模板的目录定义 shell 变量。这可显著缩短以下部分中的命令。要做到这一点:

    • 对于 x86_64 服务器中的云安装和内部安装:
$ IMAGESTREAMDIR="/usr/share/ansible/openshift-ansible/roles/openshift_examples/files/examples/x86_64/image-streams"; \
    XPAASSTREAMDIR="/usr/share/ansible/openshift-ansible/roles/openshift_examples/files/examples/x86_64/xpaas-streams"; \
    XPAASTEMPLATES="/usr/share/ansible/openshift-ansible/roles/openshift_examples/files/examples/x86_64/xpaas-templates"; \
    DBTEMPLATES="/usr/share/ansible/openshift-ansible/roles/openshift_examples/files/examples/x86_64/db-templates"; \
    QSTEMPLATES="/usr/share/ansible/openshift-ansible/roles/openshift_examples/files/examples/x86_64/quickstart-templates"
Copy to Clipboard Toggle word wrap
  • 对于 IBM POWER8 或 IBM POWER9 服务器中的内部安装:
IMAGESTREAMDIR="/usr/share/ansible/openshift-ansible/roles/openshift_examples/files/examples/ppc64le/image-streams"; \
    DBTEMPLATES="/usr/share/ansible/openshift-ansible/roles/openshift_examples/files/examples/ppc64le/db-templates"; \
    QSTEMPLATES="/usr/share/ansible/openshift-ansible/roles/openshift_examples/files/examples/ppc64le/quickstart-templates"
Copy to Clipboard Toggle word wrap

如果您的节点主机使用 Red Hat Subscription Manager 订阅,且您想要使用使用 Red Hat Enterprise Linux(RHEL)7 的镜像的核心镜像流集合:

$ oc create -f $IMAGESTREAMDIR/image-streams-rhel7.json -n openshift
Copy to Clipboard Toggle word wrap

另外,要创建使用基于 CentOS 7 的镜像的核心镜像流集合:

$ oc create -f $IMAGESTREAMDIR/image-streams-centos7.json -n openshift
Copy to Clipboard Toggle word wrap

无法同时创建 CentOS 和 RHEL 镜像流集,因为它们使用相同的名称。要将镜像流集可供用户使用,可在另一项目中创建一个集合,或者编辑其中一个文件,并修改镜像流名称以使其唯一。

10.6. 为 xPaaS 中间件镜像创建镜像流

xPaaS 中间件镜像流为 JBoss EAPJBoss JWSJBoss A-MQ红帽 Fuse on OpenShiftDecision ServerJBoss Data VirtualizationJBoss Data Grid 提供图像。它们可用于使用提供的模板为这些平台构建应用程序。

创建 xPaaS 中间件镜像流集:

$ oc create -f $XPAASSTREAMDIR/jboss-image-streams.json -n openshift
Copy to Clipboard Toggle word wrap
注意

访问这些镜像流引用的镜像需要相关的 xPaaS 中间件订阅。

10.7. 创建数据库服务模板

借助数据库服务模板,可以更轻松地运行可供其他组件使用的数据库镜像。对于每个数据库(MongoDBMySQLPostgreSQL),定义了两个模板。

一个模板使用容器中的临时存储,这意味着如果容器重启,存储的数据将会丢失,例如,如果 pod 移动。此模板仅用于演示目的。

其他模板定义了用于存储的持久性卷,但 OpenShift Container Platform 安装需要配置 持久性卷

创建数据库模板的核心集合:

$ oc create -f $DBTEMPLATES -n openshift
Copy to Clipboard Toggle word wrap

创建模板后,用户可以轻松地实例化各种模板,使它们快速访问数据库部署。

10.8. 创建 Instant App 和 Quickstart 模板

Instant App 和 Quickstart 模板为正在运行的应用程序定义一组完整的对象。它们是:

  • 从 GitHub 公共存储库中的源构建应用的构建配置
  • 用于在 应用程序镜像构建后部署应用程序镜像的部署配置。
  • 用于为应用 pod 提供负载均衡的服务
  • 提供对应用程序的外部访问的路由

有些模板也定义了数据库部署和服务,以便应用程序能够执行数据库操作。

注意

定义数据库的模板将临时存储用于数据库内容。这些模板仅限于演示目的,因为如果数据库 pod 因任何原因重启,所有数据库数据都将丢失。

通过使用这些模板,用户可以使用 OpenShift Container Platform 提供的各种语言镜像轻松实例化完整的应用程序。它们也可以在实例化过程中自定义模板参数,以便从其自己的存储库构建源,而非示例存储库,从而为构建新应用提供了简单起点。

创建核心 Instant App 和 Quickstart 模板:

$ oc create -f $QSTEMPLATES -n openshift
Copy to Clipboard Toggle word wrap

还有一组模板,可使用各种 xPaaS 中间件产品(JBoss EAP, JBoss JWS, JBoss A-MQ, Red Hat Fuse on OpenShift, Decision Server, 和 JBoss Data Grid)创建应用程序,通过运行以下命令:

$ oc create -f $XPAASTEMPLATES -n openshift
Copy to Clipboard Toggle word wrap
注意

xPaaS 中间件模板需要 xPaaS 中间件镜像流,后者需要相关的 xPaaS 中间件订阅。

注意

定义数据库的模板将临时存储用于数据库内容。这些模板仅限于演示目的,因为如果数据库 pod 因任何原因重启,所有数据库数据都将丢失。

10.9. 下一步是什么?

创建这些工件后,开发人员 现在可以登录到 web 控制台,并根据 模板创建过程 进行操作。可以选择任何数据库或应用程序模板,在当前项目中创建正在运行的数据库服务或应用程序。请注意,一些应用程序模板也定义了自己的数据库服务。

示例应用都构建了默认在模板中引用的 GitHub 存储库,如 SOURCE_REPOSITORY_URL 参数值中所示。这些存储库可以进行分叉,并且分叉可以在从模板创建时作为 SOURCE_REPOSITORY_URL 参数值提供。这使得开发人员能够尝试创建自己的应用程序。

您可以将开发人员定向到开发者指南中的使用 Instant App 和 Quickstart Templates 部分。

第 11 章 配置自定义证书

11.1. 概述

管理员可以为 OpenShift Container Platform API 和 Web 控制台的 公共主机名配置自定义服务证书。这可在集群安装过程中完成,也可以在安装后配置。

11.2. 配置证书链

如果使用证书链,则必须手动将所有证书链接到一个命名的证书文件中。这些证书必须按以下顺序放置:

  • OpenShift Container Platform master 主机证书
  • 中间 CA 证书
  • Root CA 证书
  • 第三方证书

要创建此证书链,请将证书串联为通用文件。您必须为每个证书运行这个命令,并确保它们按之前定义的顺序运行。

$ cat <certificate>.pem >> ca-chain.cert.pem
Copy to Clipboard Toggle word wrap

11.3. 在安装过程中配置自定义证书

在集群安装过程中,可以使用 openshift_master_named_certificatesopenshift_master_overwrite_named_certificates 参数来配置自定义证书,它们可在清单文件中配置。有关使用 Ansible 配置自定义证书 的更多详细信息。

自定义证书配置参数

openshift_master_overwrite_named_certificates=true 
1

openshift_master_named_certificates=[{"certfile": "/path/on/host/to/crt-file", "keyfile": "/path/on/host/to/key-file", "names": ["public-master-host.com"], "cafile": "/path/on/host/to/ca-file"}] 
2

openshift_hosted_router_certificate={"certfile": "/path/on/host/to/app-crt-file", "keyfile": "/path/on/host/to/app-key-file", "cafile": "/path/on/host/to/app-ca-file"} 
3
Copy to Clipboard Toggle word wrap

1
如果您为 openshift_master_named_certificates 参数提供值,请将此参数设置为 true
2
置备 主 API 证书。如有必要,将组成 证书链 的所有必需文件串联为提供给 certFile 参数的证书文件。
3

master API 证书的参数示例:

openshift_master_overwrite_named_certificates=true
openshift_master_named_certificates=[{"names": ["master.148.251.233.173.nip.io"], "certfile": "/home/cloud-user/master.148.251.233.173.nip.io.cert.pem", "keyfile": "/home/cloud-user/master.148.251.233.173.nip.io.key.pem", "cafile": "/home/cloud-user/master-bundle.cert.pem"}]
Copy to Clipboard Toggle word wrap

路由器通配符证书的参数示例:

openshift_hosted_router_certificate={"certfile": "/home/cloud-user/star-apps.148.251.233.173.nip.io.cert.pem", "keyfile": "/home/cloud-user/star-apps.148.251.233.173.nip.io.key.pem", "cafile": "/home/cloud-user/ca-chain.cert.pem"}
Copy to Clipboard Toggle word wrap

11.4. 为 Web 控制台或 CLI 配置自定义证书

您可以通过主配置文件serviceInfo 部分为 web 控制台和 CLI 指定自定义证书:

  • serviceInfo.namedCertificates 部分为 web 控制台提供自定义证书。
  • serviceInfo 部分提供 CLI 和其它 API 调用的自定义证书。

您可以以这种方式配置多个证书,每个证书都可与多个主机名多个路由器OpenShift Container Platform 镜像 registry 关联。

除了 namedCertificates 外,还必须在 serviceInfo.certFileserviceInfo.keyFile 配置部分中配置默认证书。

注意

namedCertificates 部分应仅为与 /etc/origin/master/master-config.yaml 文件中的 masterPublicURLoauthConfig.assetPublicURL 设置关联的主机名配置。将自定义服务证书用于与 masterURL 关联的主机名将导致 TLS 错误,因为基础架构组件将尝试使用内部 masterURL 主机联系 master API。

自定义证书配置

servingInfo:
  logoutURL: ""
  masterPublicURL: https://openshift.example.com:8443
  publicURL: https://openshift.example.com:8443/console/
  bindAddress: 0.0.0.0:8443
  bindNetwork: tcp4
  certFile: master.server.crt 
1

  clientCA: ""
  keyFile: master.server.key 
2

  maxRequestsInFlight: 0
  requestTimeoutSeconds: 0
  namedCertificates:
    - certFile: wildcard.example.com.crt 
3

      keyFile: wildcard.example.com.key 
4

      names:
        - "openshift.example.com"
  metricsPublicURL: "https://metrics.os.example.com/hawkular/metrics"
Copy to Clipboard Toggle word wrap

1
CLI 和其他 API 调用的证书文件的路径。
2
CLI 和其他 API 调用的密钥文件的路径。
3
OpenShift Container Platform API 和 Web 控制台的公共主机名的证书文件的路径。如有必要,将组成 证书链 的所有必需文件串联为提供给 certFile 参数的证书文件。
4
OpenShift Container Platform API 和 Web 控制台的公共主机名的密钥文件的路径。

Ansible 清单文件(默认为 /etc/ansible/hosts)中的 openshift_master_cluster_public_hostnameopenshift_master_cluster_hostname 参数必须是不同的。如果它们相同,命名的证书将失败,您需要重新安装它们。

# Native HA with External LB VIPs
openshift_master_cluster_hostname=internal.paas.example.com
openshift_master_cluster_public_hostname=external.paas.example.com
Copy to Clipboard Toggle word wrap

有关在 OpenShift Container Platform 中使用 DNS 的更多信息,请参阅 DNS 安装先决条件

这种方法允许您利用 OpenShift Container Platform 生成的自签名证书,并根据需要将自定义可信证书添加到各个组件中。

请注意,内部基础架构证书仍是自签名的,这可能被某些安全或 PKI 团队视为不当做法。但是,这里的风险最小,因为信任这些证书的唯一客户端是集群中的其他组件。所有外部用户和系统都使用自定义可信证书。

相对路径基于主配置文件的位置解析。重启服务器以获取配置更改。

11.5. 配置自定义 master 主机证书

为了促进与 OpenShift Container Platform 的外部用户的可信连接,您可以置备一个与 Ansible 清单文件(默认为 /etc/ansible/hosts)中的 openshift_master_cluster_public_hostname 参数提供的域名匹配的命名证书。

您必须将此证书放在 Ansible 可访问的目录中,并在 Ansible 清单文件中添加路径,如下所示:

openshift_master_named_certificates=[{"certfile": "/path/to/console.ocp-c1.myorg.com.crt", "keyfile": "/path/to/console.ocp-c1.myorg.com.key", "names": ["console.ocp-c1.myorg.com"]}]
Copy to Clipboard Toggle word wrap

如果参数值是:

  • cert File 是包含 OpenShift Container Platform 自定义主 API 证书的文件的路径。
  • keyfile 是包含 OpenShift Container Platform 自定义主 API 证书密钥的文件的路径。
  • name 是集群的公共主机名。

对于 Ansible 允许,文件路径需要是系统的本地路径。证书被复制到 master 主机,并部署到 /etc/origin/master 目录中。

在保护 registry 时,将服务主机名和 IP 地址添加到 registry 的服务器证书中。主题备用名称(SAN)必须包含以下内容:

  • 两个服务主机名:

    docker-registry.default.svc.cluster.local
    docker-registry.default.svc
    Copy to Clipboard Toggle word wrap
  • 服务 IP 地址.

    例如:

    172.30.252.46
    Copy to Clipboard Toggle word wrap

    使用以下命令获取容器镜像 registry 服务 IP 地址:

    oc get service docker-registry --template='{{.spec.clusterIP}}'
    Copy to Clipboard Toggle word wrap
  • 公共主机名.

    docker-registry-default.apps.example.com
    Copy to Clipboard Toggle word wrap

    使用以下命令获取容器镜像 registry 公共主机名:

    oc get route docker-registry --template '{{.spec.host}}'
    Copy to Clipboard Toggle word wrap

例如,服务器证书应包含类似如下的 SAN 详情:

X509v3 Subject Alternative Name:
               DNS:docker-registry-public.openshift.com, DNS:docker-registry.default.svc, DNS:docker-registry.default.svc.cluster.local, DNS:172.30.2.98, IP Address:172.30.2.98
Copy to Clipboard Toggle word wrap

11.6. 为默认路由器配置自定义通配符证书

您可以使用默认通配符证书配置 OpenShift Container Platform 默认路由器。默认通配符证书为在 OpenShift Container Platform 中部署的应用程序提供了一种便捷方式,而无需自定义证书,即可使用默认加密。

注意

不建议在非生产环境中使用默认通配符证书。

要配置默认通配符证书,置备一个对 *.<app_domain> 有效的证书,其中 <app_domain>Ansible 清单文件 中的 openshift_master_default_subdomain 的值,默认为 /etc/ansible/hosts。置备后,将证书、密钥和 ca 证书文件放在 Ansible 主机上,并将下面这一行添加到您的 Ansible 清单文件。

openshift_hosted_router_certificate={"certfile": "/path/to/apps.c1-ocp.myorg.com.crt", "keyfile": "/path/to/apps.c1-ocp.myorg.com.key", "cafile": "/path/to/apps.c1-ocp.myorg.com.ca.crt"}
Copy to Clipboard Toggle word wrap

例如:

openshift_hosted_router_certificate={"certfile": "/home/cloud-user/star-apps.148.251.233.173.nip.io.cert.pem", "keyfile": "/home/cloud-user/star-apps.148.251.233.173.nip.io.key.pem", "cafile": "/home/cloud-user/ca-chain.cert.pem"}
Copy to Clipboard Toggle word wrap

参数值是:

  • cert File 是包含 OpenShift Container Platform 路由器通配符证书的文件的路径。
  • keyfile 是包含 OpenShift Container Platform 路由器通配符证书密钥的文件的路径。
  • CAfile 是包含此密钥和证书 root CA 的文件的路径。如果使用了中间 CA,则该文件应包含中间和 root CA。

如果这些证书文件是 OpenShift Container Platform 集群的新文件,请切换到 playbook 目录,并运行 Ansible deploy_router.yml playbook,将这些文件添加到 OpenShift Container Platform 配置文件中。playbook 将证书文件添加到 /etc/origin/master/ 目录中。

# ansible-playbook [-i /path/to/inventory] \
    /usr/share/ansible/openshift-ansible/playbooks/openshift-hosted/deploy_router.yml
Copy to Clipboard Toggle word wrap

如果 证书不是新的,例如,要更改现有证书或替换过期的证书,请切换到 playbook 目录并运行以下 playbook:

ansible-playbook /usr/share/ansible/openshift-ansible/playbooks/redeploy-certificates.yml
Copy to Clipboard Toggle word wrap
注意

要使此 playbook 运行,证书名称不得更改。如果证书名称改变,请重新运行 Ansible deploy_cluster.yml playbook,就像证书是新证书一样。

11.7. 为 Image Registry 配置自定义证书

OpenShift Container Platform 镜像 registry 是一个可促进构建和部署的内部服务。大多数与 registry 的通信都由 OpenShift Container Platform 中的内部组件处理。因此,您不应该需要替换 registry 服务本身使用的证书。

但是,默认情况下,registry 使用路由来允许外部系统和用户拉取和推送镜像。您可以使用带有提供给外部用户的自定义证书的重新加密路由,而不使用内部自签名证书。

要配置此功能,请将以下行添加到 Ansible 清单文件的 [OSEv3:vars] 部分,默认为 /etc/ansible/hosts 文件。指定要与 registry 路由一起使用的证书。

openshift_hosted_registry_routehost=registry.apps.c1-ocp.myorg.com 
1

openshift_hosted_registry_routecertificates={"certfile": "/path/to/registry.apps.c1-ocp.myorg.com.crt", "keyfile": "/path/to/registry.apps.c1-ocp.myorg.com.key", "cafile": "/path/to/registry.apps.c1-ocp.myorg.com-ca.crt"} 
2

openshift_hosted_registry_routetermination=reencrypt 
3
Copy to Clipboard Toggle word wrap
1
registry 的主机名。
2
cacert, cert, 和 key 文件的位置。
  • cert File 是包含 OpenShift Container Platform registry 证书的文件的路径。
  • keyfile 是包含 OpenShift Container Platform registry 证书密钥的文件的路径。
  • CAfile 是包含此密钥和证书 root CA 的文件的路径。如果使用了中间 CA,则该文件应包含中间和 root CA。
3
指定执行加密的位置:
  • 设置为 reencrypt,使用重新加密路由在边缘路由器中终止加密,并使用目的地提供的新证书重新加密。
  • 设置为 passthrough 会在目的地终止加密。目的地负责对数据进行解密。

11.8. 为负载均衡器配置自定义证书

如果您的 OpenShift Container Platform 集群使用默认的负载均衡器或企业级负载均衡器,您可以使用自定义证书使 Web 控制台和 API 使用公开签名的自定义证书。保留内部端点的现有内部证书。

以这种方式将 OpenShift Container Platform 配置为使用自定义证书:

  1. 编辑 master 配置文件servingInfo 部分:

    servingInfo:
      logoutURL: ""
      masterPublicURL: https://openshift.example.com:8443
      publicURL: https://openshift.example.com:8443/console/
      bindAddress: 0.0.0.0:8443
      bindNetwork: tcp4
      certFile: master.server.crt
      clientCA: ""
      keyFile: master.server.key
      maxRequestsInFlight: 0
      requestTimeoutSeconds: 0
      namedCertificates:
        - certFile: wildcard.example.com.crt 
    1
    
          keyFile: wildcard.example.com.key 
    2
    
          names:
            - "openshift.example.com"
      metricsPublicURL: "https://metrics.os.example.com/hawkular/metrics"
    Copy to Clipboard Toggle word wrap
    1
    OpenShift Container Platform API 和 Web 控制台的公共主机名的证书文件的路径。如有必要,将组成 证书链 的所有必需文件串联为提供给 certFile 参数的证书文件。
    2
    OpenShift Container Platform API 和 Web 控制台的公共主机名的密钥文件的路径。
    注意

    仅为与 masterPublicURLoauthConfig.assetPublicURL 设置关联的主机名配置 namedCertificates 部分。将自定义服务证书用于与 masterURL 关联的主机名会导致 TLS 错误,因为基础架构组件尝试使用内部 masterURL 主机联系主 API。

  2. 在 Ansible 清单文件中指定 openshift_master_cluster_public_hostnameopenshift_master_cluster_hostname 参数,默认为 /etc/ansible/hosts。这些值必须不同。如果它们相同,则命名证书将失败。

    # Native HA with External LB VIPs
    openshift_master_cluster_hostname=paas.example.com 
    1
    
    openshift_master_cluster_public_hostname=public.paas.example.com 
    2
    Copy to Clipboard Toggle word wrap
    1
    为 SSL 透传配置的内部负载均衡器的 FQDN。
    2
    带有自定义(public)证书的外部负载均衡器的 FQDN。

有关负载均衡器环境的信息,请参阅 供应商和自定义证书 SSL 终止(产品) 的 OpenShift Container Platform 参考架构

11.9. 将自定义证书重新引入到集群中

您可以将自定义 master 和自定义路由器证书重新创建到现有的 OpenShift Container Platform 集群中。

11.9.1. 将自定义 Master 证书重新引入到集群中

重新引进自定义证书

  1. 编辑 Ansible 清单文件,以设置 openshift_master_overwrite_named_certificates=true
  2. 使用 openshift_master_named_certificates 参数指定证书的路径。

    openshift_master_overwrite_named_certificates=true
    openshift_master_named_certificates=[{"certfile": "/path/on/host/to/crt-file", "keyfile": "/path/on/host/to/key-file", "names": ["public-master-host.com"], "cafile": "/path/on/host/to/ca-file"}] 
    1
    Copy to Clipboard Toggle word wrap
    1
    到一个 master API 证书的路径。如有必要,将组成 证书链 的所有必需文件串联为提供给 certFile 参数的证书文件。
  3. 进入 playbook 目录并运行以下 playbook:

    ansible-playbook /usr/share/ansible/openshift-ansible/playbooks/redeploy-certificates.yml
    Copy to Clipboard Toggle word wrap
  4. 如果您使用命名的证书:

    1. 更新每个 master 节点上的 master-config.yaml 文件中的证书参数
    2. 重启 OpenShift Container Platform master 服务以应用更改。

      # master-restart api
      # master-restart controllers
      Copy to Clipboard Toggle word wrap

11.9.2. 将自定义路由器证书重新引入到集群中

重新引进自定义路由器证书:

  1. 编辑 Ansible 清单文件,以设置 openshift_master_overwrite_named_certificates=true
  2. 使用 openshift_hosted_router_certificate 参数指定证书的路径。

    openshift_master_overwrite_named_certificates=true
    openshift_hosted_router_certificate={"certfile": "/path/on/host/to/app-crt-file", "keyfile": "/path/on/host/to/app-key-file", "cafile": "/path/on/host/to/app-ca-file"} 
    1
    Copy to Clipboard Toggle word wrap
  3. 进入 playbook 目录并运行以下 playbook:

    $ cd /usr/share/ansible/openshift-ansible
    $ ansible-playbook playbooks/openshift-hosted/redeploy-router-certificates.yml
    Copy to Clipboard Toggle word wrap

11.10. 将自定义证书与其他组件一起使用

如需有关其他组件(如日志记录和指标等)如何使用自定义证书,请参阅证书管理

第 12 章 重新部署证书

12.1. 概述

OpenShift Container Platform 使用证书为以下组件提供安全连接:

  • master(API 服务器和控制器)
  • etcd
  • 节点
  • registry
  • 路由器

您可以使用由安装程序提供的 Ansible playbook 来自动检查集群证书的过期日期。此外,还提供了 playbook 来自动备份和恢复这些证书,从而可以修复常见的证书错误。

重新部署证书的可能用例包括:

  • 安装程序检测到错误的主机名,发现问题的时间太晚。
  • 证书已过期,您需要更新它们。
  • 您有新的 CA 并想要改用证书。

12.2. 检查证书过期

您可以使用安装程序在可配置的窗口内过期任何证书,并通知您了解已经过期的任何证书。证书到期 playbook 使用 Ansible 角色 openshift_certificate_expiry

角色检查的证书包括:

  • Master 和节点服务证书
  • 来自 etcd secret 的路由器和 registry 服务证书
  • cluster-admin 用户的 master、node、router、registry 和 kubeconfig 文件
  • etcd 证书(包括嵌入式)

了解如何列出所有 OpenShift TLS 证书到期日期

12.2.1. 角色变量

openshift_certificate_expiry 角色使用以下变量:

Expand
表 12.1. 核心变量
变量名称默认值描述

openshift_certificate_expiry_config_base

/etc/origin

OpenShift Container Platform 基础配置目录。

openshift_certificate_expiry_warning_days

365

标记将在从现在开始的这个天数后过期的证书。

openshift_certificate_expiry_show_all

在结果中包含健康状态(非过期和非警告)的证书。

Expand
表 12.2. 可选变量
变量名称默认值描述

openshift_certificate_expiry_generate_html_report

生成到期检查结果的 HTML 报告。

openshift_certificate_expiry_html_report_path

$HOME/cert-expiry-report.yyyymmddTHHMMSS.html

保存 HTML 报告的完整路径。默认为由报告文件的主目录和时间戳后缀组成。

openshift_certificate_expiry_save_json_results

将到期检查结果保存为 JSON 文件。

openshift_certificate_expiry_json_results_path

$HOME/cert-expiry-report.yyyymmddTHHMMSS.json

保存 JSON 报告的完整路径。默认为由报告文件的主目录和时间戳后缀组成。

12.2.2. 运行证书过期 Playbook

OpenShift Container Platform 安装程序提供一组示例证书过期 playbook,它使用了 openshift_certificate_expiry 角色的不同配置集合。

这些 playbook 必须与代表集群 的清单文件 一起使用。要获得最佳结果,请使用 -v 选项运行 ansible-playbook

使用 easy-mode.yaml 示例 playbook,您可以根据需要尝试角色在对规格进行调整。此 playbook:

  • $HOME 目录中生成 JSON 和 stylized HTML 报告。
  • 将警告窗口设置得非常大,以保证您将总能得到结果。
  • 在结果中包含所有证书(健康或非 )。

进入 playbook 目录并运行 easy-mode.yaml playbook:

$ cd /usr/share/ansible/openshift-ansible
$ ansible-playbook -v -i <inventory_file> \
    playbooks/openshift-checks/certificate_expiry/easy-mode.yaml
Copy to Clipboard Toggle word wrap
其他 Playbook 示例

其它示例 playbook 还可用于直接从 /usr/share/ansible/openshift-ansible/playbooks/certificate_expiry/ 目录运行。

Expand
表 12.3. 其他 Playbook 示例
文件名使用方法

default.yaml

生成 openshift_certificate_expiry 角色的默认行为。

html_and_json_default_paths.yaml

在默认路径中生成 HTML 和 JSON 工件。

longer_warning_period.yaml

将到期警告窗口更改为 1500 天。

longer-warning-period-json-results.yaml

将过期警告窗口更改为 1500 天,并将结果保存为 JSON 文件。

运行其中任何示例 playbook:

$ cd /usr/share/ansible/openshift-ansible
$ ansible-playbook -v -i <inventory_file> \
    playbooks/openshift-checks/certificate_expiry/<playbook>
Copy to Clipboard Toggle word wrap

12.2.3. 输出格式

如上方所述,可以通过两种方式格式化检查报告。在用于机器解析的 JSON 格式,或作为风格的 HTML 页面,用于简单skimming。

HTML 报告

安装程序提供了 HTML 报告示例。您可以在浏览器中打开以下文件以查看它:

/usr/share/ansible/openshift-ansible/roles/openshift_certificate_expiry/examples/cert-expiry-report.html

JSON 报告

保存的 JSON 结果中有两个顶层键: 数据和 摘要

data 键是一个哈希值,其中键是检查每个主机的名称,值是每个对应主机上标识的证书的检查结果。

summary 键是一个哈希,用于总结证书的总数:

  • 在整个集群中检查
  • 这是正确的
  • 在配置的警告窗口中过期
  • 已过期

有关完整 JSON 报告示例,请参阅 /usr/share/ansible/openshift-ansible/roles/openshift_certificate_expiry/examples/cert-expiry-report.json

可以使用各种命令行工具,轻松检查 JSON 数据的摘要,是否有警告或过期时间。例如,使用 grep 查找单词 summary,并在匹配项后打印出两行 (-A2):

$ grep -A2 summary $HOME/cert-expiry-report.yyyymmddTHHMMSS.json
    "summary": {
        "warning": 16,
        "expired": 0
Copy to Clipboard Toggle word wrap

如果可用,也可以使用 jq 工具查找特定值。下面的前两个示例显示了如何仅选择一个值,可以是 warning已过期。第三个示例演示了如何同时选择这两个值:

$ jq '.summary.warning' $HOME/cert-expiry-report.yyyymmddTHHMMSS.json
16

$ jq '.summary.expired' $HOME/cert-expiry-report.yyyymmddTHHMMSS.json
0

$ jq '.summary.warning,.summary.expired' $HOME/cert-expiry-report.yyyymmddTHHMMSS.json
16
0
Copy to Clipboard Toggle word wrap

12.3. 重新部署证书

警告

重新部署 playbook 重启 control plane 服务,并可能导致集群停机。一个服务中的错误可能会导致 playbook 失败并影响集群健康状况。如果 playbook 失败,您可能需要手动解决问题并重新启动 playbook。playbook 必须按顺序完成所有任务才能成功。

使用以下 playbook 在所有相关主机上重新部署 master、etcd、node、registry 和路由器证书。您可以一次使用当前的 CA 重新部署所有这些证书,只为特定组件重新部署证书,或者自行重新部署新生成的或自定义 CA。

与证书到期 playbook 一样,这些 playbook 必须使用代表集群 的清单文件 运行。

特别是,清单必须通过以下变量指定或覆盖所有主机名和 IP 地址,以便它们与当前的集群配置匹配:

  • openshift_public_hostname
  • openshift_public_ip
  • openshift_master_cluster_hostname
  • openshift_master_cluster_public_hostname

您需要的 playbook 通过以下方式提供:

# yum install openshift-ansible
Copy to Clipboard Toggle word wrap
注意

任何证书在重新部署时自动生成的任何证书的有效性(以天为单位),也可以通过 Ansible 配置。请参阅 配置证书有效期

注意

OpenShift Container Platform CA 和 etcd 证书在 5 年后过期。签名的 OpenShift Container Platform 证书在两年后过期。

redeploy-certificates.yml playbook 不会 重新生成 OpenShift Container Platform CA 证书。使用当前 CA 证书创建新 master、etcd、node、registry 和路由器证书,为新证书签名。

这还包括以下串行重启:

  • etcd
  • 主服务
  • 节点服务

要使用当前的 OpenShift Container Platform CA 重新部署 master、etcd 和节点证书,请切换到 playbook 目录并运行此 playbook,指定您的清单文件:

$ cd /usr/share/ansible/openshift-ansible
$ ansible-playbook -i <inventory_file> \
    playbooks/redeploy-certificates.yml
Copy to Clipboard Toggle word wrap
重要

如果 OpenShift Container Platform CA 被重新部署为 openshift-master/redeploy-openshift-ca.yml playbook,则必须将 -e openshift_redeploy_openshift_ca=true 添加到这个命令。

openshift-master/redeploy-openshift-ca.yml playbook 通过生成新的 CA 证书并将更新的捆绑包分发到所有组件,包括客户端 kubeconfig 文件和可信 CA( CA-trust) 的节点数据库 (CA-trust)。

这还包括以下串行重启:

  • 主服务
  • 节点服务
  • docker

另外,您可以在重新部署证书时 指定自定义 CA 证书,而不依赖于 OpenShift Container Platform 生成的 CA。

当主服务重启时,registry 和路由器可以继续与 master 通信,而没有重新部署,因为主设备的 serving 证书相同,并且注册表和路由器仍然有效。

要重新部署新生成的或自定义 CA:

  1. 如果要使用自定义 CA,请在清单文件中设置以下变量。要使用当前的 CA,请跳过这一步。

    # Configure custom ca certificate
    # NOTE: CA certificate will not be replaced with existing clusters.
    # This option may only be specified when creating a new cluster or
    # when redeploying cluster certificates with the redeploy-certificates
    # playbook.
    openshift_master_ca_certificate={'certfile': '</path/to/ca.crt>', 'keyfile': '</path/to/ca.key>'}
    Copy to Clipboard Toggle word wrap

    如果 CA 证书由中间 CA 发布,则捆绑的证书必须包含 CA 的完整链(中间和 root 证书)来验证子证书。

    例如:

    $ cat intermediate/certs/intermediate.cert.pem \
          certs/ca.cert.pem >> intermediate/certs/ca-chain.cert.pem
    Copy to Clipboard Toggle word wrap
  2. 进入 playbook 目录并运行 openshift-master/redeploy-openshift-ca.yml playbook,指定您的清单文件:

    $ cd /usr/share/ansible/openshift-ansible
    $ ansible-playbook -i <inventory_file> \
        playbooks/openshift-master/redeploy-openshift-ca.yml
    Copy to Clipboard Toggle word wrap

    新的 OpenShift Container Platform CA 已就位,每当您想要在所有组件上重新部署由新 CA 签名的证书时,请使用 redeploy-certificates.yml playbook

    重要

    在新的 OpenShift Container Platform CA 之后使用 redeploy-certificates.yml playbook 时,您必须在 playbook 命令中添加 -e openshift_redeploy_openshift_ca=true

12.3.3. 重新部署新的 etcd CA

openshift-etcd/redeploy-ca.yml playbook 通过生成新的 CA 证书来重新部署 etcd CA 证书,并将更新的捆绑包分发到所有 etcd peers 和 master 客户端。

这还包括以下串行重启:

  • etcd
  • 主服务

重新部署新生成的 etcd CA:

  1. 运行 openshift-etcd/redeploy-ca.yml playbook,指定您的清单文件:

    $ cd /usr/share/ansible/openshift-ansible
    $ ansible-playbook -i <inventory_file> \
        playbooks/openshift-etcd/redeploy-ca.yml
    Copy to Clipboard Toggle word wrap
重要

首次运行 playbook/openshift-etcd/redeploy-ca.yml playbook 后,包含 CA 符号器的压缩捆绑包将保留到 /etc/etcd/etcd_ca.tgz 中。因为生成新 etcd 证书需要 CA 签名者,所以备份它们非常重要。

如果 playbook 再次运行,因为预注意它不会在磁盘上覆盖这个捆绑包。要再次运行 playbook,请备份并移动该路径中的捆绑包,然后运行 playbook。

当新的 etcd CA 已就绪后,每当您希望使用由 etcd 对等和 master 客户端上的新的 etcd CA 签发的证书进行重新部署时,您可以自行决定使用 openshift-etcd/redeploy-certificates.yml playbook。另外,除了 etcd peers 和 master 客户端外,您还可以使用 redeploy-certificates.yml playbook 为 OpenShift Container Platform 组件重新部署证书。

注意

etcd 证书重新部署可能会导致将 串行 复制到所有 master 主机上。

12.3.4. 重新部署 Master 和 Web 控制台证书

openshift-master/redeploy-certificates.yml playbook 会重新部署 master 证书和密钥。这包括 master 服务的串行重启。

要重新部署 master 证书和密钥,请切换到 playbook 目录并运行此 playbook,指定您的清单文件:

$ cd /usr/share/ansible/openshift-ansible
$ ansible-playbook -i <inventory_file> \
    playbooks/openshift-master/redeploy-certificates.yml
Copy to Clipboard Toggle word wrap
注意

如果使用命名证书,您必须更新每个 master-config.yaml 文件中的 命名证书参数。如有必要,将组成 证书链 的所有必需文件串联为提供给 certFile 参数的证书文件。

然后,重启 OpenShift Container Platform master 服务以应用更改。

重要

运行此 playbook 后,您必须通过删除包含服务证书的现有 secret 或密钥对 来重新生成任何服务签名证书或密钥对,或删除并重新添加注解到适当的服务。

如果需要,您可以在清单文件中设置 openshift_redeploy_service_signer=false 参数,以跳过对服务签名证书的重新部署。如果在清单文件中设置了 openshift_redeploy_openshift_ca=trueopenshift_redeploy_service_signer=true,则服务签名证书会在重新部署 master 证书时重新部署。如果设置了 openshift_redeploy_openshift_ca=false 或省略了参数,则服务 signer 证书永远不会重新部署。

12.3.5. 仅重新部署指定证书

openshift-master/redeploy-named-certificates.yml playbook 只重新部署命名的证书。运行此 playbook 也会完成 master 服务的串行重启。

要仅重新部署指定证书,请更改到包含 playbook 的目录,并运行此 playbook。

$ cd /usr/share/ansible/openshift-ansible
$ ansible-playbook -i <inventory_file> \
    playbooks/openshift-master/redeploy-named-certificates.yml
Copy to Clipboard Toggle word wrap
注意

ansible 清单文件中的 _ openshift_master_named_certificates_ 参数必须包含与 master-config.yaml 文件中同名的证书。如果更改了 certfilekeyfile 的名称,您必须更新每个 master-config.yaml 文件中的命名证书参数,然后重新启动 apicontrollers 服务。带有完整 ca 链的 cafile 已添加到 /etc/origin/master/ca-bundle.crt 中。

12.3.6. 只重新部署 etcd 证书

openshift-etcd/redeploy-certificates.yml playbook 只重新部署包含 master 客户端证书的 etcd 证书。

这还包括以下串行重启:

  • etcd
  • 主服务。

要重新部署 etcd 证书,请切换到 playbook 目录并运行此 playbook,指定您的清单文件:

$ cd /usr/share/ansible/openshift-ansible
$ ansible-playbook -i <inventory_file> \
    playbooks/openshift-etcd/redeploy-certificates.yml
Copy to Clipboard Toggle word wrap

12.3.7. 重新部署节点证书

默认情况下,节点证书有效期为一年。OpenShift Container Platform 会在节点接近到期时自动轮转节点证书。如果没有配置自动批准您必须手动批准证书签名请求(CSR)

如果您需要重新部署证书,因为 CA 证书已被更改,您可以使用 -e openshift_redeploy_openshift_ca=true 标记的 playbooks/redeploy-certificates.yml playbook。详情请参阅 使用当前 OpenShift Container Platform 和 etcd CA 重新部署所有证书。在运行此 playbook 时,CSR 会被自动批准。

12.3.8. 只重新部署 Registry 或路由器证书

openshift-hosted/redeploy-registry-certificates.ymlopenshift-hosted/redeploy-router-certificates.yml playbook 替换 registry 和路由器的安装程序创建的证书。如果自定义证书用于这些组件,请参阅 重新部署自定义 registry 或路由器证书 来手动替换它们。

12.3.8.1. 只重新部署 registry 证书

要重新部署 registry 证书,请切换到 playbook 目录并运行以下 playbook,指定您的清单文件:

$ cd /usr/share/ansible/openshift-ansible
$ ansible-playbook -i <inventory_file> \
    playbooks/openshift-hosted/redeploy-registry-certificates.yml
Copy to Clipboard Toggle word wrap
12.3.8.2. 只重新部署路由器证书

要重新部署路由器证书,请切换到 playbook 目录并运行以下 playbook,指定您的清单文件:

$ cd /usr/share/ansible/openshift-ansible
$ ansible-playbook -i <inventory_file> \
    playbooks/openshift-hosted/redeploy-router-certificates.yml
Copy to Clipboard Toggle word wrap

12.3.9. 重新部署自定义 registry 或路由器证书

当因为重新部署了 CA 节点被撤离时,registry 和路由器 pod 会重启。如果 registry 和路由器证书也未被新的 CA 重新部署,这可能会导致中断,因为它们无法使用其旧证书访问 master。

12.3.9.1. 手动重新部署 registry 证书

要手动重新部署 registry 证书,您必须将新的 registry 证书添加到名为 registry-certificates 的 secret 中,然后重新部署 registry:

  1. 使用以下步骤的其余部分切换到 default 项目:

    $ oc project default
    Copy to Clipboard Toggle word wrap
  2. 如果您的 registry 最初是在 OpenShift Container Platform 3.1 或更早版本上创建,它可能仍在使用环境变量来存储证书(这已被淘汰使用 secret)。

    1. 运行以下命令,并查找 OPENSHIFT_CA_DATAOPENSHIFT_CERT_DATAOPENSHIFT_KEY_DATA 环境变量:

      $ oc set env dc/docker-registry --list
      Copy to Clipboard Toggle word wrap
    2. 如果不存在,请跳过这一步。如果这样做,请创建以下 ClusterRoleBinding

      $ cat <<EOF |
      apiVersion: v1
      groupNames: null
      kind: ClusterRoleBinding
      metadata:
        creationTimestamp: null
        name: registry-registry-role
      roleRef:
        kind: ClusterRole
        name: system:registry
      subjects:
      - kind: ServiceAccount
        name: registry
        namespace: default
      userNames:
      - system:serviceaccount:default:registry
      EOF
      oc create -f -
      Copy to Clipboard Toggle word wrap

      然后,运行以下命令来删除环境变量:

      $ oc set env dc/docker-registry OPENSHIFT_CA_DATA- OPENSHIFT_CERT_DATA- OPENSHIFT_KEY_DATA- OPENSHIFT_MASTER-
      Copy to Clipboard Toggle word wrap
  3. 本地设置以下环境变量使其更复杂:

    $ REGISTRY_IP=`oc get service docker-registry -o jsonpath='{.spec.clusterIP}'`
    $ REGISTRY_HOSTNAME=`oc get route/docker-registry -o jsonpath='{.spec.host}'`
    Copy to Clipboard Toggle word wrap
  4. 创建新 registry 证书:

    $ oc adm ca create-server-cert \
        --signer-cert=/etc/origin/master/ca.crt \
        --signer-key=/etc/origin/master/ca.key \
        --hostnames=$REGISTRY_IP,docker-registry.default.svc,docker-registry.default.svc.cluster.local,$REGISTRY_HOSTNAME \
        --cert=/etc/origin/master/registry.crt \
        --key=/etc/origin/master/registry.key \
        --signer-serial=/etc/origin/master/ca.serial.txt
    Copy to Clipboard Toggle word wrap

    仅从 Ansible 主机清单文件中列出的第一个 master 运行 oc adm 命令,默认为 /etc/ansible/hosts

  5. 使用新的 registry 证书更新 registry-certificates secret:

    $ oc create secret generic registry-certificates \
        --from-file=/etc/origin/master/registry.crt,/etc/origin/master/registry.key \
        -o json --dry-run | oc replace -f -
    Copy to Clipboard Toggle word wrap
  6. 重新部署 registry:

    $ oc rollout latest dc/docker-registry
    Copy to Clipboard Toggle word wrap
12.3.9.2. 手动重新部署路由器证书

要手动重新部署路由器证书,您必须将新的路由器证书添加到名为 router-certs 的 secret 中,然后重新部署路由器:

  1. 使用以下步骤的其余部分切换到 default 项目:

    $ oc project default
    Copy to Clipboard Toggle word wrap
  2. 如果您的路由器最初是在 OpenShift Container Platform 3.1 或更早版本创建的,它可能仍然使用环境变量来存储证书,这已被使用 service serving 证书 secret。

    1. 运行以下命令并查找 OPENSHIFT_CA_DATAOPENSHIFT_CERT_DATAOPENSHIFT_KEY_DATA 环境变量:

      $ oc set env dc/router --list
      Copy to Clipboard Toggle word wrap
    2. 如果这些变量存在,请创建以下 ClusterRoleBinding

      $ cat <<EOF |
      apiVersion: v1
      groupNames: null
      kind: ClusterRoleBinding
      metadata:
        creationTimestamp: null
        name: router-router-role
      roleRef:
        kind: ClusterRole
        name: system:router
      subjects:
      - kind: ServiceAccount
        name: router
        namespace: default
      userNames:
      - system:serviceaccount:default:router
      EOF
      oc create -f -
      Copy to Clipboard Toggle word wrap
    3. 如果存在这些变量,请运行以下命令删除它们:

      $ oc set env dc/router OPENSHIFT_CA_DATA- OPENSHIFT_CERT_DATA- OPENSHIFT_KEY_DATA- OPENSHIFT_MASTER-
      Copy to Clipboard Toggle word wrap
  3. 获取证书。

    • 如果您使用外部证书颁发机构(CA)为证书进行签名,请创建新的证书并根据内部流程将其提供给 OpenShift Container Platform。
    • 如果使用内部 OpenShift Container Platform CA 签署证书,请运行以下命令:

      重要

      以下命令生成内部签名的证书。它仅被信任 OpenShift Container Platform CA 的客户端信任。

      $ cd /root
      $ mkdir cert ; cd cert
      $ oc adm ca create-server-cert \
          --signer-cert=/etc/origin/master/ca.crt \
          --signer-key=/etc/origin/master/ca.key \
          --signer-serial=/etc/origin/master/ca.serial.txt \
          --hostnames='*.hostnames.for.the.certificate' \
          --cert=router.crt \
          --key=router.key \
      Copy to Clipboard Toggle word wrap

      这些命令生成以下文件:

      • 名为 router.crt 的新证书。
      • 签名 CA 证书链 /etc/origin/master/ca.crt 的副本。如果您使用中间 CA,则此链可以包含多个证书。
      • 对应的名为 router.key 的私钥。
  4. 创建新文件以串联生成的证书:

    $ cat router.crt /etc/origin/master/ca.crt router.key > router.pem
    Copy to Clipboard Toggle word wrap
    注意

    只有在使用由 OpenShift CA 签名的证书时,此步骤才有效。如果使用自定义证书,则应该使用正确的 CA 链的文件而不是 /etc/origin/master/ca.crt

  5. 在生成新的 secret 前,备份当前 secret:

    $ oc get -o yaml --export secret router-certs > ~/old-router-certs-secret.yaml
    Copy to Clipboard Toggle word wrap
  6. 创建新 secret 以容纳新证书和密钥,并替换现有 secret 的内容:

    $ oc create secret tls router-certs --cert=router.pem \ 
    1
    
        --key=router.key -o json --dry-run | \
        oc replace -f -
    Copy to Clipboard Toggle word wrap
    1
    router.pem 是包含您生成的证书的串联的文件。
  7. 重新部署路由器:

    $ oc rollout latest dc/router
    Copy to Clipboard Toggle word wrap

    最初部署路由器时,会将注解添加到路由器的服务,该服务自动创建一个名为 router-metrics-tls服务证书 secret

    要手动重新部署 router-metrics-tls 证书,可通过删除 secret、删除并重新添加注解到路由器服务来重新创建服务证书,然后重新部署 router-metrics-tls secret:

  8. router 服务中删除以下注解:

    $ oc annotate service router \
        service.alpha.openshift.io/serving-cert-secret-name- \
        service.alpha.openshift.io/serving-cert-signed-by-
    Copy to Clipboard Toggle word wrap
  9. 删除现有的 router-metrics-tls secret。

    $ oc delete secret router-metrics-tls
    Copy to Clipboard Toggle word wrap
  10. 重新添加注解:

    $ oc annotate service router \
        service.alpha.openshift.io/serving-cert-secret-name=router-metrics-tls
    Copy to Clipboard Toggle word wrap

12.4. 管理证书签名请求

集群管理员可以查看证书签名请求(CSR)并批准或拒绝它们。

12.4.1. 查看证书签名请求

您可以查看证书签名请求(CSR)的列表。

  • 获取当前 CSR 列表。

    $ oc get csr
    Copy to Clipboard Toggle word wrap
  • 查看 CSR 的详细信息以验证其是否有效:

    $ oc describe csr <csr_name> 
    1
    Copy to Clipboard Toggle word wrap
    1
    <csr_name> 是当前 CSR 列表中 CSR 的名称。

12.4.2. 批准证书签名请求

您可以使用 oc certificate approve 命令手动批准证书签名请求(CSR)。

  • 批准 CSR:

    $ oc adm certificate approve <csr_name> 
    1
    Copy to Clipboard Toggle word wrap
    1
    <csr_name> 是当前 CSR 列表中 CSR 的名称。
  • 批准所有待处理的 CSR:

    $ oc get csr -o go-template='{{range .items}}{{if not .status}}{{.metadata.name}}{{"\n"}}{{end}}{{end}}' | xargs oc adm certificate approve
    Copy to Clipboard Toggle word wrap

12.4.3. 拒绝证书签名请求

您可以使用 oc certificate deny 命令手动拒绝证书签名请求(CSR)。

  • 拒绝 CSR:

    $ oc adm certificate deny <csr_name> 
    1
    Copy to Clipboard Toggle word wrap
    1
    <csr_name> 是当前 CSR 列表中 CSR 的名称。

12.4.4. 配置证书签名请求的自动批准

您可以在安装集群时将以下参数添加到 Ansible 清单文件,来配置节点证书签名请求(CSR):

openshift_master_bootstrap_auto_approve=true
Copy to Clipboard Toggle word wrap

添加此参数可让使用 bootstrap 凭证生成的所有 CSR,或者从之前验证的节点中批准,而无需管理员干预。

如需更多信息,请参阅配置集群变量

第 13 章 配置身份验证和用户代理

13.1. 概述

OpenShift Container Platform master 包含内置的 OAuth 服务器。开发人员和管理员获取 OAuth 访问令牌,以完成自身的 API 身份验证。

作为管理员,您可以使用 master 配置文件 配置 OAuth,以指定身份提供程序。最好 在集群安装过程中 配置身份提供程序,但您可以在安装后配置它。

注意

OpenShift Container Platform 用户名不能包括 /:%

Deny All identity provider 被默认使用,它拒绝对所有用户名和密码的访问。要允许访问,您必须选择不同的身份提供程序并配置 master 配置文件(默认为 /etc/origin/master/master-config.yaml )。

当您运行没有配置文件的 master 时,Allow All identity provider 会被默认使用,它允许任何非空用户名和密码登录。这可用于测试目的。要使用其他身份提供程序,或者修改任何 token, grant, 或 session options,您必须从配置文件运行 master。

注意

需要分配的角色以通过外部用户管理设置。

在修改了身份提供程序后,您必须重启 master 服务才能使更改生效:

# master-restart api
# master-restart controllers
Copy to Clipboard Toggle word wrap

13.2. 身份提供程序参数

所有身份提供程序都有四个参数:

Expand
参数描述

name

此提供程序名称作为前缀放在提供程序用户名前,以此组成身份名称。

challenge

true 时,来自非 Web 客户端(如 CLI)的未经身份验证的令牌请求会发送 WWW-Authenticate challenge 标头。不支持所有身份提供程序。

要防止跨站点请求伪造 (CSRF) 攻击,只有在请求上存在 X-CSRF-Token 标头时,才会发送浏览器客户端基本身份验证质询。希望接收基本 WWW-Authenticate 质询的客户端应将此标头设置为非空值。

login

true 时,来自 Web 客户端(如 Web 控制台)的未经身份验证的令牌请求会重定向到由该供应商支持的登录页面。不支持所有身份提供程序。

如果您希望在重定向到身份提供程序登录前将用户发送到品牌页面,然后在 master 配置文件中设置 oauthConfig → alwaysShowProviderSelection: true。此提供程序选择页面 可以自定义

mappingMethod

定义在用户登录时如何将新身份映射到用户。输入以下值之一:

claim
默认值。使用身份的首选用户名置备用户。如果具有该用户名的用户已映射到另一身份,则失败。
lookup
查找现有的身份、用户身份映射和用户,但不自动置备用户或身份。这允许集群管理员手动或使用外部流程设置身份和用户。使用此方法需要手动置备用户。在使用 Lookup 映射方法时,请参阅手动置备用户
generate
使用身份的首选用户名置备用户。如果拥有首选用户名的用户已映射到现有的身份,则生成一个唯一用户名。例如:myuser2。此方法不应与需要在 OpenShift Container Platform 用户名和身份提供程序用户名(如 LDAP 组同步)之间完全匹配的外部流程一同使用。
add
使用身份的首选用户名置备用户。如果已存在具有该用户名的用户,此身份将映射到现有用户,添加到该用户的现有身份映射中。如果配置了多个身份提供程序并且它们标识同一组用户并映射到相同的用户名,则需要进行此操作。
注意

在添加或更改身份提供程序时,您可以通过把 mappingMethod 参数设置为 add,将新提供程序中的身份映射到现有的用户。

13.3. 配置身份提供程序

OpenShift Container Platform 不支持为同一身份提供程序配置多个 LDAP 服务器。但是,您可以为更复杂的配置(如 LDAP 故障转移 )扩展基本身份验证。

您可以使用这些参数在安装过程中或安装后定义身份提供程序。

13.3.1. 使用 Ansible 配置身份提供程序

对于初始集群安装,但 Deny All identity provider 被默认配置,但可在安装过程中配置 openshift_master_identity_providers 参数OAuth 配置中的会话选项也可在清单文件中配置。

使用 Ansible 的用户身份供应商配置示例

# htpasswd auth
openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true', 'challenge': 'true', 'kind': 'HTPasswdPasswordIdentityProvider'}]
# Defining htpasswd users
#openshift_master_htpasswd_users={'user1': '<pre-hashed password>', 'user2': '<pre-hashed password>'}
# or
#openshift_master_htpasswd_file=/etc/origin/master/htpasswd

# Allow all auth
#openshift_master_identity_providers=[{'name': 'allow_all', 'login': 'true', 'challenge': 'true', 'kind': 'AllowAllPasswordIdentityProvider'}]

# LDAP auth
#openshift_master_identity_providers=[{'name': 'my_ldap_provider', 'challenge': 'true', 'login': 'true', 'kind': 'LDAPPasswordIdentityProvider', 'attributes': {'id': ['dn'], 'email': ['mail'], 'name': ['cn'], 'preferredUsername': ['uid']}, 'bindDN': '', 'bindPassword': '', 'insecure': 'false', 'url': 'ldap://ldap.example.com:389/ou=users,dc=example,dc=com?uid'}]
# Configuring the ldap ca certificate 
1

#openshift_master_ldap_ca=<ca text>
# or
#openshift_master_ldap_ca_file=<path to local ca file to use> 
2


# Available variables for configuring certificates for other identity providers:
#openshift_master_openid_ca
#openshift_master_openid_ca_file 
3

#openshift_master_request_header_ca
#openshift_master_request_header_ca_file 
4
Copy to Clipboard Toggle word wrap

1
如果您只为 LDAP 身份提供程序在 openshift_master_identity_providers 参数中指定了 'insecure': 'true',您可以省略 CA 证书。
2 3 4
如果您在运行 playbook 的主机上指定一个文件,则其内容将复制到 /etc/origin/master/<identity_provider_name>_<identity_provider_type>_ca.crt 文件中。身份供应商的名称是 openshift_master_identity_providers 参数的值, ldap, openid, 或 request_header。如果您没有指定 CA 文本或本地 CA 文件的路径,您必须将 CA 证书放在该位置。如果指定多个身份提供程序,则必须手动放置每个供应商的 CA 证书。您无法更改此位置。

您可以指定多个身份提供程序。如果这样做,您必须将每个身份提供程序的 CA 证书放在 /etc/origin/master/ 目录中。例如,您可以在 openshift_master_identity_providers 值中包含以下供应商:

openshift_master_identity_providers:
- name: foo
  provider:
    kind: OpenIDIdentityProvider
    ...
- name: bar
  provider:
    kind: OpenIDIdentityProvider
    ...
- name: baz
  provider:
    kind: RequestHeaderIdentityProvider
    ...
Copy to Clipboard Toggle word wrap

您必须将这些身份提供程序的 CA 证书放在以下文件中:

  • /etc/origin/master/foo_openid_ca.crt
  • /etc/origin/master/bar_openid_ca.crt
  • /etc/origin/master/baz_requestheader_ca.crt

13.3.2. 在 master 配置文件中配置身份提供程序

您可以通过修改 master 主配置文件,配置 master 主机以使用所需的身份提供程序进行身份验证。

例 13.1. master 配置文件中的身份提供程序配置示例

...
oauthConfig:
  identityProviders:
  - name: htpasswd_auth
    challenge: true
    login: true
    mappingMethod: "claim"
...
Copy to Clipboard Toggle word wrap

当设置为默认的 声明 值时,如果身份映射到之前存在的用户名,OAuth 将失败。

13.3.2.1. 使用 lookup 映射方法时手动置备用户

使用 lookup 映射方法时,用户置备由外部系统通过 API 进行。通常,身份在登录时自动映射到用户。'lookup' 映射方法自动禁用这个自动映射,这需要您手动置备用户。

如需有关身份对象的更多信息,请参阅 Identity user API obejct。

如果使用 lookup 映射方法,请在配置身份提供程序后为每个用户执行以下步骤:

  1. 如果还没有创建,创建一个 OpenShift Container Platform 用户:

    $ oc create user <username>
    Copy to Clipboard Toggle word wrap

    例如,以下命令会创建一个 OpenShift Container Platform 用户 bob

    $ oc create user bob
    Copy to Clipboard Toggle word wrap
  2. 如果尚未创建,请创建一个 OpenShift Container Platform 身份。使用身份提供程序的名称,并在身份提供程序范围内唯一代表此身份的名称:

    $ oc create identity <identity-provider>:<user-id-from-identity-provider>
    Copy to Clipboard Toggle word wrap

    & lt;identity-provider > 是 master 配置中身份提供程序的名称,如下面的相应身份提供程序部分所示。

    例如,以下命令会创建一个身份提供程序 ldap_provider 和身份提供程序用户名 bob_s 的身份。

    $ oc create identity ldap_provider:bob_s
    Copy to Clipboard Toggle word wrap
  3. 为创建用户和身份创建 user/identity 映射:

    $ oc create useridentitymapping <identity-provider>:<user-id-from-identity-provider> <username>
    Copy to Clipboard Toggle word wrap

    例如,以下命令将身份映射到用户:

    $ oc create useridentitymapping ldap_provider:bob_s bob
    Copy to Clipboard Toggle word wrap

13.3.3. 允许所有

identityProviders 小节中设置 AllowAllPasswordIdentityProvider,以允许任何非空用户名和密码登录。

例 13.2. 使用 AllowAllPasswordIdentityProvider 的 master 配置

oauthConfig:
  ...
  identityProviders:
  - name: my_allow_provider 
1

    challenge: true 
2

    login: true 
3

    mappingMethod: claim 
4

    provider:
      apiVersion: v1
      kind: AllowAllPasswordIdentityProvider
Copy to Clipboard Toggle word wrap
1
此提供程序名称作为前缀放在提供程序用户名前,以此组成身份名称。
2
true 时,来自非 Web 客户端(如 CLI)的未经身份验证的令牌请求会为此提供程序发送 WWW-Authenticate 质询标头。
3
true 时,来自 Web 客户端(如 Web 控制台)的未经身份验证的令牌请求会重定向到由该供应商支持的登录页面。
4
控制如何在此提供程序的身份和用户对象之间建立映射,如上 所述

13.3.4. 拒绝所有

identityProviders 小节中设置 DenyAllPasswordIdentityProvider,以拒绝对所有用户名和密码的访问。

例 13.3. 使用 DenyAllPasswordIdentityProvider 的 master 配置

oauthConfig:
  ...
  identityProviders:
  - name: my_deny_provider 
1

    challenge: true 
2

    login: true 
3

    mappingMethod: claim 
4

    provider:
      apiVersion: v1
      kind: DenyAllPasswordIdentityProvider
Copy to Clipboard Toggle word wrap
1
此提供程序名称作为前缀放在提供程序用户名前,以此组成身份名称。
2
true 时,来自非 Web 客户端(如 CLI)的未经身份验证的令牌请求会为此提供程序发送 WWW-Authenticate 质询标头。
3
true 时,来自 Web 客户端(如 Web 控制台)的未经身份验证的令牌请求会重定向到由该供应商支持的登录页面。
4
控制如何在此提供程序的身份和用户对象之间建立映射,如上 所述

13.3.5. HTPasswd

identityProviders 小节中设置 HTPasswdPasswordIdentityProvider,针对使用 htpasswd 生成的文件验证用户名和密码。

注意

htpasswd 工具程序位于 httpd-tools 软件包中:

# yum install httpd-tools
Copy to Clipboard Toggle word wrap

OpenShift Container Platform 支持 Bcrypt、SHA-1 和 MD5 加密哈希功能,而 MD5 是 htpasswd 的默认值。目前不支持明文、加密文本和其他散列功能。

如果修改时间更改,则无格式文件重新读取,无需重新启动服务器。

重要

由于 OpenShift Container Platform master API 现在作为静态 pod 运行,因此您必须在 /etc/origin/master/ 中创建 HTPasswdPasswordIdentityProvider htpasswd 文件,使其可以被容器读取。

使用 htpasswd 命令:

  • 要创建带有用户名和散列密码的平面文件,请运行:

    $ htpasswd -c /etc/origin/master/htpasswd <user_name>
    Copy to Clipboard Toggle word wrap

    然后,输入 并确认该用户的明文密码。该命令将生成散列版本的密码。

    例如:

    htpasswd -c /etc/origin/master/htpasswd user1
    New password:
    Re-type new password:
    Adding password for user user1
    Copy to Clipboard Toggle word wrap
    注意

    您可以包含 -b 选项,用于在命令行中提供密码:

    $ htpasswd -c -b <user_name> <password>
    Copy to Clipboard Toggle word wrap

    例如:

    $ htpasswd -c -b file user1 MyPassword!
    Adding password for user user1
    Copy to Clipboard Toggle word wrap
  • 要在文件中添加或更新登录,请运行:

    $ htpasswd /etc/origin/master/htpasswd <user_name>
    Copy to Clipboard Toggle word wrap
  • 要从文件中删除登录,请运行:

    $ htpasswd -D /etc/origin/master/htpasswd <user_name>
    Copy to Clipboard Toggle word wrap

例 13.4. 使用 HTPasswdPasswordIdentityProvider 的 master 配置

oauthConfig:
  ...
  identityProviders:
  - name: my_htpasswd_provider 
1

    challenge: true 
2

    login: true 
3

    mappingMethod: claim 
4

    provider:
      apiVersion: v1
      kind: HTPasswdPasswordIdentityProvider
      file: /etc/origin/master/htpasswd 
5
Copy to Clipboard Toggle word wrap
1
此提供程序名称作为前缀放在提供程序用户名前,以此组成身份名称。
2
true 时,来自非 Web 客户端(如 CLI)的未经身份验证的令牌请求会为此提供程序发送 WWW-Authenticate 质询标头。
3
true 时,来自 Web 客户端(如 Web 控制台)的未经身份验证的令牌请求会重定向到由该供应商支持的登录页面。
4
控制如何在此提供程序的身份和用户对象之间建立映射,如上 所述
5
使用 htpasswd 生成的文件。

13.3.6. Keystone

Keystone 是一个提供身份、令牌、目录和策略服务的 OpenStack 项目。您可以将 OpenShift Container Platform 集群与 Keystone 集成,以便通过配置为将用户存储在内部数据库中的 OpenStack Keystone v3 服务器启用共享身份验证。此配置允许用户使用其 Keystone 凭证登录 OpenShift Container Platform。

您可以配置与 Keystone 的集成,以便 OpenShift Container Platform 的新用户基于 Keystone 用户名或者唯一 Keystone ID。使用这两种方法时,用户可以输入其 Keystone 用户名和密码进行登录。使 OpenShift Container Platform 用户基于 Keystone ID 更为安全。如果删除了某一 Keystone 用户并使用其用户名创建了新的 Keystone 用户,新用户或许能够访问旧用户的资源。

13.3.6.1. 在 master 上配置身份验证
  1. 如果您有:

    • 已完成 Openshift 的安装,然后将 /etc/origin/master/master-config.yaml 文件复制到新目录中,例如:

      $ cd /etc/origin/master
      $ mkdir keystoneconfig; cp master-config.yaml keystoneconfig
      Copy to Clipboard Toggle word wrap
    • 尚未安装 OpenShift Container Platform,然后启动 OpenShift Container Platform API 服务器,指定(future)OpenShift Container Platform master 的主机名,以及一个用于存储由 start 命令创建的配置文件的目录:

      $ openshift start master --public-master=<apiserver> --write-config=<directory>
      Copy to Clipboard Toggle word wrap

      例如:

      $ openshift start master --public-master=https://myapiserver.com:8443 --write-config=keystoneconfig
      Copy to Clipboard Toggle word wrap
      注意

      如果要使用 Ansible 安装,您必须将 identityProvider 配置添加到 Ansible playbook 中。如果在使用 Ansible 安装后使用以下步骤手动修改配置,那么每当您重新运行安装工具或升级时,您都会丢失任何修改。

  2. 编辑新的 keystoneconfig/master-config.yaml 文件的 identityProviders 小节,并复制示例 KeystonePasswordIdentityProvider 配置并粘贴它来替换现有的小节:

    oauthConfig:
      ...
      identityProviders:
      - name: my_keystone_provider 
    1
    
        challenge: true 
    2
    
        login: true 
    3
    
        mappingMethod: claim 
    4
    
        provider:
          apiVersion: v1
          kind: KeystonePasswordIdentityProvider
          domainName: default 
    5
    
          url: http://keystone.example.com:5000 
    6
    
          ca: ca.pem 
    7
    
          certFile: keystone.pem 
    8
    
          keyFile: keystonekey.pem 
    9
    
          useKeystoneIdentity: false 
    10
    Copy to Clipboard Toggle word wrap
    1
    此提供程序名称作为前缀放在提供程序用户名前,以此组成身份名称。
    2
    true 时,来自非 Web 客户端(如 CLI)的未经身份验证的令牌请求会为此提供程序发送 WWW-Authenticate 质询标头。
    3
    true 时,来自 Web 客户端(如 Web 控制台)的未经身份验证的令牌请求会重定向到由该供应商支持的登录页面。
    4
    控制如何在此提供程序的身份和用户对象之间建立映射,如上 所述
    5
    Keystone 域名。在 Keystone 中,用户名是特定于域的。只支持一个域。
    6
    用于连接到 Keystone 服务器的 URL(必需)。
    7
    可选:用于验证所配置 URL 的服务器证书的证书捆绑包。
    8
    可选:向配置的 URL 发出请求时要出现的客户端证书。
    9
    客户端证书的密钥。如果指定了 certFile,则需要此项。
    10
    true 时,表示用户通过 Keystone ID 进行身份验证,而不是由 Keystone 用户名进行身份验证。设置为 false 以根据用户名进行身份验证。
  3. identityProviders 小节进行以下修改:

    1. 更改提供程序 名称 ("my_keystone_provider")以匹配您的 Keystone 服务器。此名称作为前缀放在提供程序用户名前,以此组成身份名称。
    2. 如果需要,更改 mappingMethod 来控制如何在提供程序的身份和用户对象之间建立映射。
    3. domainName 更改为 OpenStack Keystone 服务器的域名。在 Keystone 中,用户名是特定于域的。只支持一个域。
    4. 指定用于连接 OpenStack Keystone 服务器的 url
    5. 另外,要根据 Keystone ID(而非 Keystone 用户名)验证用户身份,可将KeystoneIdentity 设置为 true
    6. (可选)将 ca 更改为证书捆绑包,以用于验证所配置 URL 的服务器证书。
    7. (可选)将 certFile 更改为客户端证书,使其在向配置的 URL 发出请求时显示。
    8. 如果指定了 certFile,您必须将 keyFile 更改为客户端证书的密钥。
  4. 保存您的更改并关闭该文件。
  5. 启动 OpenShift Container Platform API 服务器,指定您刚才修改的配置文件:

    $ openshift start master --config=<path/to/modified/config>/master-config.yaml
    Copy to Clipboard Toggle word wrap

配置之后,系统会提示您使用其 Keystone 凭据登录 OpenShift Container Platform Web 控制台。

13.3.6.2. 使用 Keystone 身份验证创建用户

在 OpenShift Container Platform 中与外部身份验证供应商(如本例中为 Keystone)集成时,您不会在 OpenShift Container Platform 中创建用户。Keystone 是记录系统,表示用户在 Keystone 数据库中定义用户,并且配置的身份验证服务器的有效 Keystone 用户名的任何用户都可以登录。

要为 OpenShift Container Platform 添加用户,用户必须存在于 Keystone 数据库中,如果需要,必须为该用户创建新的 Keystone 帐户。

13.3.6.3. 验证用户

登录一个或多个用户后,您可以运行 oc get users 来查看用户列表并验证用户是否已成功创建:

例 13.5. oc get users 命令的输出

$ oc get users
NAME         UID                                    FULL NAME   IDENTITIES
bobsmith     a0c1d95c-1cb5-11e6-a04a-002186a28631   Bob Smith   keystone:bobsmith 
1
Copy to Clipboard Toggle word wrap
1
OpenShift Container Platform 中的身份由作为 Keystone 用户名前缀的身份提供商名称组成。

在这里,您可能需要 了解如何管理用户角色

13.3.7. LDAP 身份验证

identityProviders 小节中设置 LDAPPasswordIdentityProvider,以使用简单的绑定身份验证根据 LDAPv3 服务器验证用户名和密码。

注意

如果您需要 LDAP 服务器故障转移,而不是按照以下步骤,通过 为 LDAP 故障转移配置 SSSD 来扩展基本验证方法。

在身份验证过程中,搜索 LDAP 目录中与提供的用户名匹配的条目。如果找到一个唯一匹配项,则尝试使用该条目的可分辨名称 (DN) 以及提供的密码进行简单绑定。

执行下面这些步骤:

  1. 通过将配置的 url 中的属性和过滤器与用户提供的用户名组合来生成搜索过滤器。
  2. 使用生成的过滤器搜索目录。如果搜索返回的不是一个条目,则拒绝访问。
  3. 尝试使用搜索所获条目的 DN 和用户提供的密码绑定到 LDAP 服务器。
  4. 如果绑定失败,则拒绝访问。
  5. 如果绑定成功,则将配置的属性用作身份、电子邮件地址、显示名称和首选用户名来构建一个身份。

配置的 url 是 RFC 2255 URL,指定要使用的 LDAP 主机和搜索参数。URL 的语法是:

ldap://host:port/basedn?attribute?scope?filter
Copy to Clipboard Toggle word wrap

对于以上示例:

Expand
URL 组件描述

ldap

对于常规 LDAP,使用 ldap 字符串。对于安全 LDAP (LDAPS),改为使用 ldaps

host:port

LDAP 服务器的名称和端口。LDAP 默认为 localhost:389,LDAPS 则默认为 localhost:636

basedn

所有搜索都应从中开始的目录分支的 DN。至少,这必须是目录树的顶端,但也可指定目录中的子树。

attribute

要搜索的属性。虽然 RFC 2255 允许使用逗号分隔属性列表,但无论提供多少个属性,都仅使用第一个属性。如果没有提供任何属性,则默认使用 uid。建议选择一个在您使用的子树中的所有条目间是唯一的属性。

scope

搜索的范围。可以是 onesub。如果未提供范围,则默认使用 sub 范围。

filter

有效的 LDAP 搜索过滤器。如果未提供,则默认为 (objectClass=*)

在进行搜索时,属性、过滤器和提供的用户名会组合在一起,创建类似如下的搜索过滤器:

(&(<filter>)(<attribute>=<username>))
Copy to Clipboard Toggle word wrap

例如,可考虑如下 URL:

ldap://ldap.example.com/o=Acme?cn?sub?(enabled=true)
Copy to Clipboard Toggle word wrap

当客户端尝试使用用户名 bob 连接时,生成的搜索过滤器将为 (&(enabled=true)(cn=bob))

如果 LDAP 目录需要身份验证才能搜索,请指定用于执行条目搜索的 bindDNbindPassword

使用 LDAPPasswordIdentityProvider 的 master 配置

oauthConfig:
  ...
  identityProviders:
  - name: "my_ldap_provider" 
1

    challenge: true 
2

    login: true 
3

    mappingMethod: claim 
4

    provider:
      apiVersion: v1
      kind: LDAPPasswordIdentityProvider
      attributes:
        id: 
5

        - dn
        email: 
6

        - mail
        name: 
7

        - cn
        preferredUsername: 
8

        - uid
      bindDN: "" 
9

      bindPassword: "" 
10

      ca: my-ldap-ca-bundle.crt 
11

      insecure: false 
12

      url: "ldap://ldap.example.com/ou=users,dc=acme,dc=com?uid" 
13
Copy to Clipboard Toggle word wrap

1
此提供程序名称作为前缀放在返回的用户 ID 前,以此组成身份名称。
2
true 时,来自非 Web 客户端(如 CLI)的未经身份验证的令牌请求会为此提供程序发送 WWW-Authenticate 质询标头。
3
true 时,来自 Web 客户端(如 Web 控制台)的未经身份验证的令牌请求会重定向到由该供应商支持的登录页面。
4
控制如何在此提供程序的身份和用户对象之间建立映射,如上 所述
5
用作身份的属性列表。使用第一个非空属性。至少需要一个属性。如果列出的属性都没有值,身份验证会失败。
6
用作电子邮件地址的属的列表。使用第一个非空属性。
7
用作显示名称的属性列表。使用第一个非空属性。
8
为此身份置备用户时用作首选用户名的属性列表。使用第一个非空属性。
9
在搜索阶段用来绑定的可选 DN。
10
在搜索阶段用来绑定的可选密码。此值也可在 环境变量、外部文件或加密文件 中提供。
11
用于验证所配置 URL 的服务器证书的证书捆绑包。此文件的内容复制到 /etc/origin/master/<identity_provider_name>_ldap_ca.crt 文件中。身份提供程序名称是 openshift_master_identity_providers 参数的值。如果您没有指定 CA 文本或本地 CA 文件的路径,您必须将 CA 证书放在 /etc/origin/master/ 目录中。如果指定多个身份提供程序,您必须手动将每个供应商的 CA 证书放在 /etc/origin/master/ 目录中。您无法更改此位置。只有在清单文件中设置了 insecure: false 时,才会定义证书捆绑包。
12
true 时,不会对服务器进行 TLS 连接。为 false 时,ldaps:// URL 使用 TLS 进行连接,并且 ldap:// URL 升级到 TLS。
13
RFC 2255 URL,指定要使用的 LDAP 主机和搜索参数,如上所述
注意

要将用户列在 LDAP 集成的白名单中,请使用 lookup 映射方法。在允许从 LDAP 登录前,集群管理员必须为每个 LDAP 用户创建身份和用户对象。

13.3.8. 基本身份验证(远程)

基本身份验证是一种通用后端集成机制,用户可以使用针对远程身份提供程序验证的凭证来登录 OpenShift Container Platform。

由于基本身份验证是通用的,因此您可以在高级身份验证配置中使用此身份提供程序。您可以配置 LDAP 故障转移,或使用 容器化基本身份验证 存储库作为另一个高级远程基本身份验证配置的起点。

Important

基本身份验证必须使用 HTTPS 连接到远程服务器,以防止遭受用户 ID 和密码嗅探以及中间人攻击。

配置了 BasicAuthPasswordIdentityProvider 后,用户将其用户名和密码发送到 OpenShift Container Platform,然后通过发出服务器对服务器请求来传递凭证作为 Basic Auth 标头来针对远程服务器验证这些凭证。这要求用户在登录期间向 OpenShift Container Platform 发送凭证。

注意

这只适用于用户名/密码登录机制,并且 OpenShift Container Platform 必须能够向远程身份验证服务器发出网络请求。

identityProviders 小节中设置 BasicAuthPasswordIdentityProvider,以使用 server-to-server 基本身份验证请求对远程服务器验证用户名和密码。针对受基本身份验证保护并返回 JSON 的远程 URL 验证用户名和密码。

401 响应表示身份验证失败。

200 状态或出现非空“error”键表示出现错误:

{"error":"Error message"}
Copy to Clipboard Toggle word wrap

200 状态并带有 sub(subject)键则表示成功:

{"sub":"userid"} 
1
Copy to Clipboard Toggle word wrap
1
主体必须是经过身份验证的用户所特有的,而且必须不可修改。

成功响应可能会(可选)提供额外的数据,例如:

  • 使用 name 键的显示名称。例如:

    {"sub":"userid", "name": "User Name", ...}
    Copy to Clipboard Toggle word wrap
  • 使用 email 键的电子邮件地址。例如:

    {"sub":"userid", "email":"user@example.com", ...}
    Copy to Clipboard Toggle word wrap
  • 使用 preferred_username 键的首选用户名。这可用在唯一不可改主体是数据库密钥或 UID 且存在更易读名称的情形中。为经过身份验证的身份置备 OpenShift Container Platform 用户时,这可用作提示。例如:

    {"sub":"014fbff9a07c", "preferred_username":"bob", ...}
    Copy to Clipboard Toggle word wrap
13.3.8.1. 在 master 上配置身份验证
  1. 如果您有:

    • 已完成 Openshift 的安装,然后将 /etc/origin/master/master-config.yaml 文件复制到新目录中,例如:

      $ mkdir basicauthconfig; cp master-config.yaml basicauthconfig
      Copy to Clipboard Toggle word wrap
    • 尚未安装 OpenShift Container Platform,然后启动 OpenShift Container Platform API 服务器,指定(future)OpenShift Container Platform master 的主机名,以及一个用于存储由 start 命令创建的配置文件的目录:

      $ openshift start master --public-master=<apiserver> --write-config=<directory>
      Copy to Clipboard Toggle word wrap

      例如:

      $ openshift start master --public-master=https://myapiserver.com:8443 --write-config=basicauthconfig
      Copy to Clipboard Toggle word wrap
      注意

      如果要使用 Ansible 安装,您必须将 identityProvider 配置添加到 Ansible playbook 中。如果在使用 Ansible 安装后使用以下步骤手动修改配置,那么每当您重新运行安装工具或升级时,您都会丢失任何修改。

  2. 编辑新的 master-config.yaml 文件的 identityProviders 小节,并复制 示例 BasicAuthPasswordIdentityProvider 配置 并粘贴它来替换现有的小节:

    oauthConfig:
      ...
      identityProviders:
      - name: my_remote_basic_auth_provider 
    1
    
        challenge: true 
    2
    
        login: true 
    3
    
        mappingMethod: claim 
    4
    
        provider:
          apiVersion: v1
          kind: BasicAuthPasswordIdentityProvider
          url: https://www.example.com/remote-idp 
    5
    
          ca: /path/to/ca.file 
    6
    
          certFile: /path/to/client.crt 
    7
    
          keyFile: /path/to/client.key 
    8
    Copy to Clipboard Toggle word wrap
    1
    此提供程序名称作为前缀放在返回的用户 ID 前,以此组成身份名称。
    2
    true 时,来自非 Web 客户端(如 CLI)的未经身份验证的令牌请求会为此提供程序发送 WWW-Authenticate 质询标头。
    3
    true 时,来自 Web 客户端(如 Web 控制台)的未经身份验证的令牌请求会重定向到由该供应商支持的登录页面。
    4
    控制如何在此提供程序的身份和用户对象之间建立映射,如上 所述
    5
    接受基本身份验证标头中凭证的 URL。
    6
    可选:用于验证所配置 URL 的服务器证书的证书捆绑包。
    7
    可选:向配置的 URL 发出请求时要出现的客户端证书。
    8
    客户端证书的密钥。如果指定了 certFile,则需要此项。

    identityProviders 小节进行以下修改:

    1. 将供应商名称设置为与您的部署的唯一且相关内容。此名称作为前缀放在返回的用户 ID 前,以此组成身份名称。
    2. 如果需要,设置 mappingMethod 来控制如何在提供程序的身份和用户对象之间建立映射。
    3. 指定 HTTPS URL 用于连接到接受基本身份验证标头中凭证的服务器。
    4. (可选)将 ca 设置为证书捆绑包,以使用 以验证所配置 URL 的服务器证书,或将其留空,以使用系统信任的根证书。
    5. (可选)删除或将 certFile 设置为客户端证书,以便在向配置的 URL 发出请求时显示。
    6. 如果指定了 certFile,您必须将 keyFile 设置为客户端证书的密钥。
  3. 保存您的更改并关闭该文件。
  4. 启动 OpenShift Container Platform API 服务器,指定您刚才修改的配置文件:

    $ openshift start master --config=<path/to/modified/config>/master-config.yaml
    Copy to Clipboard Toggle word wrap

配置后,系统会提示您使用其基本身份验证凭证登录 OpenShift Container Platform Web 控制台。

13.3.8.2. 故障排除

最常见的问题与后端服务器网络连接相关。要进行简单调试,请在 master 上运行 curl 命令。要测试成功的登录,请将以下示例命令中的 <user><password> 替换为有效的凭证。要测试无效的登录,请将它们替换为错误的凭证。

curl --cacert /path/to/ca.crt --cert /path/to/client.crt --key /path/to/client.key -u <user>:<password> -v https://www.example.com/remote-idp
Copy to Clipboard Toggle word wrap

成功响应

200 状态并带有 sub(subject)键则表示成功:

{"sub":"userid"}
Copy to Clipboard Toggle word wrap

subject 必须是经过身份验证的用户所特有的,而且必须不可修改。

成功响应可能会(可选)提供额外的数据,例如:

  • 使用 name 键的显示名称:

    {"sub":"userid", "name": "User Name", ...}
    Copy to Clipboard Toggle word wrap
  • 使用 email 键的电子邮件地址:

    {"sub":"userid", "email":"user@example.com", ...}
    Copy to Clipboard Toggle word wrap
  • 使用 preferred_username 键的首选用户名:

    {"sub":"014fbff9a07c", "preferred_username":"bob", ...}
    Copy to Clipboard Toggle word wrap

    preferred_username 键可用在唯一不可改主体是数据库密钥或 UID 且存在更易读名称的情形中。为经过身份验证的身份置备 OpenShift Container Platform 用户时,这可用作提示。

失败的响应

  • 401 响应表示身份验证失败。
  • 200 状态或带有非空“error”键表示错误:{"error":"Error message"}

13.3.9. 请求标头(Request header)

identityProviders 小节中设置 RequestHeaderIdentityProvider,以标识请求标头值中的用户,如 X-Remote-User。它通常与设定请求标头值的身份验证代理一起使用。这与 OpenShift Enterprise 2 中的远程用户插件 是,管理员可以提供 Kerberos、LDAP 和许多其他形式的企业身份验证。

注意

您还可以将请求标头身份提供程序用于高级配置,如由社区支持的 SAML 身份验证。请注意,红帽不支持 SAML 验证。

要使用户使用这个身份提供程序进行身份验证,必须通过身份验证代理访问 https://<master>/oauth/authorize (及子路径)。要达到此目的,请将 OAuth 服务器配置为将 OAuth 令牌的未经身份验证的请求重定向到代理到 https://<master>/oauth/authorize 的代理端点

重定向来自希望基于浏览器型登录流的客户端的未经身份验证请求:

  1. login 参数设置为 true
  2. provider.loginURL 参数设置为身份验证代理 URL,该代理将验证交互式客户端并将其请求代理到 https://<master>/oauth/authorize

重定向来自希望 WWW-Authenticate 质询的客户端的未经身份验证请求:

  1. challenge 参数设置为 true
  2. provider.challengeURL 参数设置为身份验证代理 URL,该代理将验证希望 WWW-Authenticate 质询的客户端,然后将请求代理到 https://<master>/oauth/authorize

provider.challengeURLprovider.loginURL 参数可以在 URL 的查询部分中包含以下令牌:

  • ${url} 替换为当前的 URL,进行转义以在查询参数中安全使用。

    例如:https://www.example.com/sso-login?then=${url}

  • ${query} 替换为当前的查询字符串,不进行转义。

    例如:https://www.example.com/auth-proxy/oauth/authorize?${query}

警告

如果您期望未经身份验证的请求可以访问 OAuth 服务器,则需要为此此身份提供程序设置 clientCA 参数,以便在检查请求标头检查用户名的标头前检查传入的请求。否则,任何向 OAuth 服务器直接请求都可通过设置请求标头来模拟该提供程序的任何身份。

使用 RequestHeaderIdentityProvider 的 master 配置

oauthConfig:
  ...
  identityProviders:
  - name: my_request_header_provider 
1

    challenge: true 
2

    login: true 
3

    mappingMethod: claim 
4

    provider:
      apiVersion: v1
      kind: RequestHeaderIdentityProvider
      challengeURL: "https://www.example.com/challenging-proxy/oauth/authorize?${query}" 
5

      loginURL: "https://www.example.com/login-proxy/oauth/authorize?${query}" 
6

      clientCA: /path/to/client-ca.file 
7

      clientCommonNames: 
8

      - my-auth-proxy
      headers: 
9

      - X-Remote-User
      - SSO-User
      emailHeaders: 
10

      - X-Remote-User-Email
      nameHeaders: 
11

      - X-Remote-User-Display-Name
      preferredUsernameHeaders: 
12

      - X-Remote-User-Login
Copy to Clipboard Toggle word wrap

1
此提供程序名称作为前缀放在请求标头中的用户名前,以此组成身份名称。
2
RequestHeaderIdentityProvider 只能通过重定向到配置的 challengeURL 来响应请求 WWW-Authenticate 质询的客户端。配置的 URL 应以 WWW-Authenticate 质询进行响应。
3
RequestHeaderIdentityProvider 只能通过重定向到配置的 loginURL来响应请求登录流的客户端。配置的 URL 应通过登录流做出响应。
4
控制如何在此提供程序的身份和用户对象之间建立映射,如上 所述
5
可选:将未经身份验证的 /oauth/authorize 请求重定向到的 URL,该请求将验证希望 WWW-Authenticate 质询的客户端,然后将它们代理到 https://<master>/oauth/authorize. ${url} 替换为当前的 URL,进行转义以在查询参数中安全使用。${query} 替换为当前的查询字符串。
6
可选:将未经身份验证的 /oauth/authorize 请求重定向到的 URL,它将验证基于浏览器的客户端,然后将请求代理到 https://<master>/oauth/authorize。代理到 https://<master>/oauth /authorize 的 URL 必须以 /authorize 结尾(不含尾部斜杠),并代理子路径,以便 OAuth 批准流正常工作。${url} 替换为当前的 URL,进行转义以在查询参数中安全使用。${query} 替换为当前的查询字符串。
7
可选:PEM 编码的证书捆绑包。如果设置,则必须根据指定文件中的证书颁发机构显示并验证有效的客户端证书,然后才能检查请求标头中的用户名。
8
可选:通用名称 (cn) 的列表。如果设定,则必须出示带有指定列表中通用名称 (cn) 的有效客户端证书,然后才能检查请求标头中的用户名。如果为空,则允许任何通用名称。只能与 clientCA 结合使用。
9
按顺序查找用户身份的标头名称。第一个包含值的标头被用作身份。必需,不区分大小写。
10
按顺序查找电子邮件地址的标头名称。第一个包含值的标头被用作电子邮件地址。可选,不区分大小写。
11
按顺序查找显示名称的标头名称。第一个包含值的标头被用作显示名称。可选,不区分大小写。
12
按顺序查找首选用户名的标头名称(如果与通过 headers 中指定的标头确定的不可变身份不同)。在置备时,第一个包含值的标头用作首选用户名。可选,不区分大小写。
Microsoft Windows 上的 SSPI 连接支持
重要

使用 Microsoft Windows 上的 SSPI 连接支持是技术预览功能。技术预览功能不包括在红帽生产服务级别协议(SLA)中,且其功能可能并不完善。因此,红帽不建议在生产环境中使用它们。这些技术预览功能可以使用户提早试用新的功能,并有机会在开发阶段提供反馈意见。

如需红帽技术预览功能支持范围的更多信息,请参阅 https://access.redhat.com/support/offerings/techpreview/

从版本 3.11 开始,

oc 支持安全支持提供程序接口 (SSPI),以允许 Microsft Windows 上的 SSO 流。如果您使用请求标头身份提供程序与支持 GSSAPI 的代理将 Active Directory 服务器连接到 OpenShift Container Platform,用户可以通过加入了域的 Microsoft Windows 计算机使用 oc 命令行界面来自动进行 OpenShift Container Platform 身份验证。

使用 Request 标头的 Apache 身份验证

本例在与 master 位于同一主机上配置身份验证代理。在同一主机上让代理和 master 提供方便方便的,可能不适用于您的环境。例如,如果您已在 master 上运行 路由器,端口 443 不可用。

另请务必注意,尽管此参考配置使用 Apache 的 mod_auth_gssapi,但这种引用配置并不是必需的,且如果满足以下要求,您可以轻松地使用其他代理:

  1. 阻断来自客户端请求的 X-Remote-User 标头以防止欺骗。
  2. RequestHeaderIdentityProvider 配置中强制进行客户端证书验证 。
  3. 使用质询流为所有身份验证请求设置 X-Csrf-Token 标头。
  4. 只有 /oauth/authorize 端点及其子路径应代理,并且不应重写重定向,从而使后端服务器可以将客户端发送到正确的位置。
  5. 代理到 https://<master>/oauth/authorize 的 URL 必须以 /authorize 结尾(不含尾部斜杠)。例如:

    • https://proxy.example.com/login-proxy/authorize?…​https://<master>/oauth/authorize?…​
  6. 代理到 https://<master>/oauth/authorize 的 URL 的子路径必须代理到 https://<master>/oauth/authorize 的 子路径。例如:

    • https://proxy.example.com/login-proxy/authorize/approve?…​https://<master>/oauth/authorize/approve?…​
安装先决条件
  1. 通过 Optional channel 获得 mod_auth_gssapi 模块。安装以下软件包:

    # yum install -y httpd mod_ssl mod_session apr-util-openssl mod_auth_gssapi
    Copy to Clipboard Toggle word wrap
  2. 生成用于验证提交可信标头的请求的 CA。此 CA 应在 master 身份提供程序配置中用作 clientCA 的文件名。

    # oc adm ca create-signer-cert \
      --cert='/etc/origin/master/proxyca.crt' \
      --key='/etc/origin/master/proxyca.key' \
      --name='openshift-proxy-signer@1432232228' \
      --serial='/etc/origin/master/proxyca.serial.txt'
    Copy to Clipboard Toggle word wrap
    注意

    oc adm ca create-signer-cert 命令生成有效 5 年的证书。这可以通过 --expire-days 选项进行修改,但出于安全原因,建议不要超过这个值。

    仅从 Ansible 主机清单文件中列出的第一个 master 运行 oc adm 命令,默认为 /etc/ansible/hosts

  3. 示例:为代理生成客户端证书这可以通过任何 x509 证书工具完成。为方便起见,可以使用 oc adm CLI:

    # oc adm create-api-client-config \
      --certificate-authority='/etc/origin/master/proxyca.crt' \
      --client-dir='/etc/origin/master/proxy' \
      --signer-cert='/etc/origin/master/proxyca.crt' \
      --signer-key='/etc/origin/master/proxyca.key' \
      --signer-serial='/etc/origin/master/proxyca.serial.txt' \
      --user='system:proxy' 
    1
    
    
    # pushd /etc/origin/master
    # cp master.server.crt /etc/pki/tls/certs/localhost.crt 
    2
    
    # cp master.server.key /etc/pki/tls/private/localhost.key
    # cp ca.crt /etc/pki/CA/certs/ca.crt
    # cat proxy/system\:proxy.crt \
      proxy/system\:proxy.key > \
      /etc/pki/tls/certs/authproxy.pem
    # popd
    Copy to Clipboard Toggle word wrap
    1
    用户名可以是任何内容,但为它赋予一个描述性名称,因为它将在日志中出现时很有用。
    2
    在与 master 不同的主机名中运行身份验证代理时,生成与主机名匹配的证书非常重要,而不必使用如上所示的默认 master 证书。/etc/origin/master/master-config.yaml 文件中的 masterPublicURL 的值需要包括在为 SSLCertificateFile 指定的证书的 X509v3 Subject Alternative Name 中。如果需要创建新证书,可以使用 oc adm ca create-server-cert 命令。
    注意

    oc adm create-api-client-config 命令生成有效期为两年的证书。这可以通过 --expire-days 选项进行修改,但出于安全原因,建议不要超过这个值。仅从 Ansible 主机清单文件中列出的第一个 master 运行 oc adm 命令,默认为 /etc/ansible/hosts

配置 Apache

此代理不需要驻留在与 master 相同的主机上。它使用客户端证书连接到 master,该 master 配置为信任 X-Remote-User 标头。

  1. 为 Apache 配置创建证书。您通过 SSLProxyMachineCertificateFile 参数值指定的证书是用于向服务器验证代理的代理的客户端证书。它必须使用 TLS Web 客户端身份验证作为扩展密钥类型。
  2. 创建 Apache 配置文件。使用以下模板来提供所需设置和值:

    重要

    仔细检查模板的内容,并根据您的环境自定义其相应的内容。

    LoadModule request_module modules/mod_request.so
    LoadModule auth_gssapi_module modules/mod_auth_gssapi.so
    # Some Apache configurations might require these modules.
    # LoadModule auth_form_module modules/mod_auth_form.so
    # LoadModule session_module modules/mod_session.so
    
    # Nothing needs to be served over HTTP.  This virtual host simply redirects to
    # HTTPS.
    <VirtualHost *:80>
      DocumentRoot /var/www/html
      RewriteEngine              On
      RewriteRule     ^(.*)$     https://%{HTTP_HOST}$1 [R,L]
    </VirtualHost>
    
    <VirtualHost *:443>
      # This needs to match the certificates you generated.  See the CN and X509v3
      # Subject Alternative Name in the output of:
      # openssl x509 -text -in /etc/pki/tls/certs/localhost.crt
      ServerName www.example.com
    
      DocumentRoot /var/www/html
      SSLEngine on
      SSLCertificateFile /etc/pki/tls/certs/localhost.crt
      SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
      SSLCACertificateFile /etc/pki/CA/certs/ca.crt
    
      SSLProxyEngine on
      SSLProxyCACertificateFile /etc/pki/CA/certs/ca.crt
      # It's critical to enforce client certificates on the Master.  Otherwise
      # requests could spoof the X-Remote-User header by accessing the Master's
      # /oauth/authorize endpoint directly.
      SSLProxyMachineCertificateFile /etc/pki/tls/certs/authproxy.pem
    
      # Send all requests to the console
      RewriteEngine              On
      RewriteRule     ^/console(.*)$     https://%{HTTP_HOST}:8443/console$1 [R,L]
    
      # In order to using the challenging-proxy an X-Csrf-Token must be present.
      RewriteCond %{REQUEST_URI} ^/challenging-proxy
      RewriteCond %{HTTP:X-Csrf-Token} ^$ [NC]
      RewriteRule ^.* - [F,L]
    
      <Location /challenging-proxy/oauth/authorize>
          # Insert your backend server name/ip here.
          ProxyPass https://[MASTER]:8443/oauth/authorize
          AuthName "SSO Login"
          # For Kerberos
          AuthType GSSAPI
          Require valid-user
          RequestHeader set X-Remote-User %{REMOTE_USER}s
    
          GssapiCredStore keytab:/etc/httpd/protected/auth-proxy.keytab
          # Enable the following if you want to allow users to fallback
          # to password based authntication when they do not have a client
          # configured to perform kerberos authentication
          GssapiBasicAuth On
    
          # For ldap:
          # AuthBasicProvider ldap
          # AuthLDAPURL "ldap://ldap.example.com:389/ou=People,dc=my-domain,dc=com?uid?sub?(objectClass=*)"
    
          # It's possible to remove the mod_auth_gssapi usage and replace it with
          # something like mod_auth_mellon, which only supports the login flow.
        </Location>
    
        <Location /login-proxy/oauth/authorize>
        # Insert your backend server name/ip here.
        ProxyPass https://[MASTER]:8443/oauth/authorize
    
          AuthName "SSO Login"
          AuthType GSSAPI
          Require valid-user
          RequestHeader set X-Remote-User %{REMOTE_USER}s env=REMOTE_USER
    
          GssapiCredStore keytab:/etc/httpd/protected/auth-proxy.keytab
          # Enable the following if you want to allow users to fallback
          # to password based authntication when they do not have a client
          # configured to perform kerberos authentication
          GssapiBasicAuth On
    
          ErrorDocument 401 /login.html
        </Location>
    
    </VirtualHost>
    
    RequestHeader unset X-Remote-User
    Copy to Clipboard Toggle word wrap
配置 master

/etc/origin/master/master-config.yaml 文件中的 identityProviders 小节必须更新:

  identityProviders:
  - name: requestheader
    challenge: true
    login: true
    provider:
      apiVersion: v1
      kind: RequestHeaderIdentityProvider
      challengeURL: "https://[MASTER]/challenging-proxy/oauth/authorize?${query}"
      loginURL: "https://[MASTER]/login-proxy/oauth/authorize?${query}"
      clientCA: /etc/origin/master/proxyca.crt
      headers:
      - X-Remote-User
Copy to Clipboard Toggle word wrap
重启服务

最后,重启以下服务:

# systemctl restart httpd
# master-restart api
# master-restart controllers
Copy to Clipboard Toggle word wrap
验证配置
  1. 通过绕过代理来测试。如果您提供正确的客户端证书和标头,则可以请求令牌:

    # curl -L -k -H "X-Remote-User: joe" \
       --cert /etc/pki/tls/certs/authproxy.pem \
       https://[MASTER]:8443/oauth/token/request
    Copy to Clipboard Toggle word wrap
  2. 如果没有提供客户端证书,请求应该被拒绝:

    # curl -L -k -H "X-Remote-User: joe" \
       https://[MASTER]:8443/oauth/token/request
    Copy to Clipboard Toggle word wrap
  3. 这应该会显示指向配置的 challengeURL (带有额外查询参数)的重定向:

    # curl -k -v -H 'X-Csrf-Token: 1' \
       '<masterPublicURL>/oauth/authorize?client_id=openshift-challenging-client&response_type=token'
    Copy to Clipboard Toggle word wrap
  4. 这会显示带有 WWW-Authenticate 基本质询、协商质询或两个质询都有的 401 响应:

    #  curl -k -v -H 'X-Csrf-Token: 1' \
        '<redirected challengeURL from step 3 +query>'
    Copy to Clipboard Toggle word wrap
  5. 测试在使用 Kerberos ticket 并不使用 Kerberos ticket 的情况下登录到 oc 命令行:

    1. 如果您使用 kinit生成了 Kerberos ticket,请将其销毁:

      # kdestroy -c cache_name 
      1
      Copy to Clipboard Toggle word wrap
      1
      提供 Kerberos 缓存的名称。
    2. 使用您的 Kerberos 凭证登录到 oc

      # oc login
      Copy to Clipboard Toggle word wrap

      在提示符后输入您的 Kerberos 用户名和密码。

    3. oc 命令行注销:

      # oc logout
      Copy to Clipboard Toggle word wrap
    4. 使用您的 Kerberos 凭证获得一个 ticket:

      # kinit
      Copy to Clipboard Toggle word wrap

      在提示符后输入您的 Kerberos 用户名和密码。

    5. 确认您可以登录到 oc 命令行:

      # oc login
      Copy to Clipboard Toggle word wrap

      如果配置正确,您会在不需要单独输入凭证的情况下成功登录。

13.3.10. GitHub 和 GitHub Enterprise

GitHub 使用 OAuth,您可以集成 OpenShift Container Platform 集群以使用该 OAuth 身份验证。OAuth 可以协助 OpenShift Container Platform 和 GitHub 或 GitHub Enterprise 之间的令牌交换流。

您可以使用 GitHub 集成来连接 GitHub 或 GitHub Enterprise。对于 GitHub Enterprise 集成,您必须提供实例的 hostname,并可选择提供要在服务器请求中使用的 ca 证书捆绑包。

注意

除非有所注明,否则以下步骤同时适用于 GitHub 和 GitHub Enterprise。

配置 GitHub 身份验证后,用户可使用 GitHub 凭证登录 OpenShift Container Platform。为防止具有任何 GitHub 用户 ID 的任何人登录 OpenShift Container Platform 集群,您可以将访问权利限制给仅属于特定 GitHub 组织的用户。

13.3.10.1. 在 GitHub 上注册应用程序
  1. 注册应用程序:

  2. 输入应用程序名称,如 My OpenShift Install
  3. 输入主页 URL,如 https://myapiserver.com:8443
  4. (可选)输入应用程序描述。
  5. 输入授权回调 URL,其中 URL 的末尾包含身份提供程序 名称,该名称在 master 配置文件(该配置文件在下一节中配置)的 identityProviders 小节中定义:

    <apiserver>/oauth2callback/<identityProviderName>
    Copy to Clipboard Toggle word wrap

    例如:

    https://myapiserver.com:8443/oauth2callback/github/
    Copy to Clipboard Toggle word wrap
  6. 点击 Register application。Github 会提供客户端 ID 和客户端 Secret。保持此窗口打开,以便您可以复制这些值并将其粘贴到主配置文件中。
13.3.10.2. 在 master 上配置身份验证
  1. 如果您有:

    • 已安装 OpenShift Container Platform,然后将 /etc/origin/master/master-config.yaml 文件复制到新目录中,例如:

      $ cd /etc/origin/master
      $ mkdir githubconfig; cp master-config.yaml githubconfig
      Copy to Clipboard Toggle word wrap
    • 尚未安装 OpenShift Container Platform,然后启动 OpenShift Container Platform API 服务器,指定(future)OpenShift Container Platform master 的主机名,以及一个用于存储由 start 命令创建的配置文件的目录:

      $ openshift start master --public-master=<apiserver> --write-config=<directory>
      Copy to Clipboard Toggle word wrap

      例如:

      $ openshift start master --public-master=https://myapiserver.com:8443 --write-config=githubconfig
      Copy to Clipboard Toggle word wrap
      注意

      如果要使用 Ansible 安装,您必须将 identityProvider 配置添加到 Ansible playbook 中。如果在使用 Ansible 安装后使用以下步骤手动修改配置,那么每当您重新运行安装工具或升级时,您都会丢失任何修改。

      注意

      使用 openshift 自行启动 master 将自动检测主机名,但 GitHub 必须能够重定向到您在注册应用程序时指定的准确主机名。因此,您无法自动检测 ID,因为它可能会重定向到错误的地址。反之,您必须指定 Web 浏览器用来与 OpenShift Container Platform 集群交互的主机名。

  2. 编辑新的 master-config.yaml 文件的 identityProviders 小节,并复制示例 GitHubIdentityProvider 配置并粘贴它来替换现有的小节:

    oauthConfig:
      ...
      identityProviders:
      - name: github 
    1
    
        challenge: false 
    2
    
        login: true 
    3
    
        mappingMethod: claim 
    4
    
        provider:
          apiVersion: v1
          kind: GitHubIdentityProvider
          ca: ... 
    5
    
          clientID: ... 
    6
    
          clientSecret: ... 
    7
    
          hostname: ... 
    8
    
          organizations: 
    9
    
          - myorganization1
          - myorganization2
          teams: 
    10
    
          - myorganization1/team-a
          - myorganization2/team-b
    Copy to Clipboard Toggle word wrap
    1
    此提供程序名称作为前缀放在 GitHub 数字用户 ID 前,以此组成身份名称。它还可用来构建回调 URL。
    2
    GitHubIdentityProvider 无法用于发送 WWW-Authenticate 质询。
    3
    true 时,来自 Web 客户端(如 Web 控制台)的未经身份验证的令牌请求将重定向到 GitHub 以进行登录。
    4
    控制如何在此提供程序的身份和用户对象之间建立映射,如上 所述
    5
    对于 GitHub Enterprise,CA 是向服务器发出请求时使用的可选的可信证书颁发机构捆绑包。省略此参数以使用默认系统 root 证书。对于 GitHub,请省略此参数。
    6
    注册的 GitHub OAuth 应用程序的客户端 ID。应用程序必须配置有 < master>/oauth2callback/<identityProviderName&gt; 的回调 URL。
    7
    GitHub 发布的客户端 secret。此值也可在 环境变量、外部文件或加密文件 中提供。
    8
    对于 GitHub Enterprise,您必须提供实例的主机名,如 example.com。这个值必须与 /setup/settings 文件中的 GitHub Enterprise hostname 值匹配,且不可包括端口号。对于 GitHub,请省略此参数。
    9
    可选的组织列表。如果指定,只有至少是一个所列组织成员的 GitHub 用户才能登录。如果在 clientID 中配置的 GitHub OAuth 应用程序不归该组织所有,则组织所有者必须授予第三方访问权限才能使用此选项。这可以在组织管理员第一次登录 GitHub 时完成,也可以在 GitHub 组织设置中完成。不可与 teams 字段结合使用。
    10
    可选的团队列表。如果指定,只有是至少一个列出团队的成员的 GitHub 用户才能登录。如果在 clientID 中配置的 GitHub OAuth 应用程序不归该团队的组织所有,则组织所有者必须授予第三方访问权限才能使用此选项。这可以在组织管理员第一次登录 GitHub 时完成,也可以在 GitHub 组织设置中完成。不可与 organizations 字段结合使用。
  3. identityProviders 小节进行以下修改:

    1. 更改供应商名称,以匹配您在 GitHub 上配置回调 URL。

      例如,如果您将回调 URL 定义为 https://myapiserver.com:8443/oauth2callback/github/,则 name 必须是 github

    2. clientID 更改为您之前注册的 GitHub 中的客户端 ID。
    3. clientSecret 改为 之前注册的 GitHub 中的 Client Secret。
    4. 更改 organizationsteams,使其包含一个或多个 GitHub 机构或团队的列表,用户必须具有成员资格才能进行身份验证。如果指定,只有至少是一个列出的机构或团队的成员的 GitHub 用户才能登录。如果未指定,则具有有效 GitHub 帐户的任何人都可以登录。
  4. 保存您的更改并关闭该文件。
  5. 启动 OpenShift Container Platform API 服务器,指定您刚才修改的配置文件:

    $ openshift start master --config=<path/to/modified/config>/master-config.yaml
    Copy to Clipboard Toggle word wrap

配置后,任何登录 OpenShift Container Platform Web 控制台的用户都将提示使用其 GitHub 凭证登录。首次登录时,用户必须点击 授权应用程序 来允许 GitHub 使用其用户名、密码和机构成员资格。然后,用户会被重新重定向到 Web 控制台。

13.3.10.3. 使用 GitHub 身份验证创建用户

当与外部身份验证供应商(如 GitHub)集成时,不会在 OpenShift Container Platform 中创建用户。GitHub 或 GitHub Enterprise 是记录系统,即用户由 GitHub 定义,以及属于指定机构的任何用户可以登录。

要将用户添加到 OpenShift Container Platform,您必须将该用户添加到 GitHub 或 GitHub Enterprise 上的批准机构中,如果需要为用户创建新的 GitHub 帐户。

13.3.10.4. 验证用户

登录一个或多个用户后,您可以运行 oc get users 来查看用户列表并验证用户是否已成功创建:

例 13.6. oc get users 命令的输出

$ oc get users
NAME         UID                                    FULL NAME   IDENTITIES
bobsmith     433b5641-066f-11e6-a6d8-acfc32c1ca87   Bob Smith   github:873654 
1
Copy to Clipboard Toggle word wrap
1
OpenShift Container Platform 中的身份由身份提供程序名称和 GitHub 的内部数字用户 ID 组成。这样,如果用户更改 GitHub 用户名或电子邮件,他们仍然可以登录到 OpenShift Container Platform,而不依赖于附加到 GitHub 帐户的凭证。这会创建一个稳定的登录。

在这里,您可能需要了解如何 控制用户角色

13.3.11. GitLab

identityProviders 小节中设置 GitLabIdentityProvider,以使用 GitLab.com 或任何其他 GitLab 实例作为身份提供程序。如果使用 GitLab 版本 7.7.0 到 11.0,您可以使用 OAuth 集成进行连接。如果使用 GitLab 版本 11.1 或更高版本,您可以使用 OpenID Connect (OIDC) 进行连接,而不使用 OAuth。

例 13.7. 使用 GitLabIdentityProvider的 master 配置

oauthConfig:
  ...
  identityProviders:
  - name: gitlab 
1

    challenge: true 
2

    login: true 
3

    mappingMethod: claim 
4

    provider:
      apiVersion: v1
      kind: GitLabIdentityProvider
      legacy: 
5

      url: ... 
6

      clientID: ... 
7

      clientSecret: ... 
8

      ca: ... 
9
Copy to Clipboard Toggle word wrap
1
此提供程序名称作为前缀放在 GitLab 数字用户 ID 前,以此组成身份名称。它还可用来构建回调 URL。
2
true 时,来自非 Web 客户端(如 CLI)的未经身份验证的令牌请求会为此提供程序发送 WWW-Authenticate 质询标头。这将使用 Resource Owner Password Credentials 授权流从 GitLab 获取访问令牌。
3
true 时,来自 Web 客户端(如 Web 控制台)的未经身份验证的令牌请求将重定向到 GitLab 以进行登录。
4
控制如何在此提供程序的身份和用户对象之间建立映射,如上 所述
5
决定是否使用 OAuth 或 OIDC 作为身份验证供应商。设置为 true,以使用 OAuth 和 false 来使用 OIDC。您必须使用 GitLab.com 或 GitLab 版本 11.1 或更高版本使用 OIDC。如果没有提供值,OAuth 用于连接 GitLab 实例,并使用 OIDC 连接到 GitLab.com。
6
GitLab 提供程序的主机 URL。这可以是 https://gitlab.com/ 或其他自托管 GitLab 实例。
7
注册的 GitLab OAuth 应用程序的客户端 ID 。应用程序必须配置有 < master>/oauth2callback/<identityProviderName&gt; 的回调 URL。
8
GitLab 发布的客户端 secret。此值也可在 环境变量、外部文件或加密文件 中提供。
9
CA 是一个可选的可信证书颁发机构捆绑包,用于在向 GitLab 实例发出请求时使用。若为空,则使用默认的系统根证书。

13.3.12. Google

identityProviders 小节中将 GoogleIdentityProvider 设置为将 Google 用作身份提供程序,使用 Google 的 OpenID Connect 集成

注意

使用 Google 作为身份提供程序要求用户使用 <master>/oauth/token/request 来获取令牌,以便用于命令行工具。

警告

使用 Google 作为身份提供程序时,任何 Google 用户都能与您的服务器进行身份验证。您可以使用 hostedDomain 配置属性将身份验证限制到特定托管域的成员,如下所示。

例 13.8. 使用 GoogleIdentityProvider进行 master 配置

oauthConfig:
  ...
  identityProviders:
  - name: google 
1

    challenge: false 
2

    login: true 
3

    mappingMethod: claim 
4

    provider:
      apiVersion: v1
      kind: GoogleIdentityProvider
      clientID: ... 
5

      clientSecret: ... 
6

      hostedDomain: "" 
7
Copy to Clipboard Toggle word wrap
1
此提供程序名称作为前缀放在 Google 数字用户 ID 前,以此组成身份名称。它还可用来构建的重定向 URL。
2
GoogleIdentityProvider 无法用于发送 WWW-Authenticate 质询。
3
当为 true 时,来自 web 客户端(如 Web 控制台)的未经身份验证的令牌请求会被重定向到 Google 进行登录。
4
控制如何在此提供程序的身份和用户对象之间建立映射,如上 所述
5
注册的 Google 项目的客户端 ID 。项目必须配置有重定向 URI < master>/oauth2callback/<identityProviderName>
6
Google 发布的客户端 secret。此值也可在 环境变量、外部文件或加密文件 中提供。
7
可选的 hosted domain 以限制登录帐户。如果为空,任何 Google 帐户都可进行身份验证。

13.3.13. OpenID 连接

identityProviders 小节中设置 OpenIDIdentityProvider,以使用授权代码流与 OpenID Connect 身份提供程序 集成

您可以将 Red Hat Single Sign-On 配置为 OpenShift Container Platform 的 OpenID Connect 身份提供程序。

注意

不支持 ID TokenUserInfo 解密。

默认情况下,需要 openid 范围。如果必要,可在 extraScopes 字段中指定额外的范围。

声明可读取自从 OpenID 身份提供程序返回的 JWT id_token;若有指定,也可读取自从 UserInfo URL 返回的 JSON。

必须至少配置一个声明,以用作用户的身份。标准的身份声明是 sub

您还可以指定将哪些声明用作用户的首选用户名、显示名称和电子邮件地址。如果指定了多个声明,则使用第一个带有非空值的声明。标准的声明是:

sub

“subject identifier”的缩写。 用户在签发者处的远程身份。

preferred_username

置备用户时的首选用户名。用户希望使用的简写名称,如 janedoe。通常,与身份验证系统中用户的登录或用户名对应的值,如用户名或电子邮件。

email

电子邮件地址。

name

显示名称。

如需更多信息,请参阅 OpenID 声明文档

注意

使用 OpenID Connect 身份提供程序要求用户使用 <master>/oauth/token/request 来获取令牌,以便用于命令行工具。

使用 OpenIDIdentityProvider的标准 master 配置

oauthConfig:
  ...
  identityProviders:
  - name: my_openid_connect 
1

    challenge: true 
2

    login: true 
3

    mappingMethod: claim 
4

    provider:
      apiVersion: v1
      kind: OpenIDIdentityProvider
      clientID: ... 
5

      clientSecret: ... 
6

      claims:
        id: 
7

        - sub
        preferredUsername:
        - preferred_username
        name:
        - name
        email:
        - email
      urls:
        authorize: https://myidp.example.com/oauth2/authorize 
8

        token: https://myidp.example.com/oauth2/token 
9
Copy to Clipboard Toggle word wrap

1
此提供程序名称作为前缀放在身份声明值前,以此组成身份名称。它还可用来构建的重定向 URL。
2
true 时,来自非 Web 客户端(如 CLI)的未经身份验证的令牌请求会为此提供程序发送 WWW-Authenticate 质询标头。这要求 OpenID 供应商支持 Resource Owner Password Credentials 授权流。
3
当为 true 时,来自 Web 客户端(如 Web 控制台)的未经身份验证的令牌请求会重定向到要登录的授权 URL。
4
控制如何在此提供程序的身份和用户对象之间建立映射,如上 所述
5
在 OpenID 提供程序中注册的客户端的客户端 ID。该客户端必须能够重定向到 <master>/oauth2callback/<identityProviderName>
6
客户端机密。此值也可在 环境变量、外部文件或加密文件 中提供。
7
用作身份的声明的列表。使用第一个非空声明。至少需要一个声明。如果列出的声明都没有值,身份验证会失败。例如,这使用返回的 id_token 中的 sub 声明的值作为用户的身份。
8
OpenID spec 中描述的 授权端点。必须使用 https
9
OpenID spec 中描述的令牌端点。必须使用 https

也可以指定自定义证书捆绑包、额外范围、额外授权请求参数和 userInfo URL:

例 13.9. 使用 OpenIDIdentityProvider的完整 Master 配置

oauthConfig:
  ...
  identityProviders:
  - name: my_openid_connect
    challenge: false
    login: true
    mappingMethod: claim
    provider:
      apiVersion: v1
      kind: OpenIDIdentityProvider
      clientID: ...
      clientSecret: ...
      ca: my-openid-ca-bundle.crt 
1

      extraScopes: 
2

      - email
      - profile
      extraAuthorizeParameters: 
3

        include_granted_scopes: "true"
      claims:
        id: 
4

        - custom_id_claim
        - sub
        preferredUsername: 
5

        - preferred_username
        - email
        name: 
6

        - nickname
        - given_name
        - name
        email: 
7

        - custom_email_claim
        - email
      urls:
        authorize: https://myidp.example.com/oauth2/authorize
        token: https://myidp.example.com/oauth2/token
        userInfo: https://myidp.example.com/oauth2/userinfo 
8
Copy to Clipboard Toggle word wrap
1
用于验证所配置 URL 的服务器证书的证书捆绑包。如果为空,则使用系统可信根。
2
openid 范围外的可选请求范围列表,在授权令牌请求期间使用。
3
添加至授权令牌请求的附加参数的可选映射。
4
用作身份的声明的列表。使用第一个非空声明。至少需要一个声明。如果列出的声明都没有值,身份验证会失败。
5
为此身份置备用户时用作首选用户名的声明的列表。使用第一个非空声明。
6
用作显示名称的声明列表。使用第一个非空声明。
7
用作电子邮件地址的声明列表。使用第一个非空声明。
8
OpenID spec 中描述的 UserInfo 端点。必须使用 https

13.4. 令牌选项

OAuth 服务器生成两种令牌:

访问令牌

存在时间较长的令牌,用于授权对 API 的访问。

授权代码

存在时间较短的令牌,仅用于交换访问令牌。

使用 tokenConfig 小节来设置令牌选项:

例 13.10. 主配置选项

oauthConfig:
  ...
  tokenConfig:
    accessTokenMaxAgeSeconds: 86400 
1

    authorizeTokenMaxAgeSeconds: 300 
2
Copy to Clipboard Toggle word wrap
1
设置 accessTokenMaxAgeSeconds 以控制访问令牌的生命周期。默认生命周期为 24 小时。
2
设置 authorizeTokenMaxAgeSeconds 来控制授权代码的生命周期。默认生命周期为五分钟。
注意

您可以通过 OAuthClient 对象定义 覆盖 accessTokenMaxAgeSeconds 值。

13.5. 授权选项

当 OAuth 服务器收到用户之前没有授予权限的客户端的令牌请求时,OAuth 服务器采取的操作取决于 OAuth 客户端的授权策略。

当请求令牌的 OAuth 客户端不提供自己的授权策略时,会使用服务器端的默认策略。要配置默认策略,请在 grantConfig 部分中设置 method 值。方法 的有效值有:

auto

自动批准授权并重试请求。

prompt

提示用户批准或拒绝授权。

deny

自动拒绝授权并给客户端返回失败错误。

例 13.11. 主配置选项

oauthConfig:
  ...
  grantConfig:
    method: auto
Copy to Clipboard Toggle word wrap

13.6. 会话选项

OAuth 服务器在登录和重定向流程期间使用签名和加密的 cookie 会话。

使用 sessionConfig 小节来设置会话选项:

例 13.12. Master 配置会话选项

oauthConfig:
  ...
  sessionConfig:
    sessionMaxAgeSeconds: 300 
1

    sessionName: ssn 
2

    sessionSecretsFile: "..." 
3
Copy to Clipboard Toggle word wrap
1
控制会话的最长期限;会话会在令牌请求完成后自动过期。如果没有启用 auto-grant,只要用户希望批准或拒绝客户端授权请求,就需要会话有效。
2
用于存储会话的 Cookie 名称。
3
包含序列化 SessionSecrets 对象的文件名。如果为空,则在每次服务器启动时都会生成随机签名和加密 secret。

如果没有指定 sessionSecretsFile,则会在每次主服务器启动时生成一个随机签名和加密 secret。这意味着,如果重启 master,任何正在进行中的登录都将在 master 重新启动时其会话无效。这也意味着它们将无法解码由其他其中一个 master 生成的会话。

要指定要使用的签名和加密 secret,请指定 sessionSecretsFile。这可让您将 secret 值与配置文件分开,并保留可分发的配置文件,例如用于调试目的。

可以在 sessionSecretsFile 中指定多个 secret 来启用轮转。使用列表中第一个 secret,对新会话进行签名和加密。现有会话由每个 secret 进行解密和验证,直到成功为止。

例 13.13. 会话 Secret 配置:

apiVersion: v1
kind: SessionSecrets
secrets: 
1

- authentication: "..." 
2

  encryption: "..." 
3

- authentication: "..."
  encryption: "..."
...
Copy to Clipboard Toggle word wrap
1
用于进行身份验证和加密 cookie 会话的 secret 列表。必须至少指定一个 secret。每个 secret 必须设置身份验证和加密 secret。
2
签名 secret,用于使用 HMAC 验证会话。建议您使用具有 32 或 64 字节的 secret。
3
加密 secret,用于加密会话。必须长度为 16、24 或 32 个字符,才能选择 AES-128、AES-192 或 AES-256。

13.7. 防止 CLI 版本与用户代理不匹配

OpenShift Container Platform 实施了一个用户代理,可用于防止应用程序开发人员的 CLI 访问 OpenShift Container Platform API。

OpenShift Container Platform CLI 的用户代理由 OpenShift Container Platform 中的一组值组成:

<command>/<version>+<git_commit> (<platform>/<architecture>) <client>/<git_commit>
Copy to Clipboard Toggle word wrap

例如,在以下情况下:

  • <command> = oc
  • <version> = 客户端版本。例如: v3.3.0。对位于 /api 的 Kubernetes API 发出的请求会接收 Kubernetes 版本,对位于 /oapi 的 OpenShift Container Platform API 发出的请求则会接收 OpenShift Container Platform 版本(如 oc version 所指定)
  • <platform> = linux
  • <architecture> = amd64
  • <client> = openshiftkubernetes,具体取决于请求的目标是位于 /api 的 Kubernetes API 还是位于 /oapi 的 OpenShift Container Platform API
  • <git_commit> = 客户端版本的 Git 提交(例如 f034127

用户代理将是:

oc/v3.3.0+f034127 (linux/amd64) openshift/f034127
Copy to Clipboard Toggle word wrap

您必须在 master 配置文件 /etc/origin/master/master-config.yaml 中配置用户代理。要应用配置,重启 API 服务器:

$ /usr/local/bin/master-restart api
Copy to Clipboard Toggle word wrap

作为 OpenShift Container Platform 管理员,您可以使用 master 配置中的 userAgentMatching 配置设置来防止客户端访问 API。因此,如果客户端使用特定的库或二进制代码,则阻止它们访问 API。

以下用户代理示例拒绝 Kubernetes 1.2 客户端二进制文件、OpenShift Origin 1.1.3 二进制文件,以及 POST 和 PUT httpVerbs

policyConfig:
  userAgentMatchingConfig:
    defaultRejectionMessage: "Your client is too old.  Go to https://example.org to update it."
    deniedClients:
    - regex: '\w+/v(?:(?:1\.1\.1)|(?:1\.0\.1)) \(.+/.+\) openshift/\w{7}'
    - regex: '\w+/v(?:1\.1\.3) \(.+/.+\) openshift/\w{7}'
      httpVerbs:
      - POST
      - PUT
    - regex: '\w+/v1\.2\.0 \(.+/.+\) kubernetes/\w{7}'
      httpVerbs:
      - POST
      - PUT
    requiredClients: null
Copy to Clipboard Toggle word wrap

管理员也可以拒绝与预期客户端不完全匹配的客户端:

policyConfig:
  userAgentMatchingConfig:
    defaultRejectionMessage: "Your client is too old.  Go to https://example.org to update it."
    deniedClients: []
    requiredClients:
    - regex: '\w+/v1\.1\.3 \(.+/.+\) openshift/\w{7}'
    - regex: '\w+/v1\.2\.0 \(.+/.+\) kubernetes/\w{7}'
      httpVerbs:
      - POST
      - PUT
Copy to Clipboard Toggle word wrap

要拒绝将原本包含在一组允许的客户端中的客户端,请结合使用 deniedClientsrequiredClients 值。以下示例允许除 1.13 之外的所有 1.X 客户端二进制文件:

policyConfig:
  userAgentMatchingConfig:
    defaultRejectionMessage: "Your client is too old.  Go to https://example.org to update it."
    deniedClients:
    - regex: '\w+/v1\.13.0\+\w{7} \(.+/.+\) openshift/\w{7}'
    - regex: '\w+/v1\.13.0\+\w{7} \(.+/.+\) kubernetes/\w{7}'
    requiredClients:
    - regex: '\w+/v1\.[1-9][1-9].[0-9]\+\w{7} \(.+/.+\) openshift/\w{7}'
    - regex: '\w+/v1\.[1-9][1-9].[0-9]\+\w{7} \(.+/.+\) kubernetes/\w{7}'
Copy to Clipboard Toggle word wrap
注意

当客户端的用户代理与配置不匹配时,会出现错误。要确保变异请求匹配,强制白名单。规则映射到特定的操作动词,因此您可以在允许非处理请求时对请求进行攻击。

第 14 章 使用 LDAP 同步组

14.1. 概述

作为 OpenShift Container Platform 管理员,您可以使用组来管理用户、更改其权限,并加强协作。您的组织可能已创建了用户组,并将其存储在 LDAP 服务器中。OpenShift Container Platform 可以将这些 LDAP 记录与 OpenShift Container Platform 内部记录同步,让您能够集中在一个位置管理您的组。OpenShift Container Platform 目前支持与使用以下三种通用模式定义组成员资格的 LDAP 服务器进行组同步:RFC 2307、Active Directory 和增强 Active Directory。

注意

您必须具有 cluster-admin 特权才能 同步组。

14.2. 配置 LDAP 同步

在运行 LDAP 同步 之前,您需要有一个同步配置文件。此文件包含 LDAP 客户端配置详情:

  • 用于连接 LDAP 服务器的配置。
  • 依赖于您的 LDAP 服务器中所用模式的同步配置选项。

同步配置文件也可以包含管理员定义的名称映射列表,用于将 OpenShift Container Platform 组名称映射到 LDAP 服务器中的组。

14.2.1. LDAP 客户端配置

LDAP 客户端配置

url: ldap://10.0.0.0:389 
1

bindDN: cn=admin,dc=example,dc=com 
2

bindPassword: password 
3

insecure: false 
4

ca: my-ldap-ca-bundle.crt 
5
Copy to Clipboard Toggle word wrap

1
连接协议、托管数据库的 LDAP 服务器的 IP 地址以及要连接的端口,格式为 scheme://host:port
2
可选的可分辨名称 (DN),用作绑定 DN。如果需要升级特权才能检索同步操作的条目,OpenShift Container Platform 会使用此项。
3
用于绑定的可选密码。如果需要升级特权才能检索同步操作的条目,OpenShift Container Platform 会使用此项。此值也可在 环境变量、外部文件或加密文件 中提供。
4
false 时,安全 LDAP ldaps:// URL 使用 TLS 进行连接,并且不安全 LDAP ldap:// URL 会被升级到 TLS。为 true 时,不会对服务器进行 TLS 连接,除非您指定了 ldaps:// URL,这时 URL 仍然尝试使用 TLS 进行连接。
5
用于验证所配置 URL 的服务器证书的证书捆绑包。如果为空,OpenShift Container Platform 将使用系统信任的根证书。只有 insecure 设为 false 时才会应用此项。

14.2.2. LDAP 查询定义

同步配置由用于同步所需条目的 LDAP 查询定义组成。LDAP 查询的具体定义取决于用来在 LDAP 服务器中存储成员资格信息的模式。

LDAP 查询定义

baseDN: ou=users,dc=example,dc=com 
1

scope: sub 
2

derefAliases: never 
3

timeout: 0 
4

filter: (objectClass=inetOrgPerson) 
5

pageSize: 0 
6
Copy to Clipboard Toggle word wrap

1
所有搜索都应从其中开始的目录分支的可分辨名称 (DN)。您需要指定目录树的顶端,但也可以指定目录中的子树。
2
搜索的范围。有效值为 baseonesub。如果未定义,则假定为 sub 范围。下表中可找到范围选项的描述。
3
与 LDAP 树中别名相关的搜索行为。有效值是 neversearchbasealways。如果未定义,则默认为 always 解引用别名。下表中可找到有关解引用行为的描述。
4
客户端可进行搜索的时间限值(以秒为单位)。0 代表不实施客户端限制。
5
有效的 LDAP 搜索过滤器。如果未定义,则默认为 (objectClass=*)
6
服务器响应页面大小的可选最大值,以 LDAP 条目数衡量。如果设置为 0,则不会对响应页面进行大小限制。当查询返回的条目数量多于客户端或服务器默认允许的数量时,需要设置分页大小。
Expand
表 14.1. LDAP 搜索范围选项
LDAP 搜索范围描述

base

仅考虑通过为查询给定的基本 DN 指定的对象。

one

考虑作为查询的基本 DN 的树中同一级上的所有对象。

sub

考虑根部是为查询给定的基本 DN 的整个子树。

Expand
表 14.2. LDAP 解引用行为
dereferencing Behavior描述

never

从不解引用 LDAP 树中找到的任何别名。

search

仅解引用搜索时找到的别名。

base

仅在查找基本对象时解引用别名。

always

始终解引用 LDAP 树中找到的所有别名。

14.2.3. 用户定义的名称映射

用户定义的名称映射明确将 OpenShift Container Platform 组的名称映射到可在 LDAP 服务器上找到组的唯一标识符。映射使用普通 YAML 语法。用户定义的映射可为 LDAP 服务器中每个组包含一个条目,或者仅包含这些组的一个子集。如果 LDAP 服务器上的组没有用户定义的名称映射,同步过程中的默认行为是使用指定为 OpenShift Container Platform 组名称的属性。

用户定义的名称映射

groupUIDNameMapping:
  "cn=group1,ou=groups,dc=example,dc=com": firstgroup
  "cn=group2,ou=groups,dc=example,dc=com": secondgroup
  "cn=group3,ou=groups,dc=example,dc=com": thirdgroup
Copy to Clipboard Toggle word wrap

14.3. 运行 LDAP 同步

创建 同步配置文件 后,同步可以开始。OpenShift Container Platform 允许管理员与同一服务器进行多种不同类型的同步。

注意

默认情况下,所有组同步或修剪操作都是空运行,因此您必须在 sync-groups 命令上设置 --confirm 标志,以便更改 OpenShift Container Platform 组记录。

将 LDAP 服务器上的所有组与 OpenShift Container Platform 同步:

$ oc adm groups sync --sync-config=config.yaml --confirm
Copy to Clipboard Toggle word wrap

同步所有已在 OpenShift Container Platform 中并与配置文件中指定的 LDAP 服务器中的组对应的组:

$ oc adm groups sync --type=openshift --sync-config=config.yaml --confirm
Copy to Clipboard Toggle word wrap

要将 LDAP 组的子集与 OpenShift Container Platform 同步,您可以使用白名单文件、黑名单文件或两者:

注意

您可以使用黑名单文件、白名单文件或白名单字面量的任意组合。白名单和黑名单文件必须每行包含一个唯一组标识符,您可以在该命令本身中直接包含白名单字面量。这些准则适用于在 LDAP 服务器上找到的组,以及 OpenShift Container Platform 中已存在的组。

$ oc adm groups sync --whitelist=<whitelist_file> \
                   --sync-config=config.yaml    \
                   --confirm
$ oc adm groups sync --blacklist=<blacklist_file> \
                   --sync-config=config.yaml    \
                   --confirm
$ oc adm groups sync <group_unique_identifier>    \
                   --sync-config=config.yaml    \
                   --confirm
$ oc adm groups sync <group_unique_identifier>    \
                   --whitelist=<whitelist_file> \
                   --blacklist=<blacklist_file> \
                   --sync-config=config.yaml    \
                   --confirm
$ oc adm groups sync --type=openshift             \
                   --whitelist=<whitelist_file> \
                   --sync-config=config.yaml    \
                   --confirm
Copy to Clipboard Toggle word wrap

14.4. 运行组修剪任务

如果创建组的 LDAP 服务器上的记录已不存在,管理员也可以选择从 OpenShift Container Platform 记录中移除这些组。修剪任务将接受与用于同步任务相同的同步配置文件和白名单。Pruning groups 部分提供了更多信息。

14.5. 同步示例

本节包含 RFC 2307Active Directory 和增强 Active Directory 模式的示例。以下示例中两个成员同步了名为 admins 的组:JaneJim.每个示例都解释了:

  • 如何将组和用户添加到 LDAP 服务器中。
  • LDAP 同步配置文件的概貌。
  • 同步之后 OpenShift Container Platform 中会生成什么组记录。
注意

这些示例假定所有用户都是其各自组的直接成员。具体而言,没有任何组的成员是其他组。如需有关如何 同步嵌套组 的信息,请参阅嵌套成员资格同步示例。

14.5.1. 使用 RFC 2307 模式同步组

在 RFC 2307 模式中,用户(Jane 和 Jim)和组都作为第一类条目存在于 LDAP 服务器上,组成员资格则存储在组的属性中。以下 ldif 片段定义了这个模式的用户和组:

使用 RFC 2307 模式的 LDAP 条目:rfc2307.ldif

  dn: ou=users,dc=example,dc=com
  objectClass: organizationalUnit
  ou: users

  dn: cn=Jane,ou=users,dc=example,dc=com
  objectClass: person
  objectClass: organizationalPerson
  objectClass: inetOrgPerson
  cn: Jane
  sn: Smith
  displayName: Jane Smith
  mail: jane.smith@example.com

  dn: cn=Jim,ou=users,dc=example,dc=com
  objectClass: person
  objectClass: organizationalPerson
  objectClass: inetOrgPerson
  cn: Jim
  sn: Adams
  displayName: Jim Adams
  mail: jim.adams@example.com

  dn: ou=groups,dc=example,dc=com
  objectClass: organizationalUnit
  ou: groups

  dn: cn=admins,ou=groups,dc=example,dc=com 
1

  objectClass: groupOfNames
  cn: admins
  owner: cn=admin,dc=example,dc=com
  description: System Administrators
  member: cn=Jane,ou=users,dc=example,dc=com 
2

  member: cn=Jim,ou=users,dc=example,dc=com
Copy to Clipboard Toggle word wrap

1
组是 LDAP 服务器中的第一类条目。
2
组成员使用作为组属性的标识引用来列出。

要同步此组,您必须首先创建配置文件。RFC 2307 模式要求您提供用户和组条目的 LDAP 查询定义,以及在 OpenShift Container Platform 内部记录中代表它们的属性。

为明确起见,您在 OpenShift Container Platform 中创建的组应尽可能将可分辨名称以外的属性用于面向用户或管理员的字段。例如,通过电子邮件标识 OpenShift Container Platform 组的用户,并将该组的名称用作通用名称。以下配置文件创建了这些关系:

注意

如果使用用户定义的名称映射,您的配置文件 会有所不同。

使用 RFC 2307 模式的 LDAP 同步配置:rfc2307_config.yaml

kind: LDAPSyncConfig
apiVersion: v1
url: ldap://LDAP_SERVICE_IP:389 
1

insecure: false 
2

rfc2307:
    groupsQuery:
        baseDN: "ou=groups,dc=example,dc=com"
        scope: sub
        derefAliases: never
        pageSize: 0
    groupUIDAttribute: dn 
3

    groupNameAttributes: [ cn ] 
4

    groupMembershipAttributes: [ member ] 
5

    usersQuery:
        baseDN: "ou=users,dc=example,dc=com"
        scope: sub
        derefAliases: never
        pageSize: 0
    userUIDAttribute: dn 
6

    userNameAttributes: [ uid ] 
7

    tolerateMemberNotFoundErrors: false
    tolerateMemberOutOfScopeErrors: false
Copy to Clipboard Toggle word wrap

1
存储该组记录的 LDAP 服务器的 IP 地址和主机。
2
false 时,安全 LDAP ldaps:// URL 使用 TLS 进行连接,并且不安全 LDAP ldap:// URL 会被升级到 TLS。为 true 时,不会对服务器进行 TLS 连接,除非您指定了 ldaps:// URL,这时 URL 仍然尝试使用 TLS 进行连接。
3
唯一标识 LDAP 服务器上组的属性。将 DN 用于 groupUIDAttribute 时,您无法指定 groupsQuery 过滤器。要进行精细过滤,请使用 白名单/黑名单方法
4
要用作组名称的属性。
5
存储成员资格信息的组属性。
6
唯一标识 LDAP 服务器上用户的属性。将 DN 用于 userUIDAttribute 时,您无法指定usersQuery 过滤器。要进行精细过滤,请使用 白名单/黑名单方法
7
OpenShift Container Platform 组记录中用作用户名称的属性。

使用 rfc2307_config.yaml 文件运行同步:

$ oc adm groups sync --sync-config=rfc2307_config.yaml --confirm
Copy to Clipboard Toggle word wrap

OpenShift Container Platform 创建以下组记录作为上述同步操作的结果:

使用 rfc2307_config.yaml 文件创建的 OpenShift Container Platform 组

apiVersion: user.openshift.io/v1
kind: Group
metadata:
  annotations:
    openshift.io/ldap.sync-time: 2015-10-13T10:08:38-0400 
1

    openshift.io/ldap.uid: cn=admins,ou=groups,dc=example,dc=com 
2

    openshift.io/ldap.url: LDAP_SERVER_IP:389 
3

  creationTimestamp:
  name: admins 
4

users: 
5

- jane.smith@example.com
- jim.adams@example.com
Copy to Clipboard Toggle word wrap

1
此 OpenShift Container Platform 组与 LDAP 服务器最后一次同步的时间,采用 ISO 6801 格式。
2
LDAP 服务器上组的唯一标识符。
3
存储该组记录的 LDAP 服务器的 IP 地址和主机。
4
根据同步文件指定的组的名称。
5
属于组的成员的用户,名称由同步文件指定。
14.5.1.1. RFC2307,带有用户定义的名称映射

使用用户定义的名称映射同步组时,配置文件会更改为包含这些映射,如下所示。

使用 RFC 2307 模式及用户定义的名称映射的 LDAP 同步配置: rfc2307_config_user_defined.yaml

kind: LDAPSyncConfig
apiVersion: v1
groupUIDNameMapping:
  "cn=admins,ou=groups,dc=example,dc=com": Administrators 
1

rfc2307:
    groupsQuery:
        baseDN: "ou=groups,dc=example,dc=com"
        scope: sub
        derefAliases: never
        pageSize: 0
    groupUIDAttribute: dn 
2

    groupNameAttributes: [ cn ] 
3

    groupMembershipAttributes: [ member ]
    usersQuery:
        baseDN: "ou=users,dc=example,dc=com"
        scope: sub
        derefAliases: never
        pageSize: 0
    userUIDAttribute: dn 
4

    userNameAttributes: [ uid ]
    tolerateMemberNotFoundErrors: false
    tolerateMemberOutOfScopeErrors: false
Copy to Clipboard Toggle word wrap

1
用户定义的名称映射。
2
唯一标识符属性,用于用户定义的名称映射中的键。将 DN 用于 groupUIDAttribute 时,您无法指定 groupsQuery 过滤器。要进行精细过滤,请使用 白名单/黑名单方法
3
如果其唯一标识符不在用户定义的名称映射中,用于指定 OpenShift Container Platform 组的属性。
4
唯一标识 LDAP 服务器上用户的属性。将 DN 用于 userUIDAttribute 时,您无法指定usersQuery 过滤器。要进行精细过滤,请使用 白名单/黑名单方法

使用 rfc2307_config_user_defined.yaml 文件运行同步:

$ oc adm groups sync --sync-config=rfc2307_config_user_defined.yaml --confirm
Copy to Clipboard Toggle word wrap

OpenShift Container Platform 创建以下组记录作为上述同步操作的结果:

使用 rfc2307_config_user_defined.yaml 文件创建的 OpenShift Container Platform 组

apiVersion: user.openshift.io/v1
kind: Group
metadata:
  annotations:
    openshift.io/ldap.sync-time: 2015-10-13T10:08:38-0400
    openshift.io/ldap.uid: cn=admins,ou=groups,dc=example,dc=com
    openshift.io/ldap.url: LDAP_SERVER_IP:389
  creationTimestamp:
  name: Administrators 
1

users:
- jane.smith@example.com
- jim.adams@example.com
Copy to Clipboard Toggle word wrap

1
由用户定义的名称映射指定的组名称。

默认情况下,如果要同步的组包含其条目在成员查询中定义范围之外的成员,组同步会失败并显示以下错误:

Error determining LDAP group membership for "<group>": membership lookup for user "<user>" in group "<group>" failed because of "search for entry with dn="<user-dn>" would search outside of the base dn specified (dn="<base-dn>")".
Copy to Clipboard Toggle word wrap

这通常表示 usersQuery 字段中配置了 baseDN。不过,如果 baseDN 有意不含有组中的部分成员,那么设置 tolerateMemberOutOfScopeErrors: true 可以让组同步继续进行。范围之外的成员将被忽略。

同样,当组同步过程未能找到某个组的某一成员时,它会彻底失败并显示错误:

Error determining LDAP group membership for "<group>": membership lookup for user "<user>" in group "<group>" failed because of "search for entry with base dn="<user-dn>" refers to a non-existent entry".

Error determining LDAP group membership for "<group>": membership lookup for user "<user>" in group "<group>" failed because of "search for entry with base dn="<user-dn>" and filter "<filter>" did not return any results".
Copy to Clipboard Toggle word wrap

这通常表示错误配置的 usersQuery 字段。不过,如果组中包含已知缺失的成员条目,那么设置 tolerateMemberNotFoundErrors: true 可以让组同步继续进行。有问题的成员将被忽略。

警告

为 LDAP 组同步启用容错会导致同步过程忽略有问题的成员条目。如果 LDAP 组同步配置不正确,这可能会导致同步的 OpenShift Container Platform 组中缺少成员。

使用 RFC 2307 模式并且组成员资格有问题的 LDAP 条目:rfc2307_problematic_users.ldif

  dn: ou=users,dc=example,dc=com
  objectClass: organizationalUnit
  ou: users

  dn: cn=Jane,ou=users,dc=example,dc=com
  objectClass: person
  objectClass: organizationalPerson
  objectClass: inetOrgPerson
  cn: Jane
  sn: Smith
  displayName: Jane Smith
  mail: jane.smith@example.com

  dn: cn=Jim,ou=users,dc=example,dc=com
  objectClass: person
  objectClass: organizationalPerson
  objectClass: inetOrgPerson
  cn: Jim
  sn: Adams
  displayName: Jim Adams
  mail: jim.adams@example.com

  dn: ou=groups,dc=example,dc=com
  objectClass: organizationalUnit
  ou: groups

  dn: cn=admins,ou=groups,dc=example,dc=com
  objectClass: groupOfNames
  cn: admins
  owner: cn=admin,dc=example,dc=com
  description: System Administrators
  member: cn=Jane,ou=users,dc=example,dc=com
  member: cn=Jim,ou=users,dc=example,dc=com
  member: cn=INVALID,ou=users,dc=example,dc=com 
1

  member: cn=Jim,ou=OUTOFSCOPE,dc=example,dc=com 
2
Copy to Clipboard Toggle word wrap

1
LDAP 服务器上不存在的成员。
2
可能存在,但不在同步任务的用户查询的 baseDN 下的成员。

要容许以上示例中的错误,您必须在同步配置文件中添加以下内容:

使用 RFC 2307 模式且容许错误的 LDAP 同步配置:rfc2307_config_tolerating.yaml

kind: LDAPSyncConfig
apiVersion: v1
url: ldap://LDAP_SERVICE_IP:389
rfc2307:
    groupsQuery:
        baseDN: "ou=groups,dc=example,dc=com"
        scope: sub
        derefAliases: never
    groupUIDAttribute: dn
    groupNameAttributes: [ cn ]
    groupMembershipAttributes: [ member ]
    usersQuery:
        baseDN: "ou=users,dc=example,dc=com"
        scope: sub
        derefAliases: never
    userUIDAttribute: dn 
1

    userNameAttributes: [ uid ]
    tolerateMemberNotFoundErrors: true 
2

    tolerateMemberOutOfScopeErrors: true 
3
Copy to Clipboard Toggle word wrap

2
true 时,同步任务容许找不到部分成员的组,并且找不到 LDAP 条目的成员将被忽略。如果找不到组成员,同步任务的默认行为将失败。
3
true 时,同步任务容许其部分成员在 usersQuery 基本 DN 中给定用户范围之外的组,并且不在成员查询范围的成员将被忽略。如果组中某个成员超出范围,则同步任务的默认行为将失败。
1
唯一标识 LDAP 服务器上用户的属性。将 DN 用于 userUIDAttribute 时,您无法指定usersQuery 过滤器。要进行精细过滤,请使用 白名单/黑名单方法

使用 rfc2307_config_tolerating.yaml 文件运行同步:

$ oc adm groups sync --sync-config=rfc2307_config_tolerating.yaml --confirm
Copy to Clipboard Toggle word wrap

OpenShift Container Platform 创建以下组记录作为上述同步操作的结果:

使用 rfc2307_config.yaml 文件创建的 OpenShift Container Platform 组

apiVersion: user.openshift.io/v1
kind: Group
metadata:
  annotations:
    openshift.io/ldap.sync-time: 2015-10-13T10:08:38-0400
    openshift.io/ldap.uid: cn=admins,ou=groups,dc=example,dc=com
    openshift.io/ldap.url: LDAP_SERVER_IP:389
  creationTimestamp:
  name: admins
users: 
1

- jane.smith@example.com
- jim.adams@example.com
Copy to Clipboard Toggle word wrap

1
属于组的成员的用户,根据同步文件指定。缺少查询遇到容许错误的成员。

14.5.3. 使用 Active Directory 同步组

在 Active Directory 模式中,两个用户(Jane 和 Jim)都作为第一类条目存在于 LDAP 服务器中,组成员资格则存储在用户的属性中。以下 ldif 片段定义了这个模式的用户和组:

使用 Active Directory 模式的 LDAP 条目:active_directory.ldif

dn: ou=users,dc=example,dc=com
objectClass: organizationalUnit
ou: users

dn: cn=Jane,ou=users,dc=example,dc=com
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: testPerson
cn: Jane
sn: Smith
displayName: Jane Smith
mail: jane.smith@example.com
memberOf: admins 
1


dn: cn=Jim,ou=users,dc=example,dc=com
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: testPerson
cn: Jim
sn: Adams
displayName: Jim Adams
mail: jim.adams@example.com
memberOf: admins
Copy to Clipboard Toggle word wrap

1
用户的组成员资格列为用户的属性,组没有作为条目存在于服务器中。memberOf 属性不一定是用户的字面量属性;在一些 LDAP 服务器中,它在搜索过程中创建并返回给客户端,但不提交给数据库。

要同步此组,您必须首先创建配置文件。Active Directory 模式要求您提供用户条目的 LDAP 查询定义,以及在内部 OpenShift Container Platform 组记录中代表它们的属性。

为明确起见,您在 OpenShift Container Platform 中创建的组应尽可能将可分辨名称以外的属性用于面向用户或管理员的字段。例如,通过电子邮件标识 OpenShift Container Platform 组的用户,但通过 LDAP 服务器上的组名称来定义组名称。以下配置文件创建了这些关系:

使用 Active Directory 模式的 LDAP 同步配置:active_directory_config.yaml

kind: LDAPSyncConfig
apiVersion: v1
url: ldap://LDAP_SERVICE_IP:389
activeDirectory:
    usersQuery:
        baseDN: "ou=users,dc=example,dc=com"
        scope: sub
        derefAliases: never
        filter: (objectclass=inetOrgPerson)
        pageSize: 0
    userNameAttributes: [ uid ] 
1

    groupMembershipAttributes: [ memberOf ] 
2
Copy to Clipboard Toggle word wrap

1
OpenShift Container Platform 组记录中用作用户名称的属性。
2
存储成员资格信息的用户属性。

使用 active_directory_config.yaml 文件运行同步:

$ oc adm groups sync --sync-config=active_directory_config.yaml --confirm
Copy to Clipboard Toggle word wrap

OpenShift Container Platform 创建以下组记录作为上述同步操作的结果:

使用 active_directory_config.yaml 文件创建的 OpenShift Container Platform 组

apiVersion: user.openshift.io/v1
kind: Group
metadata:
  annotations:
    openshift.io/ldap.sync-time: 2015-10-13T10:08:38-0400 
1

    openshift.io/ldap.uid: admins 
2

    openshift.io/ldap.url: LDAP_SERVER_IP:389 
3

  creationTimestamp:
  name: admins 
4

users: 
5

- jane.smith@example.com
- jim.adams@example.com
Copy to Clipboard Toggle word wrap

1
此 OpenShift Container Platform 组与 LDAP 服务器最后一次同步的时间,采用 ISO 6801 格式。
2
LDAP 服务器上组的唯一标识符。
3
存储该组记录的 LDAP 服务器的 IP 地址和主机。
4
LDAP 服务器中列出的组名称。
5
属于组的成员的用户,名称由同步文件指定。

14.5.4. 使用增强 Active Directory 同步组

在增强 Active Directory 模式中,用户(Jane 和 Jim)和组都作为第一类条目存在于 LDAP 服务器中,组成员资格则存储在用户的属性中。以下 ldif 片段定义了这个模式的用户和组:

使用增强 Active Directory 模式的 LDAP 条目:increaseded_active_directory.ldif

dn: ou=users,dc=example,dc=com
objectClass: organizationalUnit
ou: users

dn: cn=Jane,ou=users,dc=example,dc=com
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: testPerson
cn: Jane
sn: Smith
displayName: Jane Smith
mail: jane.smith@example.com
memberOf: cn=admins,ou=groups,dc=example,dc=com 
1


dn: cn=Jim,ou=users,dc=example,dc=com
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: testPerson
cn: Jim
sn: Adams
displayName: Jim Adams
mail: jim.adams@example.com
memberOf: cn=admins,ou=groups,dc=example,dc=com

dn: ou=groups,dc=example,dc=com
objectClass: organizationalUnit
ou: groups

dn: cn=admins,ou=groups,dc=example,dc=com 
2

objectClass: groupOfNames
cn: admins
owner: cn=admin,dc=example,dc=com
description: System Administrators
member: cn=Jane,ou=users,dc=example,dc=com
member: cn=Jim,ou=users,dc=example,dc=com
Copy to Clipboard Toggle word wrap

1
用户的组成员资格列为用户的属性。
2
组是在 LDAP 服务器上的第一类条目。

要同步此组,您必须首先创建配置文件。增强 Active Directory(augmented Active Directory) 模式要求您提供用户条目和组条目的 LDAP 查询定义,以及在内部 OpenShift Container Platform 组记录中代表它们的属性。

为明确起见,您在 OpenShift Container Platform 中创建的组应尽可能将可分辨名称以外的属性用于面向用户或管理员的字段。例如,通过电子邮件标识 OpenShift Container Platform 组的用户,并将该组的名称用作通用名称。以下配置文件创建了这些关系。

使用增强 Active Directory 模式的 LDAP 同步配置:increaseded_active_directory_config.yaml

kind: LDAPSyncConfig
apiVersion: v1
url: ldap://LDAP_SERVICE_IP:389
augmentedActiveDirectory:
    groupsQuery:
        baseDN: "ou=groups,dc=example,dc=com"
        scope: sub
        derefAliases: never
        pageSize: 0
    groupUIDAttribute: dn 
1

    groupNameAttributes: [ cn ] 
2

    usersQuery:
        baseDN: "ou=users,dc=example,dc=com"
        scope: sub
        derefAliases: never
        filter: (objectclass=inetOrgPerson)
        pageSize: 0
    userNameAttributes: [ uid ] 
3

    groupMembershipAttributes: [ memberOf ] 
4
Copy to Clipboard Toggle word wrap

1
唯一标识 LDAP 服务器上组的属性。将 DN 用于 groupUIDAttribute 时,您无法指定 groupsQuery 过滤器。要进行精细过滤,请使用 白名单/黑名单方法
2
要用作组名称的属性。
3
OpenShift Container Platform 组记录中用作用户名称的属性。
4
存储成员资格信息的用户属性。

使用 augmented_active_directory_config.yaml 文件运行同步:

$ oc adm groups sync --sync-config=augmented_active_directory_config.yaml --confirm
Copy to Clipboard Toggle word wrap

OpenShift Container Platform 创建以下组记录作为上述同步操作的结果:

使用 augmented_active_directory_config.yaml 文件创建的 OpenShift 组

apiVersion: user.openshift.io/v1
kind: Group
metadata:
  annotations:
    openshift.io/ldap.sync-time: 2015-10-13T10:08:38-0400 
1

    openshift.io/ldap.uid: cn=admins,ou=groups,dc=example,dc=com 
2

    openshift.io/ldap.url: LDAP_SERVER_IP:389 
3

  creationTimestamp:
  name: admins 
4

users: 
5

- jane.smith@example.com
- jim.adams@example.com
Copy to Clipboard Toggle word wrap

1
此 OpenShift Container Platform 组与 LDAP 服务器最后一次同步的时间,采用 ISO 6801 格式。
2
LDAP 服务器上组的唯一标识符。
3
存储该组记录的 LDAP 服务器的 IP 地址和主机。
4
根据同步文件指定的组的名称。
5
属于组的成员的用户,名称由同步文件指定。

14.6. 嵌套成员资格同步示例

OpenShift Container Platform 中的组不嵌套。在消耗数据之前,LDAP 服务器必须平展组成员资格。Microsoft 的 Active Directory Server 通过 LDAP_MATCHING_RULE_IN_CHAIN 规则支持这一功能,其 OID 为 1.2.840.113556.1.4.1941。另外,使用此匹配规则时只能同步明确列在白名单中 的组。

本节中的示例使用了增强 Active Directory 模式,它将同步一个名为 admins 的组,该组有一个用户 Jane 和一个组 otheradminsotheradmins 组具有一个用户成员:Jim.这个示例阐述了:

  • 如何将组和用户添加到 LDAP 服务器中。
  • LDAP 同步配置文件的概貌。
  • 同步之后 OpenShift Container Platform 中会生成什么组记录。

在增强 Active Directory 模式中,用户(JaneJim)和组都作为第一类条目存在于 LDAP 服务器中,组成员资格则存储在用户或组的属性中。以下 ldif 片段定义了这个模式的用户和组:

使用增强 Active Directory 模式和嵌套成员的 LDAP 条目:augmented_active_directory_nested.ldif

dn: ou=users,dc=example,dc=com
objectClass: organizationalUnit
ou: users

dn: cn=Jane,ou=users,dc=example,dc=com
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: testPerson
cn: Jane
sn: Smith
displayName: Jane Smith
mail: jane.smith@example.com
memberOf: cn=admins,ou=groups,dc=example,dc=com 
1


dn: cn=Jim,ou=users,dc=example,dc=com
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: testPerson
cn: Jim
sn: Adams
displayName: Jim Adams
mail: jim.adams@example.com
memberOf: cn=otheradmins,ou=groups,dc=example,dc=com 
2


dn: ou=groups,dc=example,dc=com
objectClass: organizationalUnit
ou: groups

dn: cn=admins,ou=groups,dc=example,dc=com 
3

objectClass: group
cn: admins
owner: cn=admin,dc=example,dc=com
description: System Administrators
member: cn=Jane,ou=users,dc=example,dc=com
member: cn=otheradmins,ou=groups,dc=example,dc=com

dn: cn=otheradmins,ou=groups,dc=example,dc=com 
4

objectClass: group
cn: otheradmins
owner: cn=admin,dc=example,dc=com
description: Other System Administrators
memberOf: cn=admins,ou=groups,dc=example,dc=com 
5
 
6

member: cn=Jim,ou=users,dc=example,dc=com
Copy to Clipboard Toggle word wrap

1 2 5
用户和组的成员资格列为对象的属性。
3 4
组是在 LDAP 服务器上的第一类条目。
6
otheradmins 组是 admins 组的成员。

要将嵌套的组与 Active Directory 同步,您必须提供用户条目和组条目的 LDAP 查询定义,以及在内部 OpenShift Container Platform 组记录中代表它们的属性。另外,此配置也需要进行某些修改:

  • oc adm groups sync 命令必须明确将组 列在白名单中
  • 用户的 groupMembershipAttributes 必须包含 "memberOf:1.2.840.113556.1.4.1941:",以遵守 LDAP_MATCHING_RULE_IN_CHAIN 规则。
  • groupUIDAttribute 必须设为 dn
  • groupsQuery

    • 不得设置 filter
    • 必须设置有效的 derefAliases
    • 不应设置 basedn,因为此值将被忽略。
    • 不应设置 scope,因为此值将被忽略。

为明确起见,您在 OpenShift Container Platform 中创建的组应尽可能将可分辨名称以外的属性用于面向用户或管理员的字段。例如,通过电子邮件标识 OpenShift Container Platform 组的用户,并将该组的名称用作通用名称。以下配置文件创建了这些关系:

使用增强 Active Directory 模式和嵌套成员的 LDAP 同步配置:increaseded_active_directory_config_nested.yaml

kind: LDAPSyncConfig
apiVersion: v1
url: ldap://LDAP_SERVICE_IP:389
augmentedActiveDirectory:
    groupsQuery: 
1

        derefAliases: never
        pageSize: 0
    groupUIDAttribute: dn 
2

    groupNameAttributes: [ cn ] 
3

    usersQuery:
        baseDN: "ou=users,dc=example,dc=com"
        scope: sub
        derefAliases: never
        filter: (objectclass=inetOrgPerson)
        pageSize: 0
    userNameAttributes: [ uid ] 
4

    groupMembershipAttributes: [ "memberOf:1.2.840.113556.1.4.1941:" ] 
5
Copy to Clipboard Toggle word wrap

1
无法指定 groupsQuery 过滤器。groupsQuery 基本 DN 和范围值将被忽略。groupsQuery 必须设置有效的 derefAliases
2
唯一标识 LDAP 服务器上组的属性。必须设为 dn
3
要用作组名称的属性。
4
用作 OpenShift Container Platform 组记录中用户名称的属性。大多数安装中首选使用 uidsAMAccountName
5
存储成员资格信息的用户属性。注意 LDAP_MATCHING_RULE_IN_CHAIN 的使用。

使用 augmented_active_directory_config_nested.yaml 文件运行同步:

$ oc adm groups sync \
    'cn=admins,ou=groups,dc=example,dc=com' \
    --sync-config=augmented_active_directory_config_nested.yaml \
    --confirm
Copy to Clipboard Toggle word wrap
注意

您必须明确将 cn=admins,ou=groups,dc=example,dc=com列在白名单中

OpenShift Container Platform 创建以下组记录作为上述同步操作的结果:

使用 augmented_active_directory_config_nested.yaml 文件创建的 OpenShift 组

apiVersion: user.openshift.io/v1
kind: Group
metadata:
  annotations:
    openshift.io/ldap.sync-time: 2015-10-13T10:08:38-0400 
1

    openshift.io/ldap.uid: cn=admins,ou=groups,dc=example,dc=com 
2

    openshift.io/ldap.url: LDAP_SERVER_IP:389 
3

  creationTimestamp:
  name: admins 
4

users: 
5

- jane.smith@example.com
- jim.adams@example.com
Copy to Clipboard Toggle word wrap

1
此 OpenShift Container Platform 组与 LDAP 服务器最后一次同步的时间,采用 ISO 6801 格式。
2
LDAP 服务器上组的唯一标识符。
3
存储该组记录的 LDAP 服务器的 IP 地址和主机。
4
根据同步文件指定的组的名称。
5
属于组的成员的用户,名称由同步文件指定。请注意,嵌套组成员包含在内,因为 Microsoft Active Directory Server 已经平展了组成员关系。

14.7. LDAP 同步配置规格

配置文件的对象规格如下。请注意,不同的模式对象有不同的字段。例如,v1.ActiveDirectoryConfig 没有 groupsQuery 字段,而 v1.RFC2307Configv1.AugmentedActiveDirectoryConfig 都有这个字段。

重要

不支持二进制属性。所有来自 LDAP 服务器的属性数据都必须采用 UTF-8 编码字符串的格式。例如,切勿将 objectGUID 等二进制属性用作 ID 属性。您必须改为使用字符串属性,如 sAMAccountNameuserPrincipalName

14.7.1. v1.LDAPSyncConfig

LDAPSyncConfig 包含定义 LDAP 组同步所需的配置选项。

Expand
名称描述模式

kind

代表此对象所代表的 REST 资源的字符串值。服务器可以从客户端向其提交请求的端点推断。无法更新。采用驼峰拼写法 (CamelCase)。更多信息:https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#types-kinds

字符串

apiVersion

定义对象的此表示法的版本控制模式。服务器应该将识别的模式转换为最新的内部值,并可拒绝未识别的值。更多信息:https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#resources

字符串

url

主机是要连接到的 LDAP 服务器的方案、主机和端口:scheme://host:port

字符串

bindDN

要绑定到 LDAP 服务器的可选 DN。

字符串

bindPassword

在搜索阶段要绑定的可选密码。

v1.StringSource

insecure

若为 true,则表示连接不应使用 TLS。若为 false,则 ldaps:// URL 使用 TLS 进行连接,并且使用 https://tools.ietf.org/html/rfc2830 中指定的 StartTLS 将 ldap:// URL 升级为 TLS 连接。如果将 insecure 设为 true 并且使用 ldaps:// URL 方案,则 URL 仍然会尝试使用指定的 ca 进行 TLS 连接。

布尔值

ca

在向服务器发出请求时使用的可选的可信证书颁发机构捆绑包。若为空,则使用默认的系统根证书。

字符串

groupUIDNameMapping

LDAP 组 UID 与 OpenShift Container Platform 组名称的可选直接映射。

对象

rfc2307

包含用于从设置的 LDAP 服务器提取数据的配置,其格式类似于 RFC2307:第一类组和用户条目,以及由列出其成员的组条目的多值属性决定的组成员资格。

v1.RFC2307Config

activeDirectory

包含用于从设置的 LDAP 服务器提取数据的配置,其格式与 Active Directory 中使用的类似:第一类用户条目,以及由列出所在组的成员的多值属性决定的组成员资格。

v1.ActiveDirectoryConfig

augmentedActiveDirectory

包含用于从设置的 LDAP 服务器提取数据的配置,其格式与上面描述的 Active Directory 中使用的类似,再另加一项:有第一类组条目,它们用来保存元数据而非组成员资格。

v1.AugmentedActiveDirectoryConfig

14.7.2. v1.StringSource

StringSource 允许指定内联字符串,或通过环境变量或文件从外部指定。当它只包含一个字符串值时,它会编列为一个简单 JSON 字符串。

Expand
名称描述模式

value

指定明文值,或指定加密值(如果指定了 keyFile)。

字符串

env

指定包含明文值或加密值(如果指定了 keyFile)的环境变量。

字符串

file

引用含有明文值或加密值(如果指定了 keyFile)的文件。

字符串

keyFile

引用包含用于解密值的密钥的文件。

字符串

14.7.3. v1.LDAPQuery

LDAPQuery 包含构建 LDAP 查询时所需的选项。

Expand
名称描述模式

baseDN

所有搜索都应从中开始的目录分支的 DN。

字符串

scope

(可选)搜索的范围。可以是 base (仅基本对象)、one (基本级别上的所有对象)、sub (整个子树)。若未设置,则默认为 sub

字符串

derefAliases

(可选)搜索的行为与别名相关。可以是 never (不要 dereference 别名)、search (仅在搜索中 dereference)、base (仅在查找基本对象时 dereference)、always (始终 dereference)。若未设置,则默认为 always

字符串

timeout

包含所有对服务器的请求在放弃等待响应前应保持待定的时间限制,以秒为单位。如果是 0,则不会实施客户端一侧的限制。

整数

filter

使用基本 DN 从 LDAP 服务器检索所有相关条目的有效 LDAP 搜索过滤器。

字符串

pageSize

最大首选页面大小,以 LDAP 条目数衡量。页面大小为 0 表示不进行分页。

整数

14.7.4. v1.RFC2307Config

RFC2307Config 包含必要的配置选项,用于定义 LDAP 组同步如何使用 RFC2307 模式与 LDAP 服务器交互。

Expand
名称描述模式

groupsQuery

包含用于返回组条目的 LDAP 查询模板。

v1.LDAPQuery

groupUIDAttribute

定义 LDAP 组条目上的哪个属性将解释为其唯一标识符。(ldapGroupUID)

字符串

groupNameAttributes

定义 LDAP 组条目上的哪些属性将解释为用于 OpenShift Container Platform 组的名称。

字符串数组

groupMembershipAttributes

定义 LDAP 组条目上哪些属性将解释为其成员。这些属性中包含的值必须可由 UserUIDAttribute 查询。

字符串数组

usersQuery

包含用于返回用户条目的 LDAP 查询模板。

v1.LDAPQuery

userUIDAttribute

定义 LDAP 用户条目上的哪个属性将解释为其唯一标识符。它必须与 GroupMembershipAttributes 中找到的值对应。

字符串

userNameAttributes

定义要使用 LDAP 用户条目上的哪些属性,以用作其 OpenShift Container Platform 用户名。使用第一个带有非空值的属性。这应该与您的 LDAPPasswordIdentityProviderPreferredUsername 设置匹配。用作 OpenShift Container Platform 组记录中用户名称的属性。大多数安装中首选 mailsAMAccountName

字符串数组

tolerateMemberNotFoundErrors

决定在遇到缺失的用户条目时 LDAP 同步任务的行为。若为 true,则容许找不到任何匹配项的 LDAP 用户查询,并且只记录错误。若为 false,则 LDAP 同步任务在用户查询找不到匹配项时将失败。默认值为 'false'。如果此标志设为 'true',则配置错误的 LDAP 同步任务可能会导致组成员资格被移除,因此建议谨慎使用此标志。

布尔值

tolerateMemberOutOfScopeErrors

决定在遇到超出范围的用户条目时 LDAP 同步任务的行为。如果为 true,则容许超出为所有用户查询给定的基本 DN 范围的 LDAP 用户查询,并且仅记录错误。若为 false,则当用户查询在所有用户查询指定的基本 DN 范围外搜索时,LDAP 同步任务将失败。如果此标志设为 true,则配置错误的 LDAP 同步任务可导致组中缺少用户,因此建议谨慎使用此标志。

布尔值

14.7.5. v1.ActiveDirectoryConfig

ActiveDirectoryConfig 包含必要的配置选项,用于定义 LDAP 组同步如何使用 Active Directory 模式与 LDAP 服务器交互。

Expand
名称描述模式

usersQuery

包含用于返回用户条目的 LDAP 查询模板。

v1.LDAPQuery

userNameAttributes

定义 LDAP 用户条目上的哪些属性将解释为其 OpenShift Container Platform 用户名。用作 OpenShift Container Platform 组记录中用户名称的属性。大多数安装中首选 mailsAMAccountName

字符串数组

groupMembershipAttributes

定义 LDAP 用户条目上的哪些属性将解释为它所属的组。

字符串数组

14.7.6. v1.AugmentedActiveDirectoryConfig

AugmentedActiveDirectoryConfig 包含必要的配置选项,用于定义 LDAP 组同步如何使用增强 Active Directory 模式与 LDAP 服务器交互。

Expand
名称描述模式

usersQuery

包含用于返回用户条目的 LDAP 查询模板。

v1.LDAPQuery

userNameAttributes

定义 LDAP 用户条目上的哪些属性将解释为其 OpenShift Container Platform 用户名。用作 OpenShift Container Platform 组记录中用户名称的属性。大多数安装中首选 mailsAMAccountName

字符串数组

groupMembershipAttributes

定义 LDAP 用户条目上的哪些属性将解释为它所属的组。

字符串数组

groupsQuery

包含用于返回组条目的 LDAP 查询模板。

v1.LDAPQuery

groupUIDAttribute

定义 LDAP 组条目上的哪个属性将解释为其唯一标识符。(ldapGroupUID)

字符串

groupNameAttributes

定义 LDAP 组条目上的哪些属性将解释为用于 OpenShift Container Platform 组的名称。

字符串数组

第 15 章 配置 LDAP 故障切换

OpenShift Container Platform 提供了一个 身份验证供应商,用于轻量级目录访问协议(LDAP)设置,但它只能连接到单个 LDAP 服务器。在 OpenShift Container Platform 安装过程中,您可以为 LDAP 故障切换配置系统安全服务守护进程(SSSD),以确保在一个 LDAP 服务器失败时访问集群。

此配置的设置是高级的,需要单独的身份验证服务器(也称为 远程基本身份验证服务器 )用于 OpenShift Container Platform 进行通信。您可以将这个服务器配置为将额外属性(如电子邮件地址)传递给 OpenShift Container Platform,以便它可以在 web 控制台中显示它们。

本小节论述了如何在专用物理或虚拟机(VM)上完成此设置,但您也可以在容器中配置 SSSD。

重要

您必须完成本主题的所有部分。

15.1. 配置基本身份验证的先决条件

  • 在开始设置前,您需要了解以下有关 LDAP 服务器的以下信息:

    • 目录服务器是否由 FreeIPA、Active Directory 或其他 LDAP 解决方案提供驱动。
    • LDAP 服务器的统一资源标识符 (URI),如 ldap.example.com
    • LDAP 服务器的 CA 证书的位置。
    • LDAP 服务器是否为 RFC 2307 还是 RFC2307bis 供用户组使用。
  • 准备服务器:

    • remote-basic.example.com :用作远程基本身份验证服务器的虚拟机。

      • 选择包括此服务器的 SSSD 版本 1.12.0 的操作系统,如 Red Hat Enterprise Linux 7.0 或更高版本。
    • openshift.example.com :OpenShift Container Platform 的新安装。

      • 没有为这个集群配置验证方法。
      • 不要在这个集群上启动 OpenShift Container Platform。

在 Ansible 主机清单文件(默认为 /etc/ansible/hosts)中列出的第一个 master 主机上完成以下步骤。

  1. 为确保远程基本身份验证服务器和 OpenShift Container Platform 间的通信需要信任,在这组其他阶段创建一组传输层安全(TLS)证书。运行以下命令:

    # openshift start \
        --public-master=https://openshift.example.com:8443 \
        --write-config=/etc/origin/
    Copy to Clipboard Toggle word wrap

    输出中包含 /etc/origin/master/ca.crt/etc/origin/master/ca.key 签名证书。

  2. 使用签名证书生成要在远程基本身份验证服务器中使用的密钥:

    # mkdir -p /etc/origin/remote-basic/
    # oc adm ca create-server-cert \
        --cert='/etc/origin/remote-basic/remote-basic.example.com.crt' \
        --key='/etc/origin/remote-basic/remote-basic.example.com.key' \
        --hostnames=remote-basic.example.com \ 
    1
    
        --signer-cert='/etc/origin/master/ca.crt' \
        --signer-key='/etc/origin/master/ca.key' \
        --signer-serial='/etc/origin/master/ca.serial.txt'
    Copy to Clipboard Toggle word wrap
    1
    以逗号分隔的所有主机名和接口 IP 地址列表,它们需要访问远程基本身份验证服务器。
    注意

    您生成的证书文件有效期为两年。您可以通过更改 --expire-days--signer-expiredays 值来更改这个周期,但出于安全原因,不要使它们大于 730。

    重要

    如果您没有列出需要访问远程基本身份验证服务器的所有主机名和接口 IP 地址,HTTPS 连接将失败。

  3. 将必要的证书和密钥复制到远程基本身份验证服务器:

    # scp /etc/origin/master/ca.crt \
          root@remote-basic.example.com:/etc/pki/CA/certs/
    
    # scp /etc/origin/remote-basic/remote-basic.example.com.crt \
          root@remote-basic.example.com:/etc/pki/tls/certs/
    
    # scp /etc/origin/remote-basic/remote-basic.example.com.key \
          root@remote-basic.example.com:/etc/pki/tls/private/
    Copy to Clipboard Toggle word wrap

15.3. 为 LDAP 故障切换配置 SSSD

在远程基本身份验证服务器上完成这些步骤。

您可以将 SSSD 配置为检索属性,如电子邮件地址和显示名称,并将它们传递给 OpenShift Container Platform 以便在 web 界面中显示。在以下步骤中,您要将 SSSD 配置为向 OpenShift Container Platform 提供电子邮件地址:

  1. 安装所需的 SSSD 和 Web 服务器组件:

    # yum install -y sssd \
                     sssd-dbus \
                     realmd \
                     httpd \
                     mod_session \
                     mod_ssl \
                     mod_lookup_identity \
                     mod_authnz_pam \
                     php \
                     mod_php
    Copy to Clipboard Toggle word wrap
  2. 设置 SSSD 以针对 LDAP 服务器验证此虚拟机。如果 LDAP 服务器是 FreeIPA 或 Active Directory 环境,则使用 realmd 将这个计算机加入到域中。

    # realm join ldap.example.com
    Copy to Clipboard Toggle word wrap

    有关更高级的情况,请参阅 系统级验证指南

  3. 要使用 SSSD 管理 LDAP 的故障切换情况,请在 ldap_uri 行上的 /etc/sssd/sssd.conf 文件中添加更多条目。使用 FreeIPA 注册的系统可以使用 DNS SRV 记录自动处理故障转移。
  4. 修改 /etc/sssd/sssd.conf 文件的 [domain/DOMAINNAME] 部分并添加此属性:

    [domain/example.com]
    ...
    ldap_user_extra_attrs = mail 
    1
    Copy to Clipboard Toggle word wrap
    1
    指定检索 LDAP 解决方案的电子邮件地址的正确属性。对于 IPA,请指定 邮件。其他 LDAP 解决方案可能使用其他属性,如电子邮件
  5. 确认 /etc/sssd/sssd.conf 文件中的 domain 参数仅包含 [domain/DOMAINNAME] 部分中列出的域名。

    domains = example.com
    Copy to Clipboard Toggle word wrap
  6. 授予 Apache 权限以检索电子邮件属性。将以下行添加到 /etc/sssd/sssd.conf 文件的 [ifp] 部分:

    [ifp]
    user_attributes = +mail
    allowed_uids = apache, root
    Copy to Clipboard Toggle word wrap
  7. 要确定正确应用所有更改,请重启 SSSD:

    $ systemctl restart sssd.service
    Copy to Clipboard Toggle word wrap
  8. 测试用户信息是否可以正确检索:

    $ getent passwd <username>
    username:*:12345:12345:Example User:/home/username:/usr/bin/bash
    Copy to Clipboard Toggle word wrap
  9. 确认您指定的 mail 属性返回您的域的电子邮件地址:

    # dbus-send --print-reply --system --dest=org.freedesktop.sssd.infopipe \
        /org/freedesktop/sssd/infopipe org.freedesktop.sssd.infopipe.GetUserAttr \
        string:username \ 
    1
    
        array:string:mail 
    2
    
    
    method return time=1528091855.672691 sender=:1.2787 -> destination=:1.2795 serial=13 reply_serial=2
       array [
          dict entry(
             string "mail"
             variant             array [
                   string "username@example.com"
                ]
          )
       ]
    Copy to Clipboard Toggle word wrap
    1
    在 LDAP 解决方案中提供用户名。
    2
    指定您配置的属性。
  10. 尝试以 LDAP 用户身份登录虚拟机,并确认您可以使用 LDAP 凭证登录。您可以使用本地控制台或 SSH 等远程服务登录。
重要

默认情况下,所有用户都可以使用其 LDAP 凭据登录远程基本身份验证服务器。您可以更改此行为:

15.4. 配置 Apache 使用 SSSD

  1. 创建一个包含以下内容的 /etc/pam.d/openshift 文件:

    auth required pam_sss.so
    account required pam_sss.so
    Copy to Clipboard Toggle word wrap

    此配置可让 PAM(可插拔验证模块)使用 pam_ss.so 确定为 openshift 堆栈发出身份验证请求的身份验证和访问控制。

  2. 编辑 /etc/httpd/conf.modules.d/55-authnz_pam.conf 文件并取消注释以下行:

    LoadModule authnz_pam_module modules/mod_authnz_pam.so
    Copy to Clipboard Toggle word wrap
  3. 要为远程基本身份验证配置 Apache httpd.conf 文件,请在 /etc/httpd/conf.d 目录中创建 openshift-remote-basic-auth.conf 文件。使用以下模板来提供所需设置和值:

    重要

    仔细检查模板的内容,并根据您的环境自定义其相应的内容。

    LoadModule request_module modules/mod_request.so
    LoadModule php7_module modules/libphp7.so
    
    # Nothing needs to be served over HTTP.  This virtual host simply redirects to
    # HTTPS.
    <VirtualHost *:80>
      DocumentRoot /var/www/html
      RewriteEngine              On
      RewriteRule     ^(.*)$     https://%{HTTP_HOST}$1 [R,L]
    </VirtualHost>
    
    <VirtualHost *:443>
      # This needs to match the certificates you generated.  See the CN and X509v3
      # Subject Alternative Name in the output of:
      # openssl x509 -text -in /etc/pki/tls/certs/remote-basic.example.com.crt
      ServerName remote-basic.example.com
    
      DocumentRoot /var/www/html
    
      # Secure all connections with TLS
      SSLEngine on
      SSLCertificateFile /etc/pki/tls/certs/remote-basic.example.com.crt
      SSLCertificateKeyFile /etc/pki/tls/private/remote-basic.example.com.key
      SSLCACertificateFile /etc/pki/CA/certs/ca.crt
    
      # Require that TLS clients provide a valid certificate
      SSLVerifyClient require
      SSLVerifyDepth 10
    
      # Other SSL options that may be useful
      # SSLCertificateChainFile ...
      # SSLCARevocationFile ...
    
      # Send logs to a specific location to make them easier to find
      ErrorLog logs/remote_basic_error_log
      TransferLog logs/remote_basic_access_log
      LogLevel warn
    
      # PHP script that turns the Apache REMOTE_USER env var
      # into a JSON formatted response that OpenShift understands
      <Location /check_user.php>
        # all requests not using SSL are denied
        SSLRequireSSL
        # denies access when SSLRequireSSL is applied
        SSLOptions +StrictRequire
        # Require both a valid basic auth user (so REMOTE_USER is always set)
        # and that the CN of the TLS client matches that of the OpenShift master
        <RequireAll>
          Require valid-user
          Require expr %{SSL_CLIENT_S_DN_CN} == 'system:openshift-master'
        </RequireAll>
        # Use basic auth since OpenShift will call this endpoint with a basic challenge
        AuthType Basic
        AuthName openshift
        AuthBasicProvider PAM
        AuthPAMService openshift
    
        # Store attributes in environment variables. Specify the email attribute that
        # you confirmed.
        LookupOutput Env
        LookupUserAttr mail REMOTE_USER_MAIL
        LookupUserGECOS REMOTE_USER_DISPLAY_NAME
    
        # Other options that might be useful
    
        # While REMOTE_USER is used as the sub field and serves as the immutable ID,
        # REMOTE_USER_PREFERRED_USERNAME could be used to have a different username
        # LookupUserAttr <attr_name> REMOTE_USER_PREFERRED_USERNAME
    
        # Group support may be added in a future release
        # LookupUserGroupsIter REMOTE_USER_GROUP
      </Location>
    
      # Deny everything else
      <Location ~ "^((?!\/check_user\.php).)*$">
          Deny from all
      </Location>
    </VirtualHost>
    Copy to Clipboard Toggle word wrap
  4. /var/www/html 目录中创建 check_user.php 脚本。包含以下代码:

    <?php
    // Get the user based on the Apache var, this should always be
    // set because we 'Require valid-user' in the configuration
    $user = apache_getenv('REMOTE_USER');
    
    // However, we assume it may not be set and
    // build an error response by default
    $data = array(
        'error' => 'remote PAM authentication failed'
    );
    
    // Build a success response if we have a user
    if (!empty($user)) {
        $data = array(
            'sub' => $user
        );
        // Map of optional environment variables to optional JSON fields
        $env_map = array(
            'REMOTE_USER_MAIL' => 'email',
            'REMOTE_USER_DISPLAY_NAME' => 'name',
            'REMOTE_USER_PREFERRED_USERNAME' => 'preferred_username'
        );
    
        // Add all non-empty environment variables to JSON data
        foreach ($env_map as $env_name => $json_name) {
            $env_data = apache_getenv($env_name);
            if (!empty($env_data)) {
                $data[$json_name] = $env_data;
            }
        }
    }
    
    // We always output JSON from this script
    header('Content-Type: application/json', true);
    
    // Write the response as JSON
    echo json_encode($data);
    ?>
    Copy to Clipboard Toggle word wrap
  5. 启用 Apache 加载模块。修改 /etc/httpd/conf.modules.d/55-lookup_identity.conf 文件并取消注释以下行:

    LoadModule lookup_identity_module modules/mod_lookup_identity.so
    Copy to Clipboard Toggle word wrap
  6. 设置 SELinux 布尔值,以便 SElinux 允许 Apache 通过 D-BUS 连接到 SSSD:

    # setsebool -P httpd_dbus_sssd on
    Copy to Clipboard Toggle word wrap
  7. 将布尔值设置为 告知 SELinux 可以接受 Apache 联络 PAM 子系统:

    # setsebool -P allow_httpd_mod_auth_pam on
    Copy to Clipboard Toggle word wrap
  8. 启动 Apache:

    # systemctl start httpd.service
    Copy to Clipboard Toggle word wrap

修改集群的默认配置,以使用您创建的新身份提供程序。在 Ansible 主机清单文件中列出的第一个 master 主机上完成以下步骤。

  1. 打开 /etc/origin/master/master-config.yaml 文件。
  2. 找到 identityProviders 部分,并将其替换为以下代码:

      identityProviders:
      - name: sssd
        challenge: true
        login: true
        mappingMethod: claim
        provider:
          apiVersion: v1
          kind: BasicAuthPasswordIdentityProvider
          url: https://remote-basic.example.com/check_user.php
          ca: /etc/origin/master/ca.crt
          certFile: /etc/origin/master/openshift-master.crt
          keyFile: /etc/origin/master/openshift-master.key
    Copy to Clipboard Toggle word wrap
  3. 使用更新的配置重启 OpenShift Container Platform:

    # /usr/local/bin/master-restart api api
    
    # /usr/local/bin/master-restart controllers controllers
    Copy to Clipboard Toggle word wrap
  4. 使用 oc CLI 测试登录:

    $ oc login https://openshift.example.com:8443
    Copy to Clipboard Toggle word wrap

    您只能使用有效的 LDAP 凭证登录。

  5. 列出身份,并确认为每个用户名显示一个电子邮件地址。运行以下命令:

    $ oc get identity -o yaml
    Copy to Clipboard Toggle word wrap

第 16 章 配置 SDN

16.1. 概述

OpenShift SDN 启用 OpenShift Container Platform 集群内 pod 之间的通信,并建立 pod 网络。目前提供了三个 SDN 插件ovs-subnetovs-multitenantovs-networkpolicy),提供不同的方法来配置 pod 网络。

16.2. 可用的 SDN 供应商

上游 Kubernetes 项目不附带默认的网络解决方案。相反,Kubernetes 已开发了一个 Container Network Interface(CNI),以便网络供应商与自己的 SDN 解决方案集成。

有几个 OpenShift SDN 插件可用于红帽及第三方插件。

红帽已与多个 SDN 供应商合作,通过 Kubernetes CNI 接口在 OpenShift Container Platform 上认证其 SDN 网络解决方案,其中包括通过其产品授权流程对 SDN 插件的支持流程。如果您通过 OpenShift 创建支持问题单,红帽可促进交易流程,以便这两个公司都参与满足您的需求。

以下 SDN 解决方案由第三方供应商直接在 OpenShift Container Platform 上验证和支持:

  • Cisco ACI (™)
  • Juniper Contrail(™)
  • Nokia Nuage(™)
  • Tigera Calico(™)
  • VMware NSX-T (™)
在 OpenShift Container Platform 上安装 VMware NSX-T(™)

VMware NSX-T(™)提供了一个 SDN 和安全基础架构来构建云原生应用程序环境。除了 vSphere 管理程序(ESX)外,这些环境还包括 KVM 和原生公共云。

当前集成需要同时具有 NSX-T 和 OpenShift Container Platform 的安装。目前,支持 NSX-T 版本 2.4,当前只支持使用 ESXi 和 KVM 虚拟机监控程序。

如需更多信息,请参阅 OpenShift 的 NSX-T Container Plug-in

16.3. 使用 Ansible 配置 Pod 网络

对于初始集群安装,则默认安装和配置 ovs-subnet 插件,尽管可以在安装期间使用 os_sdn_network_plugin_name 参数覆盖,可在 Ansible 清单文件中配置。

例如,要覆盖标准 ovs-subnet 插件,并使用 ovs-multitenant 插件:

# Configure the multi-tenant SDN plugin (default is 'redhat/openshift-ovs-subnet')
os_sdn_network_plugin_name='redhat/openshift-ovs-multitenant'
Copy to Clipboard Toggle word wrap

如需了解可在清单文件中设置的与网络相关的 Ansible 变量的描述,请参阅配置集群变量

16.4. 在 Master 中配置 Pod 网络

集群管理员可以通过修改 master 配置文件的 networkConfig 部分中的参数(默认位于 /etc/origin/ master /master-config.yaml )来控制 master 主机上的 pod 网络设置:

为单个 CIDR 配置 pod 网络

networkConfig:
  clusterNetworks:
  - cidr: 10.128.0.0/14 
1

    hostSubnetLength: 9 
2

  networkPluginName: "redhat/openshift-ovs-subnet" 
3

  serviceNetworkCIDR: 172.30.0.0/16 
4
Copy to Clipboard Toggle word wrap

1
用于节点 IP 分配的集群网络
2
节点内 pod IP 分配的位数
3
ovs-subnet 插件设置为 redhat/openshift-ovs-subnet,为 ovs-multitenant 插件设置为 redhat/openshift-ovs-multitenant,为 ovs-networkpolicy 插件设置为 redhat/openshift-ovs-networkpolicy
4
集群的服务 IP 分配

另外,您可以通过将单独的范围添加到带有范围和 hostSubnetLengthclusterNetworks 字段中,创建具有多个 CIDR 范围的 pod 网络。

可将多个范围用于一次,而且该范围可以被扩展或合同。通过撤离节点,可以把节点从一个范围移到另一个范围,然后删除并重新创建节点。如需更多信息,请参阅 管理节点 部分。列出顺序出现节点分配,然后在范围已满后移至列表上的下一个操作。

为多个 CIDR 配置 pod 网络

networkConfig:
  clusterNetworks:
  - cidr: 10.128.0.0/14 
1

    hostSubnetLength: 9 
2

  - cidr: 10.132.0.0/14
    hostSubnetLength: 9
  externalIPNetworkCIDRs: null
  hostSubnetLength: 9
  ingressIPNetworkCIDR: 172.29.0.0/16
  networkPluginName: redhat/openshift-ovs-multitenant 
3

  serviceNetworkCIDR: 172.30.0.0/16
Copy to Clipboard Toggle word wrap

1
用于节点 IP 分配的集群网络。
2
节点内 pod IP 分配的位数。
3
ovs-subnet 插件设置为 redhat/openshift-ovs-subnet,为 ovs-multitenant 插件设置为 redhat/openshift-ovs-multitenant,为 ovs-networkpolicy 插件设置为 redhat/openshift-ovs-networkpolicy

您可以将元素添加到 clusterNetworks 值,如果没有节点正在使用这个 CIDR 范围,则删除它们。

重要

在集群首次创建后无法更改 hostSubnetLength 值,cidr 项只能更改为一个更大的网络,它需要仍然包含原始网络(如果节点在它的范围内分配),且只能扩展 serviceNetworkCIDR。例如,对于 10.128.0.0/14 的典型值,您可以将 cidr 改为 10.128.0.0/9 (例如,net 10 的整个上半个)而不是 10.64.0.0/16,因为这不会重叠原始值。

您可以将 serviceNetworkCIDR172.30.0.0/16 改为 172.30.0.0/15,但不改为 172.28.0.0/14,因为原始范围完全位于 CIDR 的开头。如需更多信息,请参阅扩展服务网络

确保重启 API 和 master 服务以使任何更改生效:

$ master-restart api
$ master-restart controllers
Copy to Clipboard Toggle word wrap
重要

节点上的 pod 网络设置必须与 master 上的 networkConfig.clusterNetworks 参数配置的 pod 网络设置匹配。这可以通过修改相应节点 配置映射的 networkConfig 部分中的参数来实现

proxyArguments:
  cluster-cidr:
  - 10.128.0.0/12 
1
Copy to Clipboard Toggle word wrap
1
CIDR 值必须包含在 master 级别上定义的所有集群网络 CIDR 范围,但不与其他 IP 范围冲突,如用于节点和服务。

在重启 master 服务后,必须将配置传播到节点。在每个节点上,必须重启 atomic-openshift-node 服务和 ovs pod。为了避免停机遵循 管理节点 中定义的步骤,并一次为每个节点或一组节点执行以下步骤:

  1. 将节点标记为不可调度。

    # oc adm manage-node <node1> <node2> --schedulable=false
    Copy to Clipboard Toggle word wrap
  2. 排空节点:

    # oc adm drain <node1> <node2>
    Copy to Clipboard Toggle word wrap
  3. 重启节点:

    # reboot
    Copy to Clipboard Toggle word wrap
  4. 将节点重新标记为可调度:

    #  oc adm manage-node <node1> <node2> --schedulable
    Copy to Clipboard Toggle word wrap

16.5. 更改集群网络的 VXLAN PORT

作为集群管理员,您可以更改系统使用的 VXLAN 端口。

由于您无法更改正在运行的 clusternetwork 对象的 VXLAN 端口,所以您必须通过编辑 master 配置文件中的 vxlanPort 变量来删除任何现有的网络配置。

  1. 删除现有的 clusternetwork

    # oc delete clusternetwork default
    Copy to Clipboard Toggle word wrap
  2. 编辑 master 配置文件(默认位于 /etc/origin/master/master-config.yaml)来创建新的 clusternetwork

    networkConfig:
      clusterNetworks:
      - cidr: 10.128.0.0/14
        hostSubnetLength: 9
      - cidr: 10.132.0.0/14
        hostSubnetLength: 9
      externalIPNetworkCIDRs: null
      hostSubnetLength: 9
      ingressIPNetworkCIDR: 172.29.0.0/16
      networkPluginName: redhat/openshift-ovs-multitenant
      serviceNetworkCIDR: 172.30.0.0/16
      vxlanPort: 4889 
    1
    Copy to Clipboard Toggle word wrap
    1
    设置为节点用于 VXLAN 端口的值。它可以是 1-65535 之间的一个整数。默认值为 4789
  3. 在每个集群节点上的 iptables 规则添加新端口:

    # iptables -A OS_FIREWALL_ALLOW -p udp -m state --state NEW -m udp --dport 4889 -j ACCEPT 
    1
    Copy to Clipboard Toggle word wrap
    1
    4889 是您在主配置文件中设置的 vxlanPort 值。
  4. 重启 master 服务:

    # master-restart api
    # master-restart controllers
    Copy to Clipboard Toggle word wrap
  5. 删除所有旧的 SDN pod,以使用新更改传播新 pod:

    # oc delete pod -l app=sdn -n openshift-sdn
    Copy to Clipboard Toggle word wrap

16.6. 在节点上配置 Pod 网络

集群管理员可以通过修改相应节点配置映射的 networkConfig 部分中的参数来控制 节点上的 pod 网络设置

networkConfig:
  mtu: 1450 
1

  networkPluginName: "redhat/openshift-ovs-subnet" 
2
Copy to Clipboard Toggle word wrap
1
pod 覆盖网络的最大传输单元(MTU)
2
ovs-subnet 插件设置为 redhat/openshift-ovs-subnet,为 ovs-multitenant 插件设置为 redhat/openshift-ovs-multitenant,为 ovs-networkpolicy 插件设置为 redhat/openshift-ovs-networkpolicy
注意

您必须在所有 master 和作为 OpenShift Container Platform SDN 一部分的节点上更改 MTU 大小。另外,tun0 接口的 MTU 大小必须在属于集群的所有节点中相同。

16.7. 扩展服务网络

如果您在服务网络中的有效地址的数量较少,只要您确定当前范围位于新范围的开头,就可以扩展该范围。

注意

服务网络只能扩展,无法更改或合同。

  1. 对所有的 master,修改配置文件中的 serviceNetworkCIDRservicesSubnet 参数(默认为 /etc/origin/master/master-config.yaml)。仅将 / 后面的数字更改为较小的数字。
  2. 删除 clusterNetwork 默认 对象:

    $ oc delete clusternetwork default
    Copy to Clipboard Toggle word wrap
  3. 在所有 master 上重启控制器组件:

    # master-restart controllers
    Copy to Clipboard Toggle word wrap
  4. 将 Ansible 清单文件中的 openshift_portal_net 变量的值更新为新的 CIDR:

    # Configure SDN cluster network and kubernetes service CIDR blocks. These
    # network blocks should be private and should not conflict with network blocks
    # in your infrastructure that pods may require access to. Can not be changed
    # after deployment.
    openshift_portal_net=172.30.0.0/<new_CIDR_range>
    Copy to Clipboard Toggle word wrap

对于集群中的每个节点,请完成以下步骤:

16.8. 在 SDN 插件之间迁移

如果您已经使用一个 SDN 插件,并希望切换到另外一个 SDN 插件:

  1. 在所有 master节点上 更改 networkPluginName 参数。
  2. 在所有 master 上重启 API 和 master 服务:

    # master-restart api
    # master-restart controllers
    Copy to Clipboard Toggle word wrap
  3. 停止所有 master 和节点上的节点服务:

    # systemctl stop atomic-openshift-node.service
    Copy to Clipboard Toggle word wrap
  4. 如果您要在 OpenShift SDN 插件间进行切换,请在所有 master 和节点上重启 OpenShift SDN。

    oc delete pod --all -n openshift-sdn
    Copy to Clipboard Toggle word wrap
  5. 在所有 master 和节点上重启节点服务:

    # systemctl restart atomic-openshift-node.service
    Copy to Clipboard Toggle word wrap
  6. 如果您要从 OpenShift SDN 插件切换到第三方插件,请清理特定于 OpenShift SDN 的工件:

    $ oc delete clusternetwork --all
    $ oc delete hostsubnets --all
    $ oc delete netnamespaces --all
    Copy to Clipboard Toggle word wrap
重要

另外,在切换到 ovs-multitenant 后,用户无法使用服务目录置备服务。对 openshift-monitoring 也是如此。要更正此问题,使这些项目成为全局项目:

$ oc adm pod-network make-projects-global kube-service-catalog
$ oc adm pod-network make-projects-global openshift-monitoring
Copy to Clipboard Toggle word wrap

如果集群最初使用 ovs-multitenant 安装,则不会出现此问题,因为这些命令是作为 Ansible playbook 的一部分执行的。

注意

ovs-subnet 切换到 ovs-multitenant OpenShift SDN 插件时,集群中的所有现有项目都将被完全隔离(作为唯一的 VNID)。集群管理员可以选择使用管理员 CLI 修改项目网络

运行以下命令来检查 VNIDs:

$ oc get netnamespace
Copy to Clipboard Toggle word wrap

16.8.1. 从 ovs-multitenant 迁移到 ovs-networkpolicy

注意

v1 NetworkPolicy 功能仅适用于 OpenShift Container Platform。这意味着 OpenShift Container Platform 不提供出口策略类型、IPBlock 和组合 podSelectornamespaceSelector

注意

不要在默认的 OpenShift Container Platform 项目中应用 NetworkPolicy 功能,因为它们可能会破坏与集群的通信。

除了在 SDN 插件间迁移以上通用的插件迁移步骤外,从 ovs-multitenant 插件迁移到 ovs-networkpolicy 插件时,会有一个额外的步骤。您需要确定每个命名空间有一个唯一的 NetID这意味着,如果您之前已将项目接合在一起将项目设置为全局项目,则需要在切换到 ovs-networkpolicy 插件前撤销该项目,否则 NetworkPolicy 对象无法正常工作。

提供了一个帮助脚本,可修复 NetID 的,创建 NetworkPolicy 对象来隔离之前隔离命名空间,并启用之前加入的命名空间之间的连接。

使用以下步骤将这个帮助程序脚本迁移到 ovs-networkpolicy 插件,同时仍然运行 ovs-multitenant 插件:

  1. 下载脚本并添加执行文件权限:

    $ curl -O https://raw.githubusercontent.com/openshift/origin/release-3.11/contrib/migration/migrate-network-policy.sh
    $ chmod a+x migrate-network-policy.sh
    Copy to Clipboard Toggle word wrap
  2. 运行脚本(需要集群管理员角色)。

    $ ./migrate-network-policy.sh
    Copy to Clipboard Toggle word wrap

运行此脚本后,每个命名空间都完全与其它命名空间隔离,因此不同命名空间中的 pod 间的连接尝试会失败,直到完成到 ovs-networkpolicy 插件为止。

如果您希望新创建的命名空间同时具有相同的策略,您可以将默认 NetworkPolicy 对象设置为与 default-deny 匹配,以及由迁移脚本创建的 allow-from-global-namespaces 策略。

注意

如果脚本失败或其他错误,或者稍后决定恢复到 ovs-multitenant 插件,您可以使用 un-migration 脚本。此脚本会撤消迁移脚本所做的更改,并重新加入之前加入的命名空间。

16.9. 外部访问集群网络

如果一个 OpenShift Container Platform 以外的主机需要访问集群网络,则有两个选项:

  1. 将主机配置为 OpenShift Container Platform 节点,但将其 不可调度,以便 master 不会在其上调度容器。
  2. 在主机和位于集群网络上的主机间创建一个隧道。

这两个选项都作为实际用例的一部分阐述,在文档中用于配置 从边缘负载均衡器到 OpenShift SDN 中的容器的路由

16.10. 使用 Flannel

作为默认 SDN 的替代方案,OpenShift Container Platform 还提供用于安装基于 flannel的网络的 Ansible playbook。这在两个平台中也依赖于 SDN 的云供应商平台(如 Red Hat OpenStack Platform)中运行 OpenShift Container Platform 非常有用。

Flannel 使用单个 IP 网络命名空间用于向每个实例分配连续空间子集。因此,容器无法尝试联系同一网络空间中的任何 IP 地址。这种障碍的多租户是多租户,因为网络无法用于将一个应用中的容器与另一个应用隔离。

根据您首选的租户隔离还是性能,您应该在决定 OpenShift SDN(多租户)和用于内部网络的 flannel(多租户)之间决定适当的选择。

重要

Flannel 仅支持 Red Hat OpenStack Platform 上的 OpenShift Container Platform。

重要

当前版本的 Neutron 默认在端口上强制实施端口安全性。这可防止端口发送或接收使用与端口本身不同的 MAC 地址的数据包。Flannel 创建虚拟 MAC 和 IP 地址,且必须在端口上发送和接收数据包,因此在执行 flannel 流量的端口上必须禁用端口安全性。

在 OpenShift Container Platform 集群中启用 flannel:

  1. Neutron 端口安全控制必须配置为与 Flannel 兼容。Red Hat OpenStack Platform 的默认配置会禁用用户对 port_security 的控制。配置 Neutron,以允许用户控制各个端口上的 port_security 设置。

    1. 在 Neutron 服务器上,将以下内容添加到 /etc/neutron/plugins/ml2/ml2_conf.ini 文件:

      [ml2]
      ...
      extension_drivers = port_security
      Copy to Clipboard Toggle word wrap
    2. 然后重启 Neutron 服务:

      service neutron-dhcp-agent restart
      service neutron-ovs-cleanup restart
      service neutron-metadata-agentrestart
      service neutron-l3-agent restart
      service neutron-plugin-openvswitch-agent restart
      service neutron-vpn-agent restart
      service neutron-server  restart
      Copy to Clipboard Toggle word wrap
  2. 在 Red Hat OpenStack Platform 上创建 OpenShift Container Platform 实例时,在容器网络 flannel 接口的端口中禁用端口安全性和安全组:

    neutron port-update $port --no-security-groups --port-security-enabled=False
    Copy to Clipboard Toggle word wrap
    注意

    Flannel 从 etcd 收集信息来配置和分配节点的子网。因此,附加到 etcd 主机的安全组应该允许从节点访问端口 2379/tcp,节点安全组应允许到 etcd 主机上该端口的出口通信。

    1. 在运行安装前,在 Ansible 清单文件中设置以下变量:

      openshift_use_openshift_sdn=false 
      1
      
      openshift_use_flannel=true 
      2
      
      flannel_interface=eth0
      Copy to Clipboard Toggle word wrap
      1
      openshift_use_openshift_sdn 设置为 false 以禁用默认的 SDN。
      2
      openshift_use_flannel 设置为 true 以启用 flannel
    2. 另外,您还可以使用 flannel_interface 变量来指定要用于主机间通信的接口。如果没有此变量,OpenShift Container Platform 安装将使用默认接口。

      注意

      以后的发行版本中将支持使用 flannel 的 pod 和服务的自定义网络 CIDR。BZ#1473858

  3. 在 OpenShift Container Platform 安装后,在每个 OpenShift Container Platform 节点上添加一组 iptables 规则:

    iptables -A DOCKER -p all -j ACCEPT
    iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
    Copy to Clipboard Toggle word wrap

    要在 /etc/sysconfig/iptables 中保留这些更改,在每个节点上使用以下命令:

    cp /etc/sysconfig/iptables{,.orig}
    sh -c "tac /etc/sysconfig/iptables.orig | sed -e '0,/:DOCKER -/ s/:DOCKER -/:DOCKER ACCEPT/' | awk '"\!"p && /POSTROUTING/{print \"-A POSTROUTING -o eth1 -j MASQUERADE\"; p=1} 1' | tac > /etc/sysconfig/iptables"
    Copy to Clipboard Toggle word wrap
    注意

    iptables-save 命令保存在 内存 iptables 规则中的所有 当前。但是,由于 Docker,Kubernetes 和 OpenShift Container Platform 会创建大量 iptables 规则(服务等),因此无法保留这些规则,保存这些规则可能会变得存在问题。

要从 OpenShift Container Platform 流量隔离容器流量,红帽建议创建隔离的租户网络并将所有节点附加到其中。如果您使用不同的网络接口(eth1),请记得通过 /etc/sysconfig/network-scripts/ifcfg-eth1 文件将接口配置为在引导时启动:

DEVICE=eth1
TYPE=Ethernet
BOOTPROTO=dhcp
ONBOOT=yes
DEFTROUTE=no
PEERDNS=no
Copy to Clipboard Toggle word wrap

第 17 章 配置 Nuage SDN

17.1. Nuage SDN 和 OpenShift Container Platform

Nuage Networks Virtualized Services Platform (VSP) 为容器环境提供虚拟网络和软件定义网络 (SDN) 基础架构,从而简化 IT 操作并扩展 OpenShift Container Platform 的原生网络功能。

Nuage Networks VSP 支持在 OpenShift Container Platform 上运行的基于 Docker 的应用程序,以加快 pod 和传统工作负载之间的虚拟网络配置,并跨整个云基础架构启用安全策略。VSP 允许自动化安全设备,为容器应用包含精细安全性和微分段策略。

将 VSP 与 OpenShift Container Platform 应用程序工作流集成,可通过删除 DevOps 团队所面临的网络布局快速打开和更新应用程序。VSP 通过 OpenShift Container Platform 支持不同的工作流,以适应用户在使用基于策略的自动化时或完全控制的场景。

如需有关 VSP 与 OpenShift Container Platform 集成的更多信息,请参阅 网络

17.2. 开发人员工作流

此工作流用于开发环境,需要开发人员进行很少的输入来设置网络。在此工作流中,nuage-openshift-monitor 负责创建为 OpenShift Container Platform 项目中创建的 pod 提供适当策略和网络所需的 VSP 结构(Zone、子网等)。创建项目时,由 nuage-openshift-monitor 创建该项目的默认区域和默认子网。当为给定项目创建的默认子网被省略时,nu age-openshift-monitor 会动态创建额外的子网。

注意

为每个 OpenShift Container Platform 项目创建一个单独的 VSP Zone,可确保在项目之间隔离。

17.3. 操作工作流

运维团队会使用此工作流来推出应用程序。在此工作流中,首先在 VSD 上配置网络和安全策略,以根据组织设置的规则来部署应用。管理用户可能会创建多个区域和子网,并使用标签将它们映射到同一项目。在启动 pod 时,用户可以使用 Nuage Labels 指定 pod 需要附加到的网络,以及需要将其应用哪些网络策略。这允许以精细的方式控制项目内和内部流量的部署。例如,项目基础上启用了项目间的通信。这可用于将项目连接到部署在共享项目中的常用服务。

17.4. 安装

VSP 与 OpenShift Container Platform 集成可用于虚拟机(VM)和裸机 OpenShift Container Platform 安装。

具有高可用性(HA)的环境可以配置多个 master 和多个节点。

在多 master 模式中的 Nuage VSP 集成只支持本节中介绍的原生 HA 配置方法。这可以和任何负载平衡解决方案结合使用,这是 HAProxy 的默认设置。清单文件包含三个 master 主机、节点、etcd 服务器和一个 HAProxy,以在所有 master 主机上平衡主 API。HAProxy 主机在清单文件的 [lb] 部分中定义,使 Ansible 能够自动安装和配置 HAProxy 作为负载平衡解决方案。

在 Ansible 节点文件中,需要指定以下参数,才能将 Nuage VSP 设置为网络插件:

 # Create and OSEv3 group that contains masters, nodes, load-balancers, and etcd hosts
 masters
 nodes
 etcd
 lb

 # Nuage specific parameters
 openshift_use_openshift_sdn=False
 openshift_use_nuage=True
 os_sdn_network_plugin_name='nuage/vsp-openshift'
 openshift_node_proxy_mode='userspace'

 # VSP related parameters
 vsd_api_url=https://192.168.103.200:8443
 vsp_version=v4_0
 enterprise=nuage
 domain=openshift
 vsc_active_ip=192.168.103.201
 vsc_standby_ip=192.168.103.202
 uplink_interface=eth0

 # rpm locations
 nuage_openshift_rpm=http://location_of_rpm_server/openshift/RPMS/x86_64/nuage-openshift-monitor-4.0.X.1830.el7.centos.x86_64.rpm
 vrs_rpm=http://location_of_rpm_server/openshift/RPMS/x86_64/nuage-openvswitch-4.0.X.225.el7.x86_64.rpm
 plugin_rpm=http://location_of_rpm_server/openshift/RPMS/x86_64/vsp-openshift-4.0.X1830.el7.centos.x86_64.rpm

 # Required for Nuage Monitor REST server and HA
 openshift_master_cluster_method=native
 openshift_master_cluster_hostname=lb.nuageopenshift.com
 openshift_master_cluster_public_hostname=lb.nuageopenshift.com
 nuage_openshift_monitor_rest_server_port=9443

 # Optional parameters
 nuage_interface_mtu=1460
 nuage_master_adminusername='admin's user-name'
 nuage_master_adminuserpasswd='admin's password'
 nuage_master_cspadminpasswd='csp admin password'
 nuage_openshift_monitor_log_dir=/var/log/nuage-openshift-monitor

 # Required for brownfield install (where a {product-title} cluster exists without Nuage as the networking plugin)
 nuage_dockker_bridge=lbr0

 # Specify master hosts
 [masters]
 fqdn_of_master_1
 fqdn_of_master_2
 fqdn_of_master_3

 # Specify load balancer host
 [lb]
 fqdn_of_load_balancer
Copy to Clipboard Toggle word wrap

第 18 章 配置 NSX-T SDN

18.1. NSX-T SDN 和 OpenShift Container Platform

VMware NSX-T Data Center ™ 为简化 IT 操作并扩展了原生 OpenShift Container Platform 网络功能提供高级软件定义网络(SDN)、安全性和可见性。

NSX-T Data Center 支持跨多个集群的虚拟机、裸机和容器工作负载。这使得组织可以在整个环境中使用单个 SDN 来完成可见性。

有关如何与 OpenShift Container Platform 集成 NSX-T 的更多信息,请参阅 Available SDN 插件中的 NSX-T SDN

18.2. Topology 示例

一个典型的用例是有一个 Tier-0 (T0) 路由器将物理系统与虚拟环境连接,以及一个 Tier-1 (T1) 路由器充当 OpenShift Container Platform 虚拟机的默认网关。

每个虚拟机有两个 vNIC:一个 vNIC 连接至管理逻辑交换机,以访问虚拟机。其他 vNIC 连接到 Dump Logical Switch,并由 nsx-node-agent 用来连接 Pod 网络。详情请参阅 OpenShift 的 NSX Container Plug-in

用于在 OpenShift Container Platform 安装过程中自动创建用于配置 OpenShift Container Platform 路由和所有项目 T1 路由器和逻辑交换机的 LoadBalancer。

在此拓扑中,默认的 OpenShift Container Platform HAProxy 路由器用于所有基础架构组件,如 Grafana、Prometheus、控制台、服务目录等。确保基础架构组件的 DNS 记录指向基础架构节点 IP 地址,因为 HAProxy 使用主机网络命名空间。这适用于基础架构路由,但为了避免将基础架构节点管理 IP 公开给外部世界,请将特定于应用程序的路由部署到 NSX-T LoadBalancer 中。

此示例拓扑假设您使用三个 OpenShift Container Platform master 虚拟机,以及四个 OpenShift Container Platform worker 虚拟机(用于基础架构,两个用于 compute)。

18.3. 安装 VMware NSX-T

先决条件

  • ESXi 主机要求:

    • 托管 OpenShift Container Platform 节点虚拟机的 ESXi 服务器必须是 NSX-T 传输节点。

      图 18.1. NSX UI 为典型的高可用性环境分离传输节点:

  • DNS 要求:

    • 您必须在 DNS 服务器中向基础架构节点使用通配符添加新条目。这允许 NSX-T 或其他第三方 LoadBalancer 进行负载均衡。在下面的 hosts 文件中,条目由 openshift_master_default_subdomain 变量定义。
    • 您必须使用 openshift_master_cluster_hostnameopenshift_master_cluster_public_hostname 变量更新您的 DNS 服务器。
  • 虚拟机要求:

    • OpenShift Container Platform 节点虚拟机必须有两个 vNIC:
    • 管理 vNIC 必须连接到连接到管理 T1 路由器的逻辑交换机。
    • 所有虚拟机上的第二个 vNIC 必须标记 NSX-T,以便 NSX Container Plug-in(NCP)知道哪个端口需要用作特定 OpenShift Container Platform 节点上运行的所有 Pod 的父 VIF。标签必须如下:

      {'ncp/node_name': 'node_name'}
      {'ncp/cluster': 'cluster_name'}
      Copy to Clipboard Toggle word wrap

      下图显示了所有节点的 NSX UI 中的标签。对于大规模集群,您可以使用 API 调用或使用 Ansible 自动标记。

      图 18.2. NSX UI 显示节点标签

      NSX UI 中的标签顺序与 API 相反。节点名称必须与 kubelet 预期相同,集群名称必须与 Ansible 主机文件中的 nsx_openshift_cluster_name 相同,如下所示。确保每个节点上的第二个 vNIC 中应用正确的标签。

  • NSX-T 要求:

    在 NSX 中需要满足以下先决条件:

    • Tier-0 路由器.
    • Overlay Transport Zone.
    • POD 网络的 IP 块。
    • (可选)用于路由(NoNAT) POD 网络的 IP 块。
    • SNAT 的 IP 池。默认情况下,每个项目从 Pod 网络 IP Block 指定的子网只能在 NSX-T 中路由。NCP 使用这个 IP 池提供与外部的连接。
    • (可选)dFW(分发防火墙)中的 top 和 Bottom 防火墙部分。NCP 在这两个部分之间放置 Kubernetes 网络策略规则。
    • Open vSwitch 和 CNI 插件 RPM 需要托管在 HTTP 服务器中,可从 OpenShift Container Platform 节点虚拟机访问(在这个示例中为 http://websrv.example.com)。这些文件包含在 NCP Tar 文件中,您可以在 Download NSX Container Plug-in 2.4.0 从 VMware 下载。
  • OpenShift Container Platform 要求:

    • 运行以下命令,为 OpenShift Container Platform 安装所需的软件包(若有):

      $ ansible-playbook -i hosts openshift-ansible/playbooks/prerequisites.yml
      Copy to Clipboard Toggle word wrap
    • 确保所有节点上本地下载 NCP 容器镜像
    • prerequisites.yml playbook 成功执行后,在所有节点上运行以下命令,将 xxx 替换为 NCP 构建版本:

      $ docker load -i nsx-ncp-rhel-xxx.tar
      Copy to Clipboard Toggle word wrap

      例如:

      $ docker load -i nsx-ncp-rhel-2.4.0.12511604.tar
      Copy to Clipboard Toggle word wrap
    • 获取镜像名称并重新标记它:

      $ docker images
      $ docker image tag registry.local/xxxxx/nsx-ncp-rhel nsx-ncp 
      1
      Copy to Clipboard Toggle word wrap
      1
      xxx 替换为 NCP 构建版本。例如:
      docker image tag registry.local/2.4.0.12511604/nsx-ncp-rhel nsx-ncp
      Copy to Clipboard Toggle word wrap
    • 在 OpenShift Container Platform Ansible 主机文件中,指定以下参数,将 NSX-T 设置为网络插件:

      [OSEv3:children]
      masters
      nodes
      etcd
      
      [OSEv3:vars]
      ansible_ssh_user=root
      openshift_deployment_type=origin
      openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true', 'challenge': 'true', 'kind': 'HTPasswdPasswordIdentityProvider'}]
      openshift_master_htpasswd_users={"admin" : "$apr1$H0QeP6oX$HHdscz5gqMdtTcT5eoCJ20"}
      openshift_master_default_subdomain=demo.example.com
      openshift_use_nsx=true
      os_sdn_network_plugin_name=cni
      openshift_use_openshift_sdn=false
      openshift_node_sdn_mtu=1500
      openshift_master_cluster_method=native
      openshift_master_cluster_hostname=master01.example.com
      openshift_master_cluster_public_hostname=master01.example.com
      openshift_hosted_manage_registry=true
      openshift_hosted_manage_router=true
      openshift_enable_service_catalog=true
      openshift_cluster_monitoring_operator_install=true
      openshift_web_console_install=true
      openshift_console_install=true
      
      # NSX-T specific configuration
      #nsx_use_loadbalancer=false
      nsx_openshift_cluster_name='cluster01'
      nsx_api_managers='nsxmgr.example.com'
      nsx_api_user='nsx_admin'
      nsx_api_password='nsx_api_password_example'
      nsx_tier0_router='LR-Tier-0'
      nsx_overlay_transport_zone='TZ-Overlay'
      nsx_container_ip_block='pod-networking'
      nsx_no_snat_ip_block='pod-nonat'
      nsx_external_ip_pool='pod-external'
      nsx_top_fw_section='containers-top'
      nsx_bottom_fw_section='containers-bottom'
      nsx_ovs_uplink_port='ens224'
      nsx_cni_url='http://websrv.example.com/nsx-cni-buildversion.x86_64.rpm'
      nsx_ovs_url='http://websrv.example.com/openvswitch-buildversion.rhel75-1.x86_64.rpm'
      nsx_kmod_ovs_url='http://websrv.example.com/kmod-openvswitch-buildversion.rhel75-1.el7.x86_64.rpm'
      nsx_insecure_ssl=true
      # vSphere Cloud Provider
      #openshift_cloudprovider_kind=vsphere
      #openshift_cloudprovider_vsphere_username='administrator@example.com'
      #openshift_cloudprovider_vsphere_password='viadmin_password'
      #openshift_cloudprovider_vsphere_host='vcsa.example.com'
      #openshift_cloudprovider_vsphere_datacenter='Example-Datacenter'
      #openshift_cloudprovider_vsphere_cluster='example-Cluster'
      #openshift_cloudprovider_vsphere_resource_pool='ocp'
      #openshift_cloudprovider_vsphere_datastore='example-Datastore-name'
      #openshift_cloudprovider_vsphere_folder='ocp'
      
      [masters]
      master01.example.com
      master02.example.com
      master03.example.com
      
      [etcd]
      master01.example.com
      master02.example.com
      master03.example.com
      
      [nodes]
      master01.example.com ansible_ssh_host=192.168.220.2 openshift_node_group_name='node-config-master'
      master02.example.com ansible_ssh_host=192.168.220.3 openshift_node_group_name='node-config-master'
      master03.example.com ansible_ssh_host=192.168.220.4 openshift_node_group_name='node-config-master'
      node01.example.com ansible_ssh_host=192.168.220.5 openshift_node_group_name='node-config-infra'
      node02.example.com ansible_ssh_host=192.168.220.6 openshift_node_group_name='node-config-infra'
      node03.example.com ansible_ssh_host=192.168.220.7 openshift_node_group_name='node-config-compute'
      node04.example.com ansible_ssh_host=192.168.220.8 openshift_node_group_name='node-config-compute'
      Copy to Clipboard Toggle word wrap

      如需有关 OpenShift Container Platform 安装参数的信息,请参阅 配置清单文件

流程

满足所有先决条件后,您可以部署 NSX Data Center 和 OpenShift Container Platform。

  1. 部署 OpenShift Container Platform 集群:

    $ ansible-playbook -i hosts openshift-ansible/playbooks/deploy_cluster.yml
    Copy to Clipboard Toggle word wrap

    如需有关 OpenShift Container Platform 安装的更多信息,请参阅安装 OpenShift Container Platform

  2. 安装完成后,验证 NCP 和 nsx-node-agent Pod 是否正在运行:

    $ oc get pods -o wide -n nsx-system
    NAME                   READY     STATUS    RESTARTS   AGE       IP              NODE                                   NOMINATED NODE
    nsx-ncp-5sggt          1/1       Running   0          1h        192.168.220.8   node04.example.com     <none>
    nsx-node-agent-b8nkm   2/2       Running   0          1h        192.168.220.5   node01.example.com     <none>
    nsx-node-agent-cldks   2/2       Running   0          2h        192.168.220.8   node04.example.com     <none>
    nsx-node-agent-m2p5l   2/2       Running   28         3h        192.168.220.4   master03.example.com   <none>
    nsx-node-agent-pcfd5   2/2       Running   0          1h        192.168.220.7   node03.example.com     <none>
    nsx-node-agent-ptwnq   2/2       Running   26         3h        192.168.220.2   master01.example.com   <none>
    nsx-node-agent-xgh5q   2/2       Running   26         3h        192.168.220.3   master02.example.com   <none>
    Copy to Clipboard Toggle word wrap

安装 OpenShift Container Platform 并验证 NCP 和 nsx-node-agent-* Pod:

  • 检查路由。确保安装期间创建了 Tier-1 路由器,并链接到 Tier-0 路由器:

    图 18.3. NSX UI dislaying 显示 T1 路由器

  • 观察网络 traceflow 和 visibility。例如,检查 'console' 和 'grafana' 之间的连接。

    如需有关保护 Pod、项目、虚拟机和外部服务间的通信的更多信息,请参见以下示例:

    图 18.4. NSX UI dislaying 显示网络 traceflow

  • 检查负载平衡。NSX-T 数据中心提供 Load Balancer 和 Ingress Controller 功能,如下例所示:

    图 18.5. NSX UI 显示展示负载均衡器

有关其他配置和选项,请参阅 VMware NSX-T v2.4 OpenShift Plug-In 文档。

第 19 章 配置 Kuryr SDN

19.1. Kuryr SDN 和 OpenShift Container Platform

Kuryr (或更具体为 Kuryr-Kubernetes)是一个使用 CNIOpenStack Neutron 构建的 SDN 解决方案。其优点包括能够使用广泛的 Neutron SDN 后端,并在 Kubernetes pod 和 OpenStack 虚拟机(VM)之间提供连接。

Kuryr-Kubernetes 和 OpenShift Container Platform 集成主要针对在 OpenStack 虚拟机上运行的 OpenShift Container Platform 集群设计。Kuryr-Kubernetes 组件作为 pod 在 kuryr 命名空间中的 OpenShift Container Platform 上安装:

  • kuryr-controller - 在一个 infra 节点上安装的单个服务实例。在 OpenShift Container Platform 中建模为一个 部署
  • kuryr-cni - 在每个 OpenShift Container Platform 节点上安装和配置 Kuryr 作为 CNI 驱动程序。在 OpenShift Container Platform 中建模为一个 DaemonSet

Kuryr 控制器监控 OpenShift API 服务器中的 pod、服务和命名空间创建、更新和删除事件。它将 OpenShift Container Platform API 调用映射到 Neutron 和 Octavia 中的对应对象。这意味着,实现了 Neutron 中继端口功能的每个网络解决方案都可以通过 Kuryr 支持 OpenShift Container Platform。这包括开源解决方案,如 OVS 和 OVN,以及 Neutron 兼容的商业 SDN。

19.2. 安装 Kuryr SDN

对于 OpenStack 云上的 Kuryr SDN 安装,您必须遵循 OpenStack 配置文档 中所述的步骤。

19.3. 验证

安装 OpenShift Container Platform 后,您可以检查 Kuryr pod 是否已成功部署:

$ oc -n kuryr get pods -o wide
NAME                                READY     STATUS    RESTARTS   AGE       IP              NODE
kuryr-cni-ds-66kt2                  2/2       Running   0          3d        192.168.99.14   infra-node-0.openshift.example.com
kuryr-cni-ds-ggcpz                  2/2       Running   0          3d        192.168.99.16   master-0.openshift.example.com
kuryr-cni-ds-mhzjt                  2/2       Running   0          3d        192.168.99.6    app-node-1.openshift.example.com
kuryr-cni-ds-njctb                  2/2       Running   0          3d        192.168.99.12   app-node-0.openshift.example.com
kuryr-cni-ds-v8hp8                  2/2       Running   0          3d        192.168.99.5    infra-node-1.openshift.example.com
kuryr-controller-59fc7f478b-qwk4k   1/1       Running   0          3d        192.168.99.5    infra-node-1.openshift.example.com
Copy to Clipboard Toggle word wrap

Kuryr-cni pod 在每个 OpenShift Container Platform 节点上运行。单一 kuryr-controller 实例可以在任何 infra 节点上运行。

注意

启用 Kuryr SDN 时不支持网络策略和节点端口服务。

第 20 章 为 Amazon Web Services(AWS)配置

20.1. 概述

OpenShift Container Platform 可以配置为访问 AWS EC2 基础架构包括使用 AWS 卷作为应用程序数据的持久性存储。配置 AWS 后,必须在 OpenShift Container Platform 主机上完成一些额外的配置。

20.1.1. 为 Amazon Web Services(AWS)配置授权

权限 AWS 实例需要使用在创建时分配给实例的 access 和 secret 密钥或 IAM 角色来请求和管理 OpenShift Container Platform 中的负载均衡器和存储的 IAM 角色。

IAM 帐户或 IAM 角色必须具有以下策略权限才能拥有完整的云供应商功能。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "ec2:DescribeVolume*",
                "ec2:CreateVolume",
                "ec2:CreateTags",
                "ec2:DescribeInstances",
                "ec2:AttachVolume",
                "ec2:DetachVolume",
                "ec2:DeleteVolume",
                "ec2:DescribeSubnets",
                "ec2:CreateSecurityGroup",
                "ec2:DescribeSecurityGroups",
                "ec2:DeleteSecurityGroup",
                "ec2:DescribeRouteTables",
                "ec2:AuthorizeSecurityGroupIngress",
                "ec2:RevokeSecurityGroupIngress",
                "elasticloadbalancing:DescribeTags",
                "elasticloadbalancing:CreateLoadBalancerListeners",
                "elasticloadbalancing:ConfigureHealthCheck",
                "elasticloadbalancing:DeleteLoadBalancerListeners",
                "elasticloadbalancing:RegisterInstancesWithLoadBalancer",
                "elasticloadbalancing:DescribeLoadBalancers",
                "elasticloadbalancing:CreateLoadBalancer",
                "elasticloadbalancing:DeleteLoadBalancer",
                "elasticloadbalancing:ModifyLoadBalancerAttributes",
                "elasticloadbalancing:DescribeLoadBalancerAttributes"
            ],
            "Resource": "*",
            "Effect": "Allow",
            "Sid": "1"
        }
    ]
}
Copy to Clipboard Toggle word wrap
aws iam put-role-policy \
  --role-name openshift-role \
  --policy-name openshift-admin \
  --policy-document file: //openshift_iam_policy
Copy to Clipboard Toggle word wrap
aws iam put-user-policy \
  --user-name openshift-admin \
  --policy-name openshift-admin \
  --policy-document file: //openshift_iam_policy
Copy to Clipboard Toggle word wrap
注意

OpenShift 节点实例只需要 ec2:DescribeInstance 权限,但安装程序仅允许定义单个 AWS 访问密钥和 secret。这可绕过使用 IAM 角色,并将上面的权限分配给 master 实例,并将 ec2:DescribeInstance 分配给节点。

流程

要使用具有 access 和 secret 键的 IAM 帐户配置 Amazon Web Services 云供应商,请将以下值添加到清单中:

[OSEv3:vars]
openshift_cloudprovider_kind=aws
openshift_clusterid=openshift 
1

openshift_cloudprovider_aws_access_key=AKIAJ6VLBLISADPBUA 
2

openshift_cloudprovider_aws_secret_key=g/8PmDNYHVSQn0BQE+xtsHzbaZaGYjGNzhbdgwjH 
3
Copy to Clipboard Toggle word wrap
1
分配给所有资源(实例、负载平衡器、vpc 等)的标签(用于 OpenShift)。
2
IAM 帐户使用的 AWS 访问密钥。
3
IAM 帐户使用的 AWS secret 密钥。

要使用 IAM 角色配置 Amazon Web Services 云供应商,请在清单中添加以下值:

[source,yaml]
----
[OSEv3:vars]
openshift_cloudprovider_kind=aws
openshift_clusterid=openshift 
1

----
<1> A tag assigned to all resources (instances, load balancers, vpc, etc) used for OpenShift.
Copy to Clipboard Toggle word wrap
NOTE: The IAM role takes the place of needing an access and secret key.
Copy to Clipboard Toggle word wrap

如果安装时没有提供 Amazon Web Services 云供应商值,则可以在安装后定义和创建配置。按照以下步骤配置配置文件,并为 AWS 手动配置 master 和节点

重要
  • 每个 master 主机、节点主机和子网必须具有 kubernetes.io/cluster/<clusterid>,Value=(owned|shared) 标签。
  • 一个安全组(最好链接到节点)必须具有 kubernetes.io/cluster/<clusterid>,Value=(owned|shared) 标签。

    • 不要使用 kubernetes.io/cluster/<clusterid>,Value=(owned|shared) 标签标记所有安全组,否则 Elastic Load Balancing(ELB)将无法创建负载均衡器。

20.2. 配置安全组

在 AWS 上安装 OpenShift Container Platform 时,请确保设置适当的安全组。

这些是在安全组中必须具有的一些端口,而安装会失败。根据您要安装的集群配置,您可能需要更多。如需更多信息,并相应地调整您的安全组,请参阅所需端口以了解更多信息。

Expand

所有 OpenShift Container Platform 主机

  • 来自运行安装程序/Ansible 的主机的 TCP/22

etcd 安全组

  • 来自 master 的 TCP/2379
  • 来自 etcd 主机的 TCP/2380

Master 安全组

  • 来自 0.0.0.0/0 的 tcp/8443
  • 从所有安装的环境到 3.2 的 OpenShift Container Platform 主机中的 TCP/53
  • 来自安装环境的所有 OpenShift Container Platform 主机到 3.2 的 UDP/53
  • 对于使用 3.2 安装的新环境,来自所有 OpenShift Container Platform 主机中的 TCP/8053
  • 对于使用 3.2 安装的新环境,所有 OpenShift Container Platform 主机中的 UDP/8053

节点安全组

  • 来自 master 的 TCP/10250
  • 来自节点的 UDP/4789

基础架构节点(一个可以托管 OpenShift Container Platform 路由器)

  • 来自 0.0.0.0/0 的 tcp/443
  • 来自 0.0.0.0/0 的 tcp/80

CRI-O

如果使用 CRIO,则必须打开 tcp/10010 以允许 oc execoc rsh 操作。

如果为 master 和/或路由器配置外部负载均衡器(ELB),您还需要为 ELB 相应地配置入口和 Egress 安全组。

20.2.1. 覆盖检测到的 IP 地址和主机名

在 AWS 中,需要覆盖变量的情况包括:

Expand
变量使用方法

hostname

用户安装在 VPC 中,它没有为 DNS 主机名DNS 解析进行配置。

ip

您已经配置了多个网络接口,并希望使用除默认接口以外的其他网络接口。

public_hostname

  • 一个 master 实例,其中没有为 Auto-assign Public IP 配置 VPC 子网。对于此 master 的外部访问权限,您需要配置一个 ELB 或其他负载均衡器来提供所需的外部访问,或者您需要通过 VPN 连接主机的内部名称进行连接。
  • 禁用元数据的 master 实例。
  • 这个值实际上没有被节点使用。

public_ip

  • 一个 master 实例,其中没有为 Auto-assign Public IP 配置 VPC 子网。
  • 禁用元数据的 master 实例。
  • 这个值实际上没有被节点使用。

对于 EC2 主机,必须部署到启用了 DNS 主机名和 DNS 解析的 VPC 中。

Amazon Web Services (AWS) 提供对象存储,OpenShift Container Platform 可以使用它们使用 OpenShift Container Platform 容器 registry 存储容器镜像。

如需更多信息,请参阅 Amazon S3

先决条件

OpenShift Container Platform 使用 S3 作为镜像存储。应创建 S3 存储桶、IAM 策略和带有 Programmatic Access 的 IAM 用户,以允许安装程序配置 registry。

以下示例使用 awscli 在 us-east-1 区域中创建一个名为 openshift-registry-storage 的存储桶。

# aws s3api create-bucket \
     --bucket openshift-registry-storage \
     --region us-east-1
Copy to Clipboard Toggle word wrap

默认策略

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:ListBucket",
        "s3:GetBucketLocation",
        "s3:ListBucketMultipartUploads"
      ],
      "Resource": "arn:aws:s3:::S3_BUCKET_NAME"
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:GetObject",
        "s3:DeleteObject",
        "s3:ListMultipartUploadParts",
        "s3:AbortMultipartUpload"
      ],
      "Resource": "arn:aws:s3:::S3_BUCKET_NAME/*"
    }
  ]
}
Copy to Clipboard Toggle word wrap

流程

将 registry 的 Ansible 清单配置为使用 S3 存储桶和 IAM 用户:

[OSEv3:vars]
# AWS Registry Configuration
openshift_hosted_manage_registry=true
openshift_hosted_registry_storage_kind=object
openshift_hosted_registry_storage_provider=s3
openshift_hosted_registry_storage_s3_accesskey=AKIAJ6VLREDHATSPBUA 
1

openshift_hosted_registry_storage_s3_secretkey=g/8PmTYDQVGssFWWFvfawHpDbZyGkjGNZhbWQpjH 
2

openshift_hosted_registry_storage_s3_bucket=openshift-registry-storage 
3

openshift_hosted_registry_storage_s3_region=us-east-1 
4

openshift_hosted_registry_storage_s3_chunksize=26214400
openshift_hosted_registry_storage_s3_rootdirectory=/registry
openshift_hosted_registry_storage_s3_encrypt=false
openshift_hosted_registry_storage_s3_kmskeyid=aws_kms_key_id 
5

openshift_hosted_registry_pullthrough=true
openshift_hosted_registry_acceptschema2=true
openshift_hosted_registry_enforcequota=true
openshift_hosted_registry_replicas=3
Copy to Clipboard Toggle word wrap
1 1
IAM 用户的访问密钥。(当前不需要 IAM 角色)
2
IAM 用户的 secret 密钥。(当前不需要 IAM 角色)
3
S3 存储桶名称。
4
bucket 所在的区域。
5
用于加密集群中数据的加密密钥的 AWS Key Management Service(AWS KMS)密钥 ID。

要使用 Amazon Web Services(AWS)S3 对象存储,请编辑 registry 的配置文件并挂载到 registry pod。

流程

  1. 导出当前的 config.yml

    $ oc get secret registry-config \
        -o jsonpath='{.data.config\.yml}' -n default | base64 -d \
      >> config.yml.old
    Copy to Clipboard Toggle word wrap
  2. 从旧 config.yml 创建新配置文件:

    $ cp config.yml.old config.yml
    Copy to Clipboard Toggle word wrap
  3. 编辑该文件,使其包含 S3 参数。在 registry 配置文件的 storage 部分指定 accountname、accountkey、container 和 realm。

    storage:
      delete:
        enabled: true
      cache:
        blobdescriptor: inmemory
      s3:
        accesskey: AKIAJ6VLREDHATSPBUA 
    1
    
        secretkey: g/8PmTYDQVGssFWWFvfawHpDbZyGkjGNZhbWQpjH 
    2
    
        region: us-east-1 
    3
    
        bucket: openshift-registry-storage 
    4
    
        encrypt: False
        secure: true
        v4auth: true
        rootdirectory: /registry 
    5
    
        chunksize: "26214400"
    Copy to Clipboard Toggle word wrap
    1
    使用有权访问 S3 存储桶的 AWS 访问密钥替换。
    2
    与定义的 AWS 访问密钥对应的 secret 键。
    3
    用作 registry 的 S3 存储桶的名称。
    4
    registry 将存储镜像和元数据的位置。(默认为 /registry)
  4. 删除 registry-config secret:

    $ oc delete secret registry-config -n default
    Copy to Clipboard Toggle word wrap
  5. 重新创建 secret 来引用更新的配置文件:

    $ oc create secret generic registry-config \
        --from-file=config.yml -n default
    Copy to Clipboard Toggle word wrap
  6. 重新部署 registry 以读取更新的配置:

    $ oc rollout latest docker-registry -n default
    Copy to Clipboard Toggle word wrap
20.2.1.1.3. 验证 registry 是否使用 S3 存储

验证 registry 是否使用 Amazon S3 存储:

流程

  1. 在成功部署 registry 后,registry deploymentconfig 会将 registry-storage 描述为 emptydir 而不是 AWS S3,但 AWS S3 存储桶的配置位于 secret docker-config 中。docker-config 机密挂载到 REGISTRY_CONFIGURATION_PATH,后者在将 AWS S3 用于注册表对象存储时提供所有 paramaters。

    $ oc describe dc docker-registry -n default
    ...
        Environment:
          REGISTRY_HTTP_ADDR:					:5000
          REGISTRY_HTTP_NET:					tcp
          REGISTRY_HTTP_SECRET:					SPLR83SDsPaGbGuwSMDfnDwrDRvGf6YXl4h9JQrToQU=
          REGISTRY_MIDDLEWARE_REPOSITORY_OPENSHIFT_ENFORCEQUOTA:	false
          REGISTRY_HTTP_TLS_KEY:					/etc/secrets/registry.key
          OPENSHIFT_DEFAULT_REGISTRY:				docker-registry.default.svc:5000
          REGISTRY_CONFIGURATION_PATH:				/etc/registry/config.yml
          REGISTRY_OPENSHIFT_SERVER_ADDR:				docker-registry.default.svc:5000
          REGISTRY_HTTP_TLS_CERTIFICATE:				/etc/secrets/registry.crt
        Mounts:
          /etc/registry from docker-config (rw)
          /etc/secrets from registry-certificates (rw)
          /registry from registry-storage (rw)
      Volumes:
       registry-storage:
        Type:	EmptyDir (a temporary directory that shares a pod's lifetime) 
    1
    
        Medium:
       registry-certificates:
        Type:	Secret (a volume populated by a Secret)
        SecretName:	registry-certificates
        Optional:	false
       docker-config:
        Type:	Secret (a volume populated by a Secret)
        SecretName:	registry-config
        Optional:	false
    ....
    Copy to Clipboard Toggle word wrap
    1
    共享 pod 生命周期的临时目录。
  2. 确定 /registry 挂载点为空:

    $ oc exec \
        $(oc get pod -l deploymentconfig=docker-registry \
        -o=jsonpath='{.items[0].metadata.name}')  -i -t -- ls -l /registry
    total 0
    Copy to Clipboard Toggle word wrap

    如果为空,则代表 S3 配置在 registry-config secret 中定义:

    $ oc describe secret registry-config
    Name:         registry-config
    Namespace:    default
    Labels:       <none>
    Annotations:  <none>
    
    Type:  Opaque
    
    Data
    ====
    config.yml:  398 bytes
    Copy to Clipboard Toggle word wrap
  3. 安装程序会使用扩展的 registry 功能创建带有所需配置的 config.yml 文件,如安装文档所述。要查看配置文件,包括存储存储桶配置的 storage 部分:

    $ oc exec \
        $(oc get pod -l deploymentconfig=docker-registry \
          -o=jsonpath='{.items[0].metadata.name}') \
      cat /etc/registry/config.yml
    
      version: 0.1
      log:
        level: debug
      http:
        addr: :5000
      storage:
        delete:
          enabled: true
        cache:
          blobdescriptor: inmemory
        s3:
          accesskey: AKIAJ6VLREDHATSPBUA
          secretkey: g/8PmTYDQVGssFWWFvfawHpDbZyGkjGNZhbWQpjH
          region: us-east-1
          bucket: openshift-registry-storage
          encrypt: False
          secure: true
          v4auth: true
          rootdirectory: /registry
          chunksize: "26214400"
      auth:
        openshift:
          realm: openshift
      middleware:
        registry:
        - name: openshift
        repository:
        - name: openshift
          options:
            pullthrough: true
            acceptschema2: true
            enforcequota: true
        storage:
        - name: openshift
    Copy to Clipboard Toggle word wrap

    另外,您可以查看 secret:

    $ oc get secret registry-config -o jsonpath='{.data.config\.yml}' | base64 -d
    version: 0.1
    log:
      level: debug
    http:
      addr: :5000
      storage:
        delete:
          enabled: true
        cache:
          blobdescriptor: inmemory
        s3:
          accesskey: AKIAJ6VLREDHATSPBUA
          secretkey: g/8PmTYDQVGssFWWFvfawHpDbZyGkjGNZhbWQpjH
          region: us-east-1
          bucket: openshift-registry-storage
          encrypt: False
          secure: true
          v4auth: true
          rootdirectory: /registry
          chunksize: "26214400"
    auth:
      openshift:
        realm: openshift
    middleware:
      registry:
      - name: openshift
      repository:
      - name: openshift
      options:
        pullthrough: true
        acceptschema2: true
        enforcequota: true
      storage:
      - name: openshift
    Copy to Clipboard Toggle word wrap

如果使用 emptyDir 卷,/registry 挂载点类似如下:

$ oc exec \
    $(oc get pod -l deploymentconfig=docker-registry \
    -o=jsonpath='{.items[0].metadata.name}')  -i -t -- df -h /registry
Filesystem      Size  Used Avail Use% Mounted on
/dev/sdc         100G  226M   30G   1% /registry


$ oc exec \
    $(oc get pod -l deploymentconfig=docker-registry \
    -o=jsonpath='{.items[0].metadata.name}')  -i -t -- ls -l /registry
total 0
drwxr-sr-x. 3 1000000000 1000000000 22 Jun 19 12:24 docker
Copy to Clipboard Toggle word wrap

20.3. 配置 AWS 变量

要设置所需的 AWS 变量,请在所有 OpenShift Container Platform 主机上(master 和 节点)创建一个 /etc/origin/cloudprovider/aws.conf 文件:

[Global]
Zone = us-east-1c 
1
Copy to Clipboard Toggle word wrap
1
这是 AWS 实例的 Availability Zone,且您的 EBS 卷所在的位置 ; 这些信息可从 AWS 管理控制台获取。

20.4. 为 AWS 配置 OpenShift Container Platform

您可以通过两种方式在 OpenShift Container Platform 上设置 AWS 配置:

在集群安装过程中,可以使用 openshift_cloudprovider_aws_access_key, openshift_cloudprovider_aws_secret_key, openshift_cloudprovider_kind, openshift_clusterid 参数配置 AWS,这些参数可以在 inventory 文件 中进行配置。

使用 Ansible 的 AWS 配置示例

# Cloud Provider Configuration
#
# Note: You may make use of environment variables rather than store
# sensitive configuration within the ansible inventory.
# For example:
#openshift_cloudprovider_aws_access_key="{{ lookup('env','AWS_ACCESS_KEY_ID') }}"
#openshift_cloudprovider_aws_secret_key="{{ lookup('env','AWS_SECRET_ACCESS_KEY') }}"
#
#openshift_clusterid=unique_identifier_per_availablility_zone
#
# AWS (Using API Credentials)
#openshift_cloudprovider_kind=aws
#openshift_cloudprovider_aws_access_key=aws_access_key_id
#openshift_cloudprovider_aws_secret_key=aws_secret_access_key
#
# AWS (Using IAM Profiles)
#openshift_cloudprovider_kind=aws
# Note: IAM roles must exist before launching the instances.
Copy to Clipboard Toggle word wrap

注意

当 Ansible 配置 AWS 时,它会自动对以下文件进行必要的更改:

  • /etc/origin/cloudprovider/aws.conf
  • /etc/origin/master/master-config.yaml
  • /etc/origin/node/node-config.yaml

在所有 master 上编辑 或创建 master 配置文件(默认为/etc/origin/master/master-config.yaml )并更新 apiServerArgumentscontrollerArguments 部分的内容:

kubernetesMasterConfig:
  ...
  apiServerArguments:
    cloud-provider:
      - "aws"
    cloud-config:
      - "/etc/origin/cloudprovider/aws.conf"
  controllerArguments:
    cloud-provider:
      - "aws"
    cloud-config:
      - "/etc/origin/cloudprovider/aws.conf"
Copy to Clipboard Toggle word wrap

目前,nodeName 必须与 AWS 中的实例名称匹配,以便云供应商集成正常工作。名称也必须与 RFC1123 兼容。

重要

在触发容器化安装时,只有 /etc/origin/var/lib/origin 的目录被挂载到 master 和节点容器。因此,aws.conf 应该位于 /etc/origin/ 而不是 /etc/ 中。

编辑 适当的节点配置映射 并更新 kubeletArguments 部分的内容:

kubeletArguments:
  cloud-provider:
    - "aws"
  cloud-config:
    - "/etc/origin/cloudprovider/aws.conf"
Copy to Clipboard Toggle word wrap
重要

在触发容器化安装时,只有 /etc/origin/var/lib/origin 的目录被挂载到 master 和节点容器。因此,aws.conf 应该位于 /etc/origin/ 而不是 /etc/ 中。

20.4.4. 手动设置键-值访问对

确保在 master 上的 /etc/origin/master/master.env 文件中设置以下环境变量,以及节点上的 /etc/sysconfig/atomic-openshift-node 文件中:

AWS_ACCESS_KEY_ID=<key_ID>
AWS_SECRET_ACCESS_KEY=<secret_key>
Copy to Clipboard Toggle word wrap
注意

在设置 AWS IAM 用户时获取访问密钥。

20.5. 应用配置更改

在所有 master 和节点主机上启动或重启 OpenShift Container Platform 服务以应用您的配置更改,请参阅重启 OpenShift Container Platform 服务

# master-restart api
# master-restart controllers
# systemctl restart atomic-openshift-node
Copy to Clipboard Toggle word wrap
注意

Kubernetes 架构需要来自云提供商的可靠端点。当云提供商停机时,kubelet 会防止 OpenShift Container Platform 重启。如果底层云供应商端点不可靠,请不要安装使用云供应商集成的集群。如在裸机环境中一样安装集群。不建议在已安装的集群中打开或关闭云提供商集成。但是,如果该情境不可避免,请完成以下过程。

从不使用云供应商切换到使用云提供商会产生错误消息。添加云供应商会尝试删除节点,因为从其切换的节点使用 hostname 作为 externalID (当没有云供应商使用时)使用云供应商的 instance-id (由云提供商指定)。要解决这个问题:

  1. 以集群管理员身份登录到 CLI。
  2. 检查和备份现有节点标签:

    $ oc describe node <node_name> | grep -Poz '(?s)Labels.*\n.*(?=Taints)'
    Copy to Clipboard Toggle word wrap
  3. 删除节点:

    $ oc delete node <node_name>
    Copy to Clipboard Toggle word wrap
  4. 在每个节点主机上,重启 OpenShift Container Platform 服务。

    # systemctl restart atomic-openshift-node
    Copy to Clipboard Toggle word wrap
  5. 在每个主机上重新添加回您以前具有的标记

20.6. 为 AWS 标记集群

如果配置 AWS 供应商凭证,还必须确保所有主机都被标记为。

要正确识别与集群关联的资源,请使用键 kubernetes.io/cluster/<clusterid> 标签资源,其中:

  • <clusterid > 是集群的唯一名称。

如果节点专门用于集群,将相关值设为 owned;如果资源与其他系统共享,将相关值设置为 shared

使用 kubernetes.io/cluster/<clusterid>,Value=(owned|shared) 标签标记所有资源,可以避免多个区或多个集群中的潜在问题。

请参阅 Pod 和服务,了解更多有关在 OpenShift Container Platform 中标记和标记的信息。

20.6.1. 需要标签的资源

需要标记四种资源:

  • 实例
  • 安全组
  • Load Balancers
  • EBS 卷

20.6.2. 标记现有集群

集群使用 kubernetes.io/cluster/<clusterid>,Value=(owned|shared) 标签的值来决定 AWS 集群的资源。这意味着所有相关资源必须使用与键相同的值的 kubernetes.io/cluster/<clusterid>,Value=(owned|shared) 标签进行标记。这些资源包括:

  • 所有主机。
  • 要在 AWS 实例中使用的所有相关负载均衡器。
  • 所有 EBS 卷。需要标记的 EBS 卷可使用以下地址找到:

    $ oc get pv -o json|jq '.items[].spec.awsElasticBlockStore.volumeID'
    Copy to Clipboard Toggle word wrap
  • 与 AWS 实例一起使用的所有相关安全组。

    注意

    不要使用 kubernetes.io/cluster/<name>,Value=<clusterid> 标签标记所有现有的安全组,否则 Elastic Load Balancing(ELB)将无法创建负载均衡器。

在标记任何资源后,重启 master 上的 master 服务,并在所有节点上重启节点服务。请参阅 应用配置部分

20.6.3. 关于 Red Hat OpenShift Container Storage

Red Hat OpenShift Container Storage(RHOCS)是 OpenShift Container Platform 内部或混合云中与无关的持久性存储供应商。作为红帽存储解决方案,RHOCS 与 OpenShift Container Platform 完全集成,用于部署、管理和监控,无论它是否安装在 OpenShift Container Platform(融合)或与 OpenShift Container Platform(独立)。OpenShift Container Storage 不仅限于单个可用区或节点,这使得它可能会停机。您可以在 RHOCS 3.11 部署指南中找到使用 RHOCS 的完整说明。

第 21 章 为 Red Hat Virtualization 配置

您可以通过创建一个堡垒虚拟机并使用它来安装 OpenShift Container Platform,为 Red Hat Virtualization 配置 OpenShift Container Platform。

21.1. 创建堡垒(bastion)虚拟机

在 Red Hat Virtualization 中创建堡垒主机来安装 OpenShift Container Platform。

流程

  1. 使用 SSH 登录到 Manager 机器。
  2. 为安装文件创建一个临时 bastion 安装目录,如 /bastion_installation
  3. 使用 ansible-vault 创建加密的 /bastion_installation/secure_vars.yaml 文件并记录密码:

    # ansible-vault create secure_vars.yaml
    Copy to Clipboard Toggle word wrap
  4. secure_vars.yaml 文件中添加以下参数值:

    engine_password: <Manager_password> 
    1
    
    bastion_root_password: <bastion_root_password> 
    2
    
    rhsub_user: <Red_Hat_Subscription_Manager_username> 
    3
    
    rhsub_pass: <Red_Hat_Subscription_Manager_password>
    rhsub_pool: <Red_Hat_Subscription_Manager_pool_id> 
    4
    
    root_password: <OpenShift_node_root_password> 
    5
    
    engine_cafile: <RHVM_CA_certificate> 
    6
    
    oreg_auth_user: <image_registry_authentication_username> 
    7
    
    oreg_auth_password: <image_registry_authentication_password>
    Copy to Clipboard Toggle word wrap
    1
    登录管理门户的密码。
    2
    堡垒虚拟机的 root 密码。
    3
    Red Hat Subscription Manager 凭证。
    4
    Red Hat Virtualization Manager 订阅池的池 ID。
    5
    OpenShift Container Platform root 密码。
    6
    Red Hat Virtualization Manager CA 证书。如果您不从 Manager 机器运行 playbook,则需要 engine_cafile 值。Manager CA 证书的默认位置为 /etc/pki/ovirt-engine/ca.pem
    7
    如果您使用需要身份验证的镜像 registry,请添加凭证。
  5. 保存该文件。
  6. 获取 Red Hat Enterprise Linux KVM 客户机镜像 下载链接:

    1. 访问 Red Hat Customer Portal:下载 Red Hat Enterprise Linux
    2. 产品软件 选项卡中,找到 Red Hat Enterprise Linux KVM 客户机镜像
    3. 右键单击 Download Now,复制 链接并保存。

      该链接对时间敏感,且必须先复制,然后才能创建 bastion 虚拟机。

  7. 使用以下内容创建 /bastion_installation/create-bastion-machine-playbook.yaml 文件并更新其参数值:

    ---
    - name: Create a bastion machine
      hosts: localhost
      connection: local
      gather_facts: false
      no_log: true
    
      roles:
        - oVirt.image-template
        - oVirt.vm-infra
      no_log: true
    
      vars:
        engine_url: https://_Manager_FQDN_/ovirt-engine/api 
    1
    
        engine_user: <admin@internal>
        engine_password: "{{ engine_password }}"
        engine_cafile: /etc/pki/ovirt-engine/ca.pem
    
        qcow_url: <RHEL_KVM_guest_image_download_link> 
    2
    
        template_cluster: Default
        template_name: rhelguest7
        template_memory: 4GiB
        template_cpu: 2
        wait_for_ip: true
        debug_vm_create: false
    
        vms:
        - name: rhel-bastion
          cluster: "{{ template_cluster }}"
          profile:
            cores: 2
            template: "{{ template_name }}"
            root_password: "{{ root_password }}"
            ssh_key: "{{ lookup('file', '/root/.ssh/id_rsa_ssh_ocp_admin.pub') }}"
            state: running
          cloud_init:
            custom_script: |
              rh_subscription:
                username: "{{ rhsub_user }}"
                password: "{{ rhsub_pass }}"
                auto-attach: true
                disable-repo: ['*']
                # 'rhel-7-server-rhv-4.2-manager-rpms' supports RHV 4.2 and 4.3
                enable-repo: ['rhel-7-server-rpms', 'rhel-7-server-extras-rpms', 'rhel-7-server-ansible-2.7-rpms', 'rhel-7-server-ose-3.11-rpms', 'rhel-7-server-supplementary-rpms', 'rhel-7-server-rhv-4.2-manager-rpms']
              packages:
                - ansible
                - ovirt-ansible-roles
                - openshift-ansible
                - python-ovirt-engine-sdk4
      pre_tasks:
        - name: Create an ssh key-pair for OpenShift admin
          user:
            name: root
            generate_ssh_key: yes
            ssh_key_file: .ssh/id_rsa_ssh_ocp_admin
    
      roles:
        - oVirt.image-template
        - oVirt.vm-infra
    
    - name: post installation tasks on the bastion machine
      hosts: rhel-bastion
      tasks:
        - name: create ovirt-engine PKI dir
          file:
            state: directory
            dest: /etc/pki/ovirt-engine/
        - name: Copy the engine ca cert to the bastion machine
          copy:
            src: "{{ engine_cafile }}"
            dest: "{{ engine_cafile }}"
        - name: Copy the secured vars to the bastion machine
          copy:
            src: secure_vars.yaml
            dest: secure_vars.yaml
            decrypt: false
        - file:
            state: directory
            path: /root/.ssh
        - name: copy the OpenShift_admin keypair to the bastion machine
          copy:
            src: "{{ item }}"
            dest: "{{ item }}"
            mode: 0600
          with_items:
            - /root/.ssh/id_rsa_ssh_ocp_admin
            - /root/.ssh/id_rsa_ssh_ocp_admin.pub
    Copy to Clipboard Toggle word wrap
    1
    Manager 机器的 FQDN。
    2
    <qcow_url>Red Hat Enterprise Linux KVM 客户机镜像的下载链接。Red Hat Enterprise Linux KVM 客户机镜像 包含 cloud-init 软件包,此 playbook 需要该软件包。如果没有使用 Red Hat Enterprise Linux,请下载 cloud-init 软件包,并在运行此 playbook 前手动安装它。
  8. 创建堡垒虚拟机:

    # ansible-playbook -i localhost create-bastion-machine-playbook.yaml -e @secure_vars.yaml --ask-vault-pass
    Copy to Clipboard Toggle word wrap
  9. 登录管理门户。
  10. 点击 ComputeVirtual Machines 来验证 rhel-bastion 虚拟机是否已成功创建。

使用 Red Hat Virtualization 中的 bastion 虚拟机安装 OpenShift Container Platform。

流程

  1. 登录 rhel-bastion
  2. 创建一个包含以下内容的 install_ocp.yaml 文件:

    ---
    - name: Openshift on RHV
      hosts: localhost
      connection: local
      gather_facts: false
    
      vars_files:
        - vars.yaml
        - secure_vars.yaml
    
      pre_tasks:
        - ovirt_auth:
            url:      "{{ engine_url }}"
            username: "{{ engine_user }}"
            password: "{{ engine_password }}"
            insecure: "{{ engine_insecure }}"
            ca_file:  "{{ engine_cafile | default(omit) }}"
    
      roles:
        - role: openshift_ovirt
    
    - import_playbook: setup_dns.yaml
    - import_playbook: /usr/share/ansible/openshift-ansible/playbooks/prerequisites.yml
    - import_playbook: /usr/share/ansible/openshift-ansible/playbooks/openshift-node/network_manager.yml
    - import_playbook: /usr/share/ansible/openshift-ansible/playbooks/deploy_cluster.yml
    Copy to Clipboard Toggle word wrap
  3. 创建一个包含以下内容的 setup_dns.yaml 文件:

    - hosts: masters
      strategy: free
      tasks:
        - shell: "echo {{ ansible_default_ipv4.address }} {{ inventory_hostname }} etcd.{{ inventory_hostname.split('.', 1)[1] }} openshift-master.{{ inventory_hostname.split('.', 1)[1] }} openshift-public-master.{{ inventory_hostname.split('.', 1)[1] }} docker-registry-default.apps.{{ inventory_hostname.split('.', 1)[1] }} webconsole.openshift-web-console.svc registry-console-default.apps.{{ inventory_hostname.split('.', 1)[1] }} >> /etc/hosts"
          when: openshift_ovirt_all_in_one is defined | ternary((openshift_ovirt_all_in_one | bool), false)
    Copy to Clipboard Toggle word wrap
  4. 创建一个包含以下内容的 /etc/ansible/openshift_3_11.hosts Ansible 清单文件:

    [workstation]
    localhost ansible_connection=local
    
    [all:vars]
    openshift_ovirt_dns_zone="{{ public_hosted_zone }}"
    openshift_web_console_install=true
    openshift_master_overwrite_named_certificates=true
    openshift_master_cluster_hostname="openshift-master.{{ public_hosted_zone }}"
    openshift_master_cluster_public_hostname="openshift-public-master.{{ public_hosted_zone }}"
    openshift_master_default_subdomain="{{ public_hosted_zone }}"
    openshift_public_hostname="{{openshift_master_cluster_public_hostname}}"
    openshift_deployment_type=openshift-enterprise
    openshift_service_catalog_image_version="{{ openshift_image_tag }}"
    
    [OSEv3:vars]
    # General variables
    debug_level=1
    containerized=false
    ansible_ssh_user=root
    os_firewall_use_firewalld=true
    openshift_enable_excluders=false
    openshift_install_examples=false
    openshift_clock_enabled=true
    openshift_debug_level="{{ debug_level }}"
    openshift_node_debug_level="{{ node_debug_level | default(debug_level,true) }}"
    osn_storage_plugin_deps=[]
    openshift_master_bootstrap_auto_approve=true
    openshift_master_bootstrap_auto_approver_node_selector={"node-role.kubernetes.io/master":"true"}
    osm_controller_args={"experimental-cluster-signing-duration": ["20m"]}
    osm_default_node_selector="node-role.kubernetes.io/compute=true"
    openshift_enable_service_catalog=false
    
    # Docker
    container_runtime_docker_storage_type=overlay2
    openshift_docker_use_system_container=false
    
    [OSEv3:children]
    nodes
    masters
    etcd
    lb
    
    [masters]
    [nodes]
    [etcd]
    [lb]
    Copy to Clipboard Toggle word wrap
  5. 获取 Red Hat Enterprise Linux KVM 客户机镜像 下载链接:

    1. 访问 Red Hat Customer Portal:下载 Red Hat Enterprise Linux
    2. 产品软件 选项卡中,找到 Red Hat Enterprise Linux KVM 客户机镜像
    3. 右键单击 Download Now,复制 链接并保存。

      不要使用您在创建堡垒虚拟机时复制的链接。下载链接区分大小写,且必须先复制后才能运行安装 playbook。

  6. 使用以下内容创建 vars.yaml 文件并更新其参数值:

    ---
    # For detailed documentation of variables, see
    # openshift_ovirt: https://github.com/openshift/openshift-ansible/tree/master/roles/openshift_ovirt#role-variables
    # openshift installation: https://github.com/openshift/openshift-ansible/tree/master/inventory
    engine_url: https://<Manager_FQDN>/ovirt-engine/api 
    1
    
    engine_user: admin@internal
    engine_password: "{{ engine_password }}"
    engine_insecure: false
    engine_cafile: /etc/pki/ovirt-engine/ca.pem
    
    openshift_ovirt_vm_manifest:
      - name: 'master'
        count: 1
        profile: 'master_vm'
      - name: 'compute'
        count: 0
        profile: 'node_vm'
      - name: 'lb'
        count: 0
        profile: 'node_vm'
      - name: 'etcd'
        count: 0
        profile: 'node_vm'
      - name: infra
        count: 0
        profile: node_vm
    
    # Currently, only all-in-one installation (`openshift_ovirt_all_in_one: true`) is supported.
    # Multi-node installation (master and node VMs installed separately) will be supported in a future release.
    openshift_ovirt_all_in_one: true
    openshift_ovirt_cluster: Default
    openshift_ovirt_data_store: data
    openshift_ovirt_ssh_key: "{{ lookup('file', '/root/.ssh/id_rsa_ssh_ocp_admin.pub') }}"
    
    public_hosted_zone:
    # Uncomment to disable install-time checks, for smaller scale installations
    #openshift_disable_check: memory_availability,disk_availability,docker_image_availability
    
    qcow_url: <RHEL_KVM_guest_image_download_link> 
    2
    
    image_path: /var/tmp
    template_name: rhelguest7
    template_cluster: "{{ openshift_ovirt_cluster }}"
    template_memory: 4GiB
    template_cpu: 1
    template_disk_storage: "{{ openshift_ovirt_data_store }}"
    template_disk_size: 100GiB
    template_nics:
      - name: nic1
        profile_name: ovirtmgmt
        interface: virtio
    
    debug_vm_create: false
    wait_for_ip: true
    vm_infra_wait_for_ip_retries: 30
    vm_infra_wait_for_ip_delay: 20
    
    node_item: &node_item
      cluster: "{{ openshift_ovirt_cluster }}"
      template: "{{ template_name }}"
      memory: "8GiB"
      cores: "2"
      high_availability: true
      disks:
        - name: docker
          size: 15GiB
          interface: virtio
          storage_domain: "{{ openshift_ovirt_data_store }}"
        - name: openshift
          size: 30GiB
          interface: virtio
          storage_domain: "{{ openshift_ovirt_data_store }}"
      state: running
      cloud_init:
        root_password: "{{ root_password }}"
        authorized_ssh_keys: "{{ openshift_ovirt_ssh_key }}"
        custom_script: "{{ cloud_init_script_node | to_nice_yaml }}"
    
    openshift_ovirt_vm_profile:
      master_vm:
        <<: *node_item
        memory: 16GiB
        cores: "{{ vm_cores | default(4) }}"
        disks:
          - name: docker
            size: 15GiB
            interface: virtio
            storage_domain: "{{ openshift_ovirt_data_store }}"
          - name: openshift_local
            size: 30GiB
            interface: virtio
            storage_domain: "{{ openshift_ovirt_data_store }}"
          - name: etcd
            size: 25GiB
            interface: virtio
            storage_domain: "{{ openshift_ovirt_data_store }}"
        cloud_init:
          root_password: "{{ root_password }}"
          authorized_ssh_keys: "{{ openshift_ovirt_ssh_key }}"
          custom_script: "{{ cloud_init_script_master | to_nice_yaml }}"
      node_vm:
        <<: *node_item
      etcd_vm:
        <<: *node_item
      lb_vm:
        <<: *node_item
    
    cloud_init_script_node: &cloud_init_script_node
      packages:
        - ovirt-guest-agent
      runcmd:
        - sed -i 's/# ignored_nics =.*/ignored_nics = docker0 tun0 /' /etc/ovirt-guest-agent.conf
        - systemctl enable ovirt-guest-agent
        - systemctl start ovirt-guest-agent
        - mkdir -p /var/lib/docker
        - mkdir -p /var/lib/origin/openshift.local.volumes
        - /usr/sbin/mkfs.xfs -L dockerlv /dev/vdb
        - /usr/sbin/mkfs.xfs -L ocplv /dev/vdc
      mounts:
        - [ '/dev/vdb', '/var/lib/docker', 'xfs', 'defaults,gquota' ]
        - [ '/dev/vdc', '/var/lib/origin/openshift.local.volumes', 'xfs', 'defaults,gquota' ]
      power_state:
        mode: reboot
        message: cloud init finished - boot and install openshift
        condition: True
    cloud_init_script_master:
      <<: *cloud_init_script_node
      runcmd:
        - sed -i 's/# ignored_nics =.*/ignored_nics = docker0 tun0 /' /etc/ovirt-guest-agent.conf
        - systemctl enable ovirt-guest-agent
        - systemctl start ovirt-guest-agent
        - mkdir -p /var/lib/docker
        - mkdir -p /var/lib/origin/openshift.local.volumes
        - mkdir -p /var/lib/etcd
        - /usr/sbin/mkfs.xfs -L dockerlv /dev/vdb
        - /usr/sbin/mkfs.xfs -L ocplv /dev/vdc
        - /usr/sbin/mkfs.xfs -L etcdlv /dev/vdd
      mounts:
        - [ '/dev/vdb', '/var/lib/docker', 'xfs', 'defaults,gquota' ]
        - [ '/dev/vdc', '/var/lib/origin/openshift.local.volumes', 'xfs', 'defaults,gquota' ]
        - [ '/dev/vdd', '/var/lib/etcd', 'xfs', 'defaults,gquota' ]
    Copy to Clipboard Toggle word wrap
    1
    Manager 机器的 FQDN。
    2
    <qcow_url>Red Hat Enterprise Linux KVM 客户机镜像的下载链接。Red Hat Enterprise Linux KVM 客户机镜像 包含 cloud-init 软件包,此 playbook 需要该软件包。如果没有使用 Red Hat Enterprise Linux,请下载 cloud-init 软件包,并在运行此 playbook 前手动安装它。
  7. 安装 OpenShift Container Platform:

    # export ANSIBLE_ROLES_PATH="/usr/share/ansible/roles/:/usr/share/ansible/openshift-ansible/roles"
    # export ANSIBLE_JINJA2_EXTENSIONS="jinja2.ext.do"
    # ansible-playbook -i /etc/ansible/openshift_3_11.hosts install_ocp.yaml -e @vars.yaml -e @secure_vars.yaml --ask-vault-pass
    Copy to Clipboard Toggle word wrap
  8. 为每个基础架构实例创建路由器的 DNS 条目。
  9. 配置循环路由,以便路由器可以将流量传递到应用。
  10. 为 OpenShift Container Platform Web 控制台创建 DNS 条目。
  11. 指定负载均衡器节点的 IP 地址。

第 22 章 为 OpenStack 配置

22.1. 概述

OpenStack 上部署时,OpenShift Container Platform 可以配置为访问 OpenStack 基础架构,包括使用 OpenStack Cinder 卷作为应用程序数据的持久性存储

重要

OpenShift Container Platform 3.11 支持与 Red Hat OpenStack Platform 13 搭配使用。

最新的 OpenShift Container Platform 版本支持最新的 Red Hat OpenStack Platform 长生命版本和中间版本。OpenShift Container Platform 和 Red Hat OpenStack Platform 的发行周期不同,今后测试的版本会根据两个产品的发行日期的不同而有所不同。

22.2. 开始前

22.2.1. OpenShift Container Platform SDN

默认的 OpenShift Container Platform SDN 是 OpenShiftSDN。还有另一个选项: 使用 Kuryr SDN

22.2.2. Kuryr SDN

Kuryr 是一个 CNI 插件,它使用 Neutron 和 Octavia 为 pod 和服务提供网络。它主要针对在 OpenStack 虚拟机上运行的 OpenShift Container Platform 集群设计。Kuryr 通过将 OpenShift Container Platform pod 插入 OpenStack SDN 来提高网络性能。另外,它还提供 OpenShift Container Platform pod 和 OpenStack 虚拟实例间的互联性。

建议在封装的 OpenStack 租户网络上部署 OpenShift Container Platform 时使用 Kuryr,以避免出现重复封装,例如通过 OpenStack 网络运行封装的 OpenShift SDN。每当需要 VXLAN、GRE 或 GENEVE 时,都建议使用 Kuryr。

因此,在以下情况下使用 Kuryr 并不有意义:

  • 您可以使用提供商网络、租户 VLAN 或第三方商业 SDN,如 Cisco ACI 或 Juniper Contrail。
  • 部署将在几个虚拟机监控程序或 OpenShift Container Platform 虚拟机节点上使用多个服务。每个 OpenShift Container Platform 服务会在 OpenStack 中创建一个 Octavia Amphora 虚拟机,它托管所需的负载均衡器。

要启用 Kuryr SDN,您的环境必须满足以下要求:

  • 运行 OpenStack 13 或更高版本
  • overcloud 带有 Octavia
  • 启用 Neutron Trunk 端口扩展
  • 如果使用 ML2/OVS Neutron 驱动程序,则必须使用 OpenvSwitch 防火墙驱动程序,而不是 ovs-hybrid。
重要

要将 Kuryr 与 OpenStack 13.0.13 搭配使用,Kuryr 容器镜像必须是版本 3.11.306 或更高版本。

22.2.3. OpenShift Container Platform 先决条件

成功部署 OpenShift Container Platform 需要满足很多前提条件。其中包括一组基础架构和主机配置步骤,然后再使用 Ansible 进行 OpenShift Container Platform 的实际安装。在后续小节中,详细介绍了 OpenStack 环境中 OpenShift Container Platform 所需的前提条件和配置更改。

注意

本参考环境中的所有 OpenStack CLI 命令都使用 CLI openstack 命令从 director 节点的不同节点执行。在另一节点中执行命令,以避免与 Ansible 版本 2.6 及更高版本产生软件包冲突。务必在指定的软件仓库中安装以下软件包。

例如:

Set Up Repositories 启用 rhel-7-server-openstack-13-tools-rpms 和所需的 OpenShift Container Platform 存储库。

$ sudo subscription-manager repos \
--enable rhel-7-server-openstack-{rhosp_version}-tools-rpms \
--enable rhel-7-server-openstack-14-tools-rpms
$ sudo subscription-manager repo-override --repo=rhel-7-server-openstack-14-tools-rpms --add=includepkgs:"python2-openstacksdk.* python2-keystoneauth1.* python2-os-service-types.*"
$ sudo yum install -y python2-openstackclient python2-heatclient python2-octaviaclient ansible
Copy to Clipboard Toggle word wrap

验证软件包是否至少包含以下版本(使用 rpm -q <package_name>):

  • python2-openstackclient - 3.14.1.-1
  • python2-heatclient 1.14.0-1
  • python2-octaviaclient 1.4.0-1
  • python2-openstacksdk 0.17.2

Octavia 是一个支持的负载均衡器解决方案,建议与 OpenShift Container Platform 一起使用,以便对外部传入的流量进行负载平衡,并为应用程序提供 OpenShift Container Platform master 服务的单一视图。

要启用 Octavia,必须包含在安装 OpenStack overcloud 的过程中,如果 overcloud 已存在则需要升级 Octavia 服务。以下步骤提供启用 Octavia 的基本非自定义步骤,并适用于 overcloud 的干净安装或 overcloud 更新。

注意

以下步骤只包括在部署 OpenStack 时需要处理 Octavia 部分的信息。有关更多信息,请参阅安装 OpenStack 文档。请注意对于节点 registry 方法会有所不同。有关更多信息,请参阅 Registry 方法 文档。这个示例使用了本地 registry 方法。

如果使用本地 registry,请创建一个模板来将镜像上传到 registry。如下例所示。

(undercloud) $ openstack overcloud container image prepare \
-e /usr/share/openstack-tripleo-heat-templates/environments/services-docker/octavia.yaml \
--namespace=registry.access.redhat.com/rhosp13 \
--push-destination=<local-ip-from-undercloud.conf>:8787 \
--prefix=openstack- \
--tag-from-label {version}-{release} \
--output-env-file=/home/stack/templates/overcloud_images.yaml \
--output-images-file /home/stack/local_registry_images.yaml
Copy to Clipboard Toggle word wrap

验证创建的 local_registry_images.yaml 是否包含 Octavia 镜像。

本地 registry 文件中的 Octavia 镜像

...
- imagename: registry.access.redhat.com/rhosp13/openstack-octavia-api:13.0-43
  push_destination: <local-ip-from-undercloud.conf>:8787
- imagename: registry.access.redhat.com/rhosp13/openstack-octavia-health-manager:13.0-45
  push_destination: <local-ip-from-undercloud.conf>:8787
- imagename: registry.access.redhat.com/rhosp13/openstack-octavia-housekeeping:13.0-45
  push_destination: <local-ip-from-undercloud.conf>:8787
- imagename: registry.access.redhat.com/rhosp13/openstack-octavia-worker:13.0-44
  push_destination: <local-ip-from-undercloud.conf>:8787
Copy to Clipboard Toggle word wrap

注意

Octavia 容器的版本会根据安装的特定 Red Hat OpenStack Platform 版本而有所不同。

以下步骤从 registry.redhat.io 拉取容器镜像到 undercloud 节点。这个过程可能需要一些时间,具体要看网络和 undercloud 磁盘的速度。

(undercloud) $ sudo openstack overcloud container image upload \
  --config-file  /home/stack/local_registry_images.yaml \
  --verbose
Copy to Clipboard Toggle word wrap

当 Octavia Load Balancer 用于访问 OpenShift API 时,需要增加它们的监听程序默认超时时间。默认超时为 50 秒。通过将以下文件传递给 overcloud deploy 命令,将超时时间增加到 20 分钟:

(undercloud) $ cat octavia_timeouts.yaml
parameter_defaults:
  OctaviaTimeoutClientData: 1200000
  OctaviaTimeoutMemberData: 1200000
Copy to Clipboard Toggle word wrap
注意

在 Red Hat OpenStack Platform 14 起,不需要这样做。

使用 Octavia 安装或更新 overcloud 环境:

openstack overcloud deploy --templates \
.
.
.
  -e /usr/share/openstack-tripleo-heat-templates/environments/services-docker/octavia.yaml \
  -e octavia_timeouts.yaml
.
.
.
Copy to Clipboard Toggle word wrap
注意

以上命令只包含与 Octavia 相关的文件。此命令将根据您具体的 OpenStack 安装而有所不同。如需更多信息,请参阅官方 OpenStack 文档 。有关自定义 Octavia 安装的详情请参考 使用 Director 安装 Octavia

注意

如果使用 Kuryr SDN,overcloud 安装需要在 Neutron 中启用"中继"扩展。这在 Director 部署中默认启用。当 Neutron 后端是 ML2/OVS 时,使用 openvswitch 防火墙而不是默认的 ovs-hybrid。如果后端为 ML2/OVN,则不需要修改。

22.2.3.2. 创建 OpenStack 用户帐户、项目和角色

在安装 OpenShift Container Platform 之前,Red Hat OpenStack Platform (RHOSP) 环境需要一个项目(通常称为 租户 ),后者存储了要安装的 OpenShift Container Platform 的 OpenStack 实例。此项目要求用户的所有权,并且该用户的角色设置为 _member_

以下步骤演示了如何完成上述操作。

作为 OpenStack overcloud 管理员,

  1. 创建一个项目(租户),用于存储 RHOSP 实例

    $ openstack project create <project>
    Copy to Clipboard Toggle word wrap
  2. 创建拥有之前创建的项目的 RHOSP 用户:

    $ openstack user create --password <password> <username>
    Copy to Clipboard Toggle word wrap
  3. 设置用户的角色:

    $ openstack role add --user <username> --project <project> _member_
    Copy to Clipboard Toggle word wrap

分配给新的 RH OSP 项目的默认配额不足以用于 OpenShift Container Platform 安装。将配额增加到至少 30 个安全组、200 个安全组规则和 200 端口。

$ openstack quota set --secgroups 30 --secgroup-rules 200 --ports 200 <project>
1
Copy to Clipboard Toggle word wrap
1
对于 <project >,请指定要修改的项目名称
22.2.3.3. Kuryr SDN 的额外步骤

如果启用了 Kuryr SDN,特别是在使用命名空间隔离时,增加项目的配额以满足这些最低要求:

  • 300 个安全组 - 每个命名空间对应一个命名空间,每个负载均衡器都对应一个
  • 150 网络 - 每个命名空间有一个
  • 150 个子网 - 每个命名空间都有一个
  • 500 个安全组规则
  • 500 端口 - 每个 Pod 一个端口,以及池的额外端口用于加快 Pod 创建
注意

这不是全球推荐。调整您的配额以满足您的要求。

如果使用命名空间隔离,则每个命名空间都会获得一个新的网络和子网。另外,还会创建一个安全组来启用命名空间中的 Pod 间的流量。

$ openstack quota set --networks 150 --subnets 150 --secgroups 300 --secgroup-rules 500 --ports 500 <project>
1
Copy to Clipboard Toggle word wrap
1
对于 <project >,请指定要修改的项目名称

如果启用了命名空间隔离,您必须在创建项目后将项目 ID 添加到 octavia.conf 配置文件中。此步骤可确保所需的 LoadBalancer 安全组属于该项目,并可将其更新为在命名空间间强制实施服务隔离。

  1. 获取项目 ID

    $ openstack project show *<project>*
    +-------------+----------------------------------+
    | Field       | Value                            |
    +-------------+----------------------------------+
    | description |                                  |
    | domain_id   | default                          |
    | enabled     | True                             |
    | id          | PROJECT_ID                       |
    | is_domain   | False                            |
    | name        | *<project>*                      |
    | parent_id   | default                          |
    | tags        | []                               |
    +-------------+----------------------------------+
    Copy to Clipboard Toggle word wrap
  2. 将项目 ID 添加到控制器上的 [filename]octavia.conf 中,然后重新启动 octavia worker。

    $ source stackrc  # undercloud credentials
    $ openstack server list
    +--------------------------------------+--------------+--------+-----------------------+----------------+------------+
    │
    | ID                                   | Name         | Status | Networks
    | Image          | Flavor     |
    │
    +--------------------------------------+--------------+--------+-----------------------+----------------+------------+
    │
    | 6bef8e73-2ba5-4860-a0b1-3937f8ca7e01 | controller-0 | ACTIVE |
    ctlplane=192.168.24.8 | overcloud-full | controller |
    │
    | dda3173a-ab26-47f8-a2dc-8473b4a67ab9 | compute-0    | ACTIVE |
    ctlplane=192.168.24.6 | overcloud-full | compute    |
    │
    +--------------------------------------+--------------+--------+-----------------------+----------------+------------+
    
    $ ssh heat-admin@192.168.24.8  # ssh into the controller(s)
    
    controller-0$ vi /var/lib/config-data/puppet-generated/octavia/etc/octavia/octavia.conf
    [controller_worker]
    # List of project ids that are allowed to have Load balancer security groups
    # belonging to them.
    amp_secgroup_allowed_projects = PROJECT_ID
    
    controller-0$ sudo docker restart octavia_worker
    Copy to Clipboard Toggle word wrap
22.2.3.4. 配置 RC 文件

配置完项目后,OpenStack 管理员可以创建对实施 OpenShift Container Platform 环境的用户所需的信息的 RC 文件。

一个 RC 文件示例:

$ cat path/to/examplerc
# Clear any old environment that may conflict.
for key in $( set | awk '{FS="="}  /^OS_/ {print $1}' ); do unset $key ; done
export OS_PROJECT_DOMAIN_NAME=Default
export OS_USER_DOMAIN_NAME=Default
export OS_PROJECT_NAME=<project-name>
export OS_USERNAME=<username>
export OS_PASSWORD=<password>
export OS_AUTH_URL=http://<ip>:5000//v3
export OS_CLOUDNAME=<cloud-name>
export OS_IDENTITY_API_VERSION=3

# Add OS_CLOUDNAME to PS1
if [ -z "${CLOUDPROMPT_ENABLED:-}" ]; then
	export PS1=${PS1:-""}
	export PS1=\${OS_CLOUDNAME:+"(\$OS_CLOUDNAME)"}\ $PS1
	export CLOUDPROMPT_ENABLED=1
fi
Copy to Clipboard Toggle word wrap
注意

只要引用同一域,就支持从默认值更改 _OS_PROJECT_DOMAIN_NAME 和 _OS_USER_DOMAIN_NAME。

作为在 OpenStack director 节点或工作站中实施 OpenShift Container Platform 环境的用户,请确保如下所示 source 凭证:

$ source path/to/examplerc
Copy to Clipboard Toggle word wrap
22.2.3.5. 创建 OpenStack 类别

在 OpenStack 中,类别通过定义 nova 计算实例的计算、内存和存储容量来定义虚拟服务器的大小。由于此参考架构中的基础镜像是 Red Hat Enterprise Linux 7.5,因此使用以下规格创建 m1.nodem1.master 大小,如 表 22.1 “OpenShift 的最低系统要求” 所示。

重要

虽然最小系统要求足以运行集群,以提高性能,但建议在 master 节点上增加 vCPU。另外,如果 etcd 位于 master 节点上,则建议更多内存。

Expand
表 22.1. OpenShift 的最低系统要求
节点类型CPURAM根磁盘Flavor

Master

4

16 GB

45 GB

m1.master

节点

1

8 GB

20 GB

m1.node

作为 OpenStack 管理员,

$ openstack flavor create <flavor_name> \
    --id auto \
    --ram <ram_in_MB> \
    --disk <disk_in_GB> \
    --vcpus <num_vcpus>
Copy to Clipboard Toggle word wrap

以下示例演示了在本参考环境中创建类别。

$ openstack flavor create m1.master \
    --id auto \
    --ram 16384 \
    --disk 45 \
    --vcpus 4
$ openstack flavor create m1.node \
    --id auto \
    --ram 8192 \
    --disk 20 \
    --vcpus 1
Copy to Clipboard Toggle word wrap
注意

如果访问 OpenStack 管理员权限来创建新类别不可用,请在 OpenStack 环境中使用现有类别来满足 表 22.1 “OpenShift 的最低系统要求” 中的要求。

通过以下方法验证 OpenStack 类别:

$ openstack flavor list
Copy to Clipboard Toggle word wrap
22.2.3.6. 创建 OpenStack 密钥对

Red Hat OpenStack Platform 使用 cloud-initssh 公钥放在每个实例上,允许 ssh 访问该实例。Red Hat OpenStack Platform 期望用户存放私钥。

警告

丢失私钥将导致无法访问实例。

要生成密钥对,请使用以下命令:

$ openstack keypair create <keypair-name> > /path/to/<keypair-name>.pem
Copy to Clipboard Toggle word wrap

对密钥对创建进行验证可通过以下方法完成:

$ openstack keypair list
Copy to Clipboard Toggle word wrap

创建了密钥对后,将权限设置为 600,从而仅允许文件所有者来读取和写入该文件。

$ chmod 600 /path/to/<keypair-name>.pem
Copy to Clipboard Toggle word wrap
22.2.3.7. 为 OpenShift Container Platform 设置 DNS

DNS 服务是 OpenShift Container Platform 环境中的一个重要组件。无论 DNS 的供应商如何,机构都需要有特定记录才能为各种 OpenShift Container Platform 组件提供服务。

警告

使用 /etc/hosts 无效,必须存在正确的 DNS 服务。

通过使用 DNS 的关键 secret,您可以为 OpenShift Ansible 安装程序提供信息,它将自动为目标实例和各种 OpenShift Container Platform 组件添加记录。稍后将在配置 OpenShift Ansible 安装程序时描述此过程设置。

预期可以访问 DNS 服务器。您可以使用 Red Hat Labs DNS 帮助程序 获得访问权限的帮助。

应用程序 DNS

OpenShift 提供的应用可通过端口 80/TCP 和 443/TCP 上的路由器访问。路由器使用通配符记录将特定子域下的所有主机名映射到同一 IP 地址,而无需为每个名称单独记录。

这允许 OpenShift Container Platform 添加带有任意名称的应用程序,只要它们位于那个子域下。

例如,*. apps.example.com 的通配符记录会导致 DNS 名称查找 tax.apps.example.comhome-goods.apps.example.com,两者返回相同的 IP 地址:10.19.x.y.所有流量都转发到 OpenShift 路由器。路由器检查查询的 HTTP 标头并将其转发到正确的目的地。

使用负载均衡器(如 Octavia、主机地址 10.19.x.y)时,可以添加通配符 DNS 记录,如下所示:

Expand
表 22.2. 负载均衡器 DNS 记录
IP 地址Hostname用途

10.19.x.y

*.apps.example.com

对应用程序 Web 服务的用户访问

在 Red Hat OpenStack Platform 上部署 OpenShift Container Platform 时,该片段中描述的要求有两个网络是 public -public 和 内部网络

公共网络

公共网络 是包含外部访问的网络,可以被外部世界访问。公共网络创建只能由 OpenStack 管理员执行。

以下命令提供了为 公共网络 访问创建 OpenStack 提供商网络的示例。

作为 OpenStack 管理员(overcloudrc 访问),

$ source /path/to/examplerc

$ openstack network create <public-net-name> \
  --external \
  --provider-network-type flat \
  --provider-physical-network datacentre

$ openstack subnet create <public-subnet-name> \
  --network <public-net-name> \
  --dhcp \
  --allocation-pool start=<float_start_ip>,end=<float_end_ip> \
  --gateway <ip> \
  --subnet-range <CIDR>
Copy to Clipboard Toggle word wrap

创建网络和子网后,通过以下方法验证:

$ openstack network list
$ openstack subnet list
Copy to Clipboard Toggle word wrap
注意

<float_start_ip & gt; 和 <float_end_ip > 是提供给标记为 公共网络 的浮动 IP 池。无类别域间路由(CIDR)采用 <ip>/<routing_prefix> 格式,如 10.0.0.1/24。

内部网络

在网络设置过程中,内部网络通过路由器连接到公共网络。这样,每个附加到内部网络的 Red Hat OpenStack Platform 实例都可以从公共网络请求浮动 IP 进行公共访问。通过设置 openshift_openstack_private_network_name 来自动由 OpenShift Ansible 安装程序自动创建 内部网络。稍后介绍了有关 OpenShift Ansible 安装程序所需更改的更多信息。

22.2.3.9. 创建 OpenStack 部署主机安全组

OpenStack 网络允许用户定义入站和出站流量过滤器,可以应用到网络上的每个实例。这允许用户根据实例服务的功能限制每个实例的网络流量,而不依赖于基于主机的过滤。OpenShift Ansible 安装程序处理除部署主机外,为 OpenShift Container Platform 集群一部分的每种主机需要的所有端口和服务正确创建。

以下命令创建一个空安全组,没有为部署主机设置规则。

$ source path/to/examplerc
$ openstack security group create <deployment-sg-name>
Copy to Clipboard Toggle word wrap

验证安全组的创建:

$ openstack security group list
Copy to Clipboard Toggle word wrap

部署主机安全组

部署实例只需要允许入站 ssh。此实例存在,供操作员提供一个稳定的基础,以部署、监控和管理 OpenShift Container Platform 环境。

Expand
表 22.3. 部署主机安全组 TCP 端口
端口/协议服务远程源用途

ICMP

ICMP

任意

允许 ping、traceroute 等。

22/TCP

SSH

任意

安全 shell 登录

创建上述安全组规则如下:

$ source /path/to/examplerc
$ openstack security group rule create \
    --ingress \
    --protocol icmp \
    <deployment-sg-name>
$ openstack security group rule create \
    --ingress \
    --protocol tcp \
    --dst-port 22 \
    <deployment-sg-name>
Copy to Clipboard Toggle word wrap

安全组规则验证如下:

$ openstack security group rule list <deployment-sg-name>
+--------------------------------------+-------------+-----------+------------+-----------------------+
| ID                                   | IP Protocol | IP Range  | Port Range | Remote Security Group |
+--------------------------------------+-------------+-----------+------------+-----------------------+
| 7971fc03-4bfe-4153-8bde-5ae0f93e94a8 | icmp        | 0.0.0.0/0 |            | None                  |
| b8508884-e82b-4ee3-9f36-f57e1803e4a4 | None        | None      |            | None                  |
| cb914caf-3e84-48e2-8a01-c23e61855bf6 | tcp         | 0.0.0.0/0 | 22:22      | None                  |
| e8764c02-526e-453f-b978-c5ea757c3ac5 | None        | None      |            | None                  |
+--------------------------------------+-------------+-----------+------------+-----------------------+
Copy to Clipboard Toggle word wrap
22.2.3.10. OpenStack Cinder 卷

OpenStack Block Storage 通过 cinder 服务提供持久的块存储管理。块存储使得 OpenStack 用户能够创建可以连接到不同 OpenStack 实例的卷。

22.2.3.10.1. Docker 卷

master 和节点实例包含用于存储 docker 镜像的卷。卷的目的是确保大型镜像或容器不破坏现有节点的节点性能或能力。

注意

运行容器至少需要 15GB 的 docker 卷。这可能需要根据每个节点运行的大小和容器数量进行调整。

docker 卷由 OpenShift Ansible 安装程序通过变量 openshift_openstack_docker_volume_size 创建。稍后介绍了有关 OpenShift Ansible 安装程序所需更改的更多信息。

22.2.3.10.2. registry 卷

OpenShift 镜像注册表需要一个 cinder 卷,以确保在 registry 需要迁移到另一个节点时保存镜像。以下步骤演示了如何通过 OpenStack 创建镜像 registry。创建卷后,卷 ID 将包含在 OpenShift Installer OSEv3.yml 文件中,该文件通过参数 openshift_hosted_registry_storage_openstack_volumeID 如下所述。

$ source /path/to/examplerc
$ openstack volume create --size <volume-size-in-GB> <registry-name>
Copy to Clipboard Toggle word wrap
注意

registry 卷大小应该至少有 30GB。

验证卷的创建。

$ openstack volume list
----------------------------------------+------------------------------------------------+
| ID                                   | Name          | Status    | Size | Attached to  |
+--------------------------------------+-------------------------------------------------+
| d65209f0-9061-4cd8-8827-ae6e2253a18d | <registry-name>| available |   30 |              |
+--------------------------------------+-------------------------------------------------+
Copy to Clipboard Toggle word wrap
22.2.3.11. 创建并配置部署实例

部署实例的角色是充当 OpenShift Container Platform 部署和管理的 utility 主机。

创建部署主机网络和路由器

在创建实例之前,必须创建一个内部网络和路由器来与部署主机通信。以下命令创建了该网络和路由器。

$ source path/to/examplerc

$ openstack network create <deployment-net-name>

$ openstack subnet create --network <deployment-net-name> \
  --subnet-range <subnet_range> \
  --dns-nameserver <dns-ip> \
  <deployment-subnet-name>

$ openstack router create <deployment-router-name>

$ openstack router set --external-gateway <public-net-name> <deployment-router-name>

$ openstack router add subnet <deployment-router-name> <deployment-subnet-name>
Copy to Clipboard Toggle word wrap

部署部署实例

创建网络和安全组时,部署该实例。

$ domain=<domain>
$ netid1=$(openstack network show <deployment-net-name> -f value -c id)
$ openstack server create \
    --nic net-id=$netid1 \
    --flavor <flavor> \
    --image <image> \
    --key-name <keypair> \
    --security-group <deployment-sg-name> \
    deployment.$domain
Copy to Clipboard Toggle word wrap
注意

默认情况下,如果 m1.small 类别不存在,则使用满足 1 vCPU 和 2GB RAM 要求的现有类别。

创建并将浮动 IP 添加到部署实例

创建部署实例后,必须创建一个浮动 IP,然后分配给实例。以下示例显示了示例。

$ source /path/to/examplerc
$ openstack floating ip create <public-network-name>
+---------------------+--------------------------------------+
| Field               | Value                                |
+---------------------+--------------------------------------+
| created_at          | 2017-08-24T22:44:03Z                 |
| description         |                                      |
| fixed_ip_address    | None                                 |
| floating_ip_address | 10.20.120.150                       |
| floating_network_id | 084884f9-d9d2-477a-bae7-26dbb4ff1873 |
| headers             |                                      |
| id                  | 2bc06e39-1efb-453e-8642-39f910ac8fd1 |
| port_id             | None                                 |
| project_id          | ca304dfee9a04597b16d253efd0e2332     |
| project_id          | ca304dfee9a04597b16d253efd0e2332     |
| revision_number     | 1                                    |
| router_id           | None                                 |
| status              | DOWN                                 |
| updated_at          | 2017-08-24T22:44:03Z                 |
+---------------------+--------------------------------------+
Copy to Clipboard Toggle word wrap

在上面的输出中,floating_ip_address 字段显示创建了浮动 IP 10.20.120.150。要将这个 IP 分配给部署实例,请运行以下命令:

$ source /path/to/examplerc
$ openstack server add floating ip <deployment-instance-name> <ip>
Copy to Clipboard Toggle word wrap

例如,如果实例 deployment.example.com 被分配 IP 10.20.120.150,则命令将为:

$ source /path/to/examplerc
$ openstack server add floating ip deployment.example.com 10.20.120.150
Copy to Clipboard Toggle word wrap

在部署主机中添加 RC 文件

部署主机存在后,通过 scp 将之前创建的 RC 文件复制到部署主机上,如下所示

scp <rc-file-deployment-host> cloud-user@<ip>:/home/cloud-user/
Copy to Clipboard Toggle word wrap
22.2.3.12. OpenShift Container Platform 的部署配置

以下小节描述了正确配置部署实例所需的所有步骤。

配置 ~/.ssh/config 以使用 Deployment Host 作为 Jumphost

要轻松连接到 OpenShift Container Platform 环境,请按照以下步骤操作。

在 OpenStack director 节点上,或使用私钥 <keypair-name>.pem 的本地工作站:

$ exec ssh-agent bash

$ ssh-add /path/to/<keypair-name>.pem
Identity added: /path/to/<keypair-name>.pem (/path/to/<keypair-name>.pem)
Copy to Clipboard Toggle word wrap

添加到 ~/.ssh/config 文件中:

Host deployment
    HostName        <deployment_fqdn_hostname OR IP address>
    User            cloud-user
    IdentityFile    /path/to/<keypair-name>.pem
    ForwardAgent     yes
Copy to Clipboard Toggle word wrap

使用带有 -A 选项的 ssh 连接到部署主机,这可以启用转发身份验证代理连接。

确保只针对 ~/.ssh/config 文件所有者的读取写入权限:

$ chmod 600 ~/.ssh/config
Copy to Clipboard Toggle word wrap
$ ssh -A cloud-user@deployment
Copy to Clipboard Toggle word wrap

登录部署主机后,请通过检查 SSH_AUTH_SOCK 来验证 ssh 代理转发是否正常工作

$ echo "$SSH_AUTH_SOCK"
/tmp/ssh-NDFDQD02qB/agent.1387
Copy to Clipboard Toggle word wrap

订阅管理器并启用 OpenShift Container Platform 软件仓库

在部署实例中,在 Red Hat Subscription Manager 中注册。这可以通过使用凭证来实现:

$ sudo subscription-manager register --username <user> --password '<password>'
Copy to Clipboard Toggle word wrap

另外,您可以使用激活码:

$ sudo subscription-manager register --org="<org_id>" --activationkey=<keyname>
Copy to Clipboard Toggle word wrap

注册后,启用以下软件仓库,如下所示:

$ sudo subscription-manager repos \
    --enable="rhel-7-server-rpms" \
    --enable="rhel-7-server-extras-rpms" \
    --enable="rhel-7-server-ose-3.11-rpms" \
    --enable="rhel-7-server-ansible-2.6-rpms" \
    --enable="rhel-7-server-openstack-13-rpms" \
    --enable="rhel-7-server-openstack-13-tools-rpms"
Copy to Clipboard Toggle word wrap
注意

请参阅设置存储库,以确认要启用的 OpenShift Container Platform 存储库和 Ansible 版本。以上文件只是一个示例。

部署主机上所需的软件包

部署主机上需要安装以下软件包。

安装以下软件包:

  • openshift-ansible
  • python-openstackclient
  • python2-heatclient
  • python2-octaviaclient
  • python2-shade
  • python-dns
  • git
  • ansible
$ sudo yum -y install openshift-ansible python-openstackclient python2-heatclient python2-octaviaclient python2-shade python-dns git ansible
Copy to Clipboard Toggle word wrap

配置 Ansible

ansible 安装在部署实例上,以执行注册、安装软件包,并在 master 和节点实例上部署 OpenShift Container Platform 环境。

在运行 playbook 前,务必要创建一个 ansible.cfg 文件来反映您要部署的环境:

$ cat ~/ansible.cfg

[defaults]
forks = 20
host_key_checking = False
remote_user = openshift
gathering = smart
fact_caching = jsonfile
fact_caching_connection = $HOME/ansible/facts
fact_caching_timeout = 600
log_path = $HOME/ansible.log
nocows = 1
callback_whitelist = profile_tasks
inventory = /usr/share/ansible/openshift-ansible/playbooks/openstack/inventory.py,/home/cloud-user/inventory

[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=600s -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=false
control_path = %(directory)s/%%h-%%r
pipelining = True
timeout = 10

[persistent_connection]
connect_timeout = 30
connect_retries = 30
connect_interval = 1
Copy to Clipboard Toggle word wrap
警告

以下参数值对于 ansible.cfg 文件很重要。

  • remote_user 必须保留为用户 openshift
  • inventory 参数确保两个清单之间没有空格。

示例: inventory = path/to/inventory1,path/to/inventory2

以上代码块可覆盖文件中的默认值。确保使用复制到部署实例的密钥对填充 <keypair-name>。

注意

inventory 目录在 第 22.3.1 节 “为置备准备清单” 中创建。

OpenShift Authentication

OpenShift Container Platform 提供了使用许多不同的身份验证平台。如需身份验证选项列表,请参阅 配置身份验证和用户代理

配置默认身份提供程序非常重要,因为默认配置是 Deny All。

完成部署配置部署主机后,我们将使用 Ansible 为部署 OpenShift Container Platform 准备环境。在以下小节中,配置了 Ansible,并修改某些 YAML 文件,以实现 OpenStack 部署成功的 OpenShift Container Platform。

22.3.1. 为置备准备清单

通过前面的步骤安装 openshift-ansible 软件包后,有一个 sample-inventory 目录,我们将复制到部署主机的 cloud-user 主目录。

在部署主机上,

$ cp -r /usr/share/ansible/openshift-ansible/playbooks/openstack/sample-inventory/ ~/inventory
Copy to Clipboard Toggle word wrap

在这个清单目录中,all.yml 文件包含所有必须设置的不同参数,才能成功置备 RHOCP 实例。OSEv3.yml 文件包含 all.yml 文件和可自定义的所有可用 OpenShift Container Platform 集群参数的一些引用。

22.3.1.1. OpenShiftSDN 所有 YAML 文件

all.yml 文件有许多选项,可以修改以符合您的特定需求。此文件中收集的信息适用于成功部署 OpenShift Container Platform 所需的实例的调配部分。务必要仔细审阅。本文档将提供所有 YAML 文件的精简版本,并专注于为成功部署而需要设置的最关键参数。

$ cat ~/inventory/group_vars/all.yml
---
openshift_openstack_clusterid: "openshift"
openshift_openstack_public_dns_domain: *"example.com"*
openshift_openstack_dns_nameservers: *["10.19.115.228"]*
openshift_openstack_public_hostname_suffix: "-public"
openshift_openstack_nsupdate_zone: "{{ openshift_openstack_public_dns_domain }}"

openshift_openstack_keypair_name: *"openshift"*
openshift_openstack_external_network_name: *"public"*

openshift_openstack_default_image_name: *"rhel75"*

## Optional (Recommended) - This removes the need for floating IPs
## on the OpenShift Cluster nodes
openshift_openstack_node_subnet_name: *<deployment-subnet-name>*
openshift_openstack_router_name: *<deployment-router-name>*
openshift_openstack_master_floating_ip: *false*
openshift_openstack_infra_floating_ip: *false*
openshift_openstack_compute_floating_ip: *false*
## End of Optional Floating IP section

openshift_openstack_num_masters: *3*
openshift_openstack_num_infra: *3*
openshift_openstack_num_cns: *0*
openshift_openstack_num_nodes: *2*

openshift_openstack_master_flavor: *"m1.master"*
openshift_openstack_default_flavor: *"m1.node"*

openshift_openstack_use_lbaas_load_balancer: *true*

openshift_openstack_docker_volume_size: "15"

# # Roll-your-own DNS
*openshift_openstack_external_nsupdate_keys:*
  public:
    *key_secret: '/alb8h0EAFWvb4i+CMA12w=='*
    *key_name: "update-key"*
    *key_algorithm: 'hmac-md5'*
    *server: '<ip-of-DNS>'*
  private:
    *key_secret: '/alb8h0EAFWvb4i+CMA12w=='*
    *key_name: "update-key"*
    *key_algorithm: 'hmac-md5'*
    *server: '<ip-of-DNS>'*

ansible_user: openshift

## cloud config
openshift_openstack_disable_root: true
openshift_openstack_user: openshift
Copy to Clipboard Toggle word wrap
注意

由于使用外部 DNS 服务器,私有和公共部分使用 DNS 服务器的公共 IP 地址,因为 DNS 服务器不驻留在 OpenStack 环境中。

以上以星号(*)括起的值需要根据您的 OpenStack 环境和 DNS 服务器进行修改。

要正确修改 All YAML 文件的 DNS 部分,登录到 DNS 服务器并执行以下命令捕获密钥名称、密钥算法和密钥 secret:

$ ssh <ip-of-DNS>
$ sudo -i
# cat /etc/named/<key-name.key>
key "update-key" {
	algorithm hmac-md5;
	secret "/alb8h0EAFWvb4i+CMA02w==";
};
Copy to Clipboard Toggle word wrap
注意

密钥名称可能有所不同,上面的只是一个示例。

22.3.1.2. KuryrSDN 所有 YAML 文件

以下 all.yml 文件启用 Kuryr SDN 而不是默认的 OpenShiftSDN。请注意,以下示例是密度的版本,务必要仔细检查默认模板。

$ cat ~/inventory/group_vars/all.yml
---
openshift_openstack_clusterid: "openshift"
openshift_openstack_public_dns_domain: *"example.com"*
openshift_openstack_dns_nameservers: *["10.19.115.228"]*
openshift_openstack_public_hostname_suffix: "-public"
openshift_openstack_nsupdate_zone: "{{ openshift_openstack_public_dns_domain }}"

openshift_openstack_keypair_name: *"openshift"*
openshift_openstack_external_network_name: *"public"*

openshift_openstack_default_image_name: *"rhel75"*

## Optional (Recommended) - This removes the need for floating IPs
## on the OpenShift Cluster nodes
openshift_openstack_node_subnet_name: *<deployment-subnet-name>*
openshift_openstack_router_name: *<deployment-router-name>*
openshift_openstack_master_floating_ip: *false*
openshift_openstack_infra_floating_ip: *false*
openshift_openstack_compute_floating_ip: *false*
## End of Optional Floating IP section

openshift_openstack_num_masters: *3*
openshift_openstack_num_infra: *3*
openshift_openstack_num_cns: *0*
openshift_openstack_num_nodes: *2*

openshift_openstack_master_flavor: *"m1.master"*
openshift_openstack_default_flavor: *"m1.node"*

## Kuryr configuration
openshift_use_kuryr: True
openshift_use_openshift_sdn: False
use_trunk_ports: True
os_sdn_network_plugin_name: cni
openshift_node_proxy_mode: userspace
kuryr_openstack_pool_driver: nested
openshift_kuryr_precreate_subports: 5

kuryr_openstack_public_net_id: *<public_ID>*

# To disable namespace isolation, comment out the next 2 lines
openshift_kuryr_subnet_driver: namespace
openshift_kuryr_sg_driver: namespace
# If you enable namespace isolation, `default` and `openshift-monitoring` become the
# global namespaces. Global namespaces can access all namespaces. All
# namespaces can access global namespaces.
# To make other namespaces global, include them here:
kuryr_openstack_global_namespaces: default,openshift-monitoring

# If OpenStack cloud endpoints are accessible over HTTPS, provide the CA certificate
kuryr_openstack_ca: *<path-to-ca-certificate>*

openshift_master_open_ports:
- service: dns tcp
  port: 53/tcp
- service: dns udp
  port: 53/udp
openshift_node_open_ports:
- service: dns tcp
  port: 53/tcp
- service: dns udp
  port: 53/udp

# To set the pod network CIDR range, uncomment the following property and set its value:
#
# openshift_openstack_kuryr_pod_subnet_prefixlen: 24
#
# The subnet prefix length value must be smaller than the CIDR value that is
# set in the inventory file as openshift_openstack_kuryr_pod_subnet_cidr.
# By default, this value is /24.

# openshift_portal_net is the range that OpenShift services and their associated Octavia
# load balancer VIPs use. Amphora VMs use Neutron ports in the range that is defined by
# openshift_openstack_kuryr_service_pool_start and openshift_openstack_kuryr_service_pool_end.
#
# The value of openshift_portal_net in the OSEv3.yml file must be within the range that is
# defined by openshift_openstack_kuryr_service_subnet_cidr. This range must be half
# of openshift_openstack_kuryr_service_subnet_cidr's range. This practice ensures that
# openshift_portal_net does not overlap with the range that load balancers' VMs use, which is
# defined by openshift_openstack_kuryr_service_pool_start and openshift_openstack_kuryr_service_pool_end.
#
# For reference only, copy the value in the next line from OSEv3.yml:
# openshift_portal_net: *"172.30.0.0/16"*

openshift_openstack_kuryr_service_subnet_cidr: *"172.30.0.0/15"*
openshift_openstack_kuryr_service_pool_start: *"172.31.0.1"*
openshift_openstack_kuryr_service_pool_end: *"172.31.255.253"*

# End of Kuryr configuration

openshift_openstack_use_lbaas_load_balancer: *true*

openshift_openstack_docker_volume_size: "15"

# # Roll-your-own DNS
*openshift_openstack_external_nsupdate_keys:*
  public:
    *key_secret: '/alb8h0EAFWvb4i+CMA12w=='*
    *key_name: "update-key"*
    *key_algorithm: 'hmac-md5'*
    *server: '<ip-of-DNS>'*
  private:
    *key_secret: '/alb8h0EAFWvb4i+CMA12w=='*
    *key_name: "update-key"*
    *key_algorithm: 'hmac-md5'*
    *server: '<ip-of-DNS>'*

ansible_user: openshift

## cloud config
openshift_openstack_disable_root: true
openshift_openstack_user: openshift
Copy to Clipboard Toggle word wrap
注意

如果使用命名空间隔离,Kuryr-controller 会为每个命名空间创建一个新的 Neutron 网络和子网。

注意

启用 Kuryr SDN 时不支持网络策略和节点端口服务。

注意

如果启用了 Kuryr,OpenShift Container Platform 服务会通过 OpenStack Octavia Amphora 虚拟机实现。

Octavia 不支持 UDP 负载均衡。不支持公开 UDP 端口的服务。

22.3.1.2.1. 配置全局命名空间访问权限

kuryr_openstack_global_namespace 参数包含定义全局命名空间的列表。默认情况下,只有 默认openshift-monitoring 命名空间包含在此列表中。

如果您要从 OpenShift Container Platform 3.11 的以前的 z-release 升级,请注意,从全局命名空间中对其他命名空间的访问由安全组 *-allow_from_default 控制。

虽然 remote_group_id 规则 可以从全局命名空间中控制对其他命名空间的访问,但使用该脚本可能会导致缩放和连接问题。要避免这些问题,请从在 *_allow_from_defaultremote_ip_prefix 处使用 remote_group_id:

  1. 在命令行中检索您的网络 subnetCIDR 值:

    $ oc get kuryrnets ns-default -o yaml | grep subnetCIDR
      subnetCIDR: 10.11.13.0/24
    Copy to Clipboard Toggle word wrap
  2. 为这个范围创建 TCP 和 UDP 规则:

    $ openstack security group rule create --remote-ip 10.11.13.0/24 --protocol tcp openshift-ansible-openshift.example.com-allow_from_default
    $ openstack security group rule create --remote-ip 10.11.13.0/24 --protocol udp openshift-ansible-openshift.example.com-allow_from_default
    Copy to Clipboard Toggle word wrap
  3. 删除使用 remote_group_id 的安全组规则:

    $ openstack security group show *-allow_from_default | grep remote_group_id
    $ openstack security group rule delete REMOTE_GROUP_ID
    Copy to Clipboard Toggle word wrap
Expand
表 22.4. All YAML 文件中的变量描述
变量描述

openshift_openstack_clusterid

集群识别名称

openshift_openstack_public_dns_domain

公共 DNS 域名

openshift_openstack_dns_nameservers

DNS 名称服务器的 IP

openshift_openstack_public_hostname_suffix

在公共和私有的 DNS 记录中的节点主机名中添加后缀

openshift_openstack_nsupdate_zone

要使用 OCP 实例 IP 更新的区域

openshift_openstack_keypair_name

用于登录 OCP 实例的密钥对名称

openshift_openstack_external_network_name

OpenStack 公共网络名称

openshift_openstack_default_image_name

用于 OCP 实例的 OpenStack 镜像

openshift_openstack_num_masters

要部署的 master 节点数量

openshift_openstack_num_infra

要部署的基础架构节点数量

openshift_openstack_num_cns

要部署的容器原生存储节点数量

openshift_openstack_num_nodes

要部署的应用程序节点数量

openshift_openstack_master_flavor

用于 master 实例的 OpenStack 类别的名称

openshift_openstack_default_flavor

如果未指定的具体类别,则 Openstack 类别的名称用于所有实例。

openshift_openstack_use_lbaas_load_balancer

启用 Octavia 负载均衡器的布尔值(必须安装Octavia)

openshift_openstack_docker_volume_size

Docker 卷的最小大小(必需变量)

openshift_openstack_external_nsupdate_keys

使用实例 IP 地址更新 DNS

ansible_user

用于部署 OpenShift Container Platform 的 Ansible 用户。"openshift"是需要的名称,且不得更改。

openshift_openstack_disable_root

禁用 root 访问权限的布尔值

openshift_openstack_user

使用此用户创建的 OCP 实例

openshift_openstack_node_subnet_name

用于部署的现有 OpenShift 子网的名称。这应该与用于您的部署主机的子网名称相同。

openshift_openstack_router_name

用于部署的现有 OpenShift 路由器的名称。这应该与用于部署主机的路由器名称相同。

openshift_openstack_master_floating_ip

默认为 true。如果您不希望分配给 master 节点的浮动 IP,则必须设置为 false

openshift_openstack_infra_floating_ip

默认为 true。如果您不希望浮动 IP 分配给基础架构节点,则必须设置为 false

openshift_openstack_compute_floating_ip

默认为 true。如果您不希望分配给计算节点的浮动 IP,则必须设置为 false

openshift_use_openshift_sdn

如果要禁用 openshift-sdn,则必须设置为 false

openshift_use_kuryr

如果要启用 kuryr sdn,则必须设置为 true

use_trunk_ports

必须设置为 true,才能创建带有中继端口的 OpenStack 虚拟机( kuryr 必需)

os_sdn_network_plugin_name

选择 SDN 行为。为 kuryr 设置为 cni

openshift_node_proxy_mode

必须将 Kuryr 设置为 用户空间

openshift_master_open_ports

使用 Kuryr 时会在虚拟机上打开的端口

kuryr_openstack_public_net_id

由 Kuryr 的需求。从中获取 FIP 的公共 OpenStack 网络的 ID

openshift_kuryr_subnet_driver

Kuryr Subnet 驱动程序。必须是 命名空间,用于为每个命名空间创建一个子网

openshift_kuryr_sg_driver

Kuryr 安全组驱动程序。必须是 命名空间 才能隔离命名空间

kuryr_openstack_global_namespaces

用于命名空间隔离的全局命名空间。默认值为 default, openshift-monitoring

kuryr_openstack_ca

到云的 CA 证书的路径。如果 OpenStack 云端点可以通过 HTTPS 访问,则需要此项。

22.3.1.3. OSEv3 YAML 文件

OSEv3 YAML 文件指定与 OpenShift 安装相关的所有不同参数和自定义。

以下是文件的一个精简版本,其中包含成功部署所需的所有变量。根据特定 OpenShift Container Platform 部署所需的自定义,可能需要额外的变量。

$ cat ~/inventory/group_vars/OSEv3.yml
---

openshift_deployment_type: openshift-enterprise
openshift_release: v3.11
oreg_url: registry.access.redhat.com/openshift3/ose-${component}:${version}
openshift_examples_modify_imagestreams: true
oreg_auth_user: <oreg_auth_user>
oreg_auth_password: <oreg_auth_pw>
# The following is required if you want to deploy the Operator Lifecycle Manager (OLM)
openshift_additional_registry_credentials: [{'host':'registry.connect.redhat.com','user':'REGISTRYCONNECTUSER','password':'REGISTRYCONNECTPASSWORD','test_image':'mongodb/enterprise-operator:0.3.2'}]

openshift_master_default_subdomain: "apps.{{ (openshift_openstack_clusterid|trim == '') | ternary(openshift_openstack_public_dns_domain, openshift_openstack_clusterid + '.' + openshift_openstack_public_dns_domain) }}"

openshift_master_cluster_public_hostname: "console.{{ (openshift_openstack_clusterid|trim == '') | ternary(openshift_openstack_public_dns_domain, openshift_openstack_clusterid + '.' + openshift_openstack_public_dns_domain) }}"

#OpenStack Credentials:
openshift_cloudprovider_kind: openstack
openshift_cloudprovider_openstack_auth_url: "{{ lookup('env','OS_AUTH_URL') }}"
openshift_cloudprovider_openstack_username: "{{ lookup('env','OS_USERNAME') }}"
openshift_cloudprovider_openstack_password: "{{ lookup('env','OS_PASSWORD') }}"
openshift_cloudprovider_openstack_tenant_name: "{{ lookup('env','OS_PROJECT_NAME') }}"
openshift_cloudprovider_openstack_blockstorage_version: v2
openshift_cloudprovider_openstack_domain_name: "{{ lookup('env','OS_USER_DOMAIN_NAME') }}"
openshift_cloudprovider_openstack_conf_file: <path_to_local_openstack_configuration_file>

#Use Cinder volume for Openshift registry:
openshift_hosted_registry_storage_kind: openstack
openshift_hosted_registry_storage_access_modes: ['ReadWriteOnce']
openshift_hosted_registry_storage_openstack_filesystem: xfs
openshift_hosted_registry_storage_volume_size: 30Gi


openshift_hosted_registry_storage_openstack_volumeID: d65209f0-9061-4cd8-8827-ae6e2253a18d
openshift_hostname_check: false
ansible_become: true

#Setting SDN (defaults to ovs-networkpolicy) not part of OSEv3.yml
#For more info, on which to choose, visit:
#https://docs.openshift.com/container-platform/3.11/architecture/networking/sdn.html#overview
networkPluginName: redhat/ovs-networkpolicy
#networkPluginName: redhat/ovs-multitenant

#Configuring identity providers with Ansible
#For initial cluster installations, the Deny All identity provider is configured
#by default. It is recommended to be configured with either htpasswd
#authentication, LDAP authentication, or Allowing all authentication (not recommended)
#For more info, visit:
#https://docs.openshift.com/container-platform/3.10/install_config/configuring_authentication.html#identity-providers-ansible
#Example of Allowing All
#openshift_master_identity_providers: [{'name': 'allow_all', 'login': 'true', 'challenge': 'true', 'kind': 'AllowAllPasswordIdentityProvider'}]


#Optional Metrics (uncomment below lines for installation)

#openshift_metrics_install_metrics: true
#openshift_metrics_cassandra_storage_type: dynamic
#openshift_metrics_storage_volume_size: 25Gi
#openshift_metrics_cassandra_nodeselector: {"node-role.kubernetes.io/infra":"true"}
#openshift_metrics_hawkular_nodeselector: {"node-role.kubernetes.io/infra":"true"}
#openshift_metrics_heapster_nodeselector: {"node-role.kubernetes.io/infra":"true"}

#Optional Aggregated Logging (uncomment below lines for installation)

#openshift_logging_install_logging: true
#openshift_logging_es_pvc_dynamic: true
#openshift_logging_es_pvc_size: 30Gi
#openshift_logging_es_cluster_size: 3
#openshift_logging_es_number_of_replicas: 1
#openshift_logging_es_nodeselector: {"node-role.kubernetes.io/infra":"true"}
#openshift_logging_kibana_nodeselector: {"node-role.kubernetes.io/infra":"true"}
#openshift_logging_curator_nodeselector: {"node-role.kubernetes.io/infra":"true"}
Copy to Clipboard Toggle word wrap

有关列出的任何变量的更多详情,请参阅 OpenShift-Ansible 主机清单示例

22.3.2. OpenStack 先决条件 Playbook

OpenShift Container Platform Ansible 安装程序提供了一个 playbook,以确保满足 OpenStack 实例的所有置备步骤。

在运行 playbook 之前,请确保 source RC 文件

$ source path/to/examplerc
Copy to Clipboard Toggle word wrap

通过部署主机上的 ansible-playbook 命令,使用 prerequisites.yml playbook 确保满足所有先决条件:

$  ansible-playbook /usr/share/ansible/openshift-ansible/playbooks/openstack/openshift-cluster/prerequisites.yml
Copy to Clipboard Toggle word wrap

当先决条件 playbook 成功完成后,运行置备 playbook,如下所示:

$ ansible-playbook /usr/share/ansible/openshift-ansible/playbooks/openstack/openshift-cluster/provision.yml
Copy to Clipboard Toggle word wrap
重要

如果 provision.yml prematurely 错误,请检查 OpenStack 堆栈的状态并等待它完成

$ watch openstack stack list
+--------------------------------------+-------------------+--------------------+----------------------+--------------+
| ID                                   | Stack Name        | Stack Status       | Creation Time        | Updated Time |
+--------------------------------------+-------------------+--------------------+----------------------+--------------+
| 87cb6d1c-8516-40fc-892b-49ad5cb87fac | openshift-cluster | CREATE_IN_PROGRESS | 2018-08-20T23:44:46Z | None         |
+--------------------------------------+-------------------+--------------------+----------------------+--------------+
Copy to Clipboard Toggle word wrap

如果堆栈显示 CREATE_IN_PROGRESS,请等待堆栈以最终结果(如 CREATE_COMPLETE )完成。如果堆栈成功完成,请重新运行 provision.yml playbook,以完成所有其他必要的步骤。

如果堆栈显示 CREATE_FAILED,请确保运行以下命令来查看导致错误的原因:

$ openstack stack failures list openshift-cluster
Copy to Clipboard Toggle word wrap

22.3.3. 堆栈名称配置

默认情况下,OpenStack 为 OpenShift Container Platform 集群创建的 Heat 堆栈名为 openshift-cluster。如果要使用其他名称,必须在运行 playbook 前设置 OPENSHIFT_CLUSTER 环境变量:

$ export OPENSHIFT_CLUSTER=openshift.example.com
Copy to Clipboard Toggle word wrap

如果使用非默认堆栈名称并运行 openshift-ansible playbook 来更新部署,您必须将 OPENSHIFT_CLUSTER 设置为您的堆栈名称以避免错误。

成功置备节点后,下一步是确保通过 subscription-manager 成功注册所有节点,以安装成功 OpenShift Container Platform 安装的所有必要软件包。为简单起见,已创建了一个并提供了 repos.yml 文件。

$ cat ~/repos.yml
---
- name: Enable the proper repositories for OpenShift installation
  hosts: OSEv3
  become: yes
  tasks:
  - name: Register with activationkey and consume subscriptions matching Red Hat Cloud Suite or Red Hat OpenShift Container Platform
    redhat_subscription:
      state: present
      activationkey: <key-name>
      org_id: <orig_id>
      pool: '^(Red Hat Cloud Suite|Red Hat OpenShift Container Platform)$'

  - name: Disable all current repositories
    rhsm_repository:
      name: '*'
      state: disabled

  - name: Enable Repositories
    rhsm_repository:
      name: "{{ item }}"
      state: enabled
    with_items:
      - rhel-7-server-rpms
      - rhel-7-server-extras-rpms
      - rhel-7-server-ansible-2.6-rpms
      - rhel-7-server-ose-3.11-rpms
Copy to Clipboard Toggle word wrap
注意

请参阅 Set Up Repositories 来确认要启用的软件仓库和版本。以上文件只是一个示例。

使用 repos.yml,运行 ansible-playbook 命令:

$ ansible-playbook repos.yml
Copy to Clipboard Toggle word wrap

上例使用 Ansible 的 redhat_subscriptionrhsm_repository 模块来进行所有注册,禁用和启用存储库。本特定示例使用了使用红帽激活码。如果您没有激活码,请确保访问 Ansible redhat_subscription 模块以使用用户名和密码进行修改,如下例所示: https://docs.ansible.com/ansible/2.6/modules/redhat_subscription_module.html

注意

有时候,redhat_subscription 模块可能会在某些节点上失败。如果出现这个问题,请使用 subscription-manager 手动注册 OpenShift Container Platform 实例。

在调配的 OpenStack 实例后,将重点转移到安装 OpenShift Container Platform。安装和配置通过 OpenShift RPM 软件包提供的一系列 Ansible playbook 和角色来进行。查看之前配置好的 OSEv3.yml 文件,以确保所有选项都已正确设置。

在运行安装程序 playbook 之前,请确保通过以下方法满足所有 {rhocp} 先决条件:

$ ansible-playbook /usr/share/ansible/openshift-ansible/playbooks/prerequisites.yml
Copy to Clipboard Toggle word wrap

运行安装程序 playbook 以安装 Red Hat OpenShift Container Platform:

$ ansible-playbook /usr/share/ansible/openshift-ansible/playbooks/openstack/openshift-cluster/install.yml
Copy to Clipboard Toggle word wrap
注意

OpenShift Container Platform 版本 3.11 支持 RH OSP 14 和 RH OSP 13。OpenShift Container Platform 版本 3.10 需要运行在 RH OSP 13 上。

在所有 master 和节点主机上启动或重启 OpenShift Container Platform 服务以应用您的配置更改,请参阅重启 OpenShift Container Platform 服务

# master-restart api
# master-restart controllers
# systemctl restart atomic-openshift-node
Copy to Clipboard Toggle word wrap
注意

Kubernetes 架构需要来自云提供商的可靠端点。当云提供商停机时,kubelet 会防止 OpenShift Container Platform 重启。如果底层云供应商端点不可靠,请不要安装使用云供应商集成的集群。如在裸机环境中一样安装集群。不建议在已安装的集群中打开或关闭云提供商集成。但是,如果该情境不可避免,请完成以下过程。

从不使用云供应商切换到使用云提供商会产生错误消息。添加云供应商会尝试删除节点,因为从其切换的节点使用 hostname 作为 externalID (当没有云供应商使用时)使用云供应商的 instance-id (由云提供商指定)。要解决这个问题:

  1. 以集群管理员身份登录到 CLI。
  2. 检查和备份现有节点标签:

    $ oc describe node <node_name> | grep -Poz '(?s)Labels.*\n.*(?=Taints)'
    Copy to Clipboard Toggle word wrap
  3. 删除节点:

    $ oc delete node <node_name>
    Copy to Clipboard Toggle word wrap
  4. 在每个节点主机上,重启 OpenShift Container Platform 服务。

    # systemctl restart atomic-openshift-node
    Copy to Clipboard Toggle word wrap
  5. 在每个主机上重新添加回您以前具有的标记

要设置所需的 OpenStack 变量,请修改所有 OpenShift Container Platform 主机上以下内容的 /etc/origin/cloudprovider/openstack.conf 文件,包括 master 和节点:

[Global]
auth-url = <OS_AUTH_URL>
username = <OS_USERNAME>
password = <password>
domain-id = <OS_USER_DOMAIN_ID>
tenant-id = <OS_TENANT_ID>
region = <OS_REGION_NAME>

[LoadBalancer]
subnet-id = <UUID of the load balancer subnet>
Copy to Clipboard Toggle word wrap

请参考您的 OpenStack 管理员获取 OS_ 变量的值,它们通常用于 OpenStack 配置。

22.6.2. 为动态创建的 OpenStack PV 配置区域标签

管理员可以为动态创建的 OpenStack PV 配置区域标签。如果 OpenStack Cinder 区域名称与计算区域名称不匹配,则此选项很有用,例如,如果只有一个 Cinder 区域,并且有多个计算区域。管理员可以动态创建 Cinder 卷,然后检查标签。

查看 PV 的区标签:

# oc get pv --show-labels
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS    CLAIM                 STORAGECLASS   REASON    AGE       LABELS
pvc-1faa6f93-64ac-11e8-930c-fa163e3c373c   1Gi        RWO            Delete           Bound     openshift-node/pvc1   standard                 12s       failure-domain.beta.kubernetes.io/zone=nova
Copy to Clipboard Toggle word wrap

默认设置是 enabled。使用 oc get pv --show-labels 命令返回 failure-domain.beta.kubernetes.io/zone=nova 标签。

要禁用区标签,请通过添加以下内容更新 openstack.conf 文件:

[BlockStorage]
ignore-volume-az = yes
Copy to Clipboard Toggle word wrap

重启 master 服务后创建的 PV 将不会具有 zone 标签。

第 23 章 为 Google Compute Engine 配置

您可以配置 OpenShift Container Platform 以访问现有的 Google Compute Engine(GCE)基础架构包括使用 GCE 卷作为应用程序数据的持久性存储

23.1. 开始前

23.1.1. 为 Google Cloud Platform 配置授权

角色

为 OpenShift Container Platform 配置 GCP 需要以下 GCP 角色:

Expand

roles/owner

创建服务帐户、云存储、实例、镜像、模板、云 DNS 条目以及部署负载均衡器和健康检查所需要的。

如果用户应在测试阶段重新部署环境,则需要删除权限。

您还可以创建服务帐户以避免在部署 GCP 对象时使用个人用户。

如需更多信息,请参阅 GCP 文档中的了解角色部分,包括如何配置角色的步骤。

范围和服务帐户

GCP 使用范围来确定经过身份验证的身份是否有权在资源内执行操作。例如,如果具有只读范围访问令牌的应用程序 A 只能读取,而具有读写范围访问令牌的应用程序 B 可能会读取和修改数据。

范围在 GCP API 级别中定义为 https://www.googleapis.com/auth/compute.readonly

您可以使用 --scopes=[SCOPE,…​ 指定范围。] 选项在创建实例时,或者您可以使用 --no-scopes 选项来创建实例,如果没有考虑实例访问 GCP API,则可以使用 --no-scopes 选项来创建实例。

如需更多信息,请参阅 GCP 文档中的 Scopes 部分

所有 GCP 项目都包括一个默认的 [PROJECT_NUMBER]-compute@developer.gserviceaccount.com 服务帐户,具有项目编辑器权限。

默认情况下,新创建的实例会自动启用为具有以下访问范围的默认服务帐户运行:

在创建实例时,您可以使用 --service-account=SERVICE_ACCOUNT 选项指定另一个服务帐户,或使用 gcloud CLI 明确禁用实例的 服务帐户

如需更多信息,请参阅 GCP 文档中的创建新服务帐户部分

23.1.2. Google Compute Engine 对象

将 OpenShift Container Platform 与 Google Compute Engine(GCE)集成需要以下组件或服务。

GCP 项目
GCP 项目是组织基本级别的实体,它组成了创建、启用和使用所有 GCP 服务的基础。这包括管理 API、启用账单、添加和删除协作器以及管理权限。

如需更多信息,请参阅 GCP 文档中的项目资源部分

重要

项目 ID 是唯一标识符,项目 ID 必须在所有 Google Cloud Engine 之间唯一。这意味着,如果其他人使用该 ID 创建了一个项目 ID,则您无法使用 myproject 作为项目 ID。

账单
除非将账单附加到帐户,否则您无法创建新的资源。新项目可以链接到现有项目,也可以输入新的信息。

如需更多信息,请参阅 GCP 文档中的创建、修改或关闭您的账单帐户

云身份和访问管理
部署 OpenShift Container Platform 需要正确权限。用户必须能够创建服务帐户、云存储、实例、镜像、模板、云 DNS 条目,以及部署负载均衡器和健康检查。删除权限也会有帮助,以便在测试过程中重新部署环境。

您可以使用特定权限创建服务帐户,然后使用它们部署基础架构组件,而不是常规用户。您还可以创建角色来限制对不同用户或服务帐户的访问。

GCP 实例使用服务帐户来允许应用程序调用 GCP API。例如,OpenShift Container Platform 节点主机可以调用 GCP 磁盘 API,为应用程序提供持久性卷。

IAM 服务可使用对各种基础架构、服务资源和细粒度角色的访问控制。如需更多信息,请参阅 GCP 文档中的访问云概述 部分

SSH 密钥
GCP 将 SSH 公钥作为授权密钥注入,以便您可以在创建的实例中使用 SSH 登录。您可以为每个实例或每个项目配置 SSH 密钥。

您可以使用现有的 SSH 密钥。GCP 元数据可帮助存储实例中引导时注入的 SSH 密钥,以允许 SSH 访问。

如需更多信息,请参阅 GCP 文档中的 Metadata 部分

GCP 区域和区
GCP 有一个覆盖区域和可用区的全局基础架构。在不同区的 GCP 中部署 OpenShift Container Platform 有助于避免出现单点故障,但存储有一些注意事项。

GCP 磁盘在区内创建。因此,如果 OpenShift Container Platform 节点主机在区域 "A" 中停机,并且 pod 移到 zone "B",则持久性存储无法附加到这些 pod,因为磁盘位于不同的区。

在安装 OpenShift Container Platform 前,部署多区 OpenShift Container Platform 环境是一个重要决定。如果部署多区环境,建议的设置是在单一区域中使用三个不同的区。

如需更多信息 ,请参阅 GCP 文档中有关 区域和 区的 Kubernetes 文档

外部 IP 地址
因此,GCP 实例可以与互联网通信,您必须将外部 IP 地址附加到实例。另外,还需要外部 IP 地址与从 Virtual Private Cloud(VPC)网络外部署的实例进行通信。
警告

需要外部 IP 地址 进行互联网访问 是该提供程序的限制。如果需要,您可以将防火墙规则配置为阻止实例中进入的外部流量。

如需更多信息,请参阅外部 IP 地址上的 GCP 文档

Cloud DNS
GCP Cloud DNS 是一个 DNS 服务,用于使用 GCP DNS 服务器将域名发布到全局 DNS。

公共云 DNS 区域需要一个通过 Google 的"Domains"服务或第三方供应商购买的域名。在创建区时,必须将 Google 提供的名称服务器添加到注册商中。

如需更多信息,请参阅 Cloud DNS 的 GCP 文档

注意

GCP VPC 网络有一个内部 DNS 服务,可自动解析内部主机名。

实例的内部完全限定域名(FQDN)遵循 [HOST_NAME].c.[PROJECT_ID].internal 格式。

如需更多信息,请参阅内部 DNS 上的 GCP 文档

负载平衡
GCP 负载均衡服务启用在 GCP 云中的多个实例间流量分布。

负载均衡有三种:

注意

HTTPS 和 TCP 代理负载平衡是 master 节点使用 HTTPS 健康检查的唯一选项,用于检查 /healthz 的状态。

由于 HTTPS 负载均衡需要自定义证书,这种实现使用 TCP 代理负载平衡来简化过程。

如需更多信息,请参阅 GCP 文档

实例大小
成功的 OpenShift Container Platform 环境需要一些最低硬件要求:
Expand
表 23.1. 实例大小
角色大小

Master

n1-standard-8

节点

n1-standard-4

GCP 允许您创建自定义实例大小来满足不同的要求。如需更多信息,请参阅使用自定义 Machine Type 创建实例,或参阅 Machine typeOpenShift Container Platform Minimum 硬件要求来获得有关实例大小的更多信息。

存储选项

默认情况下,每个 GCP 实例都有一个包含操作系统的小根磁盘。当实例中运行的应用程序需要更多存储空间时,您可以为实例添加额外的存储选项:

  • 标准持久性磁盘
  • SSD 持久性磁盘
  • 本地 SSD
  • 云存储存储桶

如需更多信息,请参阅有关存储选项的 GCP 文档

23.2. 为 GCE 配置 OpenShift Container Platform

您可以通过两种方式为 GCE 配置 OpenShift Container Platform:

您可以在安装时或安装后修改 Ansible 清单文件,为 Google Compute Platform(GCP)配置 OpenShift Container Platform。

流程

  1. 您至少必须定义 openshift_cloudprovider_kindopenshift_gcp_projectopenshift_gcp_prefix 参数,以及对于 multizone 部署的可选 openshift_gcp_multizone,则为 openshift_gcp_network_name 定义。

    在安装时将以下部分添加到 Ansible 清单文件中,以便为 GCP 配置 OpenShift Container Platform 环境:

    [OSEv3:vars]
    openshift_cloudprovider_kind=gce
    openshift_gcp_project=<projectid> 
    1
    
    openshift_gcp_prefix=<uid> 
    2
    
    openshift_gcp_multizone=False 
    3
    
    openshift_gcp_network_name=<network name> 
    4
    Copy to Clipboard Toggle word wrap
    1
    提供运行现有实例的 GCP 项目 ID。在 Google Cloud Platform 控制台中创建项目时,会生成此 ID。
    2
    提供唯一字符串来标识每个 OpenShift Container Platform 集群。这在 GCP 之间必须是唯一的。
    3
    另外,还可设置为 True 以在 GCP 上触发多 zone 部署。默认设置为 False
    4
    另外,如果没有使用默认网络,则提供网络名称。

    使用 Ansible 安装也会创建并配置以下文件以适合您的 GCP 环境:

    • /etc/origin/cloudprovider/gce.conf
    • /etc/origin/master/master-config.yaml
    • /etc/origin/node/node-config.yaml
  2. 如果您使用 GCP 运行负载均衡器服务,Compute Engine 虚拟机实例需要 ocp 后缀。例如,如果 openshift_gcp_prefix 参数的值设置为 mycluster,则必须标记带有 myclusterocp 的节点。有关如何在 Compute Engine 虚拟机实例中添加网络标签的更多信息,请参阅添加和删除网络标签
  3. 另外,您可以配置多区支持。

    集群安装过程默认配置单区支持,但您可以配置多个区以避免出现单一故障点。

    因为 GCP 磁盘是在区中创建的,在不同的区上的 GCP 中部署 OpenShift Container Platform 可能会导致存储出现问题。如果 OpenShift Container Platform 节点主机在区域 "A" 中停机,并且 pod 移到 zone "B",则持久性存储无法附加到这些 pod,因为磁盘现在位于不同的区。如需更多信息,请参阅 Kubernetes 文档中的多个区限制

    要使用 Ansible 清单文件启用多区支持,请添加以下参数:

    [OSEv3:vars]
    openshift_gcp_multizone=true
    Copy to Clipboard Toggle word wrap

    要返回单区支持,将 openshift_gcp_multizone 值设置为 false,然后重新运行 Ansible 清单文件。

23.2.2.1. 为 GCE 手动配置 master 主机

在所有 master 主机上执行以下步骤。

流程

  1. 默认情况下,将 GCE 参数添加到 /etc/origin/master/master-config.yaml 中的 master 配置文件的 apiServerArgumentscontrollerArguments 部分:

    apiServerArguments:
      cloud-provider:
        - "gce"
      cloud-config:
        - "/etc/origin/cloudprovider/gce.conf"
    controllerArguments:
      cloud-provider:
        - "gce"
      cloud-config:
        - "/etc/origin/cloudprovider/gce.conf"
    Copy to Clipboard Toggle word wrap
  2. 使用 Ansible 为 GCP 配置 OpenShift Container Platform 时,会自动创建 /etc/origin/cloudprovider/gce.conf 文件。由于您要手动为 GCP 配置 OpenShift Container Platform,所以您必须创建该文件并输入以下命令:

    [Global]
    project-id = <project-id> 
    1
    
    network-name = <network-name> 
    2
    
    node-tags = <node-tags> 
    3
    
    node-instance-prefix = <instance-prefix> 
    4
    
    multizone = true 
    5
    Copy to Clipboard Toggle word wrap
    1
    提供运行现有实例的 GCP 项目 ID。
    2
    如果没有使用默认值,则提供网络名称。
    3
    为 GCP 节点提供标签。必须包含 ocp 作为后缀。例如,如果 node-instance-prefix 参数的值设置为 mycluster,则节点必须标记为 myclusterocp
    4
    提供唯一字符串来标识 OpenShift Container Platform 集群。
    5
    设置为 true 以在 GCP 上触发多 zone 部署。默认设置为 False

    集群安装过程默认配置单区支持。

    在不同区的 GCP 中部署 OpenShift Container Platform 有助于避免出现单一故障点,但可能会导致存储出现问题。这是因为 GCP 磁盘是在区中创建。如果 OpenShift Container Platform 节点主机在区域 "A" 中停机,并且 pod 应该移到 zone "B" 中,则持久性存储无法附加到这些 pod,因为磁盘现在位于不同的区中。如需更多信息,请参阅 Kubernetes 文档中的多个区限制

    重要

    要使用 GCP 运行负载均衡器服务,Compute Engine 虚拟机节点实例需要 ocp 后缀: < openshift_gcp_prefix>ocp。例如,如果 openshift_gcp_prefix 参数的值设置为 mycluster,则必须标记带有 myclusterocp 的节点。有关如何在 Compute Engine 虚拟机实例中添加网络标签的更多信息,请参阅添加和删除网络标签

  3. 重启 OpenShift Container Platform 主机服务:

    # master-restart api
    # master-restart controllers
    # systemctl restart atomic-openshift-node
    Copy to Clipboard Toggle word wrap

要返回单区支持,将 multizone 值设置为 false,然后重新启动 master 和节点主机服务。

23.2.2.2. 为 GCE 手动配置节点主机

在所有节点主机上执行以下内容。

流程

  1. 编辑 适当的节点配置映射 并更新 kubeletArguments 部分的内容:

    kubeletArguments:
      cloud-provider:
        - "gce"
      cloud-config:
        - "/etc/origin/cloudprovider/gce.conf"
    Copy to Clipboard Toggle word wrap
    重要

    nodeName 必须与 GCP 中的实例名称匹配,才能使云供应商集成正常工作。名称也必须与 RFC1123 兼容。

  2. 重启所有节点上的 OpenShift Container Platform 服务。

    # systemctl restart atomic-openshift-node
    Copy to Clipboard Toggle word wrap

Google Cloud Platform(GCP)提供对象存储,OpenShift Container Platform 可以使用 OpenShift Container Platform 使用 OpenShift Container Platform 容器镜像 registry 存储容器镜像。

如需更多信息,请参阅 GCP 文档中的 Cloud Storage

先决条件

您必须在安装前创建存储桶来托管 registry 镜像。以下命令使用配置的服务帐户创建区域存储桶:

gsutil mb -c regional -l <region> gs://ocp-registry-bucket
cat <<EOF > labels.json
{
  "ocp-cluster": "mycluster"
}
EOF
gsutil label set labels.json gs://ocp-registry-bucket
rm -f labels.json
Copy to Clipboard Toggle word wrap
注意

默认情况下,存储桶的数据会使用 Google 管理的密钥自动加密。要指定不同的密钥来加密数据,请参阅 GCP 中的数据加密选项

如需更多信息,请参阅创建存储存储桶文档

流程

配置 registry 的 Ansible 清单文件 以使用 Google Cloud Storage (GCS) 存储桶:

[OSEv3:vars]
# GCP Provider Configuration
openshift_hosted_registry_storage_provider=gcs
openshift_hosted_registry_storage_kind=object
openshift_hosted_registry_replicas=1 
1

openshift_hosted_registry_storage_gcs_bucket=<bucket_name> 
2

openshift_hosted_registry_storage_gcs_keyfile=<bucket_keyfile> 
3

openshift_hosted_registry_storage_gcs_rootdirectory=<registry_directory> 
4
Copy to Clipboard Toggle word wrap
1
用于配置的副本数。
2
registry 存储的存储桶名称。
3
使用自定义密钥文件加密数据的安装程序主机上的路径。
4
用于存储数据的目录。默认情况下 /registry

如需更多信息,请参阅 GCP 文档中的 Cloud Storage

要使用 GCP 对象存储,请编辑 registry 的配置文件并挂载到 registry pod。

有关存储驱动程序配置文件的更多信息,请参阅 Google Cloud Storage Driver 文档

流程

  1. 导出当前的 /etc/registry/config.yml 文件:

    $ oc get secret registry-config \
        -o jsonpath='{.data.config\.yml}' -n default | base64 -d \
      >> config.yml.old
    Copy to Clipboard Toggle word wrap
  2. 从旧的 /etc/registry/config.yml 文件创建新配置文件:

    $ cp config.yml.old config.yml
    Copy to Clipboard Toggle word wrap
  3. 编辑该文件以包含 GCP 参数。在 registry 配置文件的 storage 部分指定存储桶和密钥文件:

    storage:
      delete:
        enabled: true
      cache:
        blobdescriptor: inmemory
      gcs:
        bucket: ocp-registry 
    1
    
        keyfile: mykeyfile 
    2
    Copy to Clipboard Toggle word wrap
    1
    使用 GCP 存储桶名称替换。
    2
    私有服务帐户密钥文件,采用 JSON 格式。如果使用 Google Application Default Credentials,请不要指定 keyfile 参数。
  4. 删除 registry-config secret:

    $ oc delete secret registry-config -n default
    Copy to Clipboard Toggle word wrap
  5. 重新创建 secret 来引用更新的配置文件:

    $ oc create secret generic registry-config \
        --from-file=config.yml -n default
    Copy to Clipboard Toggle word wrap
  6. 重新部署 registry 以读取更新的配置:

    $ oc rollout latest docker-registry -n default
    Copy to Clipboard Toggle word wrap
23.2.3.1.1. 验证 registry 是否使用 GCP 对象存储

验证 registry 是否使用 GCP 存储桶存储:

流程

  1. 使用 GCP 存储成功部署 registry 后,如果 registry 部署使用 emptydir 而不是 GCP 存储桶存储,registry deploymentconfig 不会显示任何信息:

    $ oc describe dc docker-registry -n default
    ...
    Mounts:
      ...
      /registry from registry-storage (rw)
    Volumes:
    registry-storage:
    Type:       EmptyDir 
    1
    
    ...
    Copy to Clipboard Toggle word wrap
    1
    共享 pod 生命周期的临时目录。
  2. 检查 /registry 挂载点是否为空。这是将使用卷 GCP 存储:

    $ oc exec \
        $(oc get pod -l deploymentconfig=docker-registry \
        -o=jsonpath='{.items[0].metadata.name}')  -i -t -- ls -l /registry
    total 0
    Copy to Clipboard Toggle word wrap