ConcurrentReal-Time-Logo

リアルタイムテクニカルドキュメント 最終更新 2024.03.01


目次

[images/hand.right] RedHawk8.4.x TigerVNC/リアルタイムコンテナへ直接ネットワークloginする方法(HTML) 2024.03.01

[images/hand.right] RedHawk8.4.x TigerVNC/>Nvidia HeadLess構成/リアルタイムコンテナへ直接ネットワークloginする方法(HTML) 2024.03.01


[images/hand.right] RedHawk8.4.x TigerVNC/リアルタイムコンテナへ直接ネットワークloginする方法 2024.03.01

RedHawk8.4.nで確認した、TigerVNC-Container動作確認の手順を下記に示します。

ベアメタル側設定

  • コンテナ内で使用する(同じ)VNC ユーザーをベアメタル側にも登録する必要があります。
  • 使用するコンテナイメージは完全なコンテナである必要があります (architect8 で image.tar を作成)
  • コンテナに直接ログインするには、プロミスキャスをサポートするイーサネット カードが必要です。
  • DHCP をコンテナに配布するには、ベアメタル側で追加のサービスを開始する必要があります。

参考:Setting container network modes

  1. ベアメタル側にvncuserを作成(ログインしないのでパスワード不要)
  2. 
    # useradd -m vncuser1
    # fgrep vncuser /etc/passwd
    vncuser1:x:1000:1000::/home/vncuser1:/bin/bash 
    
    
    :以下必要なユーザー分登録する

  3. ベアメタル側と同様にDHCPを利用する場合には、下記のio.podman.dhcp.socketの設定と起動が必要
  4. 
    # cat /usr/lib/systemd/system/io.podman.dhcp.socket
    [Unit]
    Description=DHCP Client for CNI
    
    [Socket]
    ListenStream=%t/cni/dhcp.sock
    SocketMode=0600
    
    [Install]
    WantedBy=sockets.target
    
    # cat /usr/lib/systemd/system/io.podman.dhcp.service
    [Unit]
    Description=DHCP Client CNI Service
    Requires=io.podman.dhcp.socket
    After=io.podman.dhcp.socket
    
    [Service]
    Type=simple
    ExecStart=/usr/libexec/cni/dhcp daemon
    TimeoutStopSec=30
    KillMode=process
    
    [Install]
    WantedBy=multi-user.target
    Also=io.podman.dhcp.socket
    
    # systemctl --now enable io.podman.dhcp.socket
    Created symlink /etc/systemd/system/sockets.target.wants/io.podman.dhcp.socket → /usr/lib/systemd/system/io.podman.dhcp.socket
    
    

  5. podmanサーバを起動し、コンテナを作成する。(image.tarは、ベアメタルのイメージと同じ)
  6. 
    # zcat /run/media/root/ARCHITECT/image.?? > /home/image.tar
    # systemctl enable podman.service
    # systemctl start podman.service
    # podman import /home/images.tar podman-vncserver
    Getting image source signatures
    Copying blob cb6f6cc1216d done 
    Copying config 8dae0cc79e done 
    Writing manifest to image destination
    Storing signatures
    8dae0cc79e8baa24fbace2f469c8c2b504661b945f5cbbe253c6b63b0ec1890c
    # podman images
    REPOSITORY                  TAG         IMAGE ID      CREATED            SIZE
    localhost/podman-vncserver  base        65f0d0d1e098  About an hour ago  17.9 GB
    
    

  7. ベアメタル側のIPアドレス構成を確認する(デバイス名:eth0,IPアドレス172.16.0.1/24を確認)
  8. 
    # ip a
    1: lo:  mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
       link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
       inet 127.0.0.1/8 scope host lo
          valid_lft forever preferred_lft forever
       inet6 ::1/128 scope host
          valid_lft forever preferred_lft forever
    2: eth0:  mtu 1500 qdisc fq_codel state UP group default qlen 1000
       link/ether **:**:**:**:**:** brd ff:ff:ff:ff:ff:ff
       inet 172.16.0.1/24 brd 172.16.0.255 scope global dynamic noprefixroute eth0
          valid_lft 601336sec preferred_lft 601336sec
       inet6 ****::****:****:****:****/64 scope link 
          valid_lft forever preferred_lft forever
    3: virbr0:  mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    	:
    4: virbr0-nic:  mtu 1500 qdisc fq_codel master virbr0 state DOWN group default qlen 1000
    	:
    5: cni-podman0:  mtu 1500 qdisc noqueue state DOWN group default qlen 1000
       link/ether **:**:**:**:**:** brd ff:ff:ff:ff:ff:ff
       inet 10.88.0.1/16 brd 10.88.255.255 scope global cni-podman0
          valid_lft forever preferred_lft forever
    	:
    
    

  9. ベアメタル側のIPアドレス構成に従って、公開するIPアドレスをPODMANサーバに設定する
  10. 
    # podman network create -d macvlan --subnet 172.16.0.1/24 -o parent=eth0 pub_net
    /etc/cni/net.d/pub_net.conflist
    # podman network ls
    NETWORK ID    NAME        VERSION     PLUGINS
    2f259bab93aa  podman      0.4.0       bridge,portmap,firewall,tuning
    426c6774f385  pub_net     0.4.0       macvlan
    
    

  11. インポートしたコンテナイメージから実行コンテナを作成する
  12. 
    # podman run -it -device=/dev/:/dev/ --storage-opt size=200G --name=redhawk-8.4.8.bash --privileged=true -v /home/:/home/ -v /var/run/dbus/:/var/run/dbus/ -v /tmp/:/tmp/ -v /run/user/0/:/run/user/0/  -v /var/run/cups/cups.sock:/var/run/cups/cup.sock podman-vncserver:base /usr/bin/bash
    6283f993c8fc9b9b565b4ff8a41edb40003db2dbda298456ad876be492dfa0cb
    
    
    注意:-vオプションの内容を変更すると動作しない可能性がある。

  13. 作成した実行コンテナにpub_netを追加する。
  14. 
    # podman network connect pub_net redhawk-8.4.8.bash
    
    

