kasei_sanのブログ

かせいさんのIT系のおぼえがきです。胡乱の方はnoteとtwitterへ

Alpine Linuxのパッケージ管理システムapkについて理解を深める

APK is 何?

apk = Alpine Linux package management

Alpine Linuxのパッケージ管理システム

パッケージって何?

Linuxが採用しているアプリケーションの配布形態。アプリケーションによっては、正常に動作させるためには「ライブラリ」と呼ぶ別のプログラムを必要とすることがある。パッケージは、こうした動作に必要な各種プログラムやファイルをまとめたものである

xtech.nikkei.com

Alpine Linux に標準でインストールできるパッケージ

ここで調べられる

pkgs.alpinelinux.org

主なコマンド

apk update

利用可能パッケージのインデックスを更新

  • これを実行しても、インストールされたパッケージは更新されない
  • これから取ってくるパッケージの参照先を最新にする
  • Docker で使う場合、最初の方に書く

apk upgrade

現在インストールされているパッケージをアップグレード

  • 別のパッケージ管理システムの話ではあるが、 Docker ではなるべく使わずに、親 image に upgrade を依頼することを推奨している
親イメージの「必須」パッケージの多くは、権限のないコンテナ内ではアップグレードできないため、apt-get アップグレードや dist-upgrade を実行しないようにしてください。

qiita.com

apk add ${パッケージ名}

パッケージの追加

  • apk add curl gcc のように複数指定も可能

以下で各種オプションの解説をする

--no-cache

パッケージをキャッシュしなくするオプション

通常、ダウンロードされたパッケージは /var/cache/apk にキャッシュされる

DockerでImageサイズを削減するために RUN rm -rf /var/cache/apk とかしなくて良いので便利

--update-cache

apk update を実行するオプション

-U も同義

最初に、apk update を実行してるならば不要

  • 古いweb記事を見ると --update オプションを使用していることがあるが、公式ドキュメントの間違いらしい

qiita.com

--virtual ${名前}

インストールした複数のパッケージと依存関係を一つの仮想パッケージとして 名前 で保存

これを使うことで、--virtual で名前をつけたパッケージをまとめて削除できる

Dockerで bundle install するときだけ使うパッケージ(gccとか)を、これを使ってインストール後にまとめて削除することで、imageサイズを削減できる

apk del

パッケージの削除

--virtual

apk add --virtual で追加した仮想パッケージを削除

--purge

関連ファイルも削除してくれるらしい

参考

👇 公式の解説ドキュメント

wiki.alpinelinux.org

Dockerfileで apt-get upgrade するのは止めたほうが良いとベストプラクティスに書かれていた

Dockerfile best practices によると...

Avoid RUN apt-get upgrade and dist-upgrade, as many of the “essential” packages from the parent images cannot upgrade inside an unprivileged container. If a package contained in the parent image is out-of-date, contact its maintainers. If you know there is a particular package, foo, that needs to be updated, use apt-get install -y foo to update automatically.

docs.docker.com

雑な翻訳

親イメージの「必須」パッケージの多くは、権限のないコンテナ内ではアップグレードできないため、apt-get upgrade や dist-upgrade の実行は避けてください。親イメージに含まれるパッケージが古い場合は、そのメンテナに連絡してください。更新が必要なパッケージ foo があることがわかっている場合は、apt-get install -y foo を使って自動的に更新してください。

親イメージが必須とするパッケージ、foo を更新したい場合、自前で apt-get upgrade せずに、メンテナに連絡した上で apt-get install foo で個別にインストールすべきとのこと

ついでに apt-get upgradeapt-get update の違い

  • apt-get update: パッケージリストの更新
  • apt-get upgrade: インストール済みのパッケージ更新

c5 ユーザはさっさと c5a に乗り換えたほうが良いの?

先に結論

保留で良いと思う

  • 数台しか使ってないなら乗り換えてもたいして得しない (c5.large なら1台につき 95$/年 )
  • 何十台もあるなら乗り換えたほうが良いかもだけど、少しだけCPUパワーが下がることを念頭に置く
  • CPUが AMD系に変わることで、処理速度がおちるかもしれない

2020/08/11 にc5aが東京リージョンに上陸しましたね

aws.amazon.com

c5とc5a 何が違うの?

ざっくり、プロセッサの処理速度が少し落ちて、料金が90%になった

プロセッサの違い

Amazon EC2 C5a インスタンスは 2020 年 6 月にリリースされました。C5a インスタンスは、最大 3.3 GHz の周波数で実行される第 2 世代 AMD EPYC™ 7002 シリーズのプロセッサを搭載し、Amazon EC2 コンピューティング最適化 (C5) ファミリーのインスタンスのバリアントです。

今までのc5が Intel Xeon だったのに対して、AMD EPYC に変わり、CPUパワーが少しだけ下がった

c5.large と c5a.large とを比較すると以下のような感じに

f:id:kasei_san:20200819101831j:plain
c5.large

👆2コアの3.4GHz

f:id:kasei_san:20200819101847j:plain
c5a.large

👆2コアの3.3GHz

AMDとIntelで特性の違いってあるの?

PEXT/PDEP という命令が遅いらしいけど、それが具体的にどんな時に使われるのかはちょっと分からない

AMDの時だけ処理が遅いなーって時は、これを疑うと良いかも

umezawa.dyndns.info

料金の違い

