理系学生日記

おまえはいつまで学生気分なのか

Azure PipelinesのジョブがInitialize Containersフェーズでuseradd Permission denied.で失敗する

Azure上でコンテナベースのジョブを作ったら、Initialize Containersフェーズでuseradd: Permission denied.というエラーが発生しました。

Try to create a user with UID '1001' inside the container.
/usr/bin/docker exec  dee61730d7328016d8d3f56d81cb034f1e8e478608d3214f4482da5fa1657d00 bash -c "getent passwd 1001 | cut -d: -f1 "
/usr/bin/docker exec  dee61730d7328016d8d3f56d81cb034f1e8e478608d3214f4482da5fa1657d00 useradd -m -u 1001 vsts_azpcontainer
useradd: Permission denied.
useradd: cannot lock /etc/passwd; try again later.
##[error]Docker exec fail with exit code 1

ログを見るとわかるように、Azure Pipelines上で動作するコンテナにはAzureからユーザを強制的に追加してきます。大胆ですが、これがAzure Pipelinesの仕様です。

パーミッション不足でuseraddができないエラーなので、rootで動かせば解決するのですが、ちょっとした問題が。

今回利用していたイメージは06kellyjac/markdownlint-cliであり、このイメージではnodeユーザが指定されています。

FROM node:slim
LABEL maintainer="dev+markdownlint-cli@j-k.io"
RUN npm install -g markdownlint-cli@0.27.1
USER node
WORKDIR /markdown
ENTRYPOINT [ "markdownlint" ]
CMD [ "--help" ]

このイメージをrootで動かそうとすると、自分でBase Imageを作るしかないのでしょうか。

回避策

Dockerでは、docker run時に--userオプションでユーザを切り替えることが可能です。 また、Azure Pipeliensでもdocker run時のオプションをresources.container.optionsで指定できます。

これを利用すると、以下のように--user 0:0optionsに指定すればエラーを回避できます。

resources:
  containers:
    - container: markdownlint_cli
      image: 06kellyjac/markdownlint-cli:0.23.0-slim
      options: --user 0:0 # Azure Pipelinesは内部でuseraddを使用するため

stages:
  - stage: Lint
    jobs:
      - job: mdlint
        displayName: Markdown Lint
        container: markdownlint_cli
        steps:
          - script: |
              markdownlint --version
          - script: |
              find . -type d -name tests -prune -o -name "*.md" -type f -print0 | xargs -0 markdownlint

コンテナでデフォルトユーザが指定されていようとも、強制的にrootで動かす形ですね。