Foreverly

メモ帳

unshareコマンドでLinuxのNamespaceに入門

Namespaceはコンテナで使われている技術の一つで、コンテナを理解深めるために知っておくとよいので調べてみた。 どんな使われ方をしているかというと、 例えばPID namespaceはPIDの number spaceを隔離する。 これは同じホスト上で実行されている2つのプロセスが同じPIDを持つことができるということになる。

namespaceがなくて隔離されてないとコンテナAがコンテナB、C、Dなどに filesystemのunmountやホスト名の変更、NWインターフェースの削除など できたりしてしまうので、必ず他のコンテナのプロセスがみれないようにする。

Namespace

Kernel/OSのリソースで、物理リソースは制限しない(cgroupsでする)が、 以下の項目についてNamespaceを分離する。 namespaceを分離した環境では、許可されたリソースしか見えなくなるので コンテナ内の要素だけ見えるように制限できる。

  • Mount Namespace(ファイルシステムのマウントポイントを分離: Namespace 内の mount / umount が他の Namespace に影響を与えないようにする)
  • UTS Namespace(ホスト名,ドメイン名の分離)
  • PID Namespace(PID 空間の分離、新しい PID Namespace では PID 1 から始まる)
  • IPC Namespace(セマフォ、MQ、共有メモリなどのプロセス間通信の分離)
  • User Namespace(UID、GID Namespaceの分離)
  • Network Namespace(インターフェース、ルーティングテーブル、ソケットなど)
  • cgroup Namespace(cgroupのルートディレクトリを分離)

cgroups

cpuやmemory、ディスクなどの物理リソース制限は cgroupsと呼ばれるカーネル機能で計測されアクセス制限される。 cgroupsではタスクをグループ化したり、そのグループ内のタスクに対して 以下のような物理リソースを制限できる。使用量やアクセスを制限する。

  • CPU
  • メモリ
  • ブロックデバイス(mmap可能なストレージとほぼ同義)
  • ネットワーク
  • /dev以下のデバイスファイル

unshareコマンドでNamespaceについて確認

unshare コマンドはparentから unshared されている namespaceを使用してプログラムを実行できるらしい。 unshare が新しいnamespace でどんなプログラムでも走らせることができるということ。実際にUTS Namespaceを例に unshareコマンドの動きを確認してみる。

    $ unshare -h
    
    Usage:
     unshare [options] <program> [<argument>...]
    
    Run a program with some namespaces unshared from the parent.
    
    オプション:
     -m, --mount               unshare mounts namespace
     -u, --uts                 unshare UTS namespace (hostname etc)
     -i, --ipc                 unshare System V IPC namespace
     -n, --net                 unshare network namespace
     -p, --pid                 unshare pid namespace
     -U, --user                unshare user namespace
     -f, --fork                fork before launching <program>
         --mount-proc[=<dir>]  mount proc filesystem first (implies --mount)
     -r, --map-root-user       map current user to root (implies --user)
         --propagation <slave|shared|private|unchanged>
                               modify mount propagation in mount namespace
     -s, --setgroups allow|deny  control the setgroups syscall in user namespaces
    
     -h, --help     display this help and exit
     -V, --version  output version information and exit
    
    For more details see unshare(1).

UTS Namespaceは名前空間ごとにホスト名やドメイン名を独自に持つことができる。 以下で UTS Namespace を unshare コマンドで操作してみる。

unshare -u /bin/shUTS名前空間を指定してunshare実行している これでホスト名、ドメイン名が分離されたので、 もとのホスト名は test-ozawa-dev01.amb-infra-dev.incvb.io だが、 unshare で切り替え後、 my-new-hostname に変更している。

