翼度科技»论坛 编程开发 python 查看内容

WCF 服务容器化的一些问题

3

主题

3

帖子

9

积分

新手上路

Rank: 1

积分
9
背景

目前项目当中存有 .NET Framework 和 .NET Core 两种类型的项目,但是都需要进行容器化将其分别部署在 Windows 集群和 Linux 集群当中。在 WCF 进行容器化的时候,遇到了以下几个问题:

  • 某些服务使用到了 WSHttpBinding 保护服务安全,要在容器里面加载 SSL 证书。
  • WCF 服务的日志,如何重定向到标准输出流?
解决

问题一

关于第一个问题,最开始我觉得只需要将 WCF 服务打包出来,暴露一个 HTTP 端点。然后在这个 WCF 服务的前面再加一层 NGINX,具体的证书由 NGINX 进行管理。大概的流程就是 API Caller --> (HTTPS)F5 --> (HTTPS)NGINX --> (HTTP)WCF,按照这样的方式部署之后,对应的服务端点无法访问,具体的错误提示的是 Schema 不匹配。因为 WSHttpBinding 强制使用 HTTPS,如果我仅暴露一个 HTTP 端点,是无法绕过 WSHttpBinding 的限制的。
随后我又在网上找到了 这篇文章,该文章的思路就是实现一个 CustomBinding,然后在里面忽略掉这块验证,经过我的测试无法满足需求。
上述方法行不通就只有创建一个自签 SSL 证书,并导入到 IIS 当中,随后在 NGINX 启用 SSL 转发,目前看来已经解决这个问题。下面是我的 Dockerfile 以及入口点的 PowerShell 脚本,脚本里面包含了证书生成与导入方法。
dockerfile:
  1. FROM mcr.microsoft.com/dotnet/framework/sdk:4.8 AS build
  2. WORKDIR /build
  3. COPY . .
  4. RUN cd ./src; nuget restore
  5. WORKDIR /build/src/ProjectName
  6. RUN msbuild Wcf.csproj /p:Configuration=Release -r:False
  7. FROM mcr.microsoft.com/dotnet/framework/wcf:4.8-windowsservercore-ltsc2019 AS runtime
  8. WORKDIR /WcfService
  9. EXPOSE 443
  10. COPY --from=build /build/wcf-entrypoint.ps1 .
  11. COPY --from=build /build/src/ProjectName .
  12. ENTRYPOINT ["powershell", ".\\wcf-entrypoint.ps1"]
复制代码
entrypoint.ps1
  1. $hostName = $env:HostName
  2. $port = "443"
  3. $password = "Your password."
  4. $storeLocation = "Cert:\LocalMachine\My"
  5. $certificate = New-SelfSignedCertificate -DnsName $hostName -CertStoreLocation $storeLocation
  6. $thumbPrint = $certificate.Thumbprint
  7. $certificatePath = ("cert:\localmachine\my" + $certificate.Thumbprint)
  8. $bindingInformation = "*:" + $port + ":" + $hostName
  9. $securedString = ConvertTo-SecureString -String $password -Force -AsPlainText
  10. Export-PfxCertificate -FilePath "C:\WcfService\temp.pfx" -Cert $certificatePath -Password $securedString
  11. Import-PfxCertificate -FilePath "C:\WcfService\temp.pfx" -CertStoreLocation "Cert:\LocalMachine\Root" -Password $securedString
  12. New-IISSite -Name "WcfService" -PhysicalPath C:\WcfService -BindingInformation $bindingInformation -CertificateThumbPrint $thumbPrint -CertStoreLocation $storeLocation -Protocol https
  13. # Entry point for the application.
  14. &C:\\ServiceMonitor.exe w3svc
复制代码
问题二

由于 WCF 是托管在 IIS 里面的,我们的日志信息是无法输出到标准输出流的。所以我们就采取了一个曲线救国的方案,使用一个旁路程序,我们的日志输出到文件当中,由这个旁路程序监控文件变动,然后将变动的内容输出到标准输出流里面。
这个功能有点像 Logstash,你可能会说我们为什么不直接用 Logstash 收集这些日志呢?因为我们所有项目的日志,都是由基础架构团队统一处理。规范就是我们日志必须输出到标准输出流,并且日志是结构化日志,还需带上一些 ProjectId 之类的标记信息。然后由注入的 Sidecar 容器统一收集、处理、上报到 Garylog 平台。
回到正题,最开始我找到了微软实现的一个开源工具,它的本意就是为一些 Windows 容器解决日志收集问题的。
项目的地址是: https://github.com/microsoft/windows-container-tools
使用这个工具,指定好路径与需要运行的程序,替换 Dockerfile 的入口点即可解决问题。微软那个工具的核心,就是使用了系统提供的文件监听 API,在 .NET 里面也有提供类似的 API,叫做 FileSystemWatcher,如果有兴趣的话,也可以参考 C++ 的源码和思路自己实现。

来源:https://www.cnblogs.com/myzony/archive/2023/01/01/problems-with-containerizing-a-wcf-service.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具