OpenShift × Unity-Robotics-Hubトラブル集

## はじめに
下記ブログの取り組み時に遭遇したトラブルと、その対処法・不明点が多かったのでまとめた

https://qiita.com/yoshi1006/items/2f54d49958e55c2b5ab5

## トラブルと対処集

### トラブル1. 【解決済】 `crc setup`失敗
#### 状況
- 初回の`crc setup`時にエラーで処理完了しない
- コンソール出力は下記の通り
    ```console
    $ crc setup
    CRC is constantly improving and we would like to know more about usage (more details at https://developers.redhat.com/article/tool-data-collection)
    Your preference can be changed manually if desired using 'crc config set consent-telemetry <yes/no>'
    Would you like to contribute anonymous usage statistics? [y/N]: y
    Thanks for helping us! You can disable telemetry with the command 'crc config set consent-telemetry no'.
    INFO Using bundle path /home/ttnt1013/.crc/cache/crc_libvirt_4.14.1_amd64.crcbundle 
    INFO Checking if running as non-root              
    INFO Checking if running inside WSL2              
    INFO Checking if crc-admin-helper executable is cached 
    INFO Caching crc-admin-helper executable          
    INFO Using root access: Changing ownership of /home/ttnt1013/.crc/bin/crc-admin-helper-linux 
    [sudo] password for ttnt1013: 
    INFO Using root access: Setting suid for /home/ttnt1013/.crc/bin/crc-admin-helper-linux 
    INFO Checking if running on a supported CPU architecture 
    INFO Checking if crc executable symlink exists    
    INFO Creating symlink for crc executable          
    INFO Checking minimum RAM requirements            
    INFO Checking if Virtualization is enabled        
    INFO Checking if KVM is enabled                   
    INFO Checking if libvirt is installed             
    INFO Installing libvirt service and dependencies  
    INFO Using root access: Installing virtualization packages 
    INFO Checking if user is part of libvirt group    
    INFO Checking if active user/process is currently part of the libvirt group 
    You need to logout, re-login, and run crc setup again before the user is effectively a member of the 'libvirt' group.
    ```
#### 対処法
- PCを再起動して再度`crc setup`を実施（ログアウトしてログインしただけだと同じように失敗した）

### トラブル2. 【解決済】 `docker push`時にエラー
#### 状況
- DockerfileをビルドしてDocker Hubにpushする際に、下記のエラーで完了できなかった
    ```console
    denied: requested access to the resource is denied
    ```
#### 対処法
- 下記コマンドでログインし直すとpushが完了できた
    ```console
    $ docker logout
    $ docker login
   ```
   
### トラブル3. 【解決済】 Podmanのインストールができない
#### 状況
- （今回は最終的に結局Docker hubを利用したが）Docker hubではなくOpenShiftのImage Registryを利用しようとしていたときに、コンテナランタイムをDockerで行うと設定がややこしい？っぽかったのでpodmanに変えようとした
- podmanを`apt-get`でインストールしようとすると下記のエラーが出た
    ```console
    $ sudo apt-get -y install podman
    Reading package lists... Done
    Building dependency tree       
    Reading state information... Done
    E: Unable to locate package podman
    ```
#### 対処法
- 下記のコマンドを実行することでインストールを完了できた
    ```console
    $ sudo apt update
    $ source /etc/os-release
    $ echo "deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/ /" | sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
    $ curl -L "https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/Release.key" | sudo apt-key add -
    $ sudo apt update
    $ sudo apt -y install podman
    ```
- 参考
    - https://devcoops.com/install-podman-on-ubuntu-20-04/

