ソフトウェア・アーキテクチャパターン

概要

ソフトウェア・アーキテクチャの勉強会に招待されたので改めて勉強しようと思い至りました。 最近だとクリーンアーキテクチャが話題ですが、 全体感を知るためにSoftware Architecture Patternsを読んでみたいと思います。ちゃんとした和訳を載せたりすると問題になるので自分の備忘メモを書きます。

詳細

Layer Architecture

ほとんどの人が最初に学ぶアーキテクチャだと思います。 上位から、Presentation, Business, Persistence, Databaseの層が基本となります。

観点 評価値 補足
Overall agility モノリシックな実装になりやすいため
Ease of deployment 大きなアプリになると小さな変更のためにアプリ全体をデプロイし直しが発生しやすい
Testability 別レイヤをモック化しやすい
Performance レイヤを何個もまたがる必要があるので非効率
Scalability モノリシックな実装になりやすいため
Ease of development 皆が知っており簡単なので

Event Driven Architecture

分散非同期でスケーラブルなシステムに適しています。 mediator と broker の2つのトポロジが出現します。 複雑な仕組みなので別途、実例を探して深堀りしたいと思います。 実装上は分散システムに必要な可用性の担保や、機能の一部がフェールした場合の対応が求められます。 実際にビジネス層の処理をする(event processorコンポーネント同士は独立性が高くなり、 トランザクション中に情報連携することは難しくなります。 またeventのデータフォーマットを最初から適切に決めておく事が大事です。

観点 評価値 補足
Overall agility event processor componentは独立性が高く単一目的の処理だけを行うため
Ease of deployment event processor componentは独立性が高いため
Testability 単体ユニットのテストはそれほど難しないが非同期にeventを発生させるのが厄介
Performance
Scalability event processor componentは独立性が高いため
Ease of development

Microkernel Architecture

プロダクトベースに開発する。コアシステムとプラグインから構成される。 OS系の本を読むと最初に紹介されるアーキテクチャですね。

観点 評価値 補足
Overall agility
Ease of deployment
Testability
Performance
Scalability
Ease of development

Microservices Architecture

デプロイ単位が分離されているため効率的に容易に継続的デプロイができます。 サービスコンポーネントの粒度を決める事は、最も難しい作業です。 主なトポロジは、API REST-Based、Application REST-Based、Centralized Messagingです。

観点 評価値 補足
Overall agility
Ease of deployment
Testability
Performance
Scalability
Ease of development

Space Based Architecture

CDNとかAWSのオートスケーリングの事を言っているような気がしましたが、 作る側として検討したことがないのでいまいち理解できませんでした。 一般的なWeb-Basedアプリにおいて、負荷が高くなると Webサーバ→Applicationサーバ→DBサーバとボトルネックが移行します。 後ろへ行くにつれてリソース追加が難しくなります。 そこでProcessing Unit(Applicationサーバ?)のメモリ上にデータを保持させて、 各Processing Unit同士で同期を取らせるようです。 負荷が増減に応じてProcessing Unitを追加・除去します。 かなり難しい処理が必要になりそうです。

観点 評価値 補足
Overall agility
Ease of deployment
Testability
Performance
Scalability
Ease of development

TCPを学び直してみた - RFCの確認

概要

一応インフラ部に所属しているのですがネットワークをちゃんと理解していない事にハッと気づきました。
そこでTCPの仕様書がRFCとして公開されているそうなので和訳しつつ要約 or 感想書いてみようと思います。 備忘のためなので和訳を期待された方は他をご参照ください(こことか)。

Wikipediaは本当に偉大でRFCリストが用意されていますので、 そのなかでもRFC 793 - Transmission Control Protocol (TCP v4)を読みたいと思います。

甘え体質なので自分に厳しく(?)オリジナルの英語で読みたいと思います。

目次

詳細

PREFACE

This document describes the DoD Standard Transmission Control Protocol (TCP). DoDというのは Department of Defense の略だとネットに書いてありました。

There have been nine earlier editions of the ARPA TCP specification on which this standard is based, and the present text draws heavily from them.

これは10版ということかな。

INTRODUCTION

The Transmission Control Protocol (TCP) is intended for use as a highly reliable host-to-host protocol between hosts in packet-switched computer communication networks, and in interconnected systems of such networks.

TCPの目的はホスト間の高い信頼性をもったプロトコルとして利用されることです。

This document describes the functions to be performed by the Transmission Control Protocol, the program that implements it, and its interface to programs or users that require its services.

このドキュメントにはTCPの機能、その実装、インタフェースを記述してあります。

Motivation

Computer communication systems are playing an increasingly important role in military, government, and civilian environments. This document focuses its attention primarily on military computer communication requirements, especially robustness in the presence of communication unreliability and availability in the presence of congestion, but many of these problems are found in the civilian and government sector as well.

この資料は軍事の視点に重きをおいていますが、民間でも同じような点が重要となってきます。

As strategic and tactical computer communication networks are developed and deployed, it is essential to provide means of interconnecting them and to provide standard interprocess communication protocols which can support a broad range of applications. In anticipation of the need for such standards, the Deputy Undersecretary of Defense for Research and Engineering has declared the Transmission Control Protocol (TCP) described herein to be a basis for DoD-wide inter-process communication protocol standardization.

ネットワークは大事で、利用側の利便性のために標準化が必須。

TCP is a connection-oriented, end-to-end reliable protocol designed to fit into a layered hierarchy of protocols which support multi-network applications. The TCP provides for reliable inter-process communication between pairs of processes in host computers attached to distinct but interconnected computer communication networks. Very few assumptions are made as to the reliability of the communication protocols below the TCP layer. TCP assumes it can obtain a simple, potentially unreliable datagram service from the lower level protocols. In principle, the TCP should be able to operate above a wide spectrum of communication systems ranging from hard-wired connections to packet-switched or circuit-switched networks.

TCPは階層型のプロトコルに適合するよう設計されています。

TCP is based on concepts first described by Cerf and Kahn in [1]. The TCP fits into a layered protocol architecture just above a basic Internet Protocol [2] which provides a way for the TCP to send and receive variable-length segments of information enclosed in internet datagram "envelopes". The internet datagram provides a means for addressing source and destination TCPs in different networks. The internet protocol also deals with any fragmentation or reassembly of the TCP segments required to achieve transport and delivery through multiple networks and interconnecting gateways. The internet protocol also carries information on the precedence, security classification and compartmentation of the TCP segments, so this information can be communicated end-to-end across multiple networks.

TCPは基本的なインターネット・プロトコルのすぐ上の階層に位置している。

Much of this document is written in the context of TCP implementations which are co-resident with higher level protocols in the host computer. Some computer systems will be connected to networks via front-end computers which house the TCP and internet protocol layers, as well as network specific software. The TCP specification describes an interface to the higher level protocols which appears to be implementable even for the front-end case, as long as a suitable host-to-front end protocol is implemented.

houseってどういう意味なんだろう。ここ飛ばそう。

Scope

The TCP is intended to provide a reliable process-to-process communication service in a multinetwork environment. The TCP is intended to be a host-to-host protocol in common use in multiple networks.

TCPを使うことでプロセス間で信頼性の高い通信を行えます。

About This Document

This document represents a specification of the behavior required of any TCP implementation, both in its interactions with higher level protocols and in its interactions with other TCPs. The rest of this section offers a very brief view of the protocol interfaces and operation. Section 2 summarizes the philosophical basis for the TCP design. Section 3 offers both a detailed description of the actions required of TCP when various events occur (arrival of new segments, user calls, errors, etc.) and the details of the formats of TCP segments.

この資料にはあらゆるTCP実装が備えるべき仕様が書いてあります。

Interfaces

The TCP interfaces on one side to user or application processes and on the other side to a lower level protocol such as Internet Protocol.

この文の動詞ってどれだろう...

The interface between an application process and the TCP is illustrated in reasonable detail. This interface consists of a set of calls much like the calls an operating system provides to an application process for manipulating files. For example, there are calls to open and close connections and to send and receive data on established connections. It is also expected that the TCP can asynchronously communicate with application programs. Although considerable freedom is permitted to TCP implementors to design interfaces which are appropriate to a particular operating system environment, a minimum functionality is required at the TCP/user interface for any valid implementation.

アプリとのインタフェースが図で書いてあります。 インタフェースは、OSが提供するのと同じように、処理要求(Calls)の集合として構成されています。 インタフェースには、特定OSやユーザ要求への対応のために、多少の実装の柔軟性(自由)があります。

The interface between TCP and lower level protocol is essentially unspecified except that it is assumed there is a mechanism whereby the two levels can asynchronously pass information to each other. Typically, one expects the lower level protocol to specify this interface. TCP is designed to work in a very general environment of interconnected networks. The lower level protocol which is assumed throughout this document is the Internet Protocol [2].

TCPと下位プロトコルの間のインタフェースは、 互いに非同期に情報伝達できると仮定されていることを除けば、特に規定されていません。 通常はTCPが下位プロトコル(=IP)に対してこのインタフェースを規定することを期待します。

Operation

As noted above, the primary purpose of the TCP is to provide reliable, securable logical circuit or connection service between pairs of processes. To provide this service on top of a less reliable internet communication system requires facilities in the following areas:

Basic Data Transfer Reliability Flow Control Multiplexing Connections Precedence and Security

The basic operation of the TCP in each of these areas is described in the following paragraphs.

TCPの目的達成のためには6つの領域に対してケアする必要があります。 * データ転送 * 信頼性 * フロー制御 * 多重化 * コネクション * 優先つけと安全性

Basic Data Transfer

The TCP is able to transfer a continuous stream of octets in each direction between its users by packaging some number of octets into segments for transmission through the internet system. In general, the TCPs decide when to block and forward data at their own convenience. 1セグメント = 複数オクテット(1オクテット=常に8bit)。 TCPは通信者の双方向に複数セグメントを送信できる。

Sometimes users need to be sure that all the data they have submitted to the TCP has been transmitted. For this purpose a push function is defined. To assure that data submitted to a TCP is actually transmitted the sending user indicates that it should be pushed through to the receiving user. A push causes the TCPs to promptly forward and deliver data up to that point to the receiver. The exact push point might not be visible to the receiving user and the push function does not supply a record boundary marker.

データが届いたか確認するためにpush機能が定義された。 pushによって早急にデータが受信者に転送される。 「boundary marker」がわからないよー!

Reliability

The TCP must recover from data that is damaged, lost, duplicated, or delivered out of order by the internet communication system. This is achieved by assigning a sequence number to each octet transmitted, and requiring a positive acknowledgment (ACK) from the receiving TCP. If the ACK is not received within a timeout interval, the data is retransmitted. At the receiver, the sequence numbers are used to correctly order segments that may be received out of order and to eliminate duplicates. Damage is handled by adding a checksum to each segment transmitted, checking it at the receiver, and discarding damaged segments. TCPはデータの破損、消失、重複、Internet外への配送、の状況に対応しなくてはいけない。 それはシーケンシャル番号とACKの仕組みで達成される。 あと破損検知のためチェックサム付けるよ。

As long as the TCPs continue to function properly and the internet system does not become completely partitioned, no transmission errors will affect the correct delivery of data. TCP recovers from internet communication system errors. 前提条件としてinternetが完全に分断されないこと。

Flow Control

TCP provides a means for the receiver to govern the amount of data sent by the sender. This is achieved by returning a "window" with every ACK indicating a range of acceptable sequence numbers beyond the last segment successfully received. The window indicates an allowed number of octets that the sender may transmit before receiving further permission.

受信者はうけとるデータ量を調整するために、ACKと一緒に"window"を使えるよ。 windowは送信できるオクテット数の上限のこと。

Multiplexing

To allow for many processes within a single Host to use TCP communication facilities simultaneously, the TCP provides a set of addresses or ports within each host. Concatenated with the network and host addresses from the internet communication layer, this forms a socket. A pair of sockets uniquely identifies each connection. That is, a socket may be simultaneously used in multiple connections.

単一ホスト上の複数プロセスが同時にTCP通信を使えるように socket(= network * host-address)という形式を使う。 とあるsocketは同時に複数コネクションによって利用されうる。

The binding of ports to processes is handled independently by each Host. However, it proves useful to attach frequently used processes (e.g., a "logger" or timesharing service) to fixed sockets which are made known to the public. These services can then be accessed through the known addresses. Establishing and learning the port addresses of other processes may involve more dynamic mechanisms.

Connections

The reliability and flow control mechanisms described above require that TCPs initialize and maintain certain status information for each data stream. The combination of this information, including sockets, sequence numbers, and window sizes, is called a connection. Each connection is uniquely specified by a pair of sockets identifying its two sides.

信頼性とフロー管理を達成するために、TCPは各ストリームの状態管理を余儀なくされる。

When two processes wish to communicate, their TCP's must first establish a connection (initialize the status information on each side). When their communication is complete, the connection is terminated or closed to free the resources for other uses.

Since connections must be established between unreliable hosts and over the unreliable internet communication system, a handshake mechanism with clock-based sequence numbers is used to avoid erroneous initialization of connections.

シーケンシャル番号ってclock-basedだったんですね。

Precedence and Security

The users of TCP may indicate the security and precedence of their communication. Provision is made for default values to be used when these features are not needed.

プロビジョンという何かが作られる。デフォルト値とな。

PHILOSOPHY

Elements of the Internetwork System

The internetwork environment consists of hosts connected to networks which are in turn interconnected via gateways. It is assumed here that the networks may be either local networks (e.g., the ETHERNET) or large networks (e.g., the ARPANET), but in any case are based on packet switching technology. The active agents that produce and consume messages are processes. Various levels of protocols in the networks, the gateways, and the hosts support an interprocess communication system that provides two-way data flow on logical connections between process ports.

The term packet is used generically here to mean the data of one transaction between a host and its network. The format of data blocks exchanged within the a network will generally not be of concern to us.

Hosts are computers attached to a network, and from the communication network's point of view, are the sources and destinations of packets. Processes are viewed as the active elements in host computers (in accordance with the fairly common definition of a process as a program in execution). Even terminals and files or other I/O devices are viewed as communicating with each other through the use of processes. Thus, all communication is viewed as inter-process communication.

Since a process may need to distinguish among several communication streams between itself and another process (or processes), we imagine that each process may have a number of ports through which it communicates with the ports of other processes.

ここはひとまず特に特筆すべきことはなさそうにみえる..

Model of Operation

Processes transmit data by calling on the TCP and passing buffers of data as arguments. The TCP packages the data from these buffers into segments and calls on the internet module to transmit each segment to the destination TCP. The receiving TCP places the data from a segment into the receiving user's buffer and notifies the receiving user. The TCPs include control information in the segments which they use to ensure reliable ordered data transmission.

プロセスはデータバッファを引数としてTCPの処理を呼び出すことでデータ送信を行う。 TCPはバッファデータを複数セグメントにパッケージ化して、インターネットモジュールを 呼び出す。受信側のTCPはセグメントを受け取ったらバッファに格納して、ユーザに通知する。

The model of internet communication is that there is an internet protocol module associated with each TCP which provides an interface to the local network. This internet module packages TCP segments inside internet datagrams and routes these datagrams to a destination internet module or intermediate gateway. To transmit the datagram through the local network, it is embedded in a local network packet.

インターネットモジュールというのは主にIPプロトコルモジュールを指すっぽい。 TCPセグメントはIPデータグラムでカプセル化するよってことかな。

The packet switches may perform further packaging, fragmentation, or other operations to achieve the delivery of the local packet to the destination internet module.

At a gateway between networks, the internet datagram is "unwrapped" from its local packet and examined to determine through which network the internet datagram should travel next. The internet datagram is then "wrapped" in a local packet suitable to the next network and routed to the next gateway, or to the final destination.

A gateway is permitted to break up an internet datagram into smaller internet datagram fragments if this is necessary for transmission through the next network. To do this, the gateway produces a set of internet datagrams; each carrying a fragment. Fragments may be further broken into smaller fragments at subsequent gateways. The internet datagram fragment format is designed so that the destination internet module can reassemble fragments into internet datagrams.

A destination internet module unwraps the segment from the datagram (after reassembling the datagram, if necessary) and passes it to the destination TCP.

IPってデータグラムを分割する機能あったんだー(なんか勉強したことある気がするけど)。 Internet Header Formatとか IPパケットの構造とIPフラグメンテーション (3/3)が参考になりました。

This simple model of the operation glosses over many details. One important feature is the type of service. This provides information to the gateway (or internet module) to guide it in selecting the service parameters to be used in traversing the next network. Included in the type of service information is the precedence of the datagram. Datagrams may also carry security information to permit host and gateways that operate in multilevel secure environments to properly segregate datagrams for security considerations.

サービスタイプの機能は階層層に活用されるって知っていたけど、 セキュリティの視点からも利用されるみたいですね。 (ここじゃよくわからないんだけど、あとで詳細出てくるよね...)

The Host Environment

The TCP is assumed to be a module in an operating system. The users access the TCP much like they would access the file system. The TCP may call on other operating system functions, for example, to manage data structures. The actual interface to the network is assumed to be controlled by a device driver module. The TCP does not call on the network device driver directly, but rather calls on the internet datagram protocol module which may in turn call on the device driver.

TCPはOSから提供され、FILEアクセスするかのように利用できます。 ネットワークデバイスドライバを使うのはTCPじゃなくてIPらしい。

The mechanisms of TCP do not preclude implementation of the TCP in a front-end processor. However, in such an implementation, a host-to-front-end protocol must provide the functionality to support the type of TCP-user interface described in this document.

「front-end processor」とは何を指すのか... ネットワークデバイスドライバとかかな

Interfaces

The TCP/user interface provides for calls made by the user on the TCP to OPEN or CLOSE a connection, to SEND or RECEIVE data, or to obtain STATUS about a connection. These calls are like other calls from user programs on the operating system, for example, the calls to open, read from, and close a file.

The TCP/internet interface provides calls to send and receive datagrams addressed to TCP modules in hosts anywhere in the internet system. These calls have parameters for passing the address, type of service, precedence, security, and other control information.

TCPにはOPEN,CLOSE,SEND,RECEIVE,STATUSのメソッドがありそうな雰囲気。

Relation to Other Protocols

The following diagram illustrates the place of the TCP in the protocol hierarchy:

  +------+ +-----+ +-----+       +-----+
  |Telnet| | FTP | |Voice|  ...  |     |  Application Level
  +------+ +-----+ +-----+       +-----+
        |   |         |             |
       +-----+     +-----+       +-----+
       | TCP |     | RTP |  ...  |     |  Host Level
       +-----+     +-----+       +-----+
          |           |             |
       +-------------------------------+
       |    Internet Protocol & ICMP   |  Gateway Level
       +-------------------------------+
                      |
         +---------------------------+
         |   Local Network Protocol  |    Network Level
         +---------------------------+

                    Protocol Relationships

                          Figure 2.

It is expected that the TCP will be able to support higher level protocols efficiently. It should be easy to interface higher level protocols like the ARPANET Telnet or AUTODIN II THP to the TCP.

TCPは上位層のプロトコルを効率的にサポートできることが期待されています。

Reliable Communication

A stream of data sent on a TCP connection is delivered reliably and in order at the destination.

Transmission is made reliable via the use of sequence numbers and acknowledgments. Conceptually, each octet of data is assigned a sequence number. The sequence number of the first octet of data in a segment is transmitted with that segment and is called the segment sequence number. Segments also carry an acknowledgment number which is the sequence number of the next expected data octet of transmissions in the reverse direction. When the TCP transmits a segment containing data, it puts a copy on a retransmission queue and starts a timer; when the acknowledgment for that data is received, the segment is deleted from the queue. If the acknowledgment is not received before the timer runs out, the segment is retransmitted.

An acknowledgment by TCP does not guarantee that the data has been delivered to the end user, but only that the receiving TCP has taken the responsibility to do so.

To govern the flow of data between TCPs, a flow control mechanism is employed. The receiving TCP reports a "window" to the sending TCP. This window specifies the number of octets, starting with the acknowledgment number, that the receiving TCP is currently prepared to receive.

TCPの信頼性はシーケンシャル番号とACKで成り立っている。 1. セグメントを転送 2. コピーを再送信キューにいれる 3. タイマー起動 4. 時間内にACKを受け取ったら対応するキューの要素を削除 5. 時間切れならキューの要素を再送信

フロー制御についてはwindowを使うんだけど、既出感あるので略。

Connection Establishment and Clearing

To identify the separate data streams that a TCP may handle, the TCP provides a port identifier. Since port identifiers are selected independently by each TCP they might not be unique. To provide for unique addresses within each TCP, we concatenate an internet address identifying the TCP with a port identifier to create a socket which will be unique throughout all networks connected together.

IPとPortの組み合わせによってNW上でsocketを一意に特定します。

A connection is fully specified by the pair of sockets at the ends. A local socket may participate in many connections to different foreign sockets. A connection can be used to carry data in both directions, that is, it is "full duplex".

コネクションは末端のソケットの組で特定できる。

TCPs are free to associate ports with processes however they choose. However, several basic concepts are necessary in any implementation. There must be well-known sockets which the TCP associates only with the "appropriate" processes by some means. We envision that processes may "own" ports, and that processes can initiate connections only on the ports they own. (Means for implementing ownership is a local issue, but we envision a Request Port user command, or a method of uniquely allocating a group of ports to a given process, e.g., by associating the high order bits of a port name with a given process.)

この部分はよくわからなかった。 特定のポートは特定のプロセスが専有する形になるよってことなんですかね。

A connection is specified in the OPEN call by the local port and foreign socket arguments. In return, the TCP supplies a (short) local connection name by which the user refers to the connection in subsequent calls. There are several things that must be remembered about a connection. To store this information we imagine that there is a data structure called a Transmission Control Block (TCB). One implementation strategy would have the local connection name be a pointer to the TCB for this connection. The OPEN call also specifies whether the connection establishment is to be actively pursued, or to be passively waited for.

TCPのOPENコールを呼び出すと、返り値としてコネクション名を渡される。 それとTCBを紐付ける。 OPENコールはアクティブとパッシブがある。

A passive OPEN request means that the process wants to accept incoming connection requests rather than attempting to initiate a connection. Often the process requesting a passive OPEN will accept a connection request from any caller. In this case a foreign socket of all zeros is used to denote an unspecified socket. Unspecified foreign sockets are allowed only on passive OPENs.

A service process that wished to provide services for unknown other processes would issue a passive OPEN request with an unspecified foreign socket. Then a connection could be made with any process that requested a connection to this local socket. It would help if this local socket were known to be associated with this service.

サーバはパッシブ。

Well-known sockets are a convenient mechanism for a priori associating a socket address with a standard service. For instance, the "Telnet-Server" process is permanently assigned to a particular socket, and other sockets are reserved for File Transfer, Remote Job Entry, Text Generator, Echoer, and Sink processes (the last three being for test purposes). A socket address might be reserved for access to a "Look-Up" service which would return the specific socket at which a newly created service would be provided. The concept of a well-known socket is part of the TCP specification, but the assignment of sockets to services is outside this specification. (See [4].)

well-know ソケット(=ポート)は標準的なサービスとソケットを紐付けるためには便利。

Processes can issue passive OPENs and wait for matching active OPENs from other processes and be informed by the TCP when connections have been established. Two processes which issue active OPENs to each other at the same time will be correctly connected. This flexibility is critical for the support of distributed computing in which components act asynchronously with respect to each other.

There are two principal cases for matching the sockets in the local passive OPENs and an foreign active OPENs. In the first case, the local passive OPENs has fully specified the foreign socket. In this case, the match must be exact. In the second case, the local passive OPENs has left the foreign socket unspecified. In this case, any foreign socket is acceptable as long as the local sockets match. Other possibilities include partially restricted matches.

ソケットの通信を始めるには2つの方法がある。 1つ目は、受け手側が、送り手側のソケットを正確に指定する方法。 2つ目は、受け手側が、送り手側を特に指定せずに待ち受ける方法。

If there are several pending passive OPENs (recorded in TCBs) with the same local socket, an foreign active OPEN will be matched to a TCB with the specific foreign socket in the foreign active OPEN, if such a TCB exists, before selecting a TCB with an unspecified foreign socket.

The procedures to establish connections utilize the synchronize (SYN) control flag and involves an exchange of three messages. This exchange has been termed a three-way hand shake [3].

A connection is initiated by the rendezvous of an arriving segment containing a SYN and a waiting TCB entry each created by a user OPEN command. The matching of local and foreign sockets determines when a connection has been initiated. The connection becomes "established" when sequence numbers have been synchronized in both directions.

The clearing of a connection also involves the exchange of segments, in this case carrying the FIN control flag.

Data Communication

The data that flows on a connection may be thought of as a stream of octets. The sending user indicates in each SEND call whether the data in that call (and any preceeding calls) should be immediately pushed through to the receiving user by the setting of the PUSH flag.

すぐに送信してほしいときはpushフラグをセットする。

A sending TCP is allowed to collect data from the sending user and to send that data in segments at its own convenience, until the push function is signaled, then it must send all unsent data. When a receiving TCP sees the PUSH flag, it must not wait for more data from the sending TCP before passing the data to the receiving process.

TCPは好きにバッファにデータが貯まるのを待ってもいいが、push機能が呼ばれたら、 すぐにデータを送信しければいけない。

感想

以前、勉強会のために、とある技術書をきちんと和訳していたのですが、 今回もその時と同じように「辛いな」と思いました。

(和訳自体が勉強になるわけではないですし、 どう翻訳するかで結構時間取られてしまうので、、、)

残りの部分は具体的なTCPの仕様の話になりますが和訳は止めて、 次は実装を目指したいと思います。

以上。

KubernetesのPod削除ライフサイクルについて確認してみた

概要

kubernetesにはローリングアップデートの仕組みが組み込まれているので、
ちょっと設定追加しておけば基本的にはサービスが途切れることはありません。
ただ、処理中のリクエストがどうなってしまうのか気になったので確認しました。

作業中はこちらの記事を参考にさせて頂きました。

詳細

ぶっちゃけここを見れば 私が話す事は無いのですが自分の備忘的に和訳しておこうと思います。

Podの削除ライフサイクルは以下のステップで構成されます。

1. Podの状態を"Terminating"に設定
2. preHookを(設定されていれば)実行
3. podにSIGTERMを送る
4. grace periodに設定された時間(sec)だけ待つ
5. podにSIGKILLが送る
  • preHookについてはここ
  • grace periodというのはterminationGracePeriodSecondsというキーの値として格納されています。 ここみたいに探すとサンプルがいっぱいあります。

ここから妄想なのですが、Podの状態がTerminatingに設定されたらserviceから外されるから、 処理中のリクエストはgrace periodの時間内に完了させてね。という感じですね。

これも妄想ですが、kubernetes側でPodのプロセスの状態は見ているみたいで、 grace periodを非常に長く設定しても、プロセスが終了すればその時点でPodは削除されるみたいです。

ちょっとした事ですが、なんかすっきりしたので良かったです。

Kubernetes の Annotation って何用? と思って確認してみた

概要

kubenetes を使い始めたのですが annotation っていつ使うんだろーと思って
放置していたのでちゃんと調べてみました。

ただし実行環境はOpenShiftを使っています。
中身はk8sなのであんまり違いはないかなと。

詳細

まず適当なPodを作成してみます。

$ cat pod_sample.yml 
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    app: test
spec:
  containers:
  - name: nginx
    image: bitnami/nginx:latest
    ports:
    - containerPort: 8080
$ oc apply -f pod_sample.yml 
pod/nginx created

次にPodの情報を表示します。

$ oc get po nginx -o yaml
apiVersion: v1
kind: Pod
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"labels":{"app":"test"},"name":"nginx","namespace":"default"},"spec":{"containers":[{"image":"bitnami/nginx:latest","name":"nginx","ports":[{"containerPort":8080}]}]}}
    openshift.io/scc: anyuid
  creationTimestamp: 2019-02-21T07:01:20Z
  labels:
    app: test
  name: nginx
  namespace: default

特に指示していないのに勝手にannotationが付与されています。

公式のドキュメントにはこう書いてあります。

Attaching metadata to objects You can use either labels or annotations to attach metadata to Kubernetes objects. Labels can be used to select objects and to find collections of objects that satisfy certain conditions. In contrast, annotations are not used to identify and select objects. The metadata in an annotation can be small or large, structured or unstructured, and can include characters not permitted by labels.

つまり、annotationを使ってk8sのリソースオブジェクトに対してメタデータを付与するんだよ、ってことですね。 そこはサラッと知っていたんですが、誰のために どんな情報を ってところを確認したいと思います。

すでにこことか ここ のブログにLabelとAnnotationの違いと使う方が記載されています。

  • オブジェクトの変更理由の記録
  • 特別なスケジューラへの、特別なスケジュールポリシーの伝達
  • リソースを更新したツールと、それがどのように更新したかの情報の付加
  • 他のツールからの更新検知などのため
  • Deployment オブジェクトによるロールアウトのための、ReplicaSet の追跡情報の保存など。(入門 Kubernetes P.77)

実際に運用していないから経験値が不足しまくっているけどひねり出してみると
「運用者が担当範囲のnamespaceをみると知らないPodが稼働してたけど
annotationを見るとk8s管理者が作成したものらしいから静観でいっか」みたいな感じかな。

