如何让 MSSQL 服务容器在 Azure DevOps 管道中工作?

Posted

技术标签:

【中文标题】如何让 MSSQL 服务容器在 Azure DevOps 管道中工作?【英文标题】:How do I get MSSQL service container working in Azure DevOps pipeline? 【发布时间】:2020-12-11 18:17:21 【问题描述】:

说明

我正在尝试使用 服务容器 在 azure devops 管道中进行集成数据库测试

根据这个开源虚拟 ci cd 管道项目https://dev.azure.com/funktechno/_git/dotnet%20ci%20pipelines。我正在尝试使用 azure devops service containers 进行集成管道测试。我让 postgress 和 mysql 工作。我在使用 microsoft sql server 时遇到问题。

yml 文件

resources:
  containers:
  - container: mssql
    image: mcr.microsoft.com/mssql/server:2017-latest
    ports: 
      # - 1433
      - 1433:1433
    options: -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=yourStrong(!)Password' -e 'MSSQL_PID=Express'

- job: unit_test_db_mssql
  # condition: eq('$ variables.runDbTests ', 'true')
  # continueOnError: true
  pool:
    vmImage: 'ubuntu-latest'
  services:
    localhostsqlserver: mssql
  steps:
    - task: UseDotNet@2
      displayName: 'Use .NET Core sdk 2.2'
      inputs:
        packageType: sdk
        version: 2.2.207
        installationPath: $(Agent.ToolsDirectory)/dotnet
    - task: NuGetToolInstaller@1
    - task: NuGetCommand@2
      inputs:
        restoreSolution: '$(solution)'
    - task: Bash@3
      inputs:
        targetType: 'inline'
        script: 'env | sort'

        #  echo Write your commands here...
        #   echo $agent.services.localhostsqlserver.ports.1433
        #   echo Write your commands here end...
    - task: CmdLine@2
      displayName: 'enabledb'
      inputs:
        script: |
          cp ./MyProject.Repository.Test/Data/appSettings.devops.mssql.json ./MyProject.Repository.Test/Data/AppSettings.json
    - task: DotNetCoreCLI@2
      inputs:
        command: 'test'
        workingDirectory: MyProject.Repository.Test
        arguments: '--collect:"XPlat Code Coverage"'

    - task: PublishCodeCoverageResults@1
      inputs:
        codeCoverageTool: 'Cobertura'
        summaryFileLocation: '$(Agent.TempDirectory)\**\coverage.cobertura.xml'

数据库连接字符串


    "sqlserver": 
        "ConnectionStrings": 
            "Provider": "sqlserver",
            "DefaultConnection": "User ID=sa;Password=yourStrong(!)Password;Server=localhost;Database=mockDb;Pooling=true;"
        
    

调试

    我能说的最多的是,当我运行 Bash@3 来检查环境变量 postgres 和 mysql 打印类似于

    /bin/bash --noprofile --norc /home/vsts/work/_temp/b9ec7d77-4bc2-47ab-b767-6a5e95ec3ea6.sh
        "id": "b294d39b9cc1f0d337bdbf92fb2a95f0197e6ef78ce28e9d5ad6521496713708"
      "pg11": 
      
    
    当 mssql 无法打印 id 时
    ========================== Starting Command Output ===========================
    /bin/bash --noprofile --norc /home/vsts/work/_temp/70ae8517-5199-487f-9067-aee67f8437bb.sh
      
    
    
    更新这在使用 ubuntu-latest 时不会发生,但仍然有 mssql 连接问题

    数据库错误记录。

    我目前正在处理此错误
    Error Message:
      Failed for sqlserver
        providername:Microsoft.EntityFrameworkCore.SqlServer m:A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: TCP Provider, error: 40 - Could not open a connection to SQL Server)
    
    在 TestDbContext.cs 我的错误信息是这样的。如果人们有获得更多详细信息的指针,我们将不胜感激。
    catch (System.Exception e)
       
                    var assertMsg = "Failed for " + connectionStrings.Provider + "\n" + " providername:" + dbContext.Database.ProviderName + " m:";
                    if (e.InnerException != null)
                        assertMsg += e.InnerException.Message;
                    else
                        assertMsg += e.Message;
                    _exceptionMessage = assertMsg;
        
    

