心地よいライフハック

これ便利だな〜と思ったことなど

docker コンテナ内の 設定ミス で動かなくなったら、、、

 もし docker コンテナ 内の 設定 ファイルの編集ミスなどをしてしまって、
コンテナが起動しなくてしまったら、 何も知らないと結構困る。
 
起動しなくなったコンテナを、無理やり起動させて、修正作業ができるようにしたい。 
 
「docker logo」の画像検索結果

 
 
 
ここの通り対処すればOK かと思うが、、
 
 
自分は、上記とは、多少 環境が 異なるため、一応 ここに 記録。
 

< できた環境 > 
 
ホストOS macos 10.13.6 ターミナル
仮想 ( VM ) CentOS
CentOS Linux release 7.4.1708 (Core)
 

 
まず Docker ホストの OS に ログイン状態
# docker -v
Docker version 1.13.1, build 07f3374/1.13.1
 
停止した コンテナの ID を確認 (前方の数桁がわかればOK)
# docker ps -a
・・・

 
 
該当 コンテナのディレクトリ へ移動
cd /var/lib/docker/containers/ae98d...4f6/

( * 編集前に この ファイル のバックアップを忘れずに! )
cp -p 上記config.v2.json /バックアップ退避しておきたいディレクトリ/config.v2.json
 
一時的にコンテナ起動時コマンドを編集する
vi ./config.v2.json
 
> 編集 内容
コンテナ起動時のコマンド と そのコマンドの引数を 操作する。
 
コマンド  “ Path “ 要素にかかれたものを適当なコマンドに変更する。
“ PATH “ ではないので注意。
 
たとえば  tail 。 node-red コンテナの場合は  以下のように指定した。
 

“Path" : “ /usr/bin/tail "
 
 
/usr/bin/tail 
 
続いて そのコマンドの引数の指定は “ Args “ で。
確実に有効な オプションや、ファイルパス を指定する。
 

"Args":["-f","/usr/src/node-red/package.json"]
 
 
上記で 指定 うまくいくと コンテナ起動時
tail -f /usr/src/node-red/package.json 
というコマンドがうまくいけば  コンテナが立ち上がりっぱなしになる。
 
編集した config.v2.json を 有効化する。
 
# systemctl restart docker
 
# docker start -ai  問題のコンテナ名
 
ここで、上記 で 設定した指定がうまくいけば、 立ち上がる。
立ち上がらなければ、 エラー内容を よく読み config.v2.json で 対処できそうな 問題なら、それで 立ち上げる。
 
もしうまく立ち上がったらなら、 上記の例では tail -f コマンド を実行したままになるはず。
 
この状態で、通常起動時の問題箇所を修正しておく。
( 自分の場合は、 node-red コンテナの /data/setting.js の内容を修正した。)
 
この時、 ctrl + p つづけて q と押す  と コンテナ は デーモン化して バックグラウンドへ。
 
docker ホスト側 の ターミナル操作に復帰できる。
 
また、修正したければ docker exec -it コマンドで 中に入って修正作業できる と思う。
 
 
 修正が完了したら、さきほどバックアップした、config.v2.json を使って通常コンテナ起動の設定に戻す。
( cp -p バックアップ退避しておいたパス/config.v2.json 起動方法を弄ったconfig.v2.json )
 
⬇︎その config.v2.json を 有効化する。
# systemctl restart docker
 

 
あとは通常通り、起動 できればOK。
問題があれば、docker logs コマンドを使ったりして 解析を進めよう。
 
 
 
 
 

ログイン シェル を変える

debian 9 にて。
 
< 目的 >
 
自分で作ったユーザーは、 sh でログインしてしまうので、bashにしたい。
 

 
< やり方 >
 
$ su root
 
# chsh 対象ユーザー名
 
->ここで 指定をおこなう。
 
/bin/bash 
 
あとは、ログインシェルが変わったか 確認すればOK

Centos7.6 バグ ipv6 で dadlyfailed

対策1
ipv6 を 使わない。
 
対策2 パッチを当てる
やり方までは終えてないけど。 
 
関連技術 OpenvSwitch
( Open Virtual Switch、通称「OVS」)は、ソフトウェア定義型ネットワーク(SDN)を実現する仮想スイッチです。
 
 

debian 9 stretch 固定IPアドレスの設定 ( debian公式参照 + エラー対処 )

RTNETLINK answers: Cannot assign requested address がでた。
 
 
すると 自分の場合は、ひとつのNICIPアドレスが2つ になってしまったり、しっちゃか めっちゃか。。
 
対策:flush  の実行を挟む!
 
# ifdown NIC名 ; ip addr flush dev NIC名 ; ifup NIC
 
 

 
 debian 9 stretch において、あんまり 固定IPアドレス を設定する まとまった情報がなかったので 以下にまとめます。
 

 
 