largeのオンデマンド料金で比較した場合、c5aの方が90%ほど安い

  • c5.large が 0.107USD/時間
  • c5a.large が `0.096USD/時間

c5 ユーザはさっさと c5a に乗り換えたほうが良いの?

既存の c5 はそのままで、新しくサーバを立てるときには c5a を使うのが良さそう

理由

  • c5.largeで 95$/年 程度と、大した額得しないので(リサーブドとか、Compute Savings Plans 使ってるともっと低い)
  • 何十台もc5系を使っている会社なら、c5a に更新したほうが良いかもしれない

Linux系のパッケージのバージョン番号が古くても、セキュリティフィックスは入っている場合があるというお話

概要

Linux系のパッケージのバージョン番号が古くても、セキュリティフィックスは入っている場合がある

例えば

Debianのbuster(バージョン10)に入っている apache2 は 2.4.38

本家の apache2 は 2.4.43 で、リリースノートを見ると、色々なセキュリティフィックスが入っている

debianのbusterのapache2は 2.4.38 だから、脆弱性が残っているの?

実はそんなことはなくて、2.4.38 にセキュリティフィックスを入れている

なんでそんなことしてるの?

Debianは安定性を重視しているため

勝手にパッケージのバージョンを上げて互換性を損なわないようにしている

そのため、互換性を維持しながら、現状のバージョンのセキュリティフィックスを入れている(これをバックポートと言う)

参考: 質問: なぜ旧バージョンのパッケージを変更しているのですか?

セキュリティフィックスが入ったかどうかは、どこで確認したら良いの?

security-tracker というBTSのようなもので管理されている

以下のように、https://security-tracker.debian.org/tracker/${CVE-番号} で状況が確認できる

自分の環境のパッケージにセキュリティフィックスが入っているかはどう確認するの?

例えば、上記の CVE-2019-0217 は、 バージョン 2.4.38-3+deb10u3 で修正されたと出ている

deb10u3 は、Debianのbuster(バージョン10)での 3 回目のupdateという意味

dpkg -l コマンドで、パッケージの詳細なバージョンが確認できるので、そこで +deb10u${x} のxが3以上ならば、 CVE-2019-0217 のセキュリティフィックスは適用済と分かる

# dpkg -l apache2
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name           Version          Architecture Description
+++-==============-================-============-=================================
ii  apache2        2.4.38-3+deb10u3 amd64        Apache HTTP Server

自分の環境のバージョンが古い場合どうしたら良いの?

以下のコマンドでパッケージを更新すればOK

apt-get update && apt-get install ${パッケージ名}

参考

Debianで実際にバックポートをしている方の記録

security.sios.com

RHELも同様の仕組みを採用している

access.redhat.com

Nginxのライフサイクルポリシーおぼえがき

はじめに

こんなもの見ないで原点にあたるのが良いです

www.nginx.com

Nginxのバージョニング

  • stable : 安定版 と mainline : 主流版がある
  • 偶数バージョンが stable
  • 奇数バージョンが mainline
  • 毎年4月に、mainline の最新版から分岐する
  • 2020/06 現在は、 stable が 1.18、mainline が 1.19

stable と mainline の違い

  • mainline はupdateやbugfix がドンドン入る
  • stable は重大な修正のみ

本番で使うべきは stable と mainline どっち?

stable 一択

信頼性は高いですが、いくつかの実験的なモジュールが含まれている可能性があり、いくつかの新しいバグがある可能性もあります

docs.nginx.com

旧バージョンの安定版はサポートされないの?

最新の stablemainline 以外は、deprecated だそうです

1.12, 13 Release時の記事

以前の安定版ブランチである 1.10 は非推奨となっており、今後はアップデートやサポートを行う予定はありません

www.nginx.com

serverless のバージョンが古いまま、lambda ruby 2.7 を使うと The security token included in the request is invalid エラーが出てハマるので最新版にしよう

というお話です

出てくるエラー

ruby 2.7 で serverless invoke を実行すると --aws-profile を設定していても The security token included in the request is invalid が出ます

Error raised from handler method
{ 
  "errorMessage": "The security token included in the request is invalid.",
  "errorType": "Function<Aws::SSM::Errors::UnrecognizedClientException>",
  "stackTrace": [
    "/var/runtime/gems/aws-sdk-core-3.94.1/lib/seahorse/client/plugins/raise_response_errors.rb:15:in `call'",
    "/var/runtime/gems/aws-sdk-core-3.94.1/lib/aws-sdk-core/plugins/jsonvalue_converter.rb:20:in `call'",
    "/var/runtime/gems/aws-sdk-core-3.94.1/lib/aws-sdk-core/plugins/idempotency_token.rb:17:in `call'",
    "/var/runtime/gems/aws-sdk-core-3.94.1/lib/aws-sdk-core/plugins/param_converter.rb:24:in `call'",
    "/var/runtime/gems/aws-sdk-core-3.94.1/lib/aws-sdk-core/plugins/response_paging.rb:10:in `call'",
    "/var/runtime/gems/aws-sdk-core-3.94.1/lib/seahorse/client/plugins/response_target.rb:23:in `call'",
    "/var/runtime/gems/aws-sdk-core-3.94.1/lib/seahorse/client/request.rb:70:in `send_request'",
    "/var/runtime/gems/aws-sdk-ssm-1.76.0/lib/aws-sdk-ssm/client.rb:7859:in `send_command'",
    "/var/task/handler.rb:6:in `hoge'"
  ]
}

原因

serverlessのバグです

github.com

対応方法

最新版の serverless をインストールしましょう