hidemium's blog

日々学んだことをアウトプットする。

Nested KVMでCockpitを試してみる

homelabでKVMとCockpitを利用するケースを見かけるようになったため、ESXi上にNestedでKVMを構築し、Cockpitで仮想マシンの構築ができるか試してみました。

構成

  • vCenter 8.0U3
  • ESXi 8.0U3
  • Ubuntu 22.04 (Nested KVM)

KVMとは

KVM (Kernel-based Virtual Machine) は、Linuxカーネルに組み込まれた仮想化技術です。KVM を使用すると、Linux をハイパーバイザーとして機能させることができます。

Cockpitとは

Cockpitは、Webベースのサーバー管理インターフェイスで、コマンドラインを使わなくてもサーバーの状態を確認したり、設定変更を行うことができます。また、KVM仮想マシンも管理することができます。

Nested KVMのセットアップ

Nested KVMを用意するために、Ubuntuをインストールした仮想マシンを用意します。

KVM用のUbuntu VM仮想マシンの設定の編集を開き、CPUのハードウェア仮想化にチェックを入れておきます。

ネットワークはまずはVLANを指定したポートグループを接続しておきます。

インストール

以下で必要なパッケージをインストールしておきます。

$ sudo apt install -y qemu-kvm virt-manager libvirt-daemon-system \
   virtinst libvirt-clients bridge-utils

libvirtdのサービスを有効化しておきます。

$ sudo systemctl enable --now libvirtd
$ sudo systemctl start libvirtd
$ sudo systemctl status libvirtd

kvmグループにユーザを追加します。

$ sudo usermod -aG kvm $USER
$ sudo usermod -aG libvirt $USER

Cockpitをインストールします。

$ sudo  apt install cockpit
$ sudo systemctl start cockpit
$ sudo systemctl status cockpit

http://<IPアドレス>:9090 でCockpitのWeb UIにアクセスできることを確認します。

Cockpitはネットワーク管理にNetworkManagerを使っており、Cockpit上でネットワーク設定をするために、ネットワーク管理をNetworkManagerに変更します。

$ sudo vi /etc/netplan/01-custom-config.yaml 
network:
  renderer: NetworkManager
  version: 2
$ sudo netplan apply

systemd-networkd-wait-onlineのサービスがfailedになるため、サービスを停止させておきます。

$ systemctl status systemd-networkd-wait-online
× systemd-networkd-wait-online.service - Wait for Network to be Configured
     Loaded: loaded (/lib/systemd/system/systemd-networkd-wait-online.service; enabled; vendor preset: disabled)
     Active: failed (Result: exit-code) 
       Docs: man:systemd-networkd-wait-online.service(8)
    Process: 885 ExecStart=/lib/systemd/systemd-networkd-wait-online (code=exited, status=1/FAILURE)
   Main PID: 885 (code=exited, status=1/FAILURE)
        CPU: 6ms
$ sudo systemctl stop systemd-networkd-wait-online.service
$ sudo systemctl disable systemd-networkd-wait-online.service
$ sudo systemctl mask systemd-networkd-wait-online.service

こちらの状態で、ログインし、ネットワークはこのように表示されます。

初期状態では、 virbr0 というブリッジが作成されており、libvirt が自動的に仮想ネットワークを用意してくれています。

$ brctl show
bridge name     bridge id               STP enabled     interfaces
virbr0          8000.5254001f7a81       yes
$ nmcli device show virbr0
GENERAL.DEVICE:                         virbr0
GENERAL.TYPE:                           bridge
GENERAL.HWADDR:                         52:54:00:1F:7A:81
GENERAL.MTU:                            1500
GENERAL.STATE:                          100 (connected (externally))
GENERAL.CONNECTION:                     virbr0
GENERAL.CON-PATH:                       /org/freedesktop/NetworkManager/ActiveConnection/1
IP4.ADDRESS[1]:                         192.168.122.1/24
IP4.GATEWAY:                            --
IP4.ROUTE[1]:                           dst = 192.168.122.0/24, nh = 0.0.0.0, mt = 0
IP6.GATEWAY:                            --

外部ネットワークへの通信は iptables によってNAT、DHCPはdnsmasqが行ってそうです。

