Docker 同じコンテナ間での通信 APIコンテナからDBコンテナにアクセスできない時の確認

ここでは同じDockerネットワーク内にあるAPI用コンテナ(PHP)から、SQLSERVERのあるDBコンテナにアクセスできなかった時の確認すべき部分を紹介する。MySQLの場合は設定やコマンドが違うのであまり参考にはならない。

前提条件として、コンテナが起動していること。docker psで確認。

コンテナからコンテナへの接続はコンテナ名を指定すること。

設定ファイルの確認

ymlファイルのポートマッピングやデータのマウントに問題がないか。接続の認証情報に間違いがないか。ここではポートやconfファイル、ユーザー名、パスワードなど確認する。

docker-compose.ymlの一部

 mssql:
    image: mcr.microsoft.com/mssql/server:2022-latest
    container_name: mssql
    ports:
      - 1433:1433 <-ポートマッピング ホスト側は1431とかでもいい
    user: root
    environment:
      - ACCEPT_EULA=Y
      - MSSQL_SA_PASSWORD={saユーザーのパスワード} 
      - MSSQL_PID=Express
      - MSSQL_LCID=1041
      - MSSQL_COLLATION=Japanese_CI_AS
    volumes:
      - ./db/mssql/data:/var/opt/mssql/data
      - ./db/mssql/log:/var/opt/mssql/log
      - ./db/mssql/secrets:/var/opt/mssql/secrets
      - ./db/mssql/mssql.conf:/var/opt/mssql/mssql.conf <- confファイル必要

コンテナ内のポート開放を確認する

netstatでポート確認

netstat -tuln | grep 1433

リストに0.0.0.0:1433などが表示されれば、SQL Serverはポート1433でリスニングしています

ログを確認

docker logs {コンテナ名}

拡張機能のファイルがあるか php_sqlsrvやsqlsrvは必要

Dockerfile一部
拡張機能をインストール
RUN chmod uga+x /usr/bin/install-php-extensions \
    && sync \
    && install-php-extensions bcmath ds exif gd intl opcache pcntl pdo_sqlsrv redis sqlsrv zip

以下でAPIコンテナ側のインストールされたモジュールを確認する

php -m

TCP/IP接続が有効になっているか

サーバーからDBへの接続先

localhost,1433

設定を確認するためにコンテナ内SQL Serverに接続して、SQLを打つ必要がある。

接続方法

/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P 'your_password'

SQLCMDコマンドがなければインストールする。パスも通しておくといい。

ログ確認

TCP/IPが有効になっているかログから探すSQL (SQL Serverに接続して打つ)

EXEC xp_readerrorlog 0, 1, N'Server is listening on';

出力に、Server is listening on [::] 1433. という内容が含まれていれば、TCP/IPは有効

エラーログからSQL Serverの構成を検索するコマンド(DBコンテナ内で打つ)

cat /var/opt/mssql/log/errorlog | grep "Server is listening"

出力に、Server is listening on [ ‘any’ <ipv4> 1433] accept sockets 1. という内容があればTCP/IPは有効

システムビューを使用して確認(SQL Serverに接続して打つ)

SELECT * FROM sys.dm_tcp_listener_states;
GO

このクエリの結果で、state_descカラムにLISTENINGと表示されていれば、TCP/IPは正しく動作している。

ログのどちらかにあればいい。

リモートアクセスが有効になっているか

EXEC sp_configure 'remote access';

config_value1であればリモート接続が許可されている。

TCP/IPを有効にする

上記で確認して有効になっていなければ、TCP/IPを有効にする

コンテナ側ではconfigurationマネージャーが使えないので、sqlcmdやT-SQLスクリプトを使って設定する

DBコンテナに入る
docker exec -it mssql bash
sqlcmdコマンドがなければインストールする
/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P 'your_password'
TCP/IPを有効にするT-SQLスクリプト
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
EXEC sp_configure 'remote access', 1;
RECONFIGURE;
GO

コンテナ環境で直接設定する場合、設定ファイルを編集する必要がある。

ホスト側でmssql.confを作成し、以下を記載して、コンテナ側にマウントする

mysql.conf

[network]
tcpport=1433

docker-compose.ymlでマウント

volumes:
      - ./db/mssql/mssql.conf:/var/opt/mssql/mssql.conf

リモートアクセスを有効にする

SQL Serverに接続してうつ

EXEC sp_configure 'remote access', 1;
RECONFIGURE;
GO

以上の設定を行ったら、netstatコマンドで、1433がLISTNINGになっているか確認する。

その後、以下のコマンドでAPIコンテナからDBコンテナへ接続できるか確認する。

ping db_container_name

おそらく、pingコマンドがないといわれるので、インストールする。APIコンテナ内で

apt-get update
apt-get install -y inputils-ping
仮に上記でもpingコマンドが使えなかった場合、
apt-get install -y inputils

これでpingを打ってみる。

以上で接続を確認できるはずである。