背景

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

  1. 某些服务使用到了 WSHttpBinding 保护服务安全,要在容器里面加载 SSL 证书。
  2. 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:

FROM mcr.microsoft.com/dotnet/framework/sdk:4.8 AS build
WORKDIR /build COPY . .
RUN cd ./src; nuget restore
WORKDIR /build/src/ProjectName
RUN msbuild Wcf.csproj /p:Configuration=Release -r:False FROM mcr.microsoft.com/dotnet/framework/wcf:4.8-windowsservercore-ltsc2019 AS runtime
WORKDIR /WcfService
EXPOSE 443 COPY --from=build /build/wcf-entrypoint.ps1 .
COPY --from=build /build/src/ProjectName . ENTRYPOINT ["powershell", ".\\wcf-entrypoint.ps1"]

entrypoint.ps1

$hostName = $env:HostName
$port = "443"
$password = "Your password."
$storeLocation = "Cert:\LocalMachine\My"
$certificate = New-SelfSignedCertificate -DnsName $hostName -CertStoreLocation $storeLocation
$thumbPrint = $certificate.Thumbprint
$certificatePath = ("cert:\localmachine\my\" + $certificate.Thumbprint)
$bindingInformation = "*:" + $port + ":" + $hostName
$securedString = ConvertTo-SecureString -String $password -Force -AsPlainText
Export-PfxCertificate -FilePath "C:\WcfService\temp.pfx" -Cert $certificatePath -Password $securedString
Import-PfxCertificate -FilePath "C:\WcfService\temp.pfx" -CertStoreLocation "Cert:\LocalMachine\Root" -Password $securedString
New-IISSite -Name "WcfService" -PhysicalPath C:\WcfService -BindingInformation $bindingInformation -CertificateThumbPrint $thumbPrint -CertStoreLocation $storeLocation -Protocol https # Entry point for the application.
&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++ 的源码和思路自己实现。

WCF 服务容器化的一些问题的更多相关文章

  1. .NET微服务 容器化.NET应用架构指南(支持.NET Core2)

    介绍 企业通过使用容器,日益实现成本节约.解决部署问题并改进 DevOps 和生产操作. 通过创建 Azure 容器服务.Azure Service Fabric 等产品,同时与 Docker.Mes ...

  2. Docker+Kubernetes(k8s)微服务容器化实践

    第1章 初识微服务微服务的入门,我们从传统的单体架构入手,看看在什么样的环境和需求下一步步走到微服务的,然后再具体了解一下什么才是微服务,让大家对微服务的概念有深入的理解.然后我们一起画一个微服务的架 ...

  3. 微服务SpringCloud容器化案例

    前言 当我们在使用微服务的时候,那么有一个问题一定会困扰我们,那就是项目的测试和部署.因为在单体应用下,部署项目很简单,直接打包启动就可以了,而对于微服务来说,因为有各个组件的存在所以让测试和部署都变 ...

  4. 谈到云原生, 绕不开"容器化"

    传送门 什么是云原生? 云原生设计理念 .NET微服务 Containers 现在谈到云原生, 绕不开"容器". 在<Cloud Native Patterns>一书中 ...

  5. 浅谈surging服务引擎中的rabbitmq组件和容器化部署

    1.前言 上个星期完成了surging 的0.9.0.1 更新工作,此版本通过nuget下载引擎组件,下载后,无需通过代码build集成,引擎会通过Sidecar模式自动扫描装配异构组件来构建服务引擎 ...

  6. 1. 容器化部署一套云服务 第一讲 Jenkins(Docker + Jenkins + Yii2 + 云服务器))

    容器化部署一套云服务系列 1. 容器化部署一套云服务之Jenkins 一.购买服务器 服务器

  7. 唯品会RPC服务框架与容器化演进--转

    原文地址:http://mp.weixin.qq.com/s?__biz=MzAwMDU1MTE1OQ==&mid=405781868&idx=1&sn=cbb10d37e25 ...

  8. 容器化VS微服务

    1 微服务 1.1 思想 开发人员自己测试.部署和运维自己编写的代码,即自己负责构建生命周期的全部. 1.2 Spring Boot 提供服务化的能力,即把容器.服务所需依赖和服务一起打包成一个jar ...

  9. docker容器化python服务部署(supervisor-gunicorn-flask)

    docker容器化python服务部署(supervisor-gunicorn-flask) 本文系作者原创,转载请注明出处: https://www.cnblogs.com/further-furt ...

  10. Java 服务 Docker 容器化最佳实践

    转载自:https://mp.weixin.qq.com/s/d2PFISYUy6X6ZAOGu0-Kig 1. 概述 当我们在容器中运行 Java 应用程序时,可能希望对其进行调整参数以充分利用资源 ...

随机推荐

  1. POJ2763 Housewife Wind (树链剖分)

    差不多是模板题,不过要注意将边权转化为点权,将边的权值赋给它所连的深度较大的点. 这样操作过后,注意查询ask()的代码有所改变(见代码注释) 1 #include<cstdio> 2 # ...

  2. 运行eeui项目不出现 WiFI真机同步 IP地址

    从git上 clone项目之后,安装依赖  npm install eeui环境配置    npm install eeui-cli -g 问题:npm run dev  后项目一直不出现 WiFI真 ...

  3. Mybatis组件介绍

    核心组件 SqlSessionFactoryBuilder SqlSessionFactoryBuilder的作用就是通过XML或者Java代码来建造一个工厂(SqlSessionFactory),并 ...

  4. 知识图谱-生物信息学-医学论文(Chip-2022)-BCKG-基于临床指南的中国乳腺癌知识图谱的构建与应用

    16.(2022)Chip-BCKG-基于临床指南的中国乳腺癌知识图谱的构建与应用 论文标题: Construction and Application of Chinese Breast Cance ...

  5. Spring知识框架

  6. DQL语句

    DQL语句 DQL(Data QueryLanguage )数据查询语言,基本结构是由SELECT子句,FROM子句,WHERE子句组成的查询块. 一.DQL概述 1.1.什么是DQL DQL:数据查 ...

  7. 20_Vue如何监测数组类型数据发生改变的?

    通过上一节,我们知道了vue检测对象数据发生改变的原理 但是还有个api我们没有讲解,Vue.set(): 这个API比较适合在理解了对象检测的原理后进行讲解 案例准备 html <!-- 创建 ...

  8. Codeforces Global Round 18 B. And It's Non-Zero(按位前缀和)

    题目大意:求一段数(l到r)的按位与结果不为零需要删除中间元素的最小个数 思路:按位与使得结果不为0只要有某一位全是1即可,所以只要统计每一位1的个数,用总个数减去1的个数就是某一位0的个数 删除包含 ...

  9. 将Oracle数据库迁移到达梦数据库

    公司某产品在项目现场上常用到的数据库有Oracle和达梦. 做性能测试需要根据项目现场预埋大量的基础数据和业务数据,耗费时间.精力.故完成Oracle数据库的性能测试之后,采用直接将Oracle数据库 ...

  10. Python调用golang

    有些时候因为效率问题部分代码会 使用Python调用go的编译生成动态链接库go 代码示例//add.gopackage main import "C" //export Addf ...