Skip to content

INSTALL: Build Symphony Director

Steve Norledge edited this page Nov 14, 2015 · 15 revisions

Configure Symphony Director

This guide will walk through the process of the initial configuration after a base install of CentOS 7.0 provided by the scripts and guide from the Configure VM Host wiki page.

As with the other appliances, run stage 1 completely on all appliances before moving to stage2

Assumptions

  • Network
    • 1 network interface connected to Symphony build network (eth0)
    • 1 network interface connected to external network with internet access (eth1)
    • 1 network interface connected to cluster private network (eth2)
    • 1 network interface connected to cluster management network (eth3)

(STAGE 1) Base configuration

  • Setup Hostname - Note that it is strongly advised to leave the "mgt.symphony.local" domain - this is not the domain that will be used for the specified deployment.
echo "symphony-director.mgt.symphony.local" > /etc/hostname
  • Disable Unused Services
systemctl stop NetworkManager
systemctl disable NetworkManager
  • Enable Firewall Service
systemctl enable firewalld
systemctl start firewalld
  • Configure Firewall Zones
firewall-cmd --zone=external --add-masquerade --permanent
firewall-cmd --new-zone build --permanent
firewall-cmd --new-zone prv --permanent
firewall-cmd --new-zone mgt --permanent
firewall-cmd --add-service ssh --zone build --permanent
firewall-cmd --reload
  • Configure Network Interfaces - It is strongly advised to use these settings.

Configure eth0 (Private internal Alces Symphony Network):

cat << EOF > /etc/sysconfig/network-scripts/ifcfg-eth0
IPV6INIT=no
BOOTPROTO=none
DEVICE=eth0
ONBOOT=yes
IPADDR=10.78.254.1
NETMASK=255.255.0.0
NETWORK=10.78.0.0
ZONE=build
NM_CONTROLLED=no
DNS=10.78.254.1
EOF

Configure eth1 (Public Network - This guide assumes that the external facing network is using DHCP to configure the external interface - on your VM host being used, this interface will need to be able to access the internet) :

cat << EOF > /etc/sysconfig/network-scripts/ifcfg-eth1
IPV6INIT=no
BOOTPROTO=dhcp
DEVICE=eth1
ONBOOT=yes
PEERDNS=no
ZONE=external
NM_CONTROLLED=no
EOF

cat << EOF > /etc/sysconfig/network-scripts/ifcfg-eth2
IPV6INIT=no
BOOTPROTO=none
DEVICE=eth2
IPADDR=10.110.0.254
NETMASK=255.255.0.0
ONBOOT=yes
PEERDNS=no
ZONE=prv
NM_CONTROLLED=no
EOF

cat << EOF > /etc/sysconfig/network-scripts/ifcfg-eth3
IPV6INIT=no
BOOTPROTO=none
DEVICE=eth3
IPADDR=10.111.0.254
NETMASK=255.255.0.0
ONBOOT=yes
PEERDNS=no
ZONE=mgt
NM_CONTROLLED=no
EOF

  • Perform update of currently installed packages from local, internal repository (on DMZ as referenced in hosts file).
yum -y --config=http://repo.alces-software.com/configs/centos/7/yum.conf update
  • Install some useful packages
yum -y --config=http://repo.alces-software.com/configs/centos/7/yum.conf install vim emacs yum-utils 
  • Reboot (Will remove from network)
  • reboot the machine, now is also the time to configure the host VM to sit on the correct bridge

(STAGE 2) Symphony Base Configuration

  • Add to Temporary Hosts File
cat << EOF >> /etc/hosts
10.78.254.1  symphony-director.mgt.symphony.local symphony-director
EOF
  • Checkout Alces Symphony Git Repository
yum -y --config=http://repo.alces-software.com/configs/centos/7/yum.conf install git
cd /var/lib
git clone https://github.com/alces-software/symphony.git
  • Run Alces Symphony Installer
/var/lib/symphony/director/bin/install_all.sh

Configure OpenVPN

*Install Repos and Packages Required

yum -y --config http://repo.alces-software.com/configs/centos/7/yum.conf --enablerepo=epel install openvpn easy-rsa facter
  • Prepare SSL