コンテナ側設定

  1. ネットワークpub_netの確認
  2. 
    # podman exec -it redhawk-8.4.8.bash ifconfig -a
    
    または
    
    [inside the container]# ifconfig -a
    eth0: flags=4163  mtu 1500
           inet 10.88.0.1  netmask 255.255.0.0  broadcast 10.88.255.255
           inet6 fe80::b899:3cff:feae:5986  prefixlen 64  scopeid 0x20
           ether **:**:**:**:**:**  txqueuelen 0  (Ethernet)
    	:
    eth1: flags=4163  mtu 1500
           inet 172.16.0.1  netmask 255.255.254.0  broadcast 172.16.0.255
           inet6 ****::**:****:****:***  prefixlen 64  scopeid 0x20
    	:
    
    

  3. コンテナ側にvncuserを作成(ログインするのでパスワード要、コンテナ外にホームディレクトリを見せないように/vncuser_homeを作成している)
  4. 
    [inside the container /]# cat /etc/tigervnc/vncserver.users
    :2=vncuser1
    :3=vncuser2
    :4=vncuser3
    :5=vncuser4
    
    [inside the container /]# mkdir /vncuser_home
    [inside the container /]# useradd -d /vncuser_home/vncuser1 vncuser1
    [inside the container /]# su - vncuser1
    [inside the container /]$ vncpasswd
    Password: vncuser1_password
    Verify: vncuser1_password
    Would you like to enter a view-only password (y/n)? n
    A view-only password is not used
    [inside the container /]$ exit
    
    :
    :以下必要なユーザー分登録する
    :
    
    [inside the container /]# tail -3 /etc/tigervnc/vncserver-config-defaults
    [inside the container /]# Note: change this only when you know what are you doing
    session=gnome
    ZlibLevel=9
    alwaysshared
    
    
    注意:localhostを記述すると外部からログインできなくなる

  5. ログインセッションのシェルスクリプト(/usr/local/bin/start-vncserver)を作成する
  6. 
    [inside the container /]# cat /usr/local/bin/start-vncserver
    #!/bin/bash
    #
    # Container VNC start script
    # Copyright (C) 2024 Concurrent Real Time, Inc.
    # Version 1.0 2024/02/22
    #
    # This software may be used and distributed according to the terms of
    # the GNU General Public License (GPL), version 2, or at your option
    # any later version.
    #
    export DISPLAY=`fgrep $USER /etc/tigervnc/vncserver.users|cut -d= -f1`
    export VNC_SESSION_DNO=`echo "$DISPLAY"|cut -d: -f2`
    export VNC_SESSION_UID=`fgrep $USER /etc/passwd|cut -d: -f3`
    export VNC_SESSION_DIR=`fgrep $USER /etc/passwd|cut -d: -f6`
    export HISTCONTROL=ignoredups
    export HISTSIZE=1000
    export XDG_VTNR=1
    export XDG_SESSION_ID=1
    export XDG_SEAT=seat0
    export XDG_RUNTIME_DIR=/run/user/$SESSION_UID
    export LANG=en_US.UTF-8
    
    LOGFILE="/dev/null"
    myname=$(basename $0)
    usage() {
       echo "Usage: $myname [-l][-c]"
       echo "   -l: Output log to /tmp/.vncserver.?.log"
       echo "   -c: Use GNOME-Classic instead of GNOME"
    }
    #
    # Check /etc/tigervnc/vncserver.users
    #
    if [ -z "$DISPLAY" -o -z "$VNC_SESSION_DNO" ]
    then
        echo "Error : User $USER does not exist in /etc/tigervnc/vncserver.users"
        /usr/bin/bash
        exit 1
    fi
    #
    # Check /etc/passwd
    #
    if [ -z "$VNC_SESSION_UID" ]
    then
        echo "Error : User $USER does not exist in /etc/passwd"
        /usr/bin/bash
        exit 2
    fi
    while getopts "lc" c
    do
       case "$c"
       in
           c) 
            export GNOME_SHELL_SESSION_MODE=classic
            export XDG_CURRENT_DESKTOP=GNOME-Classic:GNOME
        ;;
           l) 
            LOGFILE="/tmp/.vncserver.$VNC_SESSION_DNO.log"
            touch $LOGFILE
        ;;
           \?) usage >&2; exit 1 ;;
       esac
    done
    trap "vncserver -kill $DISPLAY" 0 1 2 3 7 13 15
    #
    # Failsafe
    #
    vncserver -kill $DISPLAY 2>&1 > /dev/null
    if [ -f /tmp/.X$VNC_SESSION_DNO-lock ]
    then
        rm -f /tmp/.X$VNC_SESSION_DNO-lock 
    fi
    if [ -f /tmp/.X11-unix/X$VNC_SESSION_DNO ]
    then
        rm -f /tmp/.X11-unix/X$VNC_SESSION_DNO 
    fi
    echo "--- Vncserver($DISPLAY) session started. ---" | tee -a $LOGFILE
    date | tee -a $LOGFILE
    ifconfig -a | tee -a $LOGFILE
    echo "vncserver -list $DISPLAY" | tee -a $LOGFILE
    vncserver -list $DISPLAY 2>&1 | tee -a $LOGFILE
    while true
    do
        vncserver $DISPLAY -xstartup /etc/X11/xinit/xinitrc -autokill -name $USER -rfbauth $VNC_SESSION_DIR/.vnc/passwd 2>&1 | tee -a $LOGFILE
        vncserver_pid=`vncserver -list 2>&1|tail -1|grep $DISPLAY|awk '{print$2}'`
        while [ -d "/proc/$vncserver_pid"  ]; do
            if [ -f "/proc/$vncserver_pid/status" ]
            then
                State=`fgrep State /proc/$vncserver_pid/status`
                case "$State" in
                    *\(zombie\))
                        echo "$USER($DISPLAY) logged out."| tee -a $LOGFILE
                        break;
                    ;;
                    *)
                        sleep 1;
                    ;;
                esac
            else
                echo "Vncserver($DISPLAY) session has been terminated." | tee -a $LOGFILE
                break;
            fi
        done
        sleep 3
        echo "--- Vncserver($DISPLAY) re-session started. ---" | tee -a $LOGFILE
        date | tee -a $LOGFILE
    done
    
    
    注意:赤字部分が無いと、gnome-shellが起動しない

  7. セッションユーザーをすべて起動するシェルスクリプト/usr/local/bin/start-vncserver-all)を作成する
  8. 
    [inside the container /]# cat /usr/local/bin/start-vncserver-all
    #!/bin/bash
    ifconfig -a|grep inet|grep netmask|grep -v 127.0.0.1
    su - vncuser1 -c "/usr/local/bin/start-vncserver -l 2>&1 > /dev/null &"
    su - vncuser2 -c "/usr/local/bin/start-vncserver -l 2>&1 > /dev/null &"
    su - vncuser3 -c "/usr/local/bin/start-vncserver -l 2>&1 > /dev/null &"
    su - vncuser4 -c "/usr/local/bin/start-vncserver -l 2>&1 > /dev/null &"
    ps -efl|grep start-vncserver|grep vncuser
    
    

  9. 作成したシェルスクリプトに実行権を与える
  10. 
    [inside the container /]# chmod 755 /usr/local/bin/start-vncserver /usr/local/bin/start-vncserver-all
    
    

  11. 試験起動し、動作を確認する(ログは、/tmp/.vncserverディスプレイ番号.logに残るので、ベアメタル側でも、コンテナ側でも確認できる)
  12. 
    [inside the container /]# su - vncuser1 -c "/usr/local/bin/start-vncserver -l 2>&1 > /dev/null &"
    
    

  13. nmapによるポート公開の確認
  14. 
    [inside the container /]# nmap 172.16.0.2 -p 5900-5999
    Starting Nmap 7.70 ( https://nmap.org ) at 2024-02-27 14:45 JST
    Nmap scan report for 172.16.0.2
    Host is up (0.0000030s latency).
    Not shown: 99 closed ports
    PORT     STATE SERVICE
    5902/tcp open  vnc-2
    Nmap done: 1 IP address (1 host up) scanned in 1.52 seconds
    
    

  15. ポートが公開されている場合、下記のように外部ネットワークのWindows等 からログインできます。
  16. 注意:この例では、最初のポート 172.16.0.2:5902 が外部ネットワーク向けに172.16.0.2が公開されていますが、コンテナが動作しているシステムのベアメタル側からは172.16.0.2に向けては接続できません。
    この例では、ベアメタル側からは podman ブリッジアドレスである、10.88.0.1で接続出来ます。

    [vnclogin2.png]
    [vnclogin2.png]

    
    
    

  17. Nvidia HeadLess構成をコンテナ内で利用する。
  18. 1. /etc/X11/headless.conf の作成方法
    以下のシェルをコンテナ内で作成し、実行すると/etc/X11/headless.confが生成されます。
    
    # WindowSize=1024x768
    # BUSID=`nvidia-xconfig --query-gpu-info|grep BusID|awk '{print $4}'`
    # nvidia-xconfig -a --allow-empty-initial-configuration --use-display-device=None --virtual=$WindowSize --busid $BUSID -o /etc/X11/headless.conf
    
    
    /etc/X11/headless.confにInputClassを追加します。
    
    # cat >> /etc/X11/headless.conf << EOL
    #
    # The following definitions are mandatory for Headless VNC connections
    # do not delete
    #
    Section "InputClass"
            Identifier "Ignore libinput"
            Driver "libinput"
            Option "Ignore" "True"
    EndSection
    #
    EOL
    
    
    下記赤字部分のオプションを追記してください。
    
    
    Section "Module"
            Load  "glx"
            Load  "glxserver_nvidia"
            Load  "vnc"
    EndSection
    
    Section "Screen"
        Identifier     "Screen0"
        Device         "Device0"
        Monitor        "Monitor0"
        DefaultDepth    24
        Option         "AllowEmptyInitialConfiguration" "True"
        Option         "UseDisplayDevice" "None"
        SubSection     "Display"
            Virtual     1024 768
            Depth       24
        EndSubSection
        Option "UserPasswdVerifier" "VncAuth"
        Option "PasswordFile" "/root/.vnc/passwd"
    EndSection
    
    
    2. コンテナ内で/etc/X11/headless.conf でXorgを起動

    注意:1 ベアメタル側のデスクトップと共存させるために、-sharevtsが必要です。
    注意:2 -auth $XAUTHORITY を付けないでください
    注意:3 nvidia-smiの結果は、ベアメタル側でしか確認できません。
    
    [inside the container]# Xorg -ardelay 300 -arinterval 25 :2 -sharevts -config /etc/X11/headless.conf
    
    
    3. コンテナ外でvncviewerを起動
    
    # vncviewer -passwd ~/.vnc/passwd --shared 10.88.0.2:2
    
    または
    
    # vncviewer --shared 10.88.0.2:2
    
    
    4. コンテナ内でWindow Managerを起動

    4.1 Open Motif
    
    [inside the container]# DISPLAY=:2 dbus-run-session -- /usr/bin/mwm -multiscreen 
    
    
    4.2 kde plasma
    
    [inside the container]# DISPLAY=:2 dbus-run-session -- /usr/bin/startplasma-x11 
    
    
    4.3 gnome-flashback(metacity)
    注意:
    gnome-flashbackの利用は、標準保守サポート外です。
    かな漢字変換へのiibusエンジン切り替えは、VNC Viewer側のメニュータブからのみ使用出来ます。
    Super+Space入力によるibusエンジンの切り替えは、ベアメタル側のGnomeがアクセプトするため、VNCViewer側では利用できません。
    下記、HeadLessシェルスクリプトをsystemd --userから起動した場合、VNC Viewer上のメニュータブからLogOutするとベアメタル側も同時にログアウトしますが、
    gnome-terminalなどから起動した場合には、シェルスクリプトを終了するだけです。
    
    [inside the container]# export XDG_CURRENT_DESKTOP="GNOME-Flashback:GNOME"
    [inside the container]# DISPLAY=:2 dbus-run-session gnome-session --session=gnome-flashback-metacity 
    
    
    5. HeadLessVNCの作成と実行

    5.1 /usr/local/bin/PodmanHeadLessVNCの作成

    PodmanHeadLessVNCをダウンロードして、/usr/local/bin/PodmanHeadLessVNCにコピーする。

    5.2 /usr/local/bin/PodmanHeadLessVNC の実行権付与
    
    [inside the container]# chmod 755 /usr/local/bin/PodmanHeadLessVNC
    
    
    5.3 /usr/local/bin/PodmanHeadLessVNCの実行例
    
    [inside the container]# PodmanHeadLessVNC :2 gnome-flashback &
    [inside the container]# PodmanHeadLessVNC :3 gnome-flashback &
    [inside the container]# PodmanHeadLessVNC :4 gnome-flashback &
    [inside the container]# PodmanHeadLessVNC :5 gnome-flashback &
    
    
    5.4 コンテナ外部でvncviewerを起動
    
    # vncviewer -passwd ~/.vnc/passwd --shared 10.88.0.2:2
    # vncviewer -passwd ~/.vnc/passwd --shared 10.88.0.2:3
    # vncviewer -passwd ~/.vnc/passwd --shared 10.88.0.2:4
    # vncviewer -passwd ~/.vnc/passwd --shared 10.88.0.2:5
    
    
    5.5 gnome-flashbackを4つ起動した結果



    5.6 ベアメタル側から強制終了させる方法
    
    # podman exec -it redhawk-8.4.8.bash pkill -KILL Xorg
    
    



[back]Back