$ sudo iptables -t nat -nvL
Chain LIBVIRT_PRT (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    1    40 RETURN     all  --  *      *       192.168.122.0/24     224.0.0.0/24        
    0     0 RETURN     all  --  *      *       192.168.122.0/24     255.255.255.255     
    0     0 MASQUERADE  tcp  --  *      *       192.168.122.0/24    !192.168.122.0/24     masq ports: 1024-65535
    0     0 MASQUERADE  udp  --  *      *       192.168.122.0/24    !192.168.122.0/24     masq ports: 1024-65535
    0     0 MASQUERADE  all  --  *      *       192.168.122.0/24    !192.168.122.0/24
$ ps aux | grep dnsmasq
libvirt+  107607  0.0  0.0  10084   388 ?        S    21:11   0:00 /usr/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf --leasefile-ro --dhcp-script=/usr/lib/libvirt/libvirt_leaseshelper

仮想マシンを管理するために、以下のインストールを行います。

$ sudo apt install cockpit-machines

こちらの状態で、仮想マシンを作成してみます。

デフォルトで、ネットワークはdefaultのvirbr0に接続するような設定になっています。

ネットワークの構成を図にすると以下のようになります。

┌─────────────────────┌──────────────┐───────────────────────┐
│     KVM Host        │    ens192    │                       │
│                     └───────┬──────┘                       │
│                             │ NAT(iptables)                │
│                     ┌───────┴──────┐                       │
│                     │    virbr0    │ 192.168.122.1/24      │
│                     └───────┬──────┘                       │
│                             │ interface member             │
│                     ┌───────┴──────┐                       │
│                     │     vnet0    │ 192.168.122.2/24      │
│                     └───────┬──────┘                       │
│                     ┌───────┴──────┐                       │
│                     │      VM      │                       │
│                     └──────────────┘                       │
└────────────────────────────────────────────────────────────┘                                            

VLANトランクへの変更

外部からのアクセスや、ネットワークをNested ESXiライクに変更するために、Nested KVMのポートグループをVLANトランクに変更します。

Cockpitのネットワークの設定で、bridge50 という名前でブリッジを追加します。

VLANの追加で、親に bridge50 を指定し、VLAN IDに50、名前を vlan.50 を入れ追加します。

仮想マシンのネットワークの設定を、インターフェイス形式を Bridge to LAN 、ソースを bridge50 に変更します。

この状態で、同じVLANからsshで接続できることを確認します。

ネットワークの構成を図にすると以下のようになります。

                      ┌──────────────┐                        
                      │  Trunk VLAN  │                        
                      └───────┬──────┘                        
┌─────────────────────┌───────┴──────┐───────────────────────┐
│     KVM Host        │    ens192    │                       │
│                     └───────┬──────┘                       │
│                             │                              │
│                     ┌───────┴──────┐                       │
│                     │    vlan.50   │ VLANID 50             │
│                     └───────┬──────┘                       │
│                             │ interface member             │
│                     ┌───────┴──────┐                       │
│                     │    brige50   │                       │
│                     └───────┬──────┘                       │
│                             │ interface member             │
│                     ┌───────┴──────┐                       │
│                     │     vnet0    │                       │
│                     └───────┬──────┘                       │
│                     ┌───────┴──────┐                       │
│                     │      VM      │                       │
│                     └──────────────┘                       │
└────────────────────────────────────────────────────────────┘

現在の構成だと、KVMホストごとにネットワークの設定を行っているため、KVMホスト1台や数台に管理にはCockpitが向いていそうに見えます。

参考

NSX-TでSLAACによるIPv6アドレスの自動生成を試してみる

前回、vSphere環境をIPv6での構築を試してみました。今回は、NSX-TでSLAACによるIPv6アドレスの払い出しを試してみました。

hidemium.hatenablog.com

構成

  • vCenter 8.0U2
  • ESXi 8.0U2 (Nested ESXi)
  • NSX-T 4.1
  • HoLを利用

SLAACとは

IPv4で動的にIPアドレスを払い出す方法として、DHCPがあります。

IPv6では、SLAAC(StateLess Address AutoConfiguration、ステートレスアドレス自動設定、「すらっく」と発音)と、DHCPv6の2種類の方法があります。

SLAACは、RFC 4862で定義されているIPv6アドレスの自動生成方法です。

SLAACの処理の流れは以下のようになっています。

  1. リンクローカルアドレスの自動生成
  2. 重複アドレスの検知(DAD、Dupulicate Address Detection)
  3. グローバルアドレスの自動生成

少し細かく書くと以下のようになっています。

  1. ホストは、仮のリンクローカルアドレスを生成し、Neighbor Solicitation(NS)メッセージを送信し、DADにより重複がないことを確認し、NAメッセージを送りリンクローカルアドレスを確定します。
  2. ホストはIPv6アドレスを自動的に設定するため、Router Solicitation(RS)メッセージを送信し、ネットワーク情報を要求します。
  3. ルーターはRouter Advertisement(RA)メッセージを返し、ネットワークプレフィックスやアドレス構成方法(SLAACの有効化など)を通知します。
  4. ホストはRAメッセージから受け取ったプレフィックスに基づき、インターフェース識別子(MACアドレスを使ってModified EUI-64形式で生成)を結合し、仮のグローバルアドレスを生成します。
  5. NSメッセージを送信して、DADにより重複がないことを確認し、NAメッセージを送りグローバルアドレスを確定します。
  6. 必要に応じてRAメッセージのオプションとしてDNS情報の配送や、Stateless DHCPv6を使用し追加のネットワーク設定を取得します。

利用するアドレスの検討

前回と同様、全体のネットワークに /48、VLAN用に /56 、VLANIDごとに /64 のプレフィックスを割り当てを行います。

NSX-T環境向けに以下のアドレスの割り当てを行います。

2001:db8:1000:2000:1::/64 LS-IPv6セグメント

NSX-Tの設定

NSX-Tは、デフォルトではIPv6が無効化されているため、有効化しておきます。

Global Networking Configで、L3 Forwarding Modeを IPv4 and IPv6 に変更して保存します。

ADD TIER-1 GATEWAYボタンをクリックし、T1-GW という名前でTier-1 Gatewayを追加してみます。

Edge Clusterに、デプロイしているEdge Clusterを設定します。

Route Advertisementに、 All Connected Segments & Service Pors をオンにして保存します。

ND Profileは、 SLAAC with DNS through RA のモードで試すため、default のままにしておきます。

また、DAD Profileは、 default のままにしておきます。

Settings>Networking Profiles>IPv6>ND Profilesには、default という名前のプロファイルがすでに登録されています。 デフォルトの ND プロファイルは、 SLAAC with DNS through RA のモードで設定され、ドメイン名やDNS パラメータは設定されません。

モードには、以下の種類があります。

mode 説明
SLAAC with DNS Through RA アドレスとDNS情報はルーターアドバタイズメントメッセージによって生成されます。
SLAAC with DNS Through DHCP アドレスはルーターアドバタイズメントメッセージで生成され、DNS情報はDHCPサーバーによって生成されます。
DHCP with Address and DNS through DHCP アドレスとDNS情報はDHCPサーバーによって生成されます。
SLAAC with Address and DNS through DHCP アドレスとDNS情報はDHCPサーバーによって生成されます。このオプションはNSX Edgeでのみサポートされ、KVMホストやESXiホストではサポートされていません。

Settings>Networking Profiles>IPv6>DAD Profilesには、default という名前のプロファイルがすでに登録されています。

モードには、以下の種類があります。

mode 説明
Loose 重複アドレスの通知は受信しますが、検出された重複アドレスに対して何も行いません。
Strict 重複アドレスの通知を受信します。重複アドレスは使用不能になります。

ADD SEGMENTボタンをクリックし、 LS-IPv6 という名前でセグメントを追加してみます。

Connected Gatewayに、 T1-GW を設定し、Toranspot Zoneに作成済みのToranspot Zoneを指定します。

Subnetに 2001:db8:1000:2000:1::/64 を割り当てます。

動作確認

テストVMでSLAACでIPv6のアドレスが自動生成されるか確認してみます。

VMネットワークアダプターに、 LS-IPv6 セグメントを割り当てます。

systemdにはデフォルトでSLAACのRAが有効となっているので、特に追加設定は不要です。

IPv6アドレスが設定されていることを確認します。

$ systemctl restart systemd-network
$ ip a
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UpP group defalut qlen 1000
    link/ether 00:50:56:99:d4:ff brd ff:ff:ff:ff:ff:ff
    inet6 2001:db8:1000:2000:250:56ff:fe99:d4ff/64 scope global dynamic mngtmpaddr noprefixroute
       valid_lft 2591687sec preferred_lft 604487sec
    inet6 fe80::250:56ff:fe99:d4ff/64 scope link
       valid_lft forever preferred_lft forever

もう一台テストVMを用意して、pingを実行してみます。

$ ping 2001:db8:1000:2000:250:56ff:fe99:5520
PING 2001:db8:1000:2000:250:56ff:fe99:5520(2001:db8:1000:2000:250:56ff:fe99:5520) 56 data bytes
64 bytes from 2001:db8:1000:2000:250:56ff:fe99:5520:  icmp_seq=1 ttl=64 time=1.22 ms
64 bytes from 2001:db8:1000:2000:250:56ff:fe99:5520:  icmp_seq=1 ttl=64 time=0.634 ms

参考

IPv6でvSphere環境の構築を試してみる

vSphere環境を構築する場合は、通常はIPv4が一般的ですが、IPv6に対応しているため、どの程度IPv6で構築が可能なのか試してみました。

構成

  • vCenter 7.0U3
  • ESXi 7.0U3 (Nested ESXi)
  • Windows 2019 (AD)

IPv6とは

IPv6は、IPv4の後継のインターネットプロトコルで。128ビットのアドレス空間を持つことで、膨大な数のデバイスにユニークなアドレスを割り当て可能です。

アドレスの構造は、 2001:0DB8:AC10:FE01:0000:0000:0000:0001 といった8つの16ビットセグメントで構成され、コロン「:」で区切られた形式を採用しています。0が連続する場合は、 :: でまとめることができ、 2001:DB8:AC10:FE01::1 とも表現できます。

アドレスの種類は、ユニキャスト、マルチキャスト、エニーキャストが利用できます。ブロードキャストが廃止され、マルチキャストが利用されています。

IPアドレスの自動設定は、IPv4ではDHCPv4でしたが、ネットワーク内でデバイスが自動的にIPアドレスを取得するStateless Address Autoconfiguration (SLAAC) 、DHCPv6が利用されています。

IPv4IPv6が共存する期間をサポートするための共存技術(デュアルスタック、トランスレーター、トンネリングなど)が考案されています。IPv4IPv6の共存環境で、DNSからAレコードとAAAAレコードが返ってきた場合、IPv4IPv6のどちらで接続するかはアプリケーションの実装にゆだねられており、先に接続に成功したほうのプロトコルで接続するHappy Eyeballsという仕組みが標準化されてます。

IPv6のアドレス体系について

IPv6のアドレス体系として、基本的な分類は以下のようなものがあります。

アドレス範囲 アドレスの種類 用途や特徴
::/128 未定義アドレス バイスIPアドレスをまだ取得していない状態を示す。
::1/128 ループバックアドレス 自デバイス内で通信を行うためのアドレス。
2000::/3 グローバルユニキャスト インターネットで利用されるグローバルなアドレス。
fc00::/7 ユニークローカルアドレス(ULA) プライベートネットワーク内で利用するアドレス。fc00::/8は将来の定義用で、fd00::/8を利用。
fe80::/10 リンクローカルアドレス 同一リンク内の通信に限定される自動生成アドレス。
ff00::/8 マルチキャストアドレス 複数のノードに同時に通信を送るためのアドレス。
2001:db8::/32 ドキュメント用アドレス ドキュメントや学習資料で使用される予約済みアドレス。

リンクローカルアドレスは、同一リンク内でのみ使われますが、EUI-64というフォーマットを使用して自動生成されます。

48ビットのMACアドレスをもとに、16ビットのFFFEを追加して、64ビットに拡張することで、インターフェイスIDを生成します。プレフィックス長は/64になります。

仮想マシンを起動すると、インターフェイスに、自身のMACアドレスをもとに fe80:: から始まるIPアドレスが自動生成されます。

$ ip a
2: ens192: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:50:56:88:6e:22 brd ff:ff:ff:ff:ff:ff
    altname enp11s0
    inet6 fe80::250:56ff:fe88:6e22/64 scope link 
       valid_lft forever preferred_lft forever

利用するアドレスの検討

vSphere環境で利用するアドレスについて検討してみます。

homelabの利用で、インターネットには出ないことを想定して、ユニークローカルアドレスを利用します。

ユニークローカルアドレスは、fc00::/8は将来の定義用のため、fd00::/8の範囲で利用します。

全体のネットワークに /48、VLAN用に /56 、VLANIDごとに /64プレフィックスを割り当てを行います。/48から/56のプレフィックスが256個、/56から/64のプレフィックスが256個作成することができます。(/48から/64は65,536個作成できます。)

fd00::/8はグローバルにユニークであることが保証されませんが、RFC 4193に従い40ビットのランダムなグローバル識別子をつけて利用します。

  • 2001:db8:1000::/48 ネットワーク全体
  • 2001:db8:1000:1000::/56 VLAN用
  • 2001:db8:1000:1000:1::/64 VLANID: 1の場合

vSphere環境向けに以下のアドレスの割り当てを行います。

  • 2001:db8:1000:1000:1::5/64 vCenter
  • 2001:db8:1000:1000:1::11/64 Nested ESXi
  • 2001:db8:1000:1000:1::20/64 Windows 2019 (AD)
  • 2001:db8:1000:1000:1::30/64 Ubuntu 22.04

ADの設定

今回の環境は他のネットワークからリーチャビリティのない環境となっており、

vCenterのデプロイと操作、DNSサーバーを利用するために、WindowsサーバーにADをインストールしておきます。

DNSマネージャーにvCenterとESXiのDNSレコードをAAAAレコードで登録しておきます。

vCenterのデプロイ

お手軽にインストールするために、WindowsGUI版のインストーラーでデプロイを行います。

vCenter Serverのデプロイターゲットは、デプロイ先のESXiの情報を入力しておきます。

デプロイサイズはTinyを指定し、データストアの選択ではThin Disk Modeにチェックを入れておきます。

ネットワークの設定では、以下のように設定します。

ブラウザから、IPアドレスで接続できるか確認してみます。

IPv6で接続する場合は、ブラウザに https://[2001:db8:1000:1000:1::5][] をつけて入力します。

はじめにの画面が表示されることを確認します。

FQDNで接続できるか、ブラウザに https://vCenter FQDN を入力しはじめにの画面が表示されることを確認します。

各種設定の確認

VAMIの設定画面がどのようになっているか、 https://vCenter FQDN:5480 にログインして確認してみます。

IPv6のアドレスのみ表示されることが分かります。

続いて、vCenterにログインし、ESXiホストの登録を行い、ESXiの管理画面がどのようになっているか確認してみます。

IPv4は設定せずに、IPv6を固定で設定した場合は、固定のIPアドレスと、リンクローカルアドレスの2つが表示されます。

ゲストOSでのDualStack

vSphere環境でのIPv6化ができたため、ゲストOSにUbuntuを利用し、ゲストOSからvCenterへの接続ができるか試してみます。

netplanに以下の設定を行います。

$ vi /etc/netplan/50-cloud-init.yaml 
network:
    ethernets:
        ens192:
            dhcp4: true
            addresses:
              - 2001:db8:1000:1000:1::30/64
            nameservers:
              addresses:
                - 2001:db8:1000:1000:1::20
            routes:
              - to: default
                via: 2001:db8:1000:1000:1::1
    version: 2

vCenterにアクセス可能か確認します。

$ ping 2001:db8:1000:1000:1::5
PING 2001:db8:1000:1000:1::5(2001:db8:1000:1000:1::5) 56 data bytes
64 bytes from 2001:db8:1000:1000:1::5: icmp_seq=1 ttl=63 time=0.830 ms
64 bytes from 2001:db8:1000:1000:1::5: icmp_seq=2 ttl=63 time=0.898 ms

参考

Visual Studio CodeでContinueとOllamaを使ったAIアシスト機能を試してみる

Visual Studio CodeGitHub Copilotを使うと、生成AIによるコード開発のアシストを行ってくれます。GitHub Copilotは有料のため、ローカル環境で似た環境を構築できないか試してみました。

構成

  • Windows 10 (Visual Studio Code)
    • Continue v0.8.60
  • Ubuntu 22.04 (開発サーバー)
    • Remote Developmentの接続先
  • Ubuntu 22.04 (LLMサーバー)
    • provider: ollama 0.5.1
    • model: llama3.2 3B

ContinueやOllamaについて

Continueは、GitHub Copilotのようにコーディング支援を行ってくれるVisual Studio Code拡張機能になります。

Continueは、コーディング支援に利用するAIは、OpenAIやGemini、Llama、Claudeといったサービスや、ローカルにデプロイしたOllamaやLM Studioなど様々なものを利用できそうでした。

ローカルの場合、Llama 3.1 8Bがおすすめなようです。

Ollamaは、ローカル環境で大規模言語モデルを簡単に使用できるツールになります。

コマンドの使用感はdockerと似ているような気がします。

Ollamaのインストール

Ollamaのインストールを行ってみます。sudo権限を付与したユーザーで実行します。

GPUカードがないため、CPU-only modeで実行されます。

$ curl -fsSL https://ollama.com/install.sh | sh
>>> Installing ollama to /usr/local
>>> Downloading Linux amd64 bundle
######################################################################## 100.0%
>>> Creating ollama user...
>>> Adding ollama user to render group...
>>> Adding ollama user to video group...
>>> Adding current user to ollama group...
>>> Creating ollama systemd service...
>>> Enabling and starting ollama service...
Created symlink /etc/systemd/system/default.target.wants/ollama.service → /etc/systemd/system/ollama.service.
>>> The Ollama API is now available at 127.0.0.1:11434.
>>> Install complete. Run "ollama" from the command line.
WARNING: No NVIDIA/AMD GPU detected. Ollama will run in CPU-only mode.

サービスが起動しているか確認してみます。

$ systemctl status ollama.service 
● ollama.service - Ollama Service
     Loaded: loaded (/etc/systemd/system/ollama.service; enabled; vendor preset: enabled)
     Active: active (running) since Sat 2024-12-07 12:39:59 JST; 5min ago
   Main PID: 116500 (ollama)
      Tasks: 11 (limit: 4557)
     Memory: 60.9M
        CPU: 723ms
     CGroup: /system.slice/ollama.service
             └─116500 /usr/local/bin/ollama serve

Llama 3.2の3B modelsをダウンロードしてみます。ファイルサイズは2GBです。

llama3.2

$ ollama pull llama3.2
pulling manifest
pulling dde5aa3fc5ff... 100%
:
verifying sha256 digest 
writing manifest 
success

試しに、手元でllamaを動かしてみます。

すごく遅いですが、応答が返ってきます。

1vCPU、4GBメモリの仮想マシンで試しましたが、稼働中はCPU使用率は100%で張り付いていましたが、何とか動いてそうでした。

$ ollama run llama3.2
>>> こんにちは。
こんにちは!どういたして今日ならなにかお話したいことあるかな?

APIからもコールしてみます。こちらも何とか返ってきます。

$ curl http://localhost:11434/api/chat -d '{
  "model": "llama3.2",
  "stream": false,
  "messages": [
    { "role": "user", "content": "こんにちは。" }
  ]
}'
{"model":"llama3.2","created_at":"2024-12-07T05:52:36.252910007Z","message":{"role":"assistant","content":"こんにちは!どういたしまして?どんなことについて話したいですか?"},"done_reason":"stop","done":true,"total_duration":5682315698,"load_duration":33451469,"prompt_eval_count":27,"prompt_eval_duration":321000000,"eval_count":17,"eval_duration":5326000000}

