yanom blog

様々な技術について書きます

Rustでicedを試してみた

この記事はアドベントカレンダー2021 Rust 18日目の記事です。

はじめに

皆さんこんにちは。寒いですね。
早いもので今年もあと少し、最後まで気を引き締めて行きましょう。

ここでは、RustのGUIライブラリであるicedを使ってGUIツールを作ったという、
紹介記事を書くつもりでしたが、諸般の都合で手がつけれず・・・。
icedのサンプルを動かすところまでになります。

環境

OS: Windows 10
rustc 1.56.0 (09c42c458 2021-10-18)
cargo 1.56.0 (4ed5d137b 2021-10-04)

iced

github.com

RustでGUIツールが簡単に作れるOSSです。
他の人が紹介している記事が沢山あるので、ここでは割愛します。

サンプルを動かしてみる

githubサンプルが沢山あるので、その中のeventsを動かしてみます。

cargo new コマンドで適当にプロジェクトを作った後、cargo.tomlに以下を追記します。

[dependencies]
iced = "0.3"
iced_native = "0.4"

その後、main.rsを以下とします。

use iced::{
    button, executor, Align, Application, Button, Checkbox,
    Clipboard, Column, Command, Container, Element, HorizontalAlignment, Length, Settings, Subscription, Text,
};
use iced_native::{window, Event};

pub fn main() -> iced::Result {
    Events::run(Settings {
        exit_on_close_request: false,
        ..Settings::default()
    })
}

#[derive(Debug, Default)]
struct Events {
    last: Vec<iced_native::Event>,
    enabled: bool,
    exit: button::State,
    should_exit: bool,
}

#[derive(Debug, Clone)]
enum Message {
    EventOccurred(iced_native::Event),
    Toggled(bool),
    Exit,
}

impl Application for Events {
    type Executor = executor::Default;
    type Message = Message;
    type Flags = ();

    fn new(_flags: ()) -> (Events, Command<Message>) {
        (Events::default(), Command::none())
    }

    fn title(&self) -> String {
        String::from("Events - Iced")
    }

    // fn update(&mut self, message: Message) -> Command<Message> {
    fn update(&mut self, message: Message, _clip: &mut Clipboard) -> Command<Message> {
        match message {
            Message::EventOccurred(event) if self.enabled => {
                self.last.push(event);

                if self.last.len() > 5 {
                    let _ = self.last.remove(0);
                }
            }
            Message::EventOccurred(event) => {
                if let Event::Window(window::Event::CloseRequested) = event {
                    self.should_exit = true;
                }
            }
            Message::Toggled(enabled) => {
                self.enabled = enabled;
            }
            Message::Exit => {
                self.should_exit = true;
            }
        };

        Command::none()
    }

    fn subscription(&self) -> Subscription<Message> {
        iced_native::subscription::events().map(Message::EventOccurred)
    }

    fn should_exit(&self) -> bool {
        self.should_exit
    }

    fn view(&mut self) -> Element<Message> {
        let events = self.last.iter().fold(
            Column::new().spacing(10),
            |column, event| {
                column.push(Text::new(format!("{:?}", event)).size(40))
            },
        );

        let toggle = Checkbox::new(
            self.enabled,
            "Listen to runtime events",
            Message::Toggled,
        );

        let exit = Button::new(
            &mut self.exit,
            Text::new("Exit")
                .width(Length::Fill)
                // .horizontal_alignment(alignment::Horizontal::Center),
                .horizontal_alignment(HorizontalAlignment::Center),
        )
        .width(Length::Units(100))
        .padding(10)
        .on_press(Message::Exit);

        let content = Column::new()
            // .align_items(Alignment::Center)
            .align_items(Align::Center)
            .spacing(20)
            .push(events)
            .push(toggle)
            .push(exit);

        Container::new(content)
            .width(Length::Fill)
            .height(Length::Fill)
            .center_x()
            .center_y()
            .into()
    }
}

コメントアウトした部分はサンプルが古くエラーとなっていましたので、書き換えています。

あとは、cargo runを実行すれば動くはずです。

f:id:yanom20:20211218190007p:plain
実行した様子

簡単ですね。
これを使って、冬休みにgrepアプリでも作って見ようと思います。

obsidian.mdのテーマを作った

