转自:https://medium.com/notbinary/the-twelve-factor-container-8d1edc2a49d4?%24identity_id=550978996201189678&feature=Share&type=0&duration=0&data=eyIkb2dfdGl0bGUiOiLigJxUaGUgVHdlbHZlLUZhY3RvciBDb250YWluZXLigJ0iLCIkY2Fub25pY2FsX3VybCI6Imh0dHBzOlwvXC9tZWRpdW0uY29tXC9wXC84ZDFlZGMyYTQ5ZDQiLCIkb2dfaW1hZ2VfdXJsIjoiaHR0cHM6XC9cL2Nkbi1pbWFnZXMtMS5tZWRpdW0uY29tXC8wKnhfS09scmc1ZkdMX1JTSnkiLCIkcHVibGljbHlfaW5kZXhhYmxlIjoidHJ1ZSIsIiRkZXNrdG9wX3VybCI6Imh0dHBzOlwvXC9tZWRpdW0uY29tXC9wXC84ZDFlZGMyYTQ5ZDQiLCIkYW5kcm9pZF91cmwiOiJodHRwczpcL1wvbWVkaXVtLmNvbVwvcFwvOGQxZWRjMmE0OWQ0IiwiJGlvc191cmwiOiJodHRwczpcL1wvbWVkaXVtLmNvbVwvcFwvOGQxZWRjMmE0OWQ0Iiwic291cmNlIjoiYW5kcm9pZCJ9

Containers hit the tech headlines around 2013 and are now more the rule than the exception. I had the privilege of working with a forward-thinking team in a well known government organisation around that time and by 2015 was running Docker in production.

This project delivered a seismic shift in the ability of the organisation to not only deliver, but deliver at pace. Let’s be clear, containers were only part of that success. The team was the first to be able to work from an agile mindset, we prioritised a high-performing culture and, crucially, the sponsorship and support of transformational leadership made the project possible.

Within this generative structure of strong culture and leadership, on a practical level, the system used containers and microservices, but that wasn’t what made it work.

What really made the difference, day-to-day for pace, progress and results, was a discipline of simplicity in design.

Simplicity not just in technology design, but also in how we expressed agile, designing our work environment and iterating our processes to minimise friction and fit the dynamic of the team. From user experience to team culture to architecture, design made it work.

The twelve factor app

The twelve factor app is an influential collection of practical design principles which grew out of the experiences of the team at Heroku. If you work with technology and haven’t come across them, I’d encourage you get to know them: https://12factor.net

These principles speak softly and carry big sticks.

I see in them the kind of hard-won ease that flows from experience and mastery. Along with the Government Design Principles, 12factor is one of my go-to resources, providing a demanding framework in which I can draw out great design.

I’ve found myself returning to the twelve factors with the work of my current team and it’s got me thinking: I don’t suffer out-of-context design lightly, whether from myself or from others. Technical architects expounding me-too aspirations of Google or Netflix scale platforms don’t end well with me.

So I’m taking my own test. The twelve factors make sense for single-deployable monolithic web applications, but do they still make sense in containers?

Unboxing the twelve factors

Let’s summarise and contextualise. To quote the introduction:

Our motivation is to raise awareness of some systemic problems we’ve seen in modern application development … and to offer a set of broad conceptual solutions to those problems

I’ve learnt over the years that when it comes to delivery, it’s important to be specific before generic. Generic is really, really, really hard. Which is why aspirations of reuse are more likely to harm than help a project.

I’ve also learnt that more often than not the right answer is not binary.

Running through those specific designs and implementations there are, nonetheless, generic patterns. Good principles make terrible laws, but held lightly, they provide helpful constraints that might guide you towards a range of good answers.

Specific and generic

I’m arriving in a place. From here my view is that specific detail is as useless as generic platitude when either ignores or belittles the other. In teams, the unit of delivery is the collective and in design the unit of delivery is “yes, and” — depolarising without losing creative tension. A multidisciplinary team where each person knows they are individually necessary but not sufficient for delivery is when a team works.

So I like broad concepts. A lot.

My favourite Government Design Principle is “Do less”. To me it speaks of the twin traits of humility and confidence. When found together, there’s no need to hide behind a smokescreen of vagueness and clutter. Specific, direct, polite. Clarity is a gift of character. At the same time, “do less” yields no value on its own, until the principled rubber hits the specific road.

Show me an architecture with one too many boxes in it and I’ll say “How could we do less here? What can we subtract to make this better?” If complexity can’t be justified, it’s complicatedness. That’s a red flag for delivery, for maintenance and for surviving the rigours of production. It’s unacceptable risk and it needs to go.