もちろんこのホスト名は新たな namespace だけで有効なので、 unshareで起動したシェルを終了すると、ホスト名はもとに戻る。

    $ sudo su       # root userになる
    # uname -n   # 現在のhostnameを確認
    test01
    # unshare -u /bin/sh  # 新しいUTS namespaceでshellを作成
    sh-4.2# hostname my-new-hostname                 # hostnameを設定
    sh-4.2# uname -n                                 # 新しいhostnameを確認
    my-new-hostname
    sh-4.2# exit                        # 新しいUTS namespaceから出る
    exit
    # uname -n   # 元のhostnameが変更されていないことを確認
    test01

2018年読んだ本

2018年の読書メーター
読んだ本の数:15
読んだページ数:4818
ナイス数:70

アシュリーの戦争 -米軍特殊部隊を最前線で支えた、知られざる「女性部隊」の記録アシュリーの戦争 -米軍特殊部隊を最前線で支えた、知られざる「女性部隊」の記録感想
15時間ほどで読めた。CST(文化支援部隊)という女性メンバーだけの特殊部隊を追ったノンフィクション。CSTの役割はアフガニスタンでの戦闘でアフガニスタン人の女性や子供たちから情報を聞き出すことが彼女たちの任務で地上戦の最前線でレンジャーの任務を支えていました。主人公のアシュリーが英雄視されているようで、プロパガンダ的作品と感じとってしまいました。2016年にアメリカの女性兵士も地上戦闘に参加することが法的に認められたのも、このCSTがあってのことのようで米軍にとっても大きな影響を与えた部隊だと思います。
読了日:12月30日 著者:ゲイル・スマク・レモン
シベリアの掟シベリアの掟感想
15時間ほどで読めた。かなりの力作だけど面白かった。筆者の幼少期の自伝的小説。これはntddkさんが面白いとツイートしていたので読んだ。この本については多くは語るのは不要だと思いますので、この本についての感想は本の中で語られているシベリアの掟の引用で締めくくる。『私たちシベリアの民は、子供の頃から「言葉にフィルターをかける」、すなわちたとえ故意でなくとも決して過ちを犯さないよう、口から出る言葉に気をつけることを教えられてきた。シベリアの掟によれば、「一度口から飛び去った言葉は二度と戻ってこない」からだ。』
読了日:12月30日 著者:ニコライ・リリン
五色の虹 満州建国大学卒業生たちの戦後五色の虹 満州建国大学卒業生たちの戦後感想
8時間ほどで読めた。日本が満州国を建国した時の理念である五族協和満州国を引っ張っていくリーダーを育成するための学校である満州建国大学についての話。日・漢・朝・満・蒙から集められた超エリートの卒業生たちを取材することで少ない資料の中、どんな学校だったのか、どんなことを考えて授業を受けたのか、戦後どうなったのか話をきいて浮き彫りになっていく建国大学。日本の敗戦とともにエリートだった学生たちが不遇の待遇を受けていたりと、国がその優秀な人材を生かさず中には忙殺する亡国もあったりと、貴重な歴史的資料のような一冊。
読了日:12月30日 著者:三浦 英之
悪童日記 (ハヤカワepi文庫)悪童日記 (ハヤカワepi文庫)感想
5時間ほどで読めた。薄い小説だけどrebuild.fmで紹介されていたように凄まじい本。打ちのめされるような本。双子の男の子の日記の体でストーリーが進んでいきます。男の子たちの行動原理みたいなものが読み取れてるので、その行動が加速するにつれてページを捲るスピードも上がっていきました。全部で第3部らしいのですが、素晴らしい作品のようですのでほかも読んでみたいです。子供だから視点は狭いようで、大人とは別の視点を持ち戦争下の描写が書かれています。筆者の幼少期の体験を双子の男の子を通して追体験するような感覚です。
読了日:12月30日 著者:アゴタ クリストフ
UNIXという考え方―その設計思想と哲学UNIXという考え方―その設計思想と哲学感想
20時間ぐらいで読めたと思う。途中何年も積んだりしたので、正確な時間がわかないけど、薄いけど一気に読めるような文章ではないので読むのが大変だった。名著ということでとりあえず読んでみたのが良くないのか、あんまり理解できなかった。これだけみんな名著と思って読まれているのにUNIXという考え方で実装していないのは何故だと思うぐらい複雑だったり謎の処理つけたりしているので気をつけたいですね。Linuxコマンドは強力でそれを使うスクリプトも強力ですね。こんな内容の現代の本が読みたいのでオススメあったら教えて下さい。
読了日:11月30日 著者:Mike Gancarz
スラスラ読める JavaScript ふりがなプログラミング (ふりがなプログラミングシリーズ)スラスラ読める JavaScript ふりがなプログラミング (ふりがなプログラミングシリーズ)感想
6時間ほどで読めた。タイトルの通りスラスラ読めました。ES6でJavaScriptを説明していますので、これからJavaScriptを勉強したい人や、プログラミングを覚えたい人が読む最初の一冊には良いと思いました。ふりがなが全てに振ってあるので、これがどんな意味なのかを、おまじないなどでごまかしていないので納得して読み進めることができると思います。監修も及川卓也さんなので内容も安心して読むことができました。次のステップはどう進めていけばいいのかは書いてないので、どうステップを進めるかが難しいと思いました。
読了日:08月20日 著者:リブロワークス
Linuxサーバーセキュリティ徹底入門 オープンソースによるサーバー防衛の基本Linuxサーバーセキュリティ徹底入門 オープンソースによるサーバー防衛の基本感想
8時間ほどで読めました。CentOS6で内容は少し古いですが、現在動いているシステムを運用している人は読んでおくとよいと思いました。LinuxのOS全般とApacheやメールなどの設定でセキュアな設定について細かく書かれており、わかりやすく書かれています。どのような運用が望ましいのかなども自分で調べるには難しいですが、このような本が増えてほしいと思いました。MySQLなどのDBやPHPなどについては記載ありませんが、それらはどのような本を読めばいいかなどの動線があればよいなと思います。おすすめの一冊です。
読了日:08月16日 著者:中島 能和
インフラエンジニアの教科書2 スキルアップに効く技術と知識インフラエンジニアの教科書2 スキルアップに効く技術と知識感想
10時間ほどで読めた。インフラエンジニア教科書とのことなのでインフラエンジニアとして読んでみた。1は立ち読みしたことありますが、個人的には2の方が読んでいて面白かったです。オペレーションシステムの基礎知識をわりと実用的なレベルで紹介されていて、インフラエンジニアになった人のまさに教科書的な存在だと思います。個人的にはなるほどUnixなどで、手で動かしてから読んでから読んだ方が理解が深まると思います。OSの動作の理屈をいきなり本を読んで理解できる人は頭がいいと思うので、普通の人は手を動かすといいと思います。
読了日:07月31日 著者:佐野 裕
絵で見てわかるOS/ストレージ/ネットワーク~データベースはこう使っている (DB Magazine Selection)絵で見てわかるOS/ストレージ/ネットワーク~データベースはこう使っている (DB Magazine Selection)感想
読むのに30時間ぐらいかかったと思う。新人の時(6年前)から何度も途中で諦めたりした本。OSやストレージ、DBMS、ネットーワークとシステム周り全般のボトルネックがどこか、リソースをどう使っているのかなどをコマンド実行レイヤ、絵を通して詳細に解説してくれている。個人的には詳解システムパフォーマンスの前に読んでおくと良いのではないかと思った。内容はオンプレミスのシステム前提で少し古いので、今のクラウド時代での内容に即した内容ではどうなるか気になるし、どんな本がそれにあたるのか気になる。このような本読みたい。
読了日:07月31日 著者:小田 圭二
オブジェクト指向でなぜつくるのか 第2版オブジェクト指向でなぜつくるのか 第2版感想
15時間ほどで読めた。Pythonでクラスをどういう時に書くべきなのか、オブジェクト指向でプログラミングするとはどういうことなのかよくわかっていないのでオブジェクト指向とは何なのかじっくり調べたいと思って読みました。この本は1冊まるまる書いているので説明が豊富でわかりやすかったです。Pythonの入門本とかだと犬とか人間とかを例にしたりして解説するのが余計に混乱させられていたのでオブジェクト指向の歴史と意義やクラス(カプセル化)・継承・ポリモーフィズムがどう意味なのかわかりやすく説明してありよかったです。
読了日:07月31日 著者:平澤 章
アカマイ―知られざるインターネットの巨人 (角川EPUB選書)アカマイ―知られざるインターネットの巨人 (角川EPUB選書)感想
6時間ほどで読めた。インターネットのトラフィックがどう流れているのか、CDNのアカマイがどういう成り立ちでできたのか。どのようにサービスを成り立たせているのか、どのような仕組みなのかなどをわかりやすく説明されているので読んでいて楽しかったです。CDNを利用すればオリジンサーバへの負荷分散にもなり、ユーザも高速にアクセスができ本当に良いものです。ネットワークの基本のようなものと併せて本書を読むことでインターネットの大枠を掴むことができるのではないでしょうか。誰にでも読むことができるので、オススメの一冊です。
読了日:06月21日 著者:小川 晃通
MySQL徹底入門 第3版 ~5.5新機能対応~MySQL徹底入門 第3版 ~5.5新機能対応~感想
10時間ほどで読めた。4年ほど積んでいましたが、そろそろMySQLに入門したい気持ちになり読みました。内容としては設定から運用までわかりやすくまとめっていて良いと思います。内容も5.5なのでそこまで古くはないので今読んでも参考になりました。昨今MySQL8がリリースされましたが、ほとんどの運用されているMySQLのバージョンはおいくつでしょうか?そうですね。おわかりのように、この本の内容は古くはないのです。次は実践ハイパフォーマンスMySQLをよんでMySQLの内部にもう少し踏み込んでいきたいと思います。
読了日:05月30日 著者:遠藤 俊裕,坂井 恵,館山 聖司,鶴長 鎮一,とみた まさひろ,班石 悦夫,松信 嘉範
忘れられた巨人忘れられた巨人感想
40時間ぐらいかけて読んだ。カズオ・イシグロは初めて読みます。牧歌的なファンタジー小説という印象で、THE・ビッグオーのような世界観です。記憶を奪う霧のせいで過去が曖昧な老夫婦がある日息子の存在を思い出して、どこに住んでいるかも顔も思い出せない息子に会いに行こうと行くあてのない旅を初めます。舞台はイングランドで時代はアーサー王伝説なので、この物語には騎士王伝説の知識があるとより楽しめるのかもしれません。読んでいて、ついさっきの記憶も危うい人達の会話を延々と読むことになるので、かなりの混乱が起こりました。
読了日:05月02日 著者:カズオ イシグロ
データ分析基盤構築入門[Fluentd、Elasticsearch、Kibanaによるログ収集と可視化]データ分析基盤構築入門[Fluentd、Elasticsearch、Kibanaによるログ収集と可視化]感想
8時間ほどで読めた。EFKで可視化したい人向けの本。 td-agentとElasticStackはバージョンが上がってしまったので、この本の内容は古いが、十分参考になる内容です。Qiitaぐらいしか日本語での情報がないEFKの可視化について上手くまとまっています。また、運用Tipsについても詳しく書かれていますので、運用や監視の勘所やチューニングの勘所についても参考になります。これからEFKで可視化をしたいと思っている人にはお勧めの一冊です。データ分析基盤の本で代表的な一冊になると思います。おすすめです。
読了日:04月22日 著者:鈴木 健太,吉田 健太郎,大谷 純,道井 俊介
Amazon Web Services 基礎からのネットワーク&サーバー構築 改訂版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つの値があります。

  1. Recreate
  2. 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
  1. deploymentを作成