mkdir /etc/openvpn/easyrsa
CN="symphony-director.mgt.symphony.local"
cp -pav /usr/share/easy-rsa/2.0/* /etc/openvpn/easyrsa/
sed -i /etc/openvpn/easyrsa/vars \
 -e 's|KEY_COUNTRY=.*$|KEY_COUNTRY=\"GB\"|g' \
 -e 's|KEY_PROVINCE=.*|KEY_PROVINCE=\"Oxfordshire"|g' \
 -e 's|KEY_CITY=.*|KEY_CITY=\"Bicester\"|g' \
 -e 's|KEY_ORG=.*|KEY_ORG=\"Alces Software Ltd\"|g' \
 -e 's|KEY_EMAIL=.*|KEY_EMAIL=\"ssl@alces-software.com\"|g' \
 -e 's|KEY_NAME=.*|KEY_NAME=\"server\"|g' \
 -e 's|KEY_OU=.*|KEY_OU=\"server\"|g' \
 -e "s|KEY_CN=.*|KEY_CN=\"${CN}\"|g"
cd /etc/openvpn/easyrsa/
source ./vars
./clean-all
./pkitool --initca
./pkitool --server server
./build-dh

Configure Management VPN

cat << EOF > /etc/openvpn/manage.conf
port 1194
proto tcp
dev tun0
ca /etc/openvpn/easyrsa/keys/ca.crt
cert /etc/openvpn/easyrsa/keys/server.crt
key /etc/openvpn/easyrsa/keys/server.key
dh /etc/openvpn/easyrsa/keys/dh2048.pem
server 10.80.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "route 10.78.0.0 255.255.0.0"
push "route 10.110.0.0 255.255.0.0"
push "route 10.111.0.0 255.255.0.0"
duplicate-cn
keepalive 10 120
comp-lzo
persist-key
persist-tun
status openvpn-status.log
log         /var/log/openvpn.log
log-append  /var/log/openvpn.log
verb 3
client-cert-not-required
username-as-common-name
plugin /usr/lib64/openvpn/plugins/openvpn-plugin-auth-pam.so openvpn-manage
EOF

FQDN='symphony-director.mgt.symphony.cluster'
cat << EOF > /etc/openvpn/manage.client.conf
client
dev tun
proto tcp
remote $FQDN 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
auth-user-pass
ns-cert-type server
comp-lzo
verb 3
EOF

cat << EOF > /etc/openvpn/manage.users
admin
EOF

#Only allow specific users
sed -e "/^account    required     pam_nologin.so$/iauth       required     pam_listfile.so onerr=fail item=group sense=allow file=/etc/openvpn/manage.users" /etc/pam.d/login  > /etc/pam.d/openvpn-manage

systemctl enable openvpn@manage.service
systemctl start openvpn@manage.service

#Create management vpn user
useradd admin
passwd admin
usermod admin -s /sbin/nologin

firewall-cmd --zone trusted --add-interface tun0 --permanent
firewall-cmd --add-port 1194/tcp --zone external --permanent
firewall-cmd --add-rich-rule 'rule family="ipv4" source address="10.80.0.0/24" masquerade' --zone mgt --permanent
firewall-cmd --add-rich-rule 'rule family="ipv4" source address="10.80.0.0/24" masquerade' --zone prv --permanent
firewall-cmd --add-rich-rule 'rule family="ipv4" source address="10.80.0.0/24" masquerade' --zone build --permanent
firewall-cmd --reload

ln -sn /etc/openvpn/easyrsa/keys/ca.crt /etc/openvpn/.

Syslog Server

  • Install and Enable Syslog
yum --config http://repo.alces-software.com/configs/centos/7/yum.conf --enablerepo=epel install rsyslog
systemctl enable rsyslog
firewall-cmd --add-port 514/udp --zone build --permanent
firewall-cmd --add-port 514/tcp --zone build --permanent
  • Configure Syslog
#Put these three lines as the first rule in /etc/rsyslog.conf (after the ###RULES### comment)
$template remoteMessage, "/var/log/slave/%FROMHOST%/messages.log"
:fromhost-ip, !isequal, "127.0.0.1" ?remoteMessage
& ~

sed -i -e "s/^#\$ModLoad imudp.*$/\$ModLoad imudp/g" /etc/rsyslog.conf
sed -i -e "s/^#\$UDPServerRun 514.*$/\$UDPServerRun 514/g" /etc/rsyslog.conf
sed -i -e "s/^#\$ModLoad imtcp.*$/\$ModLoad imtcp/g" /etc/rsyslog.conf
sed -i -e "s/^#\$InputTCPServerRun 514.*$/\$InputTCPServerRun 514/g" /etc/rsyslog.conf

#log rotate
cat << EOF > /etc/logrotate.d/rsyslog-remote
/var/log/slave/*/*.log {
    sharedscripts
    compress
    rotate 2
    postrotate
        /bin/kill -HUP \`cat /var/run/syslogd.pid 2> /dev/null\` 2> /dev/null || true
        /bin/kill -HUP \`cat /var/run/rsyslogd.pid 2> /dev/null\` 2> /dev/null || true
    endscript
}
EOF
#fix bug with virt-sysprep cleaning /var/log/spooler
sed -i -e "s/sharedscripts/missingok\n    sharedscripts/g" /etc/logrotate.d/syslog
  • Restart
systemctl restart rsyslog

Puppet

  • Install Puppet and Passenger - Press enter to confirm all defaults during the passenger install, don't make any manual edits.
yum -y --config http://repo.alces-software.com/configs/centos/7/yum.conf --enablerepo=epel --enablerepo=puppet-deps --enablerepo=puppet-base install puppet puppet-server hiera httpd httpd-devel mod_ssl ruby-devel rubygems gcc gcc-c++ libcurl-devel openssl-devel zlib-devel
gem install rack passenger
passenger-install-apache2-module
  • Configure Puppet
cat << EOF > /etc/puppet/puppet.conf
[main]
    vardir = /var/lib/puppet
    logdir = /var/log/puppet
    rundir = /var/run/puppet
    ssldir = \$vardir/ssl
    allow_duplicate_certs = true
    pluginsync  = true
    hiera_config=/etc/puppet/hiera.yaml
    #dns_alt_names=
[agent]
    classfile = \$vardir/classes.txt
    localconfig = \$vardir/localconfig
    report      = true
    pluginsync  = true
    certname    = symphony-director
    server      = symphony-director
    listen      = false
    environment = production
[master]
    reports     = store
    certname    = symphony-director
    ca = true
    environmentpath = \$confdir/environments/
EOF

cat << EOF > /etc/puppet/hiera.yaml
---
:backends:
  - yaml
:yaml:
  :datadir: /etc/puppet/environments/%{environment}/hieradata/
:hierarchy:
  - common
  - "%{::clientcert}"
  - "%{::alces_hostname}"
  - "%{::hostname}"
  - "%{::alces_machine}"
  - "%{::alces_role}"
  - "%{::environment}"
  - network
  - cluster
  - site
EOF
  • Create Default Puppet Environment
mv /etc/puppet/environments/example_env /etc/puppet/environments/production
  • Invoke Generation of initial certificates
systemctl start puppetmaster
puppet agent -t
systemctl stop puppetmaster
  • Configure http
#GET LASTEST mod_passenger
PASSENGER_MOD=`find /usr/local/share/gems/gems/passenger-* -type f -iname mod_passenger.so -printf '%T@ %p\n'| sort -n | tail -1 | cut -f2- -d" "`
PASSENGER_ROOT=`echo $PASSENGER_MOD | sed -e 's|/buildout/apache2/mod_passenger.so||'`
cat << EOF > /etc/httpd/conf.d/passenger.conf
LoadModule passenger_module $PASSENGER_MOD
<IfModule mod_passenger.c>
   PassengerRoot $PASSENGER_ROOT
   PassengerRuby /usr/bin/ruby
   PassengerEnabled off
</IfModule>
EOF

cat << EOF > /etc/httpd/conf.d/puppet-master.conf
PassengerHighPerformance On
PassengerMaxPoolSize 12
PassengerMaxRequests 1000
PassengerPoolIdleTime 600

Listen 8140
<VirtualHost *:8140>
    PassengerEnabled On
    SSLEngine On

    SSLProtocol             All -SSLv2
    SSLCipherSuite          HIGH:!ADH:RC4+RSA:-MEDIUM:-LOW:-EXP
    SSLCertificateFile      /var/lib/puppet/ssl/certs/symphony-director.pem
    SSLCertificateKeyFile   /var/lib/puppet/ssl/private_keys/symphony-director.pem
    SSLCertificateChainFile /var/lib/puppet/ssl/ca/ca_crt.pem
    SSLCACertificateFile    /var/lib/puppet/ssl/ca/ca_crt.pem
    SSLCARevocationFile     /var/lib/puppet/ssl/ca/ca_crl.pem
    SSLCARevocationCheck    chain
    SSLVerifyClient         optional
    SSLVerifyDepth          1
    SSLOptions              +StdEnvVars +ExportCertData
    RequestHeader set X-SSL-Subject %{SSL_CLIENT_S_DN}e
    RequestHeader set X-Client-DN %{SSL_CLIENT_S_DN}e
    RequestHeader set X-Client-Verify %{SSL_CLIENT_VERIFY}e

    DocumentRoot /usr/share/puppet/rack/puppetmasterd/public
    <Directory /usr/share/puppet/rack/puppetmasterd/>
        Options None
        AllowOverride None
        Order Allow,Deny
        Allow from All
    </Directory>
    ErrorLog /var/log/httpd/puppet-server.example.com_ssl_error.log
    CustomLog /var/log/httpd/puppet-server.example.com_ssl_access.log combined
</VirtualHost>
EOF

mkdir -p /usr/share/puppet/rack/puppetmasterd
mkdir /usr/share/puppet/rack/puppetmasterd/public /usr/share/puppet/rack/puppetmasterd/tmp
cp /usr/share/puppet/ext/rack/config.ru /usr/share/puppet/rack/puppetmasterd/
chown puppet:puppet /usr/share/puppet/rack/puppetmasterd/config.ru

systemctl restart httpd
#Open firewall
firewall-cmd --add-port 8140/tcp --zone build --permanent

Cobbler

  • Install Cobbler Package
yum -y --config http://repo.alces-software.com/configs/centos/7/yum.conf --enablerepo=epel --enablerepo=cobbler install cobbler httpd dhcp fence-agents tftp xinetd tftp-server cobbler-web bind bind-utils bind-chroot
  • Modify Configuration
#Set default password - password needs to be entered.
PASS=`openssl passwd -1` ; sed -i /etc/cobbler/settings -e "s|^default_password_crypted.*|default_password_crypted: \"$PASS\"|g"

#Set master ip
IP=`hostname -i`; sed -i /etc/cobbler/settings -e "s/^server:.*/server: $IP/g"
IP=`hostname -i`; sed -i /etc/cobbler/settings -e "s/^next_server:.*/next_server: $IP/g"
#Enable dhcp management
sed -ri /etc/cobbler/settings -e "s/^#?manage_dhcp.*/manage_dhcp: 1/g"
#Enable DNS
sed -ri /etc/cobbler/settings -e "s/^#?manage_dns.*/manage_dns: 1/g"
sed -ri /etc/cobbler/settings -e "s/^#?manage_forward_zones.*/manage_forward_zones: ['mgt.symphony.local']/g"
sed -ri /etc/cobbler/settings -e "s/^#?manage_reverse_zones.*/manage_reverse_zones: ['10.78']/g"
#Enable Puppet management
sed -ri /etc/cobbler/settings \
-e "s/^#?puppet_auto_setup:.*/puppet_auto_setup: 1/g" \
-e "s/^#?sign_puppet_certs_automatically:.*/sign_puppet_certs_automatically: 1/g" \
-e "s/^#?remove_old_puppet_certs_automatically:.*/remove_old_puppet_certs_automatically: 1/g" \
-e "s/^#?puppet_version:.*/puppet_version: 3/g" \
-e "s/^#?puppet_server:.*/puppet_server: symphony-director/g" \
-e "s/^#?puppetca_path:.*/puppetca_path: \/usr\/bin\/puppet/g"

#Other
sed -i /etc/cobbler/settings -e "s/^pxe_just_once.*$/pxe_just_once: 1/g"
cat << EOF > /etc/cobbler/dhcp.template
#Configure dhcp template
# ******************************************************************
# Cobbler managed dhcpd.conf file
#
# generated from cobbler dhcp.conf template ($date)
# Do NOT make changes to /etc/dhcpd.conf. Instead, make your changes
# in /etc/cobbler/dhcp.template, as /etc/dhcpd.conf will be
# overwritten.
#
# ******************************************************************

ddns-update-style interim;

allow booting;
allow bootp;

ignore client-updates;
set vendorclass = option vendor-class-identifier;

option pxe-system-type code 93 = unsigned integer 16;

subnet 10.78.0.0 netmask 255.255.0.0 {
     option routers             10.78.254.1;
     option domain-name-servers 10.78.254.1;
     option domain-search "mgt.symphony.local","cluster.local";
     option subnet-mask         255.255.0.0;
     #range dynamic-bootp        10.78.0.1 10.78.0.254;
     default-lease-time         21600;
     max-lease-time             43200;
     next-server                \$next_server;
     class "pxeclients" {
          match if substring (option vendor-class-identifier, 0, 9) = "PXEClient";
          if option pxe-system-type = 00:02 {
                  filename "ia64/elilo.efi";
          } else if option pxe-system-type = 00:06 {
                  filename "grub/grub-x86.efi";
          } else if option pxe-system-type = 00:07 {
                  filename "grub/grub-x86_64.efi";
          } else {
                  filename "pxelinux.0";
          }
     }

}

#for dhcp_tag in \$dhcp_tags.keys():
    ## group could be subnet if your dhcp tags line up with your subnets
    ## or really any valid dhcpd.conf construct ... if you only use the
    ## default dhcp tag in cobbler, the group block can be deleted for a
    ## flat configuration
# group for Cobbler DHCP tag: \$dhcp_tag
group {
        #for mac in \$dhcp_tags[\$dhcp_tag].keys():
            #set iface = \$dhcp_tags[\$dhcp_tag][\$mac]
    host \$iface.name {
        hardware ethernet \$mac;
        #if \$iface.ip_address:
        fixed-address \$iface.ip_address;
        #end if
        #if \$iface.hostname:
        option host-name "\$iface.hostname";
        #end if
        #if \$iface.netmask:
        option subnet-mask \$iface.netmask;
        #end if
        #if \$iface.gateway:
        option routers \$iface.gateway;
        #end if
        #if \$iface.enable_gpxe:
        if exists user-class and option user-class = "gPXE" {
            filename "http://\$cobbler_server/cblr/svc/op/gpxe/system/\$iface.owner";
        } else if exists user-class and option user-class = "iPXE" {
            filename "http://\$cobbler_server/cblr/svc/op/gpxe/system/\$iface.owner";
        } else {
            filename "undionly.kpxe";
        }
        #else
        filename "\$iface.filename";
        #end if
        ## Cobbler defaults to \$next_server, but some users
        ## may like to use \$iface.system.server for proxied setups
        next-server \$next_server;
        ## next-server \$iface.next_server;
    }
        #end for
}
#end for
EOF
  • Set WebUI password for 'admin' user (use cluster-wide 'admin' password)
htdigest /etc/cobbler/users.digest 'Cobbler' admin
  • Start Services
systemctl start cobblerd.service
systemctl enable cobblerd.service
systemctl enable httpd
systemctl restart httpd
systemctl start xinetd
systemctl enable xinetd
systemctl enable dhcpd
systemctl enable named
  • Get Loaders TODO Needs internet accesss
cobbler get-loaders
  • Configure DNS
SITE_DNS=10.101.0.1
cat << EOF > /etc/cobbler/named.template
options {
          listen-on port 53 { any; };
          directory       "/var/named";
          dump-file       "/var/named/data/cache_dump.db";
          statistics-file "/var/named/data/named_stats.txt";
          memstatistics-file "/var/named/data/named_mem_stats.txt";
          allow-query     { any; };
          recursion yes;


          dnssec-enable no;
          dnssec-validation no;
          dnssec-lookaside auto;

          forward first;
          forwarders {
              $SITE_DNS;
          };

};

logging {
        channel default_debug {
                file "data/named.run";
                severity dynamic;
        };
};

#for \$zone in \$forward_zones
zone "\${zone}." {
    type master;
    file "\$zone";
};

#end for
#for \$zone, \$arpa in \$reverse_zones
zone "\${arpa}." {
    type master;
    file "\$zone";
};

#end for
EOF
  • Generate Zone files for each managed domain
cat << EOF > /etc/cobbler/zone_templates/mgt.symphony.local
\\\$TTL 300
@                       IN      SOA     \$cobbler_server. nobody.example.com. (
                                        \$serial   ; Serial
                                        600         ; Refresh
                                        1800         ; Retry
                                        604800       ; Expire
                                        300          ; TTL
                                        )

                        IN      NS      \$cobbler_server.


symphony-director        IN A    10.78.254.1
@       IN MX   10  symphony-director
symphony-directory1 IN A 10.78.254.2
symphony-repo   IN A    10.78.254.3
symphony-monitor IN A    10.78.254.4
symphony-app    IN A    10.78.254.5
symphony-controller IN A 10.78.254.10
symphony-gateway IN A   10.78.254.11
symphony-storage IN A   10.78.254.12

\$cname_record

\$host_record
EOF

cat << EOF > /etc/cobbler/zone_templates/10.78
\\\$TTL 300
@                       IN      SOA     \$cobbler_server. nobody.example.com. (
                                        \$serial   ; Serial
                                        600         ; Refresh
                                        1800         ; Retry
                                        604800       ; Expire
                                        300          ; TTL
                                        )

                        IN      NS      \$cobbler_server.

254.1   IN PTR   symphony-director.mgt.symphony.local.;
254.2   IN PTR   symphony-directory.mgt.symphony.local.;
254.3   IN PTR   symphony-repo.mgt.symphony.local.;
254.4   IN PTR   symphony-monitor.mgt.symphony.local;
254.5   IN PTR   symphony-app.mgt.symphony.local;
254.10  IN PTR   symphony-controller.mgt.symphony.local;
254.11  IN PTR   symphony-gateway.mgt.symphony.local;
254.12  IN PTR   symphony-storage.mgt.symphony.local;

\$cname_record

\$host_record
EOF
  • Configure Firewall
firewall-cmd --zone build --add-service dhcp --permanent

firewall-cmd --zone build --add-service tftp --permanent

firewall-cmd --zone build --add-service http --permanent

firewall-cmd --add-service dns --zone build --permanent

firewall-cmd --add-service smtp --zone build --permanent

firewall-cmd --add-service ntp --zone build --permanent
firewall-cmd --reload
  • Delete temp entries from host file
cat << EOF > /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
EOF
cat << EOF > /etc/resolv.conf
search mgt.symphony.local. symphony.local.
nameserver 10.78.254.1
EOF
  • Sync cobbler to create dns
cobbler sync
  • Restart
shutdown -r now

(STAGE 3) Puppet run

  • Install Symphony Templates
/var/lib/symphony/puppet/bin/install_all.sh

  • Generate Heira configuration

TODO: /var/lib/symphony/puppet/environments/symphony/modules/symphonyrepo/fetch_templates.sh - needs to reference repo.alces-software.com

/var/lib/symphony/puppet/bin/prepare_modules.sh
  • Restart puppet
systemctl restart httpd
  • Run puppet symphony env
puppet agent -t --environment=symphony
  • Prepare Cobbler
/var/lib/symphony/cobbler/bin/install_all.sh

(STAGE 4) Configure

  • Install Alces Metalware
curl -sL http://git.io/metalware-installer | sudo alces_OS=el7 /bin/bash
cat << EOF > /opt/metalware/etc/genders
################################################################################
##
## Alces Metalware - Genders configuration
## Copyright (c) 2015 Alces Software Ltd
##
################################################################################
# APPLIANCE
symphony-director       symphony
symphony-directory      symphony
symphony-monitor        symphony
symphony-repo           symphony
symphony-app            symphony
symphony-controller     symphony
symphony-gateway        symphony
symphony-storage        symphony

# MASTER
master1 master,masters,cluster,all

# SLAVES
slave[01-10] nodes,slave,cluster,all
EOF

* Symphony detector endpoint

curl -L https://raw.githubusercontent.com/alces-software/symphony-detector-endpoint/master/scripts/install | /bin/bash


* Symphony management dashboard

* Install the package:

  ```
curl -L https://raw.githubusercontent.com/alces-software/symphony-management-dashboard/master/scripts/install | /bin/bash
  ```

* Modify `/opt/symphony-management-dashboard/htdocs/index.html` to replace "your cluster" with the name of the cluster.

Clone this wiki locally