转自: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. Maven提示找不到dependency依赖包

    最近C盘爆炸,又重装了一下系统,打开之前创建的Maven项目,提示找不到仓库里的jar包了 我更新了Maven,重新加载都没用,我去系统盘查看的时候发现了这么一个情况: 我在装WIN10的时候用的是U ...

  2. rabbitMQ 的三种Exchange

    rabbitMQ 的Exchange有3种路由方式:  direct.fanout.topic ,以下为详细说明 1.  Direct Exchange 处理路由键.需要将一个队列绑定到交换机上,要求 ...

  3. IOS 下载app

    ---------------------------------------------------------------------------------------------------- ...

  4. 美国FLAG和中国BAT的比较(王益)

    美国FLAG和中国BAT的比较(王益) http://cxwangyi.github.io/notes/2014-09-29-flag-vs-bat.html 知乎 http://www.zhihu. ...

  5. 版本控制工具Git的复杂用法的情境分析

    Git的版本库中的文件的三种状态 对于任何一个文件,在 Git 内都只有三种状态: 已提交(committed),已修改(modified)和已暂存(staged). 已提交表示该文件已经被安全地保存 ...

  6. RMAN 的优缺点及RMAN 备份及恢复步骤

    一. RMAN 备份的一些优点和OS命令备份方式相比,使用RMAN的优点 1  备份执行期间不需要人工干预,因此减少了误操作的机会:2  可以有效的将备份和恢复结合起来:3  支持除逻辑备份以外的所有 ...

  7. 7——ThinkPhp中的响应和重定向:

    public function index3(){ //响应数据: $data=['title'=>"标题部分","content"=>" ...

  8. angularjs 下滑线滑动

    css: .detail_row { width: 410px; height: 34px; clear: both; border-bottom: 1px solid #eaeeef; font-s ...

  9. LeetCode Best to buy and sell stock

    Best Time to Buy and Sell Stock 题目大意;给定数组a[..],求解max a[j]-a[i]    j>i 解决思路:将数组a的相邻值相减(右边减左边)变换成数组 ...

  10. Python之路,Day9 - 异步IO\数据库\队列\缓存

    https://www.cnblogs.com/alex3714/articles/5248247.html http://www.cnblogs.com/wupeiqi/articles/51327 ...