Jekyll2023-03-29T14:57:49+00:00/feed.xmlSimon GreavesThe official blog site of Simon Greaves covering cloud technologiesCKA Part 1 - Native Kubernetes Core Concepts2023-02-24T00:00:00+00:002023-02-24T00:00:00+00:00/CKA-Part-1-Kubernetes-Core-Concepts<p>The following blog series contains my notes from the Udemy training course in preperation for the Certified Kubernetes Administrator (CKA) exam. <br />
Use the code - <strong>DEVOPS15</strong> - while registering for the CKA or CKAD exams at Linux Foundation to get a 15% discount.</p>
<h1 id="labs">Labs</h1>
<p>You need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. It is recommended to run this tutorial on a cluster with at least two nodes that are not acting as control plane hosts. If you do not already have a cluster, you can create one by using <a href="https://minikube.sigs.k8s.io/docs/tutorials/multi_node/">minikube</a> or you can use one of these Kubernetes playgrounds:</p>
<ul>
<li><a href="https://killercoda.com/playgrounds/scenario/kubernetes">Killercoda</a></li>
<li><a href="http://labs.play-with-k8s.com/">Play with Kubernetes</a>
<!--more--></li>
</ul>
<h1 id="basics">Basics</h1>
<p>Nodes Types</p>
<ul>
<li>Worker
<ul>
<li>Hosts applications as containers</li>
</ul>
</li>
<li>Master (Control Plane)
<ul>
<li>Controllers, manage, plan, schedule, monitor nodes</li>
</ul>
</li>
</ul>
<p>Master Node Components</p>
<ul>
<li>kube-apiserver
<ul>
<li>Oversees APIs and make changes with all sub-manager components</li>
</ul>
</li>
<li>ETCD Cluster
<ul>
<li>database of key value store of container inventory</li>
</ul>
</li>
<li>kube-scheduler
<ul>
<li>Scheduler, affinity rule observer</li>
</ul>
</li>
<li>Controller-Manager
<ul>
<li>Node-Controller</li>
<li>Replication Manager</li>
</ul>
</li>
</ul>
<p>All nodes require container runtime engines such as Docker, ContainerD, or Rocket. If containers are run on the master node, a container runtime engine like Docker must also be installed on there.</p>
<p>kubeadm tool configures these master node components as pods in the master node automatically but you can also configure them manually.</p>
<p>Worker Nodes</p>
<ul>
<li>kubelet
<ul>
<li>Manages containers on the worker nodes, listens to instructions from the kube-apiserver</li>
</ul>
</li>
<li>Kube-proxy
<ul>
<li>Allows cross container (services) communications</li>
</ul>
</li>
</ul>
<h1 id="etcd">ETCD</h1>
<p>Distributed key-value store.<br />
runs on port 2379.</p>
<p>installation steps:</p>
<ul>
<li>download
<ul>
<li>https://github.com/etcd-io/etcd/releases</li>
<li><code class="highlighter-rouge">curl -L ${DOWNLOAD_URL}/${ETCD_VER}/etcd-${ETCD_VER}-darwin-amd64.zip -o /tmp/etcd-${ETCD_VER}-darwin-amd64.zip</code></li>
</ul>
</li>
<li>extract
<ul>
<li><code class="highlighter-rouge">unzip /tmp/etcd-${ETCD_VER}-darwin-amd64.zip -d /tmp && rm -f /tmp/etcd-${ETCD_VER}-darwin-amd64.zip</code></li>
<li><code class="highlighter-rouge">mv /tmp/etcd-${ETCD_VER}-darwin-amd64/* /tmp/etcd-download-test && rm -rf mv /tmp/etcd-${ETCD_VER}-darwin-amd64z</code></li>
</ul>
</li>
<li>run
<ul>
<li><code class="highlighter-rouge">./etcd</code></li>
</ul>
</li>
<li>validate
<ul>
<li><code class="highlighter-rouge">/tmp/etcd-download-test/etcd --version</code></li>
<li><code class="highlighter-rouge">/tmp/etcd-download-test/etcdctl version</code></li>
</ul>
</li>
</ul>
<p>ETCD Control<br />
<code class="highlighter-rouge">./etcdctl --version</code> <br />
etcdctl version 3.x is API version 2.<br />
run <code class="highlighter-rouge">./etcdctl</code> on its own to see available versions.<br />
can change the API version using this<br />
<code class="highlighter-rouge">ETCDCTL_API=3 {command}</code> <br />
or export it as an environmental variable using<br />
<code class="highlighter-rouge">export etcdtl_api=3 {command}</code></p>
<p>Note: in v2 you ran <code class="highlighter-rouge">--version</code>, whereas now you just run <code class="highlighter-rouge">./etcdctl version</code> on its own.</p>
<p>Set a value with <br />
<code class="highlighter-rouge">./etcdctl put key1 value1</code> <br />
Get a value with<br />
<code class="highlighter-rouge">./etcdctl get key1</code></p>
<p>when running the commands, link together the API version, together with the certificate files that ETCDCTL can authenticate against the ETCD API server with.<br />
for example<br />
<code class="highlighter-rouge">kubectl exec etcd-master -n kube-system -- sh -c "ETCDCTL_API=3 etcdctl get / --prefix --keys-only --limit=10 --cacert /etc/kubernetes/pki/etcd/ca.crt --cert /etc/kubernetes/pki/etcd/server.crt --key /etc/kubernetes/pki/etcd/server.key"</code></p>
<h2 id="kube-api-server">kube API Server</h2>
<p>Responsibilities</p>
<ul>
<li>Authenticate User</li>
<li>validate request</li>
<li>retrieve data</li>
<li>update ETCD</li>
<li>scheduler</li>
<li>kubelet</li>
</ul>
<p>View options<br />
<code class="highlighter-rouge">kubectl get pods -n kube-system</code></p>
<p>Available options are in the manifest yaml file.<br />
<code class="highlighter-rouge">cat /etc/kubernetes/manifests/kube-apiserver.yaml</code></p>
<p>kube-apiserver service location<br />
<code class="highlighter-rouge">cat /etc/systemd/system/kube-apiserver.service</code></p>
<p>view running process and available options with<br />
<code class="highlighter-rouge">ps -aux | grep kube-apiserver</code></p>
<h2 id="kube-controller-manager">Kube Controller Manager</h2>
<ul>
<li>watches the status of nodes</li>
<li>remediates situation if there are issues</li>
</ul>
<p>Comprised of many controllers, including</p>
<ul>
<li>Node-controller</li>
<li>Replication Monitor</li>
</ul>
<h3 id="node-controller">Node-Controller</h3>
<ul>
<li>checks state every 5 seconds</li>
<li>node monitor grace period 40s</li>
<li>POD eviction timeout 5m</li>
</ul>
<p>Replication-Controller</p>
<ul>
<li>monitors status of replica pods</li>
</ul>
<p>Install<br />
<code class="highlighter-rouge">wget https://xx</code></p>
<h2 id="kube-scheduler">Kube Scheduler</h2>
<p>decides which pods go on which nodes only, does not place the pods, thats the job of the kubelet (the kubelet is the captain of the ship).</p>
<p>The scheduler</p>
<ul>
<li>filters nodes</li>
<li>rank nodes</li>
</ul>
<p>View the kube-scheduler options<br />
<code class="highlighter-rouge">cat/kubernetes/manifests/kube-scheduler-yaml</code></p>
<p>Process list<br />
<code class="highlighter-rouge">ps -aux | grep kube-scheduler</code></p>
<p>View available nodes <br />
<code class="highlighter-rouge">kubectl get nodes</code></p>
<h2 id="kubelet">Kubelet</h2>
<p>Like a captain on the ship. Leads all activities on the ship as instructed by the scheduler</p>
<ul>
<li>Registers node with the cluster</li>
<li>creates PODs</li>
<li>Monitors node and PODs</li>
</ul>
<p>Kubeadmin does not deploy Kubelets, you must install manually using the <code class="highlighter-rouge">wget xxxx</code> command.</p>
<p>View the running process and options with<br />
<code class="highlighter-rouge">ps -aux | grep kubelet</code></p>
<h2 id="kubeproxy">Kubeproxy</h2>
<p>As a nodes application IP address can change, K8s uses services to map a link between the service, such as database, with the current IP address.<br />
e.g.<br />
<code class="highlighter-rouge">service: db 10.96.0.12</code><br />
kube-proxy looks for new services and creates rules on each node to forward traffic heading to the service to the IP of the POD where it is running.<br />
download with <code class="highlighter-rouge">wget</code>.<br />
<br />
view kubeproxy with <br />
<code class="highlighter-rouge">kubectl get pods -n kube-system</code><br />
or<br />
<code class="highlighter-rouge">kubectl get daemonset -n kube-system</code></p>
<h1 id="pods">PODs</h1>
<p>smallest manageable object in K8s. <br />
Usually contains one container.<br />
Can container helper containers in a POD alongside the application container.</p>
<p><code class="highlighter-rouge">kubectl get pods</code> - get a list of PODs and their running state.</p>
<h2 id="yaml-in-k8s">YAML in K8s</h2>
<p>all K8s pod definition files contain</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">apiVersion</span><span class="pi">:</span>
<span class="na">kind</span><span class="pi">:</span>
<span class="na">metadata</span><span class="pi">:</span>
<span class="na">spec</span><span class="pi">:</span>
</code></pre></div></div>
<p>example of a file called pod-definition.yml</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">apiVersion</span><span class="pi">:</span> <span class="s">v1</span>
<span class="na">kind</span><span class="pi">:</span> <span class="s">Pod</span>
<span class="na">metadata</span><span class="pi">:</span>
<span class="err"> </span><span class="na">name</span><span class="pi">:</span> <span class="s">myapp-pod</span>
<span class="na"> labels</span><span class="pi">:</span>
<span class="err"> </span><span class="na">app</span><span class="pi">:</span> <span class="s">myapp</span>
<span class="na"> type</span><span class="pi">:</span> <span class="s">front-end</span>
<span class="na">spec</span><span class="pi">:</span>
<span class="na">containers</span><span class="pi">:</span>
<span class="err"> </span><span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">nginx-container</span>
<span class="na"> image</span><span class="pi">:</span> <span class="s">nginx</span>
</code></pre></div></div>
<p>Definitions of entries</p>
<ul>
<li><code class="highlighter-rouge">apiVersion:</code> - API version of the object being created. String value item
<ul>
<li>Alternative option <code class="highlighter-rouge">app/v1</code></li>
</ul>
</li>
<li><code class="highlighter-rouge">kind:</code> The kind of object type. String value item
<ul>
<li>alternative options <code class="highlighter-rouge">Service, ReplicaSet, Deployment</code></li>
</ul>
</li>
<li><code class="highlighter-rouge">metadata:</code> - data about the object. Dictionary value item, spaces in front of the object makes it a child object, so in the example above <code class="highlighter-rouge">app</code> is a child of <code class="highlighter-rouge">labels:</code>
<ul>
<li>alternative dictionary options can be various. the values are string value items.</li>
</ul>
</li>
<li><code class="highlighter-rouge">spec:</code> - Specification section of the object, types vary based on object type. <code class="highlighter-rouge">spec:</code> is a dictionary, <code class="highlighter-rouge">containers</code> is an array.
<ul>
<li>the <code class="highlighter-rouge">-</code> right before the <code class="highlighter-rouge">name:</code> variable means its the 1st item in the list</li>
</ul>
</li>
</ul>
<p>To create the pod-definition.yml file listed above, type:<br />
<code class="highlighter-rouge">kubectl create -f pod-definition.yml</code><br />
<br />
To create and run the pod run<br />
<code class="highlighter-rouge">kubectl run -f pod-definition.yml</code><br />
<br />
To create and run a pod without specifying the yml file, run<br />
<code class="highlighter-rouge">kubectl run nginx --image=nginx</code><br />
<br />
to create a pod definition file with the correct format/layout, run<br />
<code class="highlighter-rouge">kubectl run redis --image=redis --dry-run=client -o yaml > redis.yaml</code><br />
<br />
to see a list of pods run<br />
<code class="highlighter-rouge">kubectl get pods</code><br />
<br />
to see detailed information run<br />
<code class="highlighter-rouge">kubectl describe pod myapppod</code> <br />
<br />
Create a new object. Can use either <code class="highlighter-rouge">create</code> or <code class="highlighter-rouge">apply</code><br />
<code class="highlighter-rouge">kubectl apply -f pod.yaml</code> <br />
<br />
See which node the pods are running on <br />
<code class="highlighter-rouge">kubectl get pods -o wide</code> <br />
<br />
To change the configuration of a running pod, run<br />
<code class="highlighter-rouge">kubectl apply -f redis.yaml</code> <br />
<br />
To delete a running pod and then redeploy based on a YAML, run <br />
<code class="highlighter-rouge">kubectl replace --force -f redis.yaml</code></p>
<h2 id="editing-pods">Editing Pods</h2>
<p>There are limits on what you can edit on Pods, only the following specifications can be edited.</p>
<ul>
<li>spec.containers[*].image</li>
<li>spec.initContainers[*].image</li>
<li>spec.activeDeadlineSeconds</li>
<li>spec.tolerations</li>
</ul>
<p>If you edit a running Pod it will fail to save, however it will save it to a temporary file which you can then edit, delete the running Pod, and then redeploy from this yaml file.<br />
Alternatively you can edit a <a href="#Deployments">Deployments</a> (covered below) that contains the Pod definition and redeploy from that.</p>
<h1 id="replica-sets--replication-controllers">Replica Sets & Replication Controllers</h1>
<p>Replica sets is the newer technology that replaces the replication controllers. Fundamentally they fulfil the same purpose.</p>
<p>Replica Sets and Replication Controllers are defined using definition files, similar to the pods earlier. They contain the same core elements. <code class="highlighter-rouge">apiVersion:</code>, <code class="highlighter-rouge">kind:</code>, <code class="highlighter-rouge">metadata:</code>, and <code class="highlighter-rouge">spec:</code>
Under <code class="highlighter-rouge">spec:</code> you add a <code class="highlighter-rouge">template:</code> child object and then you place the pod data that is part of this replica set as a child of the <code class="highlighter-rouge">template:</code> line, except for the <code class="highlighter-rouge">apiVersion:</code> and <code class="highlighter-rouge">kind:</code></p>
<h2 id="replication-controllers">Replication Controllers</h2>
<p>example Replication Controller yml file.</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">apiVersion</span><span class="pi">:</span> <span class="s">v1</span>
<span class="na">kind</span><span class="pi">:</span> <span class="s">ReplicationController</span>
<span class="na">metadata</span><span class="pi">:</span>
<span class="err"> </span><span class="na">name</span><span class="pi">:</span> <span class="s">myapp-rc</span>
<span class="na"> labels</span><span class="pi">:</span>
<span class="err"> </span><span class="na">app</span><span class="pi">:</span> <span class="s">myapp</span>
<span class="na"> type</span><span class="pi">:</span> <span class="s">front-end</span>
<span class="na">spec</span><span class="pi">:</span>
<span class="na">template</span><span class="pi">:</span>
<span class="na">metadata</span><span class="pi">:</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">myapp-pod</span>
<span class="na">labels</span><span class="pi">:</span>
<span class="err"> </span> <span class="na">app</span><span class="pi">:</span> <span class="s">myapp</span>
<span class="na"> type</span><span class="pi">:</span> <span class="s">front-end</span>
<span class="s">spec</span><span class="err">:</span>
<span class="na">containers</span><span class="pi">:</span>
<span class="err"> </span><span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">nginx-container</span>
<span class="na"> image</span><span class="pi">:</span> <span class="s">nginx</span>
</code></pre></div></div>
<p>The number of replicas to add is defined by the <code class="highlighter-rouge">replica:</code> line. As this is a property of the Replication Controller <code class="highlighter-rouge">spec:</code>, it aligns with the replication controller <code class="highlighter-rouge">spec:</code> definitions.</p>
<p>Example Replication Controller yml file with the number of replicas defined.</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">apiVersion</span><span class="pi">:</span> <span class="s">v1</span>
<span class="na">kind</span><span class="pi">:</span> <span class="s">ReplicationController</span>
<span class="na">metadata</span><span class="pi">:</span>
<span class="err"> </span><span class="na">name</span><span class="pi">:</span> <span class="s">myapp-rc</span>
<span class="na"> labels</span><span class="pi">:</span>
<span class="err"> </span><span class="na">app</span><span class="pi">:</span> <span class="s">myapp</span>
<span class="na"> type</span><span class="pi">:</span> <span class="s">front-end</span>
<span class="na">spec</span><span class="pi">:</span>
<span class="na">template</span><span class="pi">:</span>
<span class="na">metadata</span><span class="pi">:</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">myapp-pod</span>
<span class="na">labels</span><span class="pi">:</span>
<span class="err"> </span> <span class="na">app</span><span class="pi">:</span> <span class="s">myapp</span>
<span class="na"> type</span><span class="pi">:</span> <span class="s">front-end</span>
<span class="s">spec</span><span class="err">:</span>
<span class="na">containers</span><span class="pi">:</span>
<span class="err"> </span><span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">nginx-container</span>
<span class="na"> image</span><span class="pi">:</span> <span class="s">nginx</span>
<span class="s">replicas</span><span class="err">:</span> <span class="m">3</span>
</code></pre></div></div>
<p>To create, run<br />
<code class="highlighter-rouge">kubectl create -f rc-definition.yml</code></p>
<p>This will create the 3 pods first, then the replication controller. To view run<br />
<code class="highlighter-rouge">kubectl get replicationcontroller</code></p>
<p>To see pods created by the replication controller, run<br />
<code class="highlighter-rouge">kubectl get pods</code></p>
<h2 id="replica-sets">Replica Sets</h2>
<p>replica Sets have an additional <code class="highlighter-rouge">selector:</code> setting. This defines the pod to use in this selection. A replica set can manage pods that are already configured/deployed so you have to add which pod to select when defining the replica set. The selector must contain <code class="highlighter-rouge">matchLabels:</code> and <code class="highlighter-rouge">type:</code>. As you can imagine <code class="highlighter-rouge">matchLabels:</code> matches the label defined in the pod.</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">apiVersion</span><span class="pi">:</span> <span class="s">apps/v1</span>
<span class="na">kind</span><span class="pi">:</span> <span class="s">ReplicaSet</span>
<span class="na">metadata</span><span class="pi">:</span>
<span class="err"> </span><span class="na">name</span><span class="pi">:</span> <span class="s">myapp-replicaset</span>
<span class="na"> labels</span><span class="pi">:</span>
<span class="err"> </span><span class="na">app</span><span class="pi">:</span> <span class="s">myapp</span>
<span class="na"> type</span><span class="pi">:</span> <span class="s">front-end</span>
<span class="na">spec</span><span class="pi">:</span>
<span class="na">template</span><span class="pi">:</span>
<span class="na">metadata</span><span class="pi">:</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">myapp-pod</span>
<span class="na">labels</span><span class="pi">:</span>
<span class="err"> </span> <span class="na">app</span><span class="pi">:</span> <span class="s">myapp</span>
<span class="na"> type</span><span class="pi">:</span> <span class="s">front-end</span>
<span class="s">spec</span><span class="err">:</span>
<span class="na">containers</span><span class="pi">:</span>
<span class="err"> </span><span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">nginx-container</span>
<span class="na"> image</span><span class="pi">:</span> <span class="s">nginx</span>
<span class="s">replicas</span><span class="err">:</span> <span class="m">3</span>
<span class="na">selector</span><span class="pi">:</span>
<span class="na">matchLabels</span><span class="pi">:</span>
<span class="na">type</span><span class="pi">:</span> <span class="s">front-end</span>
</code></pre></div></div>
<p>To create run<br />
<code class="highlighter-rouge">kubectl create -f replicaset-definition.yml</code></p>
<p>To see Replica Sets run<br />
<code class="highlighter-rouge">kubectl get replicaset</code></p>
<p>To edit run<br />
<code class="highlighter-rouge">kubectl edit replicaset replicasetname</code></p>
<p>If unsure of what the correct format of the yml file is, use the <code class="highlighter-rouge">explain</code> command.<br />
<code class="highlighter-rouge">kubectl explain replicaset</code></p>
<p>ReplicaSet shorthand in commands is <code class="highlighter-rouge">rs</code>.<br />
<code class="highlighter-rouge">kubectl get rs</code></p>
<h3 id="scaling">Scaling</h3>
<p>To scale the number of replicas in a set, you can either update the yml file with the revised number of replicas and run the replace command. <br />
<code class="highlighter-rouge">kubectl replace -f replicaset-definition.yml</code></p>
<p>Alternatively run the <code class="highlighter-rouge">scale</code> command instead.<br />
<code class="highlighter-rouge">kubectl scale --replicas=6 -f replicaset-definition.yml</code></p>
<p>The disadvantage of this is that the definition file still only contains 3 replicas and not the revised 6.</p>
<p>Or you can run it against the running replica set without updating the file manually with<br />
<code class="highlighter-rouge">kubectl scale rs new-replica-set --replica=5</code></p>
<h1 id="deployments">Deployments</h1>
<p>A k8s object that contains the replica sets and PODs.<br />
Controlled using YAML files.</p>
<p>Example</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">apiVersion</span><span class="pi">:</span> <span class="s">apps/v1</span>
<span class="na">kind</span><span class="pi">:</span> <span class="s">Deployment</span>
<span class="na">metadata</span><span class="pi">:</span>
<span class="err"> </span><span class="na">name</span><span class="pi">:</span> <span class="s">myapp-replicaset</span>
<span class="na"> labels</span><span class="pi">:</span>
<span class="err"> </span><span class="na">app</span><span class="pi">:</span> <span class="s">myapp</span>
<span class="na"> type</span><span class="pi">:</span> <span class="s">front-end</span>
<span class="na">spec</span><span class="pi">:</span>
<span class="na">template</span><span class="pi">:</span>
<span class="na">metadata</span><span class="pi">:</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">myapp-pod</span>
<span class="na">labels</span><span class="pi">:</span>
<span class="err"> </span> <span class="na">app</span><span class="pi">:</span> <span class="s">myapp</span>
<span class="na"> type</span><span class="pi">:</span> <span class="s">front-end</span>
<span class="s">spec</span><span class="err">:</span>
<span class="na">containers</span><span class="pi">:</span>
<span class="err"> </span><span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">nginx-container</span>
<span class="na"> image</span><span class="pi">:</span> <span class="s">nginx</span>
<span class="s">replicas</span><span class="err">:</span> <span class="m">3</span>
<span class="na">selector</span><span class="pi">:</span>
<span class="na">matchLabels</span><span class="pi">:</span>
<span class="na">type</span><span class="pi">:</span> <span class="s">front-end</span>
</code></pre></div></div>
<p>View deployments with <br />
<code class="highlighter-rouge">kubectl get deployments</code><br />
or
<code class="highlighter-rouge">kubectl get deploy</code></p>
<p>To view all the deployments and PODs, run<br />
<code class="highlighter-rouge">kubectl get all</code></p>
<h1 id="certification-tips">Certification Tips</h1>
<p>Quick ways to create objects using the run command without having to first create YAML files.<br />
<a href="https://kubernetes.io/docs/reference/kubectl/conventions/">https://kubernetes.io/docs/reference/kubectl/conventions/</a><br />
<br />
Create an NGINX Pod<br />
<code class="highlighter-rouge">kubectl run nginx --image=nginx</code><br />
<br />
Generate POD Manifest YAML file on the screen (-o yaml). Don’t create it(–dry-run). Save it to a file (> nginx.yaml)<br />
<code class="highlighter-rouge">kubectl run nginx --image=nginx --dry-run=client -o yaml > nginx.yml</code><br />
<br />
Create a deployment<br />
<code class="highlighter-rouge">kubectl create deployment --image=nginx nginx</code><br />
<br />
Generate Deployment YAML file (-o yaml). Don’t create it(–dry-run)<br />
<code class="highlighter-rouge">kubectl create deployment --image=nginx nginx --dry-run=client -o yaml</code><br />
<br />
Generate Deployment YAML file (-o yaml). Don’t create it(–dry-run) with 4 Replicas (–replicas=4)<br />
<code class="highlighter-rouge">kubectl create deployment --image=nginx nginx --dry-run=client -o yaml > nginx-deployment.yaml</code><br />
<br />
Save it to a file, make necessary changes to the file (for example, adding more replicas) and then create the deployment. <br />
<code class="highlighter-rouge">kubectl create -f nginx-deployment.yaml</code><br />
<br />
OR<br />
In k8s version 1.19+, we can specify the –replicas option to create a deployment with 4 replicas.<br />
<code class="highlighter-rouge">kubectl create deployment --image=nginx nginx --replicas=4 --dry-run=client -o yaml > nginx-deployment.yaml</code></p>
<h1 id="services">Services</h1>
<p>Used to connect pods together by service types. Services enables connectivity between the pods.<br />
Enables loose coupling between micro services in the deployment.<br />
Listens to network ports on the K8s node and then forwards requests to Pods.<br />
Has its own IP called the clusternode service IP.<br />
Services use a selector within a service definition file that contains a label from the pod definition file. <br />
<br />
Service types</p>
<table>
<thead>
<tr>
<th>Service Name</th>
<th>NodePort</th>
<th>ClusterIP</th>
<th>LoadBalancer</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Role</strong></td>
<td>Performs port redirects</td>
<td>A common name/IP address shared by services</td>
<td>Take advantage of native cloud load balancers</td>
</tr>
<tr>
<td><strong>Port</strong></td>
<td>3000 - 32767</td>
<td>3000 - 32767</td>
<td>3000 - 32767</td>
</tr>
</tbody>
</table>
<h2 id="nodeport">NodePort</h2>
<p>Definition File mapping to a single pod<br />
In this example below, the NodePort service definition file is looking for the pod with the label <code class="highlighter-rouge">app:</code> that is called <code class="highlighter-rouge">myapp</code>. It is also looking for the pod with <code class="highlighter-rouge">type: front-end</code>.</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">apiVersion</span><span class="pi">:</span> <span class="s">v1</span>
<span class="na">kind</span><span class="pi">:</span> <span class="s">Service</span>
<span class="na">metadata</span><span class="pi">:</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">myapp-service</span>
<span class="na">spec</span><span class="pi">:</span>
<span class="na">type</span><span class="pi">:</span> <span class="s">NodePort</span>
<span class="na">ports</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">targetPort</span><span class="pi">:</span> <span class="m">80</span>
<span class="na">port</span><span class="pi">:</span> <span class="m">80</span>
<span class="na">nodePort</span><span class="pi">:</span> <span class="m">30008</span>
<span class="na">selector</span><span class="pi">:</span>
<span class="na">app</span><span class="pi">:</span> <span class="s">myapp</span>
<span class="na">type</span><span class="pi">:</span> <span class="s">front-end</span>
</code></pre></div></div>
<p>Get services<br />
<code class="highlighter-rouge">kubectl get services</code> <br />
<br />
Definition File mapping to multiple pods<br />
Looks very similar to the above, the selector <code class="highlighter-rouge">app: myapp</code> is looking for all pods with the label <code class="highlighter-rouge">app: myapp</code> and it will group them all together in the NodePort service.</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">apiVersion</span><span class="pi">:</span> <span class="s">v1</span>
<span class="na">kind</span><span class="pi">:</span> <span class="s">Service</span>
<span class="na">metadata</span><span class="pi">:</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">myapp-service</span>
<span class="na">spec</span><span class="pi">:</span>
<span class="na">type</span><span class="pi">:</span> <span class="s">NodePort</span>
<span class="na">ports</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">targetPort</span><span class="pi">:</span> <span class="m">80</span>
<span class="na">port</span><span class="pi">:</span> <span class="m">80</span>
<span class="na">nodePort</span><span class="pi">:</span> <span class="m">30008</span>
<span class="na">selector</span><span class="pi">:</span>
<span class="na">app</span><span class="pi">:</span> <span class="s">myapp</span>
<span class="na">type</span><span class="pi">:</span> <span class="s">front-end</span>
</code></pre></div></div>
<p>When the services are grouped together like this the service acts like a build in load balancer and will balancer loads across the pods using the following settings.</p>
<ul>
<li>Algorithm: Random</li>
<li>SessionAffinity: Yes</li>
</ul>
<p>If the pods map across multiple nodes in the cluster, K8s will automatically span the service across all nodes in the cluster.<br />
In this situation, the port 30008 will be made available across any node in the K8s cluster to the same service.</p>
<p>Create a Service named nginx-service of type NodePort to expose pod nginx’s port 80 on port 30080 on the nodes:<br />
<code class="highlighter-rouge">kubectl expose pod nginx --type=NodePort --port=80 --name=nginx-service --dry-run=client -o yaml</code><br />
<br />
<strong>Note:</strong> You use the <code class="highlighter-rouge">--port=XX</code> option here as we are telling the pod which port to open, whereas when creating services we are defining a type of port like <code class="highlighter-rouge">--node-port=30008</code> or <code class="highlighter-rouge">--target-port=80</code> or if you want to open the service port you can use either <code class="highlighter-rouge">--port=80</code>, which will assume a protocol of TCP or use <code class="highlighter-rouge">--protocol=TCP</code> together with <code class="highlighter-rouge">--port=80</code>. Alternatively you can short hand this as <code class="highlighter-rouge">--tcp=80:80</code> or <code class="highlighter-rouge">--udp=53:53</code>.<br />
<br />
(This will automatically use the pod’s labels as selectors, <a href="https://github.com/kubernetes/kubernetes/issues/25478">but you cannot specify the node port</a>. You have to generate a definition file and then add the node port in manually before creating the service with the pod.)<br />
Or<br />
<code class="highlighter-rouge">kubectl create service nodeport nginx --tcp=80:80 --node-port=30080 --dry-run=client -o yaml</code><br />
(This will not use the pods labels as selectors)<br />
Both the above commands have their own challenges. While one of it cannot accept a selector the other cannot accept a node port. I would recommend going with the <code class="highlighter-rouge">kubectl expose</code> command. If you need to specify a node port, generate a definition file using the same command and manually input the NodePort before creating the service.<br />
<br />
You can combine creating a POD and creating a ClusterIP service and exposing it using, <br />
<code class="highlighter-rouge">kubectl run httpd --image=httpd:alpine --port=80 --expose=true</code></p>
<h2 id="clusterip">ClusterIP</h2>
<p>Definition file</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">apiVersion</span><span class="pi">:</span> <span class="s">v1</span>
<span class="na">kind</span><span class="pi">:</span> <span class="s">Service</span>
<span class="na">metadata</span><span class="pi">:</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">back-end</span>
<span class="na">spec</span><span class="pi">:</span>
<span class="na">type</span><span class="pi">:</span> <span class="s">ClusterIP</span>
<span class="na">ports</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">targetPort</span><span class="pi">:</span> <span class="m">80</span>
<span class="na">port</span><span class="pi">:</span> <span class="m">80</span>
<span class="na">selector</span><span class="pi">:</span>
<span class="na">app</span><span class="pi">:</span> <span class="s">myapp</span>
<span class="na">type</span><span class="pi">:</span> <span class="s">back-end</span>
</code></pre></div></div>
<p>Get Services<br />
<code class="highlighter-rouge">kubectl get svc</code></p>
<p>Create a service named redis-service of type ClusterIP to expose pod redis on port 6379. <br />
<code class="highlighter-rouge">kubectl expose pod redis --port=6379 --name redis-service --dry-run=client -o yaml</code></p>
<p><code class="highlighter-rouge">kubectl create service clusterip redis --tcp=6379:6379 --dry-run=client -o yaml</code></p>
<p>(This will not use the pods labels as selectors, instead it will assume selectors as <strong>app=redis.</strong> <a href="https://github.com/kubernetes/kubernetes/issues/46191">You cannot pass in selectors as an option.</a> So it does not work very well if your pod has a different label set. So generate the file and modify the selectors before creating the service)</p>
<h2 id="loadbalancer">LoadBalancer</h2>
<p>The LoadBalancer type allow you to take advantage of native cloud load balancers within the K8s system. Only certain load balancer types are supported, such as GCP, AWS, or Azure.</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">apiVersion</span><span class="pi">:</span> <span class="s">v1</span>
<span class="na">kind</span><span class="pi">:</span> <span class="s">Service</span>
<span class="na">metadata</span><span class="pi">:</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">back-end</span>
<span class="na">spec</span><span class="pi">:</span>
<span class="na">type</span><span class="pi">:</span> <span class="s">LoadBalancer</span>
<span class="na">ports</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">targetPort</span><span class="pi">:</span> <span class="m">80</span>
<span class="na">port</span><span class="pi">:</span> <span class="m">80</span>
<span class="na">selector</span><span class="pi">:</span>
<span class="na">app</span><span class="pi">:</span> <span class="s">myapp</span>
<span class="na">type</span><span class="pi">:</span> <span class="s">back-end</span>
</code></pre></div></div>
<h1 id="namespaces">Namespaces</h1>
<p>Default one is called Default.<br />
All pods, deployments and services sit within a namespace.<br />
Default pods</p>
<ul>
<li>kube-system</li>
<li>Default</li>
<li>kube-public</li>
</ul>
<p>you can create your own to separate out all the resources, each namespace can have their own policies.<br />
To allow cross namespace communitcation you have to append the namespace of the other namespace.<br />
The default domain name for K8s is cluster.local<br />
The default domain name for services is svc.cluster.local<br />
A dev namespace within the local cluster you would create it in dev.svc.cluster.local<br />
To address a service within the default cluster in the dev namespace from the default namespace you would connect to it via servicename.dev.svc.cluster.local<br />
To create a pod within another namespace you would run <code class="highlighter-rouge">kubectl create -f pod-definition.yaml --namespace=dev</code><br />
Alternatively you can add <code class="highlighter-rouge">namespace: dev</code> to the yaml pod definition file like below.</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">apiVersion</span><span class="pi">:</span> <span class="s">v1</span>
<span class="s">kind Pod</span>
<span class="na">metadata</span><span class="pi">:</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">myapp-pod</span>
<span class="na">namespace</span><span class="pi">:</span> <span class="s">dev</span>
<span class="na">labels</span><span class="pi">:</span>
<span class="na">app</span><span class="pi">:</span> <span class="s">myapp</span>
<span class="na">type</span><span class="pi">:</span> <span class="s">front-end</span>
<span class="na">spec</span><span class="pi">:</span>
<span class="na">containers</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">nginx-container</span>
<span class="na">image</span><span class="pi">:</span> <span class="s">nginx</span>
</code></pre></div></div>
<p>Create with yaml definition file.<br />
Namespace definition file.</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">apiVersion</span><span class="pi">:</span> <span class="s">v1</span>
<span class="na">kind</span><span class="pi">:</span> <span class="s">Namespace</span>
<span class="na">metadata</span><span class="pi">:</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">dev</span>
</code></pre></div></div>
<p>Or run a create command<br />
<code class="highlighter-rouge">kubectl create namespace dev</code><br />
<br />
View pods in other namespaces<br />
<code class="highlighter-rouge">kubectl get pods --namespace=dev</code><br />
Alternatively<br />
<code class="highlighter-rouge">kubectl get pods -n=dev</code><br />
Or<br />
<code class="highlighter-rouge">kubectl get pods --all-namespaces</code><br />
Or<br />
<code class="highlighter-rouge">kubectl get pods -A</code><br />
<br />
To set the context for future commands as a static variable, you set the context like this.<br />
<code class="highlighter-rouge">kubectl config set-context $(kubectl config current-context) --namespace=dev</code><br />
Once complete, you can just run this to see pods in the dev namespace.<br />
<code class="highlighter-rouge">kubectl get pods</code></p>
<h2 id="resource-quota">Resource Quota</h2>
<p>Limit resources with a yaml file.</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">apiVersion</span><span class="pi">:</span> <span class="s">v1</span>
<span class="na">kind</span><span class="pi">:</span> <span class="s">ResourceQuota</span>
<span class="na">metadata</span><span class="pi">:</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">compute-quota</span>
<span class="na">namespace</span><span class="pi">:</span> <span class="s">dev</span>
<span class="na">spec</span><span class="pi">:</span>
<span class="na">hard</span><span class="pi">:</span>
<span class="na">pods</span><span class="pi">:</span> <span class="s2">"</span><span class="s">10"</span>
<span class="na">requests.cpu</span><span class="pi">:</span> <span class="s2">"</span><span class="s">4"</span>
<span class="na">requests.memory</span><span class="pi">:</span> <span class="s">5Gi</span>
<span class="na">limits.cpu</span><span class="pi">:</span> <span class="s2">"</span><span class="s">10"</span>
<span class="na">limits.memory</span><span class="pi">:</span> <span class="s">10Gi</span>
</code></pre></div></div>
<p>Create with<br />
<code class="highlighter-rouge">kubectl create -f compute-quota.yaml</code></p>
<h1 id="imperative-vs-declarative">Imperative vs Declarative</h1>
<h2 id="imperative">Imperative</h2>
<p>step by step instructions. How to do something. <br />
Create and update (edit) commands are imperative.<br />
If you are editing images, update the yaml file and use the <code class="highlighter-rouge">kubectl replace --force -f nginx.yaml</code> rather than editing a live object.</p>
<h2 id="declarative">Declarative</h2>
<p>just declaring the final destination, what to do, not how to do.<br />
Declarative command can carry out modifications of the entities by using the apply command.<br />
<code class="highlighter-rouge">kubectl apply -f nginx.yaml</code><br />
<br />
Create object with declarative approach<br />
<code class="highlighter-rouge">kubectl apply -f nginx.yaml</code><br />
To create multiple objects at once, run<br />
<code class="highlighter-rouge">kubectl apply -f /path/to/config-files</code><br />
<br />
Update running ones, run<br />
<code class="highlighter-rouge">kubectl apply -f nginx.yaml</code></p>
<h4 id="reference">Reference:</h4>
<p><a href="https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands">https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands</a><br />
<a href="https://kubernetes.io/docs/reference/kubectl/conventions/">https://kubernetes.io/docs/reference/kubectl/conventions/</a></p>
<h4 id="combining-commands">Combining commands</h4>
<p>Embed the expose option as part of the run command. This will create a pod and map a service to it to make it accessible.<br />
<code class="highlighter-rouge">kubectl run httpd --image=httpd:alpine --port=80 --expose=true</code></p>
<h3 id="apply-command">Apply command</h3>
<p>there is a ‘last applied configuration’ JSON file that contains the most recently applied configuration. It is used to compare what has changed over time and which settings should be applied to the live running YAML. It is stored in the metadata of the live configuration YAML and only used when the apply command is run.<br />
When you use the apply command it compares what is in the local yaml file against what is in the K8s live object configuration in K8s memory.<br />
<strong>Once you use the apply command, don’t switch to using imperative commands</strong> because the configuration in the local yaml file won’t contain those command line run imperative created objects. <br />
<br />
Live configuration without using the apply command</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">apiVersion</span><span class="pi">:</span> <span class="s">v1</span>
<span class="na">kind</span><span class="pi">:</span> <span class="s">Pod</span>
<span class="na">metadata</span><span class="pi">:</span>
<span class="na">creationTimestamp</span><span class="pi">:</span> <span class="s2">"</span><span class="s">2023-01-12T10:59:19Z"</span>
<span class="na">labels</span><span class="pi">:</span>
<span class="na">run</span><span class="pi">:</span> <span class="s">httpd</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">httpd</span>
<span class="na">namespace</span><span class="pi">:</span> <span class="s">default</span>
<span class="na">resourceVersion</span><span class="pi">:</span> <span class="s2">"</span><span class="s">856"</span>
<span class="na">uid</span><span class="pi">:</span> <span class="s">6a3c37d8-163e-4f6c-a9bd-44a5af858657</span>
<span class="na">spec</span><span class="pi">:</span>
<span class="na">containers</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">image</span><span class="pi">:</span> <span class="s">httpd:alpine</span>
<span class="na">imagePullPolicy</span><span class="pi">:</span> <span class="s">IfNotPresent</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">httpd</span>
<span class="na">ports</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">containerPort</span><span class="pi">:</span> <span class="m">8080</span>
<span class="na">protocol</span><span class="pi">:</span> <span class="s">TCP</span>
<span class="na">resources</span><span class="pi">:</span> <span class="pi">{}</span>
<span class="na">terminationMessagePath</span><span class="pi">:</span> <span class="s">/dev/termination-log</span>
<span class="na">terminationMessagePolicy</span><span class="pi">:</span> <span class="s">File</span>
<span class="na">volumeMounts</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">mountPath</span><span class="pi">:</span> <span class="s">/var/run/secrets/kubernetes.io/serviceaccount</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">kube-api-access-njlz4</span>
<span class="na">readOnly</span><span class="pi">:</span> <span class="no">true</span>
<span class="na">dnsPolicy</span><span class="pi">:</span> <span class="s">ClusterFirst</span>
<span class="na">enableServiceLinks</span><span class="pi">:</span> <span class="no">true</span>
<span class="na">nodeName</span><span class="pi">:</span> <span class="s">controlplane</span>
<span class="na">preemptionPolicy</span><span class="pi">:</span> <span class="s">PreemptLowerPriority</span>
<span class="na">priority</span><span class="pi">:</span> <span class="m">0</span>
<span class="na">restartPolicy</span><span class="pi">:</span> <span class="s">Always</span>
<span class="na">schedulerName</span><span class="pi">:</span> <span class="s">default-scheduler</span>
<span class="na">securityContext</span><span class="pi">:</span> <span class="pi">{}</span>
<span class="na">serviceAccount</span><span class="pi">:</span> <span class="s">default</span>
<span class="na">serviceAccountName</span><span class="pi">:</span> <span class="s">default</span>
<span class="na">terminationGracePeriodSeconds</span><span class="pi">:</span> <span class="m">30</span>
<span class="na">tolerations</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">effect</span><span class="pi">:</span> <span class="s">NoExecute</span>
<span class="na">key</span><span class="pi">:</span> <span class="s">node.kubernetes.io/not-ready</span>
</code></pre></div></div>
<p>Live configuration when using the apply command to create the object.</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">apiVersion</span><span class="pi">:</span> <span class="s">v1</span>
<span class="na">kind</span><span class="pi">:</span> <span class="s">Pod</span>
<span class="na">metadata</span><span class="pi">:</span>
<span class="na">annotations</span><span class="pi">:</span>
<span class="na">kubectl.kubernetes.io/last-applied-configuration</span><span class="pi">:</span> <span class="pi">|</span>
<span class="s">{"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"creationTimestamp":null,"labels":{"run":"httpd"},"name":"httpd","namespace":"default"},"spec":{"containers":[{"image":"httpd:alpine","name":"httpd","ports":[{"containerPort":8080}],"resources":{}}],"dnsPolicy":"ClusterFirst","restartPolicy":"Always"},"status":{}}</span>
<span class="na">creationTimestamp</span><span class="pi">:</span> <span class="s2">"</span><span class="s">2023-01-12T11:08:35Z"</span>
<span class="na">labels</span><span class="pi">:</span>
<span class="na">run</span><span class="pi">:</span> <span class="s">httpd</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">httpd</span>
<span class="na">namespace</span><span class="pi">:</span> <span class="s">default</span>
<span class="na">resourceVersion</span><span class="pi">:</span> <span class="s2">"</span><span class="s">780"</span>
<span class="na">uid</span><span class="pi">:</span> <span class="s">44e43f37-7a8e-4f99-a064-7fb4ec05dca2</span>
<span class="na">spec</span><span class="pi">:</span>
<span class="na">containers</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">image</span><span class="pi">:</span> <span class="s">httpd:alpine</span>
<span class="na">imagePullPolicy</span><span class="pi">:</span> <span class="s">IfNotPresent</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">httpd</span>
<span class="na">ports</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">containerPort</span><span class="pi">:</span> <span class="m">8080</span>
<span class="na">protocol</span><span class="pi">:</span> <span class="s">TCP</span>
<span class="na">resources</span><span class="pi">:</span> <span class="pi">{}</span>
<span class="na">terminationMessagePath</span><span class="pi">:</span> <span class="s">/dev/termination-log</span>
<span class="na">terminationMessagePolicy</span><span class="pi">:</span> <span class="s">File</span>
<span class="na">volumeMounts</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">mountPath</span><span class="pi">:</span> <span class="s">/var/run/secrets/kubernetes.io/serviceaccount</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">kube-api-access-jrkbv</span>
<span class="na">readOnly</span><span class="pi">:</span> <span class="no">true</span>
<span class="na">dnsPolicy</span><span class="pi">:</span> <span class="s">ClusterFirst</span>
<span class="na">enableServiceLinks</span><span class="pi">:</span> <span class="no">true</span>
<span class="na">nodeName</span><span class="pi">:</span> <span class="s">controlplane</span>
<span class="na">preemptionPolicy</span><span class="pi">:</span> <span class="s">PreemptLowerPriority</span>
<span class="na">priority</span><span class="pi">:</span> <span class="m">0</span>
<span class="na">restartPolicy</span><span class="pi">:</span> <span class="s">Always</span>
<span class="na">schedulerName</span><span class="pi">:</span> <span class="s">default-scheduler</span>
<span class="na">securityContext</span><span class="pi">:</span> <span class="pi">{}</span>
<span class="na">serviceAccount</span><span class="pi">:</span> <span class="s">default</span>
</code></pre></div></div>
<p>Live configuration after apply command run to change the image type to apache</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">apiVersion</span><span class="pi">:</span> <span class="s">v1</span>
<span class="na">kind</span><span class="pi">:</span> <span class="s">Pod</span>
<span class="na">metadata</span><span class="pi">:</span>
<span class="na">annotations</span><span class="pi">:</span>
<span class="na">kubectl.kubernetes.io/last-applied-configuration</span><span class="pi">:</span> <span class="pi">|</span>
<span class="s">{"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"creationTimestamp":null,"labels":{"run":"httpd"},"name":"httpd","namespace":"default"},"spec":{"containers":[{"image":"httpd:apache","name":"httpd","ports":[{"containerPort":8080}],"resources":{}}],"dnsPolicy":"ClusterFirst","restartPolicy":"Always"},"status":{}}</span>
<span class="na">creationTimestamp</span><span class="pi">:</span> <span class="s2">"</span><span class="s">2023-01-12T11:16:07Z"</span>
<span class="na">labels</span><span class="pi">:</span>
<span class="na">run</span><span class="pi">:</span> <span class="s">httpd</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">httpd</span>
<span class="na">namespace</span><span class="pi">:</span> <span class="s">default</span>
<span class="na">resourceVersion</span><span class="pi">:</span> <span class="s2">"</span><span class="s">987"</span>
<span class="na">uid</span><span class="pi">:</span> <span class="s">ebc7e191-b612-4ec6-b32a-057791cbf8ea</span>
<span class="na">spec</span><span class="pi">:</span>
<span class="na">containers</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">image</span><span class="pi">:</span> <span class="s">httpd:apache</span>
<span class="na">imagePullPolicy</span><span class="pi">:</span> <span class="s">IfNotPresent</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">httpd</span>
<span class="na">ports</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">containerPort</span><span class="pi">:</span> <span class="m">8080</span>
<span class="na">protocol</span><span class="pi">:</span> <span class="s">TCP</span>
<span class="na">resources</span><span class="pi">:</span> <span class="pi">{}</span>
<span class="na">terminationMessagePath</span><span class="pi">:</span> <span class="s">/dev/termination-log</span>
<span class="na">terminationMessagePolicy</span><span class="pi">:</span> <span class="s">File</span>
<span class="na">volumeMounts</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">mountPath</span><span class="pi">:</span> <span class="s">/var/run/secrets/kubernetes.io/serviceaccount</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">kube-api-access-swpn8</span>
<span class="na">readOnly</span><span class="pi">:</span> <span class="no">true</span>
<span class="na">dnsPolicy</span><span class="pi">:</span> <span class="s">ClusterFirst</span>
<span class="na">enableServiceLinks</span><span class="pi">:</span> <span class="no">true</span>
<span class="na">nodeName</span><span class="pi">:</span> <span class="s">controlplane</span>
<span class="na">preemptionPolicy</span><span class="pi">:</span> <span class="s">PreemptLowerPriority</span>
<span class="na">priority</span><span class="pi">:</span> <span class="m">0</span>
<span class="na">restartPolicy</span><span class="pi">:</span> <span class="s">Always</span>
<span class="na">schedulerName</span><span class="pi">:</span> <span class="s">default-scheduler</span>
<span class="na">securityContext</span><span class="pi">:</span> <span class="pi">{}</span>
<span class="na">serviceAccount</span><span class="pi">:</span> <span class="s">default</span>
</code></pre></div></div>Simon GreavesThe following blog series contains my notes from the Udemy training course in preperation for the Certified Kubernetes Administrator (CKA) exam. Use the code - DEVOPS15 - while registering for the CKA or CKAD exams at Linux Foundation to get a 15% discount. Labs You need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. It is recommended to run this tutorial on a cluster with at least two nodes that are not acting as control plane hosts. If you do not already have a cluster, you can create one by using minikube or you can use one of these Kubernetes playgrounds: Killercoda Play with KubernetesFoundational Linux Commands2022-01-12T00:00:00+00:002022-01-12T00:00:00+00:00/Foundational-Linux-Commands<p>| Command | Description |
| — | — |
| echo | Output to the screen |
| whoami | Display logged in user |
| cd ~ | Change directory into current users home directory |
| cat | concatenate |
| pwd | Print working directory (current directory) |
| ls <folder> -a | list all folder contents (including hidden files) |
| <CTRL + L> | Clear terminal |
| find <location> -name <filename> | Find the file with the name <filename> in the <location> specified. |
| grep “SearchString*” <filename> | Search the filename file for the searchstring specified |
| & | Run command in background |
| && | combine multiple commands into one line, if command one fails, command two won’t run |
| > | Redirector |
| » | appends the redirect, rather than overwriting |
| man <command> | Display the manual for the command |
| touch file1 file2 | create two blank files in the current directory. One called file1 one called file2 |
| mkdir | Make a directory |
| cp | copy a file or folder |
| mv | move a file or folder |
| rm -R <directoryname> | remove a file or folder called <directoryname> and all its sub-folder contents |
| file <filename> | determine the type of a file (e.g., ASCII) |
| su -l <user> | substitute to user using their login variables (including their home directory and environmental variables). You need to know the users password to substitute the user |
| VIM | Vi Improved |
| wget | download files from the web using http |
| scp <Source> <Destination> | Secure copy files from <source> to <destination> |
| python3 -m http.server | Start the python web server to serve the current directory and contents via http |
| ps aux | Show processes run by other users and those that don’t run from a session like system processes |
| htop | highlighted view of top |
| kill <processID> | Kill the process with the ID of <processID> |
| SIGTERM <processID> | Cleanly kill a process with ID of <processID> |
| SIGKILL <processID> | Kill the process without cleanup |
| SIGSTOP <processID> | Stop/suspend the process without killing it |
| systemctl [option] [service] | System Control of services, options include start, stop, enable (start on boot), and disable (disable boot option) |
| <CTRL+Z> | Background a running process, like a script. Shows as T^Z in the terminal |
| fg | bring background running process to foreground |
| crontab -e | Edit crontab. Crontab is a text file responsible for managing cron jobs |
<!--more-->
When creating a new user, a new group with the same name is also created.</p>
<h2 id="permissions">Permissions</h2>
<p>Permissions are displayed like the following.<br />
<code class="highlighter-rouge">-rwxrwxrwx</code><br />
These are split into permission sets.</p>
<table>
<thead>
<tr>
<th>File Type (- file) (d directory)</th>
<th>File Owner Set</th>
<th>Group Owner Set</th>
<th>All Other Users Set</th>
</tr>
</thead>
<tbody>
<tr>
<td>-</td>
<td>rwx</td>
<td>rwx</td>
<td>rwx</td>
</tr>
</tbody>
</table>
<h2 id="common-directories">Common Directories</h2>
<p>/etc - System configuration data.<br />
/var - Variable data, frequent data writes like logs.<br />
/root - Home for the root system user. <br />
/tmp - Temporary directory, when the computer is restarted, the contents is deleted. Accessible for everyone on the system.</p>
<h2 id="cron-jobs">Cron jobs</h2>
<p>Cron jobs are used to execute commands at a particular time. Using the table below you can map the hour, minute etc. to the correct position when creating the entires in the crontab file.</p>
<table>
<thead>
<tr>
<th>Value</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>MIN</td>
<td>What minute to execute at</td>
</tr>
<tr>
<td>HOUR</td>
<td>What hour to execute at</td>
</tr>
<tr>
<td>DOM</td>
<td>What day of the month to execute at</td>
</tr>
<tr>
<td>MON</td>
<td>What month of the year to execute at</td>
</tr>
<tr>
<td>DOW</td>
<td>What day of the week to execute at</td>
</tr>
<tr>
<td>CMD</td>
<td>The actual command that will be executed.</td>
</tr>
</tbody>
</table>
<p>You can use <code class="highlighter-rouge">*</code> as a wildcard.</p>
<p><strong>Example</strong><br />
<code class="highlighter-rouge">0 *12 * * * cp -R /home/<username>/Documents /var/backups/</code></p>
<p>This will copy the contents and subfolders of /home/user/Documents to the /var/backups/ directory on the hour, every 12 hours, every day of the month, every month, every day of the week.</p>
<p><strong>Useful Crontab generators</strong><br />
<a href="https://crontab-generator.org/">https://crontab-generator.org</a> <br />
<a href="https://crontab.guru/">https://crontab.guru</a></p>
<h2 id="apt">apt</h2>
<p>apt is used to install, update and remove software. apt repositories are used to manage the source of the software.<br />
To verify the integrity of the software, use GPG (Gnu Privacy Guard) keys. Add the GPG key before you add the repository.</p>
<p><strong>Example</strong><br />
Download the sublimetext GPG key and then add it to the apt-key repository.<br />
<code class="highlighter-rouge">wget -qO - https://download.sublimetext.com/sublimehq-pub.gpg | sudo apt-key add -</code><br />
Now add the sublimetext repository to the apt sources list.<br />
<code class="highlighter-rouge">touch /etc/apt/sources.list.d/sublime-text.list</code><br />
Now edit the sublime-text.list file.<br />
<code class="highlighter-rouge">vi /etc/apt/sources.list.d/sublime-text.list</code><br />
Add the following to the file.<br />
<code class="highlighter-rouge">deb https://download.sublimetext.com/ apt/stable/</code><br />
Update apt to recognise the new entry.<br />
<code class="highlighter-rouge">apt update</code><br />
Now install it.<br />
<code class="highlighter-rouge">apt install sublime-text</code></p>
<p>To remove<br />
<code class="highlighter-rouge">add-apt-repository --remove ppa:PPA_NAME/ppa</code><br />
Or delete the .list file created.<br />
Once deleted, remote the software.<br />
<code class="highlighter-rouge">apt remove <SoftwareName></code></p>
<h2 id="find">find</h2>
<p>Use the find command to search for items.<br />
Find syntax is <em>find where what</em><br />
If nowhere is specified, find will search the current working directory and all its subdirectories.</p>
<p><strong>Flags</strong><br />
The following flags can be used with find to make searching easier.<br />
<code class="highlighter-rouge">-type <d></code> (directories) or <code class="highlighter-rouge"><f></code> (files)<br />
<code class="highlighter-rouge">-name</code> case sensitive name search<br />
<code class="highlighter-rouge">-iname</code> case insensitive name search<br />
<code class="highlighter-rouge">-size</code> Size of the file. Use with <code class="highlighter-rouge">-n</code> smaller than <code class="highlighter-rouge">n</code>, <code class="highlighter-rouge">+n</code> greater than <code class="highlighter-rouge">n</code>, <code class="highlighter-rouge">n</code> on its own is exactly <code class="highlighter-rouge">n</code> sized. Size also requires a suffix, <code class="highlighter-rouge">c</code> for bytes, <code class="highlighter-rouge">k</code> for KiBs and <code class="highlighter-rouge">m</code> for MiB. Putting these together, to find one with is larger than 1 MiB use, <code class="highlighter-rouge">+1M</code>.<br />
<code class="highlighter-rouge">-perm</code> permissions flag. Can specify symbolic form <code class="highlighter-rouge">u=r</code> or octal form <code class="highlighter-rouge">644</code>.<br />
Time based searches are performed with a word <code class="highlighter-rouge">min</code> for minutes or <code class="highlighter-rouge">time</code> for days, used together with a prefix of <code class="highlighter-rouge">a</code> for accessed, <code class="highlighter-rouge">m</code> for modified or <code class="highlighter-rouge">c</code> for changed. Example <code class="highlighter-rouge">-mmin -5</code> will find files that were modified in the last 5 minutes and <code class="highlighter-rouge">-ctime -2</code> will find all files changed in the last 2 days.<br />
To find files with SUID permissions set use the flag <code class="highlighter-rouge">-perm /u=s</code>.<br />
Exmaple.<br />
<code class="highlighter-rouge">find /usr/bin -type f -user root -perm /u=s</code></p>
<h4 id="hiding-permission-denied-messages">Hiding Permission denied messages</h4>
<p>When performing a find, you will see permission denied messages when trying to access files and directories that the user runnning the command does not have permission to access. To hide these permission denied messages from the search, use this command.<br />
<code class="highlighter-rouge">find / -type f -user <username> 2>&1 | grep -v "Permission denied"</code></p>
<p>This will find all files owned by the user specified and hide Permission denied from the output. It uses the standard error (stderr) code <code class="highlighter-rouge">2</code> and combines it into the same output as the standard output (stdout) code <code class="highlighter-rouge">1</code>, then filters with grep, performing an <code class="highlighter-rouge">invert-match</code> to select non-matching lines using <code class="highlighter-rouge">-v</code> to hide all “Permission denied” messages.<br />
An alternative way is to suppress all errors by redirecting to /dev/null. Example.<br />
<code class="highlighter-rouge">find / -type f -user <username> 2> /dev/null</code><br />
The disadvantage of this is that it will output all errors encountered running the command and not just the permission denied ones.</p>
<p><strong>Useful guides</strong> <br />
Bash Scripting - <a href="https://tryhackme.com/room/bashscripting">https://tryhackme.com/room/bashscripting</a><br />
Regular Expressions - <a href="https://tryhackme.com/room/catregex">https://tryhackme.com/room/catregex</a></p>Simon GreavesCommand Description echo Output to the screen whoami Display logged in user cd ~ Change directory into current users home directory cat concatenate pwd Print working directory (current directory) ls <folder> -a list all folder contents (including hidden files) <CTRL + L> Clear terminal find <location> -name <filename> Find the file with the name <filename> in the <location> specified. grep “SearchString*” <filename> Search the filename file for the searchstring specified & Run command in background && combine multiple commands into one line, if command one fails, command two won’t run > Redirector » appends the redirect, rather than overwriting man <command> Display the manual for the command touch file1 file2 create two blank files in the current directory. One called file1 one called file2 mkdir Make a directory cp copy a file or folder mv move a file or folder rm -R <directoryname> remove a file or folder called <directoryname> and all its sub-folder contents file <filename> determine the type of a file (e.g., ASCII) su -l <user> substitute to user using their login variables (including their home directory and environmental variables). You need to know the users password to substitute the user VIM Vi Improved wget download files from the web using http scp <Source> <Destination> Secure copy files from <source> to <destination> python3 -m http.server Start the python web server to serve the current directory and contents via http ps aux Show processes run by other users and those that don’t run from a session like system processes htop highlighted view of top kill <processID> Kill the process with the ID of <processID> SIGTERM <processID> Cleanly kill a process with ID of <processID> SIGKILL <processID> Kill the process without cleanup SIGSTOP <processID> Stop/suspend the process without killing it systemctl [option] [service] System Control of services, options include start, stop, enable (start on boot), and disable (disable boot option) <CTRL+Z> Background a running process, like a script. Shows as T^Z in the terminal fg bring background running process to foreground crontab -e Edit crontab. Crontab is a text file responsible for managing cron jobsThe VCDX Defence2022-01-05T00:00:00+00:002022-01-05T00:00:00+00:00/The-VCDX-Defence<h1 id="overview">Overview</h1>
<p>A few weeks ago, in late 2021, I sat and passed the VMware Certified Design Expert on Datacenter Virtualization (VCDX-DCV). The purpose of this post is to serve as an overview of what specific actions and tactical steps I took that I believe helped me pass the defence stage of the process.</p>
<p>To pass the VCDX, regardless of technology track you need to complete some specific steps. They are:-</p>
<ul>
<li>Prepare and submit a production design package consisting of a design written to conform with business goals and business requirements, including risk management, and information on how to implement, operate, and validate said design.</li>
<li>Following submission, the design package is reviewed by a panel of experts to ensure it complies with the VCDX framework and meets the key objectives outlined in the VCDX blueprint.</li>
<li>Part 1 of the defence - Defend the design in a live panel review where you have 75 minutes to present your design to the panel and then defend your design decisions against the questions from the panel.</li>
<li>Part 2 of the defence - After a short break you are given a scenario by the panel and you have 45 minutes to question the panelists and deduce some specific requirements, identify any key risks and constraints and turn these into a logical design which forms the foundations of an entire solution design.<br />
<!--more--></li>
</ul>
<h1 id="the-presentation">The Presentation</h1>
<p>Working on the assumption that you have already produced a design, submitted it and been invited to defend, the next stage is the defence.<br />
Here is your opportunity to <strong>Succiently</strong> present your design in a series of slides, covering the key areas of the design. As per the blueprint, this should provide an summary of the design, covering the company background, key business requirements, conceptual, logical and physical design for the key items of Virtual Datacenter Management, Virtual Machine, Compute, Storage, Network & BCDR.</p>
<p>The best advice I can offer when preparing the slides is to ensure that in each slide you include enough information for you to be able to mentally recall the key decisions that made up that part. As an example, if you are discussing the network elements, ensure you know enough details to prompt yourself to discuss each design principal (Availability, Manageability, Performance, Security and Recoverability) without having to bring up other slides to back up this information.<br />
Really focus on the key decisions, my design included lots and lots of different design decisions, but not all were really specific to the key business requirements. They partly met the requirement, or acted as additional decisions to support another decision (such as priorities set for vMotion Traffic when using Network IO Control). These key items (using Network IO Control) I made sure to cover off when on this slide. My thoughts were if I reduced the unprompted information I could save some time for any questions where I hadn’t prepared an answer.<br />
Try and provide a summary of the decisions, rather than the specific details. Say “I chose this network design decision to meet requirement X, and to meet the performance & availability SLA, whilst remaining within the constraints”, rather than “I chose 10Gb networks because they offer better throughput”.</p>
<h2 id="design-decision-justification">Design Decision Justification</h2>
<p>Every design decision must map to a requirement, if you can’t justify every single design decision it shouldn’t be in your design.</p>
<h2 id="know-your-design">Know Your Design</h2>
<p>This is a common theme amongst fellow VCDX blog posts, knowing your design is crucial to passing the VCDX.<br />
You might see this and think, “of course I know my design, I wrote it!” but I know from first hand experience this is easier said then done. My design alone was over 200 pages, with 180+ design decisions, not including supporting documents! That’s a lot of information to be able to recall off the top of your head!<br />
My suggestion here is to consider re-reading your design the day before your defence so its fresh in your head, and focus in on the justifications for each design and associated risks and alternatives. This way when you are challenged on your design choices, you will fully understand why you went with that choice and not an alternative.</p>
<h2 id="backup-slides">Backup Slides</h2>
<p>Beyond the main slides that cover the key design pillars, you will want to include some backup slides with additional information in case you are pressed on a particular subject and can’t cover it in the main slides. Areas such as lifecycle management or further information on performance analysis and platform sizing to meet the performance SLA. Knowing these slides is just as crucial as knowing the design, you don’t want to waste time in your defence trying to find the correct slide. As before keep it succient and easy to understand.</p>
<h2 id="whiteboarding">Whiteboarding</h2>
<p>The whiteboard can prove useful during the presentation defence, depending on the questioning from the panelists. The whiteboard is your opportunity to showcase your design skills, perhaps down to the physical layer which you wouldn’t cover in the scenario defence. The whiteboard will not typically form part of your presentation (although I think it would be interesting to see one that did), but you may need it to cover areas in a bit more detail.<br />
Listen for clues from the panelists such as “tell me more about how you would do that?”, or “show me how you would do it if that constraint wasn’t in your design?”.</p>
<h2 id="mock-defences">Mock Defences</h2>
<p>Mock defences against mock panelists are really useful to help you practice working through your presentation to ensure you have covered all the key areas of the blueprint, address any items you may have forgotten from your presentation, and get some real world practice talking through the slides and navigating to backup slides.<br />
Apart from mock panelists, I made sure to practice going through my main slides uninterrupted. I repeated this every few weeks and a couple of times a day just before the exam so that my presentation flowed a lot more naturally. This helped me ensure I knew my presentation well and could easily jump to any slide and talk through it in a few minutes.</p>
<h1 id="the-break">The Break</h1>
<p>For me, this was the worst part! I was unable to leave the room and was buzzing with adrenaline by this point which made settling into the scenario harder. I think I would have preferred to go straight into the scenario. That said I think the break is important because it helps you take a few minutes to put the presentation behind you, because if you feel you performed strongly or not, there is nothing you can do about it now. For any areas you think of that didn’t go as planned, (think Availability, Manageability, Performance, Security and Recoverability (or AMRPS) try and cover those in the scenario defence after the break.<br />
If you feel stressed just focus on your breathing, close your eyes and take deep breaths to relax.</p>
<h1 id="the-scenario">The Scenario</h1>
<p>Working through a scenario in 45 minutes requires practice. Practice areas such as time management, requirements gathering, risk and constraint identification, and whiteboarding conceptual and logical designs. The scenario you will work through will likely be different for everyone, something that involves a ‘Swiss Army Knife’ way of thinking. As the scenarios can vary significantly its not something you get good at by asking the same questions over and over again, its challenges you to think on your feet and be prepared to modify your design on the fly as the customer requirements given by the panelists change your proposed design. Just like with real customers, this modification can change part way through the scenario defence, forcing you to revisit some key elements of your design and forcing you to change it, possibly with only a few minutes left in the defence.</p>
<h2 id="whiteboarding-1">Whiteboarding</h2>
<p>I found it useful to divide my whiteboad into columns where I captured Requirements, Constraints and Risks. I also added a Parking area for any information that was incomplete. This isn’t in the blueprint but I think it worked well for me. Be careful with this that you don’t park too much as the panelists might suprise you with the information which modifies some of the key elements of your design. I also included a space for assumptions, but ideally you want to keep those to a minimum, as time management is crucial you might be able to use some temporary assumptions to help you start a conceptual and logical design and then, just like in the real world, modify the design if those assumptions turn out to be incorrect.</p>
<h2 id="requirements-gathering">Requirements Gathering</h2>
<p>Ensure you gather sufficient requirements to cover all the design principals (AMPRS).<br />
The requirements gathering is about showing your ability to gather enough requirements to form the foundations of a solution design. There are no right/wrong ways to do this, it really depends on the situation. The way I would design a solution with no compliance constraints and no budget restrictions are significantly different to how I would design it for a highly constrained budget that must comply with strict compliancy standards.<br />
A key suggestion I picked up on time management was to be direct in my questioning when gathering requirements, ask directly for the SLA used to measure availability and performance, even if you don’t get a direct answer, you will save valuable seconds getting to the point of the question.</p>
<h3 id="key-requirements-and-constraints">Key Requirements and Constraints</h3>
<p>There are some requirements given to you by the panelists that might not be key requirements, they also may withhold some key requirements or constraints which can signicantly change the trajectory of your design. Areas such as compliance is one, if you have been given a scenario and then discover it requires PCI compliance, this will dictate how you design the management plane, encryption, two-factor authentication etc. I found it useful to read up on some key compliance types before the defence, PCI, HIPPA, SOX, GDPR. By reading up on these I knew how I needed to design encryption etc. If you are unsure you can always ask the panelists if they require storage encryption in transit etc. or use a working assumption if its not clear. Hopefully by doing this you can spend less time asking questions on security or managability etc. for each design pillar (e.g., compute, storage networking), and instead focus on other areas you haven’t addressed.</p>
<h1 id="the-wait">The Wait</h1>
<p>It takes up to 10 business days to get your result, use this time to make lots of notes on areas where you could have made improvements and any questions that you were unable to answer in case you don’t pass and require another attempt.</p>
<h1 id="the-result">The Result</h1>
<p>When you have the result, remember, what you have learned along the way has made you a better Architect, regardless of outcome. You are better all round as this process has taught you to really focus on why decisions must be made, something which will benefit you and every customer you work with in the future.<br />
I hope you pass, and I will look forward to seeing you in the club soon!</p>
<p>Good luck!</p>Simon GreavesOverview A few weeks ago, in late 2021, I sat and passed the VMware Certified Design Expert on Datacenter Virtualization (VCDX-DCV). The purpose of this post is to serve as an overview of what specific actions and tactical steps I took that I believe helped me pass the defence stage of the process. To pass the VCDX, regardless of technology track you need to complete some specific steps. They are:- Prepare and submit a production design package consisting of a design written to conform with business goals and business requirements, including risk management, and information on how to implement, operate, and validate said design. Following submission, the design package is reviewed by a panel of experts to ensure it complies with the VCDX framework and meets the key objectives outlined in the VCDX blueprint. Part 1 of the defence - Defend the design in a live panel review where you have 75 minutes to present your design to the panel and then defend your design decisions against the questions from the panel. Part 2 of the defence - After a short break you are given a scenario by the panel and you have 45 minutes to question the panelists and deduce some specific requirements, identify any key risks and constraints and turn these into a logical design which forms the foundations of an entire solution design.Run Jekyll Static Content Website on Raspberry Pi2021-12-11T00:00:00+00:002021-12-11T00:00:00+00:00/run-jekyll-static-content-website-on-raspberry-pi<h1 id="overview">Overview</h1>
<p>I run this static content website on Jekyll from files that are stored on GitHub.</p>
<p>To edit posts or add new content I would normally run a dev copy of the site locally on my laptop with Jekyll installed and modify it with Visual Studio Code then upload the changes to the live site on GitHub using git command line tools.<br />
This works well except for those times I am not sat in front of my laptop, like now where I am sat on my iPad writing this. I wanted a solution where it could be hosted at home somewhere and then access it from mulitple locations and devices. My first thought was a VM (obviously, I am a VMware nerd after all!). This is ok if you don’t mind running a server 24/7 to host the VM, but I wanted something less power (and money) hungry, like my Raspberry Pi I use to run my home network tools, which uses a tiny amount of power and runs exceptionally quitely.</p>
<p>There are a few different blog posts out there with guidance on how to do this, but I wasn’t able to easily find one that was recent and with information that worked for my deployment. My Pi is a Raspberry Pi 4 with a default out of the box Raspberry Pi OS GUI installed, and a bunch of other software like Office applications, Scratch, browser and a few others. It also includes some of the prerequiste software like Ruby, however my version of Ruby didn’t work with the guides, and when I updated to a new version I ran into challenges as well, so this is what I did to successfully install and run my static site on Jekyll and then publish to GitHub, for your enjoyment!</p>
<p>First things first, check your version and if you are on an old version, we will update it to v3.x a bit later on. <br />
<code class="highlighter-rouge">ruby --version</code><br />
Find out where its installed. <br />
<code class="highlighter-rouge">which ruby</code><br />
Check you have <code class="highlighter-rouge">gem</code>, <code class="highlighter-rouge">gcc</code>, <code class="highlighter-rouge">g++</code> and <code class="highlighter-rouge">make</code> installed. These are required to run Jekyll.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gem -v
gcc -v
g++ -v
make -v
</code></pre></div></div>
<p>Make a directory to store your static content website. <br />
<code class="highlighter-rouge">mkdir website</code><br />
Go into the directory.<br />
<code class="highlighter-rouge">cd website/</code><br />
Prepare your bashrc variables for the upcoming installs.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>echo '# Install Ruby Gems to ~/gems' >> ~/.bashrc
echo 'export GEM_HOME="$HOME/gems"' >> ~/.bashrc
echo 'export PATH="$HOME/gems/bin:$PATH"' >> ~/.bashrc
</code></pre></div></div>
<p>Reload bashrc<br />
<code class="highlighter-rouge">source ~/.bashrc</code></p>
<p>Prepare the website directory with your existing static content site by cloning the remote public site to your local website directory.<br />
<code class="highlighter-rouge">git clone https://github.com/USERNAME/blog</code><br />
Initialize the local repository.<br />
<code class="highlighter-rouge">git init</code><br />
Add the remote origin copy, which in my instance is in my master fork on GitHub.<br />
<code class="highlighter-rouge">git remote add origin https://github.com/USERNAME/blog</code><br />
Verify its set correctly.<br />
<code class="highlighter-rouge">git status</code><br />
Pull the origin copy, just to make sure you have a synchronous copy of what’s on GitHub.<br />
<code class="highlighter-rouge">git pull origin master</code> <br />
Verify status again.<br />
<code class="highlighter-rouge">git status</code></p>
<p>Now’s the time to update Ruby to v3.x.<br />
Add the script to install the latest Ruby instance.<br />
<code class="highlighter-rouge">wget https://gist.githubusercontent.com/blacktm/8302741/raw/install_ruby_rpi.sh</code><br />
Run the install script (This takes a little while to install). <br />
<code class="highlighter-rouge">bash install_ruby_rpi.sh</code><br />
Reload the bashrc.<br />
<code class="highlighter-rouge">source ~/.bashrc</code><br />
Verify the installed Ruby version, checking its now updated. <br />
<code class="highlighter-rouge">which ruby</code><br />
<code class="highlighter-rouge">ruby --version</code><br />
Install bundler using Gem<br />
<code class="highlighter-rouge">gem install bundler</code><br />
Install Jekyll <br />
<code class="highlighter-rouge">bundle install</code> <br />
If the install fails, update it first then install.<br />
Update the bundle <br />
<code class="highlighter-rouge">bundle update</code><br />
<code class="highlighter-rouge">bundle install</code><br />
Finally serve the Jekyll site. Note: If you want to access it from a remote session, like an iPad or Phone browser, specify the <code class="highlighter-rouge">--host IP_ADDPRESS</code> variable at the end.<br />
<code class="highlighter-rouge">bundle exec jekyll serve --host 192.168.2.61</code></p>
<p>Now you have the site up and running you can use the Git command line tools to upload updated content.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git status
git add -A
git status
git commit -m "New Comments on why updated or added"
git status
git push origin master
git status
</code></pre></div></div>Simon GreavesOverview I run this static content website on Jekyll from files that are stored on GitHub. To edit posts or add new content I would normally run a dev copy of the site locally on my laptop with Jekyll installed and modify it with Visual Studio Code then upload the changes to the live site on GitHub using git command line tools. This works well except for those times I am not sat in front of my laptop, like now where I am sat on my iPad writing this. I wanted a solution where it could be hosted at home somewhere and then access it from mulitple locations and devices. My first thought was a VM (obviously, I am a VMware nerd after all!). This is ok if you don’t mind running a server 24/7 to host the VM, but I wanted something less power (and money) hungry, like my Raspberry Pi I use to run my home network tools, which uses a tiny amount of power and runs exceptionally quitely. There are a few different blog posts out there with guidance on how to do this, but I wasn’t able to easily find one that was recent and with information that worked for my deployment. My Pi is a Raspberry Pi 4 with a default out of the box Raspberry Pi OS GUI installed, and a bunch of other software like Office applications, Scratch, browser and a few others. It also includes some of the prerequiste software like Ruby, however my version of Ruby didn’t work with the guides, and when I updated to a new version I ran into challenges as well, so this is what I did to successfully install and run my static site on Jekyll and then publish to GitHub, for your enjoyment! First things first, check your version and if you are on an old version, we will update it to v3.x a bit later on. ruby --version Find out where its installed. which ruby Check you have gem, gcc, g++ and make installed. These are required to run Jekyll. gem -v gcc -v g++ -v make -v Make a directory to store your static content website. mkdir website Go into the directory. cd website/ Prepare your bashrc variables for the upcoming installs. echo '# Install Ruby Gems to ~/gems' >> ~/.bashrc echo 'export GEM_HOME="$HOME/gems"' >> ~/.bashrc echo 'export PATH="$HOME/gems/bin:$PATH"' >> ~/.bashrc Reload bashrc source ~/.bashrc Prepare the website directory with your existing static content site by cloning the remote public site to your local website directory. git clone https://github.com/USERNAME/blog Initialize the local repository. git init Add the remote origin copy, which in my instance is in my master fork on GitHub. git remote add origin https://github.com/USERNAME/blog Verify its set correctly. git status Pull the origin copy, just to make sure you have a synchronous copy of what’s on GitHub. git pull origin master Verify status again. git status Now’s the time to update Ruby to v3.x. Add the script to install the latest Ruby instance. wget https://gist.githubusercontent.com/blacktm/8302741/raw/install_ruby_rpi.sh Run the install script (This takes a little while to install). bash install_ruby_rpi.sh Reload the bashrc. source ~/.bashrc Verify the installed Ruby version, checking its now updated. which ruby ruby --version Install bundler using Gem gem install bundler Install Jekyll bundle install If the install fails, update it first then install. Update the bundle bundle update bundle install Finally serve the Jekyll site. Note: If you want to access it from a remote session, like an iPad or Phone browser, specify the --host IP_ADDPRESS variable at the end. bundle exec jekyll serve --host 192.168.2.61 Now you have the site up and running you can use the Git command line tools to upload updated content. git status git add -A git status git commit -m "New Comments on why updated or added" git status git push origin master git statusSimplifying VCD Load Balancing and Certificate Replacement2020-12-02T00:00:00+00:002020-12-02T00:00:00+00:00/Simplifying-VMware-Cloud-Director-Load-Balancing-and-Certificate-Replacement<h1 id="overview">Overview</h1>
<p>Replacing certificates in VCD is a fairly straight forward process and can be made significantly easier if you deviate from the procedure outlined in the official VMware documentation and instead use a simple load balancer and install the same certificate and key pairs on each node within the VCD cluster. Let me explain.</p>
<h2 id="background">Background</h2>
<p>As a service designed for external public consumption, VCD uses two internet facing IP addresses for providing the key VCD services:</p>
<ul>
<li>one is the http service</li>
<li>the other is the console proxy service</li>
</ul>
<p>As the names suggest, http (port 443) is for web traffic such logging into the web portal and the console proxy (port 8443) is for providing the console sessions to the underlying virtual machines for things such as OS installation. Historically these services required different IP addresses, however with the VCD appliances these two services run on the same network adapter, eth0, leaving eth1 for other network traffic types. By running on two different ports the same network adapter can provide both services.<br />
<strong>Note</strong> It is possible to change the port for the console proxy to say 443 however this is beyond the scope of this guide.<br />
<!--more--></p>
<h3 id="load-balancing">Load Balancing</h3>
<p>To make these two service http and console proxy available across multiple VCD instances in a group, or cells, a load balancer is required.<br />
The VMware documentation has always recommended using L7 application load balancing with SSL offload on a load balancer for the http service and L4 SSL passthrough for the console proxy service. Whilst this can work well I think this is an unnecessarily complex design for most deployments and would strongly recommend configuring just a single L4 load balancer for the backend cells which can service both traffic types.</p>
<h3 id="server-certificates">Server Certificates</h3>
<p>Using the historic method of load balancing with SSL offload, you do gain the ability to configure load balancing rules such as creating an “administrative zone” for internal VCD requests to present an internal CA-signed certificate for internal users such as VCD admins and another “public zone” load-balancing rule for customer connections to present a public CA-signed certificate to users who do not have awareness of the internal admin zone domain. However this sort of configuration is complex.</p>
<p>A simpler way to achieve this two-zone configuration would be to install the public CA-signed certificate on every cell and configure internal DNS with an A record for the public internet address so that both public users and internal users send requests to the same public FQDN.</p>
<ul>
<li>The internal users would go directly to the load-balanced internal IP address</li>
<li>The customer users would go via the public IP address, and then NAT on your public firewall translates that connection to the internal load-balanced IP address.</li>
</ul>
<p>Both these approaches present the same public CA signed certificate. See the diagram below.<br />
<img src="/assets/images/VCD%20only%20-v01.png" alt="" class="img-fluid rounded mb-3" /></p>
<h4 id="scenario-1-customer-traffic-flow">Scenario 1: Customer Traffic Flow</h4>
<ol>
<li>The internet facing public FQDN (shown in purple) is configured on the internet DNS servers with the public address.</li>
<li>That address points to the firewall where NAT is configured to pass the traffic from the public IP to the internal address of 10.20.9.85 of the load balancer (shown in green).</li>
<li>The load balancer is configured with L4 load balancing to pass through all traffic destined for 10.20.9.85 to the back-end VCD cells on eth0 (shown in red).</li>
</ol>
<h4 id="scenario-2-internal-traffic-flow">Scenario 2: Internal Traffic Flow</h4>
<ol>
<li>Internal users follow a similar approach but their DNS records points the public FQDN (shown in purple) to the internal load balanced IP address (10.20.9.85).</li>
<li>The load-balancer then passes directly to the backend servers.</li>
</ol>
<p>In both these scenarios the public CA-Signed certificate is installed on the backend servers, as mentioned in the box next to the servers. Each cell requires three key items.</p>
<ul>
<li>Public certificate in PEM format</li>
<li>Private key in PEM format</li>
<li>Entire Public certificate chain in PEM format</li>
</ul>
<h2 id="steps">Steps</h2>
<h3 id="pre-installation-steps">Pre-Installation Steps</h3>
<ol>
<li>Generate a Certificate Signing Request (CSR) for the public FQDN and send it to your public Certificate Authority (<strong>Hint</strong> Lets Encrypt can be used for free!).</li>
<li>Once the certificate comes back, convert the files to PEM format (if not already). <strong>Reminder</strong> you need:
<ul>
<li>the public server certificate</li>
<li>the private key</li>
<li>the certificate chain consisting of the intermediate CA certificate and the root CA certificate</li>
</ul>
</li>
<li>Remove any encryption passphrase from the private key prior to installation as VCD doesn’t support importing the private key with a passphrase in place. Don’t worry though as part of the installation process is to add a passphrase to keep the private key secure and you can always delete the unencrypted private key once you have imported the key into the first VCD cell.</li>
</ol>
<p>For guidance on how to do these pre-install steps, check out the various Openssl guides out there such as this one at <a href="https://www.digicert.com/kb/ssl-support/openssl-quick-reference-guide.htm">digicert</a>. It’s a fairly straight forward process.</p>
<h3 id="vcd-installation-steps">VCD Installation Steps</h3>
<ol>
<li>copy the certificate files to the <code class="highlighter-rouge">/tmp</code> directory on the cell using SCP or WinSCP.</li>
<li>Take a backup.</li>
<li>Snapshot all VCD cells.</li>
<li>Quiesce the cell management tool service and stop the cells from servicing clients.
<ul>
<li>Check if servicing clients.<br />
<code class="highlighter-rouge">/opt/vmware/vcloud-director/bin/cell-management-tool -u <USERNAME> cell --status</code></li>
<li>Quiesce the active jobs.<br />
<code class="highlighter-rouge">/opt/vmware/vcloud-director/bin/cell-management-tool -u <USERNAME> cell --quiesce true</code></li>
<li>Check the cell isn’t processing any active jobs.<br />
<code class="highlighter-rouge">/opt/vmware/vcloud-director/bin/cell-management-tool -u <USERNAME> cell --status</code></li>
<li>Shut the cell down to prevent any other jobs from becoming active on the cell.<br />
<code class="highlighter-rouge">/opt/vmware/vcloud-director/bin/cell-management-tool -u <USERNAME> cell --shutdown</code></li>
<li>Now run the status command again to check that job count says zero.<br />
<code class="highlighter-rouge">/opt/vmware/vcloud-director/bin/cell-management-tool -u <USERNAME> cell --status</code></li>
</ul>
</li>
<li>Stop the Cloud Director service on all cells.<br />
<code class="highlighter-rouge">service vmware-vcd stop</code></li>
<li><strong>Perform the following steps on the first VCD cell only</strong><br />
Import the PEM server certificate and the private key into a new pfx format certificate<br />
<code class="highlighter-rouge">openssl pkcs12 -export -out /tmp/public_fqdn_address.pfx -inkey /tmp/public_fqdn_address.key -in /tmp/public_fqdn_address.crt</code><br />
<strong>Note:</strong> If your certificate comes with a name such as cert.pem format or cert.cer, you can just rename it to .crt. VCD requires certain formats for this step to work and a simple rename is all that is required.</li>
<li>Create a new certificates.ks file and import the pfx formatted certificate.<br />
<code class="highlighter-rouge">/opt/vmware/vcloud-director/jre/bin/keytool -keystore /tmp/certificates.ks -storepass 'ComplexPassPhrase' -keypass 'ComplexPassPhrase' -storetype JCEKS -importkeystore -srckeystore /tmp/public_fqdn_address.pfx -srcstorepass 'ComplexPassPhrase'</code><br />
Make sure to substitute <code class="highlighter-rouge">'ComplexPassPhrase'</code> with a suitably complex passphrase and store it somewhere safe for later use!!</li>
<li>Change the alias for the first certificate entry to http.<br />
<code class="highlighter-rouge">/opt/vmware/vcloud-director/jre/bin/keytool -keystore /tmp/certificates.ks -storetype JCEKS -changealias -alias 1 -destalias http -storepass 'ComplexPassPhrase'</code></li>
<li>Import the certificate again (this will recreate the alias 1 for use by the consoleproxy service)<br />
<code class="highlighter-rouge">/opt/vmware/vcloud-director/jre/bin/keytool -keystore /tmp/certificates.ks -storepass 'ComplexPassPhrase' -keypass 'ComplexPassPhrase' -storetype JCEKS -importkeystore -srckeystore /tmp/public_fqdn_address.pfx -srcstorepass 'ComplexPassPhrase'</code></li>
<li>Change the alias for the first certificate entry to consoleproxy.<br />
<code class="highlighter-rouge">/opt/vmware/vcloud-director/jre/bin/keytool -keystore /tmp/certificates.ks -storetype JCEKS -changealias -alias 1 -destalias consoleproxy -storepass 'ComplexPassPhrase'</code></li>
<li>Import the combined root and intermediate certificate (which we will give the alias of root) into the certificates.ks file.<br />
<code class="highlighter-rouge">/opt/vmware/vcloud-director/jre/bin/keytool -importcert -alias root -file /tmp/public_fqdn_address_ca.crt -storetype JCEKS -keystore /tmp/certificates.ks -storepass 'ComplexPassPhrase'</code></li>
<li>Verify the entries exist in the certificate.ks keystore. There will be three, http, consoleproxy and root.<br />
<code class="highlighter-rouge">/opt/vmware/vcloud-director/jre/bin/keytool -list -keystore /tmp/certificates.ks -storetype JCEKS -storepass 'ComplexPassPhrase'</code></li>
<li>Make a backup of the current certificate<br />
<code class="highlighter-rouge">mv /opt/vmware/vcloud-director/certificates.ks /opt/vmware/vcloud-director/certificates.ks.old</code></li>
<li>Copy the new certificate to the Cloud Director directory<br />
<code class="highlighter-rouge">cp /tmp/certificates.ks /opt/vmware/vcloud-director/</code></li>
<li>List all the entries, you should now see three, http, consoleproxy and root<br />
<code class="highlighter-rouge">/opt/vmware/vcloud-director/jre/bin/keytool-list -keystore /opt/vmware/vcloud-director/certificates.ks -storetype JCEKS -storepass 'ComplexPassPhrase'</code></li>
<li>Change the keystore owner to vcloud. <br />
<code class="highlighter-rouge">chown vcloud.vcloud /opt/vmware/vcloud-director/certificates.ks</code></li>
<li>Reconfigure the Cloud Director application to use the new certificate<br />
<code class="highlighter-rouge">/opt/vmware/vcloud-director/bin/configure</code></li>
<li>Start the Cloud Director application<br />
<code class="highlighter-rouge">service vmware-vcd start</code></li>
<li>Monitor startup logs<br />
<code class="highlighter-rouge">tail -f /opt/vmware/vcloud-director/logs/cell.log</code></li>
</ol>
<h3 id="post-installation-steps">Post Installation Steps</h3>
<p>Copy the certificates.ks file to the other cells and repeat steps 16-19 to finalize certificate installation. <br />
Once complete VCD will now be using the new certificate, the only remaining step is to update the public URL within VCD provider portal to listen for connections on the public FQDN as shown in the diagram below.<br />
<img src="/assets/images/VCD-Public-URL.png" alt="" class="img-fluid rounded mb-3" /></p>Simon GreavesOverview Replacing certificates in VCD is a fairly straight forward process and can be made significantly easier if you deviate from the procedure outlined in the official VMware documentation and instead use a simple load balancer and install the same certificate and key pairs on each node within the VCD cluster. Let me explain. Background As a service designed for external public consumption, VCD uses two internet facing IP addresses for providing the key VCD services: one is the http service the other is the console proxy service As the names suggest, http (port 443) is for web traffic such logging into the web portal and the console proxy (port 8443) is for providing the console sessions to the underlying virtual machines for things such as OS installation. Historically these services required different IP addresses, however with the VCD appliances these two services run on the same network adapter, eth0, leaving eth1 for other network traffic types. By running on two different ports the same network adapter can provide both services. Note It is possible to change the port for the console proxy to say 443 however this is beyond the scope of this guide.New VMware Cloud Director Service2020-06-05T00:00:00+00:002020-06-05T00:00:00+00:00/New-VMware%20Cloud%20Director%20Service<p>BRAND NEW VMware Cloud Director Service (CDS) has just been launched for initial availability in US-West.
Based on VMware Cloud Director (VCD) 10.1.0 in this initial build, this new micro-service powered (Kubernetes) SaaS offering from VMware will allow VMware Managed Service Providers to roll out a build version of their choice (VCD 10.1.0 or 10.1.1 or 10.1.beta or 10.whatever-comes-next!!).<br />
<!--more--></p>
<p>The Beauty of this offering is that, because it is based on a micro-service model, it deploys really fast. At around 3 minutes to build VCD and a further 12 minutes to finish plugging it in, propagating DNS and other items, it’ll be up and running before you know it!</p>
<h2 id="by-why-do-i-want-this">By why do I want this??</h2>
<p>Ah, excellent question. I am glad you asked!
Feature wise, it’ll be the same as you offer on site, even though the internal architecture is different, the service will offer the same thing. You might get the chance to use the newer features quicker using the service but those features will be rolled into the 6 monthly updates to the online service.<br />
The real value here is with offering Managed Service Providers (MSPs) the ability to scale their offering much quicker. <br />
Backed by NSX-T (currently 2.5) and running alongside VMware Cloud on AWS, it’s a SaaS solution that right now offers the ability to offer <strong>multi-tenancy within VMware Cloud on AWS SDDC infrastructure</strong>.</p>
<p>Perfect for those smaller organization’s that don’t require the full VMware Cloud on AWS offering with it’s huge amounts of storage and compute. <br />
<strong>Agility</strong> is another, the ability to rapidly scale your capacity offering along side your data centre, or in the future across AZs and geographic locations. <br />
In the not too distant future, it’ll offer the ability to provision services both in VMware Cloud on AWS and in your own data center.<br />
<strong>Cost</strong> is a huge benefit of this. Think about it, at the moment you spend tens to hundreds of thousands of pounds kitting out your data centre racks with kit to run customer workloads on VCD, well now you can save a significant amount of initial investment by using the VMC on AWS service whilst retaining that managed service edge. Ok the cost to rent might be higher in the long term, but typically that takes at least a year to start seeing a profit on new kit. If customers want a longer term deal rather than a pay monthly offering you might be better off running their workloads on your own kit. I am not involved in pricing at VMware so you might be able to sweet talk your sales rep into offering you a discount for longer term deals. :-).<br />
From what I understand the VMware Cloud Director Service is about 10% additional cost on top of the VMC on AWS managed environment.</p>
<h3 id="key-benefits">Key benefits</h3>
<ul>
<li>Multi-tenancy in VMC on AWS</li>
<li>Sell VCD pools (Flex, PAYG, Allocation or Reservation pools) to customers</li>
<li>Rapid provisioning and scale</li>
<li>99.9% service uptime</li>
<li>99.9% workload SLA single AZ uptime</li>
<li>(Future) 99.99% workload SLA cross AZ uptime</li>
<li>Custom branding based on MSP or customer requirements</li>
<li>Auto-upgrade with no downtime (check https://status.vmware-services.io)</li>
<li>Custom domain names</li>
<li>Network isolation with new Tier-1 Gateway in VMware Cloud on AWS.</li>
</ul>
<p>On that last one, within VMC on AWS you normally only get two gateways. A management gateway and and compute gateway. When you use CDS with an existing VMC on AWS environment, the CDS will create a new Tier-1 Gateway to provide an Edge Gateway into Cloud Director. This is created automatically when you create a new Edge Gateway within CDS.<br />
<img src="/assets/images/t1-gw-cds.png" alt="" class="img-fluid rounded mb-3" /></p>
<p>It will allow the provider greater visibility into the interfaces from within VMC on AWS. Useful for root cause analysis (RCA). At the moment this can only be created from within the API, or you can let CDS create it for you.</p>
<h2 id="sounds-great-where-do-i-start">Sounds great! Where do I start?</h2>
<p>First thing is you will need a VMC on AWS account and the VMware Cloud Director Service access. Speak to the VMware account team about this. At present they are offering it as 1 or 3 year offering to MSPs.<br />
Once set up, you can access it via https://cloud.vmware.com/ and click on the console icon.<br />
<img src="/assets/images/vmc-console.png" alt="" class="img-fluid rounded mb-3" /><br />
<img src="/assets/images/CDS-in-VMC.png" alt="" class="img-fluid rounded mb-3" /></p>
<h2 id="whats-not-there-yet">What’s not there yet?</h2>
<p><strong>3rd Party Backup Ecosystem</strong> Vendors are working with VMware to integrate their solutions, such as Veeam, Dell and others to offer a backup integration with CDS.<br />
<strong>Disaster Recovery</strong> DRaaS solution VMware Cloud Availability is not quite ready for CDS but it will be coming soon. This will offer the ability to use this environment as a disaster recovery location for on-premises VCD or vSphere workloads. Or to protect workloads into VMC on AWS in another availability zone (AZ).<br />
<strong>S3 Object Storage</strong> Cloudian virtual appliance will offer integration from within the Cloud Director UI and Amazon S3 buckets.<br />
<strong>Micro Services</strong> App services K8s are not currently available in CDS but they will offer the ability for developers to curate content on an infrastructure as code platform.<br />
<strong>Other services</strong> Things like VROps Cloud, HCX and other currently available services will be integrated soon.<br />
<strong>Additional Sites</strong> Frankfurt is next, then an APJ location, then is where customers want to go. If you have somewhere in mind, pester your VMware Rep!<br />
<strong>Cloud Director on anything else!</strong> VMC on AWS is currently the only location supported, but the plan is to roll it out across other services, such as VMC on Azure, Google and maybe even on site.<br />
<strong>RabbitMQ</strong> VCD has been using ActiveMQ internally for a while and RabbitMQ as an external message bus. RabbitMQ and ActiveMQ as a construct will be phased out and be replaced by Artemis. Artemis, built into future VCD builds will have it’s own websocket protocol API that you can use to connect to the message bus.<br />
In the meantime, you can bring your own RabbitMQ.</p>
<h2 id="can-i-take-a-look">Can I take a look?</h2>
<p>Once you have access to CDS you will need to associate it with an existing VMC on AWS SDDC. To do this, open the CDS service, click on the <strong>Actions</strong> icon and select <strong>Associate SDDC</strong>.<br />
<img src="/assets/images/cds-sddc-association.png" alt="" class="img-fluid rounded mb-3" />
Then type in the API token for the VMC on AWS SDDC token.<br />
<img src="/assets/images/cds-sddc-associate-api.png" alt="" class="img-fluid rounded mb-3" /></p>
<p>This will automate the firewall opening for connectivity to the VMC on AWS SDDC, and connect in the vCenter Server and NSX Manager to create the Provider VDC within the VMC on AWS SDDC.<br />
Now if you create an object within CDS, it will actually create it within your VMC on AWS SDDC.<br />
Also, if you create an Edge Gateway within the Cloud Director (provided by CDS), you will then create that Tier-1 Gateway object I showed you earlier.<br />
I would love to show you that, but alas I do not have permissions on the VMC on AWS SDDC to show you.</p>
<p>FYI this association will be automated to a certain degree soon but at the moment you need to add the API token, UUID and SDDC name manually.</p>
<p>I’ve have however had the privilege of being given early access to the service to kick the tires a bit on CDS. If you’ve used VCD 10.1 elsewhere, its basically the same but here is a video showing some of the features and capabilities.</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/un2g3P4nyU4" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>Simon GreavesBRAND NEW VMware Cloud Director Service (CDS) has just been launched for initial availability in US-West. Based on VMware Cloud Director (VCD) 10.1.0 in this initial build, this new micro-service powered (Kubernetes) SaaS offering from VMware will allow VMware Managed Service Providers to roll out a build version of their choice (VCD 10.1.0 or 10.1.1 or 10.1.beta or 10.whatever-comes-next!!).NSX-T Troubleshooting2020-04-30T00:00:00+00:002020-04-30T00:00:00+00:00/NSX-T%20Troubleshooting<p>NSX-T Troubleshooting</p>
<p>Check L2 before L3.</p>
<h2 id="check-l2">Check (L2)</h2>
<ul>
<li>MTU</li>
<li>VLAN</li>
<li>TEP
<ul>
<li>IP</li>
<li>MTU</li>
</ul>
</li>
<li>CCP</li>
</ul>
<h2 id="n-vds-settings-l3">N-VDS settings (L3)</h2>
<ul>
<li>MTU (L2)</li>
<li>Routing table (L4)</li>
<li>TEP</li>
<li>vTEP tables</li>
<li>MAC tables</li>
</ul>
<h1 id="manager-troubleshooting">Manager Troubleshooting</h1>
<p>CorfuDB3 nodesQuorum must be up, at least 2 corfu servers required for quorumGroup Member Leader Election Server (GMLE) helps in detecting the fault with an NSX Manager node failure. It also helps elect a new leader per group.Day 2 OperationsUse st en to enter engineering mode (root privileged mode)
<!--more--></p>
<h1 id="logs">Logs</h1>
<table>
<thead>
<tr>
<th> </th>
<th> </th>
</tr>
</thead>
<tbody>
<tr>
<td>Component</td>
<td>Log Files and Locations</td>
</tr>
<tr>
<td>NSX Policy Manager</td>
<td>/var/log/policy/policy.log</td>
</tr>
<tr>
<td>NSX Manager<br />NSXAPI Logs<br />CorfuDB logsCluster BootstrapManager (CBM)</td>
<td>/var/log/syslog/var/log/manger.log/var/log/proton/nsxapi.log/var/log/nsx-audit.log/var/log/corfu/var/log/cbm</td>
</tr>
<tr>
<td>NSX Controller</td>
<td>/var/log/cloudnet/nsx-ccp.log</td>
</tr>
<tr>
<td>ESXi host<br />DFW</td>
<td>/var/log/cfgAgent.logesxupdate.lognsxa-opsagent.lognsx-syslog/var/log/dfwpktlogs.log (only fills if logging enabled on rule)</td>
</tr>
<tr>
<td>KVM host<br />DFW</td>
<td>/var/log/vmware/nsx-syslog/var/log/syslog/var/log/openvswitch/ovswitchd.log/var/log/dpkg.log/var/log/dfwpktlogs.log (only fills if logging enabled on rule)</td>
</tr>
<tr>
<td>Edge NodesLoad Balancer errors</td>
<td>Syslog (get log-file syslog)Access-log [follow]Error-log [follow]</td>
</tr>
</tbody>
</table>
<p>##</p>
<h2 id="set-logging-level-on-nsx-manager-with">Set logging level on NSX Manager with</h2>
<p>Set service manager logging-level debug</p>
<h2 id="log-message-ids">Log Message IDs</h2>
<h2 id="infrastructure-preparation-logs">Infrastructure Preparation Logs</h2>
<h2 id="policy-manager-logs">Policy Manager logs</h2>
<p>View with
get log-file policy.logget log-file syslogController LogCFG Agent Log (ESXi)KVM</p>
<h1 id="syslog">Syslog</h1>
<p>Configure Syslog ExporterYou get vRLI with NSX.</p>
<h2 id="protocols-supported">Protocols Supported</h2>
<ul>
<li>TCP</li>
<li>UDP</li>
<li>TLS</li>
</ul>
<h2 id="severity-level">Severity Level</h2>
<ol>
<li>Emergency</li>
<li>Alert</li>
<li>Critical</li>
<li>Error</li>
<li>Warning</li>
<li>Notice</li>
<li>Informational</li>
<li>Debug</li>
</ol>
<h2 id="management-and-edge-node-configuration">Management and Edge Node configuration</h2>
<p>set logging-server <hostname-or-ip-address[:port]> proto <protocol> level <level></level></protocol></p>
<h2 id="esxi-configuration">ESXi Configuration</h2>
<ul>
<li>esxcli network firewall ruleset set -r syslog -e true</li>
<li>esxcli system syslog config set –loghost=<hostname-or-ip-address[:port]></li>
<li>esxcli system syslog reload</li>
</ul>
<h2 id="kvm-configuration">KVM Configuration</h2>
<ul>
<li>Login as root</li>
<li>Create this file</li>
</ul>
<p>/etc/rsyslog.d/40-vmware-remote-logging.conf</p>
<ul>
<li>Add this line to the file</li>
</ul>
<p>‘<em>.</em>@<syslog_server_ip>:514;RFC5424fmt'</syslog_server_ip></p>
<ul>
<li>Restart syslog</li>
</ul>
<p>Systemctl restart rsyslog</p>
<h1 id="granular-tech-support-bundles-added-in-24">Granular tech support bundles added in 2.4</h1>
<h2 id="monitoring-dashboards">Monitoring Dashboards</h2>
<h1 id="packet-capture">Packet Capture</h1>
<p>If you need detailed traffic info, use port mirroring.Can use CLI to setup packet capture on:</p>
<ul>
<li>NSX Manager</li>
</ul>
<p>start capture interface <interface-name> [file <filename>] [count <packet-count>] [expression <expression>]</expression></packet-count></filename></interface-name></p>
<ul>
<li>NSX Edges</li>
</ul>
<p>set capture session <session-number> interface <port-uuid> direction <direction></direction></port-uuid></session-number></p>
<ul>
<li>ESXi
<ul>
<li>Collect packets</li>
</ul>
</li>
</ul>
<p>pktcap-uw</p>
<ul>
<li>View packets</li>
</ul>
<p>tcpdump -uw</p>
<ul>
<li>KVM</li>
</ul>
<p>Tcpdump</p>
<h1 id="troubleshooting-scenarios">Troubleshooting scenarios</h1>
<h2 id="nsx-manager">NSX Manager</h2>
<p>If file corrupt check OVA or QCOW2 install files12 characters minimum on passwordCheck logs</p>
<h3 id="installation-problems">Installation problems</h3>
<p>NSX CLI
get servicesget service <service name="">
get cluster status
get configuration
get managers
get configurationget servicesget managersget cluster status</service></p>
<h1 id="nsxcli">Nsxcli</h1>
<p>Can see that ESXi is connected to 46, and KVM is on 47, showing the Shards are working correctly.</p>
<h1 id="logical-switching">Logical Switching</h1>
<h2 id="common-switching-problems">Common switching problems</h2>
<p>N-VDS is incorrectly configured on a hostOverlay tunnel (GENEVE) is misconfiguredTEPs unable to reach each other</p>
<h2 id="validate-switch">Validate switch</h2>
<p>esxcfg-vswitch -l</p>
<h3 id="check-geneve-vmkernel">Check GENEVE VMKernel</h3>
<p>esxcli network ip interface ipv4 getVmk10 is the TEP for NSX.Vmk50 is for intra-tier networking/routing and containers.</p>
<h3 id="verifying-overlay-tunnel-reachability">Verifying overlay tunnel reachability</h3>
<p>vmkping ++netstack=vxlan <host-IP> -s <packet-size>Vxlan is used by host rather than GENEVE. It's the same stack for ESXi.Try 1572 if 1575 fails. This is the minimum size needed to support GENEVE. GENEVE adds 72 bytes to a 1500 byte data packet.If 1572 fails try 1472. if that works, the overhead for the overlay hasn’t been configured.</packet-size></host-IP></p>
<h3 id="n-vds-not-initialised-on-a-host">N-VDS Not Initialised on a Host</h3>
<p>If a VM is not able to communicate on a specific host, check that the segment is present, if it isn’t showing on the host, go into the GUI, and check the N-VDS segment is present. If it is, check the advanced settings virtual switches and look for any errors like Partial Success Shown below.</p>
<p>If this happens, check that the agents are running on the host.</p>
<table>
<tbody>
<tr>
<td>/etc/init.d/nsx-mpa statusesxcli network ip connection list</td>
<td>grep 5671/etc/init.d/nsx-proxy statusesxcli network ip connection list</td>
<td>grep 1235/etc/init.d/nsx-opsagent status</td>
</tr>
</tbody>
</table>
<h1 id="routing-problems">Routing Problems</h1>
<ul>
<li>Check if BGP neighbours are not misconfigured and as a result the neighbour relationship is not established.</li>
<li>The internal route advertisement on the Tier-1 router is misconfigured</li>
<li>Route redistribution on the Tier-0 router is misconfigured</li>
</ul>
<p>Especially those check boxes! Check Routing Table get logical-router Check the SR for routingValidate the routing table for the Tier-0 SR VRFvrfget route b = BGP</p>
<p>For DR check the forwarder for similar informationget forwarding</p>
<h2 id="bgp-neighbour">BGP neighbour</h2>
<p>get bgp neighbor summaryCheck the status is established. Active means still setting up!</p>
<h2 id="bgp-route-table">BGP route table</h2>
<p>T0 SR can show BGP route infoget bgp ipv4</p>
<h1 id="firewall">Firewall</h1>
<p>Most common firewall issues are</p>
<ul>
<li>Firewall policy rules are configured but not enabled or published</li>
<li>Firewall policy rules are not applied to the intended entity</li>
<li>The sequence of rules is incorrect, remember it’s top to bottom</li>
</ul>
<p>get firewall statussummary
KVMOvs-appctl used for configuration of Firewall.Validate with</p>
<p>ovs-appctl -t /var/run/openvswitch/nsxa-ctl dfw/vifGet the VIF then typeovs-appctl -t /var/run/openvswitch/nsxa-ctl dfw/rules <VIF_ID_NUMBER> Rules are defined with addrsets (address sets). These have GUIDs on them as well.</VIF_ID_NUMBER></p>
<p>ESXiUse vsipioctl and summarize-dvfilter
Summarize-dvfilter | grep <SERVER_NAME>
Look for the filter name then use
vsipiolctl getrules -f <filter_name></filter_name></SERVER_NAME></p>
<p>The example adds the -A16 variable which tells grep to add 16 lines to the output.This is without the -A16 and with</p>
<p>Can also use the addrsets in the filter instead of name. Same commands again but with -f addrset number.The edges give definition of what’s in the rule sets using</p>
<p>get firewall <interface_id> ruleset rules
You get the interface_id by running
get firewall interfaces</interface_id></p>
<h2 id="nsxdp-cli">nsxdp-cli</h2>
<h1 id="can-get-deeper-analysis-with-nsxdp-cli">Can get deeper analysis with nsxdp-cli</h1>
<p>Again, this command only shows 1 line as the -A1 is used in the egrep.</p>
<h1 id="edge-validation">Edge Validation</h1>
<h2 id="nsxcli-1">nsxcli</h2>
<p>get configurationget node-uuidget interfacesget managersget host-switchesget tunnel-portsget vteps</p>Simon GreavesNSX-T Troubleshooting Check L2 before L3. Check (L2) MTU VLAN TEP IP MTU CCP N-VDS settings (L3) MTU (L2) Routing table (L4) TEP vTEP tables MAC tables Manager Troubleshooting CorfuDB3 nodesQuorum must be up, at least 2 corfu servers required for quorumGroup Member Leader Election Server (GMLE) helps in detecting the fault with an NSX Manager node failure. It also helps elect a new leader per group.Day 2 OperationsUse st en to enter engineering mode (root privileged mode)vCloud Director REST API (vCloud API)2020-04-17T00:00:00+00:002020-04-17T00:00:00+00:00/vCloud%20Director%20REST%20API%20(vCloud%20API)<p>VMware vCloud Director has historically been written with the vCloud API as the primary API mechanism for API modification and access.<br />
The vCloud API is being replaced by the open source vCloud Director OpenAPI, however the vCloud API can still be used to great effect on vCloud Director, up to and including vCD 10.x.
<!--more--></p>
<p><strong>Documentation</strong><br />
<a href="https://code.vmware.com/docs/10000/vcloud-api-programming-guide-for-service-providers">vCloud API</a><br />
<a href="https://vdc-download.vmware.com/vmwb-repository/dcr-public/772aa4c5-7e61-4d80-8432-b8e0d821c969/2747ec83-6aef-4560-b1d1-55ed9adc4e73/vcd-openapi-docs.html">vCloud Director OpenAPI</a></p>
<h2 id="understanding-rest">Understanding REST</h2>
<p>Whichever API you use, they both use the same format for manipulation, REST. Typically know as being a RESTful format.
REST design principals map to ‘CRUD’ operations. Create, Read, Update and Delete using the HTTP verbs below.</p>
<ul>
<li>To <code class="highlighter-rouge">create</code> a resource on the server or begin a task, use <code class="highlighter-rouge">POST</code>
<ul>
<li>Power on a vApp task</li>
</ul>
</li>
<li>To retrieve a resource or <code class="highlighter-rouge">read</code> an object, use <code class="highlighter-rouge">GET</code></li>
<li>To change the state of a resource or to <code class="highlighter-rouge">update</code> it, use <code class="highlighter-rouge">PUT</code>
<ul>
<li>Replace one object with another</li>
</ul>
</li>
<li>To remove or <code class="highlighter-rouge">delete</code> a resource, use <code class="highlighter-rouge">DELETE</code></li>
</ul>
<h3 id="accessing-the-vcd-api--basic-options">Accessing the vCD API — Basic Options</h3>
<ul>
<li>Browser — The simplest method to test the vCD API is to point a browser to one of the basic pages: <code class="highlighter-rouge">http://vcloud.com/api/versions</code></li>
<li>cURL — Command line tool which supports a number of formats including REST API calls. Is present on most Linux distros</li>
<li>REST Client — There are many standalone clients and plugins for browsers useful for making REST API calls</li>
</ul>
<p>The focus of this article is the REST Client. For my purposes I use Postman, but Chrome and Firefox have API extensions available. <br />
Using our REST Client we need to add a few elements into a request in order to get a valid response.</p>
<ol>
<li>Our HTTP verb - <code class="highlighter-rouge">GET</code>, <code class="highlighter-rouge">POST</code> etc., a corresponding URL for the request and body for the request (if required)</li>
<li>Headers
<ul>
<li>Authorization - Some form of credentials</li>
<li>Accept - An accepted header format and corresponding response type
<ul>
<li>Version - A common API version to use in the request</li>
</ul>
</li>
</ul>
</li>
</ol>
<p>Example.<br />
<code class="highlighter-rouge">POST https://vcloud.example.com/api/sessions</code> <br />
Authorization: <code class="highlighter-rouge">Bearer <Bearer_token_code></code> <br />
Accept: <code class="highlighter-rouge">application/*;version=30.0</code></p>
<p>This will give us a corresponding <strong>status code</strong> and an appropriate response.<br />
Lets break these elements down to understand how you can form your own API queries. Starting with the HTTP Verbs.</p>
<h3 id="http-verbs">HTTP Verbs</h3>
<table>
<thead>
<tr>
<th>Operation</th>
<th>REST-API-Verb</th>
<th>Action</th>
<th>Operation Summary</th>
</tr>
</thead>
<tbody>
<tr>
<td>Create</td>
<td><code class="highlighter-rouge">POST</code></td>
<td>add</td>
<td>Creates a new object</td>
</tr>
<tr>
<td>Retrieve</td>
<td><code class="highlighter-rouge">GET</code></td>
<td>down</td>
<td>Retrieves the representation of an existing object in it’s current state</td>
</tr>
<tr>
<td>Update</td>
<td><code class="highlighter-rouge">PUT</code></td>
<td>edit</td>
<td>Modifies an existing object</td>
</tr>
<tr>
<td>Delete</td>
<td><code class="highlighter-rouge">DELETE</code></td>
<td>remove</td>
<td>Deletes an existing object. If the object is a container (such as a vApp), you must remove all of it’s contents before you can delete it</td>
</tr>
</tbody>
</table>
<h3 id="status-codes">Status Codes</h3>
<h4 id="primary-rest-api-calls--vcloud-responses">Primary REST API calls — vCloud Responses</h4>
<p>When you make a REST API call, you will get a corresponding response code. You are probably familiar with some of these codes, particularly the 404 (Not found) code when you try and access a website that doesn’t exist.<br />
The type of code you get tells you a lot of information about what about the request is the issue. This is really useful when first using REST codes to help you discover what in your request is the likely causing you issues.<br />
The status code you get in response can vary depending on the request. As an example you won’t get an <code class="highlighter-rouge">202</code> (Accepted) response for a GET request as <code class="highlighter-rouge">202</code> is a response for modifications.</p>
<p>Here are some of the most common codes you will find.</p>
<table>
<thead>
<tr>
<th>Request</th>
<th>Success</th>
<th>Failure</th>
</tr>
</thead>
<tbody>
<tr>
<td><code class="highlighter-rouge">POST</code></td>
<td><code class="highlighter-rouge">201</code> (Created)</td>
<td><code class="highlighter-rouge">400</code> (Bad Request)</td>
</tr>
<tr>
<td> </td>
<td><code class="highlighter-rouge">202</code> (Accepted)</td>
<td><code class="highlighter-rouge">401</code> (Not Authorised)</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td><code class="highlighter-rouge">404</code> (Not Found)</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td><code class="highlighter-rouge">406</code> (Not Acceptable)</td>
</tr>
<tr>
<td><code class="highlighter-rouge">GET</code></td>
<td><code class="highlighter-rouge">200</code> (0K)</td>
<td><code class="highlighter-rouge">401</code> (Not Authorised)</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td><code class="highlighter-rouge">404</code> (Not Found)</td>
</tr>
<tr>
<td><code class="highlighter-rouge">PUT</code></td>
<td><code class="highlighter-rouge">200</code> (0K)</td>
<td><code class="highlighter-rouge">400</code> (Bad Request)</td>
</tr>
<tr>
<td> </td>
<td><code class="highlighter-rouge">204</code> (No Content)</td>
<td><code class="highlighter-rouge">401</code> (Not Authorised)</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td><code class="highlighter-rouge">404</code> (Not Found)</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td><code class="highlighter-rouge">406</code> (Not Acceptable)</td>
</tr>
<tr>
<td><code class="highlighter-rouge">DELETE</code></td>
<td><code class="highlighter-rouge">200</code> (0K)</td>
<td><code class="highlighter-rouge">401</code> (Not Authorised)</td>
</tr>
<tr>
<td> </td>
<td><code class="highlighter-rouge">202</code> (Accepted)</td>
<td><code class="highlighter-rouge">404</code> (Not Found)</td>
</tr>
</tbody>
</table>
<p>As you can see, sucessful ones usually are in the 200 range and failures are in the 400+ range. <br />
There are lots of status codes you may find and my hope with this table is to give you a list of all the status code descriptions you are likely to run into with vCD (don’t shoot me if I forget any!).</p>
<table>
<thead>
<tr>
<th>Status Code</th>
<th>Status</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code class="highlighter-rouge">200</code></td>
<td>OK</td>
<td>The request is valid and was completed. The response includes a document body.</td>
</tr>
<tr>
<td><code class="highlighter-rouge">201</code></td>
<td>Created</td>
<td>The request is valid. The requested object was created and can be found at the URL specified in the location header.</td>
</tr>
<tr>
<td><code class="highlighter-rouge">202</code></td>
<td>Accepted</td>
<td>The request is valid and a task was created to handle it. This response is usually accompanied by a task element.</td>
</tr>
<tr>
<td><code class="highlighter-rouge">204</code></td>
<td>No Content</td>
<td>The request is valid and was completed. The response does not include a body.</td>
</tr>
<tr>
<td><code class="highlighter-rouge">400</code></td>
<td>Bad Request</td>
<td>The request body is malformed, incomplete, or otherwise invalid.</td>
</tr>
<tr>
<td><code class="highlighter-rouge">401</code></td>
<td>Unauthorized</td>
<td>Login failed or authentication token has expired.</td>
</tr>
<tr>
<td><code class="highlighter-rouge">404</code></td>
<td>Not Found</td>
<td>Item not found. Usually indicates a malformed request URL or request body.</td>
</tr>
<tr>
<td><code class="highlighter-rouge">405</code></td>
<td>Method Not Allowed</td>
<td>The HTTP method specified in the request is not supported for this object. The verb you are using is not valid for the URI. It can also be the case that the object is not is a valid state for the action. For example deleting an Organization which has not first been disabled.</td>
</tr>
<tr>
<td><code class="highlighter-rouge">406</code></td>
<td>Not Acceptable</td>
<td>The resource identified by the request is not capable of generating a response of the type specified in the request’s Accept header.</td>
</tr>
<tr>
<td><code class="highlighter-rouge">403</code></td>
<td>Forbidden</td>
<td>Any of:</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td>One or more objects specified in the request could not be found in the specified container.</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td>The user is not authenticated or does not have adequate privileges to access one or more Objects specified in the request.</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td>The user’s session has expired.</td>
</tr>
<tr>
<td><code class="highlighter-rouge">409</code></td>
<td>Conflict</td>
<td>The Object state is not compatible with the requested operation.</td>
</tr>
<tr>
<td><code class="highlighter-rouge">415</code></td>
<td>Unsupported Media Type</td>
<td>The resource identified by the request does not support a request of the specified Content-Type and HTTP method.</td>
</tr>
<tr>
<td><code class="highlighter-rouge">500</code></td>
<td>Internal Server Error</td>
<td>The request was received but could not be completed because of an internal error at the server.</td>
</tr>
<tr>
<td><code class="highlighter-rouge">503</code></td>
<td>Service Unavailable</td>
<td>The server is currently unable to handle the request due to a temporary condition such as resource exhaustion or server maintenance. For example the vCD cell start-up has not reached 100%.</td>
</tr>
<tr>
<td><code class="highlighter-rouge">504</code></td>
<td>Gateway Timeout</td>
<td>The server, while acting as a gateway or proxy, did not receive a timely response from the upstream server specified by the request URL.</td>
</tr>
</tbody>
</table>
<h3 id="headers">Headers</h3>
<p>The other common component of the request is the header used. The common Headers used with vCD are defined as:-</p>
<ul>
<li>HTTP Headers - REST uses HTTP standard headers. They are used to control parameters of the transaction. Generally however they should not contain data.</li>
<li>Request Headers — When sending a request to the vCD API, it is required to include a number of request headers depending on the action, for example our credentials.</li>
<li>Response Headers — In the reply to our requests we will also receive headers called response headers.</li>
</ul>
<h4 id="primary-rest-api-headers-and-their-values">Primary REST API Headers and their Values</h4>
<table>
<thead>
<tr>
<th>Header</th>
<th>Function</th>
<th>Example Value</th>
</tr>
</thead>
<tbody>
<tr>
<td>Authorization</td>
<td>Used to supply login credentials</td>
<td><code class="highlighter-rouge">admin@orgname:passwd</code> or</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td>login token Text and Hex value made up of</td>
</tr>
<tr>
<td> </td>
<td>Authorization token</td>
<td><code class="highlighter-rouge">x-vmware-vcloud-token-type</code> &</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td><code class="highlighter-rouge">x-vmware-vcloud-access-token</code> received in reply to our <code class="highlighter-rouge">initial log in.</code> (defined below)</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td>e.g. <code class="highlighter-rouge">Bearer HEXCODEababab23313132<truncated></code></td>
</tr>
<tr>
<td>Accept</td>
<td>Content we wish to receive in response. Includes the version of the vCloud Director API we wish to interact with.</td>
<td><code class="highlighter-rouge">Application/*+xml;version=30.0</code></td>
</tr>
<tr>
<td>Content-Type</td>
<td>Used with POST and PUT requests to define the type of content which we are sending in our body.</td>
<td><code class="highlighter-rouge">application/vnd.vmware.vcloud.catalogItem+xml</code></td>
</tr>
<tr>
<td><strong>(Optional)</strong> Content-Length</td>
<td>The length of the request body in octets (8-bit bytes)</td>
<td>Number value, e.g. 1024</td>
</tr>
<tr>
<td><strong>(Optional)</strong> <code class="highlighter-rouge">x-vcloud-authorization</code></td>
<td>Authorization token</td>
<td>Hex value, e.g. <code class="highlighter-rouge">2d123d13ae19235ab12dac2eaea316c6</code></td>
</tr>
</tbody>
</table>
<p><strong>Note</strong> <code class="highlighter-rouge">x-vcloud-authorization</code> is depreciated in 9.1 and should be replaced with the bearer token in the Authorization header.<br />
<strong>Note</strong> Login tokens log out sessions after 30 minutes by default, however this can be set in vCD to a higher value.<br />
<strong>Note</strong> In general, client requests can access objects defined by any version of the vCloud API that is less than or equal to the API version specified in the Accept header.</p>
<h3 id="initial-log-in">Initial Log In</h3>
<p>Now we know what we need to make a request, lets make an initial login.</p>
<ol>
<li>Make an API versions request to confirm supported API version.
<code class="highlighter-rouge">GET http://vcloud.example.com/api/versions</code></li>
<li><code class="highlighter-rouge">POST</code> a request to the login URL, supplying credentials in the requests Authorization header and state what we will accept in the response.<br />
<code class="highlighter-rouge">POST https://vcloud.example.com/api/sessions</code><br />
Authorization: <code class="highlighter-rouge">Bearer|Basic|Sign Bearer_token_code|password</code><br />
Accept: <code class="highlighter-rouge">application/*;version=32.0</code></li>
<li>Examine the response for the authorization token and copy it in to the Authentication header. Use the contents of X-VMWARE-VCLOUD-TOKEN-TYPE and X-VMWARE-VCLOUD-ACCESS-TOKEN.</li>
</ol>
<p><strong>Note</strong> an asterix is used as a wildcard in the Accept header.<br />
Typically you can use Basic and user name and password for Authorization for first API sessions request in step 2 login to get the token.</p>
<h4 id="required-fields-walkthrough">Required Fields Walkthrough</h4>
<p>To reiterate the login process. When first connecting, use basic authentication POST request on <code class="highlighter-rouge">https://vcloudurl.com/api/sessions</code> to get the bearer token and then use that token in subsequent queries. The first query uses the default option of Basic, subsequent queries use the Bearer token.<br />
<img src="/assets/images/VCD-Headers-02.png" alt="" class="img-fluid rounded mb-3" /><br />
Now we have that info, update the next request with this Bearer token shown above in the x-vmware-vcloud-access-token field.<br />
Additionally add the Content-Type header, for example for admin login use<br />
Content-Type: <code class="highlighter-rouge">application/vnd.vmware.admin.vcloud+xml</code> <br />
<img src="/assets/images/VCD-Headers-03.png" alt="" class="img-fluid rounded mb-3" /><br />
From there you can view the other Content-Type headers you can use with requests. Content-Type headers have the <code class="highlighter-rouge">type="NAME"/></code> variable in the image.
<img src="/assets/images/VCD-Headers-04.png" alt="" class="img-fluid rounded mb-3" /><br />
<strong>Note</strong> As you may have already gathered, vCD API has an admin part for system level administration and a tenant part for tenant level administration. i.e. Don’t expect to be able to modify provider vDC settings from the tenant part!<br />
The body of the response includes clickable links for objects you have rights to access. This will help with navigation within vCD.<br />
The credentials token we receive is valid for 30 minutes by default. If not used, it will expire. If used, it will remain valid. This can be configured within administration settings in vCD.<br />
Now we have the credentials we need we can go ahead an make other vCD API requests. Read on and in the Query section we will walk though an API request together.</p>
<h5 id="request-headers-further-info">Request Headers Further Info</h5>
<p>Let’s dig into those headers a bit further to cover some additional ones you may find useful.</p>
<table>
<thead>
<tr>
<th>Header</th>
<th>Information</th>
</tr>
</thead>
<tbody>
<tr>
<td>Accept</td>
<td>All requests must include an HTTP Accept header that specifies the type of response that is expected. Three forms of this header are supported:</td>
</tr>
<tr>
<td> </td>
<td>Accept: <code class="highlighter-rouge">application/*</code></td>
</tr>
<tr>
<td> </td>
<td>Accept: <code class="highlighter-rouge">application/vnd.vmware.vcloud.*type*+xml</code></td>
</tr>
<tr>
<td> </td>
<td>Accept: <code class="highlighter-rouge">application/*;version=30.0</code></td>
</tr>
<tr>
<td>Accept-Language</td>
<td>To specify the language desired in responses, use the Accept-Language request header. To request a response with message strings localized to French, use the following header: Accept-Language: fr</td>
</tr>
<tr>
<td>Authorization</td>
<td>After you have established a session, you can use the value of the X-VMWARE-VCLOUD-TOKEN-TYPE and X-VMWARE-VCLOUD-ACCESS-TOKEN headers in the Session response to construct an Authorization header for use with subsequent requests.</td>
</tr>
<tr>
<td>Content-Type</td>
<td>Requests that include a body must include an appropriate HTTP Content-Type header. For example a POST or PUT request that supplies a Catalog item in the request body requires the following Content-Type header:- Content-Type: <code class="highlighter-rouge">application/vnd.vmware.vcloud.catalogItem+xml</code></td>
</tr>
<tr>
<td>x-vcloud-authorization</td>
<td>This header is returned with the Session response after a successful log-in to the integrated identity provider. As of API version 30, it is deprecated in favor of the X-VMWARE-VCLOUD-ACCESS-TOKEN value returned when you create a Session.</td>
</tr>
<tr>
<td>X-VMWARE-VCLOUD-ACCESS-TOKEN</td>
<td>Response header. An encoded key used along with the X-VMWARE-VCLOUD-TOKEN-TYPE header, to construct an Authorization header. A replacement for the deprecated x-vcloud-authorization header.</td>
</tr>
<tr>
<td>X-VMWARE-VCLOUD-TOKEN-TYPE</td>
<td>If a response includes an X-VMWARE-VCLOUD-ACCESS-TOKEN header, it also includes an X-VMWARE-VCLOUD-TOKEN-TYPE header. Example includes Bearer token type.</td>
</tr>
</tbody>
</table>
<h3 id="navigating-the-vcd-api--schema-context-or-view-types">Navigating the vCD API — Schema Context or View Types</h3>
<p>Similar to the tenant/provider approach taken with vCD, there are user elements and admin elements. The admin elements are for the service provider, the user elements are typically for the tenant elements, although you can always have an admin performing user configurations if you so desire. There are also extension elements, for vSphere elements and so forth.</p>
<ul>
<li>User —A URL of the form <code class="highlighter-rouge">/api/object/id</code> indicates that any user can access the object if they have the rights.</li>
<li>Admin —A URL of the form <code class="highlighter-rouge">/api/admin/object/id</code> indicates that org admins and system admins can access the object but an org admin may not have the rights to modify the object, like a network pool or external network.</li>
<li>Extension — A URL of the form <code class="highlighter-rouge">/api/admin/extension/object/id</code> indicates that system admins can access the object.</li>
</ul>
<h4 id="navigating-the-vcd-api--extension-elements--apiadminextension">Navigating the vCD API — Extension Elements -<code class="highlighter-rouge">/api/admin/extension</code></h4>
<ul>
<li><code class="highlighter-rouge">GET https://vcloud.example.com/api/admin/extension</code> to see a list of the available options using system admin credentials.</li>
<li>As these are system admin functions they generally refer to the capabilities we have in the System tab of the vCloud Director UI.
<ul>
<li>System level settings: <code class="highlighter-rouge">/api/admin/extension/settings</code></li>
<li>vCenter Server list: <code class="highlighter-rouge">/api/admin/extension/vimServerReferences</code></li>
<li>Blocking Tasks: <code class="highlighter-rouge">/api/admin/extension/blockingTasks</code></li>
</ul>
</li>
</ul>
<h2 id="query-service">Query Service</h2>
<p>The vCloud API query service allows for information on objects within vCloud Director to be retrieved. Queries are read only requests, i.e. GET commands and not PUT or POST.<br />
View a list of available queries with <br />
<code class="highlighter-rouge">GET https://vcloud.example.com/api/query</code> <br />
<img src="/assets/images/VCD-Query-01.png" alt="" class="img-fluid rounded mb-3" /></p>
<h3 id="vcd-query-service-definition">vCD Query Service Definition</h3>
<p>Two types of queries are available: Typed and Packaged.</p>
<ul>
<li>Typed queries are ones constructed by the administrator. Typed queries are built in the format <code class="highlighter-rouge">/api/query?type=name</code> or <code class="highlighter-rouge">https://vcloud.example.com/api/query?[&filter\]</code></li>
<li>Packaged queries have well known URLs, they are predefined and take the basic format <code class="highlighter-rouge">/api/object/query</code></li>
</ul>
<p>When making queries, you can select what is responded using filters with <code class="highlighter-rouge">?&filter=EXAMPLE-FILTER-NAME</code> appended to the end of the query.</p>
<h4 id="query-example">Query Example</h4>
<p>As a system admin, list all Org VDC Edges in the environment: <br />
<code class="highlighter-rouge">GET https://vcloud.domain.com/api/query?type=edgeGateway&format=records</code></p>
<h5 id="filter-example">Filter Example</h5>
<p>If you want Edges where the last task performed failed with an error. Then add a filter to the query: <br />
<code class="highlighter-rouge">GET https://vcloud.domain.com/api/query?type=edgeGateway&format=records&filter=taskStatus==error</code></p>
<h3 id="viewing-and-editing-objects">Viewing and Editing Objects</h3>
<p>When querying something like the VDC it returns things related to it in <code class="highlighter-rouge"><ResourceEntities></code> brackets. Such as the vApp info in the below screenshot.<br />
<img src="/assets/images/vcd-resource-entities.png" alt="" class="img-fluid rounded mb-3" /></p>
<p>You can then take the <code class="highlighter-rouge">href</code> and run subsequent queries like the below. <img src="/assets/images/vcd-vapp-info.png" alt="" class="img-fluid rounded mb-3" /></p>
<p>This then brings us to the vApp view, including the VM info<br />
<img src="/assets/images/vcd-vm-info.png" alt="" class="img-fluid rounded mb-3" /></p>
<p>To modify, go up a level to the VM and click the link to edit the CPU (note it says in the <code class="highlighter-rouge"><Link rel="edit"</code> part at the beginning of the line that this is for the editing function.
<img src="/assets/images/vcd-edit-cpu.png" alt="" class="img-fluid rounded mb-3" /></p>
<p>To perform an edit (change), do a <code class="highlighter-rouge">PUT</code> request.<br />
First include the Content-Type header for the <code class="highlighter-rouge">PUT</code> request.
<img src="/assets/images/vcd-cpu-header.png" alt="" class="img-fluid rounded mb-3" /><br />
Then include the body the change we want to make before clicking send.
<img src="/assets/images/vcd-vcpu-increase.png" alt="" class="img-fluid rounded mb-3" /><br />
<strong>Note</strong> I recommend you copy over the whole VM information, including the entry you want to change as I have seen it have unexpected consequences if you just copy over the line you want to change. The other values won’t matter applying them as they are already in place and no change will be made, only the changed values are updated, which in this case is the CPU count of the VM.</p>
<p>This should give us back a task element stating we issued a request to change the CPU.
<img src="/assets/images/vcd-vcpu-accepted.png" alt="" class="img-fluid rounded mb-3" /></p>
<h2 id="vcd-api-troubleshooting">vCD API Troubleshooting</h2>
<p>Use <code class="highlighter-rouge">https://vcloud.domain.local/api/service_status</code> to check if the service is up.<br />
Useful to test each cell using its HTTP IP address to check load balancer or firewall configurations. <br />
<strong>Note</strong> Although in our examples we have used <code class="highlighter-rouge">/api/versions</code>, calling <code class="highlighter-rouge">/api/versions</code> is a non-trivial task and as such it should not be used to determine the status of vCD on a load balancer, <code class="highlighter-rouge">/api/server_status</code> status should be used instead.</p>
<h3 id="common-errors">Common Errors</h3>
<h4 id="access-is-forbidden">Access is forbidden</h4>
<p>Your session might have timed-out. Try logging in again. <br />
Or you could possibly be missing the authorization headers Make sure to check that you have the proper headers.</p>
<h4 id="unsupported-media-type">Unsupported Media Type</h4>
<p>Check the Content-Type header. Be sure to set it correctly (it’s on the ‘Body’ tab).</p>
<h4 id="no-valid-api-version-can-be-selected">No valid API version can be selected</h4>
<p>Don’t forget to include the Accept header.</p>
<h3 id="troubleshooting-vcd-api-calls">Troubleshooting vCD API Calls</h3>
<p>All API requests to vCD are logged on the cells which received the call in a requests log file. The log file is located in <code class="highlighter-rouge">$CLOUD HOME/logs/</code> with a name in the format: <code class="highlighter-rouge">yyyy_mm dd.request.log</code>. The request logs will also contain requests made by browsers for the vCloud Director Web UI. The format of the log message should give an indication of the source. The Debug logs will not contain individual request information but will contain info and errors on tasks which are invoked.</p>
<p>Also check the <code class="highlighter-rouge">Request.log</code> file for access requests. As postman is a Chrome app it shows as a chrome app in the logs.</p>Simon GreavesVMware vCloud Director has historically been written with the vCloud API as the primary API mechanism for API modification and access. The vCloud API is being replaced by the open source vCloud Director OpenAPI, however the vCloud API can still be used to great effect on vCloud Director, up to and including vCD 10.x.NSX-T Command Line Reference Guide2020-02-01T00:00:00+00:002020-02-01T00:00:00+00:00/nsx-t-cli-reference-guide<p>Here is a reference guide for some useful command line tools you can run on NSX-T.</p>
<h1 id="nsx-cli-introduction">NSX CLI Introduction</h1>
<p>NSX CLI (nsxcli) is the command line tool for troubleshooting NSX-T. It’s run in a non-root mode so you have to use the command structure available. For instance there is no grep, But you can use find and pipe instead.
<img src="/assets/images/get-logical-find-segments.png" alt="" class="img-fluid rounded mr-3 float-left" /></p>
<p>You can use the nsxcli command line tool from various elements throughout the NSX-T deployment including NSX Manager, Edges and ESXi Transport Nodes.
<!--more--></p>
<h2 id="from-edges">From Edges</h2>
<p>SSH Access to Edges
FYI I used Edge VMs throughout this article.<br />
Post deployment, open the console and verify the SSH service is stopped.<br />
<code class="highlighter-rouge">get service ssh</code></p>
<p>Start the SSH service. <br />
<code class="highlighter-rouge">start service ssh</code></p>
<p>Set the SSH service to autostart when the VM is powered on.<br />
<code class="highlighter-rouge">set service ssh start-on-boot</code></p>
<p>Verify that the SSH service is running and Start on boot is set to True.<br />
<code class="highlighter-rouge">get service ssh</code></p>
<p>Disable the command-line timeout.<br />
<code class="highlighter-rouge">set cli-timeout 0</code></p>
<p>Obtain routing information for the gateways.<br />
<code class="highlighter-rouge">get logical-routers</code></p>
<p>Verify that the SERVICE_ROUTER_TIER0 service gateway appears with an associated VRF ID.
<img src="/assets/images/get-logical-routers.png" alt="" class="img-fluid rounded mr-3 float-left" /><br />
In the command output, VRF 2 is associated with SR-T0-GW. The VRF ID in your lab might be different.</p>
<h3 id="vrf">vrf</h3>
<p>Vrf is used to access the gateway virtual routing functions. For BGP and other Tier-0 services you access the Tier-0 service router (SR) function of the gateway.</p>
<p><code class="highlighter-rouge">vrf \<vrf_ID\></code><br />
<img src="/assets/images/vrf-2.png" alt="" class="img-fluid rounded mr-3 float-left" /></p>
<p>verify the BGP state.<br />
<code class="highlighter-rouge">get bgp neighbor summary</code></p>
<p>Check the status is established. A status of Active means still setting up!<br />
<img src="/assets/images/get-bgp-neighbor-summary.png" alt="" class="img-fluid rounded mr-3 float-left" /></p>
<p>View further information on the BGP connection. Also shows whether the connection is established or not.<br />
<code class="highlighter-rouge">get bgp neighbor</code><br />
<img src="/assets/images/get-bgp-neighbor.png" alt="" class="img-fluid rounded mr-3 float-left" /></p>
<p>View ipv4 bgp information.<br />
<code class="highlighter-rouge">get bgp ipv4</code></p>
<p>Exit the Tier-0 VRF service gateway mode.</p>
<ul>
<li>Press q to quit out of BGP neighbor output.</li>
</ul>
<h3 id="route-information-from-the-edges">Route Information from the Edges</h3>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>get logical-routers
vrf #
get route
</code></pre></div></div>
<p><img src="/assets/images/get-route.png" alt="" class="img-fluid rounded mr-3 float-left" /></p>
<p><code class="highlighter-rouge">b \></code> is a route learned from a BGP peer.</p>
<p>For DR check the forwarder for similar routing information.<br />
<code class="highlighter-rouge">get forwarding</code>
<img src="/assets/images/get-fwd.png" alt="" class="img-fluid rounded mr-3 float-left" /></p>
<p>In the previous example I was connected to the SR to collect that forwarding information, but you can also get it from the DR. This is useful for seeing routing configuration for DR components throughout the environment, such as those on a Tier-1 DR.</p>
<h3 id="dhcp">DHCP</h3>
<p>Runs on Edges.<br />
<code class="highlighter-rouge">get dhcp servers</code><br />
<img src="/assets/images/get-dhcp-server.png" alt="" class="img-fluid rounded mr-3 float-left" /></p>
<p><code class="highlighter-rouge">get dhcp ip-pools</code><br />
<img src="/assets/images/get-dhcp-ip-pools.png" alt="" class="img-fluid rounded mr-3 float-left" /></p>
<p><code class="highlighter-rouge">get dhcp leases</code><br />
<img src="/assets/images/get-dhcp-leases.png" alt="" class="img-fluid rounded mr-3 float-left" /></p>
<h3 id="load-balancer">Load Balancer</h3>
<p><code class="highlighter-rouge">get load-balancer</code><br />
<img src="/assets/images/get-load-balancer.png" alt="" class="img-fluid rounded mr-3 float-left" /><br />
The output shows the general load balancer configuration, including UUID and Virtual Server ID.</p>
<p>Copy the UUID and the Virtual Server ID values and paste them.
Verify the virtual server configuration.<br />
<code class="highlighter-rouge">get load-balancer UUID virtual-server <Virtual_Server_ID></code><br />
<img src="/assets/images/get-load-balancer-uuid.png" alt="" class="img-fluid rounded mr-3 float-left" /></p>
<p>Verify the server pool configuration.<br />
<code class="highlighter-rouge">get load-balancer UUID pools</code><br />
UUID is the value that you recorded for the load balancer.<br />
<img src="/assets/images/get-lb-pools.png" alt="" class="img-fluid rounded mr-3 float-left" /></p>
<h3 id="vpn-connectivity-tests-on-edges">VPN Connectivity Tests on Edges</h3>
<p>Verify that the L2VPN session is active, identify the peers, and ensure that the tunnel status is up.<br />
<code class="highlighter-rouge">get ipsecvpn session active</code><br />
<img src="/assets/images/ipsec-vpn.png" alt="" class="img-fluid rounded mr-3" /></p>
<p>Verify that the sessions are up.<br />
<code class="highlighter-rouge">get ipsecvpn session status</code> <br />
<img src="/assets/images/ipsec-vpn-session.png" alt="" class="img-fluid rounded mr-3" /></p>
<p>Check whether the ipsecvpn session is up between the local and remote peers.<br />
<code class="highlighter-rouge">get ipsecvpn session summary</code><br />
<img src="/assets/images/ipsec-vpn-summary.png" alt="" class="img-fluid rounded mr-3" /></p>
<p>Get the l2vpn session, tunnel, and IPSEC session numbers, and check that the status is UP.<br />
<code class="highlighter-rouge">get l2vpn sessions</code><br />
<img src="/assets/images/l2vpn-sessinns.png" alt="" class="img-fluid rounded mr-3" /></p>
<p>Get statistical information of the local and remote peers, whether the status is UP, count of packets received, bytes received (RX), packets transmitted (TX), and packets dropped, malformed, or loops.<br />
<code class="highlighter-rouge">get l2vpn session stats</code><br />
<img src="/assets/images/l2vpn-session-stats.png" alt="" class="img-fluid rounded mr-3" /></p>
<p>Get the session configuration information.<br />
<code class="highlighter-rouge">get l2vpn session config</code><br />
<img src="/assets/images/l2vpn-session-config.png" alt="" class="img-fluid rounded mr-3" /></p>
<h3 id="nsx-manager">NSX Manager</h3>
<h4 id="local-users">Local Users</h4>
<p>To change the password of an account run:<br />
<code class="highlighter-rouge">set user <username> [password <password> [old-password \<old-password>]]</code></p>
<h5 id="authentication-policy-settings-for-local-users">Authentication Policy Settings for Local Users</h5>
<p>Use the following to set:</p>
<p>Password length<br />
<code class="highlighter-rouge">set auth-policy minimum-password-length <password-length></code></p>
<p>UI and API authentication policies.
The UI and API local users have the same policy.<br />
<code class="highlighter-rouge">set auth-policy api lockout-period <lockout-period></code></p>
<p><code class="highlighter-rouge">set auth-policy api lockout-reset-period <lockout-reset-period></code></p>
<p><code class="highlighter-rouge">set auth-policy api max-auth-failures <auth-failures></code></p>
<p>Set CLI authentication policy<br />
<code class="highlighter-rouge">set auth-policy cli lockout-period lockout-period <lockout-period></code></p>
<h4 id="view-logs">View Logs</h4>
<h5 id="nsx-cli">NSX CLI</h5>
<p><code class="highlighter-rouge">get log-file policy.log</code></p>
<h5 id="engineering-mode">Engineering Mode</h5>
<p>Use <code class="highlighter-rouge">st en</code> to enter engineering mode (root privileged mode)</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>st en
tail /var/log/policy/policy.log
</code></pre></div></div>
<h5 id="syslog--manager-and-edges">Syslog – Manager and Edges</h5>
<p><code class="highlighter-rouge">set logging-server <hostname-or-ip-address[:port]> proto \<protocol> level <level></code><br />
<img src="/assets/images/set-logging-server.png" alt="" class="img-fluid rounded mr-3 float-left" /></p>
<h3 id="transport-nodes">Transport Nodes</h3>
<p>Logical Switches
List all transport nodes associated with a logical switch.<br />
<code class="highlighter-rouge">get logical-switches <switch_UUID> transport-node-table</code><br />
<img src="/assets/images/logical-switches.png" alt="" class="img-fluid rounded mr-3 float-left" /></p>
<p>List all TEPs associated with a logical switch.<br />
<code class="highlighter-rouge">get logical-switches <switch_UUID> vtep</code></p>
<p>List MAC table associated with a logical switch.<br />
<code class="highlighter-rouge">get logical-switches <switch_UUID> mac-table</code></p>
<p>List ARP table associated with a logical switch.<br />
<code class="highlighter-rouge">get logical-switches <switch_UUID> arp-table</code><br />
<img src="/assets/images/vtep-mac-arp.png" alt="" class="img-fluid rounded mr-3 float-left" /></p>
<h3 id="deploy-manager-cluster">Deploy Manager Cluster</h3>
<p>To deploy a manager to an existing cluster, get the cluster configuration ID, make a note of the existing Managers certificate thumbprint and use that to join the new node to the cluster. Finally get the cluster status to confirm the new host has joined.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>get cluster config
join <NSX-Manager-IP> cluster-id <cluster-id> username<NSX-Manager-username> password<NSX-Manager-password> thumbprint <NSX-Manager1's-thumbpint>
get cluster status
</code></pre></div></div>
<p>OR via API<br />
<code class="highlighter-rouge">POST https://<nsx-mgr>/api/v1/cluster?action=join_cluster</code></p>
<h3 id="esxi-configuration">ESXi Configuration</h3>
<p>Several esxcli commands can be used to aid in NSX-T configuration.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>esxcli network firewall ruleset set -r syslog -e true
esxcli system syslog config set --loghost=<hostname-or-ip-address[:port]>
esxcli system syslog reload
</code></pre></div></div>
<p>Can also use the nsxcli command set such as:<br />
<code class="highlighter-rouge">get logical-switches</code></p>
<p><img src="/assets/images/logical-switches-and-full-details.png" alt="" class="img-fluid rounded mr-3 float-left" /></p>
<h4 id="n-vds-and-tunnel-information">N-VDS and Tunnel Information</h4>
<p>Show logical switch and N-VDS info<br />
<code class="highlighter-rouge">get logical-switch</code></p>
<p>Display the status of the overlay tunnels
Note N-VDS’s used to be called host switches, hence the get host-switch command.<br />
<code class="highlighter-rouge">get-host switch <N-VDS_NAME> tunnel</code><br />
<img src="/assets/images/n-vds-tunnel-info.png" alt="" class="img-fluid rounded mr-3 float-left" /></p>
<h3 id="kvm-configuration">KVM Configuration</h3>
<h4 id="syslog">Syslog</h4>
<p>Login as root<br />
Create this file<br />
<code class="highlighter-rouge">/etc/rsyslog.d/40-vmware-remote-logging.conf</code></p>
<p>Add this line to the file<br />
<code class="highlighter-rouge">'*.*@<syslog_server_ip>:514;RFC5424fmt'</code></p>
<p>Restart syslog<br />
<code class="highlighter-rouge">systemctl restart rsyslog</code></p>
<p>nsxcli can also be used as outlined above. ESXi gives a bit more info as the kernel info is available in ESXi that isn’t there for KVM.</p>
<h4 id="packet-capture">Packet Capture</h4>
<p>Can use CLI to setup network packet capture on:</p>
<h5 id="nsx-manager-1">NSX Manager</h5>
<p><code class="highlighter-rouge">start capture interface <interface-name> [file <filename>] [count <packet-count>] [expression <expression>]</code></p>
<h5 id="nsx-edges">NSX Edges</h5>
<p><code class="highlighter-rouge">set capture session <session-number> interface <port-uuid> direction <direction></code></p>
<p>Example.<br />
<code class="highlighter-rouge">set capture session 1 interface fp-eth1 direction in</code><br />
<code class="highlighter-rouge">set capture session 1 expression src net 172.20.10.0/24</code></p>
<p>Removed captured session information with:<br />
<code class="highlighter-rouge">del capture session 1</code></p>
<h4 id="esxi">ESXi</h4>
<p>Collect packets. Can send to a file.<br />
<code class="highlighter-rouge">pktcap-uw</code><br />
<img src="/assets/images/pkt-cap.png" alt="" class="img-fluid rounded mr-3 float-left" /></p>
<p>Can Pipe it to view captured packets on the screen.<br />
<code class="highlighter-rouge">pktcap-uw | tcpdump -uw</code></p>
<p>View packets.<br />
<code class="highlighter-rouge">tcpdump-uw</code>
<img src="/assets/images/tcp-dump.png" alt="" class="img-fluid rounded mr-3 float-left" /></p>
<h4 id="kvm">KVM</h4>
<p><code class="highlighter-rouge">tcpdump</code></p>
<p>Installation problems</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>get services
get service <service name>
get cluster status
get configuration
get managers
</code></pre></div></div>
<h3 id="cluster-configuration-validation">Cluster Configuration Validation</h3>
<h4 id="nsx-manager-nodes">NSX Manager nodes</h4>
<table>
<thead>
<tr>
<th><code class="highlighter-rouge">get cluster status</code> (nsxcli)</th>
<th><code class="highlighter-rouge">get services</code> (nsxcli)</th>
<th><code class="highlighter-rouge">get log-file</code> (nsxcli)</th>
<th>Login as <code class="highlighter-rouge">root</code> (Linux)</th>
</tr>
</thead>
<tbody>
<tr>
<td>DATASTORE</td>
<td>datastore</td>
<td>-</td>
<td>/var/log/corfu/corfu.9000.log</td>
</tr>
<tr>
<td>CLUSTER_BOOT_MANAGER</td>
<td>cluster_manager</td>
<td>-</td>
<td>/var/log/cloudnext/nsx-ccp.log</td>
</tr>
<tr>
<td>CONTROLLER</td>
<td>controller</td>
<td>-</td>
<td>/var/log/cbm/cbm.log</td>
</tr>
<tr>
<td>MANAGER</td>
<td>manager</td>
<td>manager.log</td>
<td>/var/log/proton/nsxapi.log</td>
</tr>
<tr>
<td>POLICY</td>
<td>policy</td>
<td>policy.log</td>
<td>/var/log/policy/policy.log</td>
</tr>
<tr>
<td>HTTP</td>
<td>http</td>
<td>http.log</td>
<td>/var/log/proxy/reverse-proxy.log</td>
</tr>
<tr>
<td>-</td>
<td>-</td>
<td>syslog</td>
<td>/var/log/syslog</td>
</tr>
</tbody>
</table>
<h4 id="transport-node-preparation">Transport Node Preparation</h4>
<p>Check VIBs installed</p>
<h5 id="vsphere">vSphere</h5>
<p><code class="highlighter-rouge">esxcli software vib list | grep -e nsx -e vsip</code><br />
<img src="/assets/images/vibs.png" alt="" class="img-fluid rounded mr-3 float-left" /></p>
<p>This might work too.<br />
<code class="highlighter-rouge">esxcfg-module -l | grep nsx</code></p>
<h5 id="kvm-1">KVM</h5>
<h6 id="ubuntu">Ubuntu</h6>
<p><code class="highlighter-rouge">dpkg --list | grep nsx</code>
<img src="/assets/images/dpdk.png" alt="" class="img-fluid rounded mr-3 float-left" /></p>
<h6 id="redhat">Redhat</h6>
<p><code class="highlighter-rouge">rpm -qa | grep nsx</code><br />
<img src="/assets/images/rpm.png" alt="" class="img-fluid rounded mr-3 float-left" /></p>
<h3 id="check-tep-and-hyperbus">Check TEP and Hyperbus</h3>
<p>Hyperbus is for containers.</p>
<h4 id="vsphere-1">vSphere</h4>
<p><code class="highlighter-rouge">esxcli network ip interface ipv4 address list</code><br />
Overlay (TEP and vmk10 (default vmk)). Hyperbus (vmk50 default vmk)).<br />
<img src="/assets/images/tep-ipv4.png" alt="" class="img-fluid rounded mr-3 float-left" /></p>
<p>Verify TCP/IP for TEP and hyberbus.<br />
<code class="highlighter-rouge">esxcli network ip netstack list</code>
<img src="/assets/images/ip-stack.png" alt="" class="img-fluid rounded mr-3 float-left" /> <br />
Vxlan is GENEVE in ESXi.</p>
<h4 id="kvm-2">KVM</h4>
<p><code class="highlighter-rouge">ifconfig</code><br />
<img src="/assets/images/if-config.png" alt="" class="img-fluid rounded mr-3 float-left" /></p>
<p><code class="highlighter-rouge">ovs-vsctl list Open_vSwitch</code><br />
<img src="/assets/images/ovs.png" alt="" class="img-fluid rounded mr-3 float-left" /></p>
<p><code class="highlighter-rouge">ovs-vsctl show</code><br />
Ubuntu KVM hosts create two bridges.</p>
<p>nsx-managed<br />
nsx-vswitch.0<br />
<img src="/assets/images/ovs-show.png" alt="" class="img-fluid rounded mr-3 float-left" /></p>
<h3 id="agents-and-connectivity">Agents and Connectivity</h3>
<h4 id="esxi-1">ESXi</h4>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/etc/init.d/nsx-mpa status
esxcli network ip connection list | grep 5671
/etc/init.d/nsx-proxy status
esxcli network ip connection list | grep 1235
</code></pre></div></div>
<p><code class="highlighter-rouge">/etc/init.d/nsx-opsagent status</code><br />
<img src="/assets/images/ops-agent.png" alt="" class="img-fluid rounded mr-3 float-left" /></p>
<h4 id="kvm-3">KVM</h4>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>service nsx-mpa status
netstat -nap | grep 5671
</code></pre></div></div>
<p><img src="/assets/images/mpa-kvm.png" alt="" class="img-fluid rounded mr-3 float-left" /></p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>service nsx-proxy status
netstat -nap | grep 1235
</code></pre></div></div>
<p><img src="/assets/images/proxy-kvm.png" alt="" class="img-fluid rounded mr-3 float-left" /><br />
Alternatively, view the connection status using other CLI commands.</p>
<h4 id="esxi-2">ESXi</h4>
<p>type the <code class="highlighter-rouge">esxcli</code> command.<br />
<code class="highlighter-rouge">esxcli network ip connection list | grep 1235</code></p>
<h4 id="kvm-4">KVM</h4>
<p>Type the command netstat -anp –tcp | grep 1235.<br />
user@host:~$ <code class="highlighter-rouge">netstat -anp --tcp | grep 1235</code></p>
<h3 id="checking-communication-from-host-to-controller-and-manager">Checking Communication from Host to Controller and Manager</h3>
<h4 id="esxi-3">ESXi</h4>
<p>On an ESXi host using NSX-T CLI commands:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>esxi-01.corp.local> get managers
– 192.168.110.19 Connected
</code></pre></div></div>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>esxi-01.corp.local>
get controllers
Controller IP Port SSL Status Is Physical Master Session State Controller FQDN
192.168.110.16 1235 enabled connected true up NA
</code></pre></div></div>
<h4 id="kvm-5">KVM</h4>
<p>On a KVM host using NSX-T CLI commands:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>kvm-01\>
get managers
– 192.168.110.19 Connected
</code></pre></div></div>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>kvm-01\>
get controllers
Controller IP Port SSL Status Is Physical Master Session State Controller FQDN
192.168.110.16 1235 enabled connected true up NA
</code></pre></div></div>
<p>View details of N-VDS
The N-VDS has its own command line tool, <code class="highlighter-rouge">net-vdl2</code>.<br />
<code class="highlighter-rouge">net-vdl2 -l</code>
<img src="/assets/images/net-vdl2.png" alt="" class="img-fluid rounded mr-3 float-left" /></p>
<p>ESXi LIF MAC
View The LIF (Logical Interface) vMAC to pMAC on ESXi host.<br />
<code class="highlighter-rouge">net-vdr -C -l</code>
<img src="/assets/images/net-vdr-lif.png" alt="" class="img-fluid rounded mr-3 float-left" /><br />
<code class="highlighter-rouge">02:50:56:56:44:52</code> is always the vMAC for the LIFs for all DRs.</p>
<h3 id="dfw-validation">DFW Validation</h3>
<h4 id="esxi-4">ESXi</h4>
<p><code class="highlighter-rouge">nsxt-vsip</code> is the DFW module.
<img src="/assets/images/nsxt-vsip.png" alt="" class="img-fluid rounded mr-3 float-left" /></p>
<p>Check dvFilter for firewall rules.<br />
<code class="highlighter-rouge">summarize-dvfilter | grep <VM_NAME></code><br />
<img src="/assets/images/summarize-dvfilter.png" alt="" class="img-fluid rounded mr-3 float-left" /></p>
<h4 id="kvm-6">KVM</h4>
<p>Use these to validate the distributed firewall Settings.
View app firewall virtual interfaces.<br />
<code class="highlighter-rouge">ovs-appctl -t /var/run/openvswitch/nsxa-ctl dfw/vif</code><br />
<img src="/assets/images/ovs-appctl.png" alt="" class="img-fluid rounded mr-3 float-left" /></p>
<p>View firewall rules with containing addrsets.<br />
<code class="highlighter-rouge">ovs-appctl -t /var/run/openvswitch/nsxa-ctl dfw/rules <VIF_ID_NUMBER></code>
<img src="/assets/images/addr-sets.png" alt="" class="img-fluid rounded mr-3 float-left" /></p>
<h3 id="cli-upgrade-confirmation">CLI Upgrade Confirmation</h3>
<p>Post upgrades, use these commands to validate that NSX-T has been upgraded successfully and the correct NSX-T modules are installed.</p>
<h4 id="vsphere-2">vSphere</h4>
<p><code class="highlighter-rouge">esxcli software vib list | grep nsx</code></p>
<h4 id="kvm-7">KVM</h4>
<h5 id="ubuntu-1">Ubuntu</h5>
<p><code class="highlighter-rouge">dpkg -l | grep nsx</code></p>
<h5 id="red-hat">Red Hat</h5>
<p><code class="highlighter-rouge">rpm -qa | egrep 'nsx|openvwitch'</code></p>
<h5 id="nsxcli">nsxcli</h5>
<p><code class="highlighter-rouge">get version</code></p>Simon GreavesHere is a reference guide for some useful command line tools you can run on NSX-T. NSX CLI Introduction NSX CLI (nsxcli) is the command line tool for troubleshooting NSX-T. It’s run in a non-root mode so you have to use the command structure available. For instance there is no grep, But you can use find and pipe instead. You can use the nsxcli command line tool from various elements throughout the NSX-T deployment including NSX Manager, Edges and ESXi Transport Nodes.NSX-T Command Line Cheat Sheet2020-01-31T00:00:00+00:002020-01-31T00:00:00+00:00/nsx-t-command-line-cheat-sheet<p>Having recently passed my NSX-T VCP, I thought I’d share the command line tools I used to practice in a lab to get to grips with NSX-T installation, configuration, managing and troubleshooting.</p>
<p>I know I will be revisiting this site for reference in future. I hope you all enjoy it!</p>
<p>I will cover a walkthrough of some of these commands in another post if it’s new to you and link it <a href="/nsx-t-cli-reference-guide/">here</a>.
<!--more--></p>
<h1 id="nsx-manager">NSX Manager</h1>
<p><strong>Setup Troubleshooting</strong></p>
<table>
<thead>
<tr>
<th>Description</th>
<th>Commands</th>
</tr>
</thead>
<tbody>
<tr>
<td>Query Management Cluster Status</td>
<td><code class="highlighter-rouge">get cluster status [verbose]</code></td>
</tr>
<tr>
<td>View the cluster configuration and which node is running which cluster component</td>
<td><code class="highlighter-rouge">get cluster config</code></td>
</tr>
<tr>
<td>Detach a NSX Manager node from Cluster:</td>
<td><code class="highlighter-rouge">detach node <node-id></code></td>
</tr>
<tr>
<td>Retrieve NSX Manager Certificate Thumbprint</td>
<td><code class="highlighter-rouge">get certificate api thumbprint</code></td>
</tr>
<tr>
<td>Join NSX Manager to Cluster</td>
<td><code class="highlighter-rouge">join NSX-Manager-ip-address cluster-id <cluster-id> thumbprint <thumbprint> username <username> password <password></code></td>
</tr>
<tr>
<td>Disable CLI timeout</td>
<td><code class="highlighter-rouge">set cli-timeout 0</code></td>
</tr>
<tr>
<td>List the transport nodes registered with NSX Manager</td>
<td><code class="highlighter-rouge">get nodes</code></td>
</tr>
<tr>
<td>Query the Managers Connection Status</td>
<td><code class="highlighter-rouge">get managers</code></td>
</tr>
<tr>
<td>List all ESXi hosts to get the transport Node UUIDS</td>
<td><code class="highlighter-rouge">get transport-nodes status</code></td>
</tr>
<tr>
<td>List the transport Node Status</td>
<td><code class="highlighter-rouge">get transport-node <uuid> status</code></td>
</tr>
<tr>
<td>List the Transport Node vtep information</td>
<td><code class="highlighter-rouge">get transport-node <uuid> vtep</code></td>
</tr>
<tr>
<td>Lists the VIF UUID of a VM connected to Segment on a Transport Node</td>
<td><code class="highlighter-rouge">get transport-node <uuid> vifs</code></td>
</tr>
<tr>
<td>Set logging level on NSX Manager</td>
<td><code class="highlighter-rouge">set service manager logging-level debug</code></td>
</tr>
<tr>
<td>Configure a remote syslog server</td>
<td><code class="highlighter-rouge">set logging-server <hostname-or-ip-address[:port]> proto <protocol> level <level></code></td>
</tr>
<tr>
<td>Read the Policy Manager log</td>
<td><code class="highlighter-rouge">get log-file policy.log <follow></code></td>
</tr>
<tr>
<td>Read the syslog log</td>
<td><code class="highlighter-rouge">get log-file syslog <follow></code></td>
</tr>
<tr>
<td>Setup packet capture</td>
<td><code class="highlighter-rouge">start capture interface <interface-name> [file <filename>] [count <packet-count>] [expression <expression>]</code></td>
</tr>
<tr>
<td>Enter root privileged Mode</td>
<td><code class="highlighter-rouge">st en</code></td>
</tr>
</tbody>
</table>
<p><strong>Logical Switching</strong></p>
<table>
<thead>
<tr>
<th>Description</th>
<th>Commands</th>
</tr>
</thead>
<tbody>
<tr>
<td>List all the Logical Switches</td>
<td><code class="highlighter-rouge">get logical-switches</code></td>
</tr>
<tr>
<td>List all the switch ports connected to the Segment</td>
<td><code class="highlighter-rouge">get logical-switch <uuid> ports</code></td>
</tr>
<tr>
<td>List information about a Segment</td>
<td><code class="highlighter-rouge">get logical-switch <vni-or-uuid></code></td>
</tr>
<tr>
<td>List the ARP table of a Logical Switch</td>
<td><code class="highlighter-rouge">get logical-switch <vni-or-uuid> arp-table</code></td>
</tr>
<tr>
<td>List the MAC table of a Logical Switch</td>
<td><code class="highlighter-rouge">get logical-switch <vni-or-uuid> mac-table</code></td>
</tr>
<tr>
<td>List the statistics of a Logical Switch</td>
<td><code class="highlighter-rouge">get logical-switch <vni-or-uuid> stats</code></td>
</tr>
<tr>
<td>List the Transport Node table of a Segment</td>
<td><code class="highlighter-rouge">get logical-switch <vni-or-uuid> transport-node-table</code></td>
</tr>
<tr>
<td>List the VTEP table of a Segment</td>
<td><code class="highlighter-rouge">get logical-switch <vni-or-uuid> vtep</code></td>
</tr>
<tr>
<td>View the Logical Switch Port information</td>
<td><code class="highlighter-rouge">get logical-switch-port <uuid></code></td>
</tr>
<tr>
<td>List the logical Switches statistics</td>
<td><code class="highlighter-rouge">get logical-switches stats</code></td>
</tr>
</tbody>
</table>
<p><strong>Logical Routing</strong></p>
<table>
<thead>
<tr>
<th>Description</th>
<th>Commands</th>
</tr>
</thead>
<tbody>
<tr>
<td>View the list of logical routers</td>
<td><code class="highlighter-rouge">get logical-router</code></td>
</tr>
<tr>
<td>View the information about a logical router</td>
<td><code class="highlighter-rouge">get logical-router <uuid></code></td>
</tr>
<tr>
<td>View the list of logical router interfaces</td>
<td><code class="highlighter-rouge">get logical-router <uuid> interfaces</code></td>
</tr>
<tr>
<td>View the logical router interface information</td>
<td><code class="highlighter-rouge">get logical-router <uuid> interface <interface-id></code></td>
</tr>
<tr>
<td>View the Routers on a logical router</td>
<td><code class="highlighter-rouge">get logical-router <uuid> route</code></td>
</tr>
<tr>
<td>List the NSX Edge nodes registered with NSX Manager and their associated controller</td>
<td><code class="highlighter-rouge">get transport-node status</code></td>
</tr>
</tbody>
</table>
<p><strong>Firewall</strong></p>
<table>
<thead>
<tr>
<th>Description</th>
<th>Commands</th>
</tr>
</thead>
<tbody>
<tr>
<td>View the Rule count of L2, L3 Firewall Rules</td>
<td><code class="highlighter-rouge">get firewall summary</code></td>
</tr>
<tr>
<td>List of firewall entities in the excluded-list</td>
<td><code class="highlighter-rouge">get firewall exclude-list</code></td>
</tr>
<tr>
<td>Firewall Section that is not created or deleted completely from the system</td>
<td><code class="highlighter-rouge">get firewall orphaned-section</code></td>
</tr>
<tr>
<td>Firewall rules published to CCP</td>
<td><code class="highlighter-rouge">get firewall published-entity</code></td>
</tr>
<tr>
<td>Firewall Status</td>
<td><code class="highlighter-rouge">get firewall status</code></td>
</tr>
</tbody>
</table>
<p><strong>User Account Administration</strong></p>
<table>
<thead>
<tr>
<th>Description</th>
<th>Commands</th>
</tr>
</thead>
<tbody>
<tr>
<td>Change local user password</td>
<td><code class="highlighter-rouge">Set user <username> [password <password> [old-password <old-password>]</code></td>
</tr>
<tr>
<td>Password length</td>
<td><code class="highlighter-rouge">Set auth-policy minimum-password-length <password-length></code></td>
</tr>
<tr>
<td><strong><em>UI and API authentication policies</em></strong></td>
<td> </td>
</tr>
<tr>
<td> </td>
<td><code class="highlighter-rouge">set auth-policy api lockout-period <lockout-period></code></td>
</tr>
<tr>
<td> </td>
<td><code class="highlighter-rouge">set auth-policy api lockout-reset-period <lockout-reset-period></code></td>
</tr>
<tr>
<td> </td>
<td><code class="highlighter-rouge">set auth-policy api max-auth-failures <auth-failures></code></td>
</tr>
<tr>
<td>Set CLI authentication policy</td>
<td><code class="highlighter-rouge">set auth-policy cli lockout-period lockout-period <lockout-period></code></td>
</tr>
</tbody>
</table>
<h1 id="esxi">ESXi</h1>
<p><strong>Setup Troubleshooting</strong></p>
<table>
<thead>
<tr>
<th>Description</th>
<th>Commands</th>
</tr>
</thead>
<tbody>
<tr>
<td>List the VIBs loaded on ESXi</td>
<td><code class="highlighter-rouge">esxcli software vib list | grep -e nsx -e vsip</code></td>
</tr>
<tr>
<td>List all the NSX-T modules currently loaded in the system</td>
<td><code class="highlighter-rouge">esxcli system module list | grep nsx</code></td>
</tr>
<tr>
<td><strong><em>Check the User world agents (UWA):</em></strong></td>
<td> </td>
</tr>
<tr>
<td> </td>
<td><code class="highlighter-rouge">nsx-mpa /etc/init.d/nsx-mpa status | start | stop | restart</code></td>
</tr>
<tr>
<td> </td>
<td><code class="highlighter-rouge">nsx-proxy /etc/init.d/nsx-proxy status | start | stop | restart</code></td>
</tr>
<tr>
<td> </td>
<td><code class="highlighter-rouge">nsx-opsagent /etc/init.d/nsx-opsagent status | start | stop | restart</code></td>
</tr>
<tr>
<td> </td>
<td><code class="highlighter-rouge">nsxa /etc/init.d/nsxastatus | start | stop | restart</code></td>
</tr>
<tr>
<td><strong><em>Check UWA Connection:</em></strong></td>
<td> </td>
</tr>
<tr>
<td>Port 1235 to Controllers</td>
<td><code class="highlighter-rouge">esxcli network ip connection list | grep 1235</code></td>
</tr>
<tr>
<td>Port 5671 to NSX Manager</td>
<td><code class="highlighter-rouge">esxcli network ip connection list | grep 5671</code></td>
</tr>
<tr>
<td>List Physical NICs/vmnic</td>
<td><code class="highlighter-rouge">esxcli network nic list</code></td>
</tr>
<tr>
<td>Physical NIC details</td>
<td><code class="highlighter-rouge">esxcli network nic get -n vmnic3</code></td>
</tr>
<tr>
<td>List vmk NICs with IP addresses/MAC/MTU and so on (vmk10 is TEP, vmk50 is containers)</td>
<td><code class="highlighter-rouge">esxcli network ip interface ipv4 get</code></td>
</tr>
<tr>
<td>Details of each vmk NIC, including vDS information</td>
<td><code class="highlighter-rouge">esxcli network ip interface list</code></td>
</tr>
<tr>
<td>Details of netstack IP Stack created on ESXi</td>
<td><code class="highlighter-rouge">esxcli network ipinterface list --netstack=vxlan</code></td>
</tr>
<tr>
<td>Ping from a VXLAN TCP/IP Stack</td>
<td><code class="highlighter-rouge">vmkping ++netstack=vxlan <host-IP> -s <packet-size></code></td>
</tr>
<tr>
<td>View routing table of VXLAN-dedicated TCP/IP stack</td>
<td><code class="highlighter-rouge">esxcli network ip route ipv4 list -N vxlan</code></td>
</tr>
<tr>
<td>View ARP table of VXLAN dedicated TCP/IP stack</td>
<td><code class="highlighter-rouge">esxcli network ip neighbor list -N vxlan</code></td>
</tr>
<tr>
<td><strong><em>Setup syslog:</em></strong></td>
<td> </td>
</tr>
<tr>
<td>1.</td>
<td><code class="highlighter-rouge">esxcli network firewall ruleset set -r syslog -e true</code></td>
</tr>
<tr>
<td>2.</td>
<td><code class="highlighter-rouge">esxcli system syslog config set --loghost=<hostname-or-ip-address[:port]></code></td>
</tr>
<tr>
<td>3.</td>
<td><code class="highlighter-rouge">esxcli system syslog reload</code></td>
</tr>
</tbody>
</table>
<p><strong>Logical Switching</strong></p>
<table>
<thead>
<tr>
<th>Description</th>
<th>Commands</th>
</tr>
</thead>
<tbody>
<tr>
<td>View all the logical switches</td>
<td><code class="highlighter-rouge">get logical-switches</code></td>
</tr>
<tr>
<td>View the Logical Switch information from ESXi host</td>
<td><code class="highlighter-rouge">get logical-switch <logical-switch-id></code></td>
</tr>
<tr>
<td>View the ARP table of a logical switch</td>
<td><code class="highlighter-rouge">get logical-switch <logical-switch-id> arp-table</code></td>
</tr>
<tr>
<td>View the MAC table of a logical switch</td>
<td><code class="highlighter-rouge">get logical-switch <logical-switch-id> mac-table</code></td>
</tr>
<tr>
<td>View the Neighbor Discovery (ND) table of a logical switch</td>
<td><code class="highlighter-rouge">get logical-switch <logical-switch-id> nd-table</code></td>
</tr>
<tr>
<td>View the VTEP table of a logical Switch</td>
<td><code class="highlighter-rouge">get logical-switch <logical-switch-id> vtep-table</code></td>
</tr>
<tr>
<td>View the logical switch port status</td>
<td><code class="highlighter-rouge">get logical-switch-port status</code></td>
</tr>
<tr>
<td>View the MAC, ARP, VTEP tables from local or remote host using VNI</td>
<td><code class="highlighter-rouge">get logical-switch [local | remote] [mac-cache | arp-cache | vtep-cache] <vni></code></td>
</tr>
<tr>
<td>Verify the Transport Node Tunnel Status</td>
<td><code class="highlighter-rouge">get host-switch <host-switch-name> tunnels</code></td>
</tr>
<tr>
<td>To view the Switch port ID from root mode</td>
<td><code class="highlighter-rouge">net-stats -l</code></td>
</tr>
<tr>
<td>To view the Switches configured on ESXi</td>
<td><code class="highlighter-rouge">esxcfg-vswitch -l</code></td>
</tr>
<tr>
<td>Performance monitoring tool on ESXi</td>
<td><code class="highlighter-rouge">esxtop</code></td>
</tr>
<tr>
<td>View the VTEP and VNI Configuration</td>
<td><code class="highlighter-rouge">net-vdl2 -l</code></td>
</tr>
<tr>
<td>To view the N-VDS Uplink Configuration</td>
<td><code class="highlighter-rouge">net-vdr -C -l</code></td>
</tr>
<tr>
<td>View the Logical Routers from ESXi</td>
<td><code class="highlighter-rouge">net-vdr -I -l</code></td>
</tr>
<tr>
<td>Verify VXLAN kernel module vdl2 is loaded</td>
<td><code class="highlighter-rouge">esxcli system module get -m nsxt-vdl2</code></td>
</tr>
<tr>
<td>Setup packet capture</td>
<td><code class="highlighter-rouge">pktcap-uw [-o <filename.pcap>]</code></td>
</tr>
<tr>
<td>View captured packets</td>
<td><code class="highlighter-rouge">tcpdump-uw</code></td>
</tr>
<tr>
<td>Capture packets and display live output on screen (-dir 1 is outgoing traffic, -dir 0 is incoming traffic)</td>
<td><code class="highlighter-rouge">pktcap-uw --switchport <VM-Switch-Port-Number> [--dir <1 | 2>] | tcpdump-uw</code></td>
</tr>
<tr>
<td>Find VM Switch Port Number</td>
<td><code class="highlighter-rouge">esxtop <n></code></td>
</tr>
<tr>
<td>Packet Capture Target Options</td>
<td><code class="highlighter-rouge">pktcap-uw</code></td>
</tr>
<tr>
<td>PreDVFilter</td>
<td><code class="highlighter-rouge">--capture PreDVFilter --dvfilter <dvfilter-Name></code></td>
</tr>
<tr>
<td>PostDVFilter</td>
<td><code class="highlighter-rouge">--capture PostDVFilter --dvfilter <dvFilter-Name></code></td>
</tr>
<tr>
<td>Source VM Switch Port</td>
<td><code class="highlighter-rouge">--switchport <VM-Switchport-Number> --dir 0</code></td>
</tr>
<tr>
<td>Leaving the VNI Port</td>
<td><code class="highlighter-rouge">--switchport <VM-Switch-Port-Number> --dir 1 --vni=<Switch-VNI-Number></code></td>
</tr>
<tr>
<td>Leaving vdrPort</td>
<td><code class="highlighter-rouge">--switchport <VM-Switch-Port> --dir 0</code></td>
</tr>
<tr>
<td>Outgoing encapsulated overlay traffic</td>
<td><code class="highlighter-rouge">---uplink <vmnic#> --dir 1 --overlay geneve</code></td>
</tr>
<tr>
<td>Incoming encapsulated</td>
<td><code class="highlighter-rouge">--uplink <vmnic#> --dir 0 --overlay geneve</code></td>
</tr>
<tr>
<td>Arriving at destination VM Switch Port</td>
<td><code class="highlighter-rouge">--switchport <VM-Switchport-Number> --dir 0</code></td>
</tr>
<tr>
<td>PostDVFilter</td>
<td><code class="highlighter-rouge">--capture PostDVFilter --dvfilter <dvFilter-Name></code></td>
</tr>
<tr>
<td>PreDVFilter</td>
<td><code class="highlighter-rouge">--capture PreDVFilter --dvfilter <dvfilter-Name></code></td>
</tr>
</tbody>
</table>
<p><strong>Logical Routing</strong></p>
<table>
<thead>
<tr>
<th>Description</th>
<th>Commands</th>
</tr>
</thead>
<tbody>
<tr>
<td>View the Logical Router Forwarding table</td>
<td><code class="highlighter-rouge">get logical-router <UUID> forwarding</code></td>
</tr>
<tr>
<td>View the Logical Router Interface</td>
<td><code class="highlighter-rouge">get logical-router <UUID> interface</code></td>
</tr>
<tr>
<td>View the Logical Router Interfaces</td>
<td><code class="highlighter-rouge">get logical-router <UUID> interfaces</code></td>
</tr>
<tr>
<td>View the logical Router Neighbour</td>
<td><code class="highlighter-rouge">get logical-router <UUID> neighbor</code></td>
</tr>
<tr>
<td>View the logical Router Neighbours</td>
<td><code class="highlighter-rouge">get logical-router <UUID> neighbors</code></td>
</tr>
</tbody>
</table>
<p><strong>Firewall</strong></p>
<table>
<thead>
<tr>
<th>Description</th>
<th>Commands</th>
</tr>
</thead>
<tbody>
<tr>
<td>View the Firewall Status</td>
<td><code class="highlighter-rouge">get firewall status</code></td>
</tr>
<tr>
<td>View the Firewall Rules applied at the VIF with Address Sets</td>
<td><code class="highlighter-rouge">get firewall <vif_uuid> addrsets</code></td>
</tr>
<tr>
<td> </td>
<td><code class="highlighter-rouge">get firewall <vif_uuid> profile</code></td>
</tr>
<tr>
<td>List all the VMs dvFilter Names</td>
<td><code class="highlighter-rouge">summarize-dvfilter</code></td>
</tr>
<tr>
<td>List all the VMs dvFilter Names associated with a VM and limit the response to 16 lines</td>
<td><code class="highlighter-rouge">Summarize-dvfilter | grep -A16 <SERVER_NAME></code></td>
</tr>
<tr>
<td>List the Firewall Rules applied on DvFilter</td>
<td><code class="highlighter-rouge">vsipioctl getrules -f <filtername></code></td>
</tr>
<tr>
<td>View the Firewall Configuration for a given dvFilter name</td>
<td><code class="highlighter-rouge">vsipioctl getfwconfig -f <dvfilter-name></code></td>
</tr>
<tr>
<td>View the DVSPort ID and MAC address associated with a VM</td>
<td><code class="highlighter-rouge">nsxdp-cli -c get ports | egrep -A1 "<VM_NAME|MAC"</code></td>
</tr>
<tr>
<td>View the number of packets dropped on a host switch</td>
<td><code class="highlighter-rouge">nsxdp-cli swsec get stats -dvs <Overlay_N-VDS> --dport <DVSPort-UUID></code></td>
</tr>
</tbody>
</table>
<h1 id="kvm">KVM</h1>
<p><strong>Setup Troubleshooting</strong></p>
<table>
<thead>
<tr>
<th>Description</th>
<th>Commands</th>
</tr>
</thead>
<tbody>
<tr>
<td>List the VIBs loaded on Ubuntu KVM</td>
<td><code class="highlighter-rouge">sudo dpkg --list | grep nsx</code></td>
</tr>
<tr>
<td>List the VIBs loaded on RedHat KVM</td>
<td><code class="highlighter-rouge">rpm -qa | grep nsx</code></td>
</tr>
<tr>
<td>Check the User world agents (UWA):</td>
<td> </td>
</tr>
<tr>
<td> </td>
<td><code class="highlighter-rouge">nsx-mpa /etc/init.d/nsx-mpa status | start | stop | restart</code></td>
</tr>
<tr>
<td> </td>
<td><code class="highlighter-rouge">nsx-proxy /etc/init.d/nsx-proxy status | start | stop | restart</code></td>
</tr>
<tr>
<td> </td>
<td><code class="highlighter-rouge">nsx-opsagent /etc/init.d/nsx-opsagent status | start | stop | restart</code></td>
</tr>
<tr>
<td> </td>
<td><code class="highlighter-rouge">nsxa /etc/init.d/nsxa status | start | stop | restart</code></td>
</tr>
<tr>
<td>Check UWAs Connection:</td>
<td> </td>
</tr>
<tr>
<td>Port 1235 to Controllers</td>
<td><code class="highlighter-rouge">lsof-i -P -n | grep 1235 [or netstat -an | grep 1235]</code></td>
</tr>
<tr>
<td>Port 5671 to NSX Manager</td>
<td><code class="highlighter-rouge">lsof-i -P -n | grep 5671 [or netstat -an | grep 5671]</code></td>
</tr>
<tr>
<td>NIC Details</td>
<td><code class="highlighter-rouge">ifconfig [-a]</code></td>
</tr>
<tr>
<td> </td>
<td><code class="highlighter-rouge">lspci</code></td>
</tr>
<tr>
<td><strong><em>Setup syslog:</em></strong></td>
<td> </td>
</tr>
<tr>
<td>Login as root and create this file</td>
<td><code class="highlighter-rouge">/etc/rsyslog.d/40-vmware-remote-logging.conf</code></td>
</tr>
<tr>
<td>Add this line to the file</td>
<td><code class="highlighter-rouge">'*.*@syslog_server_ip:514;RFC5424fmt'</code></td>
</tr>
<tr>
<td>Restart syslog</td>
<td><code class="highlighter-rouge">Systemctl restart rsyslog</code></td>
</tr>
</tbody>
</table>
<p><strong>Logical Switching</strong></p>
<table>
<thead>
<tr>
<th>Description</th>
<th>Commands</th>
</tr>
</thead>
<tbody>
<tr>
<td>Query the NSX Controllers</td>
<td><code class="highlighter-rouge">get controllers</code></td>
</tr>
<tr>
<td>View all the logical switches</td>
<td><code class="highlighter-rouge">get logical-switches</code></td>
</tr>
<tr>
<td>View the Logical Switch information from ESXi host</td>
<td><code class="highlighter-rouge">get logical-switch <logical-switch-id></code></td>
</tr>
<tr>
<td>View the ARP table of a logical switch</td>
<td><code class="highlighter-rouge">get logical-switch <logical-switch-id> arp-table</code></td>
</tr>
<tr>
<td>View the MAC table of a logical switch</td>
<td><code class="highlighter-rouge">get logical-switch <logical-switch-id> mac-table</code></td>
</tr>
<tr>
<td>View the VTEP table of a logical Switch</td>
<td><code class="highlighter-rouge">get logical-switch <logical-switch-id> vtep-table</code></td>
</tr>
<tr>
<td>View the ports on a logical Switch</td>
<td><code class="highlighter-rouge">get logical-switch <logical-switch-id> ports</code></td>
</tr>
<tr>
<td>View the MAC, ARP, VTEP tables from local or remote host using VNI</td>
<td><code class="highlighter-rouge">get logical-switch [local | remote] [mac-cache | arp-cache | vtep-cache] <vni></code></td>
</tr>
<tr>
<td>Verify the OpenvSwitch Kernel Module</td>
<td><code class="highlighter-rouge">lsmod | grep openvswitch (from root mode)</code></td>
</tr>
<tr>
<td>Open vSwitch Configuration File</td>
<td><code class="highlighter-rouge">/etc/openvswitch/conf.db</code></td>
</tr>
<tr>
<td>Print the current version of openvswitch</td>
<td><code class="highlighter-rouge">ovs-vsctl –V</code></td>
</tr>
<tr>
<td>Prints a brief overview of the switch database configuration</td>
<td><code class="highlighter-rouge">ovs-vsctl show</code></td>
</tr>
<tr>
<td>Prints a list of configured bridges</td>
<td><code class="highlighter-rouge">ovs-vsctl list-br</code></td>
</tr>
<tr>
<td>Prints a list of ports on a specific bridge</td>
<td><code class="highlighter-rouge">ovs-vsctl list-ports <bridge></code></td>
</tr>
<tr>
<td>OVSDB Log</td>
<td><code class="highlighter-rouge">ovsdb-tool show-log</code></td>
</tr>
</tbody>
</table>
<p><strong>Logical Routing</strong></p>
<table>
<thead>
<tr>
<th>Description</th>
<th>Commands</th>
</tr>
</thead>
<tbody>
<tr>
<td>View the Logical Router Forwarding table</td>
<td><code class="highlighter-rouge">get logical-router <UUID> forwarding</code></td>
</tr>
<tr>
<td>View the Logical Router Interface</td>
<td><code class="highlighter-rouge">get logical-router <UUID> interface</code></td>
</tr>
<tr>
<td>View the Logical Router Interfaces</td>
<td><code class="highlighter-rouge">get logical-router <UUID> interfaces</code></td>
</tr>
<tr>
<td>View the logical Router Neighbor</td>
<td><code class="highlighter-rouge">get logical-router <UUID> neighbor</code></td>
</tr>
<tr>
<td>View the logical Router Neighbors</td>
<td><code class="highlighter-rouge">get logical-router <UUID> neighbors</code></td>
</tr>
</tbody>
</table>
<p><strong>Firewall</strong></p>
<table>
<thead>
<tr>
<th>Description</th>
<th>Commands</th>
</tr>
</thead>
<tbody>
<tr>
<td>View app firewall virtual interfaces</td>
<td><code class="highlighter-rouge">ovs-appctl -t /var/run/openvswitch/nsxa-ctl dfw/vif</code></td>
</tr>
<tr>
<td>View firewall rules with containing addrsets</td>
<td><code class="highlighter-rouge">ovs-appctl -t /var/run/openvswitch/nsxa-ctl dfw/rules <VIF_ID_NUMBER></code></td>
</tr>
</tbody>
</table>
<h1 id="edges">Edges</h1>
<p><strong>Setup Troubleshooting</strong></p>
<table>
<thead>
<tr>
<th>Description</th>
<th>Commands</th>
</tr>
</thead>
<tbody>
<tr>
<td>Verify SSH service status</td>
<td><code class="highlighter-rouge">get service ssh</code></td>
</tr>
<tr>
<td>Start the SSH service</td>
<td><code class="highlighter-rouge">start service ssh</code></td>
</tr>
<tr>
<td>Set the SSH service to autostart when the VM is powered on</td>
<td><code class="highlighter-rouge">set service ssh start-on-boot</code></td>
</tr>
<tr>
<td>Verify that the SSH service is running and Start on boot is set to True</td>
<td><code class="highlighter-rouge">get service ssh</code></td>
</tr>
<tr>
<td>View the Edge configuration</td>
<td><code class="highlighter-rouge">get configuration</code></td>
</tr>
<tr>
<td>Display the Edge node UUID</td>
<td><code class="highlighter-rouge">get node-uuid</code></td>
</tr>
<tr>
<td>View the Edge interfaces</td>
<td><code class="highlighter-rouge">get interfaces</code></td>
</tr>
<tr>
<td>Query the connection to the NSX Managers</td>
<td><code class="highlighter-rouge">get managers</code></td>
</tr>
<tr>
<td>View all the host switches information</td>
<td><code class="highlighter-rouge">get host-switches</code></td>
</tr>
<tr>
<td>View the tunnel port information</td>
<td><code class="highlighter-rouge">get tunnel-ports</code></td>
</tr>
<tr>
<td>Setup packet capture</td>
<td><code class="highlighter-rouge">set capture session <session-number> interface <port-uuid> direction <direction></code></td>
</tr>
<tr>
<td>Remove captured session information</td>
<td><code class="highlighter-rouge">del capture session 1</code></td>
</tr>
<tr>
<td>Enter root privileged Mode</td>
<td><code class="highlighter-rouge">st en</code></td>
</tr>
</tbody>
</table>
<p><strong>Logical Routing</strong></p>
<table>
<thead>
<tr>
<th>Description</th>
<th>Commands</th>
</tr>
</thead>
<tbody>
<tr>
<td>View the VTEPs</td>
<td><code class="highlighter-rouge">get vteps</code></td>
</tr>
<tr>
<td>View the logical routers</td>
<td><code class="highlighter-rouge">get logical-routers</code></td>
</tr>
<tr>
<td>View the logical router information</td>
<td><code class="highlighter-rouge">get logical-router <uuid></code></td>
</tr>
<tr>
<td>View the logical router statistics</td>
<td><code class="highlighter-rouge">get logical-routers stats</code></td>
</tr>
<tr>
<td>View the logical router interfaces</td>
<td><code class="highlighter-rouge">get logical-router <uuid> interfaces</code></td>
</tr>
<tr>
<td>View the logical router neighbour</td>
<td><code class="highlighter-rouge">get logical-router <uuid> neighbor</code></td>
</tr>
<tr>
<td>View the logical router interfaces statistics</td>
<td><code class="highlighter-rouge">get logical-router interfaces stats</code></td>
</tr>
<tr>
<td>View the logical router bgp neighbour</td>
<td><code class="highlighter-rouge">get logical-router</code></td>
</tr>
<tr>
<td>To enter into the VRF construct</td>
<td><code class="highlighter-rouge">vrf <VRF-ID-of-Tier-0-SR></code></td>
</tr>
<tr>
<td>View the bgp neighbor of a Tier-0 SR</td>
<td><code class="highlighter-rouge">(tier0_sr)> get bgp neighbor</code></td>
</tr>
<tr>
<td>(tier0_sr)></td>
<td><code class="highlighter-rouge">get bgp neighbor summary</code></td>
</tr>
<tr>
<td>View the interfaces on a Tier-0 SR</td>
<td><code class="highlighter-rouge">(tier0_sr)> get interfaces</code></td>
</tr>
<tr>
<td>View the forwarding table (tier0_sr)></td>
<td><code class="highlighter-rouge">get forwarding</code></td>
</tr>
<tr>
<td>View the Routers</td>
<td><code class="highlighter-rouge">(tier0_sr)> get route</code></td>
</tr>
<tr>
<td>View the BFG configuration</td>
<td><code class="highlighter-rouge">(tier0_sr)> get bfd-config</code></td>
</tr>
<tr>
<td>View BGP IPv4 route info</td>
<td><code class="highlighter-rouge">(tier0_sr)> get bgp ipv4</code></td>
</tr>
<tr>
<td>View the Tier-1 or Tier-0 distributed router routing information</td>
<td><code class="highlighter-rouge">(tier[0 | 1]_dr)> get forwarding</code></td>
</tr>
</tbody>
</table>
<p><strong>Firewall</strong></p>
<table>
<thead>
<tr>
<th>Description</th>
<th>Commands</th>
</tr>
</thead>
<tbody>
<tr>
<td>View the list of Firewall Interfaces</td>
<td><code class="highlighter-rouge">get firewall interfaces</code></td>
</tr>
<tr>
<td>View the Firewall Ruleset and Rules</td>
<td><code class="highlighter-rouge">get firewall <interface_id> ruleset rule</code></td>
</tr>
</tbody>
</table>
<p><strong>Load Balancer</strong></p>
<table>
<thead>
<tr>
<th>Description</th>
<th>Commands</th>
</tr>
</thead>
<tbody>
<tr>
<td>Display load balancers configuration</td>
<td><code class="highlighter-rouge">get load-balancers</code></td>
</tr>
<tr>
<td>Display load balancer pool config</td>
<td><code class="highlighter-rouge">get load-balancer <lb-uuid> pools</code></td>
</tr>
<tr>
<td>Display load balancer virtual servers configuration</td>
<td><code class="highlighter-rouge">get load-balancer <lb-uuid> virtual-servers</code></td>
</tr>
<tr>
<td>Display specific load balancer virtual servers info</td>
<td><code class="highlighter-rouge">get load-balancer <lb-uuid> virtual-server Virtual_Server_ID</code></td>
</tr>
<tr>
<td>Display load balancer status</td>
<td><code class="highlighter-rouge">get load-balancer <lb-uuid> status</code></td>
</tr>
<tr>
<td>Display load balancer virtual servers stats</td>
<td><code class="highlighter-rouge">get load-balancer <lb-uuid> virtual-servers stats</code></td>
</tr>
<tr>
<td>Display load balancer stats</td>
<td><code class="highlighter-rouge">get load-balancer <lb-uuid> stats</code></td>
</tr>
</tbody>
</table>
<p><strong>DHCP</strong></p>
<table>
<thead>
<tr>
<th>Description</th>
<th>Commands</th>
</tr>
</thead>
<tbody>
<tr>
<td>Retrieve the DHCP server information</td>
<td><code class="highlighter-rouge">get dhcp servers</code></td>
</tr>
<tr>
<td>View the configured DHCP pools</td>
<td><code class="highlighter-rouge">get dhcp ip-pools</code></td>
</tr>
<tr>
<td>List the leased IP addresses</td>
<td><code class="highlighter-rouge">get dhcp leases</code></td>
</tr>
</tbody>
</table>
<p><strong>VPN</strong></p>
<table>
<thead>
<tr>
<th>Description</th>
<th>Commands</th>
</tr>
</thead>
<tbody>
<tr>
<td>Verify L2VPN session is active, identify the peers, and ensure that the tunnel status is up</td>
<td><code class="highlighter-rouge">get ipsecvpn session active</code></td>
</tr>
<tr>
<td>Verify that the sessions are up</td>
<td><code class="highlighter-rouge">get ipsecvpn session status</code></td>
</tr>
<tr>
<td>Check whether the ipsecvpn session is up between the local and remote peer</td>
<td><code class="highlighter-rouge">get ipsecvpn session summary</code></td>
</tr>
<tr>
<td>Get the l2vpn session, tunnel, and IPSEC session numbers, and check that the status is UI</td>
<td><code class="highlighter-rouge">get l2vpn sessions</code></td>
</tr>
<tr>
<td>Get statistical information of the local and remote peers, whether the status is UP, count of packets received, bytes received (RX), packets transmitted (TX), and packets dropped, malformed, or loops</td>
<td><code class="highlighter-rouge">get l2vpn session stats</code></td>
</tr>
<tr>
<td>Get the session configuration information</td>
<td><code class="highlighter-rouge">get l2vpn session config</code></td>
</tr>
</tbody>
</table>Simon GreavesHaving recently passed my NSX-T VCP, I thought I’d share the command line tools I used to practice in a lab to get to grips with NSX-T installation, configuration, managing and troubleshooting. I know I will be revisiting this site for reference in future. I hope you all enjoy it! I will cover a walkthrough of some of these commands in another post if it’s new to you and link it here.