在软件开发的各个阶段,环境的一致性和依赖管理始终是开发者面临的挑战。传统的虚拟机虽然提供了一定的解决方案,但它们往往资源利用率低,管理复杂。容器技术的出现,为这些问题提供了新的解决思路。
容器技术在过去几年中备受关注,无论是Docker、Kubernetes还是微服务架构,都与容器技术紧密相关。从开发者的角度来看,容器技术带来了哪些好处呢?
代码或应用程序部署的环境可能各不相同。服务器数量、CPU配置、RAM等可能在开发、测试和生产环境中有所不同,而且无法保证应用程序在这些环境中的表现一致。使用容器技术,可以在启动时定义这些参数,确保每个镜像无论部署在哪里都有相同的需求。
docker run --cpus=2 --memory=1.5g myapp
由多个服务组成的应用程序可能不是用同一种语言或框架开发的。例如,如果正在开发一个.NET Core服务,它调用了一个下游服务,该服务是用Node.js或Go编写的,那么负责该服务的开发团队可以构建容器镜像,并将其发布到私有注册表中。
version: '3.0'
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"
很少有应用程序不涉及数据。在本地维护一个生产系统的实例可能是一个挑战。安装工具、平台、服务器等,以及保持所有这些项目的最新状态,可能超出了开发者愿意担心的范围。
version: '3.0'
services:
mssql:
image: microsoft/mssql-server-linux:latest
container_name: mssql
ports:
- 1433:1433
volumes:
- /var/opt/mssql
- ./sql:/usr/src/app
working_dir: /usr/src/app
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...'
/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
SQL
DROP DATABASE Names
CREATE DATABASE Names;
GO
USE Names;
GO
CREATE TABLE Names(
LastName nvarchar(max),
FirstName nvarchar(max),
FullName nvarchar(max)
);
GO
部署应用程序从来都不是一件容易的事情,失败时回滚更是困难重重。无论是使用完整的CI/CD系统构建容器,还是通过命令行工具docker build或Visual StudioDockerTools,所有依赖项都被隔离在镜像中,当从注册表部署到主机机器时,它仍然是同一个容器。
如果部署出现问题,事情确实会出错,回滚一个版本的部署可以像更改镜像的版本号一样简单,从1.1改为1.0,应用程序就会重置。