$ kubectl create -f templates/app-recreate.yaml --record
deployment "app-recreate" created

--recordこのdeploymentを開始するコマンドが確実に記録されます。 これは、アプリケーションがいくつかの更新を経て、バージョンとコマンドを関連付ける必要がある場合に便利です。

  1. deploymentsの履歴を取得
$ kubectl rollout history deployment/app-recreate
deployments "app-recreate"
REVISION  CHANGE-CAUSE
1         kubectl create --filename=templates/app-recreate.yaml --record=true
  1. サービスを公開する
$ kubectl expose deployment/app-recreate --port=80 --target-port=8080 --name=app-recreate --type=LoadBalancer
service "app-recreate" exposed
  1. サービスの詳細を取得する
$ 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
  1. serviceにアクセス
$ curl http://af2dc1f99bda211e791f402037f18a54-1616925381.eu-central-1.elb.amazonaws.com
Hello World!
  1. 別の端末では、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
  1. deploymentのイメージを更新します。
$ kubectl set image deployment/app-recreate app-recreate=arungupta/app-upgrade:v2
deployment "app-recreate" image updated
  1. 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が作成されたことを示します。

  1. 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
  1. 再度アプリケーションにアクセスする
$ curl http://af2dc1f99bda211e791f402037f18a54-1616925381.eu-central-1.elb.amazonaws.com
Howdy World!