So I like specifics. A lot.

And I see that these aren’t a contradiction. So lets look at the twelve factors in the specific context of containers.

The twelve

Let’s take a look at each of the principles and how they sit in a container world:

  1. One codebase, tracked in revision control: to quote, “There is always a one-to-one correlation between the codebase and the app”. In this case an app would correlate to a container, probably a microservice.
  2. Explicitly declare and isolate dependencies: this principle is well supported in a world of containers. “A twelve-factor app never relies on implicit existence of system-wide packages”, which is very much what container isolation gives you. A container really can contain only the files needed to do its work. With a bit of effort and determination the number of files can be counted on the fingers of one hand.
  3. Store config in the environment: if there’s a sweet spot for how containers constrain your design to improve yours results, this could well be it. Increasingly it feels uncomfortable to do self-harming things. If you’ve come across the term “immutable artifact”, the idea that software should be built once and the resulting “artifact” deployed unchanged in each environment to avoid unpredictable variations, this is it. The container is the unit of immutable deployment and the config values provided by an environment are the wiring that plugs it in to the rest of the system.
  4. Treat backing services as attached resources: when it comes to databases, queues and file storage, containers nudge you further away from storing data and state in the app. In a world where containers can appear and disappear by the bucketload from moment to moment, it becomes really important to externalise data storage. It then becomes ever clearer that delegating the operation of data storage components to your cloud provider makes sense— they’re an externality that’s going to distract from your core value.
  5. Strictly separate build and run stages: this one’s a no-brainer with containers. You build an image, push it to a registry and then pull it to a target machine to run as a container. There are ways to muddy this, but you’ll have to work ever harder to make life difficult for yourself in this respect.
  6. Execute the app as one or more stateless processes: here again, containers take 12-factor a step further. They really are only designed to be a single process, isolated inside a dedicated filesystem. You absolutely can insist on finding ways to get around this, but I think you’ll find pretty quickly that your code smells riper than a well-aged blue cheese. Accept the constraint, it’s good for your design.
  7. Export services via port binding: this one may not be obvious at first, so here’s a quote: “The contract with the execution environment is binding to a port to serve requests”. This typically holds true for containerised microservices — all the gubbins needed to respond to requests is included in the container image and the only way to connect to the service is via a port on the container. One particularly neat thing about containers is that each one has a separate address space, so there’s potentially even less effort needed to figure out which port to bind to.
  8. Scale out via the process model: the 12-factor approach to concurrency and scaling is “horizontal” or “scale out”. Containers are very much designed with this idea in mind. With a stateless design, you should normally be able to run multiple copies of it to provide additional capacity. This principle is a default assumption in Docker Compose, Docker Swarm and Kubernetes.
  9. Maximize robustness with fast startup and graceful shutdown: the principle of disposability is a corollary to the ability to scale out. If you can start an additional dozen copies of a microservice, you’ll also want to design for the ability to take instances out of service, whether for reduced capacity or rolling updates. I’ll touch on startup time here as it’s a serious point of friction that I’ve seen ignored in architecture conversations, particularly where there’s a preference for using the JVM, (Java Virtual Machine) especially with the Spring framework. Slow starts (by which I mean anything over one second) destroy both development cycle time and operational agility whilst loading up your cloud hosting bill. In short, expect to pay a lot of money for not a lot of progress. Don’t shoot the messenger.
  10. Keep development, staging, and production as similar as possible: this is a big one for containers. Assuming you’re building an image once, in a predictable way, and deploying it to your environments, this is going to help you ensure you’re running exactly the same build in each environment. There’s more to this principle, but I think it’s good to highlight that here again containers are providing a nudge towards 12-factor design.
  11. Treat logs as event streams: this is one of my favourite container wins. Log rotation was great fun, but ultimately added no real value to applications. I don’t think I’ve seen anyone argue with the practice of writing logs to stdout and allowing them to be routed to the container runtime or off to log storage and analysis — ELK, Prometheus, InfluxDB, Stackdriver — the list is long and varied (and your mileage likewise).
  12. Run admin/management tasks as one-off processes: if you’ve ever considered that containers have a lot of similarities to functions (e.g. Lambda, GCP functions) then this principle makes perfect sense. If you’ve come across the intricate solutions that have been touted over the years for database migrations, you may agree that none of them are particularly elegant they generally hang around in your production code like an awkward gooseberry after startup. Putting a one-off task into a one-shot container that starts, does its work and then exits, is a great way to keep things clean.

The design nudge

