Sitecore 10 K8S 部署 - 无效 redirect_uri 和密钥集缺失错误

Sitecore 10 K8S Deployment - Invalid redirect_uri and Keyset Missing Errors

我正在处理 k8s (AKS) Sitecore 10 XM1 部署,我在 k8s 环境中看到两个(可能相关的)问题,Docker 中的相同容器镜像不会出现 windows。我的假设是它们可能是由入口控制器配置、TLS 证书或环境变量引起的,因为这些是唯一真正的区别。我很难诊断原因,因为我对容器、新的 Sitecore 身份服务器和 k8s 还很陌生。

我已将实际域名替换为 'mydomain',并且我们拥有使用 certmanager 部署的实际域的有效 TLS 证书。

第一个问题与我们的 CD 管道无法以非交互方式登录(根据 https://doc.sitecore.com/developers/100/developer-tools/en/configure-a-non-interactive-client-login.html)以执行内容序列化命令有关。当我的部署管道执行 dotnet sitecore login --client-credentials true --authority ${{ parameters.idServerUrl }} --cm ${{ parameters.cmServerUrl }} --allow-write true --client-id "Pipeline_Automation" --client-secret "$(sitecore-identitysecret-pipeline)" 时,我收到错误 Keyset is missing。必要的配置文件通过环境 Dockerfiles 中的 COPY 命令部署到我们的 cm 和 id 实例(我可以在 运行 容器中看到),并且我可以通过客户端凭据登录解决方案是 运行 本地 Docker.

第二个问题是,当我们尝试点击 https://author.qa.mydomain.com/sitecore 时,我们在 id pod 日志中看到 Invalid redirect_uri: "https://author.qa.mydomain.com/identity/signin" 错误,我们应该被重定向到登录页面。我读到这通常是由于实际重定向 URL 与 k8s 规范的 id 环境的 Sitecore_Sitecore__IdentityServer__Clients__DefaultClient__AllowedCorsOrigins__AllowedCorsOriginsGroup1 环境变量配置的不匹配引起的,但是日志表明它们是相同的:

id 日志

[13:12:36] IdentityServer4.Validation.AuthorizeRequestValidator [Error] Invalid redirect_uri: "https://author.qa.mydomain.com/identity/signin"

AuthorizeRequestValidationLog {ClientId="Sitecore", ClientName="Sitecore", RedirectUri=null, AllowedRedirectUris=["{AllowedCorsOrigin}/identity/signin", "{AllowedCorsOrigin}/signin-oidc"], SubjectId="anonymous", ResponseType=null, ResponseMode=null, GrantType=null, RequestedScopes="", State=null, UiLocales=null, Nonce=null, AuthenticationContextReferenceClasses=null, DisplayMode=null, PromptMode=null, MaxAge=null, LoginHint=null, SessionId=null, Raw={["client_id"]="Sitecore", ["response_type"]="code id_token token", ["scope"]="openid sitecore.profile", ["state"]="OpenIdConnect.AuthenticationProperties=gradGeDSd71cNE43mbnFr-GuWj0q03FGaBiqGgyhXJW0-7qYt4xi5D5C360rNowTwT0PC9hZCut484hMo7WFSRsHmkseOJ5ud99RUhtxQwHrXuATCqErmKQE0m3UtPBsBhpySWkcs3J1EwkuPeELzplf_uMU7F6lyh77sUfyrQuTZf1bn05wJ2ZnEpGDXmAcSe5nCRQOt5D9hemDBZ4WzA", ["response_mode"]="form_post", ["nonce"]="637527067565470343.M2MwMDkxNGMtNzM0NC00OThkLWI0YmMtZTBiZmJhZDM2OWRmODM4YjViODgtOTdmOC00Nzc5LThhZWMtZjU2MmE2MzY5M2Mz", ["redirect_uri"]="https://author.qa.mydomain.com/identity/signin", ["sc_account_prefix"]="sitecore\", ["x-client-SKU"]="ID_NET461", ["x-client-ver"]="5.3.0.0"}} 

[13:12:36] IdentityServer4.Endpoints.AuthorizeEndpoint [Error] Request validation failed

nginx 日志

XXX.XX.XXX.XX - - [31/Mar/2021:12:10:16 +0000] "POST /identity/externallogin?authenticationType=SitecoreIdentityServer&ReturnUrl=%2fidentity%2fexternallogincallback%3fReturnUrl%3d%26sc_site%3dshell%26authenticationSource%3dDefault&sc_site=shell HTTP/2.0" 302 0 "https://author.qa.mydomain.com/identity/login/shell/SitecoreIdentityServer" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0" 597 0.013 [default-cm-80] [] 10.240.0.83:80 0 0.012 302 435fbe68699d547286aef26f15f4d33f
XXX.XX.XXX.XX - - [31/Mar/2021:12:10:16 +0000] "GET /connect/authorize?client_id=Sitecore&response_type=code%20id_token%20token&scope=openid%20sitecore.profile&state=OpenIdConnect.AuthenticationProperties%3DD9AWnwdC9UV0fjOTg3giJdWs0rdIRftadzkgUYO7c9sGu6nsBnyVCcrXNFJw1EhiXT2bDmJrdpqy3Gf8sMX5UXU1yJmz0u2Rpud_OUTd9YMot-1_OFzTCjPZS7-lrUxBlwkHhJP-eJN5wgDPBKCohsyHpHqmI9KaETYn2p7pnfnsQMh-7nvI9_iy3KFifcHiMYo4zyMkch-FZm7SW_pWsA&response_mode=form_post&nonce=637527894166260277.ZjdmNWIyNjUtZTk2NS00NzhmLTk4MDctMjFlNmU3ZjRjNjE4MjNhMDAwYmEtNGRmYS00YTcxLThmYTYtNTIwNzkzN2M3NGYy&redirect_uri=https%3A%2F%2Fauthor.qa.mydomain.com%2Fidentity%2Fsignin&sc_account_prefix=sitecore%5C&x-client-SKU=ID_NET461&x-client-ver=5.3.0.0 HTTP/2.0" 302 0 "https://author.qa.mydomain.com/identity/login/shell/SitecoreIdentityServer" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0" 564 0.007 [default-id-80] [] 10.240.0.73:80 0 0.008 302 354a57aea9818b47ce853edc6abee662
XXX.XX.XXX.XX - - [31/Mar/2021:12:10:16 +0000] "GET /home/error?errorId=CfDJ8B12A-SlGFlFuiZCVhQvJ8LQrI1XT9zDZiDk__KCVmMZULmTqb8K9QN9a-lqnM_gl9hxJC3CqPMCOITToOp5QKRb3nP8A8IuiY9Z0v7ofXpvYlzYiMnbe1V03MJs7t_nHh6CS8RkfqlwK1Z1R2V31JcDb7FEXn2Ek6mwWxAonA9LuGcGQe9yhxcy3zmF60DqQkun71_fWMtrgIdIeFHo4Zn1aCYSYYQpuLY84lOB-aiFNdxgS48gV1lASfUshgdBrVTD3y6KuMMdUylKsoOG4JXQRUh5aT67f6J2WCWWwzYiDQ5sos1N7Lxp_Pq7iZq5KQ HTTP/2.0" 404 0 "https://author.qa.mydomain.com/identity/login/shell/SitecoreIdentityServer" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0" 295 0.003 [default-id-80] [] 10.240.0.73:80 0 0.000 404 fd27666878ee5cf4affb008674edc693

我认为这些问题是相关的,因为当解决方案在其 traefik 入口后面本地运行时,身份服务器表现正常。我能够登录,没有遇到重定向错误并且可以非交互登录。

我想尝试在集群中的 pod 中使用诸如 lynx 运行 的 cli 浏览器,看看我是否可以重现重定向错误,以便将原因缩小到入口控制器,但是还没有找到一个简单的方法来做到这一点。

如果有人能提供一些诊断建议,我将不胜感激。

id.yaml k8s 规范

apiVersion: v1
kind: Service
metadata:
  name: id
spec:
  selector:
    app: id
  ports:
  - protocol: TCP
    port: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: id
  labels:
    app: id
spec:
  replicas: 1
  selector:
    matchLabels:
      app: id
  template:
    metadata:
      labels:
        app: id
    spec:
      nodeSelector:
        kubernetes.io/os: windows
      containers:
      - name: sitecore-xm1-id
        image: mydomain.azurecr.io/cms/mydomain-id:latest
        ports:
        - containerPort: 80
        imagePullPolicy: Always
        env:
        - name: Database_Server
          valueFrom:
            secretKeyRef:
              name: sitecore-database
              key: sitecore-databaseservername.txt
        - name: Core_Database_Username
          valueFrom:
            secretKeyRef:
              name: sitecore-database
              key: sitecore-core-database-username.txt
        - name: Core_Database_Password
          valueFrom:
            secretKeyRef:
              name: sitecore-database
              key: sitecore-core-database-password.txt
        - name: Sitecore_Sitecore__IdentityServer__Clients__PasswordClient__ClientSecrets__ClientSecret1
          valueFrom:
            secretKeyRef:
              name: sitecore-identity
              key: sitecore-identitysecret.txt
        - name: Sitecore_Sitecore__IdentityServer__CertificateRawData
          valueFrom:
            secretKeyRef:
              name: sitecore-identitycertificate
              key: sitecore-identitycertificate.txt
        - name: Sitecore_Sitecore__IdentityServer__CertificateRawDataPassword
          valueFrom:
            secretKeyRef:
              name: sitecore-identitycertificate
              key: sitecore-identitycertificatepassword.txt
        - name: Sitecore_License
          valueFrom:
            secretKeyRef:
              name: sitecore-license
              key: sitecore-license.txt
        - name: Sitecore_Sitecore__IdentityServer__Clients__CliServerClient__ClientSecrets__ClientSecret1
          valueFrom:
            secretKeyRef:
              name: sitecore-identity
              key: sitecore-identitysecret-pipeline.txt
        - name: Sitecore_Sitecore__IdentityServer__SitecoreMemberShipOptions__ConnectionString
          value: Data Source=$(Database_Server);Initial Catalog=Sitecore.Core;User ID=$(Core_Database_Username);Password=$(Core_Database_Password);
        - name: Sitecore_Sitecore__IdentityServer__AccountOptions__PasswordRecoveryUrl
          value: https://author.qa.mydomain.com/sitecore/login?rc=1
        - name: Sitecore_Sitecore__IdentityServer__Clients__DefaultClient__AllowedCorsOrigins__AllowedCorsOriginsGroup1
          value: https://author.qa.mydomain.com
        - name: Sitecore_Sitecore__IdentityServer__PublicOrigin
          value: https://id.qa.mydomain.com
        livenessProbe:
          httpGet:
            path: /healthz/live
            port: 80
            httpHeaders:
            - name: X-Kubernetes-Probe
              value: Liveness
          timeoutSeconds: 300
          periodSeconds: 30
          failureThreshold: 3
        startupProbe:
          httpGet:
            path: /healthz/ready
            port: 80
            httpHeaders:
            - name: X-Kubernetes-Probe
              value: Startup
          timeoutSeconds: 300
          periodSeconds: 30
          failureThreshold: 10
      imagePullSecrets:
      - name: acr-secret

cd.yaml k8s 规范

apiVersion: v1
kind: Service
metadata:
  name: cm
spec:
  selector:
    app: cm
  ports:
  - protocol: TCP
    port: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: cm
  labels:
    app: cm
spec:
  replicas: 1
  selector:
    matchLabels:
      app: cm
  template:
    metadata:
      labels:
        app: cm
    spec:
      nodeSelector:
        kubernetes.io/os: windows
      containers:
      - name: sitecore-xm1-cm
        image: mydomain.azurecr.io/cms/mydomain-xm1-cm:latest
        ports:
        - containerPort: 80
        imagePullPolicy: Always
        env:
        - name: Sitecore_InstanceName
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: Database_Server
          valueFrom:
            secretKeyRef:
              name: sitecore-database
              key: sitecore-databaseservername.txt
        - name: Master_Database_Username
          valueFrom:
            secretKeyRef:
              name: sitecore-database
              key: sitecore-master-database-username.txt
        - name: Master_Database_Password
          valueFrom:
            secretKeyRef:
              name: sitecore-database
              key: sitecore-master-database-password.txt
        - name: Core_Database_Username
          valueFrom:
            secretKeyRef:
              name: sitecore-database
              key: sitecore-core-database-username.txt
        - name: Core_Database_Password
          valueFrom:
            secretKeyRef:
              name: sitecore-database
              key: sitecore-core-database-password.txt
        - name: Web_Database_Username
          valueFrom:
            secretKeyRef:
              name: sitecore-database
              key: sitecore-web-database-username.txt
        - name: Web_Database_Password
          valueFrom:
            secretKeyRef:
              name: sitecore-database
              key: sitecore-web-database-password.txt
        - name: Forms_Database_Username
          valueFrom:
            secretKeyRef:
              name: sitecore-database
              key: sitecore-forms-database-username.txt
        - name: Forms_Database_Password
          valueFrom:
            secretKeyRef:
              name: sitecore-database
              key: sitecore-forms-database-password.txt
        - name: Sitecore_ConnectionStrings_Sitecoreidentity.secret
          valueFrom:
            secretKeyRef:
              name: sitecore-identity
              key: sitecore-identitysecret.txt
        - name: Sitecore_AppSettings_Telerik.AsyncUpload.ConfigurationEncryptionKey
          valueFrom:
            secretKeyRef:
              name: sitecore-telerik
              key: sitecore-telerikencryptionkey.txt
        - name: Sitecore_AppSettings_Telerik.Upload.ConfigurationHashKey
          valueFrom:
            secretKeyRef:
              name: sitecore-telerik
              key: sitecore-telerikencryptionkey.txt
        - name: Sitecore_AppSettings_Telerik.Web.UI.DialogParametersEncryptionKey
          valueFrom:
            secretKeyRef:
              name: sitecore-telerik
              key: sitecore-telerikencryptionkey.txt
        - name: Sitecore_License
          valueFrom:
            secretKeyRef:
              name: sitecore-license
              key: sitecore-license.txt
        - name: Sitecore_ConnectionStrings_Core
          value: Data Source=$(Database_Server);Initial Catalog=Sitecore.Core;User ID=$(Core_Database_Username);Password=$(Core_Database_Password);
        - name: Sitecore_ConnectionStrings_Security
          value: Data Source=$(Database_Server);Initial Catalog=Sitecore.Core;User ID=$(Core_Database_Username);Password=$(Core_Database_Password);
        - name: Sitecore_ConnectionStrings_Master
          value: Data Source=$(Database_Server);Initial Catalog=Sitecore.Master;User ID=$(Master_Database_Username);Password=$(Master_Database_Password);
        - name: Sitecore_ConnectionStrings_Web
          value: Data Source=$(Database_Server);Initial Catalog=Sitecore.Web;User ID=$(Web_Database_Username);Password=$(Web_Database_Password);
        - name: Sitecore_ConnectionStrings_ExperienceForms
          value: Data Source=$(Database_Server);Initial Catalog=Sitecore.ExperienceForms;User ID=$(Forms_Database_Username);Password=$(Forms_Database_Password);
        - name: Sitecore_ConnectionStrings_Solr.Search
          valueFrom:
            secretKeyRef:
              name: sitecore-solr
              key: sitecore-solr-connection-string.txt
        - name: Sitecore_Identity_Server_Authority
          value: https://id.qa.mydomain.com
        - name: Sitecore_Identity_Server_CallbackAuthority
          value: https://author.qa.mydomain.com
        - name: Sitecore_Identity_Server_InternalAuthority
          value: http://id
        - name: Sitecore_Identity_Server_Require_Https
          value: "false"
        - name: SOLR_CORE_PREFIX_NAME
          valueFrom:
            secretKeyRef:
              name: sitecore-solr
              key: sitecore-solr-core-prefix-name.txt
        livenessProbe:
          httpGet:
            path: /healthz/live
            port: 80
            httpHeaders:
            - name: X-Kubernetes-Probe
              value: Liveness
          timeoutSeconds: 300
          periodSeconds: 30
          failureThreshold: 3
        startupProbe:
          httpGet:
            path: /healthz/ready
            port: 80
            httpHeaders:
            - name: X-Kubernetes-Probe
              value: Startup
          timeoutSeconds: 300
          periodSeconds: 30
          failureThreshold: 10
      imagePullSecrets:
      - name: acr-secret

我们通过更改部署管道中使用的 sitecore cli 版本解决了这个问题。允许登录和 serialization/publishing 的 powershell 脚本是:

           # Add nuget source & install Sitecore CLI
           Write-Host "Installing Sitecore CLI"
           dotnet nuget add source ${{ parameters.sitecoreNugetFeed }} --name "Sitecore-Public-Nuget-Feed"
           dotnet tool install --version 2.0.0 Sitecore.CLI
           
           # Login to ID Server
           Write-Host "Logging into ID Server ${{ parameters.idServerUrl }} for environment ${{ parameters.cmServerUrl }}"
           dotnet sitecore login --client-credentials true --authority ${{ parameters.idServerUrl }} --cm ${{ parameters.cmServerUrl }} --allow-write true --client-id "Pipeline_Automation" --client-secret "$(sitecore-identitysecret-pipeline)"
          
           # Deserialize Content
           Write-Host "Push Content"
           dotnet sitecore ser push
            
           # Publish Database
           Write-Host "Publish Database"
           dotnet sitecore publish