出力にv2は、使用されているイメージのバージョンが表示されるようになりました。

Rolling update戦略

Podはローリングアップデートの方法で更新されます。 Rolling updateの実行方法を定義するには、次の2つのオプションのプロパティを使用できます。

  1. .spec.strategy.rollingUpdate.maxSurge 必要な数のポッドに作成できるポッドの最大数を指定します。値には、絶対数またはパーセンテージを使用できます。デフォルト値は25%です。
  2. .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つのポッドしか利用できなくなります。

  1. deploymentを作成
$ kubectl create -f templates/app-rolling.yaml --record
deployment "app-rolling" created

再度、--recordこの展開を開始するコマンドが確実に記録されます。 これは、アプリケーションがいくつかの更新を経て、バージョンとコマンドを関連付ける必要がある場合に便利です。

  1. デプロイの履歴を取得する
$ kubectl rollout history deployment/app-rolling
deployments "app-rolling"
REVISION  CHANGE-CAUSE
1         kubectl create --filename=templates/app-rolling.yaml --record=true
  1. サービスを公開する
$ kubectl expose deployment/app-rolling --port=80 --target-port=8080 --name=app-rolling --type=LoadBalancer
service "app-rolling" exposed
  1. サービスの詳細を取得する
$ 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
  1. サービスへアクセス