For me it’s clear that containers are a natural extension of 12-factor thinking. Ultimately, the ability to do anything at any time isn’t helpful, so convergence at a design level, whilst maintaining an open mind on specifics, helps us bring useful lessons into individual situations.

Design constraints give you nudges and apply pressure to help narrow your options and make you think harder about what good looks like.

 
 
 
 

The Twelve-Factor Container的更多相关文章

  1. AspNet Identity and IoC Container Registration

    https://github.com/trailmax/IoCIdentitySample TL;DR: Registration code for Autofac, for SimpleInject ...

  2. Bootstrap《第一篇》,关于container、jumbotron、row、col、text-center等的学习

    一.关于引入bootstrap文件 <!-- 为了确保适当的绘制和触屏缩放,需要在 <head> 之中添加 viewport 元数据标签. --> <meta name= ...

  3. 【LeetCode算法题库】Day4:Regular Expression Matching & Container With Most Water & Integer to Roman

    [Q10] Given an input string (s) and a pattern (p), implement regular expression matching with suppor ...

  4. Java Container ***

    Java Container ArrayList 和Vector是采用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,都允许直接序号索引元素,但是插入数据要设计到数组元素移动等内存 ...

  5. 关于Container容器以及IoC注入机制的认识

    container 容器的概念: 1 container 是一个Java 所编写的程序,用于对象之间之间管理对象关系. 主要的java EE 容器如下: Java容器类包含List.ArrayList ...

  6. 12 Factor App

    The Twelve-Factor App Introduction In the modern era, software is commonly delivered as a service: c ...

  7. 在docker中运行ASP.NET Core Web API应用程序(附AWS Windows Server 2016 widt Container实战案例)

    环境准备 1.亚马逊EC2 Windows Server 2016 with Container 2.Visual Studio 2015 Enterprise(Profresianal要装Updat ...

  8. .Container与.container_fluid区别

    .Container与.container_fluid是bootstrap中的两种不同类型的外层容器,两者的区别是:.container 类用于固定宽度并支持响应式布局的容器..container-f ...

  9. View and Data API Tips: Constrain Viewer Within a div Container

    By Daniel Du When working with View and Data API, you probably want to contain viewer into a <div ...

随机推荐

  1. js 数组的拷贝

    在js中,数组Array是引用类型,直接将数组赋值给一个变量名,二者所指向的地址是一样的. 所以直接复制数组会产生意想不到的结构. 要想解决拷贝一个数组但是对副本的修改不影响原来的数组,有以下方式: ...

  2. 《温故而知新》JAVA基础七

    抽象类 定义:抽象类前面使用abstract关键字修饰(只用语被继承) 应用场景: 在父类中写一些子类中即将实现的方法,具体的实现在子类中写,也可以将多种特征相同的类抽离出来 使用规则 abstrac ...

  3. Resnet-34框架

    import torch import torch.nn as nn import torch.nn.functional as F class ResidualBlock(nn.Module): ' ...

  4. [Hibernate] official tutorial - userguide

    Persistence contexts org.hibernate.Session API and javax.persistence.EntityManager API represent a c ...

  5. 微信小程序的布局css样式

    微信小程序的布局css样式width: fit-content;font-size:20px;      /*设置文字字号*/color:red;           /*设置文字颜色*/font-w ...

  6. Oracle单机Rman笔记[0]---环境准备

    A. 安装操作系统rhel6.6,关闭防火墙,修改网卡配置IP(略)PS:1.默认分区选项(第二项,默认为LVM),然后进行调整2.安装类型选择“桌面”3.安装后 分配IP.调整防火墙.测试SSH B ...

  7. 转载:VC++6.0注释快捷键设置,略有修改

    在Qt Creator,eclipse等编辑器中,都默认有注释代码的快捷键:Ctrl + /. 注释快捷键在程序编程当中的作用相当明显,提高了编程效率.我在网上找到了一个在VC++6.0工具中添加注释 ...

  8. java使用StringBuilder的方法反转字符串输出

    public class FanZhuan { public static void main(String[] args) { /**第一种方法*/ String s = "9876543 ...

  9. 19_04_02校内训练[deadline]

    题意 给出一个二分图,左边为A集合,右边为B集合,要求把A集合中每一个点染为黑白两色中的一种,B集合中的颜色已定.染色后对于原本相邻且颜色相同的点,建立新的二分图,即得到了两个新的二分图,它们是独立的 ...

  10. mac 常用终端命令

      mkdir 文件夹夹名称 创建一个文件夹 cd 文件夹名称 进入该文件夹 git init 在该文件夹下创建一个git仓库 touch 文件名称 在该文件夹下创建一个文件 echo '内容' &g ...