とことんDevOps | 日本仮想化技術のDevOps技術情報メディア

DevOpsに関連する技術情報を幅広く提供していきます。

日本仮想化技術がお届けする「とことんDevOps」では、DevOpsに関する技術情報や、日々のDevOps業務の中での検証結果、TipsなどDevOpsのお役立ち情報をお届けします。
主なテーマ: DevOps、CI/CD、コンテナ開発、IaCなど

開催予定の勉強会

読者登録と各種SNSのフォローもよろしくお願いいたします。

Dockerコンテナーで動くアプリケーションイメージの差し替えの実践

コンテナーでアプリケーションを実行していることを想定して、そのイメージを新しいイメージに置き換えてみようと思います。 私は普段の個人的な備忘録用に、Dockerでknowledgeというアプリケーションを実行しています。

Dockerfileなどは公式で配布されているものをそのまま使っています。

github.com

Dockerfileを見てみると、このファイルの最終更新は5年前です。

github.com

やばっ!?

現状を把握するために、Docker scoutでイメージをチェックしてみましょう。

Docker scoutでイメージをチェック

Docker Desktopがインストールされている環境で、このDockerfileで使っているベースイメージをチェックしてみましょう。 まずはquickviewで確認です。

結果、ベースイメージは更新したほうが良いことがわかります。

$ docker image pull tomcat:jre8

$ docker scout quickview tomcat:jre8
    ! New version 1.0.8 available (installed version is 1.0.7) at https://github.com/docker/scout-cli
    ✓ SBOM of image already cached, 235 packages indexed

  Target               │  tomcat:jre8             │    0C     5H    34M    35L   
    digest             │  f839ea30f955            │                              
  Base image           │  eclipse-temurin:8-jre   │    6C    19H    12M     2L   
  Refreshed base image │  eclipse-temurin:8-jre   │    0C     0H     3M    14L   
                       │                          │    -6    -19     -9    +12   
  Updated base image   │  eclipse-temurin:21-jre  │    0C     0H    14M    20L   
                       │                          │    -6    -19     +2    +18   

What's Next?
  View vulnerabilities → docker scout cves tomcat:jre8
  View base image update recommendations → docker scout recommendations tomcat:jre8
  Include policy results in your quickview by supplying an organization → docker scout quickview tomcat:jre8 --org <organization>

何を具体的に行うのが適切か判断するには、docker scoutコマンドにrecommendationsオプションを付けてイメージをスキャンします。 ベースイメージのタグがjre8から8-jre8に変わったようです。ここを変更すると、メンテナンスされたイメージでアプリケーションを実行できます。

$ docker scout recommendations tomcat:jre8
    ! New version 1.0.8 available (installed version is 1.0.7) at https://github.com/docker/scout-cli
    ✓ SBOM of image already cached, 235 packages indexed

Recommended fixes for image  tomcat:jre8 

  Base image is  eclipse-temurin:8-jre 

  Name            │  8-jre                                                                     
  Digest          │  sha256:00bbe5c2a28e1cf1beaf016b1aca47a2088f54b70d9203fce9aad8459bc44f75   
  Vulnerabilities │    6C    19H    12M     2L                                                 
  Pushed          │ 1 year ago                                                                 
  Size            │ 82 MB                                                                      
  Packages        │ 194                                                                        
  Flavor          │ ubuntu                                                                     
  OS              │ 22.04                                                                      
  Runtime         │ 8                                                                          

                                                                                             
  │ The base image is also available under the supported tag(s)  8-jre-jammy . If you want to 
  │ display recommendations specifically for a different tag, please re-run the command using 
  │ the  --tag  flag.                                                                         


Refresh base image
  Rebuild the image using a newer base image version. Updating this may result in breaking changes.


            Tag            │                   Details                    │   Pushed   │       Vulnerabilities        
───────────────────────────┼──────────────────────────────────────────────┼────────────┼──────────────────────────────
   8-jre                   │ Benefits:                                    │ 3 days ago │    0C     0H     3M    14L   
  Newer image for same tag │ • Newer image for same tag                  │            │    -6    -19     -9    +12   
  Also known as:           │ • Tag was pushed more recently              │            │                              
  • 8-jre-jammy           │ • Image has similar size                    │            │                              
  • 8u382-b05-jre         │ • Image contains similar number of packages │            │                              
  • 8u382-b05-jre-jammy   │ • 8-jre was pulled 44K times last month     │            │                              
                           │                                              │            │                              
                           │ Image details:                               │            │                              
                           │ • Size: 82 MB                               │            │                              
                           │ • Flavor: ubuntu                            │            │                              
                           │ • OS: 22.04                                 │            │                              
                           │ • Runtime: 8                                │            │                              
                           │                                              │            │                              
                           │                                              │            │                              
                           │                                              │            │                              


Change base image
  The list displays new recommended tags in descending order, where the top results are rated as most suitable.


              Tag              │               Details               │   Pushed   │       Vulnerabilities        
───────────────────────────────┼─────────────────────────────────────┼────────────┼──────────────────────────────
   21-jre                      │ Benefits:                           │ 3 days ago │    0C     0H    14M    20L   
  Major runtime version update │ • Image contains 10 fewer packages │            │    -6    -19     +2    +18   
  Also known as:               │ • Major runtime version update     │            │                              
  • 21-jre-jammy              │ • Tag was pushed more recently     │            │                              
  • 21_35-jre                 │                                     │            │                              
  • 21_35-jre-jammy           │ Image details:                      │            │                              
                               │ • Size: 100 MB                     │            │                              
                               │ • Flavor: ubuntu                   │            │                              
                               │ • OS: 22.04                        │            │                              
                               │ • Runtime: 21                      │            │                              
                               │                                     │            │                              
                               │                                     │            │                              
                               │                                     │            │                
                               