気がつけばもう5月ですね。
仕事も一段落つきゆっくりとGWを満喫しました。

連休中に色々勉強しようと思っていたんですが、たいして出来ず・・・。
せめてブログだけでも更新します。

obsidian.md

この手のノートアプリに興味がある人なら知っていると思いますが、obsidian.mdというアプリを最近使ってます。

個人的にはdynalistが好きなんですが、dynalistはクラウドと同期するので仕事では使えません。 その点、obsidianは全てローカル保存なので、セキュリティを気にせず使うことが出来ます。

ということで、使っていたんですがテーマがいまいちピンと来なかったので、自分で作ってみました。

obsidian-sakura

github.com

obsidian-sakuraというテーマを作りました。 その名の通り桜をイメージして、ピンク色を中心に配色しています。
実はこれ、dynalistでも同じテーマがあって、それがとても良かったのでobsidianでも使いたいと思ったので自作してみました。

よければ使ってみてください。

近況報告

ここ最近は仕事が数年ぶりに忙しく、ブログを更新している時間が取れませんでした。
(というか、精神的な余裕がなかったです)
なので、去年目標にしていた「毎週ブログを更新する」が残念ながら達成出来ませんでした・・・。
2月いっぱいくらいはまだまだ忙しそうですが、3月くらいから再開していきたいと思ってます!!

散財

忙しいながら、デスク周りの環境を更に良くしようと幾つか買い足したものがあるので紹介。

ウルトラワイドディスプレイ

これ、買いました。 www.amazon.co.jp

率直に言って作業効率が2,3倍になった気がします。
最高です!

キーボード

前からずーっと分離キーボードが欲しかったんですが、ついに購入しました!

www.zsa.io

これ親指のところの高さを調節出来るようになっていて、自分の好きな高さで固定出来るようになってます。
それによって、より楽な状態でタイピングすることが出来るんです。
親指も有効活用できますし、こちらも最高です。
ただこの先には、キー配置沼という深い深い沼が広がっており、今なお最適な配列を模索中です。

GoでActor Model入門(Proto.Actor)

はじめに

皆さんにゃっはろー。お元気ですか?
最近ホロライブにハマっているyanomです。最近のイチオシはぺこーらです!
可愛いので皆さんもぜひ見てみてください! っと、全然脈絡はないですが、一応この記事はGo 3 Advent Calendar 2020 13日目の記事です。

Akka

最近仕事では、JavaAkkaを使って非同期メッセージパッシングを使ったシステムを開発していたりします。Akkaは本当によくできており手軽に使う事ができるのでおすすめです。
ただ、今回はGoのアドベントカレンダーということで、GoでAkkaっぽいことができないか探していたところ、Proto.Actorというライブラリを見つけたので、簡単に入門をやってみました。

Proto.Actor

github.com

Akka.Netの開発メンバだった方が、開発しているということで使い方はかなり似ています。 また、言語はGoの他にC#版もあるみたいです。
(GoのチャネルとActorについての違いについてはここに詳しく書いてあります。)

Hallo Proto.Actor

まずはチュートリアルから。
環境構築などは、gitに書いてあるのでそちらを参照してください。

type Hello struct{ Who string }
type HelloActor struct{}

func (state *HelloActor) Receive(context actor.Context) {
    switch msg := context.Message().(type) {
    case Hello:
        fmt.Printf("Hello %v\n", msg.Who)
    }
}

func main() {
    context := actor.EmptyRootContext
    props := actor.PropsFromProducer(func() actor.Actor { return &HelloActor{} })
    pid, err := context.Spawn(props)
    if err != nil {
        panic(err)
    }
    context.Send(pid, Hello{Who: "Roger"})
    console.ReadLine()
}

実行すると、こんな感じでHelloActorに対して、Rogerというメッセージが送信されていることがわかります。

yanom@DESKTOP-0VPGPUH:~/go/src/proto-actor$ ./proto-actor 
Hello Roger

backpressure

Actorモデルでは各Actorがmailboxを持っており、Actorはそこからひとつずつメッセージを取り出して処理を実行しています。
Proto.Actorではそのmailboxに振る舞いを簡単に定義できるようになっています。
これを使ってバックプレッシャーを実現することが可能となっています。

package main