Ollamaのローカルマシン以外からのアクセス許可

ローカルマシン以外からもアクセスできるようにunitファイルを編集して、再起動します。

sudo vi /etc/systemd/system/ollama.service
[Service]
+ Environment="OLLAMA_HOST=0.0.0.0"
+ Environment="OLLAMA_ORIGINS=192.168.*"
sudo systemctl daemon-reload
sudo systemctl restart ollama

WindowsPowerShellから実行できるか試してみます。なぜか、PowerShellだと、英語でメッセージが返ってきました。

> Invoke-RestMethod -Uri "http://10.0.50.60:11434/api/chat" -Method Post -Body '{
  "model": "llama3.2",
  "stream": false,
  "messages": [
    { "role": "user", "content": "こんにちは。" }
  ]
}'

model                : llama3.2
created_at           : 2024-12-07T06:27:11.907561159Z
message              : @{role=assistant; content=It looks like you're using a mysterious and colorful character to repr
                       esent your question! Unfortunately, I need a bit more information or context to understand what
                       you're asking about. Could you please rephrase your question in plain text?}
done_reason          : stop
done                 : True
total_duration       : 15139379661
load_duration        : 29423999
prompt_eval_count    : 27
prompt_eval_duration : 323000000
eval_count           : 46
eval_duration        : 14786000000

Continueの設定

Continueをインストールしてみます。

Visual Studio Code拡張機能からContinueを選択し、Installをクリックします。

左側のバーにContinueのアイコンが表示されます。

歯車マークをクリックすると、config.jsonが開くため、modelsの個所に以下のように追加します。

  "models": [
    {
      "title": "Llama 3.2",
      "provider": "ollama",
      "model": "llama3.2",
      "apiBase": "http://IPアドレス:11434"
    }
  ],

チャットのコンソールにコメントを追加すると、 HTTP 500 Internal Server Error from http://IPアドレス:11434/api/chat というえらが返ってきたため、ログを確認すると、以下のエラーがあり、メモリが不足しているようです。

{"error":"model requires more system memory (7.3 GiB) than is available (4.9 GiB)"}

仮想マシンのスペックを2vCPU、8GBメモリに拡張すると動くようになりました。

ちなみに、llama3.1:8bを利用しようすると、10.8GB以上のメモリを求められます。

{"error":"model requires more system memory (10.8 GiB) than is available (7.8 GiB)"}

使い方

コードを選択して、Ctrl+Lでチャット欄にコードを張りつけることができます。

レスポンスはあまり早くはないですが、サンプル的なコードについての説明を求めると、割と分かりやすい解説を返してくれました。

Context selectionという機能があり、 @ をつけてソースコードのファイルを指定したり、ターミナルの情報をベースにして回答をしてくれます。

Autocompleteの設定

続いて、Autocomplete機能を試してみます。

Autocompleteを試すために、qwen2.5-coderの1.5B modelsをダウンロードしてみます。ファイルサイズは986MBです。

qwen2.5-coder

$ ollama pull qwen2.5-coder:1.5b

Continueのconfig.jsonに以下のように追加します。

  "tabAutocompleteModel": {
    "title": "Qwen2.5-Coder 1.5B",
    "model": "qwen2.5-coder:1.5b",
    "provider": "ollama",
    "apiBase": "http://IPアドレス:11434"
  },

コードを選択して、右クリックすると、Continueのメニューが表示され、いくつか機能が表示されます。

試しに、コメントを生成してみると、関数の説明を追加してくれました。

ただし、この処理は重かったのか、CPUがしばらく100%張り付きで稼働していました。

/**
 * Creates a new book in the database.
 *
 * @param ctx The context of the operation.
 * @param book The request to create a new book.
 * @return A new book schema if successful, or an error if not.
 */
func (u *BookUseCase) Create(ctx context.Context, book *book.CreateRequest) (*book.Schema, error) {
    bookID, err := u.bookRepo.Create(ctx, book)
    if err != nil {
        return nil, err
    }
    bookFound, err := u.bookRepo.Read(ctx, bookID)
    if err != nil {
        return nil, err
    }
    return bookFound, err
}

参考

Ollamaを動かすにあたり、最近の動向がまとまっており参考になりました。

踏み台サーバーを経由したUbuntuへのリモートデスクトップ接続

前回、踏み台サーバーを経由してVisual Studio CodeのRemote Developmentで接続する方法を記事にしました。今回は、踏み台サーバーを経由してリモートデスクトップ接続について書いてみようと思います。

hidemium.hatenablog.com

構成

  • Windows 10 (接続元)
  • Ubuntu 22.04 (踏み台サーバー)
    • public IP: 192.168.100.100/24
    • internal IP: 192.168.10.100/24
  • Ubuntu 22.04 (接続先)
    • internal IP: 192.168.10.201/24

接続先のサーバーのセットアップ

接続のサーバーは、Ubuntu Desktopとしてインストールを行います。

isoファイルからインストールするか、Ubuntu ServerからUbuntu Desktopのインストールを行いますが、今回はisoファイルからインストールを行いました。

リモートデスクトップ接続の接続先となるサーバーのインターフェイスにプライベートネットワークのIPアドレスを設定しておきます。

踏み台サーバーのインターフェイスの設定は前回と同じです。

xrdpのインストール

Ubuntuには、SettingsにSharing(共有)という機能があります。

こちらの機能は、RDPを使った画面をミラーする機能になり、Windowsリモートデスクトップ接続とは異なり、サーバーにコンソール接続してログインしたい状態ではないと操作ができません。

ログアウトした状態で、リモートデスクトップ接続を行いたい場合は、xrdpを利用します。

Ubuntu 24.04では、リモートログイン機能が入りましたが、Ubuntu 22.04ではないため、リモートデスクトップ接続できるようにxrdp をインストールします。

sudo apt install xrdp

xrdpを使用する場合、X Window SystemXorgが利用され、起動処理の中でGNOMEのデスクトップ環境が選択されて起動します。

  1. ユーザーがRDPクライアントでXorgセッションで接続。
  2. xrdpがstartwm.shを実行。
  3. startwm.sh内で、/etc/X11/Xsessionが呼び出される。
  4. /etc/X11/XsessionがGNOMEデスクトップ環境を起動し、リモートデスクトップGUIを提供。

デスクトップ環境を.xsessionrcで設定することも可能ですが、デフォルトで /usr/share/xsessions/ubuntsu-xorg.desktopGNOMEが指定されてそうでした。

ssh configの設定

接続先の踏み台サーバーが用意できたため、Local Port ForwardingでRDP接続できるように、以下のように C:\Users\User Name\.ssh/config ファイルを編集します。

Host bustion
  HostName 192.168.100.100
  User UserName
  ForwardAgent yes
  LocalForward 13389 192.168.10.201:3389

Windowsからのリモートデスクトップ接続

PowerShellsshコマンドで接続して、Local Port Forwardingができるか確認してみます。

ssh先で何もしないため、-Nオプションを指定しておきます。

ssh -N bustion

Windowsリモートデスクトップ接続を起動し、コンピューターに localhost:13389 を入力します。

接続をするとxrdpのログイン画面が表示されるため、SessionにXorg、usernameとpasswordにUbuntuのログイン情報を入力します。

ログインすると、Dockが表示されず、右上にActivitiesのみ表示されます。

gnome-extensionsコマンドでdockを有効にすると、左側にDockが表示されるようになります。

$ gnome-extensions list
[email protected]
[email protected]
[email protected]
$ gnome-extensinos enable [email protected]

踏み台サーバーを経由したVisual Studio CodeのRemote Developmentの設定

以前、Visual Studio CodeのRemote Developmentの設定方法について記事にしました。今回は、踏み台サーバーを経由して開発環境に接続する方法を記載してみようと思います。

hidemium.hatenablog.com

構成

  • Windows 10 (Visual Studio Code)
  • Ubuntu 22.04 (踏み台サーバー)
    • public IP: 192.168.100.100/24
    • internal IP: 192.168.10.100/24
  • Ubuntu 22.04 (接続先)
    • internal IP: 192.168.10.200/24

踏み台サーバーと接続先のサーバーの設定

踏み台サーバーのインターフェイスに外部接続用のIPアドレスとプライベートネットワークのIPアドレスを設定しておきます。

Visual Studio Codeの接続先となるサーバーのインターフェイスにプライベートネットワークのIPアドレスを設定しておきます。

それぞれにWindowsで生成した公開鍵を設定しておきます。

公開鍵の設定は、cloud-initを使うとログインせずに設定できます。

hidemium.hatenablog.com

ssh configの設定

以下のように C:\Users\User Name\.ssh/config ファイルを編集します。

Host bustion
  HostName 192.168.100.100
  User UserName
  ForwardAgent yes

Host dev
  HostName 192.168.10.200
  User UserName
  ProxyJump bustion

ForwardAgentは、秘密鍵を踏み台サーバーに置かずにアクセスするためのssh agent機能を使う設定となります。

ProxyJumpは、踏み台サーバーを経由してターゲットサーバーにssh接続するオプションで、以前はProxyCommandが使われていましたが、ProxyJumpはシンプルに記述ができます。

Visual Studio CodeのRemote Developmentの設定 (Windows 10側)

右下のグリーンの >< ボタンをクリックすると、メニューが表示されるため、 Connect to Host をクリックします。

ssh configに設定した踏み台サーバーを経由した接続先のホスト名をクリックします。

platformに Linux を選択します。

vscodeのファイルがインストールされて、接続が完了します。

Local Port Forwardingの利用

Local Port Forwardingを利用して、8000番のポートに届いた通信を踏み台サーバーを経由して接続先のサーバーの8000番ポートへ転送ができるか試してみます。

通信を確認するために、pythonでWebサーバーを起動してみます。

python3 -m http.server 8000

以下のように C:\Users\User Name\.ssh/config ファイルを編集すると、Local Port Forwardingができます。

Host bustion
  HostName 192.168.100.100
  User UserName
  ForwardAgent yes

Host dev
  HostName 192.168.10.200
  User UserName
  ProxyJump bustion
  LocalForward 8000 localhost:8000

PowerShellsshコマンドで接続して、Local Port Forwardingができるか確認してみます。

ssh先で何もしないため、-Nオプションを指定しておきます。

ssh -N dev

ブラウザからlocalhost:8000にアクセスし接続できることを確認します。

python3 -m http.server 8000
127.0.0.1 - - [01/Dec/2024 00:26:49] "GET / HTTP/1.1" 200 -

また、vscodeでもLocal Port Forwardingができます。

ssh configでLocalForwardの設定を戻し、vscodePORTS を開いて、 Forward a Port ボタンをクリックします。

同様に、ブラウザからlocalhost:8000にアクセスし接続できることを確認します。

Windowsのインストール後にVMware 準仮想化 SCSI コントローラに変更する

Windows Serverにて、LSI Logic SASでインストール後にVMware 準仮想化 SCSI コントローラ(PVSCSI)に変更を行った場合、OSの起動ができくなることがあり、起動ができるようにするためいくつか試してみたので書いてみようと思います。

構成

  • vCenter 8.0U3
  • ESXi 8.0U3
  • Windows Server 2019

一般的な方法

通常、LSI Logic SASでインストール後にVMware 準仮想化 SCSI コントローラ(PVSCSI)に変更を行った場合には、以下のKBが公開されています。

VMware 準仮想化 SCSI (PVSCSI) アダプタを使用するようにディスクに構成する

流れとしては、以下のようになります。

  1. VMware Toolsをインストールする
  2. 一時的な利用のため新しい SCSI コントローラ (PVSCSI) を作成する
  3. 一時的な利用のため新しい1GB ディスク (SCSI 1:0) を作成する
  4. 仮想マシンをパワーオンし、ディスク管理で新しい1GBのディスクが見えていることを確認する
  5. シャットダウンする
  6. 一時的なSCSIコントローラー(PVSCSI)とディスク(SCSI 1:0)を削除する
  7. 既存のSCSIコントローラーをLSI Logic SASからVMware 準仮想化に変更する
  8. 仮想マシンをパワーオンし、OSが起動することを確認する

こちらの方法だと確実に起動することが可能ですが、一時的なSCSIコントローラーやディスクを作成したり、電源のオンオフが必要だったりします。

試した方法

まずは、LSI Logic SASでインストール後にVMware 準仮想化 SCSI コントローラ(PVSCSI)に変更を行った場合にどのような挙動になるか確認します。

何度も試せるように、スナップショットを取得しておきます。

  1. シャットダウン
  2. 既存のSCSIコントローラーをLSI Logic SASからVMware 準仮想化に変更する
  3. 仮想マシンをパワーオン

上記の操作を行うと、OSが起動時に以下のinaccessible boot deviceというメッセージが表示され、OSの起動に失敗します。

PVSCSIを認識させる

この状態だと、OSの起動時にPVSCSIのドライバがロードされないため、ローカルディスクの読み取りに失敗します。

PVSCSIドライバを差し込んでみます。

まずは、VMware Toolsのisoファイルを入手し、以下のように仮想マシンにアタッチします。

  1. シャットダウン
  2. 既存のSCSIコントローラーをLSI Logic SASからVMware 準仮想化に変更する
  3. CD/DVDドライブにデータストアISOファイルからisoファイルとして指定する
  4. 仮想マシンをパワーオン

同じようにOSの起動に失敗します。

しばらくすると、キーボード選択に遷移します。

キーボードを選択すると、トラブルシューティングの画面に遷移します。

トラブルシューティングのメニューの中でコマンドプロンプトを選択します。

コマンドプロンプトを選択すると、「Windows Recovery Environment(WinRE)」と呼ばれるリカバリー用OSのコンソールに入れます。

WinREの操作

以下のコマンドで、PVSCSIドライバの読み込みを行います。

drvload "D:\Program Files\VMware\VMware Tools\Drivers\pvscsi\Win8\amd64\pvscsi.inf"

以下のコマンドでCドライブが読み取りできるか確認します。

PVSCSIドライバがロードできていれば表示されます。

diskpart
DISKPART> list volume

展開イメージのサービスと管理 (DISM) サービス コマンドを使って、Windows イメージにドライバーを追加します。

WinREにPVSCSIドライブをロードし、Cドライブを見えるようにし、WinREからWindowsイメージにPVSCSIのドライバをインストールする流れです。

dism /image:C:\ /add-driver /driver:"D:\Program Files\VMware\VMware Tools\Drivers\pvscsi\Win8\amd64\pvscsi.inf"

ドライバの追加ができたため、WinREを終了します。

exit

PCの電源を切るを選択して、シャットダウンします。

その後、仮想マシンをパワーオンし、OSが起動できることを確認します。

Windowsのブートについて

Windowsのブートについては、以下の詳細が書かれています。

Windows のブートに関する問題のトラブルシューティング - Windows Client | Microsoft Learn

  1. プレブート: PC のファームウェアが電源オンセルフ テスト (POST) を開始し、ファームウェア設定を読み込みます。 このプロセスは、有効なシステム ディスクが検出されると終了します。 ファームウェアはマスター ブート レコード (MBR) を読み取り、Windows Boot Manager を起動します。
  2. Windows Boot Manager: Windows Boot Manager は、Windows ブート パーティションWindows ローダー (Winload.exe) を検索して起動します。
  3. Windows オペレーティング システム ローダー: Windows カーネルを起動するために必要となる重要なドライバーが読み込まれ、実行に向けてカーネルが開始します。
  4. Windows NT OS カーネル: カーネルはシステム レジストリ ハイブと、BOOT_STARTとしてマークされているその他のドライバーをメモリに読み込みます。
  5. カーネルは、システム セッションを初期化するセッション マネージャー プロセス (Smss.exe) にコントロールを渡し、BOOT_START としてマークされていないデバイスとドライバーを読み込んで起動します。

エラー画面を見比べると、kernel phaseのWindows NT OS Kernelが実行されているところで問題起きていることが分かります。

さらに、以下に詳細のトラブルシューティング方法についても書かれています。

エラー 7B またはInaccessible_Boot_Deviceのトラブルシューティングを停止する - Windows Client | Microsoft Learn

VMware Toolsを事前にインストールしていると、以下のコマンドでPVSCSIのドライバーがあることは見えますが、カーネル起動時にもともと接続していたLSI Logic SASのデバイスとドライバーを読み込もうとするが、デバイスがPVSCSIが接続されているため、ドライバーが正しく読み込まれないのかもしれません。

dism /image:C:\ /get-drivers
公開名:oem5.inf
元のファイル名:pvscsi.inf
インボックス:いいえ
クラス名:SCSIAdapter
プロバイダー名:VMware, Inc.
日付:2022/11/30
バージョン:1.3.26.0

Linuxの場合

Linuxの場合は、LinuxカーネルにinboxドライバにPVSCSIやvmxnet3のドライバが組み込まれているため、インストール後にPVSCSIに切り替えを行っても起動することができます。

VMware support for Linux inbox VMware drivers

The vmw_pvscsi driver with version 1.0.1.0-k was accepted upstream in the 2.6.33 kernel on December 2009. Ubuntu introduced distribution of the 1.0.1.0-k version of this driver in the 10.04 release.

Ubuntu 22.04でPVSCSIのドライバの情報を見てみると、inboxドライバとして組み込まれていることが分かります。

$ modinfo vmw_pvscsi
filename:       /lib/modules/5.15.0-125-generic/kernel/drivers/scsi/vmw_pvscsi.ko
version:        1.0.7.0-k
license:        GPL
author:         VMware, Inc.
description:    VMware PVSCSI driver
srcversion:     9ECE9CD6D5195A698354F86
alias:          pci:v000015ADd000007C0sv*sd*bc*sc*i*
depends:        
retpoline:      Y
intree:         Y
name:           vmw_pvscsi
vermagic:       5.15.0-125-generic SMP mod_unload modversions