zoukankan      html  css  js  c++  java
  • 《Cloud Native Infrastructure》CHAPTER 4(2)

    The Reconciler Pattern(协调器模式)

    协调器模式是一种软件模式,可用于管理云原生基础设施或在其上进行扩展。该模式强制要求对基础设施的两种表示,第一种表示基础设施的实际状态,第二种表示基础设施的预期状态。

    The reconciler pattern is a software pattern that can be used or expanded upon for managing cloud native infrastructure. The pattern enforces the idea of having two representations of the infrastructure—the first being the actual state of the infrastructure, and the second being the expected state of the infrastructure.

    协调模式将迫使工程师有两个独立的途径来获得这些表示中的任何一个,以及实现解决方案以将实际状态调和到预期状态。

    The reconciler pattern will force the engineer to have two independent avenues for getting either of these representations, as well as to implement a solution to reconcile the actual state into the expected state.

    协调器模式可以看作是一套四种方法和四种哲学规则:

    1. 对于所有输入和输出都使用一个数据结构。
    2. 确保数据结构是不可变的。
    3. 保持资源映射简单。
    4. 使实际状态与预期状态匹配。

    The reconciler pattern can be thought of as a set of four methods, and four philosophical rules:

    1. Use a data structure for all inputs and outputs.
    2. Ensure that the data structure is immutable.
    3. Keep the resource map simple.
    4. Make the actual state match the expected state.

    这些都是模式的消费端可以依赖的有力保证。此外,它们将消费端从实现细节中解放出来。

    These are powerful guarantees that a consumer of the pattern can rely on. Furthermore, they liberate the consumer from the implementation details.

    Rule 1: Use a Data Structure for All Inputs and Outputs

    实现协调器模式的方法必须只接受一个数据结构并返回一个数据结构。该结构必须在协调器实现的上下文之外定义,但实现必须知道它。

    The methods implementing the reconciler pattern must only accept and return a data structure. The structure must be defined outside the context of the reconciler implementation, but the implementation must be aware of it.

    通过只接受一个数据结构作为输入并返回一个作为输出,消费端可以协调在其数据存储中定义的任何结构,而不必担心如何进行协调。这还允许在运行时或使用程序的不同版本来更改,修改或切换实现。

    By only accepting a data structure for input and returning one as output, the consumer can reconcile any structure defined in their data store without having to be bothered with how that reconciliation takes place. This also allows the implementations to be changed, modified, or switched at runtime or with different versions of the program.

    虽然我们希望尽可能多地遵守第一条规则,但是从不紧密地耦合数据结构和代码库也非常重要。 始终遵守最佳抽象和分离实践,并且永远不要使用API的子集传递(或接收)给函数或类。

    While we want to adhere(遵守) to the first rule as often as possible, it’s also very important to never tightly couple a data structure and codebase. Always observe best abstraction and separation practices, and never use subsets of the API to pass to/from functions or classes.

    Rule 2: Ensure That the Data Structure Is Immutable

    想象一下像契约或担保这样的数据结构。 在协调程序模式的上下文中,实际和预期的结构在运行时在内存中设置。 这保证了在结合之前,结构是准确的。 在协调基础设施的过程中,如果更改了结构,则必须创建具有相同保证的新结构。 明智的基础设施应用程序将强制执行数据结构不变性,这样即使工程师试图改变数据结构,它也不会工作,或者程序会出错(或者甚至可能无法编译)。

    Think of a data structure like a contract or guarantee. Within the context of the reconciler pattern, the actual and expected structures are set in memory at runtime. This guarantees that before a reconciliation, the structures are accurate. During the process of reconciling infrastructure, if the structure is changed, a new structure with the same guarantee must be created. A wise infrastructure application will enforce data structure immutability such that even if an engineer attempted to mutate a data structure, it wouldn’t work, or the program would error (or maybe even not compile).

    基础设施应用程序的核心组件是将“描述”映射到一组资源的能力。 资源是为了满足基础设施要求的需要运行的单个任务。 这些任务中的每一项都将以某种方式负责更改基础设施。

    The core component of an infrastructure application will be its ability to map a representation to a set of resources. A resource is a single task that will need to be run in order to fulfill the infrastructure requirements. Each of these tasks will be responsible for changing infrastructure in some way.

    基本示例可能是部署新虚拟机,设置新网络或配置现有虚拟机。 这些工作单元中的每一个都将被称为资源。 每个数据结构都应映射到一定数量的资源。 应用程序负责定义结构,并创建资源集。 有关API如何映射到各个资源的示例,请参见图4-1。

    Basic examples could be deploying a new virtual machine, setting up a new network, or provisioning an existing virtual machine. Each of these units of work will be referred to as a resource. Each data structure should map to some number of resources. The application is responsible for reasoning about(定义) the structure, and creating the set of resources. An example of how the API maps to individual resources can be seen in Figure 4-1.

    Figure 4-1 Diagram to map a structure to resources

    协调器模式示范了一种在数据结构改变资源时使用数据结构的稳定方法。因为协调器模式需要比较资源的状态,所以数据结构必须是不可变的。这意味着无论何时需要更新数据结构,都必须创建新的数据结构。

    The reconciler pattern demonstrates a stable approach to working with a data structure as it mutates resources. Because the reconciler pattern requires comparing states of resources, it is imperative that data structures be immutable. This dictates that whenever the data structure needs to be updated, a new data structure must be created.

    注意基础设施的变更。 每次发生变更时,实际的数据结构都会过时。智能的基础架构应用程序将意识到这一问题并相应地处理它。一个简单的解决方案是在发生变更时更新内存中的数据结构。 如果用每个变更更新实际状态,那么协调过程可以观察到实际状态随着时间的推移经历一系列的变化,直到最终与预期状态匹配并且协调完成。

    Be mindful of infrastructure mutations. Every time a mutation occurs, the actual data structure is then stale. A clever infrastructure application will be aware of this concern and handle it accordingly.A simple solution would be to update the data structure in memory whenever a mutation occurs. If the actual state is updated with every mutation, then the reconciliation process can be observed as the actual state going through a set of changes over time until it ultimately matches the expected state and the reconciliation is complete.

    Rule 3: Keep the Resource Map Simple

    协调器模式的背后是一个实现。实现只是一组代码,它们具有创建、修改和删除基础设施的方法。一个程序可能有许多实现。

    Behind the scenes of the reconciler pattern is an implementation. An implementation is just a set of code that has methods to create, modify, and delete infrastructure. A program might have many implementations.

    每个实现最终都需要将数据结构映射到一组资源。资源集需要以逻辑方式分组在一起,这样程序就可以对每个资源进行定义。

    Each implementation will ultimately need to map a data structure to some set of resources. The set of resources will need to be grouped together in a logical way so that the program can reason about each of the resources.

    除了创建资源的基本模型之外,您还必须非常注意每个资源的依赖性。许多资源都依赖于其他资源,这意味着许多基础设施依赖于已经就位的其他资源。例如,在将虚拟机放入网络之前,需要存在一个网络。

    Other than having the basic model of the resources created, you must give great attention to each resource’s dependencies. Many resources have dependencies on other resources, meaning that many pieces of infrastructure depend on other pieces to be in place. For example, a network will need to exist before a virtual machine can be placed in the network.

    协调器模式要求使用分组资源的最简单数据结构。

    The reconciler pattern dictates that the simplest data structure for grouping resources should be used.

    解决资源映射问题是一个工程决策,可能会因每个实现而改变。仔细选择数据结构是很重要的,因为从工程的角度来看,协调器需要稳定且易于表示。

    Solving the resource map problem is an engineering decision and might change for each implementation. It is important to pick a data structure carefully, as the reconciler needs to be stable and approachable from an engineering perspective.

    用于映射数据的两种常见结构是集合和图形。
    集合是可以迭代的资源的平面列表。 在许多编程语言中,这些被称为list、set、array等。
    图是通过指针链接在一起的顶点集合。 图的顶点通常是结构或类,具体取决于编程语言。 顶点通过在顶点某处定义的指向另一个顶点的指针的连接。 图形实现可以通过指针从一个顶点跳到另一个顶点来访问每个顶点。

    Two common structures for mapping data are sets and graphs.
    A set is a flat list of resources that can be iterated on. In many programming languages, these are called lists, sets, arrays, or the like.
    A graph is a collection of vertices that are linked together via pointers. The vertex of a graph is usually a struct or a class, depending on the programming language. A vertex has a link to another vertex via a pointer defined somewhere in the vertex. A graph implementation can visit each of the vertices by hopping from one to the other via the pointer.

    示例4-5是Go语言中基础的顶点的示例。
    遍历图的一个例子可能和递归地遍历每个子代一样简单。这种遍历有时称为遍历图。示例4-6是通过在go中编写的深度优先遍历递归访问图中每个顶点的示例。

    Example 4-5 is an example of a basic vertex in the Go programming language.

    // Vertex is a data structure that represents a single point on a graph. 
    // A single Vertex can have N number of children vertices, or none at all. 
    type Vertex struct {
    Name string
        Children []*Vertex
    }
    

    An example of traversing the graph might be as simple as recursively iterating through each of the children. This traversal is sometimes called walking the graph.
    Example 4-6 is an example of recursively visiting every vertex in the graph via a depth-first traversal written in Go.

    // recursiveWalk will recursively dig into all children, 
    // and their children accordingly and echo the name of 
    // the vertex currently being visited to STDOUT.
    func recursiveWalk(v *Vertex){
        fmt.Printf("Currently visiting vertex: %s
    ", v.Name) for _, child := range v.Children {
            recursiveWalk(child)
        }
    }
    

    Example 4-6. Depth-first traversal

    首先,图的简单实现似乎是解决资源图的合理选择,因为依赖关系可以通过以逻辑方式构建图来处理。虽然图表可以工作,但它也引入了风险和复杂性。实现图来映射资源的最大风险是图中有循环。循环是指图的一个顶点通过多条路径指向另一个顶点,这意味着遍历图是一个无止境的操作。

    At first, a simple implementation of a graph seems like a reasonable choice for solving the resource map, as dependencies can be handled by building the graph in a logical way. While a graph would work, it also introduces risk and complexity. The biggest risk with implementing a graph to map resources would be having cycles in the graph. A cycle is when one vertex of a graph points to another vertex via more than one path, meaning that traversing the graph is an endless operation.

    在必要时可以使用图,但是对于大多数情况,协调器模式应该用资源的集合而不是图表来映射。使用集合允许协调器按程序迭代资源,并提供解决映射问题的线性方法。此外,撤消或删除基础设施的过程与反向遍历集合一样简单。

    A graph can be used when necessary, but for most cases, the reconciler pattern should be mapped with a set of resources, not a graph. Using a set allows the reconciler to iterate through the resources procedurally and offers a linear approach to solving the mapping problem. Furthermore, the process of undoing or deleting infrastructure is as simple as iterating through the set in reverse.

    Rule 4: Make the Actual State Match the Expected State

    协调器模式中提供的保证是用户准确获得预期或错误。 这是消费协调器的工程师可以信赖的保证。 这一点非常重要,因为消费端不应该关注验证协调器变更是否是幂等的并且按预期结束。 实现最终负责解决这一问题。 有了保证,在更复杂的操作中使用协调器模式,例如控制器或op,现在变得更加简单。

    The guarantee offered in the reconciler pattern is that the user gets exactly what was intended or an error. This is a guarantee that an engineer who is consuming the reconciler can rely on. This is important, as the consumer shouldn’t have to concern themselves with validating that the reconciler mutation was idempotent and ended as expected. The implementation is ultimately responsible for addressing this concern. With the guarantee in place, using the reconciler pattern in more complex operations, such as a controller or operator, is now much simpler.

    在返回调用代码之前,实现应该检查新协调的实际数据结构是否与原始预期数据结构匹配。如果没有,就应该出错。消费者不应该关心自己是否验证了API,并且应该相信当出现问题的时候,协调器返回错误。

    The implementation should, before returning to the calling code, check that the newly reconciled actual data structure matches the original expected data structure. If it does not, it should error. The consumer should never concern themselves with validating the API, and should be able to trust the reconciler to error if something goes wrong.

    因为数据结构是不可变的,并且如果协调模式不成功,API将会出错,我们可以对API高度信任。 对于复杂的系统,重要的是您能够以可预测的方式信任您的软件工作或失败。

    Because the data structures are immutable and the API will error if the reconciler pattern is not successful, we can put a high level of trust in the API. With complex systems, it is important that you are able to trust that your software works or fails in predictable ways.

    The Reconciler Pattern’s Methods(协调器模式的方法)

    利用刚刚解释的协调器模式的信息和规则,让我们看看这些规则中的一些是如何实现的。我们将通过查看实现协调器模式的应用程序所需的方法来做到这一点。

    With the information and rules of the reconciler patterns we just explained, let’s look at how some of those rules have been implemented. We will do this by looking at the methods needed for an application that implements the reconciler pattern.

    协调器模式的第一个方法是GetActual()。这个方法有时被称为审计,用于查询基础设施的实际状态。该方法通过生成资源映射,然后程序调用每个资源来查看存在什么,如果有的话。该方法将根据查询更新数据结构,并返回表示实际运行内容的数据结构。

    The first method of the reconciler pattern is GetActual(). This method is sometimes called an audit and is used to query for the actual state of infrastructure. The method works by generating a map of resources, then procedurally calling each resource to see what, if anything, exists. The method will update the data structure based on the queries and return a populated data structure that represents what is actually running.

    更简单的方法GetExpected(),将从数据存储中读取预期的world状态。对于infrastructure.yaml示例(示例4-4),Getexpected()将简单地序列化此yaml,并以内存中数据结构的形式返回它。此步骤不执行资源审计。

    A much simpler method, GetExpected(), will read the intended state of the world from the data store. In the case of the infrastructure.yaml example (Example 4-4), GetExpected() would simply unmarshal this YAML and return it in the form of the data structure in memory. No resource auditing is done at this step.

    The most exciting method is the Reconcile() method, in which the reconciler implementation will be handed the actual state of the world, as well as the expected state of the world.
    最令人兴奋的方法是Reconcile()方法,其中协调程序实现将处理world的实际状态,以及world的预期状态。

    这是协调器模式的意图驱动行为的核心。 底层协调器实现将使用与GetActual()中相同的资源映射逻辑来定义一组资源。 然后,协调器实施将对这些资源进行操作,并独立地协调每个资源。

    This is the core of the intent-driven behavior of the reconciler pattern. The underlying reconciler implementation would use the same resource mapping logic used in GetActual() to define a set of resources. The reconciler implementation would then operate on these resources, reconciling each one independently.

    了解每个资源调节步骤的复杂性非常重要。 协调程序实现必须以两种方式工作。

    It is important to understand the complexity of each of these resource reconciliation steps. The reconciler implementation must work in two ways.

    首先,从期望和实际状态获取资源属性。 接下来,获取其差集属性,以使实际状态与所需状态匹配。

    First, get the resource properties from the desired and actual state. Next, apply changes to the minimal set of properties to make the actual state match the desired state.

    如果基础设施的两种表示在任何时候发生冲突,则协调器实现必须采取行动并改变基础设施。 协调步骤完成后,协调程序实现必须创建新表示,然后转到下一个资源。 在协调所有资源之后,协调程序实现将新数据结构返回给接口的调用者。 这个新的数据结构现在可以准确地表示world的实际状态,并且应该保证它与原始的实际数据结构相匹配。

    If at any time the two representations of infrastructure conflict, the reconciler implementation must take action and mutate the infrastructure. After the reconciliation step has been completed, the reconciler implementation must create a new representation and then move on to the next resource. After all the resources have been reconciled, the reconciler implementation returns a new data structure to the caller of the interface. This new data structure now accurately represents the actual state of the world and should have a guarantee that it matches the original actual data structure.

    协调模式的最终方法是Destroy()方法。 Destroy()这个词是故意选择,而不是Delete()的,因为我们希望工程师意识到该方法应该销毁基础设施,并且永远不会禁用它。 Destroy()方法的实现很简单。 它使用与前面实现方法中定义的相同的资源映射,但仅反向操作资源。

    The final method of the reconciler pattern is the Destroy() method. The word Destroy() was intentionally chosen over Delete() because we want the engineer to be aware that the method should destroy infrastructure, and never disable it. The implementation of the Destroy() method is simple. It uses the same resource mapping as defined in the preceding implementation methods, but merely operates on the resources in reverse.

    Example of the Pattern in Go

    示例4-7是在Go程序设计语言的四种方法中定义的协调器模式。

    Example 4-7 is the reconciler pattern defined in four methods in the Go programming language.

    // The reconciler interface below is an example of the reconciler pattern.
    // 只要用户打算根据可能随时间发生变化的状态改变基础架构,就应该使用它。
    // It should be used whenever a user intends on mutating infrastructure based on a  state that might have changed over time.
    type Reconciler interface {
    
        // GetActual不接受输入参数,并返回填充的数据结构以及可能的错误。
        // GetActual takes no arguments for input and returns a populated data structure as well as a possible error. 
        // 数据结构应包含基础设施的完整表示。
        // The data structure should contain a complete representation of the infrastructure.
        // 这有时称为审计。 应该使用此方法来实时表示存在的基础结构。
        // This is sometimes called an audit. This method should be used to get a real-time representation of what infrastructure is in existence.
        GetActual() (*Api, error)
    
        // GetExpected不接受输入参数,并返回一个填充的数据结构,表示操作者声明的基础结构,以及可能的错误。
        // 这有时称为期望或预期状态。 此方法用来获取实时的操作者预期存在的基础设施。
        // GetExpected takes no arguments for input and returns a populated data structure that represents what infrastructure an operator has declared to exist, as well as a possible error.          
        // This is sometimes called expected or intended state. This method should be used to get a real-time representation of what infrastructure an operator intends to be in existence.
        GetExpected() (*Api, error)
    
        // Reconcile takes two arguments.
        // actualApi is a populated data structure that is returned from the GetActual method. expectedApi is a populated data structure that is returned from the GetExpected method. 
        // Reconcile将返回一个填充的数据结构,该结构表示新的“实际”状态,以及可能的错误。
        // Reconcile will return a populated data structure that is a representation of the new "actual" state, as well as a possible error.
        // 根据定义,此处返回的数据结构应与GetExpected方法返回的数据结构相匹配。
        // By definition, the data structure returned here should match the data structure returned from the GetExpected method. 
        // 此方法负责变更基础设施。
        // This method is responsible for making changes to infrastructure.
        Reconcile(actualApi, expectedApi *Api) (*Api, error)
    
        // Destroy takes one argument.
        // actualApi is a populated data structure that is returned from the GetActual method. 
        // Destroy将返回一个填充的数据结构,它表示新的“实际”状态,以及可能的错误。
        // Destroy will return a populated data structure that is a representation of the new "actual" state, as well as a possible error. 
        // 根据定义,此处返回的数据结构应与GetExpected方法返回的数据结构相匹配。
        // By definition, the data structure returned here should match the data structure returned from the GetExpected method.
        Destroy(actualApi *Api) (*Api, error)
    }
    

    Example 4-7. The reconciler pattern interface

    The Auditing Relationship

    随着时间的推移,对我们基础设施的最后一次审计变得陈旧,增加了我们的基础设施表示不准确的风险。 因此,权衡是op可以改变审计的频率以确定基础设施描述的准确性。

    As time progresses, the last audit of our infrastructure becomes stale, increasing the risk that our representation of infrastructure is inaccurate. So the trade-off is that an operator can exchange frequency of audits for accuracy of infrastructure representation.

    一次协调是隐含的审计。 如果没有任何变化,协调器将检测到不需要做任何事情,并且操作变为审计,验证我们的基础设施表示是否准确。

    A reconciliation is implicitly an audit. If nothing has changed, the reconciler will detect that nothing needs to be done, and the operation becomes an audit, validating that our representation of our infrastructure is accurate.

    此外,如果在我们的基础设施中发生了某些变化,协调器将检测到变化并尝试纠正它。 完成协调后,基础设施的状态将保证准确。 因此,我们再次审计了基础设施。

    Furthermore, if there happens to be something that has changed in our infrastructure, the reconciler will detect the change and attempt to correct it. Upon completion of the reconcile, the state of the infrastructure is guaranteed to be accurate. So implicitly, we have audited the infrastructure again.

    一个轻量且稳定的协调器实现可以产生强大的结果,可以快速协调,使op对准确的基础设施的表示充满信心。

    A lightweight and stable reconciler implementation can yield powerful results that are reconciled quickly, giving the operator confidence in accurate infrastructure representation.

    Auditing and Reconciler Pattern in Configuration Management

    基础设施工程师可能熟悉配置管理工具中的协调器模式,这些工具使用类似的方法来改变操作系统。 配置管理工具传递一组资源,以便从工程师定义的一组manifest或recipe中进行管理。

    Infrastructure engineers may be familiar with the reconciler pattern from configuration management tools, which use similar methods to mutate operating systems. The configuration management tool is passed a set of resources to manage from a set of manifests or recipes defined by the engineer.

    然后,该工具将对系统采取措施,以确保实际状态和预期状态匹配。 如果未进行任何更改,则执行简单审计以确保状态匹配。

    The tool will then take action on the system to make sure the actual state and desired state match. If no changes are made, then a simple audit is performed to make sure the states match.

    配置管理与云原生基础设施应用程序不同的点在于,“配置管理”传统上是抽象单个节点并且不创建或管理基础设施资源。

    The reason configuration management is not the same thing as cloud native infrastructure applications is because configuration management traditionally abstracts single nodes and does not create or manage infrastructure resources.

    一些配置管理工具拓展了它们的应用场景,获得了一些成功,但它们仍然停留在“infrastructure as code”层面中,而不是 infrastructure as software的双向关系。

    Some configuration management tools are extending their use in this space to varying degrees of success, but they remain in the category of infrastructure as code and not the bidirectional relationship that infrastructure as software provides.

    Using the Reconciler Pattern in a Controller

    诸如Kubernetes之类的编排工具提供了一个可以方便地运行应用程序的平台。 控制器的想法是为预期状态提供控制回路。 Kubernetes建立在这个基础之上。 协调器模式可以轻松审计局和协调Kubernetes控制的对象。

    Orchestration tooling such as Kubernetes offers a platform in which we can run applications conveniently. The idea of a controller is to serve a control loop for an intended state. Kubernetes is built on this fundamental. The reconciler pattern makes it easy to audit and reconcile objects controlled by Kubernetes.

    想象一下,通过协调器模式,以下步骤将无休止地循环

    1. 调用GetExpected()并从数据存储中读取预期的基础结构状态。
    2. 调用GetActual()并从环境中读取以获取基础结构的实际状态。
    3. 调用Reconcile()并协调状态。

    Imagine a loop that would endlessly flow through the reconciler pattern in the following steps:

    1. Call GetExpected() and read from a data store the intended state of infrastructure.
    2. Call GetActual() and read from an environment to get the actual state of infrastructure.
    3. Call Reconcile() and reconcile the states.

    以这种方式实现协调模式的程序被将视为“控制器”。 模式的美妙立刻显而易见,因为很容易看出控制器本身的程序有多小。

    The program that implemented the reconciler pattern in this way would serve as a controller. The beauty of the pattern becomes immediately evident, since it’s easy to see how small the program for the controller itself would have to be.

    此外,对基础实施进行更改就像改变状态存储一样简单。 控制器将在下次调用GetExpected()时读取更改并触发协调。 负责基础设施的op可以放心,在后台安静地运行稳定可靠的环路,在它的基础设施环境中实施它的意愿。 现在,op可以通过管理应用程序来管理基础设施。

    Furthermore, making a change to the infrastructure is as simple as mutating the state store. The controller will read the change the next time GetExpected() is called and trigger a reconcile. The operator in charge of the infrastructure can rest assured that a stable and reliable loop is running quietly in the background, enforcing her will across her infrastructure environment. Now an operator manages infrastructure by managing an application.

    寻求控制回路行为的目标非常稳定。 这已在Kubernetes中得到证实,因为控制回路基本稳定并且随着时间的推移会自行纠正,因此我们已经发现了一些未被注意到的错误。
    如果你被边缘触发(每当状态改变就触发),你就有可能危及你的状态,并且永远无法重新建立状态。 如果你是水平触发(如果满足条件,就触发一个事件)的,那么这种模式是非常宽容的,并且不允许组件有表现的空间,因为它们应该被纠正。 这就是让Kubernetes运作良好的原因。
    -Hoe Beda,Heptio首席技术官

    The goal seeking behavior of the control loop is very stable. This has been proven in Kubernetes where we have had bugs that have gone unnoticed because the control loop is fundamentally stable and will correct itself over time.
    If you are edge triggered you run risk of compromising your state and never being able to re-create the state. If you are level triggered the pattern is very forgiving, and allows room for components not behaving as they should to be rectified. This is what makes Kubernetes work so well.
    —Joe Beda, CTO of Heptio

    现在,销毁基础设施就像通知控制器我们希望破坏基础设施一样简单。 这可以通过多种方式完成。 一种方法是让控制器监听禁用的状态文件。 这可以通过从打开(on)到关闭(off)来表示。

    Destroying infrastructure is now as simple as notifying the controller that we wish to destroy infrastructure. This could be done in a number of ways. One way would be to have the controller respect a disabled state file. This could be represented by flipping a bit from on to off.

    另一种方法可以是删除状态的内容。 无论op如何选择发出Destroy()信号,控制器都可以调用方便的Destroy()方法。

    Another way could be by deleting the content of the state. Regardless of how an operator chooses to signal a Destroy(), the controller is ready to call the convenient Destroy() method.

    Conclusion

    基础设施工程师现在是软件工程师,负责构建先进的高度分布式系统,并且可以向后工作。他们必须编写管理他们负责的基础设施的软件。

    Infrastructure engineers are now software engineers, tasked with building advanced and highly distributed systems—and working backward. They must write software that manages the infrastructure they are responsible for.

    尽管这两个学科之间存在许多相似之处,但仍需要对工程基础设施管理应用程序的行业进行终身学习。诸如自举基础设施之类的困难问题不断发展,需要工程师不断学习新事物。还需要维护和优化基础设施,确保工程师长期使用。

    While there are many similarities between the two disciplines, there is a lifetime of learning the trade of engineering infrastructure management applications. Hard problems, such as bootstrapping infrastructure, continually evolve and require engineers to keep learning new things. There is also an ongoing need to maintain and optimize infrastructure that is sure to keep engineers employed for a very long time.

    本章为用户提供了强有力的模式和基础知识,将不明确的API结构映射到粒度资源中。 资源可以应用于本地数据中心,私有云或公共云。

    The chapter has equipped the user with powerful patterns and fundamentals in mapping ambiguous API structures into granular resources. The resources can be applied in your local data center, on top of a private cloud, or in a public cloud.

    了解这些模式如何工作的基础知识对于构建可靠的基础设施管理应用程序至关重要。 本章中提出的模式旨在为工程师提供构建声明式基础实施管理应用程序的起点和灵感。

    Understanding the basics of how these patterns work is critical to building reliable infrastructure management applications. The patterns set out in this chapter are intended to give engineers a starting point and inspiration for building declarative infrastructure management applications.

    构建基础设施管理应用程序没有正确或错误的答案,只要应用程序遵循Unix哲学:“做一件事。 做得好。“

    There is no right or wrong answer in building infrastructure management applications, so long as the applications adhere to the Unix philosophy: “Do one thing. Do it well.”

  • 相关阅读:
    NGINX+uWsgi部署Django项目
    centos7 docker启动服务,无法通过宿主机ip进行访问
    基于docker 搭建Prometheus+Grafana
    centos7安装MySQL5.7
    centos7下安装python7
    loadrunner27257问题解决办法
    学习Python+selenium自动化感想
    find_element和find_elements
    正则表达式
    Jdk自带的Windows性能监控工具JVM
  • 原文地址:https://www.cnblogs.com/langshiquan/p/10847544.html
Copyright © 2011-2022 走看看