2018年読んだ本
2018年の読書メーター
読んだ本の数:15
読んだページ数:4818
ナイス数:70
アシュリーの戦争 -米軍特殊部隊を最前線で支えた、知られざる「女性部隊」の記録の感想
15時間ほどで読めた。CST(文化支援部隊)という女性メンバーだけの特殊部隊を追ったノンフィクション。CSTの役割はアフガニスタンでの戦闘でアフガニスタン人の女性や子供たちから情報を聞き出すことが彼女たちの任務で地上戦の最前線でレンジャーの任務を支えていました。主人公のアシュリーが英雄視されているようで、プロパガンダ的作品と感じとってしまいました。2016年にアメリカの女性兵士も地上戦闘に参加することが法的に認められたのも、このCSTがあってのことのようで米軍にとっても大きな影響を与えた部隊だと思います。
読了日:12月30日 著者:ゲイル・スマク・レモン
シベリアの掟の感想
15時間ほどで読めた。かなりの力作だけど面白かった。筆者の幼少期の自伝的小説。これはntddkさんが面白いとツイートしていたので読んだ。この本については多くは語るのは不要だと思いますので、この本についての感想は本の中で語られているシベリアの掟の引用で締めくくる。『私たちシベリアの民は、子供の頃から「言葉にフィルターをかける」、すなわちたとえ故意でなくとも決して過ちを犯さないよう、口から出る言葉に気をつけることを教えられてきた。シベリアの掟によれば、「一度口から飛び去った言葉は二度と戻ってこない」からだ。』
読了日:12月30日 著者:ニコライ・リリン
五色の虹 満州建国大学卒業生たちの戦後の感想
8時間ほどで読めた。日本が満州国を建国した時の理念である五族協和。満州国を引っ張っていくリーダーを育成するための学校である満州建国大学についての話。日・漢・朝・満・蒙から集められた超エリートの卒業生たちを取材することで少ない資料の中、どんな学校だったのか、どんなことを考えて授業を受けたのか、戦後どうなったのか話をきいて浮き彫りになっていく建国大学。日本の敗戦とともにエリートだった学生たちが不遇の待遇を受けていたりと、国がその優秀な人材を生かさず中には忙殺する亡国もあったりと、貴重な歴史的資料のような一冊。
読了日:12月30日 著者:三浦 英之
悪童日記 (ハヤカワepi文庫)の感想
5時間ほどで読めた。薄い小説だけどrebuild.fmで紹介されていたように凄まじい本。打ちのめされるような本。双子の男の子の日記の体でストーリーが進んでいきます。男の子たちの行動原理みたいなものが読み取れてるので、その行動が加速するにつれてページを捲るスピードも上がっていきました。全部で第3部らしいのですが、素晴らしい作品のようですのでほかも読んでみたいです。子供だから視点は狭いようで、大人とは別の視点を持ち戦争下の描写が書かれています。筆者の幼少期の体験を双子の男の子を通して追体験するような感覚です。
読了日:12月30日 著者:アゴタ クリストフ
UNIXという考え方―その設計思想と哲学の感想
20時間ぐらいで読めたと思う。途中何年も積んだりしたので、正確な時間がわかないけど、薄いけど一気に読めるような文章ではないので読むのが大変だった。名著ということでとりあえず読んでみたのが良くないのか、あんまり理解できなかった。これだけみんな名著と思って読まれているのにUNIXという考え方で実装していないのは何故だと思うぐらい複雑だったり謎の処理つけたりしているので気をつけたいですね。Linuxコマンドは強力でそれを使うスクリプトも強力ですね。こんな内容の現代の本が読みたいのでオススメあったら教えて下さい。
読了日:11月30日 著者:Mike Gancarz
スラスラ読める JavaScript ふりがなプログラミング (ふりがなプログラミングシリーズ)の感想
6時間ほどで読めた。タイトルの通りスラスラ読めました。ES6でJavaScriptを説明していますので、これからJavaScriptを勉強したい人や、プログラミングを覚えたい人が読む最初の一冊には良いと思いました。ふりがなが全てに振ってあるので、これがどんな意味なのかを、おまじないなどでごまかしていないので納得して読み進めることができると思います。監修も及川卓也さんなので内容も安心して読むことができました。次のステップはどう進めていけばいいのかは書いてないので、どうステップを進めるかが難しいと思いました。
読了日:08月20日 著者:リブロワークス
Linuxサーバーセキュリティ徹底入門 オープンソースによるサーバー防衛の基本の感想
8時間ほどで読めました。CentOS6で内容は少し古いですが、現在動いているシステムを運用している人は読んでおくとよいと思いました。LinuxのOS全般とApacheやメールなどの設定でセキュアな設定について細かく書かれており、わかりやすく書かれています。どのような運用が望ましいのかなども自分で調べるには難しいですが、このような本が増えてほしいと思いました。MySQLなどのDBやPHPなどについては記載ありませんが、それらはどのような本を読めばいいかなどの動線があればよいなと思います。おすすめの一冊です。
読了日:08月16日 著者:中島 能和
インフラエンジニアの教科書2 スキルアップに効く技術と知識の感想
10時間ほどで読めた。インフラエンジニア教科書とのことなのでインフラエンジニアとして読んでみた。1は立ち読みしたことありますが、個人的には2の方が読んでいて面白かったです。オペレーションシステムの基礎知識をわりと実用的なレベルで紹介されていて、インフラエンジニアになった人のまさに教科書的な存在だと思います。個人的にはなるほどUnixなどで、手で動かしてから読んでから読んだ方が理解が深まると思います。OSの動作の理屈をいきなり本を読んで理解できる人は頭がいいと思うので、普通の人は手を動かすといいと思います。
読了日:07月31日 著者:佐野 裕
絵で見てわかるOS/ストレージ/ネットワーク~データベースはこう使っている (DB Magazine Selection)の感想
読むのに30時間ぐらいかかったと思う。新人の時(6年前)から何度も途中で諦めたりした本。OSやストレージ、DBMS、ネットーワークとシステム周り全般のボトルネックがどこか、リソースをどう使っているのかなどをコマンド実行レイヤ、絵を通して詳細に解説してくれている。個人的には詳解システムパフォーマンスの前に読んでおくと良いのではないかと思った。内容はオンプレミスのシステム前提で少し古いので、今のクラウド時代での内容に即した内容ではどうなるか気になるし、どんな本がそれにあたるのか気になる。このような本読みたい。
読了日:07月31日 著者:小田 圭二
オブジェクト指向でなぜつくるのか 第2版の感想
15時間ほどで読めた。Pythonでクラスをどういう時に書くべきなのか、オブジェクト指向でプログラミングするとはどういうことなのかよくわかっていないのでオブジェクト指向とは何なのかじっくり調べたいと思って読みました。この本は1冊まるまる書いているので説明が豊富でわかりやすかったです。Pythonの入門本とかだと犬とか人間とかを例にしたりして解説するのが余計に混乱させられていたのでオブジェクト指向の歴史と意義やクラス(カプセル化)・継承・ポリモーフィズムがどう意味なのかわかりやすく説明してありよかったです。
読了日:07月31日 著者:平澤 章
アカマイ―知られざるインターネットの巨人 (角川EPUB選書)の感想
6時間ほどで読めた。インターネットのトラフィックがどう流れているのか、CDNのアカマイがどういう成り立ちでできたのか。どのようにサービスを成り立たせているのか、どのような仕組みなのかなどをわかりやすく説明されているので読んでいて楽しかったです。CDNを利用すればオリジンサーバへの負荷分散にもなり、ユーザも高速にアクセスができ本当に良いものです。ネットワークの基本のようなものと併せて本書を読むことでインターネットの大枠を掴むことができるのではないでしょうか。誰にでも読むことができるので、オススメの一冊です。
読了日:06月21日 著者:小川 晃通
MySQL徹底入門 第3版 ~5.5新機能対応~の感想
10時間ほどで読めた。4年ほど積んでいましたが、そろそろMySQLに入門したい気持ちになり読みました。内容としては設定から運用までわかりやすくまとめっていて良いと思います。内容も5.5なのでそこまで古くはないので今読んでも参考になりました。昨今MySQL8がリリースされましたが、ほとんどの運用されているMySQLのバージョンはおいくつでしょうか?そうですね。おわかりのように、この本の内容は古くはないのです。次は実践ハイパフォーマンスMySQLをよんでMySQLの内部にもう少し踏み込んでいきたいと思います。
読了日:05月30日 著者:遠藤 俊裕,坂井 恵,館山 聖司,鶴長 鎮一,とみた まさひろ,班石 悦夫,松信 嘉範
忘れられた巨人の感想
40時間ぐらいかけて読んだ。カズオ・イシグロは初めて読みます。牧歌的なファンタジー小説という印象で、THE・ビッグオーのような世界観です。記憶を奪う霧のせいで過去が曖昧な老夫婦がある日息子の存在を思い出して、どこに住んでいるかも顔も思い出せない息子に会いに行こうと行くあてのない旅を初めます。舞台はイングランドで時代はアーサー王伝説なので、この物語には騎士王伝説の知識があるとより楽しめるのかもしれません。読んでいて、ついさっきの記憶も危うい人達の会話を延々と読むことになるので、かなりの混乱が起こりました。
読了日:05月02日 著者:カズオ イシグロ
データ分析基盤構築入門[Fluentd、Elasticsearch、Kibanaによるログ収集と可視化]の感想
8時間ほどで読めた。EFKで可視化したい人向けの本。
td-agentとElasticStackはバージョンが上がってしまったので、この本の内容は古いが、十分参考になる内容です。Qiitaぐらいしか日本語での情報がないEFKの可視化について上手くまとまっています。また、運用Tipsについても詳しく書かれていますので、運用や監視の勘所やチューニングの勘所についても参考になります。これからEFKで可視化をしたいと思っている人にはお勧めの一冊です。データ分析基盤の本で代表的な一冊になると思います。おすすめです。
読了日:04月22日 著者:鈴木 健太,吉田 健太郎,大谷 純,道井 俊介
Amazon Web Services 基礎からのネットワーク&サーバー構築 改訂版の感想
6時間ほどで読めた。AWSでWEB/DB構成をインスタンス1台ずつたてて、Wordpressを構築するLessonとなっています。新改訂版でコンソールが日本語対応となっているので、わかりやすくなっています。一部コンソール表示は変わっていましたが。他にもネットワークの説明、VPNやサブネットなどAWS特有の説明もされているのでAWSはじめに読む本には良いと思います。TCP/IP周りの説明もされていますので、サーバやネットワークの勉強がしたい人にもおすすめです。内容は薄いのでサクサクすすめてよいと思います。
読了日:01月11日 著者:玉川憲,片山暁雄,今井雄太,大澤文孝
読書メーター
Kubernetes Application Update
303-app-updateの内容
Kubernetes Application Update
今回では、Kubernetesクラスタにデプロイされたアプリケーションを使用して更新する方法について説明しデプロイします。 また、アプリケーションのCanary Deploymentについても見ていきます。
Deploymentは、Podを管理するためのレプリカセットを作成します。 レプリカセット内のレプリカの数は、アプリケーションの要求に合わせて拡大縮小できます。 Deploymentを使用してdeployされたアプリケーションを更新するには、 Deploymentの構成を更新する必要があります。
この変更により、新しいレプリカセットが作成されます。 これは、以前のレプリカセットが縮小されている間にスケールアップされます。 これにより、アプリケーションのダウンタイムが発生しません。
kubectl rolling-update
コマンドが ありますが、レプリカセットにのみ適用されます。
このコマンドからの更新は、クライアント側で行われました。
更新がサーバー側にあるので、Deploymentを使用してrolling-updateを行うことを強くお勧めします。
我々のユースケースでは、アプリケーションは最初に画像を使用します arungupta/app-upgrade:v1
。
次に、イメージを使用するようにDeploymentが更新されます arungupta/app-upgrade:v2
。
v1イメージは "Hello World!"を出力します。
v2イメージは「Howdy World!」を印刷します。
これらのイメージのソースコードはimagesディレクトリにあります。
前提条件
この章の演習を行うには、Kubernetesクラスタ構成を展開する必要があります。 EKSベースのKubernetesクラスタを作成するには、AWS CLIを使用します。 EKSを使用せずにKubernetesクラスタを作成する場合は、代わりにkopsを使用できます。 この章の設定ファイルはすべてapp-updateディレクトリにあります。 この章のコマンドを実行する前に、そのディレクトリに移動してください。 Cloud9で作業している場合は、次のコマンドを実行します。
cd ~/environment/aws-workshop-for-kubernetes/03-path-application-development/303-app-update/
rolling-update
新しいリビジョンへのアップデート
アプリケーションを更新するには、既存のすべてのポッドを、別のバージョンのイメージを使用する新しいポッドに置き換える必要があります。
.spec.strategy
デプロイメント設定で、古いポッドを新しいポッドに置き換えるための戦略を定義することができます。
このキーには次の2つの値があります。
- Recreate
- RollingUpdate (デフォルト)
この2つのデプロイ戦略を見てみましょう。
strategy を再作成する
既存のPodはすべて、新しいものが作成される前に強制終了されます。 設定ファイルは以下のようになります
apiVersion: apps/v1 kind: Deployment metadata: name: app-recreate spec: replicas: 5 selector: matchLabels: name: app-recreate strategy: type: Recreate template: metadata: labels: name: app-recreate spec: containers: - name: app-recreate image: arungupta/app-upgrade:v1 ports: - containerPort: 8080
- deploymentを作成
$ kubectl create -f templates/app-recreate.yaml --record deployment "app-recreate" created
--recordこのdeploymentを開始するコマンドが確実に記録されます。 これは、アプリケーションがいくつかの更新を経て、バージョンとコマンドを関連付ける必要がある場合に便利です。
- deploymentsの履歴を取得
$ kubectl rollout history deployment/app-recreate deployments "app-recreate" REVISION CHANGE-CAUSE 1 kubectl create --filename=templates/app-recreate.yaml --record=true
- サービスを公開する
$ kubectl expose deployment/app-recreate --port=80 --target-port=8080 --name=app-recreate --type=LoadBalancer service "app-recreate" exposed
- サービスの詳細を取得する
$ kubectl describe svc/app-recreate Name: app-recreate Namespace: default Labels: name=app-recreate Annotations: <none> Selector: name=app-recreate Type: LoadBalancer IP: 100.65.43.233 LoadBalancer Ingress: af2dc1f99bda211e791f402037f18a54-1616925381.eu-central-1.elb.amazonaws.com Port: <unset> 80/TCP TargetPort: 80/TCP NodePort: <unset> 30158/TCP Endpoints: 100.96.1.14:80,100.96.2.13:80,100.96.3.13:80 + 2 more... Session Affinity: None External Traffic Policy: Cluster Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal CreatingLoadBalancer 24s service-controller Creating load balancer Normal CreatedLoadBalancer 23s service-controller Created load balancer
- serviceにアクセス
$ curl http://af2dc1f99bda211e791f402037f18a54-1616925381.eu-central-1.elb.amazonaws.com Hello World!
- 別の端末では、Podの状態を確認
$ kubectl get -w pods app-v1-recreate-486400321-4rwzb 1/1 Running 0 9m app-v1-recreate-486400321-fqh5l 1/1 Running 0 9m app-v1-recreate-486400321-jm02h 1/1 Running 0 9m app-v1-recreate-486400321-rl79n 1/1 Running 0 9m app-v1-recreate-486400321-z89nm 1/1 Running 0 9m
- deploymentのイメージを更新します。
$ kubectl set image deployment/app-recreate app-recreate=arungupta/app-upgrade:v2 deployment "app-recreate" image updated
- Podのステータスが更新されます。すべてのPodが最初に終了し、新しいPodが作成されたことを示します。
$ kubectl get -w pods NAME READY STATUS RESTARTS AGE app-v1-recreate-486400321-4rwzb 1/1 Running 0 9m app-v1-recreate-486400321-fqh5l 1/1 Running 0 9m app-v1-recreate-486400321-jm02h 1/1 Running 0 9m app-v1-recreate-486400321-rl79n 1/1 Running 0 9m app-v1-recreate-486400321-z89nm 1/1 Running 0 9m app-v1-recreate-486400321-rl79n 1/1 Terminating 0 10m app-v1-recreate-486400321-jm02h 1/1 Terminating 0 10m app-v1-recreate-486400321-fqh5l 1/1 Terminating 0 10m app-v1-recreate-486400321-z89nm 1/1 Terminating 0 10m app-v1-recreate-486400321-4rwzb 1/1 Terminating 0 10m app-v1-recreate-486400321-rl79n 0/1 Terminating 0 10m app-v1-recreate-486400321-4rwzb 0/1 Terminating 0 10m app-v1-recreate-486400321-fqh5l 0/1 Terminating 0 10m app-v1-recreate-486400321-z89nm 0/1 Terminating 0 10m app-v1-recreate-486400321-jm02h 0/1 Terminating 0 10m app-v1-recreate-486400321-fqh5l 0/1 Terminating 0 10m app-v1-recreate-486400321-fqh5l 0/1 Terminating 0 10m app-v1-recreate-486400321-z89nm 0/1 Terminating 0 10m app-v1-recreate-486400321-z89nm 0/1 Terminating 0 10m app-v1-recreate-486400321-rl79n 0/1 Terminating 0 10m app-v1-recreate-486400321-rl79n 0/1 Terminating 0 10m app-v1-recreate-486400321-jm02h 0/1 Terminating 0 10m app-v1-recreate-486400321-jm02h 0/1 Terminating 0 10m app-v1-recreate-486400321-4rwzb 0/1 Terminating 0 10m app-v1-recreate-486400321-4rwzb 0/1 Terminating 0 10m app-v1-recreate-2362379170-fp3j2 0/1 Pending 0 0s app-v1-recreate-2362379170-xxqqw 0/1 Pending 0 0s app-v1-recreate-2362379170-hkpt7 0/1 Pending 0 0s app-v1-recreate-2362379170-jzh5d 0/1 Pending 0 0s app-v1-recreate-2362379170-k26sf 0/1 Pending 0 0s app-v1-recreate-2362379170-xxqqw 0/1 Pending 0 0s app-v1-recreate-2362379170-fp3j2 0/1 Pending 0 0s app-v1-recreate-2362379170-hkpt7 0/1 Pending 0 0s app-v1-recreate-2362379170-jzh5d 0/1 Pending 0 0s app-v1-recreate-2362379170-k26sf 0/1 Pending 0 0s app-v1-recreate-2362379170-xxqqw 0/1 ContainerCreating 0 0s app-v1-recreate-2362379170-fp3j2 0/1 ContainerCreating 0 1s app-v1-recreate-2362379170-hkpt7 0/1 ContainerCreating 0 1s app-v1-recreate-2362379170-jzh5d 0/1 ContainerCreating 0 1s app-v1-recreate-2362379170-k26sf 0/1 ContainerCreating 0 1s app-v1-recreate-2362379170-fp3j2 1/1 Running 0 3s app-v1-recreate-2362379170-k26sf 1/1 Running 0 3s app-v1-recreate-2362379170-xxqqw 1/1 Running 0 3s app-v1-recreate-2362379170-hkpt7 1/1 Running 0 4s app-v1-recreate-2362379170-jzh5d 1/1 Running 0 4s
出力は、すべてのPodが最初に終了した後、新しいPodが作成されたことを示します。
- deploymentsの履歴を手に入れる
$ kubectl rollout history deployment/app-recreate deployments "app-recreate" REVISION CHANGE-CAUSE 1 kubectl create --filename=templates/app-recreate.yaml --record=true 2 kubectl set image deployment/app-recreate app-recreate=arungupta/app-upgrade:v2
- 再度アプリケーションにアクセスする
$ curl http://af2dc1f99bda211e791f402037f18a54-1616925381.eu-central-1.elb.amazonaws.com Howdy World!
出力にv2は、使用されているイメージのバージョンが表示されるようになりました。
Rolling update戦略
Podはローリングアップデートの方法で更新されます。 Rolling updateの実行方法を定義するには、次の2つのオプションのプロパティを使用できます。
.spec.strategy.rollingUpdate.maxSurge
必要な数のポッドに作成できるポッドの最大数を指定します。値には、絶対数またはパーセンテージを使用できます。デフォルト値は25%です。.spec.strategy.rollingUpdate.maxUnavailable
更新処理中に使用できないポッドの最大数を指定します。
設定ファイルは以下のようになります
apiVersion: apps/v1 kind: Deployment metadata: name: app-rolling spec: replicas: 5 selector: matchLabels: name: app-rolling strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 1 template: metadata: labels: name: app-rolling spec: containers: - name: app-rolling image: arungupta/app-upgrade:v1 ports: - containerPort: 8080
この場合、最大数のポッド上に1つ以上のポッドを作成することができ、更新プロセス中には1つのポッドしか利用できなくなります。
- deploymentを作成
$ kubectl create -f templates/app-rolling.yaml --record deployment "app-rolling" created
再度、--recordこの展開を開始するコマンドが確実に記録されます。 これは、アプリケーションがいくつかの更新を経て、バージョンとコマンドを関連付ける必要がある場合に便利です。
- デプロイの履歴を取得する
$ kubectl rollout history deployment/app-rolling deployments "app-rolling" REVISION CHANGE-CAUSE 1 kubectl create --filename=templates/app-rolling.yaml --record=true
- サービスを公開する
$ kubectl expose deployment/app-rolling --port=80 --target-port=8080 --name=app-rolling --type=LoadBalancer service "app-rolling" exposed
- サービスの詳細を取得する
$ kubectl describe svc/app-rolling Name: app-rolling Namespace: default Labels: name=app-rolling Annotations: <none> Selector: name=app-rolling Type: LoadBalancer IP: 100.71.164.130 LoadBalancer Ingress: abe27b4c7bdaa11e791f402037f18a54-647142678.eu-central-1.elb.amazonaws.com Port: <unset> 80/TCP TargetPort: 80/TCP NodePort: <unset> 31521/TCP Endpoints: 100.96.1.16:80,100.96.2.15:80,100.96.3.15:80 + 2 more... Session Affinity: None External Traffic Policy: Cluster Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal CreatingLoadBalancer 1m service-controller Creating load balancer Normal CreatedLoadBalancer 1m service-controller Created load balancer
- サービスへアクセス
$ curl http://abe27b4c7bdaa11e791f402037f18a54-647142678.eu-central-1.elb.amazonaws.com Hello World!
出力はv1、イメージのバージョンが使用されていることを示します。
- 別の端末では、Podの状態を確認します。
$ kubectl get -w pods NAME READY STATUS RESTARTS AGE app-rolling-1683885671-d7vpf 1/1 Running 0 2m app-rolling-1683885671-dt31h 1/1 Running 0 2m app-rolling-1683885671-k8xn9 1/1 Running 0 2m app-rolling-1683885671-sdjk3 1/1 Running 0 2m app-rolling-1683885671-x1npp 1/1 Running 0 2m
- deploymentのイメージを更新します。
$ kubectl set image deployment/app-rolling app-rolling=arungupta/app-upgrade:v2 deployment "app-rolling" image updated
- Podのステータスが更新されます。
$ kubectl get -w pods NAME READY STATUS RESTARTS AGE app-rolling-1683885671-d7vpf 1/1 Running 0 2m app-rolling-1683885671-dt31h 1/1 Running 0 2m app-rolling-1683885671-k8xn9 1/1 Running 0 2m app-rolling-1683885671-sdjk3 1/1 Running 0 2m app-rolling-1683885671-x1npp 1/1 Running 0 2m app-rolling-4154020364-ddn16 0/1 Pending 0 0s app-rolling-4154020364-ddn16 0/1 Pending 0 1s app-rolling-4154020364-ddn16 0/1 ContainerCreating 0 1s app-rolling-1683885671-sdjk3 1/1 Terminating 0 5m app-rolling-4154020364-j0nnk 0/1 Pending 0 1s app-rolling-4154020364-j0nnk 0/1 Pending 0 1s app-rolling-4154020364-j0nnk 0/1 ContainerCreating 0 1s app-rolling-1683885671-sdjk3 0/1 Terminating 0 5m app-rolling-4154020364-ddn16 1/1 Running 0 2s app-rolling-1683885671-dt31h 1/1 Terminating 0 5m app-rolling-4154020364-j0nnk 1/1 Running 0 3s app-rolling-4154020364-wlvfz 0/1 Pending 0 1s app-rolling-4154020364-wlvfz 0/1 Pending 0 1s app-rolling-1683885671-x1npp 1/1 Terminating 0 5m app-rolling-4154020364-wlvfz 0/1 ContainerCreating 0 1s app-rolling-4154020364-qr1lz 0/1 Pending 0 1s app-rolling-4154020364-qr1lz 0/1 Pending 0 1s app-rolling-1683885671-dt31h 0/1 Terminating 0 5m app-rolling-4154020364-qr1lz 0/1 ContainerCreating 0 1s app-rolling-1683885671-x1npp 0/1 Terminating 0 5m app-rolling-4154020364-wlvfz 1/1 Running 0 2s app-rolling-1683885671-d7vpf 1/1 Terminating 0 5m app-rolling-4154020364-vlb4b 0/1 Pending 0 2s app-rolling-4154020364-vlb4b 0/1 Pending 0 2s app-rolling-4154020364-vlb4b 0/1 ContainerCreating 0 2s app-rolling-1683885671-d7vpf 0/1 Terminating 0 5m app-rolling-1683885671-x1npp 0/1 Terminating 0 5m app-rolling-1683885671-x1npp 0/1 Terminating 0 5m app-rolling-4154020364-qr1lz 1/1 Running 0 3s app-rolling-1683885671-k8xn9 1/1 Terminating 0 5m app-rolling-1683885671-k8xn9 0/1 Terminating 0 5m app-rolling-4154020364-vlb4b 1/1 Running 0 2s
出力は、新しいPodが作成された後、古いPodが作成された後、新しいPodが作成されたことを示します。
- デプロイの履歴を取得する
$ kubectl rollout history deployment/app-rolling deployments "app-rolling" REVISION CHANGE-CAUSE 1 kubectl create --filename=templates/app-rolling.yaml --record=true 2 kubectl set image deployment/app-rolling app-rolling=arungupta/app-upgrade:v2
- アプリケーションに再度アクセスする
$ curl http://abe27b4c7bdaa11e791f402037f18a54-647142678.eu-central-1.elb.amazonaws.com Howdy World!
出力にv2は、使用されているイメージのバージョンが表示されるようになりました。
以前のリビジョンへのロールバック
上記で説明したように、Deploymentをどのように展開したかの詳細は、
kubectl rollout history
コマンドを使用して取得できます。
ロールバックするには、Deploymentの完全な履歴を取得できます。
$ kubectl rollout history deployment/app-rolling deployments "app-rolling" REVISION CHANGE-CAUSE 1 kubectl create --filename=templates/app-rolling.yaml --record=true 2 kubectl set image deployment/app-rolling app-rolling=arungupta/app-upgrade:v2
次のコマンドを使用して以前のバージョンにロールバックします。
$ kubectl rollout undo deployment/app-rolling --to-revision=1 deployment "app-rolling" rolled back
サービスに再度アクセスしてください
$ curl http://abe27b4c7bdaa11e791f402037f18a54-647142678.eu-central-1.elb.amazonaws.com Hello World!
出力はv1、イメージのバージョンが現在使用されていることを示します。
リソースの削除
kubectl delete deployment/app-recreate svc/app-recreate deployment/app-rolling svc/app-rolling
Canary deployment
Canaryデプロイメントを使用すると、少数のユーザーに変更を徐々に反映させることで、すべてのユーザーに展開する前に、新しいバージョンのアプリケーションを本番環境に展開することができます。 Kubernetesでこれを達成するにはいくつかの方法があります。
- Service、DeploymentおよびLabelの使用
- 入力コントローラの使用
- DNSコントローラの使用
- IstioまたはLinkerdの使用
今回はService、DeploymentおよびLabelの方法を見ていきます
Deployment, ServiceとLabels
異なるバージョンのイメージを使用した2つのデプロイメントが使用されます。 どちらの配置も同じポッドラベルを持ちますが、少なくとも1つのラベルが異なります。 一般的なポッドラベルは、サービスのセレクタとして表示されます。 レプリカの数を調整するために、異なるポッドラベルが使用されます。 新しいバージョンのDeploymentの1つのレプリカが古いバージョンとともにリリースされます。 しばらくの間エラーが検出されない場合、新しいバージョンのレプリカの数がスケールアップされ、古いバージョンのレプリカの数が縮小されます。 最終的に、古いバージョンは削除されます。
Deploymentとサービス定義
v1展開のバージョンを見てみましょう
apiVersion: apps/v1 kind: Deployment metadata: name: app-v1 spec: replicas: 2 selector: matchLabels: name: app version: v1 template: metadata: labels: name: app version: v1 spec: containers: - name: app image: arungupta/app-upgrade:v1 ports: - containerPort: 8080
それは arungupta/app-upgrade:v1
イメージを使用します。
それは2つのラベル name: app
と version: v1
v2展開のバージョンを見てみましょう
apiVersion: apps/v1 kind: Deployment metadata: name: app-v2 spec: replicas: 2 selector: matchLabels: name: app version: v2 template: metadata: labels: name: app version: v2 spec: containers: - name: app image: arungupta/app-upgrade:v2 ports: - containerPort: 8080
それは別のイメージ arungupta/app-upgrade:v2
を使用します。
これには、Deploymentのバージョン v1
と一致する1つのラベル name: app
があります。
これは、他のラベル v2
と似ていますが、異なる値 version: v2
を使用しています。
このラベルを使用するv1と、Deploymentの v1
バージョンをオーバーライドすることなく、このDeploymentを独自に拡張できます。
最後に、これらのデプロイメントを使用するサービス定義を見てみましょう。
apiVersion: v1 kind: Service metadata: name: app-service spec: selector: name: app ports: - name: app port: 80 type: LoadBalancer
サービスは、アプリケーションの両方のバージョンに共通のラベルを使用します。これにより、両方のデプロイメントのポッドをサービスの一部にすることができます。
確認しましょう。
Canary Deploymentを作成
- Deploymentのv1バージョンをデプロイする
$ kubectl apply -f templates/app-v1.yaml deployment "app-v1" created
- Deploymentのv2バージョンをデプロイする
$ kubectl apply -f templates/app-v2.yaml deployment "app-v2" created
3. サービスをデプロイする
$ kubectl apply -f templates/app-service.yaml service "app-service" created
- このサービスのPod listを確認してください
$ kubectl get pods -l name=app NAME READY STATUS RESTARTS AGE app-v1-3101668686-4mhcj 1/1 Running 0 2m app-v1-3101668686-ncbfv 1/1 Running 0 2m app-v2-2627414310-89j1v 1/1 Running 0 2m app-v2-2627414310-bgg1t 1/1 Running 0 2m
templates/app-service.yaml
のサービス定義で指定されているポッドのみを選択するように、クエリーのname=app
ラベルを明示的に指定していることに注意してください。
v1バージョンからは2つのポッド、 v2バージョンからは2つのポッドがあります。
このサービスにアクセスすると、v1バージョンから50%、2vバージョンから50%の応答が得られます。
Canary Deploymentをスケール
v1バージョンとv2バージョンから含まれるポッドの数は、2つのデプロイメントを使用して個別に拡張できます。
- v2 deployment のレプリカ数を増やす
$ kubectl scale deploy/app-v2 --replicas=4 deployment "app-v2" scaled
- サービスの一部であるポッドを確認してください
$ kubectl get pods -l name=app NAME READY STATUS RESTARTS AGE app-v1-3101668686-4mhcj 1/1 Running 0 6m app-v1-3101668686-ncbfv 1/1 Running 0 6m app-v2-2627414310-89j1v 1/1 Running 0 6m app-v2-2627414310-8jpzd 1/1 Running 0 7s app-v2-2627414310-b17v8 1/1 Running 0 7s app-v2-2627414310-bgg1t 1/1 Running 0 6m
現在、4つのポッドはアプリケーションのバージョンv2
から来ており、2つのポッドはアプリケーションのバージョンv1
から来ていることがわかります。
したがって、ユーザーからのトラフィックの3分の2が新しいアプリケーションから提供されるようになります。
- v1バージョンのレプリカ数を0に減らす
$ kubectl scale deploy/app-v1 --replicas=0 deployment "app-v1" scaled
- サービスの一部であるPodを確認してください
$ kubectl get pods -l name=app NAME READY STATUS RESTARTS AGE app-v2-2627414310-89j1v 1/1 Running 0 8m app-v2-2627414310-8jpzd 1/1 Running 0 1m app-v2-2627414310-b17v8 1/1 Running 0 1m app-v2-2627414310-bgg1t 1/1 Running 0 8m
現在、すべてのポッドがDeploymentのv2
バージョンを提供しています。
Canary Deploymentを削除する
上記で作成したすべてのリソースを削除するには、このコマンドを実行します。
$ kubectl delete svc/app-service deployment/app-v1 deployment/app-v2
Ingress Controller (まだ未実装)
デプロイメントとサービスを使用してトラフィックの適切なパーセンテージを達成するには、必要な数のポッドをスピンアップする必要があります。 たとえば、バージョンにv1ポッドのレプリカが4つある場合などです。 次に、バージョンに5%のトラフィックを向けるためにv2、1ポッドのv2バージョンのレプリカには16個のv1バージョンのレプリカがさらに必要になります。 これはリソースの最適な使用ではありません。 この問題を解決するには、Kubernetes Ingressによる重み付けトラフィックの切り替えが使用できます。
Zalandoによると Kubernetes Ingress Controller for AWS はKubernetesのIngressコントローラ
$ kubectl apply -f templates/ingress-controller.yaml deployment "app-ingress-controller" created
Service Discovery for Microservices with Kubernetes
302-app-discovery
Service Discovery for Microservices with Kubernetes
ハードコードされたIPアドレスを使用するのではなく、 アプリケーション内のさまざまなマイクロサービスがサービス検出を使用してインフラストラクチャ内で互いにどのように位置付けられるかの例を示す。
前提条件
3つのマスターノードと5つのワーカーノードを持つクラスタを使用
アプリケーションアーキテクチャ
サンプルアプリケーションでは、次の3つのサービスを使用
webapp
:Webアプリケーションのマイクロサービスはgreeter
、name
のマイクロサービスを使用して人のために挨拶を生成します。greeter
:マイクロサービスはgreet
、URLの名前/値のキーペアに基づいて挨拶を返します。name
:id
URLの名前/値のキーペアに基づいて人の名前を返すマイクロサービス。
これらのサービスは、Dockerイメージとして構築され、Kubernetesに配備されています。すべてのサービスはNode.jsアプリケーションとしてビルドされています。 サービスのソースコードは https://github.com/arun-gupta/container-service-discovery/tree/master/services にあります。
これらの webapp
サービスは name
と greeter
サービスと通信するに、以下の環境変数でサービスを構成する必要があります。
NAME_SERVICE_HOST
と GREETER_SERVICE_HOST
の環境変数は、そのラベルではなく、ポッドまたはホストのIPアドレスなどの静的参照することによって、これらのサービスを参照してください。
その利点は 存在している name
および/または greeter
ポッドがもはや操作可能でなくなった場合、それが依存するサービスを継続して実行するために十分なリソースがクラスタにある場合、 webapp
サービスは機能し続けます。
- NAME_SERVICE_HOST
- NAME_SERVICE_PORT
- NAME_SERVICE_PATH
- GREETER_SERVICE_HOST
- GREETER_SERVICE_PORT
- GREETER_SERVICE_PATH
3つの異なるサービスを持つ設定ファイルは、app.yml で定義されています。 webappサービスのレプリカセットには、次の環境変数があります。
spec: containers: - name: webapp-pod image: arungupta/webapp-service:latest env: - name: NAME_SERVICE_HOST value: name-service - name: NAME_SERVICE_PORT value: "8080" - name: NAME_SERVICE_PATH value: / - name: GREETER_SERVICE_HOST value: greeter-service - name: GREETER_SERVICE_PORT value: "8080" - name: GREETER_SERVICE_PATH value: /
環境変数は、アプリケーション構成で定義されているように、name
およびgreeter
サービスを指しています。
webapp
サービス用のイングレスロードバランサは、次のフラグメントを使用して作成されます。
spec: selector: app: webapp-pod ports: - name: web port: 80 type: LoadBalancer
全体として、サービスは次のように互いに通信します。
[Ingress LB (ELB)] → [WEBAPP] → /name-service → Name ↓ → /greeter-service → Greeter
アプリケーションのデプロイ
アプリケーションをデプロイする
$ kubectl create -f templates/app.yml service "name-service" created replicaset.extensions "name-rs" created service "greeter-service" created replicaset.extensions "greeter-rs" created service "webapp-service" created replicaset.extensions "webapp-rs" created
サービスのリストを取得
$ kubectl get svc NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE greeter-service 100.64.44.23 <none> 8080/TCP 13s kubernetes 100.64.0.1 <none> 443/TCP 23m name-service 100.66.113.58 <none> 8080/TCP 13s webapp-service 100.71.126.195 a5427e1288472... 80:31234/TCP 12s
- サービスの詳細情報を取得
$ kubectl describe svc/webapp-service Name: webapp-service Namespace: default Labels: <none> Annotations: <none> Selector: app=webapp-pod Type: LoadBalancer IP: 100.71.126.195 LoadBalancer Ingress: a5427e128847211e782280a896fc2bfc-283874069.us-east-1.elb.amazonaws.com Port: web 80/TCP NodePort: web 31234/TCP Endpoints: 100.96.2.12:80 Session Affinity: None Events: FirstSeen LastSeen Count From SubObjectPath Type Reason Message --------- -------- ----- ---- ------------- -------- ------ ------- 30s 30s 1 service-controller Normal CreatingLoadBalancer Creating load balancer 29s 29s 1 service-controller Normal CreatedLoadBalancer Created load balancer
アプリケーションへアクセス
ブラウザやcurlでアプリケーションにアクセスする
http://<host> http://<host>?greet=ho http://<host>?id=1 http://<host>?greet=ho&id=1
<host>
はロードバランサのアドレスの入力値
$ kubectl get svc/webapp-service -o jsonpath={.status.loadBalancer.ingress[0].hostname} a5427e128847211e782280a896fc2bfc-283874069.us-east-1.elb.amazonaws.com
アプリケーション削除
$ kubectl delete -f templates/app.yml
k8sクラスタのアップグレード
203-cluster-upgrades
Kubernetesクラスタのアップグレード
AWS上のKubernetesクラスタのアップグレードは、kopsで簡単にできます。 今回Kubernetesクラスターを2つの方法でアップグレードする方法を試します。
インプレースアップグレード
Kopsを使用すると、インプレースを使用してクラスタをアップグレードすることは簡単です。 バージョン1.6.10のKubernetesクラスタをセットアップし、kopsを使用して1.7.2への自動ローリングアップグレードを実行します。
クラスタを作成
次のようにKubernetes 1.6.10バージョンクラスタを作成します。
kops create cluster \ --name example.cluster.k8s.local \ --master-count 3 \ --node-count 5 \ --zones $AWS_AVAILABILITY_ZONES \ --kubernetes-version=1.6.10 \ --yes
マルチAZ配備のクラスタにより、クラスタのアップグレード中にポッドやサービスがダウンタイムを起こさないことが保証されます。
クラスタを検証
$ kops validate cluster --name example.cluster.k8s.local Validating cluster example.cluster.k8s.local INSTANCE GROUPS NAME ROLE MACHINETYPE MIN MAX SUBNETS master-eu-central-1a Master m3.medium 1 1 eu-central-1a master-eu-central-1b Master m3.medium 1 1 eu-central-1b master-eu-central-1c Master c4.large 1 1 eu-central-1c nodes Node t2.medium 5 5 eu-central-1a,eu-central-1b,eu-central-1c NODE STATUS NAME ROLE READY ip-172-20-112-170.eu-central-1.compute.internal master True ip-172-20-117-204.eu-central-1.compute.internal node True ip-172-20-54-176.eu-central-1.compute.internal master True ip-172-20-55-115.eu-central-1.compute.internal node True ip-172-20-63-241.eu-central-1.compute.internal node True ip-172-20-71-25.eu-central-1.compute.internal master True ip-172-20-91-30.eu-central-1.compute.internal node True ip-172-20-93-220.eu-central-1.compute.internal node True Your cluster example.cluster.k8s.local is ready
$ kubectl get nodes NAME STATUS ROLES AGE VERSION ip-172-20-112-170.eu-central-1.compute.internal Ready master 7m v1.6.10 ip-172-20-117-204.eu-central-1.compute.internal Ready node 6m v1.6.10 ip-172-20-54-176.eu-central-1.compute.internal Ready master 7m v1.6.10 ip-172-20-55-115.eu-central-1.compute.internal Ready node 6m v1.6.10 ip-172-20-63-241.eu-central-1.compute.internal Ready node 6m v1.6.10 ip-172-20-71-25.eu-central-1.compute.internal Ready master 7m v1.6.10 ip-172-20-91-30.eu-central-1.compute.internal Ready node 6m v1.6.10 ip-172-20-93-220.eu-central-1.compute.internal Ready node 6m v1.6.10
クラスタ内の各ノードがバージョン1.6.10であることを示しています。
クラスタ構成の編集
1.6.10の既存のクラスタを1.7.4にアップグレードしましょう。クラスタ構成を編集します。
kops edit cluster example.cluster.k8s.local
これにより、クラスタ構成がテキストエディタで開きます。
kubernetesVersion
ターゲットバージョン(この場合は1.7.4)にキーを設定し、設定ファイルを保存します。
以前の値:
kubernetesVersion: 1.6.10
以下に変更されます:
kubernetesVersion: 1.7.4
変更を保存してエディタを終了します。Kubernetesクラスタは設定を再読み込みする必要があります。 これは、次のコマンドを使用して、クラスタのローリング・アップデートを強制することで実行できます。
このプロセスには30〜45分かかることがあります。その時間中に更新なしでクラスタを離れることをお勧めします。
$ kops update cluster example.cluster.k8s.local I1028 18:18:59.671912 10844 apply_cluster.go:420] Gossip DNS: skipping DNS validation I1028 18:18:59.699729 10844 executor.go:91] Tasks: 0 done / 81 total; 36 can run I1028 18:19:00.824806 10844 executor.go:91] Tasks: 36 done / 81 total; 15 can run I1028 18:19:01.601875 10844 executor.go:91] Tasks: 51 done / 81 total; 22 can run I1028 18:19:03.340103 10844 executor.go:91] Tasks: 73 done / 81 total; 5 can run I1028 18:19:04.153174 10844 executor.go:91] Tasks: 78 done / 81 total; 3 can run I1028 18:19:04.575327 10844 executor.go:91] Tasks: 81 done / 81 total; 0 can run Will modify resources: LaunchConfiguration/master-eu-central-1a.masters.cluster.k8s.local UserData ... cat > kube_env.yaml << __EOF_KUBE_ENV Assets: + - 7bf3fda43bb8d0a55622ca68dcbfaf3cc7f2dddc@https://storage.googleapis.com/kubernetes-release/release/v1.7.4/bin/linux/amd64/kubelet - - a9258e4d2c7d7ed48a7bf2e3c77a798fa51a6787@https://storage.googleapis.com/kubernetes-release/release/v1.6.10/bin/linux/amd64/kubelet + - 819010a7a028b165f5e6df37b1bb7713ff6d070f@https://storage.googleapis.com/kubernetes-release/release/v1.7.4/bin/linux/amd64/kubectl - - 0afe23fb48276ad8c6385430962cd237367b22f7@https://storage.googleapis.com/kubernetes-release/release/v1.6.10/bin/linux/amd64/kubectl - 1d9788b0f5420e1a219aad2cb8681823fc515e7c@https://storage.googleapis.com/kubernetes-release/network-plugins/cni-0799f5732f2a11b329d9e3d51b9c8f2e3759f2ff.tar.gz - c18ca557507c662e3a072c3475da9bd1bc8a503b@https://kubeupv2.s3.amazonaws.com/kops/1.7.1/linux/amd64/utils.tar.gz ... LaunchConfiguration/master-eu-central-1b.masters.cluster.k8s.local UserData ... cat > kube_env.yaml << __EOF_KUBE_ENV Assets: + - 7bf3fda43bb8d0a55622ca68dcbfaf3cc7f2dddc@https://storage.googleapis.com/kubernetes-release/release/v1.7.4/bin/linux/amd64/kubelet - - a9258e4d2c7d7ed48a7bf2e3c77a798fa51a6787@https://storage.googleapis.com/kubernetes-release/release/v1.6.10/bin/linux/amd64/kubelet + - 819010a7a028b165f5e6df37b1bb7713ff6d070f@https://storage.googleapis.com/kubernetes-release/release/v1.7.4/bin/linux/amd64/kubectl - - 0afe23fb48276ad8c6385430962cd237367b22f7@https://storage.googleapis.com/kubernetes-release/release/v1.6.10/bin/linux/amd64/kubectl - 1d9788b0f5420e1a219aad2cb8681823fc515e7c@https://storage.googleapis.com/kubernetes-release/network-plugins/cni-0799f5732f2a11b329d9e3d51b9c8f2e3759f2ff.tar.gz - c18ca557507c662e3a072c3475da9bd1bc8a503b@https://kubeupv2.s3.amazonaws.com/kops/1.7.1/linux/amd64/utils.tar.gz ... LaunchConfiguration/master-eu-central-1c.masters.cluster.k8s.local UserData ... cat > kube_env.yaml << __EOF_KUBE_ENV Assets: + - 7bf3fda43bb8d0a55622ca68dcbfaf3cc7f2dddc@https://storage.googleapis.com/kubernetes-release/release/v1.7.4/bin/linux/amd64/kubelet - - a9258e4d2c7d7ed48a7bf2e3c77a798fa51a6787@https://storage.googleapis.com/kubernetes-release/release/v1.6.10/bin/linux/amd64/kubelet + - 819010a7a028b165f5e6df37b1bb7713ff6d070f@https://storage.googleapis.com/kubernetes-release/release/v1.7.4/bin/linux/amd64/kubectl - - 0afe23fb48276ad8c6385430962cd237367b22f7@https://storage.googleapis.com/kubernetes-release/release/v1.6.10/bin/linux/amd64/kubectl - 1d9788b0f5420e1a219aad2cb8681823fc515e7c@https://storage.googleapis.com/kubernetes-release/network-plugins/cni-0799f5732f2a11b329d9e3d51b9c8f2e3759f2ff.tar.gz - c18ca557507c662e3a072c3475da9bd1bc8a503b@https://kubeupv2.s3.amazonaws.com/kops/1.7.1/linux/amd64/utils.tar.gz ... LaunchConfiguration/nodes.cluster.k8s.local UserData ... cat > kube_env.yaml << __EOF_KUBE_ENV Assets: + - 7bf3fda43bb8d0a55622ca68dcbfaf3cc7f2dddc@https://storage.googleapis.com/kubernetes-release/release/v1.7.4/bin/linux/amd64/kubelet - - a9258e4d2c7d7ed48a7bf2e3c77a798fa51a6787@https://storage.googleapis.com/kubernetes-release/release/v1.6.10/bin/linux/amd64/kubelet + - 819010a7a028b165f5e6df37b1bb7713ff6d070f@https://storage.googleapis.com/kubernetes-release/release/v1.7.4/bin/linux/amd64/kubectl - - 0afe23fb48276ad8c6385430962cd237367b22f7@https://storage.googleapis.com/kubernetes-release/release/v1.6.10/bin/linux/amd64/kubectl - 1d9788b0f5420e1a219aad2cb8681823fc515e7c@https://storage.googleapis.com/kubernetes-release/network-plugins/cni-0799f5732f2a11b329d9e3d51b9c8f2e3759f2ff.tar.gz - c18ca557507c662e3a072c3475da9bd1bc8a503b@https://kubeupv2.s3.amazonaws.com/kops/1.7.1/linux/amd64/utils.tar.gz ... LoadBalancer/api.cluster.k8s.local Lifecycle <nil> -> Sync LoadBalancerAttachment/api-master-eu-central-1a Lifecycle <nil> -> Sync LoadBalancerAttachment/api-master-eu-central-1b Lifecycle <nil> -> Sync LoadBalancerAttachment/api-master-eu-central-1c Lifecycle <nil> -> Sync Must specify --yes to apply changes
次のコマンドを使用して変更を適用します。
kops update cluster example.cluster.k8s.local --yes
出力します
$ kops update cluster example.cluster.k8s.local --yes I1028 18:22:53.558475 10876 apply_cluster.go:420] Gossip DNS: skipping DNS validation I1028 18:22:54.487232 10876 executor.go:91] Tasks: 0 done / 81 total; 36 can run I1028 18:22:55.750674 10876 executor.go:91] Tasks: 36 done / 81 total; 15 can run I1028 18:22:56.640322 10876 executor.go:91] Tasks: 51 done / 81 total; 22 can run I1028 18:22:59.756888 10876 executor.go:91] Tasks: 73 done / 81 total; 5 can run I1028 18:23:01.154703 10876 executor.go:91] Tasks: 78 done / 81 total; 3 can run I1028 18:23:01.890273 10876 executor.go:91] Tasks: 81 done / 81 total; 0 can run I1028 18:23:02.196422 10876 update_cluster.go:247] Exporting kubecfg for cluster kops has set your kubectl context to example.cluster.k8s.local Cluster changes have been applied to the cloud. Changes may require instances to restart: kops rolling-update cluster
クラスタのアップグレード
次のコマンドを使用して、いずれかのノードで再起動が必要かどうかを判断します。
kops rolling-update cluster example.cluster.k8s.local
このコマンドは、次のように出力します。
NAME STATUS NEEDUPDATE READY MIN MAX NODES master-eu-central-1a NeedsUpdate 1 0 1 1 1 master-eu-central-1b NeedsUpdate 1 0 1 1 1 master-eu-central-1c NeedsUpdate 1 0 1 1 1 nodes NeedsUpdate 5 0 5 5 5 Must specify --yes to rolling-update.
このSTATUS列には、マスターノードとワーカーノードの両方を更新する必要があることが示されています。 次のコマンドを使用してローリングアップデートを実行します。
kops rolling-update cluster example.cluster.k8s.local --yeskops rolling-update cluster example.cluster.k8s.loc
このコマンドの出力が表示されます。
NAME STATUS NEEDUPDATE READY MIN MAX NODES master-eu-central-1a NeedsUpdate 1 0 1 1 1 master-eu-central-1b NeedsUpdate 1 0 1 1 1 master-eu-central-1c NeedsUpdate 1 0 1 1 1 nodes NeedsUpdate 5 0 5 5 5 I1028 18:26:37.124152 10908 instancegroups.go:350] Stopping instance "i-0c729296553079aab", node "ip-172-20-54-176.eu-central-1.compute.internal", in AWS ASG "master-eu-central-1a.masters.cluster.k8s.local". I1028 18:31:37.439446 10908 instancegroups.go:350] Stopping instance "i-002976b15a2968b34", node "ip-172-20-71-25.eu-central-1.compute.internal", in AWS ASG "master-eu-central-1b.masters.cluster.k8s.local". I1028 18:36:38.700513 10908 instancegroups.go:350] Stopping instance "i-0d4bd1a9668fab3e1", node "ip-172-20-112-170.eu-central-1.compute.internal", in AWS ASG "master-eu-central-1c.masters.cluster.k8s.local". I1028 18:41:39.938149 10908 instancegroups.go:350] Stopping instance "i-0048aa89472a2c225", node "ip-172-20-93-220.eu-central-1.compute.internal", in AWS ASG "nodes.cluster.k8s.local". I1028 18:43:41.019527 10908 instancegroups.go:350] Stopping instance "i-03787fa7fa77b9348", node "ip-172-20-117-204.eu-central-1.compute.internal", in AWS ASG "nodes.cluster.k8s.local". I1028 19:14:50.288739 10908 instancegroups.go:350] Stopping instance "i-084c653bad3b17071", node "ip-172-20-55-115.eu-central-1.compute.internal", in AWS ASG "nodes.cluster.k8s.local". I1028 19:16:51.339991 10908 instancegroups.go:350] Stopping instance "i-08da4ee3253afa479", node "ip-172-20-63-241.eu-central-1.compute.internal", in AWS ASG "nodes.cluster.k8s.local". I1028 19:18:52.368412 10908 instancegroups.go:350] Stopping instance "i-0a7975621a65a1997", node "ip-172-20-91-30.eu-central-1.compute.internal", in AWS ASG "nodes.cluster.k8s.local". I1028 19:20:53.743998 10908 rollingupdate.go:174] Rolling update completed!
クラスタを再度検証します。
$ kops validate cluster Using cluster from kubectl context: example.cluster.k8s.local Validating cluster example.cluster.k8s.local INSTANCE GROUPS NAME ROLE MACHINETYPE MIN MAX SUBNETS master-eu-central-1a Master m3.medium 1 1 eu-central-1a master-eu-central-1b Master m3.medium 1 1 eu-central-1b master-eu-central-1c Master c4.large 1 1 eu-central-1c nodes Node t2.medium 5 5 eu-central-1a,eu-central-1b,eu-central-1c NODE STATUS NAME ROLE READY ip-172-20-101-20.eu-central-1.compute.internal master True ip-172-20-106-93.eu-central-1.compute.internal node True ip-172-20-109-10.eu-central-1.compute.internal node True ip-172-20-41-77.eu-central-1.compute.internal node True ip-172-20-44-33.eu-central-1.compute.internal master True ip-172-20-75-132.eu-central-1.compute.internal node True ip-172-20-85-128.eu-central-1.compute.internal master True ip-172-20-93-108.eu-central-1.compute.internal node True Your cluster example.cluster.k8s.local is ready
クラスタからノードのリストを取得
$ kubectl get nodes NAME STATUS ROLES AGE VERSION ip-172-20-101-20.eu-central-1.compute.internal Ready master 42m v1.7.4 ip-172-20-106-93.eu-central-1.compute.internal Ready node 36m v1.7.4 ip-172-20-109-10.eu-central-1.compute.internal Ready node 37m v1.7.4 ip-172-20-41-77.eu-central-1.compute.internal Ready node 3m v1.7.4 ip-172-20-44-33.eu-central-1.compute.internal Ready master 51m v1.7.4 ip-172-20-75-132.eu-central-1.compute.internal Ready node 5m v1.7.4 ip-172-20-85-128.eu-central-1.compute.internal Ready master 46m v1.7.4 ip-172-20-93-108.eu-central-1.compute.internal Ready node 44s v1.7.4
Blue/green Upgrade
Blue/green メソッドを使用してクラスターをアップグレードすることは、本質的にはより控えめであると考えられ、アプリケーションの高可用性を考慮します。 2つのk8sクラスタを設定します.1つは1.6.10バージョン、もう1つは1.7.2で、ポッドの展開とサービスは新しいクラスタに移行します。
シェルスクリプトでのリトライ処理とロック処理
サーバ運用で手動でApache再起動のような対応は辛いので アラートを検知したら自動でApache再起動を実施し、 メールで知らせてくれるスクリプトを書きたいと思い、 リトライ処理やロック処理をシェルスクリプトでどうやるか調べたのでまとめます。
リトライ処理
変数でリトライ回数とリトライ間隔を決めて whileループでカウントを1ずつ増やし、 sleepコマンドの引数にリトライ間隔の変数を与えることで リトライ処理を実装できた。
## リトライ処理 RETRY_COUNT=1 # リトライ回数 RETRY_INTERVAL=1 # リトライ間隔1秒 while [[ $COUNT -ne $RETRY_COUNT ]] do COUNT=`expr $COUNT + 1` sleep $RETRY_INTERVAL done
ロック処理
こちらの記事が参考になりました。https://heartbeats.jp/hbblog/2013/10/atomic03.html#more
シンボリックリンクを作成するときに、作成先にすでにファイルが存在するとエラーとなります。そのため、ロックファイルをシンボリックリンクとして作成を試みれば、ロックファイルが存在すればエラーが発生するため、ロックファイルが存在すると判断し処理を中断できます。ロックファイルが存在しなければ、ロックファイルがシンボリックリンクとして作成されます。「ロックファイルの確認」と「ロックファイルの作成」が同時に行われるため、安全にロックすることができるのです。普通のファイルとしてロックファイルを作成する方法での問題はシンボリックリンクの場合は起きません。
以下のようにシンボリックリンクを作成することでアトミックにロックファイルを作成することができます。
#!/bin/bash LOCK_FILE=$HOME/tmp/file.lock ## ロックファイルの確認と作成 if ! ln -s $$ $LOCK_FILE; then echo "LOCKED" exit 0
このようにロックファイルの確認と作成を別々に行うとアトミックなファイルの扱いにはならないので要注意です。
## ロックファイルの確認 if [ -f $LOCK_FILE ]; then echo "LOCKED" exit 1 fi
それでは実際にリトライ処理とロック処理を使ってシェルスクリプトを書いてみましょう。 Nagios監視でcheck_httpが何度か失敗し、check_loadでも失敗したら Apache再起動を実行し、1分間はApache再起動が実行されないスクリプトを書いてみます。 これをCronなどで3分毎に実行させればWEBサーバで応答に時間がかかっている時の障害対応を自動化できますね。 ロックファイルを設置して排他制御を行うことで、Apache再起動が何度も実行されないように実装ができます。
#!/bin/bash set -uo pipefail HOSTNAME=$(uname -n) MAIL_ADDRESS_TO="メールアドレス" LOCK_FILE="$HOME/restart.lock" RETRY_COUNT=5 # リトライ回数 RETRY_INTERVAL=5 # リトライ間隔5秒 COUNT=0 ## ロックファイルの確認 ## なければロックファイルの作成 if ! ln -s $$ $LOCK_FILE; then echo "LOCKED" exit 0 fi /usr/lib64/nagios/plugins/check_http -w 5 -c 7 -H localhost -u "/" -s "</html>" RETURN_HTTP=$? if [[ ${RETURN_HTTP} -ne 0 ]]; then ## check_httpの応答判断のリトライ処理 while [[ $COUNT -ne $RETRY_COUNT ]] do COUNT=`expr $COUNT + 1` sleep $RETRY_INTERVAL /usr/lib64/nagios/plugins/check_http -w 5 -c 7 -H localhost -u "/" -s "</html>" RETURN_HTTP=$? if [[ ${RETURN_HTTP} -eq 0 ]]; then exit 0 else continue fi done ## リトライ5回繰り返してもcheck_http監視がOKでないなら以下の再起動処理に進む if [[ ${RETURN_HTTP} -ne 0 ]]; then /usr/lib64/nagios/plugins/check_load -w 2,2,2 -c 3,3,3 RETURN_LOAD=$? if [[ ${RETURN_LOAD} -ne 0 ]]; then echo "/etc/init.d/httpd restart" RETURN=$? if [[ ${RETURN} -ne -0 ]]; then RESULT="Failed" else RESULT="Success" fi SUBJECT="${HOSTNAME} httpd restart ${RESULT}" BODY="${HOSTNAME} restart apache ${RESULT}" echo "${BODY}" | mail -s "${SUBJECT}" ${MAIL_ADDRESS_TO} ## 再起動後は1分スリープ後にロックファイルの削除 sleep 60 rm -f $LOCK_FILE fi fi fi
障害対応の自動化で他によいものがあれば教えて下さい。 また、今回のアトミックなファイルの取扱いの考え方は自分ひとりではなかなか気づかなかったです。
Linuxサーバをセキュアな環境にする
Linuxサーバでセキュアな設定についてまとめてみました。 OSはCentOS6なので古いですが。。 Wordpress周りはまだ調べられてないので どこかでまとめたい。
アドレススキャン対策
ブロードキャスト宛のICMP Echo Requestに対して回答しない
vim /etc/sysctl.conf net.ipv4.icmp_echo_ignore_broadcasts=1
OSやバージョンの確認
# yum -y install nmap # nmap -O example.com
telnet example.com 80
まずはこれぐらいはやっておきたいセキュアな設定
- OSはminimalで必要最小限でインストールする
- システム管理者用のユーザを作成して利用する
yum -y update
でパッケージを最新のものを利用する- 不要なサービスは停止する
- rootユーザのログインを禁止する
- コンソールからのrootログイン禁止
# echo > /etc/securetty
- SSHでのrootログイン禁止
# vim /etc/ssh/ssh_config #PermitRootLogin yes
↓
PermitRootLogin no
- SSHを受け付けるPort番号を変更する
# vim /etc/ssh/ssh_config Ports 20022
OSのセキュリティ
- GRUBのパスワード設定
grub-md5-crypt
を実行して出力内容を/boot/grub/grub.conf
に書くコム- title で始まる行よりも前に
password --md5 パスワード
の書式で記述する
- 一般ユーザのログイン管理
- 不要なユーザのロック
usermod -L hoge
- 不要なユーザのロック解除
usermod -U hoge
- シェルログインが不要なユーザの作成
useradd -s /sbin/nologon hoge
- hogeユーザのログインシェルを
/sbin/nologin
に設定usermod -s /sbin/nologin hoge
- 不要なユーザのロック
- コンソールからのrootログイン禁止
echo > /etc/securetty
- su コマンドを使えるユーザを制限
/etc/pam.d/su
ファイルをrootユーザで開き、 「auth required pam_wheel.so use_uid」という行を追加する- これでwheelグループに追加されたユーザのみがsuコマンドを利用できるようになる
usermod -G wheel hoge
でグループに所属させることが可能
- sudoコマンドの利用設定
visudo
を実行し/etc/sudoers
を開くhoge ALL=(ALL) ALL
ですべてのroot権限が必要なコマンドの実行を許可する
- Clam AntiVirusのインストール
メールサーバのセキュリティ
- ユーザログインの禁止
- メールサーバを利用するだけのユーザならログインする必要ないのでデフォルトシェルを無効にしておく
useradd -s /sbin/nologin newuser
main.cfの主な設定
- myhostname
- ホスト名をFQDNで指定
myhostname = windsor.example.com
- mydomain
- メールサーバのドメイン名を指定
mydomain = example.com
- myorigin
- メールアドレスの[@]以降が指定されなかった時、デフォルトで保管する値を指定する
myorigin = $mydomain
- inet_interfaces
- mydestination
- mynetworks
- 中継を許可するホストの存在する内部ネットワークアドレスを指定
- ここに指定したアドレスからのメールは無条件で中継される
mynetworks = 192.168.11.0/24, 127.0.0.1/8
- smtpd_banner
- SMTPの応答コードに続いて出力されるバナー情報を指定
- できるだけ情報は少ないほうがいいが、
$myhostname
は削除しないようにすること
- disabled_vrfy_command
- STMPのVRFYコマンドを禁止にする
- VRFYコマンドはメールサーバにどのようなアカウントがあるのかを知られる可能性がある
disable_vrfy_command = yes
- smtpd_helo_required
- smtpd_recipient_restrictions
- 通常は末尾にrejectを指定する
- smtpd_sender_restictions
- メールの送信元アドレスをチェックし、受信を拒否するかどうかを判断
設定の反映
service postfix reload
デフォルト値から変更されている項目のみを表示
postconf -n
FTPサーバのセキュリティ
CentOSではセキュアなvsftpdを使う
vsftpd.confの設定
- バナーの表示
- FTP接続確立時のバナーメッセージはftpd_bannerディレクティブで設定
ftpd_banner='FTP Login
- バナーメッセージを格納したファイルを指定するbanner_fileによって無視せれるので注意
- TCP Wrapperの利用有無
tcp_wraller=Yes
tcp_wraller=No
- ユーザリストファイル
userlist_file=/etc/vsftpd/user_list userlist_enable=YES userlist_deny=YES
- ホワイトリストの場合
userlist_file=/etc/vsftpd/user_list userlist_enable=YES userlist_deny=NO
/etc/vsftpd/user_list
にはFTP接続にかかわるユーザを登録。userlist_enable=NO
となっている場合/etc/vsftpd/user_list
内に指定されたユーザのみFTP許可されるが、/etc/vsftpd/ftpusers
にユーザ名が指定されている場合はFTPログインを禁止されてしまう- ファイルのアップロード
- FTPサーバをファイル配布用にするならアップロードは不要
write_enable=NO
でアップロードが禁止になる
- ユーザの設定
- ホームディレクトリ以外に移動できないように設定
chroot_local_user=YES #chroot_list_enable=YES # (default follows) chroot_list_file=/etc/vsftpd/chroot_list
- 一部のユーザにはホームディレクトリ以外に移動できないように設定
chroot_list_enable=YES
と設定して、chroot_list
にユーザを列挙する
chroot_local_user=YES chroot_list_enable=YES # (default follows) chroot_list_file=/etc/vsftpd/chroot_list
- ホームディレクトリ配下のFTPログイン用のサブディレクトリにログインするようにする
- 匿名FTPを許可の有無
- デフォルトでは有効になっている
anonymous_enable=YES
- 匿名FTPを使ってファイル配布したい場合は、匿名アカウントでのファイルアップロードを禁止しておく
anon_upload_enable=NO
write_enbale=NO
ならanon_upload_enable=YES
でもファイルのアップロードはできない
- FTPSを使う
- 証明書と秘密鍵をまとめてpemファイルを作る
cd /etc/pki/tls/certs cp mycerts.crt mycerts.pem cat mycerts.key >> mycerts.pem
- vsftpd.confに以下の行を追加
ssl_enable=YES #SSLの有効化 rsa_cert_file=/etc/pki/tls/certs/mycerts.pem #サーバ証明書秘密鍵のパス
force_local_logins_ssl=NO #FTPログイン時にSSL接続を強制しないように設定 force_local_date_ssl=NO #FTP転送時にSSL接続を強制しないように設定
- vsftpdのログ
- デフォルトでは
/var/log/xferlog
にファイル転送に関するログが記録される
- デフォルトでは
xferlog_enable=YES xferlog_std_format=YES
- ファイル転送のログに加えて、サーバへの接続に関するログも出力されるようにする
xferlog_std_format=NO vsftpd_log_file=/var/log/vsftpd.log
- syslogへ出力するようにもできる
syslog_enable=YES
安全なSSHサーバの設定
/etc/ssh/sshd_config
の設定
- Portの変更
Port 20022 #portの待受けを22番以外にする
- Protocolのバージョンを2にする
Protocol 2
- rootログインを許可しない
PermitRootLogin no
- パスワード認証を許可しない
PasswordAuthentication no
- ログイン認証認証の失敗を許容できる回数を変更
MaxAuthTries 3
pythonでしたいと思ったことまとめ①
print()でカンマ区切りで表示したい
print(a, b, c, sep=',')
行末の改行を削除したい
string.rstrip()
文字列の末尾部分を除去したコピーを返す。引数 chars は除去される文字集合を指定する文字列。
特定の文字を除去したい
文字列.replace() メソッドを利用します。
以下で改行を除去できる。
remove_enter = jugemu.replace('\n', '')
csvファイルなどのカンマで文字列を分割したい
string.strip(',')
ファイルの中身に追記していきたい
a
を使う、 w
だと上書きしてしまう。
with open('output/hoge.log', 'a', encoding='utf-8') as f:
現在の時刻を取得する
datetimeモジュールを使う
from datetime import datetime now = datetime.now()
日時.yearで日時の年の値を数値として取得できる。
print(str(now.year) + '年')
日時.monthで日時の月の値を数値として取得できる。
print(str(now.month) + '月')
日時.dayで日時の日の値を数値として取得できる。
print(str(now.day) + '日')
日時.hourで日時の時の値を数値として取得できる。
print(str(now.hour) + '時')
日時.minuteで日時の分の値を数値として取得できる。
print(str(now.minute) + '分')
日時.secondで日時の秒の値を数値として取得できる。
print(str(now.second) + '秒')
日時のオブジェクトを作成したい
datetime(年, 月, 日, 時, 分, 秒)と指定可能で時分秒を省略すると00:00:00になる。
one_day = datetime(2016, 1, 31, 10, 20, 30)
日時を文字列に変換したい
print(now.strftime('%Y/%m/%d')) # -> 2016/01/10 print(now.strftime('%Y-%m-%d')) # -> 2016-01-10 print(now.strftime('%Y年%m月%d日')) # -> 2016年01月10日
strftime
(フォーマット)を利用して変換できる
- %Y: 西暦(4桁)の10進表記を表します。
- %m: 0埋めした10進数で表記した月。
- %d: 0埋めした10進数で表記した月中の日にち。
- %H: 0埋めした10進数で表記した時 (24時間表記)。
- %M: 0埋めした10進数で表記した分。
- %S: 0埋めした10進数で表記した秒。
文字列を日付にしたい
strptime
を使う。
from datetime import datetime day_str = '2018/3/14 12:30:00' dt = datetime.strptime(day_str, '%Y/%m/%d %H:%M:%S') # 第二引数には変換したい文字列に一致したフォーマットを渡す print(dt) # 2018-03-14 12:30:00
X日前(後)の日付を表示したい
timedelta
を使う
from datetime import datetime from datetime import timedelta olympic_day = datetime(2020, 7, 24) before_3days = now - timedelta(days=3) # 3日前 after_3days = now + timedelta(days=3) # 3日後
Pathを結合したい
os.path.join(a, b, ...)
で指定可能
Pathが存在するか確認したい
os.path.exists(path)
で指定したpathが存在するか確認できる。
指定したpathがファイルかディレクトリか確認したい
ファイルなら
os.path.isfile(path)
ディレクトリなら
os.path.isdir(path)
指定されたディレクトリー内のファイル名と子ディレクトリー名をリストで返したい
os.walk(top)
で返せる。
for文に引数root, dirs, filesを指定すると、そこに各ディレクトリーごとのデータが代入されていく。
import os def directory_tree(target_path): for root, dirs, files in os.walk(target_path) : print(root) for dir in dirs: print('\t', dir) for file in files: print('\t', file)