今回は、OpenShift上でNode.jsのpodをデプロイした際に、正常に起動せず、パーミッションエラーが出た時のトラブルシューティングの手順をここに残すこととする。
podの状態の確認
デプロイした node-app-deployment podの状態を確認する。
[xxxx@sd-roks-01 ~]$ oc get pod
NAME READY STATUS RESTARTS AGE
mysql-67d4b5d9bc-hw7d5 1/1 Running 0 18h
node-app-deployment-547989c8f5-fg5dk 0/1 CrashLoopBackOff 181 (4m25s ago) 15h
node-app-deployment-547989c8f5-xnv2r 0/1 CrashLoopBackOff 183 (3m52s ago) 15h
node-app-deployment-74c4f5857b-jv767 0/1 CrashLoopBackOff 169 (3m5s ago) 14h
➡ podのステータスは、CrashLoopBackOff で、起動に失敗していることがわかる。
node-app-deployment podのログを確認する。
[xxxx@sd-roks-01 ~]$ oc logs node-app-deployment-547989c8f5-fg5dk
node:internal/fs/utils:356
throw err;
^
Error: EACCES: permission denied, open '/usr/src/app/index.js'
at Object.openSync (node:fs:596:3)
at Object.readFileSync (node:fs:464:35)
at Module._extensions..js (node:internal/modules/cjs/loader:1385:18)
at Module.load (node:internal/modules/cjs/loader:1203:32)
at Module._load (node:internal/modules/cjs/loader:1019:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:128:12)
at node:internal/main/run_main_module:28:49 {
errno: -13,
syscall: 'open',
code: 'EACCES',
path: '/usr/src/app/index.js'
}
Node.js v18.20.6
➡ ログは、pod内の /usr/src/app/ ディレクトリに関するパーミッションの問題を示している。
トラブルシューティング
起動に失敗した node-app-deployment Pod のトラブルシューティングを行うために、デバッグ Pod を作成する。
[xxxx@sd-roks-01 ~]$ oc debug pod/node-app-deployment-547989c8f5-fg5dk
Starting pod/node-app-deployment-547989c8f5-fg5dk-debug-4gv9p ...
Pod IP: 172.17.13.176
If you don't see a command prompt, try pressing enter.
sh-4.4$
/usr/src/app/ ディレクトリのコンテンツをリストして、パーミッション、所有者、およびグループを確認する。
sh-4.4$ ls -l /usr/src/app/
total 56
-rw-------. 1 root root 748 Mar 11 05:23 Dockerfile
-rw-------. 1 root root 1566 Mar 11 05:23 index.js
drwx------. 1 root root 4096 Mar 11 05:23 node_modules
-rw-------. 1 root root 32042 Mar 11 05:23 package-lock.json
-rw-------. 1 root root 363 Mar 11 05:23 package.json
drwx------. 2 root root 4096 Mar 11 05:23 public
➡ /usr/src/app/配下のファイル・ディレクトリは、rootユーザーにパーミッションを付与するが、rootグループにはパーミッションを付与しない。
コンテナー内のユーザーの UID と GID を確認する。
sh-4.4$ whoami
1001140000
sh-4.4$ id
uid=1001140000(1001140000) gid=0(root) groups=0(root),1001140000
➡ ユーザーは非特権の non-root ユーザーであり、rootグループに属している。つまり /usr/src/app/ ディレクトリへのアクセス権はない。
デバッグ pod から抜ける。
sh-4.4$ exit
exit
Removing debug pod ...
問題の解決
/usr/src/app/ ディレクトリにコピーされるディレクトリ・ファイルのパーミッションを変更して、再度 Dockerfileからコンテナイメージをビルドして、node-app-deployment Deploymentのマニフェストに記載のコンテナレジストリにpushする。
# ベースイメージの取得
FROM registry.access.redhat.com/ubi8/nodejs-18:latest
# node.jsの利用に必要なパッケージ(ランタイム)をインストール
# RUNの後にlinuxコマンドをそのまま記載します
# コンテナ起動した後に遷移させる作業ディレクトリの設定
WORKDIR /usr/src/app
RUN npm install express mysql2 body-parser dotenv
# ホストで作成済みのnode.jsアプリケーションの動作に必要なソースコード(一部)をコンテナ内の作業ディレクトリに転送
# package.jsonは、`npm init`すると作成されるものです。
COPY . .
# コンテナを立ち上げた後に発動して欲しいコマンドを記載。
CMD ["node", "index.js"]
パーミッションの変更
アプリケーションのソースコード及びDockerfileが格納されている simple-stateful-app/source 配下のファイル・ディレクトリのパーミッションを変更する。
- ファイル:600 --> 660
- ディレクトリ:700 --> 770
[xxxx@sd-roks-01 source]$ ll
total 48
-rw-------. 1 xxxx xxxx 748 Jun 16 06:12 Dockerfile
-rw-------. 1 xxxx xxxx 1566 Jun 16 06:12 index.js
drwx------. 77 xxxx xxxx 4096 Jun 16 06:12 node_modules
-rw-------. 1 xxxx xxxx 363 Jun 16 06:12 package.json
-rw-------. 1 xxxx xxxx 32042 Jun 16 06:12 package-lock.json
drwx------. 2 xxxx xxxx 24 Jun 16 06:12 public
[xxxx@sd-roks-01 source]$ find -type d | xargs chmod 770
[xxxx@sd-roks-01 source]$ find -type f | xargs chmod 660
[xxxx@sd-roks-01 source]$ ll
total 48
-rw-rw----. 1 xxxx xxxx 748 Jun 16 06:12 Dockerfile
-rw-rw----. 1 xxxx xxxx 1566 Jun 16 06:12 index.js
drwxrwx---. 77 xxxx xxxx 4096 Jun 16 06:12 node_modules
-rw-rw----. 1 xxxx xxxx 363 Jun 16 06:12 package.json
-rw-rw----. 1 xxxx xxxx 32042 Jun 16 06:12 package-lock.json
drwxrwx---. 2 xxxx xxxx 24 Jun 16 06:12 public
コンテナイメージのビルド
[xxxx@sd-roks-01 simple-stateful-app-source]$ podman build -t jp.icr.io/cr-roks/simple-stateful-app:latest ./source
STEP 1/5: FROM registry.access.redhat.com/ubi8/nodejs-18:latest
Trying to pull registry.access.redhat.com/ubi8/nodejs-18:latest...
Getting image source signatures
Checking if image destination supports signatures
Copying blob 71932181dd87 done
Copying blob 88bc639c408f done
Copying blob 388ff50e70f6 done
Copying config 30a95955bc done
Writing manifest to image destination
Storing signatures
STEP 2/5: WORKDIR /usr/src/app
--> 9fc160ad579
STEP 3/5: RUN npm install express mysql2 body-parser dotenv
added 79 packages in 7s
16 packages are looking for funding
run `npm fund` for details
--> 6273601f4f0
STEP 4/5: COPY . .
--> 7d959c54c36
STEP 5/5: CMD ["node", "index.js"]
COMMIT jp.icr.io/cr-roks/simple-stateful-app:latest
--> 2996211f540
Successfully tagged jp.icr.io/cr-roks/simple-stateful-app:latest
2996211f54052304d5433bed8be89993be020e03cc6d54ee156201e83f462f46
該当のコンテナイメージがあることを確認する。
[xxxx@sd-roks-01 simple-stateful-app-source]$ podman images
REPOSITORY
TAG IMAGE ID CREATED SIZE
jp.icr.io/cr-roks/simple-stateful-app latest 2996211f5405 41 seconds ago 630 MB
コンテナイメージのレジストリへのpush
IBM Cloud Container Registryにイメージをpushする。
[xxxx@sd-roks-01 simple-stateful-app-source]$ podman push jp.icr.io/cr-roks/simple-stateful-app:latest
Getting image source signatures
Copying blob db15b4bfb557 done
Copying blob e3b2c38f1987 done
Copying blob f2e1923daba0 done
Copying blob 623fdec90b8f done
Copying blob 9c2ba69ce15b done
Copying config 2996211f54 done
Writing manifest to image destination
Storing signatures
イメージがpushされたことを確認する。
[xxxx@sd-roks-01 simple-stateful-app]$ ibmcloud cr image-list
Listing images...
Repository Tag Digest Namespace Created
Size Security status
jp.icr.io/cr-roks/simple-stateful-app latest c5d19dfca137 cr-roks 20 minutes ago 231 MB -
OK
問題が解決したことの確認
podの状態の再確認
デプロイした node-app-deployment podの状態を確認する。
[xxxx@sd-roks-01 simple-stateful-app-source]$ oc get pod
NAME READY STATUS RESTARTS AGE
mysql-67d4b5d9bc-hw7d5 1/1 Running 0 21h
node-app-deployment-74c4f5857b-jv767 1/1 Running 195 (40m ago) 16h
node-app-deployment-74c4f5857b-tphmc 1/1 Running 0 34m
node-app-deployment-74c4f5857b-zkcrg 1/1 Running 208 (39m ago) 17h
➡ ステータスが Running に変わっていることがわかる。
pod内のディレクトリ・ファイルのパーミッションの再確認
デバッグ Pod を作成する。
[xxxx@sd-roks-01 simple-stateful-app-source]$ oc debug pod/node-app-deployment-74c4f5857b-jv767
Starting pod/node-app-deployment-74c4f5857b-jv767-debug-l7bfw ...
Pod IP: 172.17.13.161
If you don't see a command prompt, try pressing enter.
sh-4.4$
/usr/src/app/ ディレクトリのコンテンツをリストして、パーミッション、所有者、およびグループを確認する。
sh-4.4$ ls -l /usr/src/app/
total 52
-rw-rw----. 1 root root 748 Jun 18 06:59 Dockerfile
-rw-rw----. 1 root root 1566 Jun 18 07:00 index.js
drwxrwx---. 1 root root 4096 Jun 18 07:00 node_modules
-rw-rw----. 1 root root 32042 Jun 18 07:01 package-lock.json
-rw-rw----. 1 root root 363 Jun 18 07:01 package.json
drwxrwx---. 2 root root 4096 Jun 18 07:01 public
➡ /usr/src/app/配下のファイル・ディレクトリは、rootグループにもパーミッションを付与することを確認できる。
コンテナー内のユーザーの UID と GID を確認する。
sh-4.4$ whoami
1001140000
sh-4.4$ id
uid=1001140000(1001140000) gid=0(root) groups=0(root),1001140000
➡ ユーザーは非特権の non-root ユーザーであり、rootグループに属している。つまり /usr/src/app/ ディレクトリへのアクセス権がある。
デバッグ pod から抜ける。
sh-4.4$ exit
exit
Removing debug pod ...
以上で、無事に問題が解決したことを確認できた。