import (
    "log"
    "sync/atomic"
    "time"

    console "github.com/AsynkronIT/goconsole"
    "github.com/AsynkronIT/protoactor-go/actor"
    "github.com/AsynkronIT/protoactor-go/mailbox"
)

// sent to producer to request more work
type requestMoreWork struct {
    items int
}
type requestWorkBehavior struct {
    tokens   int64
    producer *actor.PID
}

func (m *requestWorkBehavior) MailboxStarted() {
    log.Println("mailboxstarted...")
    m.requestMore()
}
func (m *requestWorkBehavior) MessagePosted(msg interface{}) {
    log.Println("posted...")
}
func (m *requestWorkBehavior) MessageReceived(msg interface{}) {
    log.Println("messagereceived...")
    atomic.AddInt64(&m.tokens, -1)
    if m.tokens == 0 {
        m.requestMore()
    }
}
func (m *requestWorkBehavior) MailboxEmpty() {
    log.Println("empty...")
}

func (m *requestWorkBehavior) requestMore() {
    log.Println("Requesting more tokens")
    m.tokens = 5
    system.Root.Send(m.producer, &requestMoreWork{items: 5})
}

type producer struct {
    requestedWork int
    producedWork  int
    worker        *actor.PID
}

func (p *producer) Receive(ctx actor.Context) {
    switch msg := ctx.Message().(type) {
    case *actor.Started:
        log.Println("started...")
        // spawn our worker
        workerProps := actor.PropsFromProducer(func() actor.Actor {
            return &worker{}
        })
        mb := mailbox.Unbounded(&requestWorkBehavior{
            producer: ctx.Self(),
        })
        p.worker = ctx.Spawn(workerProps.WithMailbox(mb))
    case *requestMoreWork:
        p.requestedWork += msg.items
        log.Println("Producer got a new work request")
        ctx.Send(ctx.Self(), &produce{})
    case *produce:
        // produce more work
        log.Println("Producer is producing work")
        p.producedWork++
        ctx.Send(p.worker, &work{p.producedWork})

        // decrease our workload and tell ourselves to produce more work
        if p.requestedWork > 0 {
            log.Println("send produce")
         
            p.requestedWork--
            ctx.Send(ctx.Self(), &produce{})
        }
    }
}

type produce struct{}
type worker struct{}

func (w *worker) Receive(ctx actor.Context) {
    switch msg := ctx.Message().(type) {
    case *work:
        log.Printf("Worker is working %+v", msg)
        time.Sleep(100 * time.Millisecond)
    }
}

type work struct {
    id int
}

var system = actor.NewActorSystem()

func main() {
    producerProps := actor.PropsFromProducer(func() actor.Actor { return &producer{} })
    system.Root.Spawn(producerProps)
    _, _ = console.ReadLine()

}

実行してみるとわかりますが、workerが一定数処理を終わるまで、producerは次の処理を投げないように制御できていることが分かります。

他にも色々サンプルが揃っているので興味がある方はぜひ覗いてみてください。

まとめ

非同期メッセージパッシングが簡単にできるようになるProto.Actorを紹介しました。 Go版はまだベータ版ということで変わる可能性がありますが、その手軽さはAkka以上だと感じました。
また、実際の開発では考慮が必要になるであろう、バックプレッシャーについても手軽に実現できるようになっているので、そこも素晴らしいと思います。今後も色々遊んでみたいと思います。
あと、久しぶりにGoを書きましたが、やっぱり最高です!

実践テスト駆動開発 を読んでる

ちょっと、仕事が忙しくて更新できてませんでしたが、今は実践テスト駆動開発を読んでいます。
まだ、半分くらいなので、また読んだら感想を追記します。

目次

第1章 テスト駆動開発のポイントとは?
第2章 オブジェクトをテスト駆動開発する
第3章 ツール紹介
第4章 テスト駆動のサイクルに火を入れる
第5章 テスト駆動のサイクルを保つ
第6章 オブジェクト指向スタイル
第7章 オブジェクト指向設計を実現する
第8章 サードパーティーコードの上に構築する
第9章 オークションスナイパーを作動させる
第10章 動くスケルトン
第11章 最初のテストを通す
第12章 入札を準備する
第13章 スナイパーが入札する
第14章 スナイパーがオークションで落札する
第15章 実際のユーザインタフェースに向けて
第16章 複数の商品をスナイプする
第17章 Mainクラスを分解する
第18章 詳細を詰める
第19章 エラー処理
第20章 テストの声を聴く
第21章 テストの可読性
第22章 複雑なテストデータの構築
第23章 テストの診断
第24章 テストの柔軟性
第25章 永続性のテスト
第26章 ユニットテストとスレッド
第27章 非同期処理のテスト
第28章 ティム・マキノンによるモックオブジェクトの簡単な歴史