示例管道:https://dev.azure.com/funktechno/dotnet%20ci%20pipelines/_build/results?buildId=73&view=logs&j=ce03965c-7621-5e79-6882-94ddf3daf982&t=a73693a5-1de9-5e3d-a243-942c60ab4775

注意事项

我已经知道 azure devops 管道 mssql 服务器在 windows 代理 b/c 中不起作用,它们是 windows server 2019 并且 mssql server 的 windows 容器版本没有得到很好的支持,仅适用于 windows server 2016。它失败了当我这样做时,在初始化容器步骤上。

我为 unit_test_db_mssql 尝试了几件事,更改 ubuntu 版本,更改参数,更改 mssql 服务器版本,都给出了相同的错误。

如果人们知道在 linux 中可以使用命令行方法来测试 mssql docker 实例是否准备就绪,那么这也可能会有所帮助。

进度更新

到目前为止,mssqlgithub 操作gitlab 管道 中工作。 postgresmysqlazure devopsbitbucket 管道 上运行良好。 让 mssqlazure devops 上工作仍然没有运气。虽然它确实提供了正在运行的数据库的大量 docker 详细信息,但它也无法正常工作,但是再一次,没有人真正关心 bitbucket 管道的时间只有 50 分钟。您可以在引用的存储库中看到所有这些管道,它们都是公开的,由于它是开源的,因此也可以进行拉取请求。

【问题讨论】:

vmImage: 'ubuntu-16.04'改成vmImage: 'ubuntu-latest',我这边打印ID就成功了。可能 ubuntu-16.04 有点老了。 检查后,你是对的,这只是我的调试步骤之一。我添加了更多细节,即使在 ubuntu-latest 中我仍然遇到 sql 连接错误。 【参考方案1】:

根据Starain Chen [MSFT] 在https://developercommunity.visualstudio.com/content/problem/1159426/working-examples-using-service-container-of-sql-se.html 的帮助。看起来需要 10 秒的延迟才能等待容器准备好。

添加

  - task: PowerShell@2
    displayName: 'delay 10'
    inputs:
      targetType: 'inline'
      script: |
        # Write your PowerShell commands here.
        
        start-sleep -s 10

使数据库连接工作。我假设到那时 mssql docker 容器可能已经准备好了。

【讨论】:

【参考方案2】:

过去几天我遇到了这个问题,并看到了你的帖子。我得到了同样的行为,然后点击了一些东西。

重要提示:如果您在 Windows 上使用 PowerShell 运行这些命令,请使用双引号而不是单引号。

该注释来自https://hub.docker.com/_/microsoft-mssql-server

我相信改变你的线路

options: -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=yourStrong(!)Password' -e 'MSSQL_PID=Express'

options: -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=yourStrong(!)Password" -e "MSSQL_PID=Express"

应该让它工作。我认为这也很有趣,在您在上面发布的链接中,密码作为自己的行传入,这可能解决了问题,不一定是 10 秒的延迟。 (下例)

- container: mssql
  image: mcr.microsoft.com/mssql/server:2017-latest
  env:
    ACCEPT_EULA: Y
    SA_PASSWORD: Password123
    MSSQL_PID: Express

【讨论】:

这在开发操作管道的所有实例中都与 b/c 无关,他们在 linux 机器上使用 docker vms,因此甚至不使用 powershell。实际上,您无法在 azure devops windows 容器中运行数据库 docker b/c 它们并不真正受支持(实际上我认为是 windows 容器而不是 docker)。 好的,我无法让它与单引号一起工作,然后当我切换到双引号时它就开始工作了。也不需要 10 秒的延迟。 这是在哪个环境中的? github、azure devops、gitlab? Azure Devops 管道 这是真正的答案,谢谢@Guyapino

以上是关于如何让 MSSQL 服务容器在 Azure DevOps 管道中工作?的主要内容,如果未能解决你的问题,请参考以下文章

使用ARM模板在Azure中国大规模部署DCOS集群

使用ARM模板在Azure中国大规模部署DC/OS集群

[Azure/mssql]如何获取插入查询记录集

如何使 Azure 应用服务容器崩溃

使用 Azure Active Directory 连接到 MSSQL 服务器的 JDBC

如何从 Azure 容器应用服务向 Azure ACR 进行身份验证