类别档案:Docker

发布一个包含VS2017机密的单一Image Docker容器并在Azure上运行它

(提前写,但在5月2日相关文章最终出版时出版。)

我刚刚完成了一个由三部分组成的系列文章,内容是构建一个容器化的ASP.NET核心API,该API使用EF核心进行数据持久化。所有这些都是在vs 2017中完成的,我利用了docker的vs2017工具。

该系列文章将于今年4月出版。5月和6月出版的《MSDN杂志》。

第1部分:码头集装箱化应用程序中的ef核心,2019年4月

第2部分:码头集装箱化应用程序中的ef核心,2019年5月

但我没有足够的空间来完成部署我编写的应用程序的重要任务,尽管我努力工作。好,部署非常简单,但是为了处理存储用于连接到我的Azure SQL数据库的密码,还有一些新的步骤需要完成。我将在这篇博文中转达这些步骤。

我的API使用EF核心并以一个Azure SQL数据库为目标。无论我在本地调试IIS还是Kestrel,在Docker容器内进行本地调试,或者在服务器或云上运行应用程序,我总是可以访问那个数据库。

这意味着我有一个连接字符串要处理,但我想保持密码的秘密。

解的结构在这里。我的ASP.NET核心API项目是DataApidocker。因为我使用docker工具来添加容器编制,我在docker-compose解决方案中有另一个文件夹。

形象

我将在本文的第2部分(2019年5月的一期)中详细介绍,但底线是在docker-compose.yml文件中使用docker环境变量。

版本:“3.4”

服务:
dataapidocker:
图片:$ {DOCKER_REGISTRY -} dataapidocker
建造:
背景:。
dockerfile:dataapidocker/dockerfile
环境:
-布兰达

在环境映射中,我有一个序列项,我在其中定义db_pw键,但不包括值。因为那里没有价值,Docker将查看主机的环境变量。因为我只是在调试,我在系统上用密码值创建了一个临时环境变量,当我从VS2017调试或运行应用程序时,将找到密码变量。环境变量被传递到正在运行的容器中,我的应用程序有读取它的代码,并在teh连接字符串中包含密码。

所以它是独立的,漂亮整洁。

将图像发布到Azure的ACI注册表

一旦你的应用程序运行起来了,是时候发布它了。但我们用的是Docker,所以你不发布应用程序,但可以为你运行应用程序的Docker图像。Docker工具也会对此有所帮助。

右键单击项目并选择“发布”。

形象

然后您将需要创建一个发布概要文件。这个概要文件的一部分是选择在哪里发布图像。这里你有选择。我有一个VIsual Studio订阅,如果我想的话,可以将它发布到Azure容器注册中心或Docker Hub或其他注册中心。

形象

我写这篇博文的目的是把图片放到Azure容器注册表中,所以这是我的选择。您的Azure帐户中可以有多个容器注册。您可以在一个注册表中存储任意数量的图像。好,可能存在技术或财务限制,但关键是,一个注册表中可以有多个图像。我不是来这里为如何管理Azure财务提供建议的,如何完成任务。

这是我让发布工具为我创建的注册表的概述页面。我圈出了链接,以查看可以访问您的图像的存储库。

形象

您可能有不同版本的特定图像,因此每个“集”是不同的存储库。我有三个储存库,我一直在那里进行试验。

形象

DataAPI只有一个图像,发布工具自动将其标记为“最新”给我。我可以在不同的标签下有其他版本。

回到Visual Studio,在浏览了发布工具关于创建新存储库的问题之后,最后一步是进行发布,发布将构建图像并将其推送到目标存储库。请记住,您希望将VS2017设置为运行版本构建,不是调试版本。

如果这是您第一次将此图像推送到存储库,该工具还将推送应用程序DockerFile中列出的ASP.NET核心SDK和运行时映像。

我很惊讶看到这个,想知道为什么Azure不只是从Docker Hub上获取它们,为什么我要直接上传那些大文件。当然,我在推特上表达了我的困惑:

故事还有很多,但它超出了我在这里的目标范围。

这个注册表的一个很酷的特性是,您可以右键单击并运行一个图像。如果你不想安排一些图像,这很好,而且与我的情况相匹配。此图像确实独立运行。

右键单击图像并选择“运行实例”。Azure将创建一个容器并将其作为Azure容器实例。尽管首先需要为实例定义规范。

形象

这有点不可思议,因为如果容器是一个简单的应用程序,您不必创建和管理一个虚拟机来运行它。

容器实例的环境变量如何?

该实例将运行,但需要从Azure SQL数据库中读取的杂志控制器将失败,因为我们没有提供容器希望通过主机的环境变量提供的密码。对于我的图像,右键单击并运行还不够。

在这里我要读很多书,研究和实验,直到我找到解决方案。(请记住,如果我在自己设计的虚拟机上运行这个程序,当您手动调用docker run时,您可以直接将变量传递进来。)

有两种方法可以为容器实例提供环境变量。

一,通过入口,表示不是右键单击图像,您需要首先在Azure中创建一个新的容器实例并指向该映像。此路径允许您在配置中最多分配3个环境变量:
形象

使用动态变量传递到容器中

我将进行第一次传递,创建一个动态变量以传递给environmentvariable。然后我将向您展示如何使用Azure密钥库

EnvironmentVariable需要一个散列表。

创建一个新的变量(我将称之为envvars,以纪念我学习到的资源),并分配一个键值对:

$envvars=@'db_pw'='eiluj'