debian 9 stretch において 固定IPアドレス設定 をする方法をまとめます。
 
例1
NIC名 : ens3  とします。
 
通常通り  /etc/network/interfaces を編集して固定IPアドレスの設定をします。
 

 
# The primary network interface
auto ens3
allow-hotplug ens3
iface ens3 inet static
address  自分の設定したい固定IPアドレス
netmask 255.255.255.0  (などサブネットマスクの設定)
gateway ルータのアドレスなど
 
# network とか broadcast とか dns-servers の設定なくてもいけるのね。。

 
 
上記 ファイルの 編集が完了したら、、
# ifdown ens3 ; ip addr flush dev ens3 ; ifup ens3
 
最後確認して 問題なければOK!
# ip a
 

 
 
参考:
公式マニュアル
 
エラー対処

HAproxy ( docker コンテナ版 ) 設定のリロード

 

 
HAproxy コンテナ起動中でもサクッと設定をリロード。config  reload 。グレイスフル リロード
 

 
起動中のコンテナのコンフィグを上書き更新する。
docker ホスト側からコマンド。
 
# docker cp ./dockerホスト側のディレクトリ/haproxy.cfg コンテナID:/usr/local/etc/haproxy/haproxy.cfg
 
上書きしたコンフィグファイルのリロード
グレイスフル・リロード方法 )
 
# docker kill -s HUP 動作中のコンテナ名
 
コマンド例
# docker kill -s HUP my-running-haproxy
 
参考:
 

 
動作確認環境 ( 2019年 2月初旬 )
 
Docker version 1.13.1, build 07f3374/1.13.1
docker-compose version 1.23.2, build 1110ad01
CentOS Linux release 7.4.1708 (Core)
HAproxy 1.9
 

 
 

docker コンテナの HAproxy で、config と一緒に ユーザーリスト を取り込む方法

 
docker 版 HAproxy を使う。その際に、Basic 認証 などで使う ユーザーリスト や、設定ファイル ( haproxy.cfg )を どうやって取り込ませるか?食わせるか?
 
できたので、記録しておく。
 
ついでに https で使う pem ファイルも取り込んだ。
 

  
 

 
 

  1. docker pull

 
    # docker pull haproxy
 

  2. haproxy の稼働に必要なファイルの準備

 
    ・ haproxy.cfg
    ・ userlist.cfg (Basic認証で使うユーザーリストなど必要に応じて)
    ・ SSL(HTTPS)で使うpemファイルなど 取り込みたいファイル
 

  3. DockerFile の作成

 
    Dockerfile という名前のファイルを作る。中身
 
 

 
    FROM haproxy:1.9
    COPY ./haproxy.cfg    /usr/local/etc/haproxy/haproxy.cfg
    COPY ./userlist.cfg   /usr/local/etc/haproxy/userlist.cfg
    COPY ./haproxy.pem    /usr/local/etc/haproxy/cert/haproxy.pem
 

 
 
    ここで、COPY コマンドの引数2つについて。
    左側: コマンドを打つDocker ホスト側の世界。ファイル名(パス)
    右側: コンテナ内のファイル名(パス)
 
    haproxy コンテナ内に /usr/local/etc/haproxy というパスがあるので、
    その中に、手元のファイルを放り込んであげる形。
 
    ( 挙動を見ている限りではビルド時にコピーされるようなので、稼働中は、難しそう )
 
    ・用意ができたら確認
 
    自分はこんな感じです。
 
 

 
    # pwd
    /root/dev/haproxy
 
    # ls
    Dockerfile  haproxy.cfg  haproxy.pem  userlist.cfg
 

 
 

  4. docker build

 
    上記、場所にいる状態で コマンドを打つ。
 
    # docker build -t myhaproxyなど任意コンテナ名 .
 

  5. HAproxyコンテナの設定検証

 
    haproxy 設定ファイル の docker 検証を行います。 
 
    # docker run -it --rm --name haproxy-syntax-check myhaproxy haproxy -c -f /usr/local/etc/haproxy/haproxy.cfg -f /usr/local/etc/haproxy/userlist.cfg
 
    < 解説 >
    ・ -f で haproxy に 直接食わせたいコンフィグファイルを指定。
    ・ -c で 設定ファイルのチェック。
 
 
 
 

 
 
    設定ファイルのチェックでNGなら 問題箇所を修正して 2.から再度チャレンジ。
 
    OKなら 以下に進んでコンテナを起動する。
 

   6. docker run

 
     (ユーザーリストなどなしの例)
    # docker run -d --name my-running-haproxy myhaproxy
 
     (ユーザーリストなどありの例)
    # docker run -d --name my-running-haproxy myhaproxy -c -f /usr/local/etc/haproxy/haproxy.cfg -f /usr/local/etc/haproxy/userlist.cfg
 
 -f で指定するファイルパスは、コンテナ内のファイルパス。
   DcokerFile で指定、Build でコピーしてあげたファイル。
 
    これで起動できても、haproxy が監視するサーバーが止まっているかアクセスできていないと、haproxyも止まってしまうようなので、注意。
 
 
 

 
 