とりあえず機能の位置づけと、Labelとは全く異なるものだと理解できたので良かったです。

File System Forensic Analysis まとめ - DD練習

背景

「File System Forensic Analysis」の Chapter 3 のDDを使った練習の一部を試してみます。

目的

DDコマンドを用いてファイルシステムを操作できるようになる。

準備

  • MacBookPro(15.3.0 Darwin
  • ddコマンド

練習

小さなファイルをコピーしてみます。

$ echo "Hello, World!" >> file1 
$ dd if=file1 of=file1_cp bs=512
0+1 records in
0+1 records out
13 bytes transferred in 0.000055 secs (237069 bytes/sec)
$ ls
file1 file1_cp

0+1 records in ここの意味は

  • 0 → 0(+1)個分のセクタブロック(??)を処理した
  • +1 → 最後のセクタブロックをFullサイズ(=512 byte)処理した(+0ならFullサイズ処理しなかった)

次にInputファイルサイズを大きくしてみます。
ただしファイルサイズ<ブロックサイズとします。

$ perl -e "print 'a'x511" > file2
$ dd if=file2 of=file2_cp bs=512
0+1 records in
0+1 records out
511 bytes transferred in 0.000054 secs (9441803 bytes/sec)

上記は 0(+1) = 1個のセクタブロックに対して読込、書込を行い、かつ
最後のセクタブロックに対してFullサイズ処理していないので0+1 records inとなっていますね。

次にファイルサイズ=ブロックサイズとしてみます

$ perl -e "print 'a'x512" > file3
$ dd if=file3 of=file3_cp bs=512
1+0 records in
1+0 records out
512 bytes transferred in 0.000064 secs (8012999 bytes/sec)

上記は 1(+1) = 2個のセクタブロックに対して読込、書込を行い(※ 1番目のブロックに対して0byte処理したってことかな)
かつ、最後のセクタブロックに対してFullサイズ処理しているので1+0 records inとなっていますね。

次にファイルサイズ>ブロックサイズとしてみます。

$ perl -e "print 'a'x513" > file4
$ dd if=file4 of=file4_cp bs=512
1+1 records in
1+1 records out
513 bytes transferred in 0.000068 secs (7549747 bytes/sec)

上記は 1(+1) = 2個のセクタブロックに対して読込、書込を行い、かつ
最後のセクタブロックに対してFullサイズ処理していないので1+1 records inとなっていますね。

思ったほどddコマンドの難しい使い方って思いつかないですね...

以上。

File System Forensic Analysis まとめ - chapter 3

背景

友人とフォレンジック勉強会を行っています。
輪講として「File System Forensic Analysis 1st edition (著: Brian Carrier) 」を読んでいます。

本題

先日 Chapter 3 をまとめたのでブログにも展開します。
speakerdeck.com

以上。

Sleuth Kit パーティション解析入門

背景

先日CTFの問題に初めて取り組んだ際、Digital Forensic の業界で有名な Sleuth Kit (TSK) というツールを使ってハードディスクのパーティションを覗いてみたので紹介します。
またTSKを使わずに物理で殴るやり方でTSKと同じ結果が得られる事を確認します。

ゴール

Dos パーティションを確認できるようになる。

準備

  • 作業用の端末:MacBookPro(15.3.0 Darwin
  • Sleuth Kit(v4.6.2)
  • hexdump
  • 解析対象のイメージファイル

作業端末の用意

Macを使います。
フォレンジックツールはMacだとCLIのものが多いのですが、
WindowsだとGUIが用意されてものが多いです。
ちなみにSleuth Kit の GUI版は Autopsy (Win/Mac対応)というものがあるみたいです。

Sleuth Kitのインストール

  1. ターミナルを開く
  2. 以下実行
    ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" < /dev/null 2> /dev/null
  3. 以下実行
    brew install sleuthkit --with-libewf --with-afflib

引用元:http://macappstore.org/sleuthkit/

今回は解析対象のイメージファイルがEncase形式なので、オプションの --with-libewf は必須となります。

解析対象のイメージファイルのダウンロード

  1. Daily Blog #451: Defcon DFIR CTF 2018 Open to the Publicにアクセス
  2. "Download Links" から Image1 だけをダウンロード
    ※およそ 11〜12GB のサイズです。容量に余裕を持ってください。
  3. 解凍する

ダウンロードファイルを解凍したものの中にHRServer_Disk0.e01というイメージファイルが含まれているはずです。 これが解析対象となります。

解析

TSK

mmlsコマンドを使います。パーティションレイアウトを確認できます。

$ mmls -i ewf HRServer_Disk0.e01 
DOS Partition Table
Offset Sector: 0
Units are in 512-byte sectors

      Slot      Start        End          Length       Description
000:  Meta      0000000000   0000000000   0000000001   Primary Table (#0)
001:  -------   0000000000   0001026047   0001026048   Unallocated
002:  000:000   0001026048   0104857599   0103831552   NTFS / exFAT (0x07)

この結果からイメージの相対的な0001026048バイト目がファイルシステムの開始地点だとわかりました。

力技

素直にバイト列を眺めてみます。

encaseフォーマットだとよくわからないのでまず生のデータを取り出します。
パーティションレイアウトは最初の1セクタ分に格納されているので最初のセクタだけ取り出します。

$ img_cat -b 512 -e 1 -i ewf HRServer_Disk0.e01 > image.raw

次にhexdumpを使ってバイト列を表示します。

$ hexdump image.raw 
0000000 33 c0 8e d0 bc 00 7c 8e c0 8e d8 be 00 7c bf 00
0000010 06 b9 00 02 fc f3 a4 50 68 1c 06 cb fb b9 04 00
0000020 bd be 07 80 7e 00 00 7c 0b 0f 85 0e 01 83 c5 10
0000030 e2 f1 cd 18 88 56 00 55 c6 46 11 05 c6 46 10 00
0000040 b4 41 bb aa 55 cd 13 5d 72 0f 81 fb 55 aa 75 09
0000050 f7 c1 01 00 74 03 fe 46 10 66 60 80 7e 10 00 74
0000060 26 66 68 00 00 00 00 66 ff 76 08 68 00 00 68 00
0000070 7c 68 01 00 68 10 00 b4 42 8a 56 00 8b f4 cd 13
0000080 9f 83 c4 10 9e eb 14 b8 01 02 bb 00 7c 8a 56 00
0000090 8a 76 01 8a 4e 02 8a 6e 03 cd 13 66 61 73 1c fe
00000a0 4e 11 75 0c 80 7e 00 80 0f 84 8a 00 b2 80 eb 84
00000b0 55 32 e4 8a 56 00 cd 13 5d eb 9e 81 3e fe 7d 55
00000c0 aa 75 6e ff 76 00 e8 8d 00 75 17 fa b0 d1 e6 64
00000d0 e8 83 00 b0 df e6 60 e8 7c 00 b0 ff e6 64 e8 75
00000e0 00 fb b8 00 bb cd 1a 66 23 c0 75 3b 66 81 fb 54
00000f0 43 50 41 75 32 81 f9 02 01 72 2c 66 68 07 bb 00
0000100 00 66 68 00 02 00 00 66 68 08 00 00 00 66 53 66
0000110 53 66 55 66 68 00 00 00 00 66 68 00 7c 00 00 66
0000120 61 68 00 00 07 cd 1a 5a 32 f6 ea 00 7c 00 00 cd
0000130 18 a0 b7 07 eb 08 a0 b6 07 eb 03 a0 b5 07 32 e4
0000140 05 00 07 8b f0 ac 3c 00 74 09 bb 07 00 b4 0e cd
0000150 10 eb f2 f4 eb fd 2b c9 e4 64 eb 00 24 02 e0 f8
0000160 24 02 c3 49 6e 76 61 6c 69 64 20 70 61 72 74 69
0000170 74 69 6f 6e 20 74 61 62 6c 65 00 45 72 72 6f 72
0000180 20 6c 6f 61 64 69 6e 67 20 6f 70 65 72 61 74 69
0000190 6e 67 20 73 79 73 74 65 6d 00 4d 69 73 73 69 6e
00001a0 67 20 6f 70 65 72 61 74 69 6e 67 20 73 79 73 74
00001b0 65 6d 00 00 00 63 7b 9a 0d 87 2c 5c 00 00 80 dd
00001c0 1f 3f 07 fe ff ff 00 a8 0f 00 00 58 30 06 00 00
00001d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
*
00001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa
0000200 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
*
0000400

ここでDosパーティションの構成は以下となっていますので

バイト範囲 意味
0-445 ブートコード
446-461 パーティションエントリ①
462-477 パーティションエントリ②
478-493 パーティションエントリ③
494-509 パーティションエントリ④
510-511 シグネチャ

さきほどの結果に当てはめてみるとこうなります。

バイト範囲 意味
0-445 ブートコード
446-461 パーティションエントリ① 80 DD 1F 3F 07 FE FF FF 00 A8 0F 00 00 58 30 06
462-477 パーティションエントリ② 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
478-493 パーティションエントリ③ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
494-509 パーティションエントリ④ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
510-511 シグネチャ 55 AA

どうやらパーティションエントリ①にしか値が格納されていないという事がわかりました。

次にパーティションエントリのバイト列がどういう意味をもつかというと

バイト範囲 意味
0-0 起動可能かを示すフラグ
1-3 CHS方式での開始アドレス
4-4 パーティションタイプ
5-7 CHS方式での終了アドレス
8-11 LBA方式での開始アドレス
12-15 セクタのサイズ

となっていますので、パーティションエントリ①のバイト列に適用するとこうなります。

バイト範囲 意味
0-0 起動可能かを示すフラグ 80
1-3 CHS方式での開始アドレス DD 1F 3F
4-4 パーティションタイプ 07
5-7 CHS方式での終了アドレス FE FF FF
8-11 LBA方式での開始アドレス 00 A8 0F 00
12-15 セクタのサイズ 00 58 30 06

まずパーティションタイプ07ファイルシステムNTFSであることを示しています。

次にLBA方式の開始アドレスを確認します。
このアドレスはリトルエンディアンなので左右をひっくり返した後に10進数に変換します。
00 A8 0F 00
-> 000FA800(16進)
-> 1026048(10進)

またセクタのサイズもリトルエンディアンで格納されているらしく、
同様に以下の10進数の値が得られます。
00 58 30 06
-> 06305800(16進)
-> 103831552(10進)

最初にmmlsコマンドを使って取得した結果と同じになっていますね。
ひとまずmmlsが何をしているか分かり満足です。

終わり。