前の環境と同じようにDocker環境を用意します。

$ sudo apt install -y docker.io docker-compose
$ sudo usermod -aG docker $USER
$ sudo systemctl enable --now docker

より新しいバージョンのDocker、そしてDocker Compose V2や新しいDocker Buildを使ったほうが良いのですが、 アップグレード対象の環境が古い構成で実行したものなので、同じバージョンの組み合わせでインストールしています。

環境を新規インストールする場合は、公式のDockerインストールの方法で新しいバージョンを入れたほうが良いです。

docs.docker.com

ここでは前で説明したとおり、古い構成でセットアップするのを前提とします。

DockerでKnowledgeの実行

アップデート前のKnowledge環境を再現するために、ソースをクローンしてデフォルトのまま実行します。

git clone https://github.com/support-project/docker-knowledge.git
cd docker-knowledge
docker-compose up -d

ブラウザーでアクセスし、管理者ログインして記事を適当に書いてみます。

URL: http://ip-address-or-fqdn:8080 初期管理者: admin 初期パスワード: admin123

※使い始めるときは任意の管理ユーザーを作って、初期管理者は削除しましょう。

デモ用にこんなタイトルの記事を書きました。テスト用なので内容は適当です。

本文を開いたスクリーンショットを取るのを忘れていました。申し訳ありません。

イメージの差し替え

docker-knowledgeというディレクトリーの中に必要なDockerfileやdocker-compose.yamlがあります。 これらを変更していきます。

まずはDockerfileを書き換えます。書き換えるのはベースイメージを指定しているFROM句のところです。 本当のところを言うとUserも追加したいところですが、それはまた今度ということで。

# Dockerfile for Knowledge

#FROM tomcat:jre8
FROM tomcat:8-jre8

# ==== dumb-init ====
RUN apt-get update && \
    apt-get install -y dumb-init && \
    apt-get clean

# ==== environment ====
RUN rm -rf /usr/local/tomcat/webapps/ROOT \
  && update-ca-certificates -f

# ==== add Knowledge ====
ADD https://github.com/support-project/knowledge/releases/download/v1.13.1/knowledge.war \
      /usr/local/tomcat/webapps/ROOT.war

VOLUME [ "/root/.knowledge" ]
EXPOSE 8080

CMD [ "dumb-init", "/usr/local/tomcat/bin/catalina.sh", "run" ]

docker-compose.yamlも書き換えます。イメージ部分をコメントアウトし、build部分のコメントを外します。これでDockerfileでビルドしたイメージを使って、コンテナーが実行されます。永続データはvolumesで渡しているので、前の状態が復元されます。

version: '2'
services:
    app:
        #image: koda/docker-knowledge
        build: .
        volumes:
            - ./volumes/knowledge:/root/.knowledge
        ports:
            - "8080:8080"
        restart: always
        depends_on:
            - "db"
    db:
        image: postgres:9
        environment:
            - POSTGRES_USER=postgres
            - POSTGRES_PASSWORD=admin123
            - POSTGRES_DB=knowledge_production
        volumes:
            #- ./volumes/initdb:/docker-entrypoint-initdb.d
            - ./volumes/postgres/data:/var/lib/postgresql/data
        restart: always

一旦今動いている環境を停止して

docker-compose stop

次のように実行します。

sudo -s
docker-compose build
docker-compose up -d

再度ログインして、アップデート前に書いたページが引き続きアクセスできることを確認します。 ページを編集して、保存を実行したときにエラーが発生しないこと、データがキチンと上書きされたことを確認します。

念のため、次のような感じで現在稼働中のコンテナーが新しいイメージを使って動作していることを確認します。

$ docker container ls
CONTAINER ID   IMAGE                  COMMAND                  CREATED       STATUS       PORTS                                       NAMES
24587a455bf6   docker-knowledge_app   "dumb-init /usr/loca…"   2 hours ago   Up 2 hours   0.0.0.0:8080->8080/tcp, :::8080->8080/tcp   docker-knowledge_app_1
06e5fa54f85c   postgres:9             "docker-entrypoint.s…"   2 hours ago   Up 2 hours   5432/tcp                                    docker-knowledge_db_1

$ docker image ls
REPOSITORY              TAG       IMAGE ID       CREATED         SIZE
docker-knowledge_app    latest    62a603137f3b   2 hours ago     418MB
tomcat                  8-jre8    a47ae350a7b7   3 days ago      242MB
postgres                9         027ccf656dc1   20 months ago   200MB
koda/docker-knowledge   latest    9ae2dde61ad6   5 years ago     611MB

$ docker image inspect 62a603137f3b |grep Id
        "Id": "sha256:62a603137f3b5c1e7e08663c9f5f9bfb5acaaf4a73ba134c26cd6b86859cde5f",
        
$ docker container inspect docker-knowledge_app_1 |grep Image
        "Image": "sha256:62a603137f3b5c1e7e08663c9f5f9bfb5acaaf4a73ba134c26cd6b86859cde5f",
            "Image": "docker-knowledge_app",

イメージが新しいものに書き換わっていれば、目的達成です。 ...さて移行先を探さないとなあ。