65.9K
CodeProject 正在变化。 阅读更多。
Home

我们为什么要关心用于开发的容器

starIconstarIconstarIconstarIconstarIcon

5.00/5 (3投票s)

2018年6月4日

CPOL

4分钟阅读

viewsIcon

11397

为什么我们应该关心用于开发的容器

Why should we care about containers for development

在你的开发生涯中,可能不止一次花费几个小时来排除问题,结果发现是依赖项或版本问题,对吗?

环境之间的差异,过时的组件和设置开发机器都是我们可以避免的令人沮丧的事情。

我们已经用虚拟机解决了其中一些问题,但是管理整个机器并为每个环境过度利用它们是昂贵的。这就是容器出现来解决许多挑战的地方。

为什么选择容器

毫无疑问,在过去一年或更长时间里,你已经听到了关于容器的各种消息。如果不是容器,那么就是一些与之相关的技术、框架或工具;Docker、Kubernetes、微服务只是其中的几个。从开发人员的角度来看,有哪些好处?

在我的机器上可以运行

你的代码或应用程序部署到的每个环境都可能不同。服务器的数量、CPU、RAM等的配置可能因开发、质量保证和生产而异,并且不能保证应用程序的性能相同。使用容器提供了在启动时定义这些参数的能力,以便每个镜像都具有相同的要求,而不管它部署在哪里。

docker run --cpus=2 --memory=1.5g myapp 

微服务

由许多服务组成的应用程序可能不是用相同的语言或框架开发的。例如,如果你正在使用 .NET Core 开发一个服务,该服务调用一个用 Node.js 或 Go 编写的下游服务,则负责该服务的开发团队可以构建容器镜像并在你的私有注册表中提供它。

使用docker-compose文件,你可以导入该容器镜像,而无需在你的机器上安装 Node.js 或 Go,并针对开发版本测试你的调用。

services:

  nodeservice:
    image: nodeservice:dev
    environment:
      - NODE_ENV=Development

  namesweb:
    depends_on:
      - nodeservice
    image: namesweb
    build:
      context: .
      dockerfile: namesweb/Dockerfile
    environment:
      - NODE_SERVICE_ENDPOINT=NodeService-Dev
    ports:
      - "57270:80"

测试数据

很少有应用程序不涉及数据,并且在本地维护生产系统的实例可能是一项任务。安装工具、平台、服务器等,以及使所有这些项目保持最新状态,远远超出了你作为开发人员可能想要担心的事情。

在此 docker-compose 文件中,启动了 Linux 上的 SQL Server 实例,并使用脚本文件创建了测试数据库,最后,使用批量复制工具加载了测试数据。

version: '3.0'  
services:

  mssql:
    image: microsoft/mssql-server-linux:latest
    container_name: mssql
    ports:
      - 1433:1433
    volumes:
      - /var/opt/mssql
      # we copy our scripts onto the container
      - ./sql:/usr/src/app
    # bash will be executed from that path, our scripts folder
    working_dir: /usr/src/app
    # run the entrypoint.sh that will import the data AND sqlserver
    command: sh -c ' chmod +x ./start.sh; ./start.sh & /opt/mssql/bin/sqlservr;'
    environment:
      ACCEPT_EULA: 'Y'
      SA_PASSWORD: P@$$w0rd

start.sh

#!/bin/bash
wait_time=20s

echo creating resources in $wait_time  
sleep $wait_time  
echo starting...

echo 'creating Names DB'  
/opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P $SA_PASSWORD -i ./init.sql

echo 'creating Names Table'  
/opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P $SA_PASSWORD -i ./data/NameTable.sql

echo 'importing data...'  
# Bulk load data from a csv file
/opt/mssql-tools/bin/bcp Names in data/Names.csv -S 0.0.0.0 -U sa -P $SA_PASSWORD -d Names -c -t ','

echo 'add uniqueid column'  
/opt/mssql-tools/bin/sqlcmd -S localhost -d Names -U SA -P $SA_PASSWORD -I 
-Q "ALTER TABLE Names ADD ID UniqueIdentifier DEFAULT newid() NOT NULL;"

echo 'checking data'  
/opt/mssql-tools/bin/sqlcmd -S localhost -d Names -U SA -P $SA_PASSWORD -I 
-Q "SELECT TOP 5 ID,FullName FROM Names;"

init.sql & NameTable.sql

DROP DATABASE Names

CREATE DATABASE Names;  
GO

USE Names;  
GO

CREATE TABLE Names(  
  LastName nvarchar(max),
  FirstName nvarchar(max),
  FullName nvarchar(max)
);
GO  

使用此测试数据库镜像,加载生产数据的子集并供应用程序使用。container_name: mssql 设置为连接字符串的服务器名称。应用程序现在需要做的就是更改设置以连接到此服务器。

如果你为所有容器使用 docker-compose,则会自动处理 DNS 名称解析。要单独使用数据库容器,请使用命令 docker inspect -f "{{ .NetworkSettings.IPAddress }}" <containerId> 获取 IP 地址。

"ConnectionStrings": {
    "NamesConnection": "Server=mssql;Initial Catalog=Names;User=sa;
                        Password=P@55w0rd;MultipleActiveResultSets=true"
  }

部署

部署应用程序从来都不是一件容易的事,对吗? 故障回滚更加困难,有时,这本身几乎就是另一次部署。

无论你是使用完整的 CI/CD 系统来构建你的容器,通过 docker build 使用命令行工具,还是使用 Visual Studio Docker Tools;从注册表部署到主机时,所有依赖项都隔离到镜像中,它仍然是同一个容器。

如果部署有问题,事情确实会出错,将部署回滚一个版本可以简单地将镜像的版本号从 1.1 更改为 1.0,你的应用程序就会重置。

摘要

容器为我们的应用程序及其依赖项提供了一种打包和部署机制。容器注册表是一个强大的概念,可以帮助部署和分发我们的应用程序。

当我们在本地工作时,特别是当我们倾向于构建微服务而不是单体应用程序时,容器还可以改善我们开发的“内部循环”。它们在本地和远程环境(包括云)之间提供更大的奇偶性,并帮助我们的基础设施变得更加不可变。

围绕容器的充满活力的工具生态系统也帮助我们使用云原生平台和开发方法。无论我们是使用无服务器容器、支持容器的 PaaS 平台,还是像 Kubernetes 这样的编排器,我们都专注于我们的应用程序,而不是考虑和管理我们部署到的单个或多个主机。

资源

© . All rights reserved.