月: 2019年7月

  • パフォーマンス・マネジメント -問題解決のための行動分析学- を読んだ

    パフォーマンス・マネジメント -問題解決のための行動分析学- を読んだ

    はじめに

    自分以外の人のモチベーションを維持・向上させ、マネジメントをしていく上で必要な本を探していた、先輩から紹介されたので即購入した。

    多くの物事は複雑に絡み合っている事が多いが、パフォーマンス・マネジメントを読んだ後は比較的シンプルに切り分ける癖がついた。

    今回はパフォーマンス・マネジメントについてまとめる。

    現状の確認

    仕事や人間関係がうまくいかない時には、他人や自分を責めるのではなく、問題を解決する方法を考える。

    仕事や人間関係がうまくいかない時、その原因を他人や自分の性格や能力、やる気や適性のせいにしてアクションを取らないことを、個人攻撃の罠と捉えている。

    個人攻撃に入った人は近づきづらく、負のスパイラルに陥る。

    個人攻撃に陥らない為には、一切の感情が入らないらないよう、チェックリストを予め作成し、それに基づいて「できているところ」、「できないところ」を整理する。

    強化の原理

    個人やチームが強くなる原理

    行動する事で、何か良い事が起こったり、悪い事がなくなったりすると、その行動は繰り返される。

    強化の原理が働くときは、

    〜〜の時〜〜したら〜〜になった

    という関係が成立している、

    〜〜の時  Antecedent:先行刺激
    〜〜したら … Behavior:行動
    〜〜になった … Consequence:結果

    と捉え、このことを行動随伴性(こうどうずいはんせい)と呼び、その頭文字からABC分析などと呼ばれる。

    これはちゃんとした医療用語で、心理カウンセラーがメンタルヘルスの一環で使う言葉のようだ。参考情報 http://www.counselorweb.jp/article/441261060.html

     

    改善点はその3つに分ける事ができる。

    Antecedent:先行刺激の改善

    例えば、他の人へ与えたタスクが、期待しているものと違っていた場合、

    その人が動く上での前提条件、Antecedent:先行刺激が足りない可能性がある。

    この際、「では自分が悪かったのか」と個人攻撃の罠にハマる危険もある。おそらくそれがひどければ鬱を誘発する。

    そのため、悪いところを探すのではなく、何か役に立つところを積極的に見つける。

     

    Behavior:行動

    作業者の「引き出し」が少なく、問題解決する上での数ある選択肢の中で、不適切な選択をするのであれば、この項目を改善するように考える。

    この点を改善するには、「引き出し」を増やすようトレーニングをする必要がある。

    Consequence:結果

    やる気の無さが直結する事が多い。

     

    行動を強化する、”何か良い事”を「好子(こうし)」と呼ぶ。これを一種のご褒美として使い、チームの強化などに使う。

    弱化の原理

    行動する事で、何か悪い事が起こったり、よくない事がなくなったりすると、その行動は繰り返されなくなる。.

    一方でチームが”悪くなる要素”を「嫌子(けんし)」と呼ぶ。これは望ましい行動を伸ばすという点からは欠点が多い。人間関係にも悪影響を与える可能性もある。

     

     

  • dockerをECSで動かした時のdebug方法について

    dockerをECSで動かした時のdebug方法について

    はじめに

    dockerコンテナを動かしていると、何らかの原因で起動シェルが止まってしまうことがある。今回はその調査方法の一つ、ECS用にAWSからオフィシャルのログ収集ツール ECSログコレクター が提供されているので、今回はそれを紹介。

    インストール方法

    AWS公式サイトにある通り、ツールを取得する

    $ curl -O https://raw.githubusercontent.com/awslabs/ecs-logs-collector/master/ecs-logs-collector.sh

    その後、sudoをつけてシェルを実行する

    $ sudo bash ./ecs-logs-collector.sh

    しばらくすると、諸々ログが取れる

    $ sudo bash ./ecs-logs-collector.sh
    Trying to check if the script is running as root ... ok
    Trying to resolve instance-id ... ok
    Trying to collect system information ... ok
    Trying to check disk space usage ... ok
    Trying to collect common operating system logs ... ok
    Trying to collect kernel logs ... ok
    Trying to get mount points and volume information ... ok
    Trying to check SELinux status ... ok
    Trying to get iptables list ... ok
    Trying to detect installed packages ... ok
    Trying to detect active system services list ... ok
    Trying to gather Docker daemon information ... ok
    Trying to inspect all Docker containers ... ok
    Trying to collect Docker daemon logs ... ok
    Trying to collect Amazon ECS Container Agent logs ... ok
    Trying to collect Amazon ECS Container Agent state and config ... ok
    Trying to collect Amazon ECS Container Agent engine data ... ok
    Trying to archive gathered log information ... ok

    無事完了すると、correctというディレクトリが作られ、ログが集約される。

    $ ls -ltr
    合計 236
    -rw-rw-r-- 1 ec2-user ec2-user  14181  7月 19 14:25 ecs-logs-collector.sh
    drwxr-xr-x 3 root     root       4096  7月 19 14:25 collect
    -rw-r--r-- 1 root     root     219653  7月 19 14:26 collect-i-0051ca9951de8e82a.tgz

    dockerの状態を確認するには、correct、インスタンスid、配下のdockerディレクトリにログとして出力される。

    /collect/i-xxxxxxxxx/docker

    ざっと見てみると、

    [
        {
            "Id": "xxxxxxx",
            "Created": "2019-07-19T12:36:48.665852002Z",
            "Path": "sh",
            "Args": [
                "/root/bin/execute.sh"
            ],
            "State": {
                "Status": "exited",
                "Running": false,
                "Paused": false,
                "Restarting": false,
                "OOMKilled": true,
                "Dead": false,
                "Pid": 0,
                "ExitCode": 137,
                "Error": "",
                "StartedAt": "2019-07-19T12:36:49.47823385Z",
                "FinishedAt": "2019-07-19T13:12:07.097787961Z"
            },

    終了したときの状態がわかる。

    OOMKilledがtrueになっており、このコンテナはメモリを使い果たし、OOMKillerが発動、コンテナがkillされたのではと推測が立つ。

    linuxのimageをbaseに使っていると、当然メモリーを使い切った際にはOOM killerなどは発生する。その際の原因調査をする上では、サーバレスのfargateよりは、まだホストにログインできるECSの方が原因調査はやりやすい。

    それ以外にも非常に細かい状態を確認することができる。

                "DnsOptions": null,
                "DnsSearch": null,
                "ExtraHosts": null,
                "GroupAdd": null,
                "IpcMode": "shareable",
                "Cgroup": "",
                "Links": null,
                "OomScoreAdj": 0,
                "PidMode": "",
                "Privileged": false,
                "PublishAllPorts": false,
                "ReadonlyRootfs": false,
                "SecurityOpt": null,
                "UTSMode": "",
                "UsernsMode": "",
                "ShmSize": 67108864,
                "Runtime": "runc",
                "ConsoleSize": [
                    0,
                    0
                ],
                "Isolation": "",
                "CpuShares": 2,
                "Memory": 2147483648,
                "NanoCpus": 0,
                "CgroupParent": "/ecs/ad627055-dc5b-4903-96ed-be9e0f25cf33",
                "BlkioWeight": 0,
                "BlkioWeightDevice": null,
                "BlkioDeviceReadBps": null,
                "BlkioDeviceWriteBps": null,
                "BlkioDeviceReadIOps": null,
                "BlkioDeviceWriteIOps": null,
                "CpuPeriod": 0,
                "CpuQuota": 0,
                "CpuRealtimePeriod": 0,
                "CpuRealtimeRuntime": 0,
                "CpusetCpus": "",
                "CpusetMems": "",
                "Devices": null,
                "DeviceCgroupRules": null,
                "DiskQuota": 0,
                "KernelMemory": 0,
                "MemoryReservation": 1073741824,
                "MemorySwap": 4294967296,
                "MemorySwappiness": null,
                "OomKillDisable": false,
                "PidsLimit": 0,
                "Ulimits": [
                    {
                        "Name": "cpu",
                        "Hard": 0,
                        "Soft": 0
                    },
                    {
                        "Name": "nofile",
                        "Hard": 4096,
                        "Soft": 1024
                    }
                ],
                "CpuCount": 0,
                "CpuPercent": 0,
                "IOMaximumIOps": 0,
                "IOMaximumBandwidth": 0,
                "MaskedPaths": [
                    "/proc/acpi",
                    "/proc/kcore",
                    "/proc/keys",
                    "/proc/latency_stats",
                    "/proc/timer_list",
                    "/proc/timer_stats",
                    "/proc/sched_debug",
                    "/proc/scsi",
                    "/sys/firmware"
                ],

    詳細はこちら。

    https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/ecs-logs-collector.html

    では、今日はこの辺で。

     

     

  • 作業ブランチを別リポジトリのブランチへ引っ越し

    作業ブランチを別リポジトリのブランチへ引っ越し

    はじめに

    アプリケーションを作っていると、当初作ろうとしていたものと、今作っているものが徐々にズレてくることがある。

    その時に考えることの一つが、「リポジトリどうしよう」ってやつだ。

    新しいリポジトリとはいえ、いきなりmasterにpushするのもなんだか忍びない。

    今回はリポジトリのブランチを別のリポジトリのブランチとしてコピーする方法を紹介。

    やりたいこと

    いたって簡単。

    これだ。これをやりたいのだ。

    コマンド

    # 新しいリポジトリをclone
    git clone git@git.sumito.com:hoge/AFTER-REPO.git
    cd AFTER-REPO
    git checkout -b AFTER-BRANCH
    
    # remote登録
    git remote add tmpbranch git@git.sumito.com:hoge/BEFORE-REPO.git
    git pull tmpbranch AFTER-BRANCH --allow-unrelated-histories
    
    # 新BRANCHへpush
    git add .
    git commit -m 'copy'
    git remote rm tmpbranch
    git push origin AFTER-BRANCH

    あとはpushした先で期待通りになっているか確認するだけでよい。

     

  • Error getting valid credentials (AKID ): NoCredentialProviders: no valid providers in chain. Deprecated.

    Error getting valid credentials (AKID ): NoCredentialProviders: no valid providers in chain. Deprecated.

    はじめに

    ECSでコンテナを動かそうとすると、作成されるEC2でdocker logsに

    2019-07-08T12:17:52Z [INFO] Event stream ContainerChange start listening...
    2019-07-08T12:17:52Z [WARN] Error getting valid credentials (AKID ): NoCredentialProviders: no valid providers in chain. Deprecated.
    	For verbose messaging see aws.Config.CredentialsChainVerboseErrors
    2019-07-08T12:17:52Z [INFO] Registering Instance with ECS
    2019-07-08T12:17:52Z [INFO] Remaining mem: 3885
    2019-07-08T12:17:52Z [ERROR] Unable to register as a container instance with ECS: NoCredentialProviders: no valid providers in chain. Deprecated.
    	For verbose messaging see aws.Config.CredentialsChainVerboseErrors
    2019-07-08T12:17:52Z [ERROR] Error registering: NoCredentialProviders: no valid providers in chain. Deprecated.
    	For verbose messaging see aws.Config.CredentialsChainVerboseErrors

    というエラーが記述された。その原因と対策を明記する。

    原因

    ecsを実行するEC2インスタンスのroleに適切な権限がない。

    roleに以下の通り権限を付与する

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": [
                    "ecs:CreateCluster",
                    "ecs:DeregisterContainerInstance",
                    "ecs:DiscoverPollEndpoint",
                    "ecs:Poll",
                    "ecs:RegisterContainerInstance",
                    "ecs:StartTelemetrySession",
                    "ecs:UpdateContainerInstancesState",
                    "ecs:Submit*",
                    "ecr:GetAuthorizationToken",
                    "ecr:BatchCheckLayerAvailability",
                    "ecr:GetDownloadUrlForLayer",
                    "ecr:BatchGetImage",
                    "logs:CreateLogStream",
                    "logs:PutLogEvents"
                ],
                "Resource": "*"
            }
        ]
    }

     

    もしEC2へattachするroleを変更したい場合は、ECSの画面からではなく、CloudFormationの画面から変更を行う。

    これは、ECSのサービス作成時、裏でCloudFormationが実行されるため。

    具体的な手順はクラメソさんのBlogが非常にわかりやすい。

    https://dev.classmethod.jp/cloud/aws/ecs-change-instance-type/

    変更点は以下の箇所

     

    有効化するには現在起動しているEC2インスタンスをterminateすること。

    オートスケールの設定がされているので、自動で新しい設定のインスタンスが立ち上がる。

     

     

     

     

     

     

  • go言語で自分のlocalIPを取得する

    go言語で自分のlocalIPを取得する

    はじめに

    dockerコンテナでgoのプログラムを動かしていると、コンテナのIPをどのように取得すればよいか困ったのでその対処を紹介。

    コード

    package main
    
    import (
    	"fmt"
    	"net"
    )
    
    func main() {
    
    	netInterfaceAddresses, _ := net.InterfaceAddrs()
    
    	for _, netInterfaceAddress := range netInterfaceAddresses {
    
    		networkIp, ok := netInterfaceAddress.(*net.IPNet)
    
    		if ok && !networkIp.IP.IsLoopback() && networkIp.IP.To4() != nil {
    
    			ip := networkIp.IP.String()
    
    			fmt.Println("Resolved Host IP: " + ip)
    
    		}
    	}
    }

    解説

    至ってシンプル。 “` net.InterfaceAddrs() “` でIPを取得することが可能だ。

    127.0.0.1 で表現できない時など、テストコードなどで活躍しそう。

  • You must specify a region. You can also configure your region by running “aws configure”.

    You must specify a region. You can also configure your region by running “aws configure”.

    はじめに

    ECSでタスクロールを指定しているのに、ECSで動かしたコンテナ内でawsコマンドを使うと、aws configureをしてくれとエラーが出る際の対処。

    You must specify a region. 
    You can also configure your region by running "aws configure".

    原因

    エラーメッセージの通りregionが指定されていないから。

    コンテナに以下の設定を入れるよう、Dockerfileを修正する。

    [default]
    region=ap-northeast-1
    output=json