Kubernetesで実践するクラウドネイティブDevOps を読んでいる

夏休みのお供にと思い、Kubernetesで実践するクラウドネイティブDevOpsを読んでいます。
今12章なので、また読み終わったら感想を追記します。
これまで、読み進めている感じ、k8sのことが環境構築からCICD、オブザーバビリティやhelm等の周辺ツールまで網羅的に書かれており、
k8sを使っている方には必携の内容になっていると思います。
また、監訳者の注釈も随所に入っておりわかりやすい内容となっています。
対象読者としては、ある程度k8sを触ったことがある人向けです。

2020/08/28 追記
一通り読んだので、感想です。
まず冒頭でも書いてますが、k8sを本番環境で使っている、あるいはこれから使う予定がある人は一読することをおすすめします。
目次の通り、網羅的に書いてある本なので、何かあったときに辞書のようにも使えます。 個人的には15章、16章が良かったです。アプリケーション/リソースの監視についてどういうことを気にしておくべきか、k8sでどのように仕組みを取り入れるのか書かれていてためになりました。詳細は別の書籍を読むことになりますが、導入としては十分だと思います。
興味がある方は是非読んでみてください。

目次

1章 クラウドでの革命
    1.1 クラウドの創造
        1.1.1 時間を買う
        1.1.2 Infrastructure as a Service
    1.2 DevOpsの黎明
        1.2.1 DevOpsに対する無理解
        1.2.2 ビジネスにとってのメリット
        1.2.3 Infrastructure as Code
        1.2.4 ともに学ぶ
    1.3 コンテナの到来
        1.3.1 これまでの状況
        1.3.2 常識を打ち破った箱
        1.3.3 ソフトウェアのコンテナへの格納
        1.3.4 プラグ&プレイ型アプリケーション
    1.4 コンテナのオーケストラを指揮する
    1.5 Kubernetes
        1.5.1 Borgから Kubernetesへ
        1.5.2 Kubernetesが高い価値を誇る理由
        1.5.3 Kubernetesもいずれ消え去るのか
        1.5.4 Kubernetesは万能ではない
    1.6 クラウドネイティブ
    1.7 運用の将来
        1.7.1 分散型の DevOps
        1.7.2 集中管理が残る領域
        1.7.3 開発者生産性工学
        1.7.4 皆さんこそが将来
    1.8 まとめ

2章 Kubernetes最初の一歩
    2.1 最初のコンテナの実行
        2.1.1 Docker Desktopのインストール
        2.1.2 Dockerの概要
        2.1.3 コンテナイメージの実行
    2.2 デモアプリケーション
        2.2.1 ソースコードの内容
        2.2.2 Goについて
        2.2.3 デモアプリケーションが動作する仕組み
    2.3 コンテナのビルド
        2.3.1 Dockerfileの理解
        2.3.2 最小限のコンテナイメージ
        2.3.3 docker image buildの実行
        2.3.4 イメージの命名
        2.3.5 ポート転送
    2.4 コンテナレジストリ
        2.4.1 レジストリの認証
        2.4.2 イメージの命名とプッシュ
        2.4.3 イメージの実行
    2.5 ようこそ Kubernetesへ
        2.5.1 デモアプリケーションの実行
        2.5.2 コンテナが起動しない場合
    2.6 Minikube
    2.7 まとめ