另一个棘手的部分是提供访问注册表中映像的凭据。在使用门户创建容器时,我们不必这样做,因为我们已经提供了容器。但现在我需要提供它们。

您需要从存储库中获得用户名和密码:

然后,可以使用PowerShell根据密码创建安全字符串,然后使用该安全字符串和用户名创建PowerShell凭据对象。

提示:如果您有多个订阅,确保您指向的是目标资源组所在的正确位置。

提示:在cloud shell中,您可以做的一件很酷的事情是键入DIR来列出您的订阅,然后使用CD进入正确的目录!检出的PowerShell云外壳快速启动详情

小贴士:如果像我一样,为了体验因果关系,你把数据库搞得一团糟,记住在我的示例代码中,在应用程序启动时迁移数据库。如果将它放在容器中,这意味着何时运行容器实例。如果你运行容器,然后删除数据库,在容器再次旋转之前,您不会再次看到数据库。停止和重新启动具有相同的效果。当然,这只是为了测试一下,不生产!再一次,有件事让我困了一个多小时,直到我有了一个“啊哈”的时刻。

创建一个密钥库并添加我的密码

关于我即将到来的交付敏捷会议的视频

下周我将在敏捷联盟技术会议上发言,亚博国际网页在田纳西州纳什维尔实现敏捷。我的演讲题目是“用Docker开发和测试数据库的敏捷性”。我和田径运动主席理查德·血清素谈了这个话题。

Julie Lerman Deliver:2019年敏捷采访Richard Serateryabo官网敏捷联盟维米欧

关于docker compose中env文件的一个小教训

最近我和Docker一起工作了很多,学习学习。我已经为我的msdn mag数据点列这将在四月出版,2019年5月和6月发行。我还有另一篇裕固族博客文章,我将在五月的文章中发表。我在研究其他人。

我研究了Docker环境变量以及将它们输入Docker映像或容器的不同方法。

我的docker compose文件引用了一个名为db_pw的环境变量,但没有指定其值。

dataapidocker:
图片:$ {DOCKER_REGISTRY -} dataapidocker
建造:
背景:。
dockerfile:dataapidocker/dockerfile
环境:
-DPY-PW

Docker将从主机读取环境变量以发现该值。

但这是一种痛苦。我没有在开发机器上永久性地存储db_pw,必须经常记住设置它。EltonStoneman(来自Docker)说我真的应该考虑使用Docker env文件特性。这允许您在环境文件中设置变量,并让Docker编写从中读取的文件。我可以把那个特殊的文件放在我的源代码管理之外。(我总是担心!)

我从下面的文档开始,其中显示使用一个名为any .env的文件。我创建了一个名为hush-hush.env的文件,在其中我指定了变量。这是文件的完整内容:

db_pw=大秘密

然后在Docker Compose中,在服务,env_文件标记允许您指向它。甚至可以删除YML文件中的环境标记。

dataapidocker:
图片:$ {DOCKER_REGISTRY -} dataapidocker
建造:
背景:。
dockerfile:dataapidocker/dockerfile
文件:
- HuSH HuS.Env

这很管用。我的应用程序能够在代码中发现环境变量。

但后来我改进了我的解决方案,为我的数据库使用另一个容器。主容器依赖于新的MSSQL容器。mssql容器要求我将数据库密码作为环境变量传入。由于DB_PW已经存在,通过替换(通过花括号),我可以很容易地做到这一点。这是新的Docker撰写文件:

版本:“3.4”
服务:
dataapidocker:
图片:$ {DOCKER_REGISTRY -} dataapidocker
建造:
背景:。
dockerfile:dataapidocker/dockerfile
文件:
- HuSH HuS.Env
依赖性:
-DB
分贝:
图片:mcr.microsoft.com/mssql/server
卷:
-mssql服务器julie data:/var/opt/mssql/data
环境:
sa_密码:“$db_pw”
接受“Y”
端口:
-“1433∶1433”
卷:
MSSQL服务器Julie数据:

这里有一个操作顺序问题。当我构建docker-compose文件时,它抱怨DB U PW不可用,我的应用程序出现故障。DB服务未获取my hush-hush.env文件的内容。我尝试了很多事情,例如向db服务添加env_file。最后,这就是我学到的。

替换使用要求在Docker Compose中定义db_pw变量。我在主服务中添加了这个,但它并没有从hush-hush.env得到价值。

但是您可以有一个没有名称的.env文件。扩展名*是文件的全名。docker compose将足够早地读取它,并将.env文件中的值提供给声明的db_pw。然后所有的碎片都到位了。将mssql容器的db_pw值作为其环境变量进行拆分。我的应用程序代码能够读取docker为自己的任务传递到运行容器中的环境变量。

最后一个docker-compose.yml文件如下:

版本:“3.4”
服务:
dataapidocker:
图片:$ {DOCKER_REGISTRY -} dataapidocker
建造:
背景:。
dockerfile:dataapidocker/dockerfile
环境:
-DPY-PW
依赖性:
-DB
分贝:
图片:mcr.microsoft.com/mssql/server
卷:
-mssql服务器julie data:/var/opt/mssql/data
环境:
sa_密码:“$db_pw”
接受“Y”
端口:
-“1433∶1433”
卷:
MSSQL服务器Julie数据:

它依赖一个名为“.env”的文件定义了变量键值对(与上面的hush-hush.env相同)。

db_pw=大秘密

资源:
https://docs.docker.com/compose/environment-variables网站/