$ curl http://abe27b4c7bdaa11e791f402037f18a54-647142678.eu-central-1.elb.amazonaws.com
Hello World!

出力はv1、イメージのバージョンが使用されていることを示します。

  1. 別の端末では、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
  1. deploymentのイメージを更新します。
$ kubectl set image deployment/app-rolling app-rolling=arungupta/app-upgrade:v2
deployment "app-rolling" image updated
  1. 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が作成されたことを示します。

  1. デプロイの履歴を取得する
$ 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
  1. アプリケーションに再度アクセスする
$ 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でこれを達成するにはいくつかの方法があります。

  1. Service、DeploymentおよびLabelの使用
  2. 入力コントローラの使用
  3. DNSコントローラの使用
  4. 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: appversion: 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を作成

  1. Deploymentのv1バージョンをデプロイする
$ kubectl apply -f templates/app-v1.yaml
deployment "app-v1" created
  1. 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
  1. このサービスの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つのデプロイメントを使用して個別に拡張できます。

  1. v2 deployment のレプリカ数を増やす
$ kubectl scale deploy/app-v2 --replicas=4
deployment "app-v2" scaled
  1. サービスの一部であるポッドを確認してください
$ 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が新しいアプリケーションから提供されるようになります。

  1. v1バージョンのレプリカ数を0に減らす
$ kubectl scale deploy/app-v1 --replicas=0
deployment "app-v1" scaled
  1. サービスの一部である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 AWSKubernetesIngressコントローラ

