{"id":2063,"date":"2024-10-11T16:50:03","date_gmt":"2024-10-11T20:50:03","guid":{"rendered":"https:\/\/enterpriseadmins.org\/blog\/?p=2063"},"modified":"2024-10-11T16:50:03","modified_gmt":"2024-10-11T20:50:03","slug":"scaling-your-tests-how-to-set-up-a-vcenter-server-simulator","status":"publish","type":"post","link":"https:\/\/enterpriseadmins.org\/blog\/virtualization\/scaling-your-tests-how-to-set-up-a-vcenter-server-simulator\/","title":{"rendered":"Scaling Your Tests: How to Set Up a vCenter Server Simulator"},"content":{"rendered":"\n<p>I&#8217;ve recently been testing a handful of reporting tools against vCenter Server endpoints.  I have several lab instances for various major releases, which allow me to test a wide range of configurations.  However, there are some tests that are hard to simulate, like what if a cluster has 100 hosts, or one host has 200 VMs?  <\/p>\n\n\n\n<p>Years ago I remember stumbling on a vCenter Server simulator.  I didn&#8217;t have a specific need for it at the time but with this recent testing I checked, and the tool still exists and is actively maintained here: <a href=\"https:\/\/github.com\/vmware\/govmomi\/blob\/main\/vcsim\/README.md\">https:\/\/github.com\/vmware\/govmomi\/blob\/main\/vcsim\/README.md<\/a>.  There is even a container image available.  This article will show how to create a single VM that can help simulate many vCenter Servers for our various reporting requirements.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Server setup<\/h2>\n\n\n\n<p>I started with an Ubuntu 24.04 virtual machine (deployed from a template previously created with Packer, as described in <a href=\"https:\/\/enterpriseadmins.org\/blog\/scripting\/ubuntu-24-04-packer-and-vcenter-server-customization-specifications\/\">this previous post<\/a>).  I then installed docker compose and make a few configuration changes to make docker a bit easier to work with.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># install docker compose, add our active directory user &amp; root to the docker group\nsudo apt install docker-compose-v2\nsudo usermod -aG docker ${USER}\nsudo usermod -aG docker root\n# Log off\/on for new group membership to become effective\n\n# create a folder for some of our configs, make the docker group owner of that folder\nsudo mkdir \/data\nsudo chgrp docker \/data\nsudo chmod g+srw -R \/data \n\n# configure docker to not overlap network ranges and make ranges smaller than default\necho '{\"default-address-pools\":&#91;{\"base\":\"172.17.0.0\/16\",\"size\":26}]}' | sudo tee --append \/etc\/docker\/daemon.json\nsudo systemctl restart docker\n\n# create a folder for our simulator \nmkdir vcsim\ncd vcsim<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Sample vCenter Inventories<\/h2>\n\n\n\n<p>William Lam maintains a github repo with recordings of some lab inventories, available here: <a href=\"https:\/\/github.com\/lamw\/govc-recordings\">https:\/\/github.com\/lamw\/govc-recordings<\/a>.  I downloaded this repo and extracted the contents to <code>\/data\/vcsim\/sims<\/code>, which provides 5 different lab environments from about 4 years ago.  <\/p>\n\n\n\n<p>This repo also contains instructions on how to save an existing inventory for use in the simulator.  Getting ready to do some maintenance or decommission an environment?  Might as well save that point in time snapshot of the inventory we can report against later.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Docker <code>compose.yml<\/code><\/h2>\n\n\n\n<p>Looking at this file, you&#8217;ll see 3 instances of the <code>vcsim<\/code> container running.  There are two generic inventories, controlled by parameters passed to <code>command<\/code> for things like number of hosts per cluster, port groups, and listening port.  The third vCenter inventory is one of the saved inventories from the govc-recordings repo.  I&#8217;m running multiple saved inventories, but in the interest of saving space have only included one sample below.  Each <code>vcsim<\/code> container will get a container IP and listen on port 8989.  In this example, <code>nginx<\/code> is handling all of the traffic coming in &#8212; we reference a <code>reverse_proxy.conf<\/code> file as well as a certificate folder.  Those will be discussed later.<\/p>\n\n\n\n<p>In the <code>\/data\/vcsim\/<\/code> folder, <code>compose.yml<\/code> has the following contents:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>version: '2'\nservices:\n  # This nginx web server will terminate at a wildcard SSL certificate, then use the first label\n  # of the DNS entry to send requests to port 8989 on the associated container, for example:\n  # https:\/\/small.vcsim.example.com:443 --> https:\/\/small:8989\n  nginx:\n    image: nginx:latest\n    volumes:\n      - \/data\/vcsim\/reverse_proxy.conf:\/etc\/nginx\/conf.d\/default.conf\n      - \/data\/vcsim\/cert:\/etc\/nginx\/certs\n    ports:\n      - \"443:443\"\n\n  # Here are a few simulated VCs with progressively larger inventories\n  small:\n    image: vmware\/vcsim:latest\n    command: -api-version \"8.0.3\" -cluster 1 -dc 1 -folder 5 -host 8 -standalone-host 0 -l \"0.0.0.0:8989\" -vm 20\n    restart: unless-stopped\n  medium:\n    image: vmware\/vcsim:latest\n    command: -api-version \"8.0.3\" -cluster 2 -dc 2 -folder 5 -host 16 -standalone-host 0 -l \"0.0.0.0:8989\" -vm 100\n    restart: unless-stopped\n\n  # The following examples are from a github repo\n  wlam7:\n    image: vmware\/vcsim\n    command: -load \/simdata -l \"0.0.0.0:8989\"\n    restart: unless-stopped\n    volumes:\n      - \/data\/vcsim\/sims\/vcsim-vcsa.primp-industries.local:\/simdata<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">nginx <code>reverse_proxy.conf<\/code><\/h2>\n\n\n\n<p>This nginx configuration will extract the subdomain from the request, for example the word <code>small<\/code> from <code>small.vcsim.example.com<\/code> and store it in a <code>$sub<\/code> variable. We will then proxy the request for each subdomain to the appropriate container, for example <code>https:\/\/small.vcsim.example.com:443\/<\/code> to the individual container of <code>https:\/\/small:8989\/<\/code>. In DNS we only need to create a single cname record for <code>*.vcsim.example.com<\/code> that points to our container host. Any container that gets created will automatically be available via our wildcard subdomain.<\/p>\n\n\n\n<p>I&#8217;ve not included the certificate files, but as you can see from the <code>compose.yml<\/code> and <code>reverse_proxy.conf<\/code> files, there is a directory at <code>\/data\/vcsim\/cert<\/code> containing a PEM formatted certificate and private key named <code>wildcard-vcsim-example-com.pem<\/code> and <code>wildcard-vcsim-example-com.key<\/code>.  This allows all our requests (from PowerCLI or the like) to have a valid certificate, while we only need to maintain a single certificate file.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>server {\n   # Listen for any HTTPS request\n   listen 443 ssl;\n\n   # Extract the subdomain name from 'SUB.vcsim.example.com'\n   server_name ~^(?&lt;sub>&#91;^.]+)\\.vcsim\\.example\\.com$;\n\n   # Define the path to the certificate and key\n   ssl_certificate \/etc\/nginx\/certs\/wildcard-vcsim-example-com.pem;\n   ssl_certificate_key \/etc\/nginx\/certs\/wildcard-vcsim-example-com.key;\n\n   # For any request, proxy to the container name on port 8989\n   location \/ {\n        resolver 127.0.0.11 valid=1s;\n        proxy_pass https:\/\/$sub:8989;\n   }\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Bring Up<\/h2>\n\n\n\n<p>With our <code>compose.yml<\/code>, <code>reverse_proxy.conf<\/code>, certificate files, and simulated inventories in place, we are ready to startup the service.  To this we only need to run a single command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker compose up -d<\/code><\/pre>\n\n\n\n<p>When the system restarts, these containers will restart automatically.  If we want to check stats or logs, we can do so with the following:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker stats\ndocker compose logs<\/code><\/pre>\n\n\n\n<p>When running the <code>docker compose<\/code> commands we need to be in the <code>\/data\/vcsim\/<\/code> folder, or specify that folder via arguments.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>Using the above steps, I have a single lab VM with ~10 vCenter inventories&#8230; using less than 2GB of RAM and 2vCPU.  There are of course some caveats, like no UI and some methods that don&#8217;t exist in the simulator, but for many test scenarios when you just need the SOAP API this works great.<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve recently been testing a handful of reporting tools against vCenter Server endpoints. I have several lab instances for various major releases, which allow me to test a wide range of configurations. However, there are some tests that are hard &hellip; <a href=\"https:\/\/enterpriseadmins.org\/blog\/virtualization\/scaling-your-tests-how-to-set-up-a-vcenter-server-simulator\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":6,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[9,4],"tags":[],"class_list":["post-2063","post","type-post","status-publish","format-standard","hentry","category-lab-infrastructure","category-virtualization"],"_links":{"self":[{"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/posts\/2063","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/users\/6"}],"replies":[{"embeddable":true,"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/comments?post=2063"}],"version-history":[{"count":3,"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/posts\/2063\/revisions"}],"predecessor-version":[{"id":2068,"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/posts\/2063\/revisions\/2068"}],"wp:attachment":[{"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/media?parent=2063"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/categories?post=2063"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/tags?post=2063"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}