雑木林

頭の中の整理と忘れないための確認メモ

ubuntuでpodmanを使うための設定など

ubuntu22.04でpodmanを入れ、docker、docker-compose、Docker Hubのイメージを使えるようにする。

要約

  • podman podman-docker をインストールする
  • docker-composeを一般ユーザで使う場合はAPIサービスと環境変数を設定する
  • Docker Hubのイメージを追加するにはレジストリにサイトを追加する

コンテナ環境にnerdctlを使おうと思ったのですが、一部機能が物足りなかったのでpodmanを使ってみました。
その時の構築メモ。

環境

podmanとpodman-dockerのインストール

コンテナエンジンであるpodmanとdockerコマンドを使うためのpodman-dockerをインストールします。

$ sudo apt install -y podman podman-docker

この時点でdockerコマンドは使用可能になりますが、以下のようにメッセージが表示されます

$ docker ps
Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg.
CONTAINER ID  IMAGE       COMMAND     CREATED     STATUS      PORTS       NAMES

メッセージにある通り、nodockerファイルを生成することで消すことができます。

$ sudo touch /etc/containers/nodocker
$ docker ps
CONTAINER ID  IMAGE       COMMAND     CREATED     STATUS      PORTS       NAMES

docker-composeはrootユーザでは利用可能ですが一般ユーザで使用するとエラーが出ます。
composeファイル

# vi docker-compose.yml 
version: "3.9"
services:
  test:
    image: "alpine:3.16"
    tty: true

rootユーザでdocker-compose

# docker-compose up -d
Creating network "tmp_default" with the default driver
Creating tmp_test_1 ... done
# docker-compose ps
   Name      Command   State   Ports
------------------------------------
tmp_test_1   /bin/sh   Up     

一般ユーザでdocker-compose

$ docker-compose up -d
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 699, in urlopen
    httplib_response = self._make_request(
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 394, in _make_request
    conn.request(method, url, **httplib_request_kw)
  File "/usr/lib/python3.10/http/client.py", line 1282, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "/usr/lib/python3.10/http/client.py", line 1328, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "/usr/lib/python3.10/http/client.py", line 1277, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "/usr/lib/python3.10/http/client.py", line 1037, in _send_output
    self.send(msg)
  File "/usr/lib/python3.10/http/client.py", line 975, in send
    self.connect()
  File "/usr/lib/python3/dist-packages/docker/transport/unixconn.py", line 30, in connect
    sock.connect(self.unix_socket)
ConnectionRefusedError: [Errno 111] Connection refused

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/requests/adapters.py", line 439, in send
    resp = conn.urlopen(
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 755, in urlopen
    retries = retries.increment(
  File "/usr/lib/python3/dist-packages/urllib3/util/retry.py", line 532, in increment
    raise six.reraise(type(error), error, _stacktrace)
  File "/usr/lib/python3/dist-packages/six.py", line 718, in reraise
    raise value.with_traceback(tb)
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 699, in urlopen
    httplib_response = self._make_request(
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 394, in _make_request
    conn.request(method, url, **httplib_request_kw)
  File "/usr/lib/python3.10/http/client.py", line 1282, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "/usr/lib/python3.10/http/client.py", line 1328, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "/usr/lib/python3.10/http/client.py", line 1277, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "/usr/lib/python3.10/http/client.py", line 1037, in _send_output
    self.send(msg)
  File "/usr/lib/python3.10/http/client.py", line 975, in send
    self.connect()
  File "/usr/lib/python3/dist-packages/docker/transport/unixconn.py", line 30, in connect
    sock.connect(self.unix_socket)
urllib3.exceptions.ProtocolError: ('Connection aborted.', ConnectionRefusedError(111, 'Connection refused'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/docker/api/client.py", line 214, in _retrieve_server_version
    return self.version(api_version=False)["ApiVersion"]
  File "/usr/lib/python3/dist-packages/docker/api/daemon.py", line 181, in version
    return self._result(self._get(url), json=True)
  File "/usr/lib/python3/dist-packages/docker/utils/decorators.py", line 46, in inner
    return f(self, *args, **kwargs)
  File "/usr/lib/python3/dist-packages/docker/api/client.py", line 237, in _get
    return self.get(url, **self._set_request_timeout(kwargs))
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 555, in get
    return self.request('GET', url, **kwargs)
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 542, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 655, in send
    r = adapter.send(request, **kwargs)
  File "/usr/lib/python3/dist-packages/requests/adapters.py", line 498, in send
    raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: ('Connection aborted.', ConnectionRefusedError(111, 'Connection refused'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/bin/docker-compose", line 33, in <module>
    sys.exit(load_entry_point('docker-compose==1.29.2', 'console_scripts', 'docker-compose')())
  File "/usr/lib/python3/dist-packages/compose/cli/main.py", line 81, in main
    command_func()
  File "/usr/lib/python3/dist-packages/compose/cli/main.py", line 200, in perform_command
    project = project_from_options('.', options)
  File "/usr/lib/python3/dist-packages/compose/cli/command.py", line 60, in project_from_options
    return get_project(
  File "/usr/lib/python3/dist-packages/compose/cli/command.py", line 152, in get_project
    client = get_client(
  File "/usr/lib/python3/dist-packages/compose/cli/docker_client.py", line 41, in get_client
    client = docker_client(
  File "/usr/lib/python3/dist-packages/compose/cli/docker_client.py", line 170, in docker_client
    client = APIClient(use_ssh_client=not use_paramiko_ssh, **kwargs)
  File "/usr/lib/python3/dist-packages/docker/api/client.py", line 197, in __init__
    self._version = self._retrieve_server_version()
  File "/usr/lib/python3/dist-packages/docker/api/client.py", line 221, in _retrieve_server_version
    raise DockerException(
docker.errors.DockerException: Error while fetching server API version: ('Connection aborted.', ConnectionRefusedError(111, 'Connection refused'))

一般ユーザでdocker-composeできるようにする

一般ユーザでPodman APIサービスを起動し、環境変数DOCKER_HOSTにAPIサービスのsocketを指定する。 ただし、ポートマッピングをしている場合、バックグラウンドで動作させないとエラーが出ます。

Podman APIサービスの起動

$ systemctl --user daemon-reload
$ systemctl --user enable --now podman.socket
$ systemctl --user status podman.socket
● podman.socket - Podman API Socket
     Loaded: loaded (/usr/lib/systemd/user/podman.socket; enabled; vendor preset: enabled)
     Active: active (listening) since Sun 2022-10-02 22:16:06 JST; 4min 28s ago
   Triggers: ● podman.service
       Docs: man:podman-system-service(1)
     Listen: /run/user/1001/podman/podman.sock (Stream)
     CGroup: /user.slice/user-1001.slice/user@1001.service/app.slice/podman.socket

10月 02 22:16:06 mgmt-rp01 systemd[3356]: Listening on Podman API Socket.

環境変数DOCKER_HOST

次回以降、ログイン時に環境変数を登録するよう設定(今回は.profileに追記)

$ echo "export DOCKER_HOST=\"unix:$XDG_RUNTIME_DIR/podman/podman.sock\"" >> ~/.profile

設定の再読み込み

$ . ~/.profile

すると一般ユーザでもdocker-composeできるようになる。 ただし、ポートマッピングを行う場合、バックグラウンドで動作する必要がある。

$ cat docker-compose.yml 
version: "3.9"
services:
  nginx:
    image: "nginx:latest"
    logging:
      driver: journald
      options:
        tag: "container.nginx"
    ports:
      - 8080:80
    container_name: sv01
$ docker-compose up
Starting sv01 ... error

ERROR: for sv01  port reloading failed: rootless port failed to add port: listen tcp 0.0.0.0:8080: bind: address already in use

ERROR: for nginx  port reloading failed: rootless port failed to add port: listen tcp 0.0.0.0:8080: bind: address already in use
ERROR: Encountered errors while bringing up the project.
$ docker-compose up -d
Creating network "nagios_default" with the default driver
Creating sv01 ... done
$ docker-compose ps
Name              Command               State       Ports    
-------------------------------------------------------------
sv01   /docker-entrypoint.sh ngin ...   Up      :8080->80/tcp

Docker Hubのイメージを使えるようにする

Docker Hubにあるイメージはデフォルトでは利用できない。
例えばnginxのイメージを取得しようとすると以下のエラーが出る。

$ docker pull nginx:latest
Error: short-name "nginx:latest" did not resolve to an alias and no unqualified-search registries are defined in "/etc/containers/registries.conf"

レジストリの一覧にないことが原因なので足してやると利用できるようになる。

$ echo "unqualified-search-registries = [\"docker.io\"]" | sudo tee -a /etc/containers/registries.conf
unqualified-search-registries = ["docker.io"]
$ docker pull nginx:latest
Resolving "nginx" using unqualified-search registries (/etc/containers/registries.conf)
Trying to pull docker.io/library/nginx:latest...
Getting image source signatures
Copying blob 8460b172ee88 done  
Copying blob 3f45c0a5377f done  
Copying blob 3d898485473e done  
Copying blob f1cdcf23708a done  
Copying blob a73e5a7988e9 done  
Copying blob 43509f6ae4b3 done  
Copying config 0c404972e1 done  
Writing manifest to image destination
Storing signatures
0c404972e13056a866875f2bf8a981a911dc17071f505b9dc72cdf08e0d40983
$ docker images
REPOSITORY               TAG         IMAGE ID      CREATED      SIZE
docker.io/library/nginx  latest      0c404972e130  2 weeks ago  139 MB