3章 Kubernetes環境の選択
    3.1 クラスタのアーキテクチャ
        3.1.1 コントロールプレーン
        3.1.2 ノードのコンポーネント
        3.1.3 高可用性
    3.2 セルフホスティング型 Kubernetesのコスト
        3.2.1 想像以上に面倒な作業
        3.2.2 初期セットアップだけの問題ではない
        3.2.3 痒いところに手が届くわけではないツール
        3.2.4 Kubernetesは難しい
        3.2.5 管理のオーバヘッド
        3.2.6 まずはマネージドサービスから
    3.3 マネージド Kubernetesサービス
        3.3.1 Google Kubernetes Engine(GKE)
        3.3.2 クラスタのオートスケール
        3.3.3 Amazon Elastic Container Service for Kubernetes(EKS)
        3.3.4 Azure Kubernetes Service(AKS)
        3.3.5 OpenShift
        3.3.6 IBM Cloud Kubernetes Service
        3.3.7 Heptio Kubernetes Subscription(HKS)
    3.4 ターンキー方式の Kubernetesソリューション
        3.4.1 Stackpoint.io
        3.4.2 Containership Kubernetes Engine(CKE)
    3.5 Kubernetesインストーラ
        3.5.1 kops
        3.5.2 Kubespray
        3.5.3 TK8
        3.5.4 Kubernetes The Hard Way
        3.5.5 kubeadm
        3.5.6 Tarmak
        3.5.7 Rancher Kubernetes Engine(RKE)
        3.5.8 Puppet Kubernetesモジュール
        3.5.9 Kubeformation
    3.6 購入か構築か:本書の推奨事項
        3.6.1 実行するソフトウェアを減らす
        3.6.2 可能ならマネージド Kubernetesを使用
        3.6.3 ベンダロックインの問題
        3.6.4 どうしても必要なら標準の Kubernetesセルフホスティングツールを使用
        3.6.5 選択肢が限られる場合
        3.6.6 ベアメタルとオンプレミス
    3.7 クラスタレスのコンテナサービス
        3.7.1 Amazon Fargate
        3.7.2 Azure Container Instances(ACI)
    3.8 まとめ

4章 Kubernetesオブジェクトの基本操作
    4.1 Deployment
        4.1.1 スーパバイズ機能とスケジューリング
        4.1.2 コンテナの再起動
        4.1.3 Deployment情報の取得
    4.2 Pod
    4.3 ReplicaSet
    4.4 望ましい状態の維持
    4.5 Kubernetesスケジューラ
    4.6 YAML形式のリソースマニフェスト
        4.6.1 リソースがデータ
        4.6.2 Deploymentマニフェスト
        4.6.3 kubectl applyの使用
        4.6.4 Serviceリソース
        4.6.5 kubectlを用いたクラスタへのクエリ
        4.6.6 リソース管理の次の段階
    4.7 Helm:Kubernetesパッケージマネージャ
        4.7.1 Helmのインストール
        4.7.2 Helmチャートのインストール
        4.7.3 チャート、リポジトリ、リリース
        4.7.4 Helmリリースのリスト表示
    4.8 まとめ

5章 リソースの管理
    5.1 リソースの理解
        5.1.1 リソースの単位
        5.1.2 リソース要求
        5.1.3 リソース制限
        5.1.4 コンテナは小さく保つ
    5.2 コンテナのライフサイクル管理
        5.2.1 Liveness probe
        5.2.2 ブローブの遅延と頻度
        5.2.3 他のタイプのプローブ
        5.2.4 gRPC probe
        5.2.5 Readiness probe
        5.2.6 ファイルベースのReadiness probe
        5.2.7 minReadySeconds
        5.2.8 Pod Disruption Budget
    5.3 Namespaceの使用
        5.3.1 Namespaceを使った作業
        5.3.2 Namespaceの選択基準
        5.3.3 Serviceのアドレス
        5.3.4 リソースのクオータ
        5.3.5 リソース要求とリソース制限のデフォルト値
    5.4 クラスタのコストの最適化
        5.4.1 Deploymentの最適化
        5.4.2 Podの最適化
        5.4.3 Vertical Pod Autoscaler
        5.4.4 ノードの最適化
        5.4.5 ストレージの最適化
        5.4.6 未使用リソースのクリーンアップ
        5.4.7 余剰キャパシティのチェック
        5.4.8 リザーブドインスタンスの使用
        5.4.9 プリエンプティブ(スポット)インスタンスの使用
        5.4.10 ワークロードのバランスの維持
    5.5 まとめ

