配置集群
OpenShift Container Platform 3.11 安装和配置
摘要
第 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
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
这将创建服务和部署配置,两者均称为 docker-registry。部署成功后,会使用类似于 docker-registry-1-cpty9 的名称创建 pod。
查看创建 registry 时可以指定的完整选项列表:
$ oc adm registry --help
--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 配置文件中需要配置的存储驱动程序:
- 文件系统。文件系统是默认设置,不需要进行配置。
- S3.如需更多信息,请参阅 CloudFront 配置 文档。
- OpenStack Swift
- Google Cloud Storage(GCS)
- Microsoft Azure
- Aliyun OSS
支持常规 registry 存储配置选项。如需更多信息,请参阅容器镜像 registry 文档。
以下存储选项需要通过文件系统驱动程序配置:
2.2.6.1. 产品使用
对于生产环境,请附加一个远程卷,或者 定义和使用您选择的持久性存储方法。
例如,使用现有持久性卷声明:
$ oc set volume deploymentconfigs/docker-registry --add --name=registry-storage -t pvc \ --claim-name=<pvc_name> --overwrite
测试显示,使用 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
所有 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>
- 1
- 为 OpenShift Container Platform 拉取正确的镜像是必需的。
${component}
和${version}
在安装过程中会被动态替换。
容器镜像 registry 容器集以用户 1001 身份运行。此用户必须能够写入主机目录。使用以下命令,您可能需要将目录所有权改为用户 ID 1001 :
$ sudo chown 1001:root <path>
2.2.7. 启用 Registry 控制台
OpenShift Container Platform 为集成的 registry 提供了一个基于 Web 的界面。此 registry 控制台是浏览和管理镜像的可选组件。它部署为作为容器集运行的无状态服务。
如果将 OpenShift Container Platform 作为独立 registry 安装,则 registry 控制台在安装过程中会自动部署和保护。
如果 Cockpit 已在运行,您需要先将其关闭,然后才能继续,以避免与 registry 控制台造成端口冲突(默认为 9090)。
2.2.7.1. 部署 Registry 控制台
您必须首先 公开 registry。
在 default 项目中创建一个 passthrough 路由。下一步中创建 registry 控制台应用时,您将需要此设置。
$ oc create route passthrough --service registry-console \ --port registry-console \ -n default
部署 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 }}')
注意如果您试图登录到 registry 控制台时重定向 URL 错误,请使用
oc get oauthclients
检查 OAuth 客户端。- 最后,使用 Web 浏览器使用路由 URI 查看控制台。
2.2.7.2. 保护 Registry 控制台
默认情况下,如果按照部署 registry 控制台中的步骤手动部署,registry 控制台会生成自签名 TLS 证书 。如需更多信息,请参阅 对 Registry 控制台进行故障排除。
使用以下步骤将组织的签名证书添加为 secret 卷。假设您的证书在 oc
客户端主机上可用。
创建一个包含证书和密钥的 .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-----
安全 registry 应包含以下主题备用名称(SAN)列表:
两个服务主机名:
例如:
docker-registry.default.svc.cluster.local docker-registry.default.svc
服务 IP 地址.
例如:
172.30.124.220
使用以下命令获取容器镜像 registry 服务 IP 地址:
oc get service docker-registry --template='{{.spec.clusterIP}}'
公共主机名.
例如:
docker-registry-default.apps.example.com
使用以下命令获取容器镜像 registry 公共主机名:
oc get route docker-registry --template '{{.spec.host}}'
例如,服务器证书应包含类似如下的 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
registry 控制台从 /etc/cockpit/ws-certs.d 目录中加载证书。它使用最后一个带有 .cert 扩展名的文件(按字母顺序排列)。因此,.cert 文件应至少包含以 OpenSSL 样式格式化的至少两个 PEM 块。
如果没有找到证书,将使用
openssl
命令创建自签名证书,并存储在 0-self-signed.cert 文件中。
创建 secret:
$ oc create secret generic console-secret \ --from-file=/path/to/console.cert
将 secret 添加到 registry-console 部署配置中:
$ oc set volume dc/registry-console --add --type=secret \ --secret-name=console-secret -m /etc/cockpit/ws-certs.d
这会触发 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
启用调试模式允许在 registry 控制台的 pod 日志中显示更详细的日志。
2.2.7.3.2. 显示 SSL 证书路径
要检查 registry 控制台正在使用的证书,可以从控制台容器集内运行命令。
列出 default 项目中的 pod,并找到 registry 控制台的 pod 名称:
$ oc get pods -n default NAME READY STATUS RESTARTS AGE registry-console-1-rssrw 1/1 Running 0 1d
使用上一命令中的容器集名称,获取 cockpit-ws 进程使用的证书路径。本例演示了使用自动生成的证书的控制台:
$ oc exec registry-console-1-rssrw remotectl certificate certificate: /etc/cockpit/ws-certs.d/0-self-signed.cert
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
2.3.2. 文件存储
标签和镜像元数据存储在 OpenShift Container Platform 中,但 registry 将层和签名数据存储在挂载到位于 /registry 的 registry 容器中的卷中。因为 oc exec
不在特权容器上工作,若要查看 registry 的内容,您必须手动 SSH 到 registry pod 的容器所在的节点,然后在容器本身上运行 docker exec
:
列出当前的 pod 以查找容器镜像 registry 的 pod 名称:
# oc get pods
然后,使用
oc describe
来查找运行容器的节点的主机名:# oc describe pod <pod_name>
登录到所需的节点:
# ssh node.example.com
从节点主机上的默认项目中列出正在运行的容器,并确定容器镜像 registry 的容器 ID:
# docker ps --filter=name=registry_docker-registry.*_default_
使用
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
2.3.3. 直接访问 Registry
对于高级用途,您可以直接访问 registry 来调用 docker
命令。这可让您直接使用 docker push
或 docker pull
等操作从集成的 registry 中推送镜像或从中提取镜像。为此,您必须使用 docker login
命令登录 registry。您可以执行的操作取决于您的用户权限,如以下各节所述。
2.3.3.1. 用户必备条件
要直接访问 registry,您使用的用户必须满足以下条件,具体取决于您的预期用途:
对于任何直接访问,您必须有首选身份提供程序的常规用户。普通用户可以生成登录到 registry 所需的访问令牌。系统用户(如 system:admin )无法获取访问令牌,因此无法直接访问 registry。
例如,如果您使用
HTPASSWD
身份验证,您可以使用以下命令创建一个:# htpasswd /etc/origin/master/htpasswd <user_name>
若要调取镜像,例如使用
docker pull
命令,用户必须具有 registry-viewer 角色。添加此角色:$ oc policy add-role-to-user registry-viewer <user_name>
为了编写或推送镜像,例如使用
docker push
命令,用户必须具有 registry-editor 角色。添加此角色:$ oc policy add-role-to-user registry-editor <user_name>
如需有关用户权限的更多信息,请参阅管理角色绑定。
2.3.3.2. 登录到 Registry
确保您的用户满足直接访问 registry 的先决条件。
直接登录到 registry:
确保您以 普通用户身份 登录到 OpenShift Container Platform:
$ oc login
使用您的访问令牌登录到容器镜像registry:
docker login -u openshift -p $(oc whoami -t) <registry_ip>:<port>
您可以为用户名传递任何值,令牌包含所有必要的信息。传递包含冒号的用户名将导致登录失败。
2.3.3.3. 推送和拉取镜像
登录 registry 后,您可以对 registry 执行 docker pull
和 docker push
操作。
您可以抓取任意镜像,但是如果已添加了system:registry角色,则只能将镜像推送到您自己的registry中。
在以下示例中,我们使用:
组件 | 值 |
<registry_ip> |
|
<port> |
|
<project> |
|
<image> |
|
<tag> |
忽略 (默认为 |
抓取任意镜像:
$ docker pull docker.io/busybox
使用
<registry_ip>:<port>/<project>/<image>
格式标记(tag)新镜像。项目名称必须出现在这个 pull 规范中,以供OpenShift Container Platform 把这个镜像正确放置在 registry 中,并在以后正确访问 registry 中的这个镜像:$ docker tag docker.io/busybox 172.30.124.220:5000/openshift/busybox
注意您的常规用户必须具有指定项目的 system:image-builder 角色,该角色允许用户写入或推送镜像。否则,下一步中的
docker push
将失败。若要进行测试,您可以创建一个新项目来推送 busybox 镜像。将新标记的镜像推送到registry:
$ docker push 172.30.124.220:5000/openshift/busybox ... cf2616975b4a: Image successfully pushed Digest: sha256:3662dd821983bc4326bee12caec61367e7fb6f6a3ee547cbaff98f77403cab55
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
访问指标的另一种方法是使用集群角色。您仍然需要启用端点,但不需要指定 <secret>
。配置文件中与指标数据相关的部分应如下所示:
openshift: version: 1.0 metrics: enabled: true ...
如果您还没有角色来访问指标,则必须创建一个集群角色:
$ 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 -
要将此角色添加到用户,请运行以下命令:
$ oc adm policy add-cluster-role-to-user prometheus-scraper <username>
有关更高级查询和推荐的可视化工具,请参阅 上游 Prometheus 文档。
2.4. 保护并公开 Registry
2.4.1. 概述
默认情况下,OpenShift Container Platform registry 在集群安装过程中是安全的,以便通过 TLS 提供流量。默认情况下还会创建一个 passthrough 路由,以将服务公开到外部。
如果出于任何原因您的 registry 没有被保护或公开,请参阅以下部分来了解如何手动操作。
2.4.2. 手动保护 Registry
手动保护 registry 以通过 TLS 提供流量:
- 部署 registry。
获取 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
您可以使用现有服务器证书,或者创建对指定 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
如果路由器将在 外部公开,请在
--hostnames
标志中添加公共路由主机名:--hostnames='mydocker-registry.example.com,docker-registry.default.svc.cluster.local,172.30.124.220 \
如需有关更新默认证书的更多详细信息,请参阅重新部署 Registry 和路由器 证书,以便可从外部访问该路由。
注意oc adm ca create-server-cert
命令会生成一个有效期为两年的证书。这可以通过--expire-days
选项进行修改,但出于安全原因,建议不要超过这个值。为 registry 证书创建 secret:
$ oc create secret generic registry-certificates \ --from-file=/etc/secrets/registry.crt \ --from-file=/etc/secrets/registry.key
将该机密添加到 registry 容器集的服务帐户(包括 默认 服务帐户):
$ oc secrets link registry registry-certificates $ oc secrets link default registry-certificates
注意默认情况下,“将 secret 仅限于引用它们的服务帐户”的功能被禁用。这意味着,如果在主配置文件中将
serviceAccountConfig.limitSecretReferences
设置为false
(默认设置),则不需要将 secret 连接到一个特定的服务。暂停
docker-registry
服务:$ oc rollout pause dc/docker-registry
将 secret 卷添加到 registry 部署配置中:
$ oc set volume dc/docker-registry --add --type=secret \ --secret-name=registry-certificates -m /etc/secrets
通过在 registry 部署配置中添加以下环境变量来启用 TLS:
$ oc set env dc/docker-registry \ REGISTRY_HTTP_TLS_CERTIFICATE=/etc/secrets/registry.crt \ REGISTRY_HTTP_TLS_KEY=/etc/secrets/registry.key
如需更多信息,请参阅 Docker 文档中的配置 registry 部分。
将 registry 的存活度探测使用从 HTTP 更新到 HTTPS:
$ oc patch dc/docker-registry -p '{"spec": {"template": {"spec": {"containers":[{ "name":"registry", "livenessProbe": {"httpGet": {"scheme":"HTTPS"}} }]}}}}'
如果您的 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"}} }]}}}}'
恢复
docker-registry
服务:$ oc rollout resume dc/docker-registry
验证 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
将 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
- 1
- ca.crt 文件是 master 上的 /etc/origin/master/ca.crt 的副本。
在使用身份验证时,一些
docker
版本还需要将集群配置为信任操作系统级别的证书。复制证书:
$ cp /etc/origin/master/ca.crt /etc/pki/ca-trust/source/anchors/myregistrydomain.com.crt
运行:
$ update-ca-trust enable
只删除 /etc/sysconfig/docker 文件中的这个特定 registry 的
--insecure-registry
选项。然后,重新载入守护进程并重启 docker 服务来反映这个配置更改:$ sudo systemctl daemon-reload $ sudo systemctl restart docker
验证
docker
客户端连接。运行docker push
到 registry 或 registry 中的docker pull
应该会成功。确保您已登录到 registry。$ docker tag|push <registry/image> <internal_registry/project/image>
例如:
$ 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
2.4.3. 手动公开安全 Registry
您可以通过首先保护 registry,然后使用路由公开它,而不是从 OpenShift Container Platform 集群内部登录到 OpenShift Container Platform registry。您可以使用路由地址从集群以外登陆到 registry,并使用路由主机进行镜像的 tag 和 push 操作。
以下每个先决条件步骤都会在典型的集群安装过程中默认执行。如果没有,请手动执行它们:
在初始集群安装过程中,默认为 registry 创建 passthrough 路由:
验证路由是否存在:
$ 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
注意也支持重新加密路由来公开安全 registry。
如果不存在,则通过
oc create route passthrough
命令创建路由,将 registry 指定为路由的服务。默认情况下,创建的路由的名称与服务名称相同:获取 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
创建路由:
$ oc create route passthrough \ --service=docker-registry \1 --hostname=<host> route "docker-registry" created 2
接下来,您必须信任主机系统上用于 registry 的证书,以允许主机推送和拉取镜像。引用的证书是在保护 registry 时创建的。
$ sudo mkdir -p /etc/docker/certs.d/<host> $ sudo cp <ca_certificate_file> /etc/docker/certs.d/<host> $ sudo systemctl restart docker
使用保护 registry 的信息,登录到 registry。但是,这一次指向路由中使用的主机名,而不是您的服务 IP。登录到安全且公开的 registry 时,请确保在
docker login
命令中指定 registry:# docker login -e user@company.com \ -u f83j5h6 \ -p Ju1PeM47R0B92Lk3AZp-bWJSck2F7aGCiZ66aFGZrs2 \ <host>
现在,您可以使用路由主机标记和推送镜像。例如,要在名为
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
注意您的镜像流将具有 registry 服务的 IP 地址和端口,而不是路由名称和端口。详情请参阅
oc get imagestreams
。
2.4.4. 手动公开 Non-Secure Registry
对于非生产环境的 OpenShift Container Platform,可以公开一个非安全的 registry,而不必通过安全 registry 来公开 registry。这允许您使用一个外部路由到 registry,而无需使用 SSL 证书。
为外部访问非安全的 registry 只适用于非生产环境。
公开一个非安全的 registry:
公开 registry:
# oc expose service docker-registry --hostname=<hostname> -n default
这会创建以下 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: {}
验证路由是否已创建成功:
# oc get route NAME HOST/PORT PATH SERVICE LABELS INSECURE POLICY TLS TERMINATION docker-registry registry.example.com docker-registry docker-registry=default
检查 registry 的健康状况:
$ curl -v http://registry.example.com/healthz
预期为 HTTP 200/OK 消息。
公开 registry 后,通过将端口号添加到
OPTIONS
条目来更新您的 /etc/sysconfig/docker 文件。例如:OPTIONS='--selinux-enabled --insecure-registry=172.30.0.0/16 --insecure-registry registry.example.com:80'
重要上面的选项应该添加到您要从其登录的客户端上。
此外,确保 Docker 在客户端上运行。
登录到非安全且公开的 registry 时,请确保在 docker login
命令中指定 registry。例如:
# docker login -e user@company.com \ -u f83j5h6 \ -p Ju1PeM47R0B92Lk3AZp-bWJSck2F7aGCiZ66aFGZrs2 \ <host>
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 地址。
记录该服务的
clusterIP
:$ oc get svc/docker-registry -o yaml | grep clusterIP:
删除服务:
$ oc delete svc/docker-registry dc/docker-registry
在 registry.yaml 中创建 registry 定义,将
<options>
替换为非生产环境使用部分中说明的第 3 步中使用的 :$ oc adm registry <options> -o yaml > registry.yaml
-
编辑 registry.yaml,找到
Service
,并将其clusterIP
更改为第 1 步中记录的地址。 使用修改后的 registry.yaml 创建 registry:
$ oc create -f registry.yaml
- 重启 Master
- 如果您无法重新使用 IP 地址,则任何使用包含旧 IP 地址的 pull specification 的操作都将失败。要最小化集群中断,您必须重启 master:
# master-restart api # master-restart controllers
这样可确保从缓存中清除包括旧 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 搜索列表:
编辑 /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']
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
registry 本身必须使用相同的内部主机名值进行配置。这可以通过在 registry 署配置中设置 REGISTRY_OPENSHIFT_SERVER_ADDR
环境变量或设置 registry 配置的 OpenShift 部分中的值来完成。
如果您已经为 registry 启用了 TLS,服务器证书必须包含您希望引用 registry 的主机名。有关添加主机名到服务器证书的说明,请参阅保护registry。
2.5.4. 覆盖 Registry 配置
您可以使用自己的自定义配置覆盖集成 registry 的默认配置,默认覆盖正在运行的 registry 容器中的 /config.yml 中的默认配置。
此文件中的上游配置选项也可使用环境变量覆盖。middleware 部分是一个例外,因为只有几个选项可以使用环境变量覆盖。了解如何覆盖特定的配置选项。
要启用对 registry 配置文件的管理,并使用 ConfigMap
部署更新的配置:
- 部署 registry。
根据需要在本地编辑 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>
创建一个
ConfigMap
,包含此目录中每个文件的内容:$ oc create configmap registry-config \ --from-file=</path/to/custom/registry/config.yml>/
将 registry-config ConfigMap 作为卷添加到 registry 的部署配置中,以在 /etc/docker/registry/ 中挂载自定义配置文件:
$ oc set volume dc/docker-registry --add --type=configmap \ --configmap-name=registry-config -m /etc/docker/registry/
通过在 registry 的部署配置中添加以下环境变量来更新 registry,以引用上一步中的配置路径:
$ oc set env dc/docker-registry \ REGISTRY_CONFIGURATION_PATH=/etc/docker/registry/config.yml
这可以作为迭代过程执行,从而实现所需的配置。例如,在故障排除期间,可临时更新配置以将其置于 debug 模式。
更新现有配置:
此流程将覆盖当前部署的 registry 配置。
- 编辑本地 registry 配置文件 config.yml。
删除 registry-config configmap:
$ oc delete configmap registry-config
重新创建 configmap 以引用更新的配置文件:
$ oc create configmap registry-config\ --from-file=</path/to/custom/registry/config.yml>/
重新部署 registry 以读取更新的配置:
$ oc rollout latest docker-registry
在源代码控制存储库中维护配置文件。
2.5.5. registry 配置参考
上游 docker distribution 库中有许多配置选项。并非所有配置选项都受到支持或启用。覆盖 registry 配置时,请使用本节作为参考。
此文件中的上游配置选项也可使用环境变量覆盖。但是,middleware 部分可能无法使用环境变量覆盖。了解如何覆盖特定的配置选项。
2.5.5.1. Log
例如:
log: level: debug formatter: text fields: service: registry environment: staging
2.5.5.2. Hook
不支持邮件 hook。
2.5.5.3. 存储
本节列出了支持的 registry 存储驱动程序。如需更多信息,请参阅容器镜像 registry 文档。
以下列表包括在 registry 配置文件中需要配置的存储驱动程序:
- 文件系统。文件系统是默认设置,不需要进行配置。
- S3.如需更多信息,请参阅 CloudFront 配置 文档。
- OpenStack Swift
- Google Cloud Storage(GCS)
- Microsoft Azure
- Aliyun OSS
支持常规 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
- 1
- 此条目对于镜像修剪正常工作是必需的。
2.5.5.4. Auth
不应更改 Auth 选项。openshift 扩展是唯一支持的选项。
auth: openshift: realm: openshift
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
- 1 2 9
- 这些条目是必需的。其存在可确保加载所需的组件。这些值不应更改。
- 3
- 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
验证 region
和 regionendpoint
字段本身是否一致。否则,集成的 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
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
- 1
- 此配置选项可以被布尔值环境变量
REGISTRY_MIDDLEWARE_REPOSITORY_OPENSHIFT_ACCEPTSCHEMA2
覆盖,允许在清单放置请求时接受清单架构 v2。可识别的值为true
和false
(适用于以下所有其他布尔值变量)。 - 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/{}
此 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 客户端支持 schema1 和 schema2。默认情况下,如果支持较新的架构,它会将后者推送到 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
- 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
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
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 会主动缓存数据,以减少对减慢外部资源的调用数量。有两个缓存:
- 用于缓存 Blob 元数据的存储缓存。此缓存没有过期时间,数据会一直存在,直到显式删除为止。
- 应用缓存包含 blob 和存储库之间的关联。此缓存中的数据具有过期时间。
要完全关闭缓存,您需要更改配置:
version: 0.1 log: level: debug http: addr: :5000 storage: cache: blobdescriptor: "" 1 openshift: version: 1.0 cache: disabled: true 2 blobrepositoryttl: 10m
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 部署扩展到多个副本。检查构建器容器集日志中的超时。
2.6.3. 使用共享 NFS 卷扩展 registry 的镜像推送错误
当将扩展的 registry 与共享 NFS 卷搭配使用时,您可能会在推送镜像的过程中看到以下错误之一:
-
digest invalid: provided digest did not match uploaded content
-
blob upload unknown
-
blob upload invalid
当 Docker 尝试推送镜像时,内部 registry 服务将返回这些错误。其原因源自于跨节点的文件属性同步。使用默认循环负载平衡配置推送镜像时可能会出现的错误,如 NFS 客户端缓存、网络延迟和层大小等因素。
您可以执行以下步骤来最大程度减少此类故障的可能性:
确保 docker-registry 服务的
sessionAffinity
设置为ClientIP
:$ oc get svc/docker-registry --template='{{.spec.sessionAffinity}}'
这应该会返回
ClientIP
,这是 OpenShift Container Platform 近期版本中的默认设置。如果没有,请修改它:$ oc patch svc/docker-registry -p '{"spec":{"sessionAffinity": "ClientIP"}}'
-
确保 NFS 服务器上的 registry 卷的 NFS 导出行列出
no_wdelay
选项。no_wdelay
选项可防止服务器延迟写入,这极大提高了读写一致性,这是 Registry 的一项要求。
测试显示,使用 RHEL NFS 服务器作为容器镜像 registry 的存储后端会出现问题。这包括 OpenShift Container Registry 和 Quay。因此,不建议使用 RHEL NFS 服务器来备份核心服务使用的 PV。
市场上的其他 NFS 实现可能没有这些问题。如需了解更多与此问题相关的信息,请联络相关的 NFS 厂商。
2.6.4. 使用 "not found" 错误来拉取内部管理的镜像故障
当拉取镜像推送到不同于从中拉取的镜像流时,会发生此错误。这是因为将构建的镜像重新标记到任意镜像流中:
$ oc tag srcimagestream:latest anyproject/pullimagestream:latest
然后,使用如下镜像引用从中提取:
internal.registry.url:5000/anyproject/pullimagestream:latest
在手动 Docker 拉取过程中,这会导致类似的错误:
Error: image anyproject/pullimagestream:latest not found
为防止这种情况,请完全避免标记内部管理的镜像,或者 手动 将构建的镜像重新推送到所需的命名空间。
2.6.5. S3 Storage 上带有 "500 Internal Server Error"的镜像 Push Fails
当 registry 在 S3 存储后端上运行时,会报告问题。推送到容器镜像 registry 有时会失败,并显示以下错误:
Received unexpected HTTP status: 500 Internal Server Error
要进行调试,您需要 查看 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
如果您看到此类错误,请联系您的 Amazon S3 支持。您所在地区或您的特定存储桶可能有问题。
2.6.6. 镜像修剪失败
如果您在修剪镜像时遇到以下错误:
BLOB sha256:49638d540b2b62f3b01c388e9d8134c55493b1fa659ed84e97cb59b87a6b8e6c error deleting blob
您的 registry 日志 包含以下信息:
error deleting blob \"sha256:49638d540b2b62f3b01c388e9d8134c55493b1fa659ed84e97cb59b87a6b8e6c\": operation unsupported
这意味着您的 自定义配置文件 缺少 storage 部分中的强制条目,即 storage:delete:enabled
设置为 true。添加它们,重新部署 registry,再重复您的镜像修剪操作。
第 3 章 设置路由器
3.1. 路由器概述
3.1.1. 关于路由器
可以通过多种方式使 流量进入集群。最常见的方法是使用 OpenShift Container Platform router 作为 OpenShift Container Platform 安装中 services 的外部流量入口点。
OpenShift Container Platform 提供和支持以下路由器插件:
- HAProxy 模板路由器是默认的插件。它使用 openshift3/ose-haproxy-router 镜像和 OpenShift Container Platform 上的容器内的模板路由器插件运行 HAProxy 实例。它目前支持通过 SNI 的 HTTP(S)流量和启用 TLS 的流量。路由器的容器侦听主机网络接口,这与大多数仅侦听私有 IP 的容器不同。路由器将路由名称的外部请求代理到与路由关联的服务标识的实际 pod 的 IP。
- F5 路由器 可与您环境中的现有 F5 BIG-IP® 系统集成,以同步路由。需要 F5 BIG-IP® 版本 11.4 或更高版本才能使用 F5 iControl REST API。
- 部署默认 HAProxy 路由器
- 部署自定义 HAProxy 路由器
- 将 HAProxy 路由器配置为使用 PROXY 协议
- 配置路由超时
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
服务帐户就位后,您可以继续安装默认的 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 地址将运行路由器以及路由器将处理的流量。路由器通过使用 节点选择器 部署到特定的节点上。
使用 oc adm router
创建的路由器 pod 具有默认的资源请求,节点必须满足这些请求才能部署路由器 pod。为提高基础架构组件的可靠性,默认资源请求用于在不使用资源请求的情况下增加 pod 以上的路由器容器集的 QoS 层。默认值表示部署基本路由器所需的已观察到最少资源,可以在路由器部署配置中编辑,并且您可能希望根据路由器负载来增加这些资源。
3.2.2. 创建路由器
如果路由器不存在,请运行以下命令来创建路由器:
$ oc adm router <router_name> --replicas=<number> --service-account=router --extended-logging=true
除非创建 高可用性 配置,否则 --replicas
通常为 1
。
--extended-logging=true
配置路由器,将 HAProxy 生成的日志转发到 syslog 容器。
查找路由器的主机 IP 地址:
$ oc get po <router-pod> --template={{.status.hostIP}}
您还可以使用路由器分片来确保路由器被过滤到特定的命名空间或路由,或者在路由器创建后设置任何环境变量。本例中为每个分片创建一个路由器。
3.2.3. 其他基本路由器命令
- 检查默认路由器
- 名为 router 的默认路由器服务帐户会在集群安装过程中自动创建。验证此帐户是否已存在:
$ oc adm router --dry-run --service-account=router
- 查看默认路由器
- 查看创建的默认路由器会是什么样子:
$ oc adm router --dry-run -o yaml --service-account=router
- 将路由器配置为转发 HAProxy 日志
-
您可以将路由器配置为将 HAProxy 生成的日志转发到 rsyslog sidecar 容器。
--extended-logging=true
参数附加 syslog 容器将 HAProxy 日志转发到标准输出。
$ oc adm router --extended-logging=true
以下示例是使用 --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
使用以下命令查看 HAProxy 日志:
$ oc set env dc/test-router ROUTER_LOG_LEVEL=info 1 $ oc logs -f <pod-name> -c syslog 2
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
- 将路由器部署到标记的节点
- 将路由器部署到与指定 节点标签 匹配的任何节点上:
$ oc adm router <router_name> --replicas=<number> --selector=<label> \ --service-account=router
例如,如果要创建一个名为 router
的路由器,并将其放置到带有 node-role.kubernetes.io/infra=true
标签的节点上:
$ oc adm router router --replicas=1 --selector='node-role.kubernetes.io/infra=true' \ --service-account=router
在集群安装过程中,openshift_router_selector
和 openshift_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
例如:
$ oc adm router region-west -o yaml --images=myrepo/somerouter:mytag \ --service-account=router
3.2.4. 过滤到特定路由器的路由
使用 ROUTE_LABELS
环境变量,您可以过滤路由,使其仅供特定路由器使用。
例如,如果您有多个路由器和 100 个路由,您可以将标签附加到路由,以便一部分标签由一个路由器处理,而其余则由另一个路由器处理。
创建路由器 后,使用
ROUTE_LABELS
环境变量标记路由器:$ oc set env dc/<router=name> ROUTE_LABELS="key=value"
将标签添加到所需路由中:
oc label route <route=name> key=value
要验证标签是否已附加到路由,请检查路由配置:
$ oc describe route/<route_name>
- 设置最大并发连接数
-
默认情况下,路由器可以处理最多 20000 连接。您可以根据需要更改该限制。由于连接太少,健康检查无法正常工作,从而导致不必要的重启。您需要配置系统,以支持最大连接数。
'sysctl fs.nr_open'
和'sysctl fs.file-max'
中显示的限值必须足够大。否则,HAproxy 将不会启动。
创建路由器时,--max-connections=
选项会设置所需的限制:
$ oc adm router --max-connections=10000 ....
编辑路由器部署配置中的 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
3.2.6. TLS 密码套件
在创建路由器时使用 --ciphers
选项设置路由器密码套件 :
$ oc adm router --ciphers=modern ....
值包括:modern
, intermediate
, 或 old
,intermediate
为默认值。或者,可以提供一组":"分隔的密码。密码必须来自以下集合:
$ openssl ciphers
或者,将 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 ....
--mutual-tls-auth
的值是 required
, optional
, 或 none
,none
是默认值。--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$' \ ....
--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 \ ....
启用 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_PORT
和 ROUTER_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
- 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
3.2.10. 使用多个路由器
管理员可以创建具有相同定义的多个路由器,为同一组路由提供服务。每个路由器将位于不同的节点,并且具有不同的 IP 地址。网络管理员需要获取到每个节点所需的流量。
可以分组多个路由器来在集群中分发路由负载,并将租户单独的租户分发到不同的路由器或 分片。组中的每个路由器或分片都根据路由器中的选择器接受路由。管理员可以使用 ROUTE_LABELS
在整个集群中创建分片。用户可以使用 NAMESPACE_LABELS
在命名空间(项目)上创建分片。
3.2.11. 在部署配置中添加 Node Selector
将特定路由器部署到特定的节点上需要两个步骤:
为所需节点添加 标签 :
$ oc label node 10.254.254.28 "router=first"
将节点选择器添加到路由器部署配置中:
$ oc edit dc <deploymentConfigName>
使用与标签对应的键和值添加
template.spec.nodeSelector
字段:... template: metadata: creationTimestamp: null labels: router: router1 spec: nodeSelector: 1 router: "first" ...
- 1
- 键和值分别是
router
和first
,对应于router=first
标签。
3.2.12. 使用路由器共享
路由器分片使用 NAMESPACE_LABELS
和 ROUTE_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. 路由器划分基于命名空间标签
使用命名空间标签选择器配置路由器:
$ oc set env dc/router NAMESPACE_LABELS="router=r1"
由于该路由器在命名空间上有一个选择器,因此路由器将仅处理匹配的命名空间的路由。要使此选择器与命名空间匹配,请相应地标记命名空间:
$ oc label namespace default "router=r1"
现在,如果您在 default 命名空间中创建路由,该路由位于默认路由器中:
$ oc create -f route1.yaml
创建新项目(命名空间)并创建路由
route2
:$ oc new-project p1 $ oc create -f route2.yaml
注意路由在路由器中不可用。
标签命名空间
p1
带有router=r1
$ oc label namespace p1 "router=r1"
添加此标签使路由在路由器中可用。
- 示例
一个路由器部署
finops-router
使用标签选择器NAMESPACE_LABELS="name in (finance, ops)"
配置,一个路由器部署dev-router
使用标签选择器NAMESPACE_LABELS="name=dev"
配置。如果所有路由都位于标有
name=finance
、name=ops
和name=dev 的命名空间
中,则此配置会在两个路由器部署之间有效分发您的路由。在上面的场景中,分片成为分区的一种特殊情况,没有重叠的子集。路由在路由器分片之间划分。
路由选择标准适用于路由的分布方式。有可能在路由器部署之间具有重叠的路由子集。
- 示例
除了上例中的
finops-router
和dev-router
外,您还有devops-router
,它使用标签选择器NAMESPACE_LABELS="name in (dev, ops)"
配置。标签为
name=dev
或name=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
这些标签表达了包括服务级别协议、地理位置、硬件要求和部门在内的概念。路由最多可在每列中有一个标签。有些路由可能具有其他标签,或者根本没有标签。
名称 | SLA | 地域 | HW | 部门 | 其他标签 |
---|---|---|---|---|---|
|
|
|
|
|
|
|
|
|
| ||
|
|
|
| ||
|
|
|
| ||
|
|
|
| ||
|
|
|
以下是一个便捷脚本 mkshard,它演示了如何一起使用 oc adm router
、oc set env
和 oc 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
运行 mkshard 几次创建多个路由器:
路由器 | 选择表达式 | Routes |
---|---|---|
|
|
|
|
|
|
|
|
|
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
在 modshard
中,如果 router-shard-<id>
部署策略 是 Rolling
,则不需要 oc scale
命令。
例如,将 router-shard-3
的部门扩展到包含 ops
和 dev
:
$ modshard 3 ROUTE_LABELS='dept in (dev, ops)'
结果是,router-shard-3
现在选择路由 g
— s
(g
— k
和 l
— s
的组合)。
本例考虑了本例中只有三个部门,并指定了一个部门离开分片,从而得到与上例相同的结果:
$ modshard 3 ROUTE_LABELS='dept != finance'
这个示例指定了三个用逗号分开的功能,并只选择路由 b
:
$ modshard 3 ROUTE_LABELS='hw=strong,type=dynamic,geo=west'
与涉及路由标签的 ROUTE_LABELS
类似,您可以使用 NAMESPACE_LABELS
环境变量根据路由命名空间的标签选择路由。本例修改 router-shard-3
以提供命名空间具有标签 frequency=weekly
的路由:
$ modshard 3 NAMESPACE_LABELS='frequency=weekly'
最后一个示例组合了 ROUTE_LABELS
和 NAMESPACE_LABELS
,以选择带有标签 sla=low
的路由,其命名空间具有标签 frequency=weekly
:
$ modshard 3 \ NAMESPACE_LABELS='frequency=weekly' \ ROUTE_LABELS='sla=low'
3.2.13. 查找路由器的主机名
在公开服务时,用户可以使用来自外部用户用于访问应用的 DNS 名称相同的路由。外部网络的网络管理员必须确保主机名解析为已接受该路由的路由器的名称。用户可以使用指向此主机名的 CNAME 设置 DNS。但是,用户可能不知道路由器的主机名。当不知道时,集群管理员可以提供它。
在创建路由器时,集群管理员可以使用 --router-canonical-hostname
选项和路由器的规范主机名。例如:
# oc adm router myrouter --router-canonical-hostname="rtr.example.com"
这会在包含路由器主机名的路由器部署配置中创建 ROUTER_CANONICAL_HOSTNAME
环境变量。
对于已存在的路由器,集群管理员可以编辑路由器的部署配置,并添加 ROUTER_CANONICAL_HOSTNAME
环境变量:
spec: template: spec: containers: - env: - name: ROUTER_CANONICAL_HOSTNAME value: rtr.example.com
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
在可用时 oc describe
会包括主机名:
$ oc describe route/hello-route3 ... Requested Host: hello.in.mycloud.com exposed on router myroute (host rtr.example.com) 12 minutes ago
利用上述信息,用户可以要求 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
如果 master 正在运行,这个更改需要重启。
运行上述配置的 OpenShift Container Platform master 时,对于名为 no-route-hostname 的示例路由(没有主机名添加到命名空间 mynamespace)生成的主机名将是:
no-route-hostname-mynamespace.v3.openshift.test
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'
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
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
在这里您可以使用 --default-cert
标志:
$ oc adm router --default-cert=cloudapps.router.pem --service-account=router
浏览器只考虑一个级别深度的子域有效通配符。因此在此示例中,证书对 a.cloudapps.example.com 有效,但不适用于 a.b.cloudapps.example.com。
3.2.17. 手动重新部署证书
手动重新部署路由器证书:
检查包含默认路由器证书的 secret 是否已添加到路由器中:
$ oc set volume dc/router deploymentconfigs/router secret/router-certs as server-certificate mounted at /etc/pki/tls/private
如果添加了证书,请跳过以下步骤并覆盖 secret。
确保为以下变量
DEFAULT_CERTIFICATE_DIR
设置了一个默认证书目录:$ oc set env dc/router --list DEFAULT_CERTIFICATE_DIR=/etc/pki/tls/private
如果没有,请使用以下命令创建该目录:
$ oc set env dc/router DEFAULT_CERTIFICATE_DIR=/etc/pki/tls/private
将证书导出到 PEM 格式:
$ cat custom-router.key custom-router.crt custom-ca.crt > custom-router.crt
覆盖或创建路由器证书 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 -
要创建新 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
部署路由器。
$ oc rollout latest dc/router
3.2.18. 使用安全路由
目前,不支持密码保护的密钥文件。启动后,HAProxy 会提示输入密码,且无法自动执行此过程。要从密钥文件中删除密码短语,您可以运行以下命令:
# openssl rsa -in <passwordProtectedKey.key> -out <new.key>
以下是如何在流量代理到目的地之前使用发生在路由器上发生 TLS 终止的安全边缘终止路由的示例:安全边缘终止路由指定 TLS 证书和密钥信息。TLS 证书由路由器前端提供。
首先,启动一个路由器实例:
# oc adm router --replicas=1 --service-account=router
接下来,为我们边缘安全路由创建私钥、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
使用上述证书和密钥生成路由。
$ oc create route edge --service=my-service \ --hostname=www.example.test \ --key=example-test.key --cert=example-test.crt route "my-service" created
看一下其定义。
$ 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-----
确保 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/
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
使用安全通配符边缘终止路由
这个示例反映了在流量代理到目的地之前在路由器上发生的 TLS 终止。发送到子域 example.org(
)中的任何主机的流量将代理到公开的服务。
*.
example.org
安全边缘终止路由指定 TLS 证书和密钥信息。TLS 证书由与子域(*.example.org
)匹配的所有主机的路由器前端提供。
启动路由器实例:
$ oc adm router --replicas=0 --service-account=router $ oc set env dc/router ROUTER_ALLOW_WILDCARD_ROUTES=true $ oc scale dc/router --replicas=1
为边缘安全路由创建私钥、证书签名请求(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
使用上述证书和密钥生成通配符路由:
$ 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
确保
*.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/
对于允许通配符路由的路由器(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
在以下示例中,允许通配符路由的路由器不允许 owner.example.test
或 aname.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
在以下示例中,允许通配符路由的路由器将允许 '\*.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.
在以下示例中,允许通配符路由的路由器不允许 '\*.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.
同样,当具有通配符路由的命名空间声明子域后,只有该命名空间中的路由才能声明同一子域中的任何主机。
在以下示例中,当命名空间 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
在以下示例中,显示了不同的场景,其中删除所有者路由并在命名空间内和跨命名空间传递所有权。虽然命名空间 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
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
在内部,这意味着路由器容器必须发布 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'
如果动态配置管理器无法动态配置 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。
流程
创建一个新项目
$ oc new-project namespace_name
创建新路由。此方法公开现有的服务:
$ oc create route edge edge_route_name --key=/path/to/key.pem \ --cert=/path/to/cert.pem --service=<service> --port=8443
标记路由:
$ oc label route edge_route_name type=route_label_1
创建与路由对象定义不同的路由 :所有都具有标签
type=route_label_1
:$ oc create -f reencrypt-blueprint.yaml $ oc create -f annotated-edge-blueprint.yaml $ oc create -f annotated-unsecured-blueprint.json
您还可以从路由中删除标签,这会阻止它用作蓝图路由。例如,防止
annotated-unsecured-blueprint
用作蓝图路由:$ oc label route annotated-unsecured-blueprint type-
创建用于蓝图池的新路由器:
$ oc adm router
为新路由器设置环境变量:
$ oc set env dc/router ROUTER_HAPROXY_CONFIG_MANAGER=true \ ROUTER_BLUEPRINT_ROUTE_NAMESPACE=namespace_name \ ROUTER_BLUEPRINT_ROUTE_LABELS="type=route_label_1"
处理命名空间或带有
type=route_label_1
标签的项目namespace_name
中的所有路由,并用作自定义蓝图。请注意,您还可以通过管理该命名空间
namespace_name
中的路由来添加、更新或删除蓝图。动态配置管理器会监视命名空间namespace_name
中路由的更改,类似于路由器监视路由
和服务
的方式。预分配的路由和后端服务器的池大小可以通过
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
这个示例将每个蓝图路由的池大小增加到
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
要提取 Prometheus 格式的原始统计信息,请运行以下命令:
curl <user>:<password>@<router_IP>:<STATS_PORT>
例如:
$ curl admin:sLzdR6SgDJ@10.254.254.35:1936/metrics
您可以获取访问路由器服务注解中的指标所需的信息:
$ 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
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 ...
在浏览器中获取指标:
从路由器部署配置文件中删除以下 环境变量 :
$ oc edit dc router - name: ROUTER_LISTEN_ADDR value: 0.0.0.0:1936 - name: ROUTER_METRICS_TYPE value: haproxy
对路由器就绪度探测进行补丁,以使用与存活度探测相同的路径,它现在由 haproxy 路由器提供:
$ oc patch dc router -p '"spec": {"template": {"spec": {"containers": [{"name": "router","readinessProbe": {"httpGet": {"path": "/healthz"}}}]}}}'
在浏览器中使用以下 URL 启动 stats 窗口,其中
STATS_PORT
值默认为1936
:http://admin:<Password>@<router_IP>:<STATS_PORT>
您可以通过在 URL 中添加
;csv
来获得 CSV 格式的统计信息:例如:
http://admin:<Password>@<router_IP>:1936;csv
获取路由器 IP、管理员名称和密码:
oc describe pod <router_pod>
禁止指标收集:
$ oc adm router --service-account=router --stats-port=0
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
当出现这个问题时,oc
命令可能会因为以下错误开始失败:
Unable to connect to the server: dial tcp: lookup <hostname> on <ip>:<port>: write udp <ip>:<port>-><ip>:<port>: write: invalid argument
要验证 IPv4 的 ARP 条目的实际数量,请运行以下内容:
# ip -4 neigh show nud all | wc -l
如果数字开始接近 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
以下 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
要使这些设置永久生效,请查看本文档。
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
- 1
- 超时 http-request 设置为 5 秒。HAProxy 为客户端 5 秒提供 * 以发送其整个 HTTP 请求。否则,HAProxy 会关闭连接并显示 *an 错误。
另外,当设置环境变量 ROUTER_SLOWLORIS_TIMEOUT
时,它会限制客户端发送整个 HTTP 请求所需的时间。否则,HAProxy 将关闭连接。
通过设置 环境变量,可以将信息捕获为路由器部署配置的一部分,不需要手动修改模板,而手动添加 HAProxy 设置要求您重新构建路由器 Pod 和维护路由器模板文件。
使用注解在 HAProxy 模板路由器中实施基本的 DDoS 保护,包括限制以下功能:
- 并发 TCP 连接数
- 客户端可以请求 TCP 连接的速率
- 可以发出 HTTP 请求的速率
这些是在每个路由上启用的,因为应用可能有完全不同的流量模式。
设置 | 描述 |
---|---|
| 启用设置(例如,设置为 true )。 |
| 此路由上相同 IP 地址可执行的并发 TCP 连接数。 |
| 客户端 IP 可以打开的 TCP 连接数。 |
| 客户端 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
另外,您可以登录到运行路由器的节点:
# docker run --rm --interactive=true --tty --entrypoint=cat \ registry.redhat.io/openshift3/ose-haproxy-router:v{product-version} haproxy-config.template
镜像名称来自容器镜像。
将此内容保存到文件中,以用作自定义模板的基础。保存的 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}}
功能 | 含义 |
---|---|
| 返回有效端点列表。当操作为"shuffle"时,端点的顺序是随机的。 |
| 尝试从容器集获取 named 环境变量。如果未定义或为空,它将返回可选的第二个参数。否则,它将返回空字符串。 |
| 第一个参数是包含正则表达式的字符串,第二个参数是要测试的变量。返回一个布尔值,指示作为第一个参数提供的正则表达式是否与作为第二个参数提供的字符串匹配。 |
| 确定给定变量是否为整数。 |
| 将给定字符串与允许字符串的列表进行比较。通过列表向右返回第一个匹配扫描. |
| 将给定字符串与允许字符串的列表进行比较。如果字符串为允许的值,则返回 "true",否则返回 false。 |
| 生成与路由主机(和路径)匹配的正则表达式。第一个参数是主机名,第二个参数是路径,第三个参数是通配符布尔值。 |
| 生成用于服务/匹配证书的主机名。第一个参数是主机名,第二个参数是通配符布尔值。 |
| 确定给定变量是否包含"true"。 |
这些功能由 HAProxy 模板路由器插件提供。
3.3.3.3. 路由器提供的信息
本节回顾路由器在模板中提供的 OpenShift Container Platform 信息。路由器配置参数是 HAProxy 路由器插件提供的一组数据。这些字段可由 (dot).Fieldname
访问。
路由器配置参数下方的表格根据各种字段的定义展开。特别是 .State 拥有一组可接受的路由。
字段 | 类型 | 描述 |
---|---|---|
| 字符串 | 文件要写入的目录,默认为 /var/lib/containers/router |
|
| 路由。 |
|
| 服务查找。 |
| 字符串 | 以 pem 格式到默认证书的完整路径名称。 |
|
| 对等。 |
| 字符串 | 公开统计数据的用户名(如果模板支持)。 |
| 字符串 | 公开统计数据的密码(如果模板支持)。 |
| int | 公开统计信息的端口(如果模板支持)。 |
| bool | 路由器是否应绑定默认端口。 |
字段 | 类型 | 描述 |
---|---|---|
| 字符串 | 路由特定于用户的名称。 |
| 字符串 | 路由的命名空间。 |
| 字符串 |
主机名。例如: |
| 字符串 |
可选路径。例如: |
|
| 此后端的终止策略;驱动映射文件和路由器配置。 |
|
| 用于保护此后端的证书。按证书 ID 的键。 |
|
| 指明需要永久保留的配置状态。 |
| 字符串 | 指明用户要公开的端口。如果为空,将为服务选择一个端口。 |
|
|
指明到边缘终端路由的不安全连接所需的行为: |
| 字符串 | 用于模糊 cookie ID 的路由 + 命名空间名称的哈希值。 |
| bool | 表示此服务单元需要通配符支持。 |
|
| 附加到此路由的注解。 |
|
| 支持此路由的服务集合,按服务名称键,并根据映射中其他条目的权重加上相应的权重。 |
| int |
权重为非零的 |
ServiceAliasConfig
是服务的路由。由主机 + 路径唯一标识指定。默认模板使用 {{range $cfgIdx、$cfg := .State }}
迭代路由。在这样的 {{range}}
块中,模板可以使用 $cfg.Field
引用当前 ServiceAliasConfig
的任何字段。
字段 | 类型 | 描述 |
---|---|---|
| 字符串 |
对应于服务名称 + namespace 的名称。由 |
|
| 支持该服务的端点。这转换为路由器的最终后端实施。 |
ServiceUnit
是一种服务封装、支持该服务的端点,以及指向服务的路由。这是驱动创建路由器配置文件的数据
字段 | 类型 |
---|---|
| 字符串 |
| 字符串 |
| 字符串 |
| 字符串 |
| 字符串 |
| 字符串 |
| bool |
Endpoint
是 Kubernetes 端点的内部表示。
字段 | 类型 | 描述 |
---|---|---|
| 字符串 |
代表一个公钥/私钥对。它通过 ID 来标识,该 ID 将成为文件名。CA 证书将不会设置 |
| 字符串 | 表示此配置所需的文件已持久保存到磁盘。有效值:"saved", ""。 |
字段 | 类型 | 描述 |
---|---|---|
ID | 字符串 | |
内容 | 字符串 | 证书。 |
PrivateKey | 字符串 | 私钥。 |
字段 | 类型 | 描述 |
---|---|---|
| 字符串 | 指定安全通信将停止的位置。 |
| 字符串 | 表示路由不安全连接所需的行为。虽然每个路由器可能会对要公开的端口做出自己的决定,但通常这是端口 80。 |
TLSTerminationType
和 InsecureEdgeTerminationPolicyType
指定安全通信将停止的位置。
常数 | 值 | 含义 |
---|---|---|
|
| 终止边缘路由器上的加密。 |
|
| 目的地终止加密,目的地负责解密流量。 |
|
| 在边缘路由器中终止加密,并使用目的地提供的新证书重新加密。 |
类型 | 含义 |
---|---|
| 流量发送到不安全端口(默认)上的服务器。 |
| 不安全的端口不允许流量。 |
| 客户端重定向到安全端口。 |
None (""
) 与 Disable
相同。
3.3.3.4. 注解
每个路由都可以附加注解。每个注释仅是一个名称和一个值。
apiVersion: v1 kind: Route metadata: annotations: haproxy.router.openshift.io/timeout: 5500ms [...]
名称可以是与现有 Annotations 没有冲突的任何内容。值是任意字符串。字符串可以具有多个令牌,用空格分开。例如,aa bb cc
.该模板使用 {{index}}
来提取注释的值。例如:
{{$balanceAlgo := index $cfg.Annotations "haproxy.router.openshift.io/balance"}}
这是如何将其用于相互客户端授权的示例。
{{ 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 }}
然后,您可以使用此命令处理列入白名单的 CN。
$ oc annotate route <route-name> --overwrite whiteListCertCommonName="CN1 CN2 CN3"
如需更多信息,请参阅特定于路由的注解。
3.3.3.5. 环境变量
该模板可以使用路由器 pod 中存在的任何环境变量。环境变量可以在部署配置中设置。可以添加新的环境变量。
它们由 env
函数引用:
{{env "ROUTER_MAX_CONNECTIONS" "20000"}}
第一个字符串是 变量,第二个字符串是变量缺失或 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. */}}
模板可以创建任意数量的输出文件。使用定义结构来创建输出文件。文件名指定为要定义的参数,定义块内直到匹配端的所有内容都会被写入为该文件的内容。
{{ define "/var/lib/haproxy/conf/haproxy.config" }} global {{ end }}
上方会将 global
复制到 /var/lib/haproxy/conf/haproxy.config 文件,然后关闭该文件。
根据环境变量设置日志记录。
{{ with (env "ROUTER_SYSLOG_ADDRESS" "") }} log {{.}} {{env "ROUTER_LOG_FACILITY" "local1"}} {{env "ROUTER_LOG_LEVEL" "warning"}} {{ end }}
env
函数提取环境变量的值。如果未定义环境变量或 nil
,则返回第二个参数。
通过,使用 将 块中的 "."(dot)值设置为作为使用 的参数提供的任何值。with
操作测试点为 nil
。如果没有 nil
,则会处理到最后
。在上面,假设 ROUTER_SYSLOG_ADDRESS
包含 /var/log/msg、ROUTER_LOG_FACILITY
未定义,并且 ROUTER_LOG_LEVEL
包含 info
。以下命令将复制到输出文件中:
log /var/log/msg local1 info
每个接受的路由最终都会在配置文件中生成行。使用 范围
来进入接受的路由:
{{ range $cfgIdx, $cfg := .State }} backend be_http_{{$cfgIdx}} {{end}}
.State
是 ServiceAliasConfig
的映射,其中键是路由名称. 范围
步骤通过映射,每个传递都使用 键
设置 $cfgIdx
,并将 $cfg
设置为指向描述路由的 ServiceAliasConfig
。如果有两个路由名为 myroute
和 heroute
,则上述命令会将以下内容复制到输出文件中:
backend be_http_myroute backend be_http_hisroute
Route Annotations、$cfg.Annotations
也是注解名称作为键的映射,内容字符串作为值。路由可以根据需要拥有更多注解,其使用由模板作者定义。用户将注解代码到路由中,模板作者则自定义 HAProxy 模板来处理注解。
常见用法是索引注解以获取值。
{{$balanceAlgo := index $cfg.Annotations "haproxy.router.openshift.io/balance"}}
索引提取给定注解的值(若有)。因此,$balanceAlgo
将包含与注解或 nil
关联的字符串。如上所示,您可以测试非空字符串
,并使用 with
结构对其执行操作。
{{ with $balanceAlgo }} balance $balanceAlgo {{ end }}
此处,如果 $balanceAlgo
不是 nil
,平衡 $balanceAlgo
将复制到输出文件中。
在第二个示例中,您想要根据注释中设置的超时值设置服务器超时。
$value := index $cfg.Annotations "haproxy.router.openshift.io/timeout"
现在 $value
会被评估,以确保它包含正确构建的字符串。matchPattern
函数接受正则表达式,如果参数满足表达式要求,则返回 true
。
matchPattern "[1-9][0-9]*(us\|ms\|s\|m\|h\|d)?" $value
这会接受 5000ms
,但不接受 7y
。结果可用于测试。
{{if (matchPattern "[1-9][0-9]*(us\|ms\|s\|m\|h\|d)?" $value) }} timeout server {{$value}} {{ end }}
它还可用于匹配令牌:
matchPattern "roundrobin|leastconn|source" $balanceAlgo
另外,也可以使用 matchValues
来匹配令牌:
matchValues $balanceAlgo "roundrobin" "leastconn" "source"
3.3.4. 使用 ConfigMap 替换路由器配置模板
您可以使用 ConfigMap 来自定义路由器实例,而无需重新构建路由器镜像。可以修改 haproxy-config.template、reload-haproxy 和其他脚本,以及创建和修改路由器环境变量。
- 复制您要修改的 haproxy-config.template,如上所述根据需要进行修改。
创建 ConfigMap:
$ oc create configmap customrouter --from-file=haproxy-config.template
customrouter
ConfigMap 现在包含修改后的 haproxy-config.template 文件的副本。修改路由器部署配置,将 ConfigMap 挂载为文件,并将
TEMPLATE_FILE
环境变量指向该文件。这可以通过oc set env
和oc 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
- 编辑路由器部署配置
使用
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 ...
保存更改并退出编辑器。这将重新启动路由器。
- 使用
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 }}
更改重新加载脚本
使用粘滞位时,您可以选择告知 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
- 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 }}
在修改后,您可以重建路由器。
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
您可以编辑或替换其中任何一个文件。但是,conf/haproxy-config.template 和 reload-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
要使用新路由器,请通过更改 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
将变量设置为 true
或 TRUE
以外的任何值,以禁用 PROXY 协议:
禁用 PROXY 协议
$ oc set env dc/router ROUTER_USE_PROXY_PROTOCOL=false
如果您在路由器中启用 PROXY 协议,则必须将路由器前面的负载均衡器配置为使用 PROXY 协议。以下是配置 Amazon Elastic Load Balancer(ELB)服务以使用 PROXY 协议的示例。本例假定 ELB 将端口 80(HTTP)、443(HTTPS)和 5000(镜像注册表)转发到一个或多个 EC2 实例上运行的路由器。
将 Amazon ELB 配置为使用 PROXY 协议
要简化后续步骤,首先设置一些 shell 变量:
$ lb='infra-lb' 1 $ instances=( 'i-079b4096c654f563c' ) 2 $ secgroups=( 'sg-e1760186' ) 3 $ subnets=( 'subnet-cf57c596' ) 4
接下来,使用适当的监听程序、安全组和子网创建 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" }
使用 ELB 注册路由器实例或实例:
$ aws elb register-instances-with-load-balancer --load-balancer-name "$lb" \ --instances $instances { "Instances": [ { "InstanceId": "i-079b4096c654f563c" } ] }
配置 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 } }
最后,创建一个启用了
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
验证配置
您可以按如下所示检查负载均衡器以验证配置是否正确:
$ 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 } ] ]
或者,如果您已经配置了 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'
验证协议更新
验证协议是否已更新,如下所示:
$ 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": []
}
]
]
- 1
- 所有监听器(包括 TCP 端口 80 的监听器)都应使用 TCP 协议。
然后,创建一个负载均衡器策略,并将其添加到 ELB 中,如上一步第 5 步所述。
第 4 章 部署 Red Hat CloudForms
4.1. 在 OpenShift Container Platform 上部署 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 时,需要做出两个主要决策:
- 您是否想要外部或容器化(也称为 podified)PostgreSQL 数据库?
- 哪个存储类将支持您的持久性卷(PV)?
对于第一个决定,您可以使用两种方式之一部署 Red Hat CloudForms,具体取决于 Red Hat CloudForms 使用的 PostgreSQL 数据库的位置:
Deployment Variant | 描述 |
---|---|
完全容器化 | 所有应用程序服务和 PostgreSQL 数据库都作为 pod 在 OpenShift Container Platform 上运行。 |
外部数据库 | 应用程序使用外部托管的 PostgreSQL 数据库服务器,所有其他服务则作为 pod 在 OpenShift Container Platform 上运行。 |
对于第二个决定,openshift-management 角色提供了覆盖许多默认部署参数的自定义选项。这包括以下存储类选项来支持 PV:
Storage class | 描述 |
---|---|
NFS(默认) | 本地,在集群上 |
NFS 外部 | NFS(如存储设备) |
云供应商 | 使用云供应商(Google Cloud Engine、Amazon Web Services 或 Microsoft Azure)的自动存储置备。 |
预配置(高级) | 假设您提前创建了所有内容 |
本指南的主题包括:在 OpenShift Container Platform 上运行 Red Hat CloudForms 的要求、可用配置变量的说明,以及在初始 OpenShift Container Platform 安装期间或置备集群之后运行安装程序的说明。
4.2. OpenShift Container Platform 上 Red Hat CloudForms 的要求
下表中列出了默认要求。可以通过 自定义模板参数 来覆盖它们。
如果无法满足这些要求,应用性能将会受到影响,甚至可能无法部署。
项 | 要求 | 描述 | 自定义参数 |
---|---|---|---|
应用程序内存 | ≥ 4.0 Gi | 应用程序所需的最小内存 |
|
应用程序存储 | ≥ 5.0 Gi | 应用程序所需的最小 PV 大小 |
|
PostgreSQL 内存 | ≥ 6.0 Gi | 数据库所需的最小内存 |
|
PostgreSQL 存储 | ≥ 15.0 Gi | 数据库所需的最小 PV 大小 |
|
集群主机 | ≥ 3 | 集群中的主机数量 | N/A |
满足这些要求:
- 您必须具有几个集群节点。
- 您的集群节点必须具有大量可用内存。
- 您必须有多个 GiB 的可用存储,无论是本地还是云供应商。
- 可以通过为模板参数提供覆盖值来更改 PV 大小。
4.3. 配置角色变量
4.3.1. 概述
以下小节描述了 Ansible 清单文件中可能使用的角色变量,用于控制 运行安装程序 时红帽 CloudForms 安装的行为。
4.3.2. 常规变量
变量 | 必填 | 默认 | 描述 |
---|---|---|---|
| 否 |
|
布尔值,设置为 |
| 是 |
|
要安装的红帽 CloudForms 的部署变体。为容器化数据库设置 |
| 否 |
| 红帽 CloudForms 安装的命名空间(项目) |
| 否 |
| 命名空间(项目)描述。 |
| 否 |
| 默认管理用户名。更改此值不会更改用户名;只有在您更改了名称并运行集成脚本(如 添加容器提供程序的脚本)时,才会更改此值。 |
| 否 |
| 默认管理密码。更改此值不会更改密码;只有在您更改了密码并且正在运行集成脚本(如用于 添加容器提供程序的脚本)时,才会更改此值。 |
4.3.3. 自定义模板参数
您可以使用 openshift_management_template_parameters
Ansible 角色变量来指定要在应用程序或 PV 模板中覆盖的任何模板参数。
例如,如果要降低 PostgreSQL pod 的内存要求,您可以设置以下内容:
openshift_management_template_parameters={'POSTGRESQL_MEM_REQ': '1Gi'}
处理红帽 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'}
- 1
- 将
openshift_management_app_template
参数设置为cfme-template-ext-db
。
4.3.5. 存储类变量
变量 | 必填 | 默认 | 描述 |
---|---|---|---|
| 否 |
|
要使用的存储类型。选项包括 |
| 否 |
|
如果您使用的是外部 NFS 服务器,如 NetApp 设备,则必须在此处设置主机名。如果没有使用外部 NFS,则该值保留为 |
| 否 |
| 如果您使用外部 NFS,则可以在此处将基本路径设置为导出位置。对于本地 NFS,如果您要更改用于本地 NFS 导出的默认路径,您还可以更改此值。 |
| 否 |
|
如果您的清单中没有 |
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. 运行安装程序
4.4.1. 在 OpenShift Container Platform 安装期间或之后部署 Red Hat CloudForms
您可以选择在初始 OpenShift Container Platform 安装过程中或置备集群后部署 Red Hat CloudForms:
确定在清单文件
[OSEv3:vars]
部分下的清单文件中将openshift_management_install_management
设置为true
:[OSEv3:vars] openshift_management_install_management=true
- 在清单文件中设置任何其他红帽 CloudForms 角色变量,如 配置角色变量 中所述。清单文件示例中提供了有助于执行此操作 的资源。
根据是否已置备 OpenShift Container Platform,选择要运行的 playbook:
- 如果要在安装 OpenShift Container Platform 集群的同时安装 Red Hat CloudForms,请调用标准 config.yml playbook,如 运行安装 Playbook 所述以开始 OpenShift Container Platform 集群和 Red Hat CloudForms 安装。
如果要在已置备的 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
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
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
如果外部 NFS 主机在不同的父目录下导出目录,如 /exports/hosted/prod,请添加以下额外变量:
openshift_management_storage_nfs_base_dir=/exports/hosted/prod
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'}
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'}
本例指示安装程序处理应用程序模板,参数 APPLICATION_MEM_REQ
设置为 3000Mi
,POSTGRESQL_MEM_REQ
设置为 1Gi
,ANSIBLE_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'}
确保您正在运行 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:
- 收集所需的身份验证 secret。
- 查找指向红帽 CloudForms 应用程序和集群 API 的公共路由。
- 发出 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
4.5.2. 多个容器供应商
除了提供 playbook 以将当前 OpenShift Container Platform 集群集成到 Red Hat CloudForms 部署中,此角色包含一个脚本,允许您在任何任意红帽 CloudForms 服务器中添加多个容器平台作为容器供应商。容器平台可以是 OpenShift Container Platform 或 OpenShift Origin。
在运行 playbook 时,使用多个提供程序脚本需要在 CLI 上手动配置和设置 EXTRA_VARS
参数。
4.5.2.1. 准备脚本
要准备多个供应商脚本,请完成以下手动配置:
- 复制 /usr/share/ansible/openshift-ansible/roles/openshift_management/files/examples/container_providers.yml 示例,如 /tmp/cp.yml。您将修改此文件。
-
如果您更改了红帽 CloudForms 名称或密码,请更新您复制的 container_providers.yml 文件中的
management_server
键中的hostname
、user和
password
参数。 填写您要添加为容器供应商的每个容器平台集群的
container_providers
键下的条目。必须配置以下参数:
-
auth_key
- 这是具有cluster-admin
权限的服务帐户的令牌。 -
hostname
- 这是指向集群 API 的主机名。每个容器提供程序必须具有唯一的主机名。 -
name -
这是要在红帽 CloudForms 服务器容器提供程序概览页面中显示的集群名称。这必须是唯一的。
提示从集群中获取
auth_key
bearer 令牌:$ oc serviceaccounts get-token -n management-infra management-admin
-
可选择性地配置以下参数:
-
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>
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
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
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
然后,您将:
- 从数据库 NFS 导出中删除数据。
运行:
$ oc delete postgresql-1-6w2t4
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-exporter 和 kube-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。
变量 | 描述 |
---|---|
|
如果为 |
|
每个 Prometheus 实例的持久性卷声明大小。只有在 |
|
每个 Alertmanager 实例的持久性卷声明大小。只有在 |
|
设置为所需的现有 节点选择器,以确保 pod 放置到具有特定标签的节点上。默认为 |
| 配置 Alertmanager。 |
|
启用 Prometheus 时间序列数据的持久性存储。默认将此变量设置为 |
|
启用 Alertmanager 通知和静默的持久性存储。默认将此变量设置为 |
|
如果启用了 |
|
如果启用了 |
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
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
可以使用 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>"
子路由仅匹配严重性为 critical
的警报,并使用名为 team-frontend-page
的接收器发送它们。如名称所示,对于关键警报,应传出某人。参阅 Alertmanager 配置来配置通过不同警报接收器发送警报。
5.3.1. 死人开关
OpenShift Container Platform Monitoring 附带了一个 死人开关,用于确保监控基础架构的可用性。
死人开关是始终触发的简单 Prometheus 警报规则。Alertmanager 持续向支持此功能的通知提供程序发送死人交换机的通知。这也可确保 Alertmanager 和通知提供程序之间的通信正常工作。
PagerDuty 支持这种机制,以在监控系统本身停机时发出警报。如需更多信息,请参阅下面的死人开关 PagerDuty。
5.3.2. 分组警报
在警报针对 Alertmanager 触发后,必须将其配置为了解如何在逻辑上分组它们。
在本例中,添加了一个新的路由来反映 frontend
团队的警报路由。
流程
添加新路由。可以在原始路由下添加多个路由,通常用于定义通知的接收方。以下示例使用匹配器来确保只使用来自服务
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
子路由仅匹配严重性为
critical
的警报,并使用名为team-frontend-page
的接收器发送它们。如名称所示,对于关键警报,应传出某人。
5.3.3. 死人开关 PagerDuty
PagerDuty 通过名为 死人开关 的集成来支持此机制。只需将 PagerDuty
配置添加到默认的 deadmanswitch 接收器
。使用上述流程添加此配置。
如果死人开关警报静默 15 分钟,将死人开关配置为页面运算符。使用默认的 Alertmanager 配置时,死人开关警报每五分钟重复一次。如果死人开关在 15 分钟后触发,这表明通知失败至少两次。
了解如何 为 PagerDuty 配置死人开关。
5.3.4. 警报规则
OpenShift Container Platform Cluster Monitoring 附带了以下默认配置的警报规则。目前无法添加自定义警报规则。
有些警报规则的名称相同。这是有意设计的。它们会警告同一事件,它们具有不同的阈值,或严重性不同。在禁止规则中,触发较高的严重性时会禁止较低严重性。
有关警报规则的详情,请查看配置文件。
警报 | 重要性 | 描述 |
---|---|---|
|
| Cluster Monitoring Operator 会出现 X% 错误。 |
|
| Alertmanager 已从 Prometheus 目标发现中消失。 |
|
| ClusterMonitoringOperator 已从 Prometheus 目标发现中消失。 |
|
| KubeAPI 已从 Prometheus 目标发现中消失。 |
|
| kubecontrollermanager 已从 Prometheus 目标发现中消失。 |
|
| kubescheduler 已从 Prometheus 目标发现中消失。 |
|
| kubeStateMetrics 已从 Prometheus 目标发现中消失。 |
|
| kubelet 已从 Prometheus 目标发现中消失。 |
|
| NodeExporter 已从 Prometheus 目标发现中消失。 |
|
| Prometheus 已从 Prometheus 目标发现中消失。 |
|
| PrometheusOperator 已从 Prometheus 目标发现中消失。 |
|
| Namespace/Pod (Container) 重启 times / second |
|
| Namespace/Pod 未就绪。 |
|
| 部署 Namespace/Deployment 生成不匹配 |
|
| 部署 Namespace/Deployment 副本不匹配 |
|
| StatefulSet Namespace/StatefulSet 副本不匹配 |
|
| StatefulSet Namespace/StatefulSet 生成不匹配 |
|
| 只有调度并准备好用于守护进程设置 Namespace/DaemonSet 的所需 pod 的 X% |
|
| 没有调度 daemonset Namespace/DaemonSet 的 pod。 |
|
| 许多 daemonset Namespace/DaemonSet 的 pod 在不应该运行的位置运行。 |
|
| CronJob Namespace/CronJob 需要 1h 以上才能完成。 |
|
| Job Namespaces/Job 需要超过 1h 的时间才能完成。 |
|
| Job Namespaces/Job 无法完成。 |
|
| Pod 上过量使用的 CPU 资源请求无法容忍节点失败。 |
|
| Pod 上过量使用的内存资源请求,无法容忍节点失败。 |
|
| 命名空间上过量使用的 CPU 资源请求配额。 |
|
| 命名空间上过量使用的内存资源请求配额。 |
|
| 命名空间 Namespace 中的 X% 的资源已使用。 |
|
| 命名空间 Namespace 中的 PersistentVolumeClaim 声明的持久性卷有 X% free。 |
|
| 根据最近的抽样,命名空间 Namespace 中的 PersistentVolumeClaim 声明的持久性卷应该在四天内填满。X 字节当前可用。 |
|
| 节点 已就绪一小时以上 |
|
| 运行 X 种不同版本的 Kubernetes 组件。 |
|
| Kubernetes API 服务器客户端的 'Job/Instance' 正在遇到 X% 错误。 |
|
| Kubernetes API 服务器客户端的 'Job/Instance' 正在遇到 X 错误/ sec'。 |
|
| kubelet 实例正在运行 X pod,接近 110。 |
|
| API 服务器具有 99% 的 Verb 资源 延迟 X 秒。 |
|
| API 服务器具有 99% 的 Verb 资源 延迟 X 秒。 |
|
| API 服务器针对 X% 的请求出错。 |
|
| API 服务器针对 X% 的请求出错。 |
|
| Kubernetes API 证书将在不到 7 天后过期。 |
|
| Kubernetes API 证书将在不到 1 天后过期。 |
|
|
Summary:配置不同步.描述:Alertmanager 集群 |
|
| Summary:Alertmanager 的配置重新加载失败。描述:重新加载 Alertmanager 的配置对于 Namespace/Pod 失败。 |
|
| Summary:目标已停机。描述:X% 的作业 目标为 down。 |
|
| Summary:通知 DeadMansSwitch.描述:这是一个 DeadMansSwitch,可确保整个 Alerting 管道正常工作。 |
|
| node-exporter Namespace/Pod 的设备设备在接下来 24 小时内完全运行。 |
|
| node-exporter Namespace/Pod 的设备设备在接下来 2 小时内完全运行。 |
|
| Summary:重新载入 Prometheus 配置失败。描述:为 Namespace/Pod 重新载入 Prometheus 配置失败 |
|
| Summary:Prometheus 的警报通知队列已满运行。描述:Prometheus 的警报通知队列已完全针对 Namespace/Pod 运行 |
|
| Summary:从 Prometheus 发送警报时出错。描述:将警报从 Prometheus Namespace/Pod 发送到 Alertmanager 时出错 |
|
| Summary:从 Prometheus 发送警报时出错。描述:将警报从 Prometheus Namespace/Pod 发送到 Alertmanager 时出错 |
|
| Summary:Prometheus 没有连接到任何 Alertmanager。描述:Prometheus Namespace/Pod 没有连接到任何 Alertmanager |
|
| Summary:Prometheus 在从磁盘重新载入数据块时遇到问题。描述:在过去四个小时内,实例中的作业有 X 重新加载失败。 |
|
| Summary:Prometheus 在压缩示例块时遇到问题。描述:实例的作业过去四小时内出现 X 紧凑故障。 |
|
| Summary:Prometheus write-ahead 日志已被损坏。描述:Instance 中的 作业 具有损坏的 write-ahead 日志(WAL)。 |
|
| Summary:Prometheus 不捕获示例。描述:Prometheus Namespace/Pod 不嵌套示例。 |
|
| Summary:Prometheus 有许多示例被拒绝。描述:Namespace/Pod 因为时间戳重复但不同的值而拒绝多个示例 |
|
| Etcd 集群 "Job": insufficient members (X). |
|
| Etcd 集群 "Job": member Instance 没有 leader。 |
|
| Etcd 集群 "Job": 实例 Instance 在过去一小时内看到 X leader 改变。 |
|
| Etcd 集群 "Job":X% 的 GRPC_Method 请求在 etcd 实例 Instance 上失败。 |
|
| Etcd 集群 "Job":X% 的 GRPC_Method 请求在 etcd 实例 Instance 上失败。 |
|
| Etcd 集群 "Job": 到 GRPC_Method 的 gRPC 请求在 X_s on etcd instance _Instance。 |
|
| Etcd 集群 "Job": 成员与 To 通信正在 X_s on etcd instance _Instance。 |
|
| Etcd 集群 "Job":X 提议在 etcd 实例 Instance 的最后一小时内失败。 |
|
| Etcd 集群 "Job":99th percentile fync durations 是 X_s on etcd instance _Instance。 |
|
| Etcd 集群 "Job":99 percentile 的提交持续时间为 X_s on etcd instance _Instance。 |
|
| Job instance Instance 很快会耗尽其文件描述符 |
|
| Job instance Instance 很快会耗尽其文件描述符 |
5.4. 配置 etcd 监控
如果 etcd
服务没有正确运行,则整个 OpenShift Container Platform 集群的成功操作将处于危险之中。因此,最好为 etcd
配置监控。
按照以下步骤配置 etcd
监控 :
流程
验证监控堆栈是否正在运行:
$ 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
打开集群监控堆栈的配置文件:
$ oc -n openshift-monitoring edit configmap cluster-monitoring-config
在
config.yaml: |+
下,添加etcd
部分。如果在 master 节点上运行静态 pod 的
etcd
,您可以使用选择器指定etcd
节点:... data: config.yaml: |+ ... etcd: targets: selector: openshift.io/component: etcd openshift.io/control-plane: "true"
如果在单独的主机上运行
etcd
,则需要使用 IP 地址指定节点:... data: config.yaml: |+ ... etcd: targets: ips: - "127.0.0.1" - "127.0.0.2" - "127.0.0.3"
如果
etcd
节点的 IP 地址有变化,您必须更新此列表。
验证
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
- 1
etcd
服务监控器。
etcd
服务监控器最多可能需要一分钟才能启动。现在,您可以进入 Web 界面来查看有关
etcd
监控状态的更多信息。要获取 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
-
使用
https
,导航到为prometheus-k8s
列出的 URL。登录。
确保该用户属于
cluster-monitoring-view
角色。此角色提供查看集群监控 UI 的访问权限。例如,要将用户
developer
添加到cluster-monitoring-view
角色中,请运行:$ oc adm policy add-cluster-role-to-user cluster-monitoring-view developer
-
在 Web 界面中,以属于
cluster-monitoring-view
角色的用户身份登录。 单击 Status,然后单击 Targets。如果您看到
etcd
条目,则会监控etcd
。虽然
etcd
被监控,但 Prometheus 还无法通过etcd
进行身份验证,因此无法收集指标数据。针对
etcd
配置 Prometheus 身份验证:将
/etc/etcd/ca/ca.crt
和/etc/etcd/ca/ca.key
凭证文件从 master 节点复制到本地机器:$ ssh -i gcp-dev/ssh-privatekey cloud-user@35.237.54.213
创建包含以下内容的
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
生成
etcd.key
私钥文件:$ openssl genrsa -out etcd.key 2048
生成
etcd.csr
证书签名请求文件:$ openssl req -new -key etcd.key -out etcd.csr -subj "/CN=etcd" -config openssl.cnf
生成
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
将凭证置于 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
这会创建 etcd-cert-secret.yaml 文件
将凭证文件应用到集群:
$ oc apply -f etcd-cert-secret.yaml
现在您已配置了身份验证,请再次访问 Web 界面的 Targets 页面。验证
etcd
现在是否正确监控。可能需要几分钟后更改才会生效。如果您希望在更新 OpenShift Container Platform 时自动更新
etcd
监控,请将 Ansible 清单文件中的这个变量设置为true
:openshift_cluster_monitoring_operator_etcd_enabled=true
如果您在单独的主机上运行
etcd
,请按照 IP 地址使用此 Ansible 变量指定节点:openshift_cluster_monitoring_operator_etcd_hosts=[<address1>, <address2>, ...]
如果
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 的地址:
流程
运行以下命令:
$ 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
确保将
https://
添加到这些地址。您无法使用未加密的连接访问 Web UI。-
根据 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. 创建用户帐户
如果您是有权使用红帽产品的红帽客户,则拥有具有适用用户凭证的帐户。这些是您用于登录到红帽客户门户的用户名和密码。
如果您没有帐户,可以通过注册以下选项之一获取免费帐户:
6.1.2. 为 Red Hat Registry 创建服务帐户和身份验证令牌
如果您的组织管理共享帐户,则必须创建令牌。管理员可以创建、查看和删除与组织关联的所有令牌。
先决条件
- 用户凭证
流程
要创建令牌以完成 docker login
,请执行以下操作 :
-
导航到
registry.redhat.io
。 - 使用您的红帽网络(RHN)用户名和密码登录。
出现提示时接受条款.
- 如果未立即提示您接受条款,则在继续以下步骤时会提示您。
在 Registry Service Accounts 页面中点 Create Service Account
- 为服务帐户提供名称。它将带有一个随机字符串。
- 输入描述。
- 单击 create。
- 切回到您的服务帐户。
- 点您创建的服务帐户。
- 复制用户名,包括前缀字符串。
- 复制令牌。
6.1.3. 管理用于安装和升级的 registry 凭证
您还可以在安装过程中使用 Ansible 安装程序管理 registry 凭据。
这将设置以下内容:
-
OpenShift 命名空间中的
imagestreamsecret
。 - 所有节点上的凭据。
当您将 registry.redhat.io
的默认值用于 openshift_examples_registryurl
或 oreg_url
时,Ansible 安装程序将需要凭证。
先决条件
- 用户凭证
- 服务帐户
- 服务帐户令牌
流程
要在安装过程中使用 Ansible 安装程序管理 registry 凭证:
-
在安装或升级过程中,指定安装程序清单中的
oreg_auth_user
和oreg_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'}]
6.1.4. 在 Red Hat Registry 中使用服务帐户
在为 Red Hat Registry 创建服务帐户和生成的令牌后,您可以执行其他任务。
本节提供了手动步骤,可以通过提供 管理 registry Credentials for Installation 和 Upgrade 部分中概述的清单变量来自动执行这些步骤。
先决条件
- 用户凭证
- 服务帐户
- 服务帐户令牌
流程
在 Registry Service Accounts 页面中点击您的帐户名称。在这里,您可以执行以下任务:
- 在 Token Information 选项卡中,您可以查看您的用户名(您提供的带有随机字符串的名称)和密码(令牌)。在此选项卡中,您可以重新生成令牌。
在 OpenShift Secret 选项卡中,您可以:
- 单击选项卡中的链接,以下载该机密。
将 secret 提交到集群:
# oc create -f <account-name>-secret.yml --namespace=openshift
使用
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
在 Docker Login 选项卡中,您可以运行
docker login
。例如:# docker login -u='<numerical-string|account-name>' -p=<token>
成功登录后,将
~/.docker/config.json
复制到/var/lib/origin/.docker/config.json
,然后重新启动节点。# cp -r ~/.docker /var/lib/origin/ systemctl restart atomic-openshift-node
在 Docker Configuration 选项卡中,您可以:
- 单击选项卡中的链接,下载凭据配置。
通过将文件放入 Docker 配置目录中,将配置写入到磁盘。这将覆盖现有的凭据。例如:
# mv <account-name>-auth.json ~/.docker/config.json
第 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。
如果在 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 和清单文件进行集群安装,但您也可以使用其他管理工具,如 Puppet、Chef 或 Salt。
使用案例:将集群配置为使用 HTPasswd 身份验证
- 此用例假定您已为 playbook 中引用的所有节点设置了 SSH 密钥。
htpasswd
工具程序位于httpd-tools
软件包中:# yum install httpd-tools
修改 Ansible 清单并进行配置更改:
- 打开 ./hosts 清单文件。
在文件的
[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
对于 HTPasswd 身份验证,
openshift_master_identity_providers
变量启用身份验证类型。您可以使用 HTPasswd 配置三个不同的身份验证选项:-
如果主机上已配置了
/etc/origin/master/htpasswd,则仅指定
。openshift_master
_identity_providers -
指定
openshift_master_identity_providers
和openshift_master_htpasswd_file
将本地 htpasswd 文件复制到主机。 -
指定
openshift_master_identity_providers
和openshift_master_htpasswd_users
,以在主机上生成新的 htpasswd 文件。
由于 OpenShift Container Platform 需要哈希密码来配置 HTPasswd 身份验证,因此您可以使用
htpasswd
命令(如以下小结所述)为用户生成哈希密码,或使用用户和相关哈希密码创建平面文件。以下示例将身份验证方法从默认
拒绝所有
设置到htpasswd
,并使用指定的文件为jsmith
和blob 用户可以生成用户 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
-
如果主机上已配置了
重新运行 ansible playbook 以使这些修改生效:
$ ansible-playbook -b -i ./hosts ~/src/openshift-ansible/playbooks/deploy_cluster.yml
playbook 更新配置,并重启 OpenShift Container Platform master 服务以应用更改。
您现在已使用 Ansible 修改了 master 和节点配置文件,但这只是一个简单的用例。从此处您可以看到哪些 master 和 节点配置选项 公开给 Ansible,并自定义您自己的 Ansible 清单。
7.4.1. 使用 htpasswd
命令
要将 OpenShift Container Platform 集群配置为使用 HTPasswd 身份验证,您至少需要一个带有哈希密码的用户才能包含在 清单文件中。
您可以:
创建用户和散列密码:
运行以下命令来添加指定用户:
$ htpasswd -n <user_name>
注意您可以包含
-b
选项,用于在命令行中提供密码:$ htpasswd -nb <user_name> <password>
输入并确认用户的明文密码。
例如:
$ htpasswd -n myuser New password: Re-type new password: myuser:$apr1$vdW.cI3j$WSKIOzUPs6Q
该命令将生成散列版本的密码。
然后您可以在配置 HTPasswd 身份验证时使用哈希密码。hashed 密码是字符串,位于 :
后面。在上例中,请输入:
openshift_master_htpasswd_users={'myuser': '$apr1$wIwXkFLI$bAygtISk2eKGmqaJftB'}
创建带有用户名和散列密码的平面文件:
执行以下命令:
$ htpasswd -c /etc/origin/master/htpasswd <user_name>
注意您可以包含
-b
选项,用于在命令行中提供密码:$ htpasswd -c -b <user_name> <password>
输入并确认用户的明文密码。
例如:
htpasswd -c /etc/origin/master/htpasswd user1 New password: Re-type new password: Adding password for user user1
命令会生成一个文件,其中包含用户名以及用户密码的散列版本。
然后,您可以在配置 HTPasswd 身份验证时使用密码文件。
如需有关 htpasswd
命令的更多信息,请参阅 HTPasswd 身份提供程序。
7.5. 进行手动配置更改
使用案例:配置集群以使用 HTPasswd 身份验证
手动修改配置文件:
- 打开您要修改的配置文件,本例中为 /etc/origin/master/master-config.yaml 文件:
将以下新变量添加到文件的
identityProviders
小节中:oauthConfig: ... identityProviders: - name: my_htpasswd_provider challenge: true login: true mappingMethod: claim provider: apiVersion: v1 kind: HTPasswdPasswordIdentityProvider file: /etc/origin/master/htpasswd
- 保存您的更改并关闭该文件。
重启 master 以使更改生效:
# master-restart api # master-restart controllers
您现在已手动修改 master 和节点配置文件,但这只是一个简单的用例。在这里,您可以通过进行进一步的修改来查看所有 master 和节点配置选项,并进一步自定义自己的集群。
要修改集群中的节点,请根据需要更新节点配置映射。不要手动编辑 node-config.yaml 文件。
7.6. 主配置文件
本节介绍了 master-config.yaml 文件中提到的参数。
您可以 创建新的 master 配置文件 来查看已安装 OpenShift Container Platform 版本的有效选项。
每当修改 master-config.yaml 文件时,您必须重启 master 才能使更改生效。请参阅重启 OpenShift Container Platform 服务。
7.6.1. 准入控制配置
参数名称 | 描述 |
---|---|
| 包含 准入插件 配置。OpenShift Container Platform 具有可在创建或修改 API 对象时触发的准入控制器插件的可配置列表。此选项允许您覆盖默认插件列表;例如,禁用一些插件、添加其他插件、更改顺序以及指定配置。插件及其配置列表都可从 Ansible 控制。 |
|
键值对将直接传递给与 API 服务器的命令行参数匹配的 Kube API 服务器。它们不会被迁移,但如果您引用了不存在服务器的值,则不会启动。这些值可能会覆盖 apiServerArguments: event-ttl: - "15m" |
|
键值对将直接传递给与控制器管理器的命令行参数匹配的 Kube 控制器管理器。它们不会被迁移,但如果您引用了不存在服务器的值,则不会启动。这些值可能会覆盖 |
|
用于启用或禁用各种准入插件。当此类型作为 |
| 允许为每个准入插件指定配置文件。 |
| master 上将安装的准入插件名称列表。订购非常显著。如果为空,则使用默认插件列表。 |
|
键值对将直接传递给与调度程序的命令行参数匹配的 Kube 调度程序。它们不会被迁移,但如果您引用了不存在服务器的值,则不会启动。这些值可能会覆盖 |
7.6.2. 资产配置
参数名称 | 描述 |
---|---|
| 如果存在,则资产服务器会根据定义的参数启动。例如: 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 |
|
要使用其他主机名从 web 应用访问 API 服务器,您必须通过将配置字段中的 corsAllowedOrigins 指定 |
| 不应启动的功能列表。您可能想将其设置为 null。不太可能每个人都希望手动禁用功能,不建议这样做。 |
| 从子上下文下资产服务器文件系统提供服务的文件。 |
| 当设置为 true 时,告诉资产服务器为每个请求重新载入扩展脚本和样式表,而不是只在启动时使用。它使您可以开发扩展,无需每次更改重启服务器。 |
|
key-(string)和 value-(字符串)对,这些对将注入到全局变量 |
| Web 控制台加载时,资产服务器文件中的文件路径作为脚本加载。 |
| Web 控制台加载时,资产服务器上的文件路径以作为风格的表加载。 |
| 用于日志记录的公共端点(可选)。 |
| 在登出 Web 控制台后将 Web 浏览器重定向到的一个可选的绝对 URL。如果未指定,则会显示内置注销页面。 |
| Web 控制台如何访问 OpenShift Container Platform 服务器。 |
| 指标的公共端点(可选)。 |
| 资产服务器的 URL。 |
7.6.3. 认证和授权配置
参数名称 | 描述 |
---|---|
| 包含身份验证和授权配置选项。 |
| 指明应缓存多少个验证结果。如果为 0,则使用默认的缓存大小。 |
| 表示应缓存授权结果的时长。它接受有效的持续时间字符串(例如:"5m").如果为空,则获得默认超时。如果为 0 (例如"0m"), 禁用缓存。 |
7.6.4. Controller 配置
参数名称 | 描述 |
---|---|
|
应该启动的控制器列表。如果设置为 none,则不会自动启动任何控制器。默认值为 *,它将启动所有控制器。当使用 * 时,您可以通过在其名称前加上 |
|
启用控制器选择,指示 master 在控制器启动并在该值定义的秒数内尝试获取租期。将此值设置为非负值会强制 |
| 指示 master 不会自动启动控制器,而是等待接收通知到服务器,然后再启动它们。 |
7.6.5. etcd 配置
参数名称 | 描述 |
---|---|
| advertised host:port 用于客户端连接到 etcd。 |
| 包含有关如何连接到 etcd 的信息。指定 etcd 是否作为嵌入式或非嵌入运行,以及主机。其余的配置由 Ansible 清单处理。例如: etcdClientInfo: ca: ca.crt certFile: master.etcd-client.crt keyFile: master.etcd-client.key urls: - https://m1.aos.example.com:4001 |
| 如果存在,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 |
| 包含 API 资源如何在 etcd 中存储的信息。这些值只有在 etcd 是集群的后备存储时才相关。 |
| etcd 中的路径,Kubernetes 资源将在其下作为根(root) 。如果更改,这个值将意味着 etcd 中的现有对象将不再存在。默认值为 kubernetes.io。 |
| etcd 中的 Kubernetes 资源应该被序列化为的 API 版本。当从 etcd 读取的集群的所有客户端都有相应的代码才能读取新版本时,这个值不应该为高级。 |
| OpenShift Container Platform 资源根到的 etcd 中的路径。如果更改,这个值将意味着 etcd 中的现有对象将不再存在。默认值为 openshift.io。 |
| etcd 中 OS 资源的 API 版本应序列化为。当从 etcd 读取的集群的所有客户端都有相应的代码才能读取新版本时,这个值不应该为高级。 |
| 到 etcd 的对等点连接的广告 host:port。 |
| 描述如何开始为 etcd peer 提供服务。 |
| 描述如何开始服务。例如: servingInfo: bindAddress: 0.0.0.0:8443 bindNetwork: tcp4 certFile: master.server.crt clientCA: ca.crt keyFile: master.server.key maxRequestsInFlight: 500 requestTimeoutSeconds: 3600 |
| etcd 存储目录的路径。 |
7.6.6. 授权配置
参数名称 | 描述 |
---|---|
| 描述如何处理补贴。 |
| 自动批准客户端授权请求。 |
| 自动拒绝客户端授权请求。 |
| 提示用户批准新的客户端授权请求。 |
| 决定在 OAuth 客户端请求授权时使用的默认策略。只有特定的 OAuth 客户端不提供自己策略,则使用这种方法。有效的授权处理方法有:
|
7.6.7. 镜像配置
参数名称 | 描述 |
---|---|
| 为系统组件构建的名称格式。 |
| 决定是否将从 registry 中拉取 latest 标签。 |
7.6.8. 镜像策略配置
参数名称 | 描述 |
---|---|
| 允许禁用镜像的调度后台导入。 |
| 控制用户执行 Docker 存储库批量导入时导入的镜像数量。此数字默认为 5,以防止用户意外导入大量镜像。设置 -1 代表没有限制。 |
| 每分钟将在后台导入的最大调度镜像流数。默认值为 60。 |
| 针对上游存储库检查调度后台导入的镜像流时可达最少的秒数。默认值为 15 分钟。 |
| 限制普通用户可从中导入镜像的 Docker docker。将此列表设置为您信任包含有效 Docker 镜像且希望应用程序能够从中导入的 registry。有权通过 API 创建镜像或 ImageStreamMappings 的用户不受此策略的影响 - 通常只有管理员或系统集成将具有这些权限。 |
| 指定到 PEM 编码文件的文件路径,它列出了在镜像流导入期间应被信任的额外证书颁发机构。此文件需要可以被 API 服务器进程访问。根据集群安装的方式,这可能需要将文件挂载到 API 服务器 pod 中。 |
|
设置默认内部镜像 registry 的主机名。该值必须采用 |
|
ExternalRegistryHostname 设置默认外部镜像 registry 的主机名。只有在镜像 registry 对外公开时才应设置外部主机名。该值用于 ImageStreams 中的 |
7.6.9. Kubernetes 的主配置
参数名称 | 描述 |
---|---|
| 应该在启动时启用的 API 级别的列表 v1 作为示例。 |
|
组映射到应禁用的版本(或 |
| 包含有关如何连接到 kubelet 的信息。 |
| 包含如何连接到 kubelet 的 KubernetesMasterConfig 的信息。如果存在,则使用此流程启动 kubernetes master。 |
| 应正在运行的预期 master 数量。这个值默认为 1,可以被设置为正整数,或者设置为 -1,这表示这是集群的一部分。 |
|
Kubernetes 资源的公共 IP 地址。如果为空,来自 |
| 描述如何将此节点连接到 master 的 .kubeconfig 文件的文件名。 |
|
控制删除失败节点上的 pod 的宽限期。它需要有效的持续时间字符串。如果为空,您会收到默认的 pod 驱除超时。默认值为 |
| 指定代理到 pod 时使用的客户端证书/密钥。例如: proxyClientInfo: certFile: master.proxy-client.crt keyFile: master.proxy-client.key |
| 用于分配主机上服务公共端口的范围。默认 30000-32767。 |
| 用于分配服务 IP 的子网。 |
| 静态已知的节点列表。 |
7.6.10. 网络配置
仔细选择以下参数中的 CIDR,因为 IPv4 地址空间由节点的所有用户共享。OpenShift Container Platform 为自己的使用保留 IPv4 地址空间中的 CIDR,并为外部用户和集群间共享的地址保留来自 IPv4 地址空间的 CIDR。
参数名称 | 描述 |
---|---|
| 指定全局覆盖网络的 L3 空间的 CIDR 字符串。这为集群网络的内部使用保留。 |
|
控制服务外部 IP 字段可接受哪些值。如果为空,则不能设置 |
| 分配给每一主机子网的位数。例如,8 表示主机上的 /24 网络。 |
|
控制为裸机上的类型为 LoadBalancer 的服务分配入口 IP 的范围。它可以包含从其中分配的一个 CIDR。默认情况下,配置了 |
| 分配给每一主机子网的位数。例如,8 表示主机上的 /24 网络。 |
| 传递给 compiled-in-network 的插件。此处的许多选项可以在 Ansible 清单中控制。
例如: 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 |
| 要使用的网络插件的名称。 |
| 用于指定服务网络的 CIDR 字符串。 |
7.6.11. OAuth 身份验证配置
参数名称 | 描述 |
---|---|
| 强制供应商选择页面,即使只有一个提供程序,也要呈现。 |
| 用于构建有效客户端重定向 URL 用于外部访问。 |
| 一个包含 go 模板的文件路径,用于在身份验证期间呈现错误页面,或授权流(如果没有指定),则会使用默认错误页面。 |
| 订购用户以识别自身的方式列表。 |
| 包含用来呈现登录页面的 go 模板的文件路径。如果未指定,则使用默认登录页面。 |
|
用于验证到 |
| 用于构建有效客户端重定向 URL 用于外部访问。 |
| 用于让服务器对服务器调用来交换访问令牌的授权代码。 |
| 如果存在,/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 |
| 允许自定义登录页面等页面。 |
| 包含用来呈现提供程序选择页面的 go 模板的文件路径。如果未指定,则使用默认供应商选择页面。 |
| 包含有关配置会话的信息。 |
| 允许您自定义登录页面等页面。 |
| 包含授权和访问令牌的选项。 |
7.6.12. 项目配置
参数名称 | 描述 |
---|---|
| 包含默认项目节点选择器。 |
| 包含有关项目创建和默认值的信息:
|
| 当用户无法通过项目请求 API 端点来请求项目时向用户显示的字符串。 |
| 响应 projectrequest 以创建项目时使用的模板。它采用 namespace/template 格式,它是可选的。如果没有指定,则使用默认模板。 |
7.6.13. 调度程序配置
参数名称 | 描述 |
---|---|
| 指向描述如何设置调度程序的文件。如果为空,您可以获得默认的调度规则 |
7.6.14. 安全分配器配置
参数名称 | 描述 |
---|---|
|
定义将分配给命名空间的 MCS 类别范围。格式为 |
| 控制为项目自动分配 UID 和 MCS 标签。如果为 nil,则禁用分配。 |
| 定义会自动分配给项目的 Unix 用户 ID(UID),以及每个命名空间获取的块的大小。例如,1000-1999/10 将根据每个命名空间分配十个 UID,并在用尽空间前分配最多 100 个块。默认值为在 10k 块中分配 10 亿到 20 亿的块(这是在用户命名空间启动后使用范围容器镜像的预期大小)。 |
7.6.15. 服务帐户配置
参数名称 | 描述 |
---|---|
| 控制是否允许服务帐户在没有显式引用命名空间中引用任何 secret。 |
|
在每个命名空间中创建的服务帐户名称列表。如果没有指定名称,则不会启动 |
| 用于验证 TLS 连接到主主机的 CA。服务帐户控制器会自动将此文件的内容注入到 pod 中,以便它们能够验证与主控机的连接。 |
|
包含 PEM 编码私有 RSA 密钥的文件,用于签署服务帐户令牌。如果没有指定私钥,则不会启动服务帐户 |
| 文件列表,各自包含 PEM 编码的公共 RSA 密钥。如果有任何文件包含私钥,则使用密钥的公钥部分。公钥列表用于验证所提供的服务帐户令牌。每个密钥按顺序尝试,直到列表耗尽或验证成功为止。如果没有指定密钥,则不会使用服务帐户身份验证。 |
| 包含与服务帐户相关的选项:
|
7.6.16. 服务信息配置
参数名称 | 描述 |
---|---|
| 允许主服务器上的 DNS 服务器以递归方式应答查询。请注意,打开解析器可用于 DNS 模糊攻击,并且主 DNS 不应该被公共网络访问。 |
| 要服务的 ip:port。 |
| 控制导入镜像的限值和行为。 |
| 包含 PEM 编码证书的文件。 |
| 用于提供安全流量的 TLS 证书信息。 |
| 您识别传入客户端证书的所有签名人的证书捆绑包。 |
| 如果存在,则根据定义的参数启动 DNS 服务器。例如: dnsConfig: bindAddress: 0.0.0.0:8053 bindNetwork: tcp4 |
| 包含域后缀。 |
| 包含 IP。 |
|
包含由 |
| 为用于连接 master 的客户端连接提供覆盖。这个参数不被支持。要设置 QPS 和 burst 值,请参阅设置节点 QPS 和 Burst 值。 |
| 允许到服务器的并发请求数。如果零,则不限制。 |
| 用于保护到特定主机名请求的证书列表。 |
| 请求超时前的秒数。默认值为 60 分钟。如果 -1,请求没有限制。 |
| 资产的 HTTP 服务信息。 |
7.6.17. 卷配置
参数名称 | 描述 |
---|---|
| 启用或禁用动态置备的布尔值。默认为 true。 |
FSGroup |
为每个 FSGroup 在每个节点上启用 本地存储配额。目前,这仅适用于 emptyDir 卷,如果底层 |
| 包含用于在 master 节点上配置卷插件的选项。 |
| 包含用于在节点上配置卷的选项。 |
| 包含用于在节点中配置卷插件的选项:
|
|
卷所在的目录。使用 |
7.6.18. 基本审计
审计提供一组安全相关的按时间排序的记录,记录各个用户、管理员或其他系统组件影响系统的一系列活动。
审计在 API 服务器级别运作,记录所有传入到服务器的请求。每个审计日志包含两个条目:
请求行中包含:
- 用于匹配响应行的唯一 ID(参见 #2)
- 请求的源 IP
- 被调用的 HTTP 方法
- 调用该操作的原始用户
-
操作的模拟用户(
self
表示自己) -
操作的模拟组(
lookup
表示用户的组) - 请求的命名空间或 <none>
- 请求的 URI
响应行中包括:
- #1 中的唯一 ID
- 响应代码
用户 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"
7.6.18.1. 启用基本审计
以下流程在安装后启用基本审计。
高级审计必须在安装过程中启用。
编辑所有 master 节点上的 /etc/origin/master/master-config.yaml 文件,如下例所示:
auditConfig: auditFilePath: "/var/log/origin/audit-ocp.log" enabled: true maximumFileRetentionDays: 14 maximumFileSizeMegabytes: 500 maximumRetainedFiles: 15
重启集群中的 API pod。
# /usr/local/bin/master-restart api
要在安装过程中启用基本审计,请在清单文件中添加以下变量声明。根据情况调整值。
openshift_master_audit_config={"enabled": true, "auditFilePath": "/var/lib/origin/openpaas-oscp-audit.log", "maximumFileRetentionDays": 14, "maximumFileSizeMegabytes": 500, "maximumRetainedFiles": 5}
审计配置采用以下参数:
参数名称 | 描述 |
---|---|
|
启用或禁用审计日志的布尔值。默认为 |
| 请求应记录到的文件路径。如果没有设置,日志会被输出到 master 日志中。 |
| 根据文件名中编码的时间戳,指定用于保留旧审计日志文件的最大天数。 |
| 指定要保留的旧审计日志文件的最大数量。 |
| 在轮转日志文件前,指定日志文件的最大大小(以 MB 为单位)。默认值为 100MB。 |
Audit 配置示例
auditConfig: auditFilePath: "/var/log/origin/audit-ocp.log" enabled: true maximumFileRetentionDays: 14 maximumFileSizeMegabytes: 500 maximumRetainedFiles: 15
当您定义 auditFilePath
参数时,如果该目录不存在,则会创建该目录。
7.6.19. 高级审计
高级审计功能对 基本审计功能 进行了一些改进,包括精细的事件过滤和多个输出后端。
要启用高级审计功能,您可以创建一个审计策略文件,并在 openshift_master_audit_config
和 openshift_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"
您必须在安装集群前创建 adv-audit.yaml 文件,并指定其在集群清单文件中的位置。
下表包含您可以使用的附加选项。
参数名称 | 描述 |
---|---|
| 定义审计策略配置的文件的路径。 |
| 嵌入式审计策略配置。 |
|
指定保存的审计日志的格式。允许的值是 |