$ 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つのサービスを使用

  1. webapp :Webアプリケーションのマイクロサービスは greetername のマイクロサービスを使用して人のために挨拶を生成します。
  2. greeter :マイクロサービスは greet 、URLの名前/値のキーペアに基づいて挨拶を返します。
  3. nameid URLの名前/値のキーペアに基づいて人の名前を返すマイクロサービス。

これらのサービスは、Dockerイメージとして構築され、Kubernetesに配備されています。すべてのサービスはNode.jsアプリケーションとしてビルドされています。 サービスのソースコードhttps://github.com/arun-gupta/container-service-discovery/tree/master/services にあります。

これらの webapp サービスは namegreeter サービスと通信するに、以下の環境変数でサービスを構成する必要があります。 NAME_SERVICE_HOSTGREETER_SERVICE_HOST環境変数は、そのラベルではなく、ポッドまたはホストのIPアドレスなどの静的参照することによって、これらのサービスを参照してください。 その利点は 存在している name および/または greeter ポッドがもはや操作可能でなくなった場合、それが依存するサービスを継続して実行するために十分なリソースがクラスタにある場合、 webapp サービスは機能し続けます。

  1. NAME_SERVICE_HOST
  2. NAME_SERVICE_PORT
  3. NAME_SERVICE_PATH
  4. GREETER_SERVICE_HOST
  5. GREETER_SERVICE_PORT
  6. 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

アプリケーションのデプロイ

  1. アプリケーションをデプロイする

    $ 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

  2. サービスのリストを取得

$ 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
  1. サービスの詳細情報を取得
$ 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

ロードバランサーがリクエストを受け入れるまで3分ほど待つ

アプリケーションへアクセス

ブラウザや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 でパッケージを最新のものを利用する
  • 不要なサービスは停止する
    • audit(コマンドの監査をしない場合)
    • ip6tables(IPv6を使用しない場合)
    • netfs(NFSクライアントを使用しない場合)
    • postfix(SMTPサーバを使用しない場合)
  • 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
  • SSHサーバを再起動して設定を反映させる
  • ポートやファイアウォールの設定を確認する
    • netstat -atnp iptables -Ln

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のインストール
    • yum install clamav
    • freshclam でウィルスデータベースのアップデート
    • ウィルススキャンはスキャンしたいディレクトリに移動し、clamscanコマンドを実行
    • cd /home して clamscan -r再帰的にディレクトリをスキャンする
    • スキャンしかしないので clamscan --remove で実行時にウィルスの自動削除もしてくれる

メールサーバのセキュリティ

  • ユーザログインの禁止
    • メールサーバを利用するだけのユーザならログインする必要ないのでデフォルトシェルを無効にしておく
    • useradd -s /sbin/nologin newuser

main.cfの主な設定

  • myhostname
    • ホスト名をFQDNで指定
    • myhostname = windsor.example.com
  • mydomain
    • メールサーバのドメイン名を指定
    • mydomain = example.com
  • myorigin
    • メールアドレスの[@]以降が指定されなかった時、デフォルトで保管する値を指定する
    • myorigin = $mydomain
  • inet_interfaces
  • mydestination
    • ローカル配送を行うドメイン名、つまりメールを受け取るドメイン名を指定
    • mydestination = $myhostname, localhost.$mydomain, localhost
  • 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
    • SMTP開始時のHELO/EHLOコマンドを必須とするかどうかを指定
    • yesとするとスパムメールの抑制となる
    • smtpd_helo_required = yes
  • 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 でアップロードが禁止になる
  • ユーザの設定
    • Linuxユーザのログインを許可するには local_enable=YES と設定するとLinuxシステムのユーザ名とパスワードを使ってFTPログインが可能になる
  • ホームディレクトリ以外に移動できないように設定
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 #サーバ証明書秘密鍵のパス
  • 通常のFTP接続も許可するなら以下の設定もする
  • SSL非対応のFTPクライアントからの利用も想定するときは必要
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