6章 クラスタの運用
    6.1 クラスタのサイジングとスケーリング
        6.1.1 キャパシティ計画
        6.1.2 ノードとインスタンス
        6.1.3 クラスタのスケーリング
    6.2 適合性のチェック
        6.2.1 CNCF認定
        6.2.2 Sonobuoyによる適合性テスト
    6.3 検証と監査
        6.3.1 K8Guard
        6.3.2 Copper
        6.3.3 kube-bench
        6.3.4 Kubernetesの監査ロギング
    6.4 カオステスト
        6.4.1 本番だけが本番
        6.4.2 chaoskube
        6.4.3 kube-monkey
        6.4.4 PowerfulSeal
    6.5 まとめ

7章 Kubernetesの強力なツール
    7.1 kubectlを極める
        7.1.1 シェルエイリアス
        7.1.2 フラグの短縮形の使用
        7.1.3 リソースタイプの省略
        7.1.4 kubectlコマンドの自動補完機能
        7.1.5 ヘルプの表示
        7.1.6 Kubernetesリソースに関するヘルプの表示
        7.1.7 より詳細な出力の表示
        7.1.8 JSONデータと jqの活用
        7.1.9 オブジェクトの監視
        7.1.10 オブジェクトに関する記述
    7.2 リソースを使った作業
        7.2.1 命令的な kubectlコマンド
        7.2.2 命令的コマンドを使うべきではない場合
        7.2.3 リソースマニフェストの生成
        7.2.4 リソースのエクスポート
        7.2.5 リソースの差分チェック
    7.3 コンテナを使った作業
        7.3.1 コンテナのログの閲覧
        7.3.2 コンテナへのアタッチ
        7.3.3 kubespyによる Kubernetesリソースの監視
        7.3.4 コンテナポートの転送
        7.3.5 コンテナでのコマンド実行
        7.3.6 トラブルシューティングのためのコンテナ実行
        7.3.7 BusyBoxコマンドの使用
        7.3.8 BusyBoxのコンテナへの追加
        7.3.9 コンテナへのプログラムのインストール
        7.3.10 kubesquashによるライブデバッグ
    7.4 Contextと Namespace
        7.4.1 kubectxと kubens
        7.4.2 kube-ps1
    7.5 Kubernetesのシェルとツール
        7.5.1 kube-shell
        7.5.2 Click
        7.5.3 kubed-sh
        7.5.4 Stern
    7.6 独自の Kubernetesツールの構築
    7.7 まとめ

8章 コンテナの実行
    8.1 コンテナと Pod
        8.1.1 コンテナとは何か
        8.1.2 コンテナの構成要素
        8.1.3 Podの構成要素
    8.2 コンテナのマニフェスト
        8.2.1 イメージ識別子
        8.2.2 latestタグ
        8.2.3 コンテナのダイジェスト
        8.2.4 ベースイメージのタグ
        8.2.5 ポート
        8.2.6 リソース要求とリソース制限
        8.2.7 イメージのプルに関するポリシ
        8.2.8 環境変数
    8.3 コンテナのセキュリティ
        8.3.1 非rootユーザとしてのコンテナ実行
        8.3.2 rootコンテナのブロック
        8.3.3 読み取り専用ファイルシステムの設定
        8.3.4 権限昇格の無効化
        8.3.5 ケイパビリティ
        8.3.6 Podのセキュリティコンテキスト
        8.3.7 Podのセキュリティに関するポリシ
        8.3.8 Podのサービスアカウント
    8.4 ボリューム
        8.4.1 emptyDirボリューム
        8.4.2 永続ボリューム
    8.5 再起動ポリシ
    8.6 Image Pull Secret
    8.7 まとめ

9章 Podの管理
    9.1 Label
        9.1.1 Labelとは何か
        9.1.2 セレクタ
        9.1.3 セレクタの高度な使い方
        9.1.4 Labelの他の使い方
        9.1.5 LabelとAnnotation
    9.2 Node Affinity
        9.2.1 ハード Affinity
        9.2.2 ソフト Affinity
    9.3 Podの Affinityと Anti-Affinity
        9.3.1 Podの同居
        9.3.2 Podの分離
        9.3.3 ソフト Anti-Affinity
        9.3.4 Pod Affinityを使ってもよい場合
    9.4 Taintと Toleration
    9.5 Podコントローラ
        9.5.1 DaemonSet
        9.5.2 StatefulSet
        9.5.3 Job
        9.5.4 CronJob
        9.5.5 Horizontal Pod Autoscaler
        9.5.6 PodPreset
        9.5.7 Operatorと Custom Resource Definition(CRD)
    9.6 Ingressリソース
        9.6.1 Ingressルール
        9.6.2 Ingressによる TLS終端
        9.6.3 Ingressコントローラ
    9.7 Istio
    9.8 Envoy
    9.9 まとめ

10章 設定と機密情報
    10.1 ConfigMap
        10.1.1 ConfigMapの作成
        10.1.2 ConfigMapからの環境変数の設定
        10.1.3 ConfigMapからの環境全体の設定
        10.1.4 コマンド引数での環境変数の使用
        10.1.5 ConfigMapからの設定ファイルの作成
        10.1.6 設定変更に伴う Podの更新
    10.2 Kubernetesの Secret
        10.2.1 環境変数としてのSecretの使用
        10.2.2 Secretのファイルへの書き込み
        10.2.3 Secretの読み取り
        10.2.4 Secretへのアクセス
        10.2.5 保存データの暗号化
        10.2.6 Secretの保持
    10.3 機密情報管理の戦略
        10.3.1 バージョン管理を通じた機密情報の暗号化
        10.3.2 機密情報のリモート保存
        10.3.3 専用の機密情報管理ツールの使用
        10.3.4 本書の推奨事項
    10.4 SOPSによる機密情報の暗号化
        10.4.1 SOPSの概要
        10.4.2 SOPSによるファイルの暗号化
        10.4.3 KMSバックエンドの使用
    10.5 まとめ

11章 セキュリティとバックアップ
    11.1 アクセス制御とパーミッション
        11.1.1 クラスタ別のアクセス管理
        11.1.2 ロールベースのアクセス制御(RBAC)の導入
        11.1.3 ロールの理解
        11.1.4 ユーザに対するロールのバインディング
        11.1.5 必要なロールの判断
        11.1.6 cluster-adminに対するアクセスの保護
        11.1.7 アプリケーションとデプロイ
        11.1.8 RBACのトラブルシューティング
    11.2 セキュリティスキャン
        11.2.1 Clair
        11.2.2 Aqua Security
        11.2.3 Anchore Engine
    11.3 バックアップ
        11.3.1 Kubernetesをバックアップする必要性
        11.3.2 etcdのバックアップ
        11.3.3 リソース状態のバックアップ
        11.3.4 クラスタ状態のバックアップ
        11.3.5 大小のディザスタ
        11.3.6 Velero
    11.4 クラスタのステータスの監視
        11.4.1 kubectl
        11.4.2 CPUとメモリの使用率
        11.4.3 クラウドプロバイダのコンソール
        11.4.4 Kubernetes Dashboard
        11.4.5 Weave Scope
        11.4.6 kube-ops-view
        11.4.7 node-problem-detector
    11.5 参考文献
    11.6 まとめ

12章 Kubernetesアプリケーションのデプロイ
    12.1 Helmによるマニフェストのビルド
        12.1.1 Helmチャートの内部構成
        12.1.2 Helmテンプレート
        12.1.3 変数の補完
        12.1.4 テンプレートにおける値の引用
        12.1.5 依存関係の指定
    12.2 Helmチャートのデプロイ
        12.2.1 変数の設定
        12.2.2 Helmリリースにおける値の指定
        12.2.3 アプリケーションの Helmによる更新
        12.2.4 以前のバージョンへのロールバック
        12.2.5 Helmチャートリポジトリの作成
        12.2.6 Helmチャート内の SecretのSOPSによる管理
    12.3 Helmfileによる複数チャートの管理
        12.3.1 Helmfileの内容
        12.3.2 チャートのメタデータ
        12.3.3 Helmfileの適用
    12.4 高度なマニフェスト管理ツール
        12.4.1 ksonnet
        12.4.2 Kapitan
        12.4.3 kustomize
        12.4.4 kompose
        12.4.5 Ansible
        12.4.6 Kubeval
    12.5 まとめ

13章 開発ワークフロー
    13.1 開発ツール
        13.1.1 Skaffold
        13.1.2 Draft
        13.1.3 Telepresence
        13.1.4 Knative
    13.2 デプロイ戦略
        13.2.1 ローリングアップデート
        13.2.2 Recreate
        13.2.3 maxSurgeと maxUnavailable
        13.2.4 ブルーグリーンデプロイ
        13.2.5 レインボーデプロイ
        13.2.6 カナリアデプロイ
    13.3 Helmによる移行処理
        13.3.1 Helmのフック機能
        13.3.2 フック失敗時の対応
        13.3.3 他のフック
        13.3.4 フックのチェーン化
    13.4 まとめ