run した後、何らかの理由で停止状態としていた際に、もう一度 その設定を保持した状態で動作させたい場合は、以下コマンドも便利。
 
# docker restart コンテナID
 
 

 
 
次回は、HAproxy コンテナ 動作中でもできる 設定ファイルの リロードについて。
 
別途、docker compose でも できたので機会があればそちらも記録しておこうかなと思う。
 

 
動作確認環境 ( 2019年 2月初旬 )
 
Docker version 1.13.1, build 07f3374/1.13.1
docker-compose version 1.23.2, build 1110ad01
CentOS Linux release 7.4.1708 (Core)
HAproxy 1.9
 

 
 
 

HAproxy 設定  ( Basic認証の結果で分岐 )

REST API サーバーのフロントに立たせる HAproxyの設定において、Basic認証の結果をもとに分岐させたい。
その場合の HAproxy 設定について、挙動の結果を経てここに記録。
 
< 動作環境 >
CentOS Linux release 7.5.1804 (Core) 
Linux 3.10.0-862.14.4.el7.x86_64 #1 SMP Wed Sep 26 15:12:11 UTC 2018
HAproxy 1.5x
 
< 前提知識 > HAproxy の設定について
・ユーザーリストの定義ができること
BASIC認証で分岐できること
・簡単な front_end 定義
ACL で 意図した back_end、ホストへ誘導できること
 
#ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
 
その上で、以下 2行の設定方法をマスターする。
 
#ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
 
acl auth_ok     http_auth(定義済みユーザーリスト)
http-request deny   unless   auth_ok
 
#ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
 
 
 

 
< " http-request deny " について >
例えば、BASIC認証で NGだった場合、403 を返したい。
その際に、 http-request により、 宛先を deny とすることで、実現できた。
 
  deny : 認めない     (参照: eow.alc.co.jp)
 
 
< " unless " について >
 
まず普通に辞書を紐解く
 
  unless :  ~でない限り、~である場合を除いて   (参照: eow.alc.co.jp)
 
 
以上を踏まえて 以下を読み解く。
 
#ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
 
" http-request deny   unless   auth_ok "
 
(BASIC認証の結果) auth_ok でなければ deny へ飛ばすぞ😤
 
#ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
 
です。
deny へ飛ばされると 403 エラー となります。
(403エラー関連のHAproxyの設定がデフォルトから更新されていなければ)
 
 
以上より、この2行の設定方法がわかった。
#ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
 
acl auth_ok     http_auth(定義済みユーザーリスト)
http-request deny   unless   auth_ok
 
#ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
 
 
 

 
 
また、似たような書き方として以下もある。
 
#ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
 
acl auth_ok http_auth(user_list)
http-request auth if !auth_ok
 
#ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
 
auth_OK でない場合、つまり認証が通らなかったら、もう一度 認証を行う。
(以後 通らないと 同じく繰り返す)
 
これは、REST API ではなく、ブラウザで見るwebサイトへの対応では、親切な書き方かもしれない。
( パスワード入力画面を出してくれるなど )
 
ただし、REST API クライアントからこの処理を叩くと、 503 エラーを返却してしまう。
 
REST APIBASIC認証を 叩いて認証NGの際、 HAproxy から 403 エラーを出して欲しい場合は、前者の書き方でいくべき。
 
前者は REST API ( CUI )向き、後者は ブラウザからみる webサイト( GUI )向き と思われる。
 
目的に応じて 好きな方 を使おう。
 

 
 
また、OR条件で繋げることもできる。
( ユーザーか 管理者 いずれかのBASIC認証が通ってなければ、 403エラー。)
 
#ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
 
http-request   deny unless  auth_user_ok or auth_mngr_ok
 
#ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
 
 
( 応用例 ) こんな書き方もできた。
 
# 前略
#ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
# ユーザーリスト定義
#ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
 
userlist user_list
  user userman  insecure-password ippandaze
userlist mngr_list
  user mngrman  insecure-password watasigakanrisya
 
#ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
frontend main *:80
 
    acl auth_user_ok     http_auth(user_list)
    acl auth_mngr_ok     http_auth(mngr_list)
    http-request deny    unless    auth_user_ok or auth_mngr_ok
 
    acl ・・・ 分岐させたい acl 処理や default_backend など
 
#ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー