cockpit-podmanを試してみた

cockpitにはコンテナ管理のプラグインがあるようなので試してみた。

cockpitにはcockpit-dockerという、dockerコンテナの管理ツールがあったようだが、パッケージがない。どうもRedhatが開発している同じようなシステムであるPodmanに移行したようだ。

podmanについて簡単に調べた感じ、コマンドはほぼdocker互換でいいっぽい。Dockerfileから作れるので、コンテナ作る程度なら困らなさそう。

物は試しでcockpitのWebUIをコンテナにして、同じくコンテナに入れたnginxからアクセスできるように構築してみた。

nginxのコンテナ

nginxのコンテナは、公式のコンテナにちょっとだけ設定を入れて完成

FROM nginx:mainline-alpine

COPY default.conf /etc/nginx/conf.d/default.conf
COPY index.html /var/www/html/index.html
COPY 0-self-signed.key /etc/cockpit/ws-certs.d/
COPY 0-self-signed.cert /etc/cockpit/ws-certs.d/

EXPOSE 443

途中でCOPYしてる0-self-signed.keyと0-self-signed.certはcockpit実行時に自動生成される自己署名証明書。cockpitは設定でHTTPでも接続できるようになるが、CookieがHTTPS前提の設定で送り付けてきてchromiumが捨てちゃうので、自己署名証明書でhttpsできるようにした。

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    location / {
        return 301 https://$host$request_uri;
    }
}
server {
    listen 443 ssl;
    listen [::]:443 ssl;

    ssl_certificate /etc/cockpit/ws-certs.d/0-self-signed.cert;
    ssl_certificate_key /etc/cockpit/ws-certs.d/0-self-signed.key;
    client_max_body_size 2G;
    index index.html index.php;
    location / {
        root /var/www/html;
        index index.html;
    }
    location /private/cp/ {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-CSRF-Token $http_x_csrf_token;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_http_version 1.1;
        proxy_buffering off;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        gzip off;
        proxy_pass http://cockpit:9090;
    }
}

default.confはhttpsの設定とルーティングの設定。cockpitはwebsockerも使うので、proxy_set_headerでそれ用のヘッダも渡さないと動かなくなる

cockpitのコンテナ

FROM debian:bookworm-slim

RUN apt-get update && \
    apt-get upgrade -y && apt-get install -y cockpit locales && \
    rm -rf /var/lib/apt/lists/* && \
    /usr/lib/cockpit/cockpit-certificate-ensure && \
    localedef -i ja_JP -c -f UTF-8 -A /usr/share/locale/locale.alias ja_JP.UTF-8

RUN groupadd -g 1000 user && useradd -m -s /bin/sh -u 1000 -g 1000 -G sudo mattyan && echo mattyan:password | chpasswd && echo "mattyan   ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers

ENV LANG ja_JP.utf8
ADD config.conf /etc/cockpit/cockpit.conf
EXPOSE 9090
ENTRYPOINT ["/usr/lib/cockpit/cockpit-ws"]

最初alpine linuxで組もうかと思ったが、alpine linuxのパッケージにcockpitが無かった(systemdに依存してるらしい)ので、debian:bookworm-slimで構築。

パッケージを入れて、日本語設定。

途中でgroupaddとuseraddしているのは、cockpitは「そのLinux機のユーザーアカウントでログインする」ため。Dockerだとユーザーが無くて入れないので事前に作っておく。

[WebService]
AllowUnencrypted=true
UrlRoot=/private/cp/
ProtocolHeader=X-Forwarded-Proto

AllowUnencryptedの設定で、HTTPでのアクセスを許可。
UrlRootはURLのプレフィックスを設定。
ProtocolHeaderではnginxから渡されるヘッダを指定。

これらの準備が終わったところで

podman build -t nginx_server --rm .
# と
podman build -t cockpit --rm .

でコンテナを作成

cockpit podmanの画面

イメージ一覧にビルドしたイメージが表示されるので、Podを作成してコンテナ作成して実行。

podman generate kubeコマンドでKubernetes用yamlファイルを出せるみたいなので、お試しで出してみた

mattyan@mattyannetstg:~/test_cockpit$ podman generate kube test_cockpit
# Save the output of this file and use kubectl create -f to import
# it into Kubernetes.
#
# Created with podman-4.9.3
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: "2024-05-13T11:54:33Z"
  labels:
    app: testcockpit
  name: testcockpit
spec:
  containers:
  - args:
    - nginx
    - -g
    - daemon off;
    env:
    - name: TERM
      value: xterm
    image: localhost/nginx_server:latest
    name: blissfulhertz
    ports:
    - containerPort: 443
      hostIP: 0.0.0.0
      hostPort: 8443
    tty: true
  - env:
    - name: TERM
      value: xterm
    image: localhost/cockpit:latest
    name: cockpit
    tty: true

なお、読み方はよくわからない。これを実行するとPodが立ち上がるんだろうけど、cockpit-podmanの画面ではこれを取り込むところが無さそうなので、

podman play kube test_cockpit.yaml

で実行してみたところ

Podが増えた

ちゃんと新しいPodが表示された。

ブラウザでアクセスしてみたら

Pod内部のcockpitにアクセス

Cockpitの画面に到達できた。ただ、ここで見えてるのはDockerコンテナ内部なので、ここからSSHでホストに接続してデータ取り出して……ってできれば楽しいんだけど。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です