14章 Kubernetesにおける継続的デプロイ
    14.1 継続的デプロイとは何か
    14.2 おすすめの CDツール
        14.2.1 Jenkins
        14.2.2 Drone
        14.2.3 Google Cloud Build
        14.2.4 Concourse
        14.2.5 Spinnaker
        14.2.6 GitLab CI
        14.2.7 Codefresh
        14.2.8 Azure Pipelines
    14.3 CDのコンポーネント
        14.3.1 Docker Hub
        14.3.2 Gitkube
        14.3.3 Flux
        14.3.4 Keel
    14.4 Cloud Buildによる CDパイプライン
        14.4.1 Google Cloudと GKEのセットアップ
        14.4.2 デモリポジトリのフォーク
        14.4.3 Cloud Buildの導入
        14.4.4 テスト用コンテナのビルド
        14.4.5 テストの実行
        14.4.6 アプリケーションコンテナのビルド
        14.4.7 Kubernetesマニフェストの検証
        14.4.8 イメージのパブリッシュ
        14.4.9 Git SHAタグ
        14.4.10 最初のビルドトリガの作成
        14.4.11 トリガのテスト
        14.4.12 CDパイプラインからのデプロイ
        14.4.13 デプロイトリガの作成
        14.4.14 ビルドパイプラインの最適化
        14.4.15 パイプライン例の適応化
    14.5 まとめ

15章 オブザーバビリティと監視
    15.1 オブザーバビリティとは何か
        15.1.1 監視とは何か
        15.1.2 ブラックボックス監視
        15.1.3 「アップ」の意味
        15.1.4 ロギング
        15.1.5 メトリクスの導入
        15.1.6 トレーシング
        15.1.7 オブザーバビリティ
    15.2 オブザーバビリティパイプライン
    15.3 Kubernetesにおける監視
        15.3.1 外部からのブラックボックス型チェック
        15.3.2 内部ヘルスチェック
    15.4 まとめ

16章 Kubernetesにおけるメトリクス
    16.1 メトリクスとは実際のところ何か
        16.1.1 時系列データ
        16.1.2 カウンタとゲージ
        16.1.3 メトリクスは何を語れるか
    16.2 優れたメトリクスの選択
        16.2.1 サービス:REDパターン
        16.2.2 リソース:USEパターン
        16.2.3 ビジネスメトリクス
        16.2.4 Kubernetesのメトリクス
    16.3 メトリクスの分析
        16.3.1 単純な平均の問題点
        16.3.2 単純平均、中央値、外れ値
        16.3.3 パーセンタイルの把握
        16.3.4 メトリクスデータへのパーセンタイルの適用
        16.3.5 最悪を知ることこそ一般の関心事
        16.3.6 パーセンタイルを超えて
    16.4 メトリクスのダッシュボードによるグラフ化
        16.4.1 すべてのサービスで標準レイアウトを使う
        16.4.2 マスタダッシュボードで情報ラジエータを構築
        16.4.3 壊れていくもののダッシュボード
    16.5 メトリクスに基づくアラート
        16.5.1 アラートの問題点
        16.5.2 オンコールを地獄にすべきではない
        16.5.3 緊急かつ重要で対処可能なアラート
        16.5.4 アラート、時間外呼び出し、夜間起床の追跡管理
    16.6 メトリクス管理のツールとサービス
        16.6.1 Prometheus
        16.6.2 Google Stackdriver
        16.6.3 AWS CloudWatch
        16.6.4 Azure Monitor
        16.6.5 Datadog
        16.6.6 New Relic
    16.7 まとめ

あとがき
索引

tviewを使ってFileViewを作ってみた

最近、Fukuoka.go#16でGoで作るTUIツールという発表を見て、
tviewの存在を思い出したのでちょっと使ってみました。
(発表でも書いてありましたが、tviewはちょっとしたTUIを作るには最高にお手軽なのでTUIに興味がある方は是非)

作ったもの

github.com

Todo

  • ファイルの色付
  • バイナリファイルを開いた際に落ちる
  • キーボードショートカット対応