### トラブル4. 【解決済】 コンテナの状態がCrashLoopBackになりPodが立ち上がらない
#### 状況
- Pod立ち上げ後、**CrashLoopBack**の状態になり、コンソールに下記のエラーが表示される
    - [ここ](https://qiita.com/yoshi1006/items/2f54d49958e55c2b5ab5#ros%E3%82%A2%E3%83%97%E3%83%AA%E8%B5%B7%E5%8B%95)の工程で発生したエラー
    ```
    0/1 nodes are available: 1 Insufficient memory. preemption: 0/1 nodes are available: 1 No preemption victims found for incoming pod..
    ```
#### 対処法
- 当初、OpenShift立ち上げ時に`crc start`を実行していたが、リソースを確保するためのオプションを追記した
- 念の為、`crc cleanup`、`crc setup`することでまっさらな状態にしておいた
    ```console
    $ crc stop
    $ crc cleanup
    $ crc setup
    $ crc start -c 6 -m 14000
    ```

### トラブル5. 【動いたが謎が残る】 OpenShift上でROSのコマンドが動かない
本件に関しては、試した経緯を共有したい
#### Dockerでテスト動作：成功
- 下記のDockerfileを用意（リポジトリに上がってるものそのまま）
    ```Dockerfile
    FROM ros:melodic-ros-base

    RUN sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys F42ED6FBAB17C654
    
    RUN sudo apt-get update && sudo apt-get install -y vim iputils-ping net-tools python-pip ros-melodic-robot-state-publisher ros-melodic-moveit ros-melodic-rosbridge-suite ros-melodic-joy ros-melodic-ros-control ros-melodic-ros-controllers ros-melodic-tf2-web-republisher dos2unix
    
    RUN sudo -H pip install rospkg jsonpickle
    
    ENV ROS_WORKSPACE=/catkin_ws
    
    # Copy each directory explicitly to avoid workspace cruft
    COPY ./ROS/src/moveit_msgs $ROS_WORKSPACE/src/moveit_msgs
    COPY ./ROS/src/niryo_moveit $ROS_WORKSPACE/src/niryo_moveit
    COPY ./ROS/src/niryo_one_ros $ROS_WORKSPACE/src/niryo_one_ros
    COPY ./ROS/src/niryo_one_urdf $ROS_WORKSPACE/src/niryo_one_urdf
    COPY ./ROS/src/ros_tcp_endpoint $ROS_WORKSPACE/src/ros_tcp_endpoint
    
    COPY ./docker/set-up-workspace /setup.sh
    COPY docker/tutorial /
    
    RUN /bin/bash -c "find $ROS_WORKSPACE -type f -print0 | xargs -0 dos2unix"
    
    RUN dos2unix /tutorial && dos2unix /setup.sh && chmod +x /setup.sh && /setup.sh && rm /setup.sh
    
    WORKDIR $ROS_WORKSPACE
    
    # making sure the file modes are executable
    RUN chmod +x src/niryo_moveit/scripts/*.py
    
    ENTRYPOINT ["/tutorial"]
    ```
- ビルド後、下記コマンドでコンテナ実行・ログイン
    ```console
    $ docker run -it --rm -p 10000:10000 <docker-user>/pick-and-place:latest /bin/bash
    ```
- コンテナ内で下記コマンドを実行し、Unityと連携できることを確認
    ```console
    root@d56a1d919195:/catkin_ws# roslaunch niryo_moveit part_3.launch
    ```
#### テスト実行したコンテナをOpenShiftのPodで実行：失敗→Dockerfile修正
- [この流れ](https://qiita.com/yoshi1006/items/2f54d49958e55c2b5ab5#ros%E3%82%A2%E3%83%97%E3%83%AA%E8%B5%B7%E5%8B%95)でDeploymentを作成すると、PodのstatusがCompleted（→CrashLoopBack→Completed→CrashLoopBack→…）になり何も起こらない
- OpenShiftのコンソール上でTerminalに入れないので、処理が終わってしまわないようにDockerfileを下記のように修正
    ```Dockerfile
    FROM ros:melodic-ros-base

    RUN sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys F42ED6FBAB17C654
    
    RUN sudo apt-get update && sudo apt-get install -y vim iputils-ping net-tools python-pip ros-melodic-robot-state-publisher ros-melodic-moveit ros-melodic-rosbridge-suite ros-melodic-joy ros-melodic-ros-control ros-melodic-ros-controllers ros-melodic-tf2-web-republisher dos2unix
    
    RUN sudo -H pip install rospkg jsonpickle
    
    ENV ROS_WORKSPACE=/catkin_ws
    
    # Copy each directory explicitly to avoid workspace cruft
    COPY ./ROS/src/moveit_msgs $ROS_WORKSPACE/src/moveit_msgs
    COPY ./ROS/src/niryo_moveit $ROS_WORKSPACE/src/niryo_moveit
    COPY ./ROS/src/niryo_one_ros $ROS_WORKSPACE/src/niryo_one_ros
    COPY ./ROS/src/niryo_one_urdf $ROS_WORKSPACE/src/niryo_one_urdf
    COPY ./ROS/src/ros_tcp_endpoint $ROS_WORKSPACE/src/ros_tcp_endpoint
    
    COPY ./docker/set-up-workspace /setup.sh
    COPY docker/tutorial /
    
    RUN /bin/bash -c "find $ROS_WORKSPACE -type f -print0 | xargs -0 dos2unix"
    
    RUN dos2unix /tutorial && dos2unix /setup.sh && chmod +x /setup.sh && /setup.sh && rm /setup.sh
    
    WORKDIR $ROS_WORKSPACE
    
    # making sure the file modes are executable
    RUN chmod +x src/niryo_moveit/scripts/*.py
    
    CMD exec /bin/bash -c "trap: TERM INT; sleep infinity & wait" # 追記
    
    ENTRYPOINT ["/tutorial"]
    ```
- 上記のDockerfileをビルドしてDocker hubにpushした

#### Sleep処理を入れて起動しっぱなしにしたコンテナをOpenShiftのPodで実行：失敗→コンテナの実行ユーザーをrootに変更
- 前節と同様の流れでDeploymentを作成すると、PodのstatusがRunningで継続されるようになり、Terminalからコンテナ操作が可能になった
- 下記のROSコマンドを実行するとエラー発生
    ```console
    $ roslaunch niryo_moveit part_3.launch
    sh: 1: roslaunch: not found
    ```
- ユーザーidと環境変数$PATHを調べる
    ```console
    $ id
    uid=1000660000(1000660000) gid=0(root) groups=0(root),1000660000
    $ echo $PATH
    /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    ```
    - Dockerでテスト成功したときの状況は下記のとおり
        ```console
        root@cbb16a77366a:/catkin_ws# id
        uid=0(root) gid=0(root) groups=0(root)
        root@cbb16a77366a:/catkin_ws# echo $PATH
       /opt/ros/melodic/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
        ```
    - @ydo さんにPodはランダムなIDのユーザーが割り振られることを教えていただきました
    
- 試しにOpenShiftのPodで$PATHを追加してみたが、動作しない
    ```console
    $ export PATH=$PATH:/opt/ros/melodic/bin      
    $ echo $PATH
    /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/ros/melodic/bin
    $ roslaunch niryo_moveit part_3.launch
    Traceback (most recent call last):
      File "/opt/ros/melodic/bin/roslaunch", line 34, in <module>
        import roslaunch
    ImportError: No module named roslaunch
    ```
- rootユーザーにしたらどうかと思い、DeploymentのYAMLの148行目のsecurityContextに下記のように値を設定
    ```yaml
    ...
    securityContext: 
        runAsUser: 0
    ...
    ```
#### Sleep処理を入れて起動しっぱなしにしたコンテナをOpenShiftのPodで実行、rootでログイン：失敗→Dockerfileに実行したい処理も書く
- DeploymentのYAML修正後にできたPodのTerminalからユーザーidと環境変数$PATHを調べる
    ```console
    # id
    uid=0(root) gid=0(root) groups=0(root)
    # echo $PATH
    /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    ```
    - rootユーザーにはなっているが、パスが通っていない
- $PATHを追加してみたが、動作しない
    ```console
    # export PATH=$PATH:/opt/ros/melodic/bin
    # roslaunch niryo_moveit part_3.launch
    Traceback (most recent call last):
      File "/opt/ros/melodic/bin/roslaunch", line 34, in <module>
        import roslaunch
    ImportError: No module named roslaunch
    ```
- 問題の検討がつかなかったので、DockerfileのCMDから`roslaunch niryo_moveit part_3.launch`を実行するように変更する
    ```Dockerfile
    FROM ros:melodic-ros-base

    RUN sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys F42ED6FBAB17C654
    
    RUN sudo apt-get update && sudo apt-get install -y vim iputils-ping net-tools python-pip ros-melodic-robot-state-publisher ros-melodic-moveit ros-melodic-rosbridge-suite ros-melodic-joy ros-melodic-ros-control ros-melodic-ros-controllers ros-melodic-tf2-web-republisher dos2unix
    
    RUN sudo -H pip install rospkg jsonpickle
    
    ENV ROS_WORKSPACE=/catkin_ws
    
    # Copy each directory explicitly to avoid workspace cruft
    COPY ./ROS/src/moveit_msgs $ROS_WORKSPACE/src/moveit_msgs
    COPY ./ROS/src/niryo_moveit $ROS_WORKSPACE/src/niryo_moveit
    COPY ./ROS/src/niryo_one_ros $ROS_WORKSPACE/src/niryo_one_ros
    COPY ./ROS/src/niryo_one_urdf $ROS_WORKSPACE/src/niryo_one_urdf
    COPY ./ROS/src/ros_tcp_endpoint $ROS_WORKSPACE/src/ros_tcp_endpoint
    
    COPY ./docker/set-up-workspace /setup.sh
    COPY docker/tutorial /
    
    RUN /bin/bash -c "find $ROS_WORKSPACE -type f -print0 | xargs -0 dos2unix"
    
    RUN dos2unix /tutorial && dos2unix /setup.sh && chmod +x /setup.sh && /setup.sh && rm /setup.sh
    
    WORKDIR $ROS_WORKSPACE
    
    # making sure the file modes are executable
    RUN chmod +x src/niryo_moveit/scripts/*.py
    
    CMD exec /bin/bash -c "roslaunch niryo_moveit part_3.launch"
    
    ENTRYPOINT ["/tutorial"]
    ```

#### ROSコマンドを実行するコンテナをOpenShiftのPodで起動、rootでログイン：失敗→defaultのSCCを変更
- Deploymentを作成すると、PodのStatusがError→CrashLoopBackとなる
- Logは下記の通り
    ```
    (略)
    ...
     * /robot_description_planning/joint_limits/joint_3/max_velocity: 2.0
     * /robot_description_planning/joint_limits/joint_4/has_acceleration_No handlers could be found for logger "roslaunch"
    [31m[master] ERROR: unable to configure logging [unable to create directory for log file [/.ros/log/70dd233a-a091-11ee-9ccb-0a580ad9016e].
    Please check permissions.][0m
    [31mRLException: Roslaunch got a 'No such file or directory' error while attempting to run:
    
    rosmaster --core -p 11311 -w 3
    
    Please make sure that all the executables in this command exist and have
    executable permission. This is often caused by a bad launch-prefix.[0m
    [31mThe traceback for the exception was written to the log file[0m
    limits: True
     * /robot_description_planning/joint_limits/joint_4/has_velocity_limits: True
     * /robot_description_planning/joint_limits/joint_4/max_acceleration: 1.3
     * /robot_description_planning/joint_limits/joint_4/max_velocity: 2.0
     * /robot_description_planning/joint_limits/joint_5/has_acceleration_limits: True
     * /robot_description_planning/joint_limits/joint_5/has_velocity_limits: True
     * /robot_description_planning/joint_limits/joint_5/max_acceleration: 1.8
     * /robot_description_planning/joint_limits/joint_5/max_velocity: 2.5
     * /robot_description_planning/joint_limits/joint_6/has_acceleration_limits: True
     * /robot_description_planning/joint_limits/joint_6/has_velocity_limits: True
     * /robot_description_planning/joint_limits/joint_6/max_acceleration: 2.6
     * /robot_description_planning/joint_limits/joint_6/max_velocity: 3.14
     * /robot_description_semantic: <?xml version="1....
     * /robot_description_tf2: <?xml version="1....
     * /rosdistro: melodic
     * /rosversion: 1.14.13
     * /server_endpoint/tcp_ip: 0.0.0.0
     * /server_endpoint/tcp_port: 10000
    
    NODES
      /
        controller_spawner (controller_manager/spawner)
        move_group (moveit_ros_move_group/move_group)
        mover (niryo_moveit/mover.py)
        niryo_one_driver (niryo_one_driver/niryo_one_driver)
        robot_state_publisher (robot_state_publisher/robot_state_publisher)
        server_endpoint (ros_tcp_endpoint/default_server_endpoint.py)
    
    auto-starting new master
    [master] killing on exit
    ```
- DeploymentのYAMLに`runAsUser: 0`を追加
    - 上記と同様のStatus、Logが出る
- @ydo さんよりdefaultのSCC（Security Context Constrains）を変更してはどうかというアドバイスをいただき、試してみた（ただしこれは普通はしない設定とのこと）
    - ホストPCで下記のコマンドを実行
    ```console
    $ eval $(crc oc-env)
    $ oc login -u kubeadmin -p xxxxxxxx
    Login successful.
    
    You have access to 67 projects, the list has been suppressed. You can list all projects with 'oc projects'
    
    Using project "unity-test".
    $ oc adm policy add-scc-to-user privileged -z default
    clusterrole.rbac.authorization.k8s.io/system:openshift:scc:privileged added: "default"

    ```
- PodのStatusが継続的にRunning、Logを見ると所望のコマンドが正常に実行されていることを確認できた
    ```console
    [ INFO] [1703233271.214119380]: MoveGroup context using planning plugin ompl_interface/OMPLPlanner
    [ INFO] [1703233271.214145419]: MoveGroup context initialization complete
    You can start planning now!
    ```

## 謎
- Docker container上のrootとPodのrootの実行状況が違う？
- SCCについて全般的に知識が薄い
    - 参考：https://rheb.hatenablog.com/entry/scc-process-on-openshift-202008
- トラブル5の問題は、結局何をどう設定するのがよかったのか？