投稿者: sumito.tsukada

  • 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

     

     

     

  • 【Docker】ストレージ容量不足時の対処法【解決済み】

    【Docker】ストレージ容量不足時の対処法【解決済み】

    はじめに

    Dockerのビルドサーバーでストレージ不足が発生しました。
    不要なファイルを削除する必要があるため、安全に容量を確保する方法を紹介します。
    dockerで/var/lib/docker/overlay2 が肥大化した時の対処になります。

    まず対応すべきこと

    現状把握

    Dockerがディスク容量を圧迫している原因を確認するため、以下のコマンドを使用します。

    docker system df このコマンドで、Dockerに関連するディスク使用状況を確認できます。

    TYPE TOTAL ACTIVE SIZE RECLAIMABLE
    Images 9 1 2.014GB 1.962GB (97%)
    Containers 2 0 0B 0B
    Local Volumes 4 2 824.6MB 781.2MB (94%)
    Build Cache 0 0 0B 0B
    対処

    使用されていないコンテナ、ボリューム、ネットワーク、イメージを削除するには、以下のコマンドを使用します。

    docker system prune

    ただし、使用されていないボリュームとイメージを削除するには、以下のオプションが必要です。
    docker system prune --volumes --all

    volumesの削除

    上記コマンドで、不要なvolumesを削除しました。この操作で、355.4MBの容量を確保できます。ただし、storageの削除には、–volumesオプションを追加する必要があります。

    53d15cd6b78ad0f21788a22e9ce16a7295c4bab97609973
    deleted: sha256:7ae9338aed73a0f33568db53740431038d3a1f779c4dae40d27433984e1cd97c
    deleted: sha256:b1be54c8cadff1e50b87b93559320a1ae57b8d0dd326507148f7ca81d707beed
    deleted: sha256:86d78f10b9718618eaae056f5dfa1edae518949aee4578e4147268e9db2e75f0

    Total reclaimed space: 355.4MB
    ただし、storageの削除には、 --volumes オプションを追加する必要があります。

    imagesの削除

    docker system prune --all

    作業後

    上記の操作を完了した後、Dockerのディスク使用状況を再度確認すると、すべてのカテゴリーで容量が0になります。

  • ワンライナーでサイトのレスポンス速度を計測する

    ワンライナーでサイトのレスポンス速度を計測する

    はじめに

    しっかりした監視ツールを導入せずに、さくっとレスポンス速度を可視化したいときがある。

    手軽に描写できるワンライナーを紹介。

    どんなことができるか

    ワンライナー

    while true; do sleep 1; curl -kL 'http://接続先URL' -o /dev/null -w "%{time_total}" 2> /dev/null | perl -anle 'print "▇"x($F[0]*100)." $F[0]"' ;done
    

    [ec2-user@ip-10-1-8-134 ~]$ while true; do sleep 1; curl -kL 'https://tsukada.sumito.jp' -o /dev/null -w "%{time_total}" 2> /dev/null | perl -anle 'print "▇"x($F[0]*100)." $F[0]"' ;done
    ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 0.361941
    ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 0.370393
    ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 0.904969

    状況に応じて

    “` *100 “` の部分を適宜変更する。

     

  • standard_init_linux.go:190: exec user process caused “exec format error”

    standard_init_linux.go:190: exec user process caused “exec format error”

    概要

    dockerで起動シェルを渡した際、 “` standard_init_linux.go:190: exec user process caused “exec format error” “` というエラーが発生した際の対処

    原因

    起動シェルの中でshebangが抜けていたことが原因

    dockerの起動スクリプトでは必ず指定しなければならない

    対処

    起動シェルの1行目に

    #!/bin/bash

    を追加してあげるのみ(環境によって適宜変える)

    そもそもshebangとは

    “`  #! “` で始まる行。

    実行プログラムのインタプリタが定義される。

    ほとんどのプログラムは shebang が自動補完されるため無くても動く。しかし、dockerでは省略が不可能。shebangが必要なようだ。

     

     

  • let’s encrypt に登録したメールアドレスを変更する

    let’s encrypt に登録したメールアドレスを変更する

    はじめに

    let’s encrypt にメールアドレスを登録すると、証明書の有効期限が近くなると通知してくれる機能がある。その通知先を変更する方法を紹介。

    手順

    “` certbot-auto “` を利用することで簡単に変更が可能だ。

    詳細は以下の通り

    /usr/local/src/certbot/certbot-auto register --update-registration --email [new Mailaddress]

    結果

    # /usr/local/src/certbot/certbot-auto register --update-registration --email letsencrypt@sumito.jp
    Upgrading certbot-auto 0.34.2 to 0.35.1...
    Replacing certbot-auto...
    Creating virtual environment...
    Installing Python packages...
    Installation succeeded.
    Saving debug log to /var/log/letsencrypt/letsencrypt.log
    Usage 'certbot register --update-registration' is deprecated.
    Please use 'certbot update_account [options]' instead.
    
    
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Would you be willing to share your email address with the Electronic Frontier
    Foundation, a founding partner of the Let's Encrypt project and the non-profit
    organization that develops Certbot? We'd like to send you email about our work
    encrypting the web, EFF news, campaigns, and ways to support digital freedom.
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    (Y)es/(N)o: y
    
    IMPORTANT NOTES:
     - Your e-mail address was updated to letsencrypt@sumito.jp

     

  • watch curl時にダウンロード状況を出さない

    watch curl時にダウンロード状況を出さない

    はじめに

    curlをwatchコマンドでポーリングしたい場合がある。しかし、
    普通に実施すると、ダウンロード進捗状況が表示されてしまう。

    watch curl http://hogehoge.com/version

    % Total % Received % Xferd Average Speed Time Time Time Current
    Dload Upload Total Spent Left Speed
    0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 100 199 100 199 0 0 199 0 0:00:01 --:--:-- 0:00:01 33166

    対処

    curlには “` -s “` という進捗を表示しないモードがある。

    watch curl -s http://hogehoge.com/version