<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Matt Dorn</title><link>http://www.madorn.com/</link><description></description><atom:link href="http://www.madorn.com/feeds/all.rss.xml" rel="self"></atom:link><lastBuildDate>Mon, 01 Oct 2018 12:00:00 -0500</lastBuildDate><item><title>oc cluster up vs. minishift vs. CKD vs. Ansible Playbooks</title><link>http://www.madorn.com/deploying-openshift.html</link><description>&lt;p&gt;As you may already know, OpenShift Origin, the Red Hat distribution of Kubernetes, was recently &lt;a class="reference external" href="https://blog.openshift.com/okd310release/"&gt;renamed OKD&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I couldn't find a document that explained the difference between the various methods for deploying an OKD dev environment so I thought this would be helpful.&lt;/p&gt;
&lt;div class="section" id="oc-cluster-up"&gt;
&lt;h2&gt;oc cluster up&lt;/h2&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;oc cluster up&lt;/tt&gt; is a command that is part of the &lt;tt class="docutils literal"&gt;oc&lt;/tt&gt; (OpenShift Client) binary. Linux is currently the only supported platform for running the command.
It will call Docker on the host where the command is run and bootstrap a local OKD cluster. The version of OKD that gets created is relative to your version of &lt;tt class="docutils literal"&gt;oc&lt;/tt&gt;.
It was first introduced in OpenShift Origin 1.3 and was created to give engineers a quick way to test their work. It is best suited for creating quick, disposable environments that you don't plan on persisting (i.e. testing, adding to your CI/CD workflow, etc.).
If you are eager to try out the latest OKD release, you'll usually be able to get your hands on it via &lt;tt class="docutils literal"&gt;oc cluster up&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;You can download the &lt;tt class="docutils literal"&gt;oc&lt;/tt&gt; binary from &lt;a class="reference external" href="https://github.com/openshift/origin/releases"&gt;here&lt;/a&gt; and place it in your path.&lt;/p&gt;
&lt;p&gt;You can check out all the available &lt;tt class="docutils literal"&gt;oc cluster&lt;/tt&gt; commands by running &lt;tt class="docutils literal"&gt;oc cluster &lt;span class="pre"&gt;--help&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;More info can be found &lt;a class="reference external" href="https://github.com/openshift/origin/blob/master/docs/cluster_up_down.md"&gt;here&lt;/a&gt; as well.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="minishift"&gt;
&lt;h2&gt;minishift&lt;/h2&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;minishift&lt;/tt&gt; is supported on a variety of platforms including MacOS, Windows, and Linux.
It uses &lt;tt class="docutils literal"&gt;libmachine&lt;/tt&gt; for provisoning a single-node OKD cluster and is compatible with a variety of hypervisors like VirtualBox, VMware Fusion, xhyve, hyperkit, etc). Behind the scenes, it is actually using &lt;tt class="docutils literal"&gt;oc cluster up&lt;/tt&gt;.
It has some very cool profiling features for creating and persisting a variety of dev environments. It's great if you are looking for a local, reusable, dev environment that's isolated in a virtual machine.&lt;/p&gt;
&lt;p&gt;More info on installing Minishift can be found &lt;a class="reference external" href="https://docs.okd.io/latest/minishift/getting-started/preparing-to-install.html"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="cdk-container-development-kit"&gt;
&lt;h2&gt;CDK (Container Development Kit)&lt;/h2&gt;
&lt;p&gt;CDK could best be described as an Enterprise version of &lt;tt class="docutils literal"&gt;minishift&lt;/tt&gt;. It is a downstream productized version of &lt;tt class="docutils literal"&gt;minishift&lt;/tt&gt; that allows a user with a &lt;a class="reference external" href="https://developers.redhat.com/"&gt;Red Hat developer subscription&lt;/a&gt; to deploy OpenShift on Red Hat Enterprise Linux (RHEL).&lt;/p&gt;
&lt;p&gt;More info can be found &lt;a class="reference external" href="https://access.redhat.com/documentation/en-us/red_hat_container_development_kit/"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="installing-manually-via-ansible-playbooks"&gt;
&lt;h2&gt;Installing manually via Ansible Playbooks&lt;/h2&gt;
&lt;p&gt;If you want to deploy an environment the &amp;quot;official way&amp;quot;, you can always provision a single virtual machine and manually run the &lt;a class="reference external" href="https://github.com/openshift/openshift-ansible"&gt;ansible-openshift playbooks&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Check out this &lt;a class="reference external" href="https://blog.openshift.com/installing-okd-3-10-on-a-single-host"&gt;video from Grant Shipley&lt;/a&gt; that shows you how to do it with a &lt;a class="reference external" href="https://github.com/gshipley/installcentos"&gt;handy script&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Dorn</dc:creator><pubDate>Mon, 01 Oct 2018 12:00:00 -0500</pubDate><guid>tag:www.madorn.com,2018-10-01:deploying-openshift.html</guid><category>kubernetes</category><category>openshift</category><category>okd</category></item><item><title>Certified Kubernetes Application Developer Exam</title><link>http://www.madorn.com/certified-kubernetes-application-developer-exam.html</link><description>&lt;p&gt;In case you didn't notice, the &lt;a class="reference external" href="http://cncf.io/"&gt;Cloud Native Computing Foundation&lt;/a&gt; recently dropped another Kubernetes exam called the &lt;a class="reference external" href="https://www.cncf.io/certification/expert/cka/ckad/"&gt;Certified Kubernetes Application Developer (CKAD)&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I took the exam a few weeks ago and thought it was pretty good. Unlike the &lt;a class="reference external" href="https://www.cncf.io/certification/expert/cka/"&gt;Certified Kubernetes Administrator Exam (CKA)&lt;/a&gt;, the CKAD only focuses on the Developer persona.
This makes the CKAD much easier than the CKA but keep in mind you only have two hours to complete all tasks.&lt;/p&gt;
&lt;div class="note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;The CNCF has updated their open-book policy for both CKA and CKAD. You are only permitted to open one additional web browser tab to access official documentation at &lt;a class="reference external" href="http://kubernetes.io"&gt;kubernetes.io&lt;/a&gt; during the exam.
No other websites are permitted.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="objectives"&gt;
&lt;h2&gt;Objectives&lt;/h2&gt;
&lt;p&gt;The objectives for the CKAD can be found throughout the &lt;a class="reference external" href="https://github.com/cncf/curriculum/blob/master/certified_kubernetes_application_developer_exam_v1.0.pdf"&gt;Official Certified Kubernetes Application Developer Exam Curriculum&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Together, all of these domains make up 100% of the exam.&lt;/p&gt;
&lt;div class="section" id="core-concepts-13"&gt;
&lt;h3&gt;Core Concepts - 13%&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Understand Kubernetes API primitives&lt;/li&gt;
&lt;li&gt;Create and configure basic Pods&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="multi-container-pods-10"&gt;
&lt;h3&gt;Multi-Container Pods - 10%&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Understand Multi-Container Pod design patterns (e.g. ambassador, adapter, sidecare)&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="pod-design-20"&gt;
&lt;h3&gt;Pod Design - 20%&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Understand how to use Labels, Selectors, and Annotations&lt;/li&gt;
&lt;li&gt;Understand Deployments and how to perform rolling updates&lt;/li&gt;
&lt;li&gt;Understand Deployments and how to perform rollbacks&lt;/li&gt;
&lt;li&gt;Understand Jobs and CronJobs&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="state-persistence-8"&gt;
&lt;h3&gt;State Persistence - 8%&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Understand PersistentVolumeClaims for storage&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="configuration-18"&gt;
&lt;h3&gt;Configuration - 18%&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Understand ConfigMaps&lt;/li&gt;
&lt;li&gt;Understand SecurityContexts&lt;/li&gt;
&lt;li&gt;Define an application’s resource requirements&lt;/li&gt;
&lt;li&gt;Create and consume Secrets&lt;/li&gt;
&lt;li&gt;Understand ServiceAccounts&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="observability-18"&gt;
&lt;h3&gt;Observability - 18%&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Understand LivenessProbes and ReadinessProbes&lt;/li&gt;
&lt;li&gt;Understand container logging&lt;/li&gt;
&lt;li&gt;Understand how to monitor applications in Kubernetes&lt;/li&gt;
&lt;li&gt;Understand debugging in Kubernetes&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="services-networking-13"&gt;
&lt;h3&gt;Services &amp;amp; Networking - 13%&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Understand Services&lt;/li&gt;
&lt;li&gt;Demonstrate basic understanding of NetworkPolicies&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="about-the-exam-environment"&gt;
&lt;h3&gt;About the Exam Environment&lt;/h3&gt;
&lt;p&gt;The exam environment is the exact same as the CKA and described in my &lt;a class="reference external" href="http://madorn.com/certified-kubernetes-administrator-exam.html"&gt;last post&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="good-luck"&gt;
&lt;h3&gt;Good Luck!&lt;/h3&gt;
&lt;p&gt;Have fun preparing and taking the Certified Kubernetes Developer Exam! Check out the &lt;a class="reference external" href="https://www.cncf.io/certification/expert/cka/faq/"&gt;CNCF's FAQ&lt;/a&gt; for additional info.&lt;/p&gt;
&lt;img alt="" src="https://s3.amazonaws.com/madorn.com/images/ckad.png" /&gt;
&lt;/div&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Dorn</dc:creator><pubDate>Tue, 15 May 2018 12:00:00 -0500</pubDate><guid>tag:www.madorn.com,2018-05-15:certified-kubernetes-application-developer-exam.html</guid><category>kubernetes</category><category>certification</category></item><item><title>Certified Kubernetes Administrator Exam</title><link>http://www.madorn.com/certified-kubernetes-administrator-exam.html</link><description>&lt;p&gt;The &lt;a class="reference external" href="http://cncf.io/"&gt;Cloud Native Computing Foundation&lt;/a&gt; has officially released the brand new &lt;a class="reference external" href="https://www.cncf.io/certification/expert/"&gt;Certified Kubernetes Exam (CKA)&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I took the exam last week and loved it! It was extremely challenging and covered many different aspects of Kubernetes.&lt;/p&gt;
&lt;div class="section" id="exam-personas"&gt;
&lt;h2&gt;Exam Personas&lt;/h2&gt;
&lt;p&gt;The exam can best be described as a series of objectives that cover two target personas: &lt;em&gt;Developers&lt;/em&gt; and &lt;em&gt;Operators&lt;/em&gt;.&lt;/p&gt;
&lt;div class="section" id="developers"&gt;
&lt;h3&gt;Developers&lt;/h3&gt;
&lt;p&gt;The developer section requires you to understand how to directly interact with the Kubernetes API via &lt;tt class="docutils literal"&gt;kubectl&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;These objectives require you to act as the developer deploying cloud-native applications on Kubernetes by creating Pods, Jobs, Deployments, Services and ConfigMaps. You should understand how to run ad-hoc &lt;tt class="docutils literal"&gt;kubectl&lt;/tt&gt; commands as well as create object manifest files in JSON or YAML format.&lt;/p&gt;
&lt;p&gt;This makes up about 60% of the exam.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="operators"&gt;
&lt;h3&gt;Operators&lt;/h3&gt;
&lt;p&gt;The operators portion of the exam requires you to put on your System Engineer hat and understand how to install, manage, and troubleshoot live Kubernetes clusters!
You must be familiar with all aspects of the Kubernetes installation process, including flags and settings for the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;kube-apiserver&lt;/span&gt;&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;kube-scheduler&lt;/span&gt;&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;kube-controller-manager&lt;/span&gt;&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;kubelet&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;kube-proxy&lt;/span&gt;&lt;/tt&gt;, and &lt;tt class="docutils literal"&gt;etcd&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;This makes up about 40% of the exam.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="objectives"&gt;
&lt;h2&gt;Objectives&lt;/h2&gt;
&lt;p&gt;The objectives for the Developer/Operator personas can be found throughout the &lt;a class="reference external" href="https://github.com/cncf/curriculum/blob/master/certified_kubernetes_administrator_exam_V0.9.pdf"&gt;Official Certified Kubernetes Administrator Exam Curriculum&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Together, all of these domains make up 100% of the exam.&lt;/p&gt;
&lt;div class="section" id="core-concepts-19"&gt;
&lt;h3&gt;Core Concepts - 19%&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Understand the Kubernetes API primitives.&lt;/li&gt;
&lt;li&gt;Understand the Kubernetes cluster architecture.&lt;/li&gt;
&lt;li&gt;Understand Services and other network primitives.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="security-12"&gt;
&lt;h3&gt;Security - 12%&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Know how to configure authentication and authorization.&lt;/li&gt;
&lt;li&gt;Understand Kubernetes security primitives.&lt;/li&gt;
&lt;li&gt;Know how to configure network policies.&lt;/li&gt;
&lt;li&gt;Create and manage TLS certificates for cluster components.&lt;/li&gt;
&lt;li&gt;Work with images securely.&lt;/li&gt;
&lt;li&gt;Define security contexts.&lt;/li&gt;
&lt;li&gt;Secure persistent key value store.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="installation-configuration-validation-12"&gt;
&lt;h3&gt;Installation, Configuration, Validation - 12%&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Design a Kubernetes cluster.&lt;/li&gt;
&lt;li&gt;Install Kubernetes masters and nodes.&lt;/li&gt;
&lt;li&gt;Configure secure cluster communications.&lt;/li&gt;
&lt;li&gt;Configure a HA Kubernetes cluster.&lt;/li&gt;
&lt;li&gt;Know where to get the Kubernetes release binaries.&lt;/li&gt;
&lt;li&gt;Provision underlying infrastructure to deploy a Kubernetes cluster.&lt;/li&gt;
&lt;li&gt;Choose a network solution.&lt;/li&gt;
&lt;li&gt;Choose your Kubernetes infrastructure configuration.&lt;/li&gt;
&lt;li&gt;Run end-to-end tests on your cluster.&lt;/li&gt;
&lt;li&gt;Analyze end-to-end test results.&lt;/li&gt;
&lt;li&gt;Run Node end-to-end tests.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="networking-11"&gt;
&lt;h3&gt;Networking - 11%&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Understand the networking configuration on the cluster nodes.&lt;/li&gt;
&lt;li&gt;Understand Pod networking concepts.&lt;/li&gt;
&lt;li&gt;Understand service networking.&lt;/li&gt;
&lt;li&gt;Deploy and configure network load balancer.&lt;/li&gt;
&lt;li&gt;Know how to use Ingress rules.&lt;/li&gt;
&lt;li&gt;Configure secure cluster communications.&lt;/li&gt;
&lt;li&gt;Configure a HA Kubernetes cluster.&lt;/li&gt;
&lt;li&gt;Know where to get the Kubernetes release binaries.&lt;/li&gt;
&lt;li&gt;Provision underlying infrastructure to deploy a Kubernetes cluster.&lt;/li&gt;
&lt;li&gt;Choose a network solution.&lt;/li&gt;
&lt;li&gt;Choose your Kubernetes infrastructure configuration.&lt;/li&gt;
&lt;li&gt;Run end-to-end tests on your cluster.&lt;/li&gt;
&lt;li&gt;Analyze end-to-end test results.&lt;/li&gt;
&lt;li&gt;Run Node end-to-end tests.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="cluster-maintenance-11"&gt;
&lt;h3&gt;Cluster Maintenance - 11%&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Understand Kubernetes cluster upgrade process.&lt;/li&gt;
&lt;li&gt;Facilitate operating system upgrades.&lt;/li&gt;
&lt;li&gt;Implement backup and restore methodologies.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="troubleshooting-10"&gt;
&lt;h3&gt;Troubleshooting - 10%&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Troubleshoot application failure.&lt;/li&gt;
&lt;li&gt;Troubleshoot control panel plane failure.&lt;/li&gt;
&lt;li&gt;Troubleshoot worker node failure.&lt;/li&gt;
&lt;li&gt;Troubleshoot networking.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="application-lifecycle-management-8"&gt;
&lt;h3&gt;Application Lifecycle Management - 8%&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Understand Deployments and how to perform rolling updates and rollbacks.&lt;/li&gt;
&lt;li&gt;Know various ways to configure applications.&lt;/li&gt;
&lt;li&gt;Know how to scale applications.&lt;/li&gt;
&lt;li&gt;Understand the primitives necessary to create a self-healing application.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="storage-7"&gt;
&lt;h3&gt;Storage - 7%&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Understand Persistent Volumes and know how to create them.&lt;/li&gt;
&lt;li&gt;Understand access modes for volumes.&lt;/li&gt;
&lt;li&gt;Understand Persistent Volume Claims.&lt;/li&gt;
&lt;li&gt;Understand Kubernetes storage objects.&lt;/li&gt;
&lt;li&gt;Know how to configure applications with Persistent Storage.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="scheduling-5"&gt;
&lt;h3&gt;Scheduling - 5%&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Use label selectors to schedule Pods.&lt;/li&gt;
&lt;li&gt;Understand the role of DaemonSets.&lt;/li&gt;
&lt;li&gt;Understand how Resource Limits can affect Pod scheduling.&lt;/li&gt;
&lt;li&gt;Understand how to run multiple schedulers and how to configure Pods to use them.&lt;/li&gt;
&lt;li&gt;Manually schedule a pod without a scheduler.&lt;/li&gt;
&lt;li&gt;Display scheduler events.&lt;/li&gt;
&lt;li&gt;Know how to configure the Kubernetes scheduler.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="logging-monitoring-5"&gt;
&lt;h3&gt;Logging/Monitoring - 5%&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Understand how to monitor all cluster components.&lt;/li&gt;
&lt;li&gt;Understand how to monitor applications.&lt;/li&gt;
&lt;li&gt;Manage cluster component logs.&lt;/li&gt;
&lt;li&gt;Manage application logs.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="about-the-exam-environment"&gt;
&lt;h3&gt;About the Exam Environment&lt;/h3&gt;
&lt;p&gt;The exam expects its test-takers to be proficient in completing all objectives in a terminal environment.&lt;/p&gt;
&lt;p&gt;Here is a visual representation of the exam console as described in the &lt;a class="reference external" href="https://www.cncf.io/certification/agreement"&gt;Certification and Confidentiality Agreement&lt;/a&gt;:&lt;/p&gt;
&lt;img alt="" src="https://s3.amazonaws.com/madorn.com/images/cka-exam.jpeg" /&gt;
&lt;p&gt;The exam console is embedded into the browser. It is composed of two primary parts: The &lt;strong&gt;Content Panel&lt;/strong&gt; and the &lt;strong&gt;Terminal Panel&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;Content Panel&lt;/strong&gt; is the section that displays the exam timer and objectives. You can use the next and back button to move to each objective.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;Terminal Panel&lt;/strong&gt; gives you full access to an Ubuntu 16.04 environment with previously installed programs including &lt;tt class="docutils literal"&gt;kubectl&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;SSH&lt;/tt&gt; to access a Kubernetes cluster environment.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="it-s-open-book"&gt;
&lt;h3&gt;It's Open Book!&lt;/h3&gt;
&lt;p&gt;Although you &lt;strong&gt;can't&lt;/strong&gt; use your personal notes for the exam, you &lt;strong&gt;can&lt;/strong&gt; use the net to browse official Kubernetes documentation.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="good-luck"&gt;
&lt;h3&gt;Good Luck!&lt;/h3&gt;
&lt;p&gt;Have fun preparing and taking the Certified Kubernetes Administrator!&lt;/p&gt;
&lt;img alt="" src="https://s3.amazonaws.com/madorn.com/images/cka.jpg" /&gt;
&lt;/div&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Dorn</dc:creator><pubDate>Sun, 10 Sep 2017 12:00:00 -0500</pubDate><guid>tag:www.madorn.com,2017-09-10:certified-kubernetes-administrator-exam.html</guid><category>kubernetes</category><category>certification</category></item><item><title>Kubernetes Non-Masquerade CIDR</title><link>http://www.madorn.com/kubernetes-non-masquerade-cidr.html</link><description>&lt;p&gt;I've noticed a few people running into DNS issues when attempting to install Kubernetes from scratch on VirtualBox with Vagrant.&lt;/p&gt;
&lt;p&gt;As you may already know, VirtualBox's default NAT network assigns an IP address from a &lt;tt class="docutils literal"&gt;10.0.2.0/24&lt;/tt&gt; CIDR to any virtual machine with a network adapter set to NAT.  This will result in your virtual machine receiving a DHCP option that sets &lt;tt class="docutils literal"&gt;/etc/resolv.conf&lt;/tt&gt; to a nameserver that is typically at something like &lt;tt class="docutils literal"&gt;10.0.2.3&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;From Ubuntu 16.04:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="gp"&gt;ubuntu@worker1:~$&lt;/span&gt; cat /etc/resolv.conf
&lt;span class="go"&gt; # Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)&lt;/span&gt;
&lt;span class="gp"&gt;#&lt;/span&gt;     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
&lt;span class="go"&gt;nameserver 10.0.2.3&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For node-to-node communication, we can use a VirtualBox host-only network (For example, &lt;tt class="docutils literal"&gt;192.168.56.0/24&lt;/tt&gt;) and statically assign an ip address to eth1 on our virtual machines.&lt;/p&gt;
&lt;p&gt;This will result in the interfaces on our virtual machines looking something like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="gp"&gt;ubuntu@worker1:~$&lt;/span&gt; ip a
&lt;span class="go"&gt;1: lo: &amp;lt;LOOPBACK,UP,LOWER_UP&amp;gt; mtu 65536 qdisc noqueue state UNKNOWN qlen 1&lt;/span&gt;
&lt;span class="go"&gt;  link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00&lt;/span&gt;
&lt;span class="go"&gt;  inet 127.0.0.1/8 scope host lo&lt;/span&gt;
&lt;span class="go"&gt;     valid_lft forever preferred_lft forever&lt;/span&gt;
&lt;span class="go"&gt;  inet6 ::1/128 scope host&lt;/span&gt;
&lt;span class="go"&gt;     valid_lft forever preferred_lft forever&lt;/span&gt;
&lt;span class="go"&gt;2: enp0s3: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc pfifo_fast state UP qlen 1000&lt;/span&gt;
&lt;span class="go"&gt;  link/ether 08:00:27:82:73:25 brd ff:ff:ff:ff:ff:ff&lt;/span&gt;
&lt;span class="go"&gt;  inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic enp0s3&lt;/span&gt;
&lt;span class="go"&gt;     valid_lft 86041sec preferred_lft 86041sec&lt;/span&gt;
&lt;span class="go"&gt;  inet6 fe80::a00:27ff:fe82:7325/64 scope link&lt;/span&gt;
&lt;span class="go"&gt;     valid_lft forever preferred_lft forever&lt;/span&gt;
&lt;span class="go"&gt;3: enp0s8: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000&lt;/span&gt;
&lt;span class="go"&gt;  link/ether 08:00:27:fa:05:a3 brd ff:ff:ff:ff:ff:ff&lt;/span&gt;
&lt;span class="go"&gt;  inet 192.168.56.56/24 brd 192.168.56.255 scope global enp0s8&lt;/span&gt;
&lt;span class="go"&gt;     valid_lft forever preferred_lft forever&lt;/span&gt;
&lt;span class="go"&gt;  inet6 fe80::a00:27ff:fefa:5a3/64 scope link&lt;/span&gt;
&lt;span class="go"&gt;     valid_lft forever preferred_lft forever&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To keep things simple in a typical Kubernetes environment, you may want to have each worker node's pod network on a unique &lt;tt class="docutils literal"&gt;/24&lt;/tt&gt;.  This would result in each worker node's network bridge getting assigned something like &lt;tt class="docutils literal"&gt;10.200.0.1/24&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;10.200.1.1/24&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;10.200.2.1/24&lt;/tt&gt;, and so on.  If using &lt;tt class="docutils literal"&gt;kubenet&lt;/tt&gt;, the out-of-the-box Kubernetes networking plugin, this can be achieved by setting the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;--cluster-cidr&lt;/span&gt;&lt;/tt&gt; flag on the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;kube-controller-manager&lt;/span&gt;&lt;/tt&gt; daemon to &lt;tt class="docutils literal"&gt;10.200.0.0/16&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Here's an example of one commonly used &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;kube-controller-manager&lt;/span&gt;&lt;/tt&gt; systemd unit config from Kelsey Hightower's &lt;a class="reference external" href="https://github.com/kelseyhightower/kubernetes-the-hard-way"&gt;Learn Kubernetes the Hard Way&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;cat &amp;gt; kube-controller-manager.service &amp;lt;&amp;lt;EOF&lt;/span&gt;
&lt;span class="go"&gt;[Unit]&lt;/span&gt;
&lt;span class="go"&gt;Description=Kubernetes Controller Manager&lt;/span&gt;
&lt;span class="go"&gt;Documentation=https://github.com/GoogleCloudPlatform/kubernetes&lt;/span&gt;

&lt;span class="go"&gt;[Service]&lt;/span&gt;
&lt;span class="go"&gt;ExecStart=/usr/bin/kube-controller-manager \\&lt;/span&gt;
&lt;span class="go"&gt;  --address=0.0.0.0 \\&lt;/span&gt;
&lt;span class="go"&gt;  --allocate-node-cidrs=true \\&lt;/span&gt;
&lt;span class="go"&gt;  --cluster-cidr=10.200.0.0/16 \\&lt;/span&gt;
&lt;span class="go"&gt;  --cluster-name=kubernetes \\&lt;/span&gt;
&lt;span class="go"&gt;  --cluster-signing-cert-file=&amp;quot;/var/lib/kubernetes/ca.pem&amp;quot; \\&lt;/span&gt;
&lt;span class="go"&gt;  --cluster-signing-key-file=&amp;quot;/var/lib/kubernetes/ca-key.pem&amp;quot; \\&lt;/span&gt;
&lt;span class="go"&gt;  --leader-elect=true \\&lt;/span&gt;
&lt;span class="go"&gt;  --master=http://${INTERNAL_IP}:8080 \\&lt;/span&gt;
&lt;span class="go"&gt;  --root-ca-file=/var/lib/kubernetes/ca.pem \\&lt;/span&gt;
&lt;span class="go"&gt;  --service-account-private-key-file=/var/lib/kubernetes/ca-key.pem \\&lt;/span&gt;
&lt;span class="go"&gt;  --service-cluster-ip-range=10.32.0.0/16 \\&lt;/span&gt;
&lt;span class="go"&gt;  --v=2&lt;/span&gt;
&lt;span class="go"&gt;Restart=on-failure&lt;/span&gt;
&lt;span class="go"&gt;RestartSec=5&lt;/span&gt;

&lt;span class="go"&gt;[Install]&lt;/span&gt;
&lt;span class="go"&gt;WantedBy=multi-user.target&lt;/span&gt;
&lt;span class="go"&gt;EOF&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;After creating your DNS deployment in the kube-system namespace, resolution of service names &lt;strong&gt;inside&lt;/strong&gt; the cluster may work fine:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="gp"&gt;ubuntu@worker1:~$&lt;/span&gt; kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; -it mypod /bin/sh
&lt;span class="go"&gt;/ # nslookup kubernetes&lt;/span&gt;
&lt;span class="go"&gt;Server:    10.32.0.10&lt;/span&gt;
&lt;span class="go"&gt;Address 1: 10.32.0.10 kube-dns.kube-system.svc.cluster.local&lt;/span&gt;

&lt;span class="go"&gt;Name:      kubernetes&lt;/span&gt;
&lt;span class="go"&gt;Address 1: 10.32.0.1 kubernetes.default.svc.cluster.local&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But resolution to something outside your cluster doesn't work:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;/ # nslookup kubernetes.io&lt;/span&gt;
&lt;span class="go"&gt;Server:    10.32.0.10&lt;/span&gt;
&lt;span class="go"&gt;Address 1: 10.32.0.10 kube-dns.kube-system.svc.cluster.local&lt;/span&gt;

&lt;span class="go"&gt;nslookup: can&amp;#39;t resolve &amp;#39;kubernetes.io&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If we check out the &lt;a class="reference external" href="https://raw.githubusercontent.com/kubernetes/kubernetes/release-1.6.3/cluster/addons/dns/kubedns-controller.yaml.base"&gt;upstream kube-dns deployment object manifest&lt;/a&gt; the dnsmasq container does &lt;strong&gt;not&lt;/strong&gt; have the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;--resolv-file&lt;/span&gt;&lt;/tt&gt; flag set.  This flag would allow us to specify our own customized &lt;tt class="docutils literal"&gt;resolv.conf&lt;/tt&gt;.  By default, the dnsmasq container will use the &lt;tt class="docutils literal"&gt;/etc/resolv.conf&lt;/tt&gt; of the node the pod resides on for resolving all non-cluster queries.  In our case with VirtualBox NAT network, it will use the &lt;tt class="docutils literal"&gt;10.0.2.3&lt;/tt&gt; nameserver.&lt;/p&gt;
&lt;p&gt;Rather than play around with setting a new DNS server like &lt;tt class="docutils literal"&gt;8.8.8.8&lt;/tt&gt;, let's do some tcpdumping on the worker node's NAT network interface to see if we can see the packets attempting to hit the VirtualBox DNS:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="gp"&gt;ubuntu@worker1:~$&lt;/span&gt; sudo tcpdump -n &lt;span class="s2"&gt;&amp;quot;dst host 10.0.2.3&amp;quot;&lt;/span&gt;
&lt;span class="go"&gt;tcpdump: verbose output suppressed, use -v or -vv for full protocol decode&lt;/span&gt;
&lt;span class="go"&gt;listening on cbr0, link-type EN10MB (Ethernet), capture size 262144 bytes&lt;/span&gt;
&lt;span class="go"&gt;02:29:54.364528 IP 10.200.0.3.15612 &amp;gt; 10.0.2.3.53: 28501+ AAAA? kubernetes.io. (31)&lt;/span&gt;
&lt;span class="go"&gt;02:29:54.364629 IP 10.200.0.3.15612 &amp;gt; 10.0.2.3.53: 28501+ AAAA? kubernetes.io. (31)&lt;/span&gt;
&lt;span class="go"&gt;02:29:59.370219 IP 10.200.0.3.22452 &amp;gt; 10.0.2.3.53: 53929+ AAAA? kubernetes.io. (31)&lt;/span&gt;
&lt;span class="go"&gt;02:29:59.370413 IP 10.200.0.3.22452 &amp;gt; 10.0.2.3.53: 53929+ AAAA? kubernetes.io. (31)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It looks like the source IP address is still the original pod IP.&lt;/p&gt;
&lt;p&gt;Checking iptables NAT table, we can see the following in the &lt;tt class="docutils literal"&gt;POSTROUTING&lt;/tt&gt; chain:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="gp"&gt;ubuntu@worker1:~$&lt;/span&gt; sudo iptables -t nat -vxnL POSTROUTING

&lt;span class="go"&gt;Chain POSTROUTING (policy ACCEPT 8 packets, 480 bytes)&lt;/span&gt;
&lt;span class="go"&gt;    pkts      bytes target     prot opt in     out     source               destination&lt;/span&gt;
&lt;span class="go"&gt;      861    57670 KUBE-POSTROUTING  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* kubernetes postrouting rules */&lt;/span&gt;
&lt;span class="go"&gt;      49     2940 MASQUERADE  all  --  *      *       0.0.0.0/0           !10.0.0.0/8           /* kubenet: SNAT for outbound traffic from cluster */ ADDRTYPE match dst-type !LOCAL&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It looks like all traffic destined for something within &lt;tt class="docutils literal"&gt;10.0.0.0/8&lt;/tt&gt; will &lt;strong&gt;not&lt;/strong&gt; be source natted!&lt;/p&gt;
&lt;p&gt;Where did it get this &lt;tt class="docutils literal"&gt;10.0.0.0/8&lt;/tt&gt; network?  As you can see &lt;a class="reference external" href="https://github.com/kubernetes/kubernetes/blob/v1.6.3/pkg/kubelet/network/kubenet/kubenet_linux.go#L122"&gt;here&lt;/a&gt;, &lt;tt class="docutils literal"&gt;kubelet&lt;/tt&gt; automatically sets this cidr value when the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;--non-masquerade-cidr&lt;/span&gt;&lt;/tt&gt; flag for &lt;tt class="docutils literal"&gt;kubelet&lt;/tt&gt; is not specified.  The intention is to ensure proper pod-to-pod communication within the cluster by preserving the pod's source IP.  In my dev environment, I have manually generated host-routes, but you may be using &lt;a class="reference external" href="https://github.com/coreos/flannel"&gt;flannel&lt;/a&gt; or another pod networking solution.  Anyway, it looks like this will be a problem since our VirtualBox DNS falls into the &lt;tt class="docutils literal"&gt;10.0.0.0/8&lt;/tt&gt; &lt;a class="reference external" href="https://tools.ietf.org/html/rfc1918"&gt;RFC 1918&lt;/a&gt;  range.&lt;/p&gt;
&lt;p&gt;We could certainly work around this by changing our cluster-cidr to something like &lt;tt class="docutils literal"&gt;192.168.0.0/16&lt;/tt&gt;.  We could also manually modify iptables rules on all of our worker nodes.  Let's try something easier.&lt;/p&gt;
&lt;div class="section" id="the-ip-masq-agent"&gt;
&lt;h2&gt;The ip-masq-agent&lt;/h2&gt;
&lt;p&gt;Enter the &lt;a class="reference external" href="https://github.com/kubernetes-incubator/ip-masq-agent"&gt;ip-masq-agent&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;In Kubernetes 1.7 there is some &lt;a class="reference external" href="https://github.com/kubernetes/kubernetes/blob/release-1.7/pkg/kubelet/network/kubenet/kubenet_linux.go#L181-L192"&gt;new code&lt;/a&gt; that allows you to completely void out the creation of the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;--non-masquerade-cidr&lt;/span&gt;&lt;/tt&gt; by setting its value to &lt;tt class="docutils literal"&gt;0.0.0.0/0&lt;/tt&gt;, i.e. &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;--non-masquerade-cidr=0.0.0.0/0&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;I will create ConfigMap that says I do not want to SNAT any traffic destined for the cluster, in my case the user-provided cluster-cidr and service-cluster-ip ranges:  &lt;tt class="docutils literal"&gt;10.200.0.0/16&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;10.32.0.0/16&lt;/tt&gt;.  This is pretty cool because the kubelet's &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;--non-masquerade-cidr&lt;/span&gt;&lt;/tt&gt; is limited to one CIDR.  The template for the ConfigMap is available &lt;a class="reference external" href="https://raw.githubusercontent.com/kubernetes-incubator/ip-masq-agent/v2.0.1/agent-config/config"&gt;here&lt;/a&gt;.  Here is my ConfigMap:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;nonMasqueradeCIDRs:&lt;/span&gt;
&lt;span class="go"&gt;  - 10.200.0.0/16&lt;/span&gt;
&lt;span class="go"&gt;  - 10.32.0.0/16&lt;/span&gt;
&lt;span class="go"&gt;masqLinkLocal: false&lt;/span&gt;
&lt;span class="go"&gt;resyncInterval: 60s&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;strong&gt;masqLinkLocal&lt;/strong&gt; determinws whether to masquerade traffic to&amp;nbsp;169.254.0.0/16. False by default.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;resyncInterval&lt;/strong&gt; sets the interval at which the agent attempts to reload config from disk.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Deploy the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ip-masq-agent&lt;/span&gt;&lt;/tt&gt; DaemonSet&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;kubectl create -f https://raw.githubusercontent.com/kubernetes-incubator/ip-masq-agent/v2.0.1/ip-masq-agent.yaml&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We should see a brand new &lt;tt class="docutils literal"&gt;POSTROUTING&lt;/tt&gt; rule that points to a new chain called &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;IP-MASQ-AGENT&lt;/span&gt;&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="gp"&gt;ubuntu@worker1:~$&lt;/span&gt; sudo iptables -t nat -vxnL POSTROUTING
&lt;span class="go"&gt;Chain POSTROUTING (policy ACCEPT 4 packets, 240 bytes)&lt;/span&gt;
&lt;span class="go"&gt;  pkts      bytes target     prot opt in     out     source               destination&lt;/span&gt;
&lt;span class="go"&gt; 11235   674191 KUBE-POSTROUTING  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* kubernetes postrouting rules */&lt;/span&gt;
&lt;span class="go"&gt; 10067   604182 IP-MASQ-AGENT  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* ip-masq-agent: ensure nat POSTROUTING directs all non-LOCAL destination traffic to our custom IP-MASQ-AGENT chain */ ADDRTYPE match dst-type !LOCAL&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let's look at the new chain:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="gp"&gt;ubuntu@worker1:~$&lt;/span&gt; sudo iptables -t nat -vxnL IP-MASQ-AGENT
&lt;span class="go"&gt;Chain IP-MASQ-AGENT (1 references)&lt;/span&gt;
&lt;span class="go"&gt;    pkts      bytes target     prot opt in     out     source               destination&lt;/span&gt;
&lt;span class="go"&gt;       0        0 RETURN     all  --  *      *       0.0.0.0/0            169.254.0.0/16       /* ip-masq-agent: cluster-local traffic should not be subject to MASQUERADE */ ADDRTYPE match dst-type !LOCAL&lt;/span&gt;
&lt;span class="go"&gt;      12      720 RETURN     all  --  *      *       0.0.0.0/0            10.200.0.0/16        /* ip-masq-agent: cluster-local traffic should not be subject to MASQUERADE */ ADDRTYPE match dst-type !LOCAL&lt;/span&gt;
&lt;span class="go"&gt;       0        0 RETURN     all  --  *      *       0.0.0.0/0            10.32.0.0/16         /* ip-masq-agent: cluster-local traffic should not be subject to MASQUERADE */ ADDRTYPE match dst-type !LOCAL&lt;/span&gt;
&lt;span class="go"&gt;       0        0 MASQUERADE  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* ip-masq-agent: outbound traffic should be subject to MASQUERADE (this match must come after cluster-local CIDR matches) */ ADDRTYPE match dst-type !LOCAL&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Our non-masquerade rules have been applied!&lt;/p&gt;
&lt;p&gt;Let's check DNS resolution:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="gp"&gt;ubuntu@worker1:~$&lt;/span&gt; kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; -it mypod /bin/sh
&lt;span class="go"&gt;/ # nslookup kubernetes.io&lt;/span&gt;
&lt;span class="go"&gt;Server:    10.32.0.10&lt;/span&gt;
&lt;span class="go"&gt;Address 1: 10.32.0.10 kube-dns.kube-system.svc.cluster.local&lt;/span&gt;

&lt;span class="go"&gt;Name:      kubernetes.io&lt;/span&gt;
&lt;span class="go"&gt;Address 1: 23.236.58.218 218.58.236.23.bc.googleusercontent.com&lt;/span&gt;
&lt;span class="go"&gt;/ #&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It works!&lt;/p&gt;
&lt;p&gt;Let's check out &lt;tt class="docutils literal"&gt;tcpdump&lt;/tt&gt; again:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="gp"&gt;ubuntu@worker1:~$&lt;/span&gt; sudo tcpdump -i enp0s3 dst host 10.0.2.3
&lt;span class="go"&gt;tcpdump: verbose output suppressed, use -v or -vv for full protocol decode&lt;/span&gt;
&lt;span class="go"&gt;listening on enp0s3, link-type EN10MB (Ethernet), capture size 262144 bytes&lt;/span&gt;
&lt;span class="go"&gt;12:30:35.522668 IP 10.0.2.15.65039 &amp;gt; 10.0.2.3.domain: 36319+ AAAA? google.com. (28)&lt;/span&gt;
&lt;span class="go"&gt;12:30:35.522781 IP 10.0.2.15.65039 &amp;gt; 10.0.2.3.domain: 36319+ AAAA? google.com. (28)&lt;/span&gt;
&lt;span class="go"&gt;12:30:35.522928 IP 10.0.2.15.63090 &amp;gt; 10.0.2.3.domain: 3284+ AAAA? google.com. (28)&lt;/span&gt;
&lt;span class="go"&gt;12:30:35.523002 IP 10.0.2.15 &amp;gt; 10.0.2.3: ICMP 10.0.2.15 udp port 65039 unreachable, length 64&lt;/span&gt;
&lt;span class="go"&gt;12:30:35.523099 IP 10.0.2.15.12876 &amp;gt; 10.0.2.3.domain: 44566+ AAAA? google.com. (28)&lt;/span&gt;
&lt;span class="go"&gt;12:30:35.523476 IP 10.0.2.15.57223 &amp;gt; 10.0.2.3.domain: 37209+ PTR? 3.2.0.10.in-addr.arpa. (39)&lt;/span&gt;
&lt;span class="go"&gt;12:30:35.523639 IP 10.0.2.15.40473 &amp;gt; 10.0.2.3.domain: 10359+ AAAA? google.com. (28)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Looks like SNAT is working for our request to the VirtualBox DNS.&lt;/p&gt;
&lt;p&gt;If you are interested in diving more into customizing upstream dns servers and/or private dns zones, check out this recent &lt;a class="reference external" href="http://blog.kubernetes.io/2017/04/configuring-private-dns-zones-upstream-nameservers-kubernetes.html"&gt;kubernetes blog article&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Dorn</dc:creator><pubDate>Thu, 27 Jul 2017 11:19:00 -0500</pubDate><guid>tag:www.madorn.com,2017-07-27:kubernetes-non-masquerade-cidr.html</guid><category>kubernetes</category><category>virtualbox</category></item><item><title>Certified OpenStack Administrator Exam Book</title><link>http://www.madorn.com/certified-openstack-administrator-exam.html</link><description>&lt;p&gt;My new book, &lt;a class="reference external" href="https://www.amazon.com/dp/B06WRT43DW/ref=cm_sw_r_cp_ep_dp_Spw5ybQD6YEBF"&gt;Preparing for the Certified OpenStack Administrator Exam&lt;/a&gt; , will be out in July 2017 on &lt;a class="reference external" href="https://packtpub.com"&gt;Packt Publishing&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The exam prepares students for the upcoming Newton version of the exam on Ubuntu 16.04.  The exam currently tests on &lt;strong&gt;Liberty&lt;/strong&gt; but will be upgraded to &lt;strong&gt;Newton&lt;/strong&gt; in May 2017.&lt;/p&gt;
&lt;p&gt;Here is an excerpt from the first chapter:&lt;/p&gt;
&lt;div class="section" id="benefits-of-passing-the-exam"&gt;
&lt;h2&gt;Benefits of Passing the Exam&lt;/h2&gt;
&lt;p&gt;Ask anyone about getting started in the IT world and they may suggest looking into industry-recognized&amp;nbsp;technical certifications.&amp;nbsp; IT certifications measure competency in a number of areas and are a great way to open doors to opportunities. &amp;nbsp;While they certainly should not be the only determining&amp;nbsp;factor in the hiring process, achieving them can&amp;nbsp;be a measure of your competence and commitment to facing challenges.&lt;/p&gt;
&lt;div class="section" id="if-you-pass"&gt;
&lt;h3&gt;If You Pass...&lt;/h3&gt;
&lt;p&gt;Upon completion of a passing grade, you will receive your certificate.  Laminate, frame, or pin it to your home office wall or work cubicle! &amp;nbsp;It’s proof that you have met all the requirements to become an official OpenStack Administrator.&amp;nbsp; The certification is valid for three years from the pass date so don't forget to renew!&lt;/p&gt;
&lt;img alt="" src="https://s3.amazonaws.com/madorn.com/images/coacert.png" /&gt;
&lt;p&gt;In addition to the certification, a COA badge will appear next to your name in the &lt;a class="reference external" href="https://www.openstack.org/community/members/"&gt;OpenStack Foundation Member Directory&lt;/a&gt;.&lt;/p&gt;
&lt;img alt="" src="https://s3.amazonaws.com/madorn.com/images/coamember.png" /&gt;
&lt;div class="note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;The OpenStack Foundation has put together a great tool for helping employers verify the validity of COA certifications. &amp;nbsp;Check out the &lt;a class="reference external" href="https://www.openstack.org/coa/coa-verify/"&gt;Certified OpenStack Administrator Verification Tool&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="steps-to-becoming-a-certified-openstack-administrator"&gt;
&lt;h2&gt;7 Steps to Becoming a Certified OpenStack Administrator!&lt;/h2&gt;
&lt;p&gt;Let's begin by walking through some steps to become a Certified OpenStack Administrator!&lt;/p&gt;
&lt;div class="section" id="step-1-study"&gt;
&lt;h3&gt;Step 1 - Study!&lt;/h3&gt;
&lt;p&gt;Practice. Practice. Practice. Use this book and the included OpenStack All-in-One Virtual Appliance as a resource as you begin your Certified OpenStack Administrator journey.
If you still find yourself struggling with the concepts and objectives in this book, you can always refer to the Official OpenStack Documentation or even seek out a live training class at
the &lt;a class="reference external" href="https://www.openstack.org/marketplace/training/"&gt;OpenStack Training Marketplace&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="step-2-purchase"&gt;
&lt;h3&gt;Step 2 - Purchase!&lt;/h3&gt;
&lt;p&gt;Once you feel that you’re ready to conquer the exam, head to the &lt;a class="reference external" href="https://www.openstack.org/coa/"&gt;Official Certified OpenStack Administrator Homepage&lt;/a&gt; and click on &lt;a class="reference external" href="https://www.openstack.org/coa/get-started"&gt;Get Started&lt;/a&gt;.
After signing in, you will be directed to checkout to purchase your exam.
The OpenStack Foundation accepts all major credit cards and as of April 2017, costs $300.00 USD but is subject to change so keep an eye out on the website.
You can also get a FREE retake within 12 months of the original exam purchase date if you do not pass on the first attempt.&lt;/p&gt;
&lt;div class="note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;To encourage academia students to get their feet wet with OpenStack technologies,
the OpenStack Foundation is offering the exam for $150.00 (50% off the retail price) with a valid student ID.
Check out &lt;a class="reference external" href="https://www.openstack.org/coa/student/"&gt;https://www.openstack.org/coa/student/&lt;/a&gt; for more info.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="step-3-coa-portal-page"&gt;
&lt;h3&gt;Step 3 - COA Portal Page&lt;/h3&gt;
&lt;p&gt;Once your order is processed, you will receive an email with access to the &lt;a class="reference external" href="https://cert.openstack.org/portal"&gt;COA Portal&lt;/a&gt;.
Think of the portal as your personal COA website where you can download your exam receipt and keep track of your certification efforts.
Once you take the exam, you can come back to the COA Portal to check your exam status, exam score, and even download certificates and badges
for displaying on business cards or websites!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="step-4-hardware-compatibility-check"&gt;
&lt;h3&gt;Step 4 - Hardware Compatibility Check&lt;/h3&gt;
&lt;p&gt;The COA exam can be taken from your personal laptop or desktop but you must ensure that your system meets the exam’s minimum system requirements.
A link on the COA Portal page will present you with the Compatibility Check Tool which will run a series of tests to ensure you meet the requirements.
It will also assist you in downloading a Chrome plugin for taking the exam.
At this time, you must use the Chrome or Chromium browser and have access to reliable internet, a webcam, and microphone.
Here is a current list of requirements:&lt;/p&gt;
&lt;img alt="" src="https://s3.amazonaws.com/madorn.com/images/hardware.png" /&gt;
&lt;/div&gt;
&lt;div class="section" id="step-5-identification"&gt;
&lt;h3&gt;Step 5 - Identification&lt;/h3&gt;
&lt;p&gt;You must be at least 18 years old and have proper identification to take the exam!&lt;/p&gt;
&lt;p&gt;Any of the following pieces of identification are acceptable:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Passport&lt;/li&gt;
&lt;li&gt;Government-issued driver's license or permit&lt;/li&gt;
&lt;li&gt;National identity card&lt;/li&gt;
&lt;li&gt;State or province-issued identity card&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div class="section" id="step-6-schedule-the-exam"&gt;
&lt;h3&gt;Step 6 - Schedule the Exam&lt;/h3&gt;
&lt;p&gt;I personally recommend scheduling your exam a few months ahead of time to give yourself a realistic goal.
Click on the Schedule Exam link on the COA Portal to be directed and automatically logged into the Exam Proctor Partner website.
Once logged into the site, type OpenStack Foundation in the search box and select the COA exam.
You will then choose from available dates and times. The latest possible exam date you can schedule will be 30 days out from the current date.
Once you have scheduled it, you can cancel or reschedule up to 24 hours before the start time of the exam.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="step-7-take-the-exam"&gt;
&lt;h3&gt;Step 7 - Take the Exam!&lt;/h3&gt;
&lt;p&gt;Your day has arrived!  You've used this book and have practiced day and night to master all of the covered objectives!  It's finally time to take the exam!&lt;/p&gt;
&lt;p&gt;One of the most important factors determining your success on the exam is the location.
You cannot be in a crowded place! This means no coffee shops, work desks, or football games!
The testing location policy is very strict, so please consider taking the exam from home or perhaps a private room in the office.&lt;/p&gt;
&lt;p&gt;Log into the COA Portal fifteen minutes before your scheduled exam time.
You should now see a Take Exam link which will connect to the Exam Proctor Partner website so you can connect to the testing environment.&lt;/p&gt;
&lt;p&gt;Once in the exam environment, an Exam Proctor chat window will appear and assist you with starting your exam.
You must allow sharing of your entire operating system screen (this includes all applications), webcam, and microphone.  t’s time to begin!  You have two and a half hours to complete all exam objectives.  You're almost on your way to becoming a Certified OpenStack Administrator!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="about-the-exam-environment"&gt;
&lt;h3&gt;About the Exam Environment&lt;/h3&gt;
&lt;p&gt;The exam expects its test-takers to be proficient in interacting with OpenStack via the Horizon dashboard and command-line interface.
Here is a visual representation of the exam console as outlined in the &lt;a class="reference external" href="https://www.openstack.org/assets/coa/COA-Candidate-Handbook-V1.4.14.pdf"&gt;COA Candidate Handbook&lt;/a&gt;:&lt;/p&gt;
&lt;img alt="" src="https://s3.amazonaws.com/madorn.com/images/console.png" /&gt;
&lt;p&gt;The exam console is embedded into the browser. It is composed of two primary parts: The &lt;strong&gt;Content Panel&lt;/strong&gt; and the &lt;strong&gt;Dashboard/Terminal Panel&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;Content Panel&lt;/strong&gt; is the section that displays the exam timer and objectives.  As per the COA Handbook, exam objectives can only be navigated linearly. You can use the next and back button to move to each objective.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;Dashboard/Terminal Panel&lt;/strong&gt; gives you full access to an OpenStack environment.  Chapter 2 of this book will assist you with getting your practice OpenStack environment environment up and running so you can work through all the objectives.&lt;/p&gt;
&lt;div class="note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;The exam console terminal is embedded in a browser and you cannot SCP (secure copy) to it
from your local system. Within the terminal environment, you are permitted to install a multiplexor such as screen,
tmux, or byobu if you think these will assist you but are not necessary for successful completion of all objectives.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;You are not permitted to browse websites, email, or notes during the exam but you are free to access the &lt;a class="reference external" href="https://docs.openstack.org"&gt;Official OpenStack Documentation&lt;/a&gt;.  This can be a major waste of time on the exam and shouldn’t be necessary after working through the exam objectives in this book.  You can also easily copy and paste from the objective window into the Horizon dashboard or terminal.&lt;/p&gt;
&lt;p&gt;If you struggle with a question, move on! Hit the next button and try the next objective. You can always come back and tackle it before time is up.&lt;/p&gt;
&lt;p&gt;The exam is scored automatically within 24 hours and you should receive the results via email within 72 hours after exam completion.  At this time, the results will be made available on the COA Portal.  Please review the Professional Code of Conduct on the OpenStack Foundation Certification Handbook.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="the-exam-objectives"&gt;
&lt;h3&gt;The Exam Objectives&lt;/h3&gt;
&lt;p&gt;Let's now take a look at the objectives you will be responsible for performing on the exam.
As of March 2017,  these are all the exam objectives published on the Official COA website.
These objectives will test your competence and proficiency in the domains listed below.
These domains cover multiple core OpenStack services as well as general OpenStack troubleshooting.
Together, all of these domains make up 100% of the exam.&lt;/p&gt;
&lt;div class="note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;Because some of the objectives on the official COA Requirements list overlap,
this book utilizes its own convenient strategy to ensure you can fulfill all objectives within all content areas.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="getting-to-know-openstack-3-chapter-1"&gt;
&lt;h3&gt;Getting To know OpenStack - 3%  -  Chapter 1&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Understand the components that make up the cloud&lt;/li&gt;
&lt;li&gt;Use the OpenStack API/CLI&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="keystone-identity-management-12-chapter-3"&gt;
&lt;h3&gt;Keystone - Identity management - 12%  - Chapter 3&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Manage Keystone catalogue services and endpoints&lt;/li&gt;
&lt;li&gt;Manage/Create domains, groups, projects, users, and roles&lt;/li&gt;
&lt;li&gt;Create roles for the environment&lt;/li&gt;
&lt;li&gt;Manage the identity service&lt;/li&gt;
&lt;li&gt;Verify operation of the Identity service&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="glance-image-management-10-chapter-4"&gt;
&lt;h3&gt;Glance - Image management - 10%  - Chapter 4&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Deploy a new image to an OpenStack instance&lt;/li&gt;
&lt;li&gt;Manage image types and backends&lt;/li&gt;
&lt;li&gt;Manage images (e.g. add, update, remove)&lt;/li&gt;
&lt;li&gt;Verify operation of the Image Service&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="nova-compute-15-chapter-5"&gt;
&lt;h3&gt;Nova - Compute - 15%  - Chapter 5&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Manage flavors&lt;/li&gt;
&lt;li&gt;Manage compute instance actions (e.g. launch, shutdown, terminate)&lt;/li&gt;
&lt;li&gt;Manage Nova user keypairs&lt;/li&gt;
&lt;li&gt;Launch a new instance&lt;/li&gt;
&lt;li&gt;Shutdown an Instance&lt;/li&gt;
&lt;li&gt;Terminate Instance&lt;/li&gt;
&lt;li&gt;Configure an Instance with a Floating IP address&lt;/li&gt;
&lt;li&gt;Manage project security group rules&lt;/li&gt;
&lt;li&gt;Assign security group to Instance&lt;/li&gt;
&lt;li&gt;Assign floating IP address to Instance&lt;/li&gt;
&lt;li&gt;Detach floating IP address from Instance&lt;/li&gt;
&lt;li&gt;Manage Nova host consoles (rdp, spice, tty)&lt;/li&gt;
&lt;li&gt;Access an Instance using a keypair&lt;/li&gt;
&lt;li&gt;Manage instance snapshots&lt;/li&gt;
&lt;li&gt;Manage Nova compute servers&lt;/li&gt;
&lt;li&gt;Manage quotas&lt;/li&gt;
&lt;li&gt;Get Nova stats (hosts, services, tenants&lt;/li&gt;
&lt;li&gt;Verify operation of the Compute service&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="neutron-networking-16-chapter-6"&gt;
&lt;h3&gt;Neutron - Networking - 16%  - Chapter 6&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Manage network resources (e.g., routers, subnets)&lt;/li&gt;
&lt;li&gt;Create external networks&lt;/li&gt;
&lt;li&gt;Create project networks&lt;/li&gt;
&lt;li&gt;Create project routers&lt;/li&gt;
&lt;li&gt;Manage network services for a virtual environment&lt;/li&gt;
&lt;li&gt;Manage project security group rules&lt;/li&gt;
&lt;li&gt;Manage quotas&lt;/li&gt;
&lt;li&gt;Verify operation of network service&lt;/li&gt;
&lt;li&gt;Manage network interfaces on compute instances&lt;/li&gt;
&lt;li&gt;Troubleshoot network issues for a tenant network (enter namespace, run tcpdump, etc)&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="cinder-block-storage-10-chapter-7"&gt;
&lt;h3&gt;Cinder - Block Storage - 10% - Chapter 7&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Manage volume&lt;/li&gt;
&lt;li&gt;Create volume group for block storage&lt;/li&gt;
&lt;li&gt;Create a new Block Storage Volume and mount it to a Nova Instance&lt;/li&gt;
&lt;li&gt;Manage quotas&lt;/li&gt;
&lt;li&gt;Manage volumes quotas&lt;/li&gt;
&lt;li&gt;Manage volumes backups&lt;/li&gt;
&lt;li&gt;Backup and restore volumes&lt;/li&gt;
&lt;li&gt;Manage volume snapshots (e.g, take, list, recover)&lt;/li&gt;
&lt;li&gt;Verify that block storage can perform snapshotting function&lt;/li&gt;
&lt;li&gt;Snapshot volume&lt;/li&gt;
&lt;li&gt;Manage volumes encryption&lt;/li&gt;
&lt;li&gt;Set up storage pools&lt;/li&gt;
&lt;li&gt;Monitor reserve capacity of block storage devices&lt;/li&gt;
&lt;li&gt;Analyze discrepancies in reported volume sizes&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="swift-object-storage-10-chapter-8"&gt;
&lt;h3&gt;Swift - Object Storage - 10%  - Chapter 8&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Manage access to object storage&lt;/li&gt;
&lt;li&gt;Manage expiring objects&lt;/li&gt;
&lt;li&gt;Manage storage policies&lt;/li&gt;
&lt;li&gt;Monitor space available for object store&lt;/li&gt;
&lt;li&gt;Verify operation of Object Storage&lt;/li&gt;
&lt;li&gt;Manage permissions on a container in object storage&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="heat-orchestration-8-chapter-9"&gt;
&lt;h3&gt;Heat - Orchestration - 8% - Chapter 9&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Launch a stack using a Heat/Orchestration template (e.g., storage, network, and compute&lt;/li&gt;
&lt;li&gt;Use Heat/Orchestration CLI and Dashboard&lt;/li&gt;
&lt;li&gt;Verify Heat/Orchestration stack is working&lt;/li&gt;
&lt;li&gt;Verify operation of Heat/Orchestration&lt;/li&gt;
&lt;li&gt;Create a Heat/Orchestration template that matches a specific scenario&lt;/li&gt;
&lt;li&gt;Update a stack&lt;/li&gt;
&lt;li&gt;Obtain detailed information about a stack&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="horizon-dashboard-3-chapters-3-through-9"&gt;
&lt;h3&gt;Horizon - Dashboard - 3%  - Chapters 3 through 9&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Verify operation of the Dashboard&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="troubleshooting-13-chapter-10"&gt;
&lt;h3&gt;Troubleshooting - 13%  - Chapter 10&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Analyze log files&lt;/li&gt;
&lt;li&gt;Backup the database(s) used by an OpenStack instance&lt;/li&gt;
&lt;li&gt;Centralize and analyze logs (e.g.,/var/log/COMPONENT_NAME, Database Server, Messaging Server, Web Server, syslog)&lt;/li&gt;
&lt;li&gt;Analyze database servers&lt;/li&gt;
&lt;li&gt;Analyze Host/Guest OS and Instance status&lt;/li&gt;
&lt;li&gt;Analyze messaging servers&lt;/li&gt;
&lt;li&gt;Analyze metadata servers&lt;/li&gt;
&lt;li&gt;Analyze network status (physical &amp;amp; virtual)&lt;/li&gt;
&lt;li&gt;Analyze storage status (local, block &amp;amp; object)&lt;/li&gt;
&lt;li&gt;Manage OpenStack Services&lt;/li&gt;
&lt;li&gt;Diagnose service incidents&lt;/li&gt;
&lt;li&gt;Digest OpenStack environment (Controller, Compute, Storage and Network nodes)&lt;/li&gt;
&lt;li&gt;Direct logging files through centralized logging system&lt;/li&gt;
&lt;li&gt;Backup and restore an OpenStack instance&lt;/li&gt;
&lt;li&gt;Troubleshoot network performance&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Dorn</dc:creator><pubDate>Wed, 05 Apr 2017 12:00:00 -0500</pubDate><guid>tag:www.madorn.com,2017-04-05:certified-openstack-administrator-exam.html</guid><category>openstack</category><category>certification</category></item><item><title>Configure Cloud-Init to Use Admin Pass</title><link>http://www.madorn.com/cloud-init-admin-pass.html</link><description>&lt;p&gt;When one spins up a cloud image with Cloud-Init installed, password authentication via SSH is typically disabled by default.  This requires that one SSH into the instance by injecting a public key.  One can override this behavior by passing the following cloud-config directives which correspond to the &lt;a class="reference external" href="http://bazaar.launchpad.net/~cloud-init-dev/cloud-init/trunk/view/head:/cloudinit/config/cc_set_passwords.py"&gt;cc_set_passwords.py&lt;/a&gt; module set to run during Cloud-Init's &lt;strong&gt;config&lt;/strong&gt; stage (/etc/cloud/cloud.cfg).&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;ssh_pwauth&lt;/tt&gt; - edits sshd config to either allow or unallow password auth via ssh.&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;password&lt;/tt&gt; - set password for default user (default user specified in /etc/cloud/cloud.cfg, i.e. ubuntu on ubuntu cloud image, centos on centos7 cloud image, etc.)&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;chpasswd&lt;/tt&gt; - allows you to provide a list of user password changes as well as ensure the passwords do not expire.  If expire is not set to False, one will be prompted to set a new password after authenticating.  Provide &lt;em&gt;RANDOM&lt;/em&gt; or &lt;em&gt;R&lt;/em&gt; as the password to have it auto-generate a password.  The password will appear in the console-log (nova console-log &amp;lt;your_instance_id&amp;gt;) and inside /var/log/cloud-init-output.log.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="gp"&gt;#&lt;/span&gt;cloud-config
&lt;span class="go"&gt;ssh_pwauth: True&lt;/span&gt;
&lt;span class="go"&gt;password: passw0rd&lt;/span&gt;
&lt;span class="go"&gt;chpasswd:&lt;/span&gt;
&lt;span class="go"&gt;  list: |&lt;/span&gt;
&lt;span class="go"&gt;    user1:password1&lt;/span&gt;
&lt;span class="go"&gt;    user2:password2&lt;/span&gt;
&lt;span class="go"&gt;    user3:RANDOM&lt;/span&gt;
&lt;span class="go"&gt;  expire: False&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can modify the cc_set_passwords.py module to allow it to set root's password to the metadata admin_pass value found here:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;+--------------------------------------+---------------------------------------------------+&lt;/span&gt;
&lt;span class="go"&gt;| Property                             | Value                                             |&lt;/span&gt;
&lt;span class="go"&gt;+--------------------------------------+---------------------------------------------------+&lt;/span&gt;
&lt;span class="go"&gt;| OS-DCF:diskConfig                    | MANUAL                                            |&lt;/span&gt;
&lt;span class="go"&gt;| OS-EXT-AZ:availability_zone          |                                                   |&lt;/span&gt;
&lt;span class="go"&gt;| OS-EXT-SRV-ATTR:host                 | -                                                 |&lt;/span&gt;
&lt;span class="go"&gt;| OS-EXT-SRV-ATTR:hypervisor_hostname  | -                                                 |&lt;/span&gt;
&lt;span class="go"&gt;| OS-EXT-SRV-ATTR:instance_name        | instance-0000000e                                 |&lt;/span&gt;
&lt;span class="go"&gt;| OS-EXT-STS:power_state               | 0                                                 |&lt;/span&gt;
&lt;span class="go"&gt;| OS-EXT-STS:task_state                | scheduling                                        |&lt;/span&gt;
&lt;span class="go"&gt;| OS-EXT-STS:vm_state                  | building                                          |&lt;/span&gt;
&lt;span class="go"&gt;| OS-SRV-USG:launched_at               | -                                                 |&lt;/span&gt;
&lt;span class="go"&gt;| OS-SRV-USG:terminated_at             | -                                                 |&lt;/span&gt;
&lt;span class="go"&gt;| accessIPv4                           |                                                   |&lt;/span&gt;
&lt;span class="go"&gt;| accessIPv6                           |                                                   |&lt;/span&gt;
&lt;span class="go"&gt;| adminPass                            | AcSVqg3koaeS                                      |&lt;/span&gt;
&lt;span class="go"&gt;| config_drive                         |                                                   |&lt;/span&gt;
&lt;span class="go"&gt;| created                              | 2016-05-04T01:05:46Z                              |&lt;/span&gt;
&lt;span class="go"&gt;| flavor                               | m1.summit (8)                                     |&lt;/span&gt;
&lt;span class="go"&gt;| hostId                               |                                                   |&lt;/span&gt;
&lt;span class="go"&gt;| id                                   | ed7b97ef-cea9-4140-8cd0-d30d6abba802              |&lt;/span&gt;
&lt;span class="go"&gt;| image                                | ubuntu1604 (ad673fbe-2402-462b-b29c-d10d49252310) |&lt;/span&gt;
&lt;span class="go"&gt;| key_name                             | -                                                 |&lt;/span&gt;
&lt;span class="go"&gt;| metadata                             | {}                                                |&lt;/span&gt;
&lt;span class="go"&gt;| name                                 | myinstance                                        |&lt;/span&gt;
&lt;span class="go"&gt;| os-extended-volumes:volumes_attached | []                                                |&lt;/span&gt;
&lt;span class="go"&gt;| progress                             | 0                                                 |&lt;/span&gt;
&lt;span class="go"&gt;| security_groups                      | default                                           |&lt;/span&gt;
&lt;span class="go"&gt;| status                               | BUILD                                             |&lt;/span&gt;
&lt;span class="go"&gt;| tenant_id                            | 9d119a1e9de4498da818abe32124eb32                  |&lt;/span&gt;
&lt;span class="go"&gt;| updated                              | 2016-05-04T01:05:46Z                              |&lt;/span&gt;
&lt;span class="go"&gt;| user_id                              | 3545fc68adb349828d3f98893fb0d47f                  |&lt;/span&gt;
&lt;span class="go"&gt;+--------------------------------------+---------------------------------------------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can also force a specific admin pass while booting:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;nova boot --image ubuntu1604 --flavor m1.summit --admin-pass mypassword mycustomrootpasswordinstance&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here is a link to a &lt;a class="reference external" href="https://github.com/madorn/cloud-init-guide/blob/master/cc_set_passwords.py"&gt;modified cc_set_passwords&lt;/a&gt; to fetch admin_pass from metadata and set as root password.&lt;/p&gt;
&lt;p&gt;Cloud-Init python modules:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Ubuntu 14.04: /usr/lib/python2.7/dist-packages/cloudinit/config/&lt;/li&gt;
&lt;li&gt;Ubuntu 16.04: /usr/lib/python3/dist-packages/cloudinit/config/&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Dorn</dc:creator><pubDate>Wed, 04 May 2016 13:59:00 -0500</pubDate><guid>tag:www.madorn.com,2016-05-04:cloud-init-admin-pass.html</guid><category>openstack</category><category>metadata</category><category>cloud-init</category></item><item><title>Cloud-Init Stages in Upstart and Systemd</title><link>http://www.madorn.com/cloud-init-stages.html</link><description>&lt;p&gt;Cloud-init can be found on most cloud images provided by an elastic cloud vendor. If you are rolling/baking your own cloud image, you can typically install cloud-init via your distro's package manager.&lt;/p&gt;
&lt;p&gt;Cloud-init executes in several key stages.&lt;/p&gt;
&lt;div class="section" id="stage-1-init-local"&gt;
&lt;h2&gt;Stage-1 - Init Local&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/etc/init/cloud-init-local.conf&lt;/span&gt;&lt;/tt&gt; (Upstart)&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;start on mounted MOUNTPOINT=/&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/lib/systemd/system/cloud-init-local.service&lt;/span&gt;&lt;/tt&gt; (Systemd)&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Before=shutdown.target multi-user.target cloud-config.target cloud-init.service&lt;/li&gt;
&lt;li&gt;After=local-fs.target systemd-journald.socket basic.target system.slice&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Execute: &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/usr/bin/cloud-init&lt;/span&gt; init &lt;span class="pre"&gt;--local&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Runs prior to network setup.  It looks for a NoCloud data source at &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/var/lib/cloud/seed/nocloud/{meta-data,user-data,network-data,vendor-data}&lt;/span&gt;&lt;/tt&gt;.  If present, it will copy to /var/lib/cloud/instances/&amp;lt;instance-id&amp;gt; and execute all Python modules listed in init stage at /etc/cloud/cloud.cfg.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;If a data source is not found at the above, it will look for VFAT or ISO device with LABEL=&amp;quot;cidata&amp;quot;.  If present, it will copy to /var/lib/cloud/instances/&amp;lt;instance-id&amp;gt; and excute all Python modules listed in &lt;strong&gt;init&lt;/strong&gt; stage at /etc/cloud/cloud.cfg.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="stage-2-init"&gt;
&lt;h2&gt;Stage-2 - Init&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/etc/init/cloud-init.conf&lt;/span&gt;&lt;/tt&gt; (Upstart)&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;start on mounted MOUNTPOINT=/&lt;/li&gt;
&lt;li&gt;stopped cloud-init-nonet (After network is up)&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/lib/systemd/system/cloud-init.service&lt;/span&gt;&lt;/tt&gt; (Systemd)&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Before=multi-user.target shutdown.target systemd-user-sessions.service cloud-config.target sshd-keygen.service ssh.service&lt;/li&gt;
&lt;li&gt;After=network-online.target basic.target cloud-init-local.service system.slice systemd-journald.socket local-fs.target&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Execute: &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/usr/bin/cloud-init&lt;/span&gt; init&lt;/tt&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;datasource_list: [ NoCloud, ConfigDrive, OpenNebula, Azure, AltCloud, OVF, MAAS, GCE, OpenStack, CloudSigma, Ec2, CloudStack, None ] (/etc/cloud/cloud.cfg.d/90_dpkg.cfg)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;By default, first datasource listed is the priority. If metadata is discovered, it is copied to /var/lib/cloud/instances/&amp;lt;instance-id&amp;gt;/.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;All Python modules listed in &lt;strong&gt;init&lt;/strong&gt; stage (/etc/cloud/cloud.cfg) will execute.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="stage-3-config"&gt;
&lt;h2&gt;Stage-3 - Config&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/etc/init/cloud-config.conf&lt;/span&gt;&lt;/tt&gt; (Upstart)&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;start on (filesystem and started rsyslog)&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/lib/systemd/system/cloud-config.service&lt;/span&gt;&lt;/tt&gt; (Systemd)&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Before=cloud-final.service multi-user.target shutdown.target&lt;/li&gt;
&lt;li&gt;After=systemd-journald.socket network-online.target syslog.target system.slice basic.target cloud-config.target&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Execute: &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/usr/bin/cloud-init&lt;/span&gt; modules &lt;span class="pre"&gt;--mode=config&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;All Python modules listed in &lt;strong&gt;config&lt;/strong&gt; stage (/etc/cloud/cloud.cfg) will execute.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="stage-4-final"&gt;
&lt;h2&gt;Stage-4 - Final&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/etc/init/cloud-final.conf&lt;/span&gt;&lt;/tt&gt; (Upstart)&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;start on (stopped rc RUNLEVEL=[2345] (starts after rc.local)&lt;/li&gt;
&lt;li&gt;stopped cloud-config&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/lib/systemd/system/cloud-final.service&lt;/span&gt;&lt;/tt&gt; (Systemd)&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Before=multi-user.target shutdown.target&lt;/li&gt;
&lt;li&gt;After=rc-local.service network-online.target cloud-config.service basic.target system.slice systemd-journald.socket syslog.target&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Execute: &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/usr/bin/cloud-init&lt;/span&gt; modules &lt;span class="pre"&gt;--mode=final&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;All Python modules listed in &lt;strong&gt;final&lt;/strong&gt; stage (/etc/cloud/cloud.cfg) will execute.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="additional-info"&gt;
&lt;h2&gt;Additional Info&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Most cloud-init Python modules have a default run frequency:  per_always (run on every boot), per_instance (run only if it has never run with this specific instance-id), per_boot (run only once, regardless of the instance-id).&lt;/li&gt;
&lt;li&gt;Cloud-init keeps track of whether particular modules have been run by using semaphores. These get placed into the &lt;tt class="docutils literal"&gt;/var/lib/cloud/sem&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/var/lib/cloud/sem/instances/&amp;lt;instance-id&amp;gt;/sem&lt;/span&gt;&lt;/tt&gt; directories.&lt;/li&gt;
&lt;li&gt;One can specify which specific modules to run at specific stages and override default module frequency:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="gp"&gt;#&lt;/span&gt;cloud-config
&lt;span class="go"&gt;cloud_init_modules:&lt;/span&gt;
&lt;span class="go"&gt;  - seed_random&lt;/span&gt;
&lt;span class="go"&gt;  - [bootcmd, once]&lt;/span&gt;
&lt;span class="go"&gt;  - [write-files, instance]&lt;/span&gt;
&lt;span class="go"&gt;  - growpart&lt;/span&gt;
&lt;span class="go"&gt;  - resizefs&lt;/span&gt;
&lt;span class="go"&gt;  - set_hostname&lt;/span&gt;
&lt;span class="go"&gt;  - update_hostname&lt;/span&gt;
&lt;span class="go"&gt;  - rsyslog&lt;/span&gt;
&lt;span class="go"&gt;  - users-groups&lt;/span&gt;
&lt;span class="go"&gt;  - ssh&lt;/span&gt;

&lt;span class="go"&gt;cloud_config_modules:&lt;/span&gt;
&lt;span class="go"&gt;  - disable-ec2-metadata&lt;/span&gt;
&lt;span class="go"&gt;  - runcmd&lt;/span&gt;
&lt;span class="go"&gt;  - byobu&lt;/span&gt;

&lt;span class="go"&gt;cloud_final_modules:&lt;/span&gt;
&lt;span class="go"&gt;  - scripts-per-boot&lt;/span&gt;
&lt;span class="go"&gt;  - scripts-per-instance&lt;/span&gt;
&lt;span class="go"&gt;  - [scripts-user, always]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Dorn</dc:creator><pubDate>Tue, 03 May 2016 18:46:00 -0500</pubDate><guid>tag:www.madorn.com,2016-05-03:cloud-init-stages.html</guid><category>openstack</category><category>metadata</category><category>cloud-init</category></item><item><title>Overview of OpenStack Metadata Types</title><link>http://www.madorn.com/openstack-metadata-types.html</link><description>&lt;p&gt;As a follow up to my recent workshop at the Austin OpenStack Summit, here is some of the information from this session:&lt;/p&gt;
&lt;p&gt;When it comes to instance personalization on OpenStack, there are currently four primary types of metadata (these often show up on other cloud platforms as well): Meta-Data, User-Data, Vendor-Data, and Network-Data (&lt;a class="reference external" href="https://github.com/openstack/nova/blob/7b032f5339d39ae3f57832c0285b2b818b1ec918/nova/api/metadata/base.py"&gt;https://github.com/openstack/nova/blob/7b032f5339d39ae3f57832c0285b2b818b1ec918/nova/api/metadata/base.py&lt;/a&gt;)&lt;/p&gt;
&lt;div class="section" id="meta-data"&gt;
&lt;h2&gt;Meta-Data&lt;/h2&gt;
&lt;p&gt;Meta-Data is typically an instance-id, account-id, random seed, hostname, etc. It is found in the &lt;tt class="docutils literal"&gt;meta_data.json&lt;/tt&gt; file residing on ConfigDrive or the Neutron Metadata Service via 169.254.169.254/openstack/latest/meta_data.json.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;{&lt;/span&gt;
&lt;span class="go"&gt;&amp;quot;admin_pass&amp;quot;: &amp;quot;Amgkg8aehSeZ&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;&amp;quot;availability_zone&amp;quot;: &amp;quot;nova&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;&amp;quot;hostname&amp;quot;: &amp;quot;hi.novalocal&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;&amp;quot;launch_index&amp;quot;: 0,&lt;/span&gt;
&lt;span class="go"&gt;&amp;quot;name&amp;quot;: &amp;quot;hi&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;&amp;quot;project_id&amp;quot;: &amp;quot;b884b287309140b495821eb8f0f9e30d&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;&amp;quot;random_seed&amp;quot;: &amp;quot;FZHvd6YUHwDZUk4KYkVZkYrWHt61L1gGdbeoeefseeUUhmXvqCj9RfzKt9/RdD0DY2Fn48aAOVovSh6I6VtsRScV6ASjC+mpweJX1Jjmh73cjQnEfuN5YwUNknMYHZWDhWcKEjgRYpgM1BnaWYCt/wDVFC/Y0esLODy4156V94Sm8VhotDUawkoXT7BlCeLD+3bpAV1iprJn26CcM6Ob0ODKT3/qRVaSqxGD7qYi69RAelsneDOVn41xDJiQeIUqBCRzzahgDUoJ8HjFNuawFAqfez0Z3TqVsWuNHP03FhmNOG9Tqw7GevsMhLmzYY65ZHoCaJb/Ew64mDt57XyU+SZOeJDV9El9ENRQtO9vBmXttMpX5MIlsNsy/eeDTmfMZWxKsubmenMmtT7AUEO+PdPhTa/UMfnxCUX+ehFjUaPfTxTJJ8zBPyPoSMFpE5yA04z0G2U20Yt1Nisb4tt2UBKHJeDERjf1Ta7lE0Uc5HFBjg9U2LxZy1DKG18py7LajbsbCHfMyJtMM2RrhR/910VarUgscYhRo++EQzEAZfBwf+e3UFbmOCFrMP8ndq/jyyhGeGuPa7Rusd42Y70JZxnZTRfPQN9w2kSPxCu0l7RJ1+Ry/+rp77NDlhOHXZMf6a7CG8MbEbDslwtMMrFpCjcgTcY1ZETVvFFaqSg6uNM=&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;&amp;quot;uuid&amp;quot;: &amp;quot;f8b406c4-7da1-4d20-8c44-a93dc42308e2&amp;quot;&lt;/span&gt;
&lt;span class="go"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For security reasons, the admin_pass value is not typically used during most OpenStack deployments.  One can create a customized cloud-init python module to fetch this admin_pass value and set it as root password. One can also choose to have &lt;a class="reference external" href="https://kimizhang.wordpress.com/2014/03/18/how-to-inject-filemetassh-keyroot-passworduserdataconfig-drive-to-a-vm-during-nova-boot/"&gt;libvirt mount the image and inject the password&lt;/a&gt; prior to boot.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;random_seed is taken from the compute host's &lt;tt class="docutils literal"&gt;/dev/urandom&lt;/tt&gt;.&lt;/li&gt;
&lt;li&gt;launch_index is the number assigned to an instance when booting multiple servers via one api call or cli command, i.e.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;nova boot --flavor 1 --image ubuntu --max-count 3 myinstance&lt;/span&gt;

&lt;span class="go"&gt;myinstance-1 = launch_index: 0&lt;/span&gt;
&lt;span class="go"&gt;myinstance-2 = launch_index: 1&lt;/span&gt;
&lt;span class="go"&gt;myinstance-3 = launch_index: 2&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="user-data"&gt;
&lt;h2&gt;User-Data&lt;/h2&gt;
&lt;p&gt;The user passes user-data at boot via the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;--user-data&lt;/span&gt;&lt;/tt&gt; flag.  It is found in the &lt;tt class="docutils literal"&gt;user_data&lt;/tt&gt; file residing on ConfigDrive or the Neutron Metadata Service via 169.254.169.254/openstack/latest/user_data.  User-data is typically cloud-config syntax.  cloud-config is interepreted by cloud-init and provides an abstraction that is distro agnostic.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="gp"&gt;#&lt;/span&gt;cloud-config

&lt;span class="go"&gt;package_update: true&lt;/span&gt;
&lt;span class="go"&gt;package_upgrade: true&lt;/span&gt;

&lt;span class="go"&gt;write_files:&lt;/span&gt;
&lt;span class="go"&gt;- path: /etc/hosts&lt;/span&gt;
&lt;span class="go"&gt;  permissions: &amp;#39;0644&amp;#39;&lt;/span&gt;
&lt;span class="go"&gt;  content: |&lt;/span&gt;
&lt;span class="go"&gt;    192.168.1.4 server2&lt;/span&gt;
&lt;span class="go"&gt;    192.168.1.5 server3&lt;/span&gt;
&lt;span class="go"&gt;    192.168.1.6 server4&lt;/span&gt;
&lt;span class="go"&gt;    192.168.1.7 server5&lt;/span&gt;

&lt;span class="go"&gt;packages:&lt;/span&gt;
&lt;span class="go"&gt;  - vim&lt;/span&gt;
&lt;span class="go"&gt;  - git&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Each one of these directives (package_update/upgrade, write_files, packages, etc.) is directly related to a python module found in the cloud-init application (&lt;a class="reference external" href="http://bazaar.launchpad.net/~cloud-init-dev/cloud-init/trunk/files/head:/cloudinit/config/"&gt;http://bazaar.launchpad.net/~cloud-init-dev/cloud-init/trunk/files/head:/cloudinit/config/&lt;/a&gt;).   Cloud-init is typically found on any cloud image you boot, whether on Amazon, Rackspace, Google Cloud Platform, Azure, Digital Ocean, etc.&lt;/p&gt;
&lt;p&gt;Cloud-init can also run a variety of other scripts (as long as the intereprter exists on the image).  Examples include &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;#!/bin/sh&lt;/span&gt;&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;#!/usr/bin/python&lt;/span&gt;&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;#!/usr/bin/perl&lt;/span&gt;&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;#!/usr/bin/awk&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;User-Data is typically limited to 16K so you can also to the following to fetch the script and overcome the limitation:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="gp"&gt;#&lt;/span&gt;include
&lt;span class="go"&gt;http://yoursite.com/yourscript.txt&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="vendor-data"&gt;
&lt;h2&gt;Vendor-Data&lt;/h2&gt;
&lt;p&gt;Vendor-Data is a way for a vendor to provide site specific information.  This can be information on local mirrors, a local proxy, or a one-time registration code.  It is found in the &lt;tt class="docutils literal"&gt;vendor_data.json&lt;/tt&gt; file residing on ConfigDrive or the Neutron Metadata Service via 169.254.169.254/openstack/latest/vendor_data.json.  By default, Cloud-Init executes the Vendor-Data on every boot.&lt;/p&gt;
&lt;p&gt;When running OpenStack, one can setup Vendor Data by adding the following lines to nova-api's &lt;tt class="docutils literal"&gt;/etc/nova/nova.conf&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;[DEFAULT]&lt;/span&gt;
&lt;span class="go"&gt;vendordata_driver=nova.api.metadata.vendordata_json.JsonFileVendorData&lt;/span&gt;
&lt;span class="go"&gt;vendordata_jsonfile_path=/etc/nova/vendordata.json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;vendordata.json&lt;/tt&gt; file can be any cloud-init readable data in json format.  Example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;{&lt;/span&gt;
&lt;span class="go"&gt;&amp;quot;cloud-init&amp;quot;: &amp;quot;#cloud-config\nfinal_message: This is Vendor Data for the Austin OpenStack Summit Workshop by Rackspace Training&amp;quot;&lt;/span&gt;
&lt;span class="go"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="network-data"&gt;
&lt;h2&gt;Network-Data&lt;/h2&gt;
&lt;p&gt;Network-Data is network information found on ConfigDrive.  It resides in the &lt;tt class="docutils literal"&gt;network_data.json&lt;/tt&gt; file.  Nova retrieves this info from Neutron.  It includes fixed ip addresses, MAC addresses, port-id's, network-id's, subnet-id's, DNS name-servers, etc.&lt;/p&gt;
&lt;p&gt;Consider a scenario where DHCP is disabled in the cloud.  One could create a basic script or cloud-init module to assign static IP address found in this data to eth0.  Or perhaps DHCP is enabled and ones to statically assign eth1 and eth2.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;{&lt;/span&gt;
&lt;span class="go"&gt;&amp;quot;links&amp;quot;: [&lt;/span&gt;
&lt;span class="go"&gt;        {&lt;/span&gt;
&lt;span class="go"&gt;        &amp;quot;ethernet_mac_address&amp;quot;: &amp;quot;fa:16:3e:9c:bf:3d&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;        &amp;quot;id&amp;quot;: &amp;quot;tapcd9f6d46-4a&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;        &amp;quot;mtu&amp;quot;: null,&lt;/span&gt;
&lt;span class="go"&gt;        &amp;quot;type&amp;quot;: &amp;quot;bridge&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;        &amp;quot;vif_id&amp;quot;: &amp;quot;cd9f6d46-4a3a-43ab-a466-994af9db96fc&amp;quot;&lt;/span&gt;
&lt;span class="go"&gt;        }&lt;/span&gt;
&lt;span class="go"&gt;],&lt;/span&gt;
&lt;span class="go"&gt;&amp;quot;networks&amp;quot;: [&lt;/span&gt;
&lt;span class="go"&gt;        {&lt;/span&gt;
&lt;span class="go"&gt;        &amp;quot;id&amp;quot;: &amp;quot;network0&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;        &amp;quot;link&amp;quot;: &amp;quot;tapcd9f6d46-4a&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;        &amp;quot;network_id&amp;quot;: &amp;quot;99e88329-f20d-4741-9593-25bf07847b16&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;        &amp;quot;type&amp;quot;: &amp;quot;ipv4_dhcp&amp;quot;&lt;/span&gt;
&lt;span class="go"&gt;        }&lt;/span&gt;
&lt;span class="go"&gt;],&lt;/span&gt;
&lt;span class="go"&gt;&amp;quot;services&amp;quot;: [&lt;/span&gt;
&lt;span class="go"&gt;        {&lt;/span&gt;
&lt;span class="go"&gt;        &amp;quot;address&amp;quot;: &amp;quot;8.8.8.8&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;        &amp;quot;type&amp;quot;: &amp;quot;dns&amp;quot;&lt;/span&gt;
&lt;span class="go"&gt;        }&lt;/span&gt;
&lt;span class="go"&gt;]&lt;/span&gt;
&lt;span class="go"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Dorn</dc:creator><pubDate>Mon, 02 May 2016 15:46:00 -0500</pubDate><guid>tag:www.madorn.com,2016-05-02:openstack-metadata-types.html</guid><category>openstack</category><category>metadata</category><category>cloud-init</category></item><item><title>An Exploration of the OpenStack Metadata Service</title><link>http://www.madorn.com/openstack-metadata-service.html</link><description>&lt;p&gt;Here's a video of my workshop on the OpenStack Metadata Service at the Austin OpenStack Summit.&lt;/p&gt;
&lt;p&gt;Although it was a live hands-on workshop, the first 20-minutes provide the historical context for all current public/private clouds' metadata services.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Correction&lt;/strong&gt;: I mention that the OpenStack config-drive is turned on by default in Nova.  This is not true. One must ensure the following flag is set in &lt;tt class="docutils literal"&gt;/etc/nova/nova.conf&lt;/tt&gt; on the nova-api server:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;force_config_drive = True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If config-drive is set to false or not set at all, one can force it by using the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;--config-drive&lt;/span&gt;&lt;/tt&gt; flag on boot:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;nova boot --config-drive true --image my-image-name --flavor my-flavor myinstance&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I will be posting all my cloud-init content from this workshop in some upcoming posts.&lt;/p&gt;
&lt;iframe width="560" height="315" src="https://www.youtube.com/embed/YGUG8vU5KuQ" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Dorn</dc:creator><pubDate>Sun, 01 May 2016 12:00:00 -0500</pubDate><guid>tag:www.madorn.com,2016-05-01:openstack-metadata-service.html</guid><category>openstack</category><category>metadata</category><category>cloud-init</category></item><item><title>VirtualBox for the OpenStack Liberty Install Guide</title><link>http://www.madorn.com/virtualbox-liberty-install-guide.html</link><description>&lt;p&gt;The official &lt;a class="reference external" href="http://docs.openstack.org/liberty/"&gt;OpenStack Liberty Install Guides&lt;/a&gt; are a great way to get hands-on experience with installing and configuring OpenStack by hand.  This post describes how to install and configure a local VirtualBox environment for performing the step-by-step deployment instructions found in the guide.&lt;/p&gt;
&lt;div class="section" id="minimum-hardware-requirements"&gt;
&lt;h2&gt;Minimum Hardware Requirements&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;2 GHz or faster 64-bit (x64) processor with Intel VTx or AMD-V support&lt;/li&gt;
&lt;li&gt;5 GB RAM or higher&lt;/li&gt;
&lt;li&gt;20 GB or more available hard disk space&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="download-and-install-virtualbox"&gt;
&lt;h2&gt;Download and Install VirtualBox&lt;/h2&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Navigate to
&lt;a class="reference external" href="https://www.virtualbox.org/wiki/Downloads"&gt;VirtualBox Downloads&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Download and install the latest version of VirtualBox for your host
operating system.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class="section" id="configure-virtualbox-networking"&gt;
&lt;h2&gt;Configure VirtualBox Networking&lt;/h2&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p class="first"&gt;Launch the VirtualBox application.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;From the VirtualBox menu bar, select Preferences.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;From the VirtualBox Preferences menu, select the Network icon.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Ensure the Nat Networks tab is highlighted and select the + icon:&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="VirtualBox Nat Networks" src="https://s3.amazonaws.com/madorn.com/images/virtualbox-nat-networks.png" /&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;This will automatically create a Nat Network named NatNetwork.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Select the tool icon to modify NatNetwork.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Rename the network to Management and change the Network CIDR to
10.0.0.0/24. Verify the Supports DHCP box is checked:&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="VirtualBox Management Network" src="https://s3.amazonaws.com/madorn.com/images/virtualbox-management.png" /&gt;
&lt;/div&gt;
&lt;div class="note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;The gateway for the Management network is 10.0.0.1.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Select Port Forwarding.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Select the + icon on the right to create a new rule.
Name: SSH, Protocol: TCP, Host IP: 127.0.0.1, Host Port: 2022,
Guest IP: 10.0.0.11, and Guest Port: 22.
Select OK to save your changes:&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="VirtualBox Port Forwarding" src="https://s3.amazonaws.com/madorn.com/images/virtualbox-port-forwarding.png" /&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Select the + icon to create another Nat Network.
This will automatically create a Nat Network named NatNetwork1.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Select the tool icon to modify NatNetwork1.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Rename the network to Public and change the Network CIDR to
203.0.113.0/24. Uncheck the Supports DHCP box. Select OK to
save your changes:&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="VirtualBox Public Network" src="https://s3.amazonaws.com/madorn.com/images/virtualbox-public.png" /&gt;
&lt;/div&gt;
&lt;div class="note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;The gateway for the Public network is 203.0.113.1.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;You should now have two VirtualBox Nat Networks: Management and Public.
Select OK to save your changes:&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="VirtualBox Nat Networks Complete" src="https://s3.amazonaws.com/madorn.com/images/virtualbox-nat-networks-complete.png" /&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class="section" id="download-operating-system-iso"&gt;
&lt;h2&gt;Download Operating System ISO&lt;/h2&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Navigate to the downloads pages for the operating system
to be installed.&lt;/li&gt;
&lt;li&gt;Download ISO.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class="section" id="create-the-controller-virtual-machine"&gt;
&lt;h2&gt;Create the Controller Virtual Machine&lt;/h2&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p class="first"&gt;From the VirtualBox toolbar, select the New button.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Type Controller in the Name section. The type is Linux.
Select the version of Operating System you are installing:&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="VirtualBox New Controller - Ubuntu" src="https://s3.amazonaws.com/madorn.com/images/virtualbox-newcontroller-ubuntu.png" /&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Set the memory allocation to 2048 MB:&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="VirtualBox Memory" src="https://s3.amazonaws.com/madorn.com/images/virtualbox-memory.png" /&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Select VDI (VirtualBox Disk Image).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Select Dynamically Allocated and size 5GB:&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="VirtualBox Virtual Disk" src="https://s3.amazonaws.com/madorn.com/images/virtualbox-controller-vdi.png" /&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class="section" id="modify-controller-virtual-machine-settings"&gt;
&lt;h2&gt;Modify Controller Virtual Machine Settings&lt;/h2&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p class="first"&gt;Highlight the controller virtual machine and click the Settings
button in the VirtualBox toolbar.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Click the System icon and click on the Acceleration tab.
Ensure Paravirtualzation Inteface is Default and Enable VT-x/AMD-V
and Enable Nested Paging are checked:&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="VirtualBox Controller Accleration" src="https://s3.amazonaws.com/madorn.com/images/virtualbox-controller-acceleration.png" /&gt;
&lt;/div&gt;
&lt;div class="note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;If the Acceleration tab is grayed out, enable
Virtualization Technology (Intel VTx or AMD-V) in the host
machine's BIOS.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Select the Storage icon. Select the cd-rom icon titled Empty.
In the Attributes section on the right, select the cd-rom icon and
select Choose Virtual Optical Disk File from the drop down.
Select your operating system iso:&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="VirtualBox Controller ISO" src="https://s3.amazonaws.com/madorn.com/images/virtualbox-controller-iso.png" /&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Select the Network icon and click on the Adapter 1 tab.
Select Nat Network from the Attached to section.
In the Name section, select Management:&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="VirtualBox Controller Adapter 1" src="https://s3.amazonaws.com/madorn.com/images/virtualbox-controller-adapter1.png" /&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Select the Adapter 2 tab and ensure Enable Network Adapter is checked.
Select Nat Network from the Attached to section.
In the Name section, select Public.  Select OK to save your settings:&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="VirtualBox Controller Adapter 2" src="https://s3.amazonaws.com/madorn.com/images/virtualbox-controller-adapter2.png" /&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class="section" id="start-and-install-controller-virtual-machine"&gt;
&lt;h2&gt;Start and Install Controller Virtual Machine&lt;/h2&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Highlight the controller virtual machine and select the Start button.
The virtual machine will begin to boot.&lt;/li&gt;
&lt;li&gt;Follow the installation instructions for the operating system.
Ensure SSH is installed and enabled.&lt;/li&gt;
&lt;li&gt;Refer to &lt;a class="reference external" href="http://docs.openstack.org/liberty/install-guide-ubuntu/environment-networking.html"&gt;Host Networking&lt;/a&gt;    section of the Install Guide for instructions on configuring the Management and Public interfaces
for the controller node.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class="section" id="create-the-compute-virtual-machine"&gt;
&lt;h2&gt;Create the Compute Virtual Machine&lt;/h2&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p class="first"&gt;From the VirtualBox toolbar, click the New button.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Type Compute in the Name section.  The type is Linux.
Select the version of Operating System you are installing:&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="VirtualBox New Compute - Ubuntu" src="https://s3.amazonaws.com/madorn.com/images/virtualbox-newcompute-ubuntu.png" /&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Set the memory allocation to 2048 MB:&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="VirtualBox Memory" src="https://s3.amazonaws.com/madorn.com/images/virtualbox-memory.png" /&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Select VDI (VirtualBox Disk Image).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Select Dynamically Allocated and size 10GB:&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="VirtualBox Compute Virtual Disk" src="https://s3.amazonaws.com/madorn.com/images/virtualbox-compute-vdi.png" /&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class="section" id="modify-compute-virtual-machine-settings"&gt;
&lt;h2&gt;Modify Compute Virtual Machine Settings&lt;/h2&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p class="first"&gt;Highlight the controller virtual machine and click the Settings
button in the VirtualBox toolbar.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Click the System icon and click on the Acceleration tab.
Ensure Paravirtualzation Inteface is Default and Enable VT-x/AMD-V
and Enable Nested Paging are checked:&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="VirtualBox Compute Accleration" src="https://s3.amazonaws.com/madorn.com/images/virtualbox-compute-acceleration.png" /&gt;
&lt;/div&gt;
&lt;div class="note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;If the Acceleration tab is grayed out, enable
Virtualization Technology (Intel VTx or AMD-V) in the
host machine's BIOS.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Select the Storage icon. Select the cd-rom icon titled Empty.
In the Attributes section on the right, select the cd-rom icon and
select Choose Virtual Optical Disk File from the drop down.
Select your operating system iso:&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="VirtualBox Compute ISO" src="https://s3.amazonaws.com/madorn.com/images/virtualbox-compute-iso.png" /&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Select the Network icon and click on the Adapter 1 tab.
Select Nat Network from the Attached to section.
In the Name section, select Management:&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="VirtualBox Compute Adapter 1" src="https://s3.amazonaws.com/madorn.com/images/virtualbox-compute-adapter1.png" /&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Select the Adapter 2 tab and ensure Enable Network Adapter is checked.
Select Nat Network from the Attached to section.
In the Name section, select Public.  Select OK to save your settings:&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="VirtualBox ComputeAdapter 2" src="https://s3.amazonaws.com/madorn.com/images/virtualbox-compute-adapter2.png" /&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class="section" id="start-and-install-compute-virtual-machine"&gt;
&lt;h2&gt;Start and Install Compute Virtual Machine&lt;/h2&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Highlight the compute virtual machine and select the start button.
The virtual machine will begin to boot.&lt;/li&gt;
&lt;li&gt;Follow the installation instructions for your specific operating system.&lt;/li&gt;
&lt;li&gt;Refer to &lt;a class="reference external" href="http://docs.openstack.org/liberty/install-guide-ubuntu/environment-networking.html"&gt;Host Networking&lt;/a&gt;    section of the Install Guide for instructions on configuring the Management and Public interfaces
for the controller node.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class="section" id="verify-connectivity"&gt;
&lt;h2&gt;Verify Connectivity&lt;/h2&gt;
&lt;p&gt;Verify SSH connectivity to the controller and compute nodes.&lt;/p&gt;
&lt;div class="note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;This section assumes the network interfaces and name resolution on
controller and compute have been configured per the steps outlined
in &lt;a class="reference external" href="http://docs.openstack.org/liberty/install-guide-ubuntu/environment-networking.html"&gt;Host Networking&lt;/a&gt;
section of the Install Guide.&lt;/p&gt;
&lt;/div&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p class="first"&gt;From terminal software on the host machine, SSH into the controller node:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="gp"&gt;$&lt;/span&gt; ssh root@127.0.0.1 -p 2022
&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;From the controller node, verify ssh connectivity to the compute node:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="gp"&gt;$&lt;/span&gt; ssh root@compute1
&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Dorn</dc:creator><pubDate>Tue, 17 Nov 2015 16:20:00 -0600</pubDate><guid>tag:www.madorn.com,2015-11-17:virtualbox-liberty-install-guide.html</guid><category>virtualbox</category><category>openstack</category><category>liberty</category></item><item><title>RabbitMQ 3.4.3 Guest User Access with OpenStack Kilo</title><link>http://www.madorn.com/rabbitmq-guest-access-kilo.html</link><description>&lt;p&gt;If one attempts to install OpenStack Kilo via the Ubuntu Cloud Archive, you will get Rabbit 3.4.3.&lt;/p&gt;
&lt;p&gt;All RabbitMQ versions after 3.3.0 prohibit the guest user from connecting remotely by default so you must create a config file to allow this.&lt;/p&gt;
&lt;p&gt;Don't use the guest user in a production OpenStack environment.&lt;/p&gt;
&lt;p&gt;If you are setting up OpenStack Kilo for dev/testing purposes do the following:&lt;/p&gt;
&lt;p&gt;Install RabbitMQ-Server:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;apt-get install rabbitmq-server&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Create the config file to allow the guest user to connect from anywhere:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;cat &amp;gt; /etc/rabbitmq/rabbitmq.config &amp;lt;&amp;lt;EOF&lt;/span&gt;
&lt;span class="go"&gt;[{rabbit, [{loopback_users, []}]}].&lt;/span&gt;
&lt;span class="go"&gt;EOF&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Restart RabbitMQ.  Rabbit listens on 5672 by default.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;service rabbitmq-server restart&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;Optional:&lt;/tt&gt;&lt;/p&gt;
&lt;p&gt;Enable the RabbitMQ API for management and monitoring:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;rabbitmq-plugins enable rabbitmq_management&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Restart RabbitMQ.  The API will listen on 15672 by default.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;service rabbitmq-server restart&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Verify that you can authenticate against the RabbitMQ API with u:guest p:guest&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;curl -i -u guest:guest yourip:15672/api/whoami&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Open up a web browser and connect to the Rabbit Management portal at &lt;a class="reference external" href="http://yourip:15672"&gt;http://yourip:15672&lt;/a&gt; with u:guest p:guest.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Dorn</dc:creator><pubDate>Fri, 08 May 2015 19:33:00 -0500</pubDate><guid>tag:www.madorn.com,2015-05-08:rabbitmq-guest-access-kilo.html</guid><category>rabbitmq</category><category>openstack</category><category>kilo</category></item><item><title>Juno Neutron-Server Not Starting</title><link>http://www.madorn.com/juno-neutron-server-not-starting.html</link><description>&lt;p&gt;The neutron-server service behavior in Juno has changed a bit since Icehouse.&lt;/p&gt;
&lt;p&gt;Prior to Juno, when one went to start up neutron-server for the first time, an initial db sync was performed which generates the database schema.&lt;/p&gt;
&lt;p&gt;One who attempts to intall Neutron on Juno without running a neutron-db-manage will no be able to start neutron-server and may see the following error or similar in /var/log/neutron/server.log:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;ProgrammingError: (ProgrammingError) (1146, &amp;quot;Table &amp;#39;neutron.ml2_gre_allocations&amp;#39; doesn&amp;#39;t exist&amp;quot;) &amp;#39;SELECT ml2_gre_allocations.gre_id AS ml2_gre_allocations_gre_id, ml2_gre_allocations.allocated AS ml2_gre_allocations_allocated \nFROM ml2_gre_allocations&amp;#39; ()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To fix the issue, run the following prior to starting neutron-server:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;sudo neutron-db-manage --config-file /etc/neutron/neutron.conf --config-file /etc/neutron/plugins/ml2/ml2_conf.ini upgrade juno&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Dorn</dc:creator><pubDate>Mon, 17 Nov 2014 15:11:00 -0600</pubDate><guid>tag:www.madorn.com,2014-11-17:juno-neutron-server-not-starting.html</guid><category>neutron</category><category>openstack</category><category>juno</category></item><item><title>Installing VMware Tools on Centos7</title><link>http://www.madorn.com/installing-vmwaretools-centos7.html</link><description>&lt;p&gt;If one attempts to install VMware Tools (VMwareTools-9.6.2-1688356) on Centos7 running the 3.10 kernel (i.e. 3.10.0-123.el7.x86_64), you will most likely see the following error:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;In file included from /tmp/modconfig-5vxwsx/vmhgfs-only/inode.c:36:0:&lt;/span&gt;
&lt;span class="go"&gt;/tmp/modconfig-5vxwsx/vmhgfs-only/inode.c: In function ‘HgfsPermission&amp;#39;:&lt;/span&gt;
&lt;span class="go"&gt;/tmp/modconfig-5vxwsx/vmhgfs-only/./shared/compat_dcache.h:57:38: error: ‘struct dentry’ has no member named ‘d_count’&lt;/span&gt;
&lt;span class="gp"&gt;#&lt;/span&gt;define compat_d_count&lt;span class="o"&gt;(&lt;/span&gt;dentry&lt;span class="o"&gt;)&lt;/span&gt; dentry-&amp;gt;d_count
&lt;span class="go"&gt;/tmp/modconfig-5vxwsx/vmhgfs-only/inode.c:1904:23: note: in expansion of macro ‘compat_d_count&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Although most of the features will get installed, one will not have the ability to use VMware Shared Folders for file sharing between guest and host.&lt;/p&gt;
&lt;p&gt;The issue is due to a VMware Tools bug which we can repair via a simple script.  This script will replace a reference to kernel 3.11 with kernel 3.10 and then run the installer with default options for non-interactive installation.&lt;/p&gt;
&lt;p&gt;Verify that you have the following packages installed before running:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;yum -y install kernel-devel gcc dracut make perl&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="gp"&gt;#&lt;/span&gt;!/bin/bash

&lt;span class="go"&gt;mkdir /tmp/vmfusion&lt;/span&gt;
&lt;span class="go"&gt;mkdir /tmp/vmfusion-archive&lt;/span&gt;
&lt;span class="go"&gt;mount /dev/sr0 /tmp/vmfusion&lt;/span&gt;
&lt;span class="go"&gt;tar xzfv /tmp/vmfusion/VMwareTools-*.tar.gz -C /tmp/vmfusion-archive&lt;/span&gt;
&lt;span class="go"&gt;tar xfv /tmp/vmfusion-archive/vmware-tools-distrib/lib/modules/source/vmhgfs.tar -C /tmp/vmfusion-archive/vmware-tools-distrib/lib/modules/source/&lt;/span&gt;
&lt;span class="go"&gt;sed -i -e &amp;#39;/KERNEL_VERSION/{s/3, 11, 0/3, 10, 0/}&amp;#39; /tmp/vmfusion-archive/vmware-tools-distrib/lib/modules/source/vmhgfs-only/shared/compat_dcache.h&lt;/span&gt;
&lt;span class="go"&gt;rm -rf /tmp/vmfusion-archive/vmware-tools-distrib/lib/modules/source/vmhgfs.tar&lt;/span&gt;
&lt;span class="go"&gt;tar cfv /tmp/vmfusion-archive/vmware-tools-distrib/lib/modules/source/vmhgfs.tar -C /tmp/vmfusion-archive/vmware-tools-distrib/lib/modules/source/ vmhgfs-only&lt;/span&gt;
&lt;span class="go"&gt;rm -rf /tmp/vmfusion-archive/vmware-tools-distrib/lib/modules/source/vmhgfs-only/&lt;/span&gt;
&lt;span class="go"&gt;/tmp/vmfusion-archive/vmware-tools-distrib/vmware-install.pl --default&lt;/span&gt;
&lt;span class="go"&gt;umount /tmp/vmfusion&lt;/span&gt;
&lt;span class="go"&gt;rm -rf  /tmp/vmfusion&lt;/span&gt;
&lt;span class="go"&gt;rm -rf  /tmp/vmfusion-archive&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you exerienced this issue while attempting to build a Vagrant box with &lt;a class="reference external" href="http://www.packer.io/"&gt;Packer&lt;/a&gt;, here is a shell provisioner script that I've tested and seems to be working fine: &lt;a class="reference external" href="https://github.com/madorn/packer/blob/master/scripts/common/vmtools.sh"&gt;vmtools.sh&lt;/a&gt;&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Dorn</dc:creator><pubDate>Sun, 16 Nov 2014 15:11:00 -0600</pubDate><guid>tag:www.madorn.com,2014-11-16:installing-vmwaretools-centos7.html</guid><category>vmware fusion</category><category>centos7</category><category>packer</category></item><item><title>Nic Bonding in Ubuntu with VirtualBox</title><link>http://www.madorn.com/ubuntu-nic-bonding-with-virtualbox.html</link><description>&lt;p&gt;I recently needed to setup nic bonding in Virtualbox to demo software intended to be deployed in a nic bonded environment.&lt;/p&gt;
&lt;p&gt;When doing this in VirtualBox, one needs to activiate the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;bond-fail-over-mac&lt;/span&gt;&lt;/tt&gt; parameter to prevent issues with host-to-vm communication.&lt;/p&gt;
&lt;p&gt;Here's the VirtualbBox network config:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;Name:            node1&lt;/span&gt;
&lt;span class="go"&gt;Guest OS:        Ubuntu (64 bit)&lt;/span&gt;
&lt;span class="go"&gt;UUID:            cc550cfd-60b9-427c-b09d-0a2e0dad932b&lt;/span&gt;
&lt;span class="go"&gt;NIC 1:           MAC: 08002760454A, Attachment: Host-only Interface &amp;#39;vboxnet0&amp;#39;&lt;/span&gt;
&lt;span class="go"&gt;NIC 2:           MAC: 080027A206C5, Attachment: Host-only Interface &amp;#39;vboxnet0&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here is the Ubuntu config in /etc/network/interfaces.  Notice the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;bond-fail-over-mac&lt;/span&gt;&lt;/tt&gt; flag.  This will ensure that only one of the nic slaves is assigned the bond0 mac address at a given time, thus resolving any host-to-vm routing issues.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="gp"&gt;#&lt;/span&gt; The loopback network interface
&lt;span class="go"&gt;auto lo&lt;/span&gt;
&lt;span class="go"&gt;iface lo inet loopback&lt;/span&gt;

&lt;span class="gp"&gt;#&lt;/span&gt; Physical interface 0
&lt;span class="go"&gt;auto eth0&lt;/span&gt;
&lt;span class="go"&gt;iface eth0 inet manual&lt;/span&gt;
&lt;span class="go"&gt;bond-master bond0&lt;/span&gt;
&lt;span class="go"&gt;bond-primary eth0&lt;/span&gt;

&lt;span class="gp"&gt;#&lt;/span&gt; Physical interface 1
&lt;span class="go"&gt;auto eth1&lt;/span&gt;
&lt;span class="go"&gt;iface eth1 inet manual&lt;/span&gt;
&lt;span class="go"&gt;bond-master bond0&lt;/span&gt;

&lt;span class="gp"&gt;#&lt;/span&gt; Bond interface 0: eth0 &lt;span class="o"&gt;(&lt;/span&gt;vboxnet0&lt;span class="o"&gt;)&lt;/span&gt;, eth2 &lt;span class="o"&gt;(&lt;/span&gt;vboxnet0&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="go"&gt;auto bond0&lt;/span&gt;
&lt;span class="go"&gt;iface bond0 inet static&lt;/span&gt;
&lt;span class="go"&gt;bond-slaves none&lt;/span&gt;
&lt;span class="go"&gt;bond-mode active-backup&lt;/span&gt;
&lt;span class="go"&gt;bond-miimon 100&lt;/span&gt;
&lt;span class="go"&gt;bond-downdelay 200&lt;/span&gt;
&lt;span class="go"&gt;bond-updelay 200&lt;/span&gt;
&lt;span class="go"&gt;bond-fail-over-mac 1&lt;/span&gt;
&lt;span class="go"&gt;address 192.168.56.56&lt;/span&gt;
&lt;span class="go"&gt;netmask 255.255.255.0&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Dorn</dc:creator><pubDate>Mon, 06 Oct 2014 11:50:00 -0500</pubDate><guid>tag:www.madorn.com,2014-10-06:ubuntu-nic-bonding-with-virtualbox.html</guid><category>virtualbox</category><category>ubuntu</category></item><item><title>Configure Keystone to Utilize Apache</title><link>http://www.madorn.com/configure-keystone-apache.html</link><description>&lt;p&gt;Keystone and many current OpenStack API components run in an &lt;a class="reference external" href="http://eventlet.net/"&gt;Eventlet&lt;/a&gt; based http server.  Eventlet is designed to perform well in networked environments and handles everything in a single thread.&lt;/p&gt;
&lt;p&gt;The developers responsible for the Keystone project have recently recommended using Apache (with the mod_wsgi module) as a front-end rather than the traditional “Keystone” Eventlet-based process.&lt;/p&gt;
&lt;p&gt;By using Apache as the front-end for Keystone, one gains better performance due to Apache’s ability to do multithreading.  One can also take advantage of the variety of http server modules currently available for Apache.  One popular module, &lt;a class="reference external" href="http://shibboleth.net"&gt;Shibboleth&lt;/a&gt;, provides the ability to use one set of credentials to authenticate against multiple OpenStack clouds (more info &lt;a class="reference external" href="http://docs.openstack.org/developer/keystone/configure_federation.html"&gt;here&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Here is a straight forward guide on how to setup Keystone to utilize Apache in your existing OpenStack deployment.&lt;/p&gt;
&lt;p&gt;Stop Keystone Service (It is not necessary to run this service with this config)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;sudo service keystone stop&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Install Apache&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;sudo apt-get install -y apache2&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Install Python WSGI module for Apache&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;sudo apt-get install -y libapache2-mod-wsgi&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Make cgi-bin directory for Keystone&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;sudo mkdir -p /var/www/cgi-bin/keystone/&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Create Python script for Apache (admin and main)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;( cat | sudo tee /var/www/cgi-bin/keystone/admin /var/www/cgi-bin/keystone/main ) &amp;lt;&amp;lt;EOF&lt;/span&gt;
&lt;span class="go"&gt;import logging&lt;/span&gt;
&lt;span class="go"&gt;import os&lt;/span&gt;

&lt;span class="go"&gt;from paste import deploy&lt;/span&gt;

&lt;span class="go"&gt;from keystone.openstack.common import gettextutils&lt;/span&gt;
&lt;span class="gp"&gt;#&lt;/span&gt; NOTE&lt;span class="o"&gt;(&lt;/span&gt;dstanek&lt;span class="o"&gt;)&lt;/span&gt;: gettextutils.enable_lazy&lt;span class="o"&gt;()&lt;/span&gt; must be called before
&lt;span class="gp"&gt;#&lt;/span&gt; gettextutils._&lt;span class="o"&gt;()&lt;/span&gt; is called to ensure it has the desired lazy &lt;span class="c"&gt;#lookup behavior. This includes cases, like keystone.exceptions, #where gettextutils._() is called at import time.&lt;/span&gt;
&lt;span class="go"&gt;gettextutils.enable_lazy()&lt;/span&gt;

&lt;span class="go"&gt;from keystone.common import dependency&lt;/span&gt;
&lt;span class="go"&gt;from keystone.common import environment&lt;/span&gt;
&lt;span class="go"&gt;from keystone.common import sql&lt;/span&gt;
&lt;span class="go"&gt;from keystone import config&lt;/span&gt;
&lt;span class="go"&gt;from keystone.openstack.common import log&lt;/span&gt;
&lt;span class="go"&gt;from keystone import service&lt;/span&gt;


&lt;span class="go"&gt;CONF = config.CONF&lt;/span&gt;

&lt;span class="go"&gt;config.configure()&lt;/span&gt;
&lt;span class="go"&gt;sql.initialize()&lt;/span&gt;
&lt;span class="go"&gt;config.set_default_for_default_log_levels()&lt;/span&gt;

&lt;span class="go"&gt;CONF(project=&amp;#39;keystone&amp;#39;)&lt;/span&gt;
&lt;span class="go"&gt;config.setup_logging()&lt;/span&gt;

&lt;span class="go"&gt;environment.use_stdlib()&lt;/span&gt;
&lt;span class="go"&gt;name = os.path.basename(__file__)&lt;/span&gt;

&lt;span class="go"&gt;if CONF.debug:&lt;/span&gt;
&lt;span class="go"&gt;CONF.log_opt_values(log.getLogger(CONF.prog), logging.DEBUG)&lt;/span&gt;


&lt;span class="go"&gt;drivers = service.load_backends()&lt;/span&gt;

&lt;span class="gp"&gt;#&lt;/span&gt; NOTE&lt;span class="o"&gt;(&lt;/span&gt;ldbragst&lt;span class="o"&gt;)&lt;/span&gt;: &lt;span class="s1"&gt;&amp;#39;application&amp;#39;&lt;/span&gt; is required in this context by WSGI spec.
&lt;span class="gp"&gt;#&lt;/span&gt; The following is a reference to Python Paste Deploy documentation
&lt;span class="gp"&gt;#&lt;/span&gt; http://pythonpaste.org/deploy/
&lt;span class="go"&gt;application = deploy.loadapp(&amp;#39;config:%s&amp;#39; % config.find_paste_config(),&lt;/span&gt;
&lt;span class="go"&gt;                     name=name)&lt;/span&gt;

&lt;span class="go"&gt;dependency.resolve_future_dependencies()&lt;/span&gt;
&lt;span class="go"&gt;EOF&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Configure Apache to listen on ports 35357(admin) and 5000(main)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;( cat | sudo tee /etc/apache2/ports.conf ) &amp;lt;&amp;lt;EOF&lt;/span&gt;
&lt;span class="go"&gt;Listen 35357&lt;/span&gt;
&lt;span class="go"&gt;Listen 5000&lt;/span&gt;
&lt;span class="go"&gt;EOF&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Configure Keystone Virtual Hosts&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;( cat | sudo tee /etc/apache2/sites-available/keystone-httpd.conf ) &amp;lt;&amp;lt;EOF&lt;/span&gt;
&lt;span class="go"&gt;WSGIDaemonProcess keystone user=keystone group=nogroup processes=3 threads=10&lt;/span&gt;

&lt;span class="go"&gt;&amp;lt;VirtualHost *:5000&amp;gt;&lt;/span&gt;
&lt;span class="go"&gt;    LogLevel  info&lt;/span&gt;
&lt;span class="go"&gt;    ErrorLog  /var/log/keystone/keystone-apache-error.log&lt;/span&gt;
&lt;span class="go"&gt;    CustomLog /var/log/keystone/ssl_access.log combined&lt;/span&gt;
&lt;span class="go"&gt;    Options +FollowSymLinks&lt;/span&gt;

&lt;span class="gp"&gt;#&lt;/span&gt;SSLEngine on
&lt;span class="gp"&gt;#&lt;/span&gt;SSLCertificateFile /etc/ssl/certs/mycert.pem
&lt;span class="gp"&gt;#&lt;/span&gt;SSLCertificateKeyFile /etc/ssl/private/mycert.key
&lt;span class="gp"&gt;#&lt;/span&gt;SSLVerifyClient optional
&lt;span class="gp"&gt;#&lt;/span&gt;SSLVerifyDepth 10
&lt;span class="gp"&gt;#&lt;/span&gt;SSLProtocol all -SSLv2
&lt;span class="gp"&gt;#&lt;/span&gt;SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
&lt;span class="gp"&gt;#&lt;/span&gt;SSLOptions +StdEnvVars +ExportCertData

&lt;span class="go"&gt;    WSGIScriptAlias /  /var/www/cgi-bin/keystone/main&lt;/span&gt;
&lt;span class="go"&gt;    WSGIProcessGroup keystone&lt;/span&gt;
&lt;span class="go"&gt;&amp;lt;/VirtualHost&amp;gt;&lt;/span&gt;

&lt;span class="go"&gt;&amp;lt;VirtualHost *:35357&amp;gt;&lt;/span&gt;
&lt;span class="go"&gt;    LogLevel  info&lt;/span&gt;
&lt;span class="go"&gt;    ErrorLog  /var/log/keystone/keystone-apache-error.log&lt;/span&gt;
&lt;span class="go"&gt;    CustomLog /var/log/keystone/ssl_access.log combined&lt;/span&gt;
&lt;span class="go"&gt;    Options +FollowSymLinks&lt;/span&gt;

&lt;span class="gp"&gt;#&lt;/span&gt;SSLEngine on
&lt;span class="gp"&gt;#&lt;/span&gt;SSLCertificateFile /etc/ssl/certs/mycert.pem
&lt;span class="gp"&gt;#&lt;/span&gt;SSLCertificateKeyFile /etc/ssl/private/mycert.key
&lt;span class="gp"&gt;#&lt;/span&gt;SSLVerifyClient optional
&lt;span class="gp"&gt;#&lt;/span&gt;SSLVerifyDepth 10
&lt;span class="gp"&gt;#&lt;/span&gt;SSLProtocol all -SSLv2
&lt;span class="gp"&gt;#&lt;/span&gt;SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
&lt;span class="gp"&gt;#&lt;/span&gt;SSLOptions +StdEnvVars +ExportCertData

&lt;span class="go"&gt;    WSGIScriptAlias / /var/www/cgi-bin/keystone/admin&lt;/span&gt;
&lt;span class="go"&gt;    WSGIProcessGroup keystone&lt;/span&gt;
&lt;span class="go"&gt;&amp;lt;/VirtualHost&amp;gt;&lt;/span&gt;
&lt;span class="go"&gt;EOF&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Enable Keystone site&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;sudo a2ensite keystone-httpd&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Reload Apache&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;sudo service apache2 reload&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Dorn</dc:creator><pubDate>Fri, 22 Aug 2014 12:11:00 -0500</pubDate><guid>tag:www.madorn.com,2014-08-22:configure-keystone-apache.html</guid><category>openstack</category><category>keystone</category></item><item><title>Adjust File Injection Upon Boot Quota</title><link>http://www.madorn.com/quota-injected-files.html</link><description>&lt;p&gt;One way to customize the personality of an instance is by injecting data into it upon boot&lt;/p&gt;
&lt;p&gt;This would be handy for updating &lt;tt class="docutils literal"&gt;/etc/passwd&lt;/tt&gt; or &lt;tt class="docutils literal"&gt;/etc/group&lt;/tt&gt; with customized pre-built files.&lt;/p&gt;
&lt;p&gt;Here is an example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;nova boot --image cirros-qcow2 --flavor m1.tiny  --file /etc/passwd=/your/local/path/passwd MyInstance&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;By default, the Icehouse release of OpenStack can support up 5 files:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;nova boot --image cirros-qcow2 --flavor m1.tiny  --file /home/cirros/myfirstfile=myfirstfile --file /home/cirros/mysecondfile=mysecondfile --file /home/cirros/mythirdfile=mythirdfile --file /home/cirros/myfourthfile=myfourthfile --file /home/cirros/myfifthfile=myfifthfile MyInstance&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you would like to inject more than 5 files, update your &lt;tt class="docutils literal"&gt;/etc/nova/nova.conf&lt;/tt&gt; with the following flag:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;quota_injected_files=50&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Restart &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;nova-compute&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;sudo service nova-compute restart&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;50 appears to the max amount of files it will allow you to pass.&lt;/p&gt;
&lt;p&gt;Additional info about file injection:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Max size per file is 255 bytes.&lt;/li&gt;
&lt;li&gt;One can only inject text files.  Binary or zip files won't work.&lt;/li&gt;
&lt;li&gt;During file injection, any existing files that match specified files are renamed to include .bak extension appended with a time stamp.&lt;/li&gt;
&lt;li&gt;Once written, the files have 0440 permissions.&lt;/li&gt;
&lt;/ul&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Dorn</dc:creator><pubDate>Thu, 29 May 2014 16:03:00 -0500</pubDate><guid>tag:www.madorn.com,2014-05-29:quota-injected-files.html</guid><category>openstack</category><category>nova</category></item><item><title>Glance Direct URL Metadata</title><link>http://www.madorn.com/glance-direct-url-metadata.html</link><description>&lt;p&gt;OpenStack Havana comes with Glance's v1 and v2 API.&lt;/p&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;python-glanceclient&lt;/span&gt;&lt;/tt&gt; fully supports v1 while support for v2 is in progress.&lt;/p&gt;
&lt;p&gt;v2 adds some cool stuff including:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;The ability to share images with specific users or projects&lt;/li&gt;
&lt;li&gt;Image tagging&lt;/li&gt;
&lt;li&gt;Schemas: Gets a JSON-schema document that represents an image or image-entity&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;One particular useful feature is direct-url metadata which allows one to see where a particular image resides.&lt;/p&gt;
&lt;p&gt;Here's how to enable it:&lt;/p&gt;
&lt;div class="section" id="modify-etc-glance-glance-api-conf"&gt;
&lt;h2&gt;Modify /etc/glance/glance-api.conf&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;show_image_direct_url = True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="restart-glance-services"&gt;
&lt;h2&gt;Restart Glance Services&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;service glance-api restart&lt;/span&gt;
&lt;span class="go"&gt;service glance-registry restart&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="utilize-v2-api-to-display-direct-url"&gt;
&lt;h2&gt;Utilize v2 API to Display Direct-Url&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;glance --os-image-api-version 2 image-show b9f44c5c-fc27-4891-b246-2df086f32ed7&lt;/span&gt;

&lt;span class="go"&gt;+------------------+--------------------------------------------------------------------+&lt;/span&gt;
&lt;span class="go"&gt;| Property         | Value                                                              |&lt;/span&gt;
&lt;span class="go"&gt;+------------------+--------------------------------------------------------------------+&lt;/span&gt;
&lt;span class="go"&gt;| checksum         | 4296b4c64655746fd44b7239fb66cf07                                   |&lt;/span&gt;
&lt;span class="go"&gt;| container_format | bare                                                               |&lt;/span&gt;
&lt;span class="go"&gt;| created_at       | 2014-03-07T23:30:00Z                                               |&lt;/span&gt;
&lt;span class="go"&gt;| direct_url       | file:///var/lib/glance/images/b9f44c5c-fc27-4891-b246-2df086f32ed7 |&lt;/span&gt;
&lt;span class="go"&gt;| disk_format      | qcow2                                                              |&lt;/span&gt;
&lt;span class="go"&gt;| id               | b9f44c5c-fc27-4891-b246-2df086f32ed7                               |&lt;/span&gt;
&lt;span class="go"&gt;| min_disk         | 0                                                                  |&lt;/span&gt;
&lt;span class="go"&gt;| min_ram          | 0                                                                  |&lt;/span&gt;
&lt;span class="go"&gt;| name             | cirros-qcow2                                                       |&lt;/span&gt;
&lt;span class="go"&gt;| protected        | False                                                              |&lt;/span&gt;
&lt;span class="go"&gt;| size             | 13139456                                                           |&lt;/span&gt;
&lt;span class="go"&gt;| status           | active                                                             |&lt;/span&gt;
&lt;span class="go"&gt;| tags             | []                                                                 |&lt;/span&gt;
&lt;span class="go"&gt;| updated_at       | 2014-03-07T23:30:00Z                                               |&lt;/span&gt;
&lt;span class="go"&gt;| visibility       | public                                                             |&lt;/span&gt;
&lt;span class="go"&gt;+------------------+--------------------------------------------------------------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Dorn</dc:creator><pubDate>Fri, 07 Mar 2014 19:52:00 -0600</pubDate><guid>tag:www.madorn.com,2014-03-07:glance-direct-url-metadata.html</guid><category>openstack</category><category>glance</category></item><item><title>Intro to Keystone v3 API</title><link>http://www.madorn.com/keystone-v3-api.html</link><description>&lt;p&gt;The Keystone v3 API is included with OpenStack Grizzly &amp;amp; Havana but the Python-KeystoneClient does not expose v3 functionality at this time.  Any interaction with the v3 API needs to be done directly via curl or tool of your choice.  The term &lt;strong&gt;tenant&lt;/strong&gt; is now officially replaced with &lt;strong&gt;project&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The Keystone v3 API introduces two significant Keystone features/concepts:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Domains&lt;/li&gt;
&lt;li&gt;Groups&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let's first take a look at the Keystone v2 model.&lt;/p&gt;
&lt;div class="section" id="example-org-structure-utilizing-keystone-v2-api"&gt;
&lt;h2&gt;Example Org Structure Utilizing Keystone v2 API&lt;/h2&gt;
&lt;img alt="" src="https://s3.amazonaws.com/madorn.com/images/Screen%20Shot%202014-01-08%20at%201.58.09%20PM.png" /&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;A user can reside in multiple departments yet have a different role in that department.&lt;/li&gt;
&lt;li&gt;SandraD is a Sysadmin in Aerospace, but not in Biology.  In the CompSci project, she has the Support role, but not the Sysadmin role.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="example-of-v3-api-domains"&gt;
&lt;h2&gt;Example of v3 API &amp;quot;Domains&amp;quot;&lt;/h2&gt;
&lt;img alt="" src="https://s3.amazonaws.com/madorn.com/images/Screen%20Shot%202014-01-08%20at%201.04.26%20PM.png" /&gt;
&lt;p&gt;v3 now introduces true multi-tenancy with the use of domains.  As we can see the domain acts as a high level container for projects.&lt;/p&gt;
&lt;p&gt;With domains, a cloud customer can be the owner of the domain.  They can then create additional users, groups, and roles to be used within their specified domain.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="example-of-v3-api-groups"&gt;
&lt;h2&gt;Example of v3 API &amp;quot;Groups&amp;quot;&lt;/h2&gt;
&lt;p&gt;A group is simply a container representing a collection of users.  Rather than assign a role directly to user/project, a domain owner can assign a role to a group, and then add users to that group.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;A role can be assigned to a &lt;strong&gt;domain&lt;/strong&gt; on a group or a &lt;strong&gt;project&lt;/strong&gt; on a group.&lt;/li&gt;
&lt;/ul&gt;
&lt;img alt="" src="https://s3.amazonaws.com/madorn.com/images/ss.png" /&gt;
&lt;p&gt;In this example:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;JohnB will authenticate with Keystone, obtain the Sysadmin role and belong to Biology, Aerospace, and Compsci projects.&lt;/li&gt;
&lt;li&gt;LisaD will authenticate with Keystone, obtain the Engineer role and only belong to the Compsci project.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Other Info:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Groups are &lt;strong&gt;optional&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The domain name and role name is &lt;strong&gt;globally unique across all domains&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The username, project, and group name are &lt;strong&gt;only unique to the owning domain&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="new-v3-commands"&gt;
&lt;h2&gt;New v3 Commands&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Create a group&lt;/li&gt;
&lt;li&gt;Delete a group&lt;/li&gt;
&lt;li&gt;Update a group (change its name or description)&lt;/li&gt;
&lt;li&gt;Add a user to a group&lt;/li&gt;
&lt;li&gt;Remove a user from a group&lt;/li&gt;
&lt;li&gt;List group members&lt;/li&gt;
&lt;li&gt;List groups for a user&lt;/li&gt;
&lt;li&gt;Assign a role on a tenant to a group&lt;/li&gt;
&lt;li&gt;Assign a role on a domain to a group&lt;/li&gt;
&lt;li&gt;Query role assignments to groups&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="interacting-with-keystone-v3-api"&gt;
&lt;h2&gt;Interacting with Keystone v3 API&lt;/h2&gt;
&lt;p&gt;Adam Young's blog has some examples of interacting with v3:  &lt;a class="reference external" href="http://adam.younglogic.com/2013/09/keystone-v3-api-examples/"&gt;http://adam.younglogic.com/2013/09/keystone-v3-api-examples/&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Dorn</dc:creator><pubDate>Mon, 20 Jan 2014 22:04:00 -0600</pubDate><guid>tag:www.madorn.com,2014-01-20:keystone-v3-api.html</guid><category>openstack</category><category>keystone</category></item><item><title>Resize a Running Instance on a Single Compute Node</title><link>http://www.madorn.com/resize-on-single-compute.html</link><description>&lt;p&gt;One can resize a running instance in OpenStack by running the following nova command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;nova resize --poll &amp;lt;server&amp;gt; &amp;lt;flavor&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The default behavior of this command is to invoke the nova scheduler to determine the best compute node for the resized instance.  If there is only one compute node in the environment, the resize will fail.&lt;/p&gt;
&lt;p&gt;We need to tell nova to allow resizing on the same host by modifying &lt;tt class="docutils literal"&gt;/etc/nova/nova.conf&lt;/tt&gt; .&lt;/p&gt;
&lt;div class="section" id="modify-etc-nova-nova-conf"&gt;
&lt;h2&gt;Modify /etc/nova/nova.conf&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;allow_resize_to_same_host=True&lt;/span&gt;
&lt;span class="go"&gt;scheduler_default_filters=AllHostsFilter&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;By changing the default nova scheduler filter to &lt;tt class="docutils literal"&gt;AllHostsFilter&lt;/tt&gt; , all compute hosts will be available and unfiltered.  It is not a good idea to keep this setting in a multi-compute environment.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="restart-services"&gt;
&lt;h2&gt;Restart Services&lt;/h2&gt;
&lt;p&gt;After making the changes to nova.conf, restart scheduler and compute services:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;service nova-scheduler restart&lt;/span&gt;
&lt;span class="go"&gt;service nova-compute restart&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="resize-confirm"&gt;
&lt;h2&gt;Resize Confirm&lt;/h2&gt;
&lt;p&gt;After resizing the instance, the status will change to &lt;tt class="docutils literal"&gt;VERIFY_RESIZE&lt;/tt&gt; .  One will see two copies of the instance in &lt;tt class="docutils literal"&gt;/var/lib/nova/instances&lt;/tt&gt; :  the &lt;strong&gt;original&lt;/strong&gt; and the &lt;strong&gt;resized&lt;/strong&gt;.  Run the following command to verify the resize and delete the original instance:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;nova resize-confirm &amp;lt;server&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Dorn</dc:creator><pubDate>Wed, 18 Dec 2013 20:22:00 -0600</pubDate><guid>tag:www.madorn.com,2013-12-18:resize-on-single-compute.html</guid><category>openstack</category><category>nova</category></item><item><title>Quickly Delete a Large Cloud Files Container</title><link>http://www.madorn.com/quickly-delete-cloud-files-container.html</link><description>&lt;p&gt;As you probably know, one cannot delete a Cloud Files container without deleting all the objects inside it first.  This can take quite a bit of time if you have many objects in your container.&lt;/p&gt;
&lt;p&gt;I had to delete about 30GB of data in a container and it was taking forever.  I discovered a script by &lt;a class="reference external" href="http://onelx.com/blog/2013/9/14/delete-cloudfiles-container-with-python"&gt;Fernando Florez&lt;/a&gt; which utilizes the Python Gevent library and Pyrax SDK to do a speedy container deletion.  The Gevent library contains Greenlet which does micro-threading.  Executing this script sends deletion requests to Cloud Files concurrently, drastically reducing total deletion time.&lt;/p&gt;
&lt;p&gt;This method assumes you are utilizing a Python virtual environment and that you have &lt;strong&gt;activated&lt;/strong&gt; it.&lt;/p&gt;
&lt;div class="section" id="install-pyrax"&gt;
&lt;h2&gt;Install Pyrax&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;pip install pyrax&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="install-libevent"&gt;
&lt;h2&gt;Install Libevent&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;curl -L -O https://github.com/downloads/libevent/libevent/libevent-2.0.21-stable.tar.gz&lt;/span&gt;
&lt;span class="go"&gt;tar xzf libevent-2.0.21-stable.tar.gz&lt;/span&gt;
&lt;span class="go"&gt;cd libevent-2.0.21-stable&lt;/span&gt;
&lt;span class="go"&gt;./configure --prefix=&amp;quot;$VIRTUAL_ENV&amp;quot;&lt;/span&gt;
&lt;span class="go"&gt;make &amp;amp;&amp;amp; make install&lt;/span&gt;
&lt;span class="go"&gt;cd $VIRTUAL_ENV/..&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="install-greenlet-and-gevent"&gt;
&lt;h2&gt;Install Greenlet and Gevent&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;pip install greenlet&lt;/span&gt;
&lt;span class="go"&gt;pip install gevent --global-option &amp;quot;-L$VIRTUAL_ENV/lib&amp;quot;  --global-option &amp;quot;-I$VIRTUAL_ENV/include&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="test-gevent"&gt;
&lt;h2&gt;Test Gevent&lt;/h2&gt;
&lt;p&gt;Enter a Python interactive shell and try to import Gevent.  If you do not get any errors you should be good.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;python&lt;/span&gt;
&lt;span class="go"&gt;import gevent&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="delete-all-objects-in-container"&gt;
&lt;h2&gt;Delete All Objects in Container&lt;/h2&gt;
&lt;p&gt;Be sure to specify your region, i.e. DFW, ORD, etc.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;from gevent import monkey&lt;/span&gt;
&lt;span class="go"&gt;from gevent.pool import Pool&lt;/span&gt;
&lt;span class="go"&gt;from gevent import Timeout&lt;/span&gt;
&lt;span class="go"&gt;monkey.patch_all()&lt;/span&gt;
&lt;span class="go"&gt;import pyrax&lt;/span&gt;

&lt;span class="go"&gt;if __name__ == &amp;#39;__main__&amp;#39;:&lt;/span&gt;
&lt;span class="go"&gt;pool = Pool(100)&lt;/span&gt;
&lt;span class="go"&gt;pyrax.set_setting(&amp;#39;identity_type&amp;#39;, &amp;#39;rackspace&amp;#39;)&lt;/span&gt;
&lt;span class="go"&gt;pyrax.set_setting(&amp;#39;verify_ssl&amp;#39;, False)&lt;/span&gt;
&lt;span class="go"&gt;pyrax.set_setting(&amp;quot;region&amp;quot;, &amp;#39;region&amp;#39;)&lt;/span&gt;
&lt;span class="go"&gt;pyrax.set_credentials(&amp;#39;username&amp;#39;, &amp;#39;api_key&amp;#39;)&lt;/span&gt;

&lt;span class="go"&gt;cf = pyrax.cloudfiles&lt;/span&gt;
&lt;span class="go"&gt;container = cf.get_container(&amp;#39;container_name&amp;#39;)&lt;/span&gt;
&lt;span class="go"&gt;objects = container.get_objects(full_listing=True)&lt;/span&gt;
&lt;span class="go"&gt;def delete_object(obj):&lt;/span&gt;
&lt;span class="gp"&gt;#&lt;/span&gt; added timeout of 5 seconds just in &lt;span class="k"&gt;case&lt;/span&gt;
&lt;span class="go"&gt;with Timeout(5, False):&lt;/span&gt;
&lt;span class="go"&gt;          try:&lt;/span&gt;
&lt;span class="go"&gt;              obj.delete()&lt;/span&gt;
&lt;span class="go"&gt;          except:&lt;/span&gt;
&lt;span class="go"&gt;              pass&lt;/span&gt;
&lt;span class="go"&gt;  for obj in objects:&lt;/span&gt;
&lt;span class="go"&gt;      pool.spawn(delete_object, obj)&lt;/span&gt;
&lt;span class="go"&gt;  pool.join()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Dorn</dc:creator><pubDate>Tue, 29 Oct 2013 02:44:00 -0500</pubDate><guid>tag:www.madorn.com,2013-10-29:quickly-delete-cloud-files-container.html</guid><category>openstack</category><category>cloud files</category><category>swift</category></item><item><title>How Keystone Signs, Encodes, Decodes, &amp; Verifies</title><link>http://www.madorn.com/keystone-signing-encoding-decoding-verifying.html</link><description>&lt;p&gt;There seemed to be a great deal of confusion about whether Keystone PKI tokens were encrypted or signed.&lt;/p&gt;
&lt;p&gt;I spent a few days digging into this.&lt;/p&gt;
&lt;div class="section" id="initial-setup-keystone-creates-a-self-signed-certificate-and-becomes-the-root-ca"&gt;
&lt;h2&gt;Initial Setup:  Keystone Creates a Self-Signed Certificate and Becomes the Root CA&lt;/h2&gt;
&lt;p&gt;Utilizing OpenSSL, Keystone sets itself up as the root CA by generating a self-signed cert:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;openssl genrsa -out /etc/keystone/ssl/certs/cakey.pem 1024 -config /etc/keystone/ssl/certs/openssl.conf&lt;/span&gt;
&lt;span class="go"&gt;openssl req -new -x509 -extensions v3_ca -passin pass:None -key /etc/keystone/ssl/certs/cakey.pem -out /etc/keystone/ssl/certs/ca.pem -days 3650 -config /etc/keystone/ssl/certs/openssl.conf -subj /C=US/ST=Unset/L=Unset/O=Unset/CN=www.example.com&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="generate-signing-certificate"&gt;
&lt;h2&gt;Generate Signing Certificate&lt;/h2&gt;
&lt;p&gt;Now that Keystone has established itself as the root CA, it is ready to generate legitimate certs.  We will generate a &lt;strong&gt;signing certificate&lt;/strong&gt;.  This certificate is going to be used to sign our token info:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;openssl req -out /etc/keystone/ssl/certs/req.pem -config /etc/keystone/ssl/certs/openssl.conf -subj /C=US/ST=Unset/L=Unset/O=Unset/CN=www.example.com&lt;/span&gt;
&lt;span class="go"&gt;openssl ca -batch -out /etc/keystone/ssl/certs/signing_cert.pem -config /etc/keystone/ssl/certs/openssl.conf -infiles /etc/keystone/ssl/certs/req.pem&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If we did not want to use Keystone as the root CA, we could generate a request here and send it off to an established CA like Verisign. Verisign would then send back our signing cert.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="initial-authentication"&gt;
&lt;h2&gt;Initial Authentication&lt;/h2&gt;
&lt;p&gt;When a user &lt;strong&gt;initially&lt;/strong&gt; authenticates with Keystone, it will authenticate the user and grab data about the user from the Keystone DB:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;{&lt;/span&gt;
&lt;span class="go"&gt; &amp;quot;access&amp;quot;: {&lt;/span&gt;
&lt;span class="go"&gt;     &amp;quot;metadata&amp;quot;: {&lt;/span&gt;
&lt;span class="go"&gt;         &amp;quot;is_admin&amp;quot;: 0,&lt;/span&gt;
&lt;span class="go"&gt;         &amp;quot;roles&amp;quot;: [&lt;/span&gt;
&lt;span class="go"&gt;             &amp;quot;9fe2ff9ee4384b1894a90878d3e92bab&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;             &amp;quot;9ccd9139439e41ceac20a5e33e81555b&amp;quot;&lt;/span&gt;
&lt;span class="go"&gt;         ]&lt;/span&gt;
&lt;span class="go"&gt;     },&lt;/span&gt;
&lt;span class="go"&gt;     &amp;quot;serviceCatalog&amp;quot;: [&lt;/span&gt;
&lt;span class="go"&gt;         {&lt;/span&gt;
&lt;span class="go"&gt;             &amp;quot;endpoints&amp;quot;: [&lt;/span&gt;
&lt;span class="go"&gt;                 {&lt;/span&gt;
&lt;span class="go"&gt;                     &amp;quot;adminURL&amp;quot;: &amp;quot;http://10.0.10.10:8776/v1/5dd0ede8bcc44f26ae8983f03249b4de&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;                     &amp;quot;id&amp;quot;: &amp;quot;4be86b9f26564ffc9b40fa1f68eb1603&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;                     &amp;quot;internalURL&amp;quot;: &amp;quot;http://10.0.10.10:8776/v1/5dd0ede8bcc44f26ae8983f03249b4de&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;                     &amp;quot;publicURL&amp;quot;: &amp;quot;http://10.0.10.10:8776/v1/5dd0ede8bcc44f26ae8983f03249b4de&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;                     &amp;quot;region&amp;quot;: &amp;quot;RegionOne&amp;quot;&lt;/span&gt;
&lt;span class="go"&gt;                 }&lt;/span&gt;
&lt;span class="go"&gt;             ],&lt;/span&gt;
&lt;span class="go"&gt;             &amp;quot;endpoints_links&amp;quot;: [],&lt;/span&gt;
&lt;span class="go"&gt;             &amp;quot;name&amp;quot;: &amp;quot;volume&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;             &amp;quot;type&amp;quot;: &amp;quot;volume&amp;quot;&lt;/span&gt;
&lt;span class="go"&gt;         },&lt;/span&gt;
&lt;span class="go"&gt;         {&lt;/span&gt;
&lt;span class="go"&gt;             &amp;quot;endpoints&amp;quot;: [&lt;/span&gt;
&lt;span class="go"&gt;                 {&lt;/span&gt;
&lt;span class="go"&gt;                     &amp;quot;adminURL&amp;quot;: &amp;quot;http://10.0.10.10:9292&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;                     &amp;quot;id&amp;quot;: &amp;quot;5655ca5092b14a63a5a6a1882426bce6&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;                     &amp;quot;internalURL&amp;quot;: &amp;quot;http://10.0.10.10:9292&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;                     &amp;quot;publicURL&amp;quot;: &amp;quot;http://10.0.10.10:9292&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;                     &amp;quot;region&amp;quot;: &amp;quot;RegionOne&amp;quot;&lt;/span&gt;
&lt;span class="go"&gt;                 }&lt;/span&gt;
&lt;span class="go"&gt;             ],&lt;/span&gt;
&lt;span class="go"&gt;             &amp;quot;endpoints_links&amp;quot;: [],&lt;/span&gt;
&lt;span class="go"&gt;             &amp;quot;name&amp;quot;: &amp;quot;glance&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;             &amp;quot;type&amp;quot;: &amp;quot;image&amp;quot;&lt;/span&gt;
&lt;span class="go"&gt;         },&lt;/span&gt;
&lt;span class="go"&gt;         {&lt;/span&gt;
&lt;span class="go"&gt;             &amp;quot;endpoints&amp;quot;: [&lt;/span&gt;
&lt;span class="go"&gt;                 {&lt;/span&gt;
&lt;span class="go"&gt;                     &amp;quot;adminURL&amp;quot;: &amp;quot;http://10.0.10.10:8774/v2/5dd0ede8bcc44f26ae8983f03249b4de&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;                     &amp;quot;id&amp;quot;: &amp;quot;5721a24df1c3492da5532ed71d13ebe0&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;                     &amp;quot;internalURL&amp;quot;: &amp;quot;http://10.0.10.10:8774/v2/5dd0ede8bcc44f26ae8983f03249b4de&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;                     &amp;quot;publicURL&amp;quot;: &amp;quot;http://10.0.10.10:8774/v2/5dd0ede8bcc44f26ae8983f03249b4de&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;                     &amp;quot;region&amp;quot;: &amp;quot;RegionOne&amp;quot;&lt;/span&gt;
&lt;span class="go"&gt;                 }&lt;/span&gt;
&lt;span class="go"&gt;             ],&lt;/span&gt;
&lt;span class="go"&gt;             &amp;quot;endpoints_links&amp;quot;: [],&lt;/span&gt;
&lt;span class="go"&gt;             &amp;quot;name&amp;quot;: &amp;quot;nova&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;             &amp;quot;type&amp;quot;: &amp;quot;compute&amp;quot;&lt;/span&gt;
&lt;span class="go"&gt;         },&lt;/span&gt;
&lt;span class="go"&gt;         {&lt;/span&gt;
&lt;span class="go"&gt;             &amp;quot;endpoints&amp;quot;: [&lt;/span&gt;
&lt;span class="go"&gt;                 {&lt;/span&gt;
&lt;span class="go"&gt;                     &amp;quot;adminURL&amp;quot;: &amp;quot;http://10.0.10.10:9696&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;                     &amp;quot;id&amp;quot;: &amp;quot;5ab1bbb07fa644a0b95c1a1cad3061be&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;                     &amp;quot;internalURL&amp;quot;: &amp;quot;http://10.0.10.10:9696&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;                     &amp;quot;publicURL&amp;quot;: &amp;quot;http://10.0.10.10:9696&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;                     &amp;quot;region&amp;quot;: &amp;quot;RegionOne&amp;quot;&lt;/span&gt;
&lt;span class="go"&gt;                 }&lt;/span&gt;
&lt;span class="go"&gt;             ],&lt;/span&gt;
&lt;span class="go"&gt;             &amp;quot;endpoints_links&amp;quot;: [],&lt;/span&gt;
&lt;span class="go"&gt;             &amp;quot;name&amp;quot;: &amp;quot;quantum&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;             &amp;quot;type&amp;quot;: &amp;quot;network&amp;quot;&lt;/span&gt;
&lt;span class="go"&gt;         },&lt;/span&gt;
&lt;span class="go"&gt;         {&lt;/span&gt;
&lt;span class="go"&gt;             &amp;quot;endpoints&amp;quot;: [&lt;/span&gt;
&lt;span class="go"&gt;                 {&lt;/span&gt;
&lt;span class="go"&gt;                     &amp;quot;adminURL&amp;quot;: &amp;quot;http://10.0.10.10:35357/v2.0&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;                     &amp;quot;id&amp;quot;: &amp;quot;6e89262f99b54900a066d1310c2e4c87&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;                     &amp;quot;internalURL&amp;quot;: &amp;quot;http://10.0.10.10:5000/v2.0&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;                     &amp;quot;publicURL&amp;quot;: &amp;quot;http://10.0.10.10:5000/v2.0&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;                     &amp;quot;region&amp;quot;: &amp;quot;RegionOne&amp;quot;&lt;/span&gt;
&lt;span class="go"&gt;                 }&lt;/span&gt;
&lt;span class="go"&gt;             ],&lt;/span&gt;
&lt;span class="go"&gt;             &amp;quot;endpoints_links&amp;quot;: [],&lt;/span&gt;
&lt;span class="go"&gt;             &amp;quot;name&amp;quot;: &amp;quot;keystone&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;             &amp;quot;type&amp;quot;: &amp;quot;identity&amp;quot;&lt;/span&gt;
&lt;span class="go"&gt;         }&lt;/span&gt;
&lt;span class="go"&gt;     ],&lt;/span&gt;
&lt;span class="go"&gt;     &amp;quot;token&amp;quot;: {&lt;/span&gt;
&lt;span class="go"&gt;         &amp;quot;expires&amp;quot;: &amp;quot;2013-10-12T20:02:49Z&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;         &amp;quot;id&amp;quot;: &amp;quot;placeholder&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;         &amp;quot;issued_at&amp;quot;: &amp;quot;2013-10-11T20:02:49.623814&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;         &amp;quot;tenant&amp;quot;: {&lt;/span&gt;
&lt;span class="go"&gt;             &amp;quot;description&amp;quot;: &amp;quot;Default Tenant&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;             &amp;quot;enabled&amp;quot;: true,&lt;/span&gt;
&lt;span class="go"&gt;             &amp;quot;id&amp;quot;: &amp;quot;5dd0ede8bcc44f26ae8983f03249b4de&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;             &amp;quot;name&amp;quot;: &amp;quot;demo&amp;quot;&lt;/span&gt;
&lt;span class="go"&gt;         }&lt;/span&gt;
&lt;span class="go"&gt;     },&lt;/span&gt;
&lt;span class="go"&gt;     &amp;quot;user&amp;quot;: {&lt;/span&gt;
&lt;span class="go"&gt;         &amp;quot;id&amp;quot;: &amp;quot;a366ed02b00f4cc6ac9af6f6d5990778&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;         &amp;quot;name&amp;quot;: &amp;quot;admin&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;         &amp;quot;roles&amp;quot;: [&lt;/span&gt;
&lt;span class="go"&gt;             {&lt;/span&gt;
&lt;span class="go"&gt;                 &amp;quot;name&amp;quot;: &amp;quot;_member_&amp;quot;&lt;/span&gt;
&lt;span class="go"&gt;             },&lt;/span&gt;
&lt;span class="go"&gt;             {&lt;/span&gt;
&lt;span class="go"&gt;                 &amp;quot;name&amp;quot;: &amp;quot;admin&amp;quot;&lt;/span&gt;
&lt;span class="go"&gt;             }&lt;/span&gt;
&lt;span class="go"&gt;         ],&lt;/span&gt;
&lt;span class="go"&gt;         &amp;quot;roles_links&amp;quot;: [],&lt;/span&gt;
&lt;span class="go"&gt;         &amp;quot;username&amp;quot;: &amp;quot;admin&amp;quot;&lt;/span&gt;
&lt;span class="go"&gt;     }&lt;/span&gt;
&lt;span class="go"&gt; }&lt;/span&gt;
&lt;span class="go"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="sign-encode"&gt;
&lt;h2&gt;Sign &amp;amp; Encode&lt;/h2&gt;
&lt;p&gt;Keystone then signs the data above with both the &lt;strong&gt;signing cert&lt;/strong&gt; and associated &lt;strong&gt;signing private key&lt;/strong&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;openssl cms -sign -in mytext.json -signer /etc/keystone/ssl/certs/signing_cert.pem -inkey /etc/keystone/ssl/private/signing_key.pem -outform PEM -nosmimecap -nodetach -nocerts -noattr&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The result is our signed info encoded, &lt;strong&gt;not encrypted&lt;/strong&gt;, in PEM format:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;-----BEGIN CMS-----&lt;/span&gt;
&lt;span class="go"&gt;MIIJWAYJKoZIhvcNAQcCoIIJSTCCCUUCAQExCTAHBgUrDgMCGjCCCDEGCSqGSIb3&lt;/span&gt;
&lt;span class="go"&gt;DQEHAaCCCCIEgggeeyJhY2Nlc3MiOiB7InRva2VuIjogeyJpc3N1ZWRfYXQiOiAi&lt;/span&gt;
&lt;span class="go"&gt;MjAxMy0xMC0xMVQyMDowMjo0OS42MjM4MTQiLCAiZXhwaXJlcyI6ICIyMDEzLTEw&lt;/span&gt;
&lt;span class="go"&gt;LTEyVDIwOjAyOjQ5WiIsICJpZCI6ICJwbGFjZWhvbGRlciIsICJ0ZW5hbnQiOiB7&lt;/span&gt;
&lt;span class="go"&gt;ImRlc2NyaXB0aW9uIjogIkRlZmF1bHQgVGVuYW50IiwgImVuYWJsZWQiOiB0cnVl&lt;/span&gt;
&lt;span class="go"&gt;LCAiaWQiOiAiNWRkMGVkZThiY2M0NGYyNmFlODk4M2YwMzI0OWI0ZGUiLCAibmFt&lt;/span&gt;
&lt;span class="go"&gt;ZSI6ICJkZW1vIn19LCAic2VydmljZUNhdGFsb2ciOiBbeyJlbmRwb2ludHMiOiBb&lt;/span&gt;
&lt;span class="go"&gt;eyJhZG1pblVSTCI6ICJodHRwOi8vMTAuMC4xMC4xMDo4Nzc2L3YxLzVkZDBlZGU4&lt;/span&gt;
&lt;span class="go"&gt;YmNjNDRmMjZhZTg5ODNmMDMyNDliNGRlIiwgInJlZ2lvbiI6ICJSZWdpb25PbmUi&lt;/span&gt;
&lt;span class="go"&gt;LCAiaW50ZXJuYWxVUkwiOiAiaHR0cDovLzEwLjAuMTAuMTA6ODc3Ni92MS81ZGQw&lt;/span&gt;
&lt;span class="go"&gt;ZWRlOGJjYzQ0ZjI2YWU4OTgzZjAzMjQ5YjRkZSIsICJpZCI6ICI0YmU4NmI5ZjI2&lt;/span&gt;
&lt;span class="go"&gt;NTY0ZmZjOWI0MGZhMWY2OGViMTYwMyIsICJwdWJsaWNVUkwiOiAiaHR0cDovLzEw&lt;/span&gt;
&lt;span class="go"&gt;LjAuMTAuMTA6ODc3Ni92MS81ZGQwZWRlOGJjYzQ0ZjI2YWU4OTgzZjAzMjQ5YjRk&lt;/span&gt;
&lt;span class="go"&gt;ZSJ9XSwgImVuZHBvaW50c19saW5rcyI6IFtdLCAidHlwZSI6ICJ2b2x1bWUiLCAi&lt;/span&gt;
&lt;span class="go"&gt;bmFtZSI6ICJ2b2x1bWUifSwgeyJlbmRwb2ludHMiOiBbeyJhZG1pblVSTCI6ICJo&lt;/span&gt;
&lt;span class="go"&gt;dHRwOi8vMTAuMC4xMC4xMDo5MjkyIiwgInJlZ2lvbiI6ICJSZWdpb25PbmUiLCAi&lt;/span&gt;
&lt;span class="go"&gt;aW50ZXJuYWxVUkwiOiAiaHR0cDovLzEwLjAuMTAuMTA6OTI5MiIsICJpZCI6ICI1&lt;/span&gt;
&lt;span class="go"&gt;NjU1Y2E1MDkyYjE0YTYzYTVhNmExODgyNDI2YmNlNiIsICJwdWJsaWNVUkwiOiAi&lt;/span&gt;
&lt;span class="go"&gt;aHR0cDovLzEwLjAuMTAuMTA6OTI5MiJ9XSwgImVuZHBvaW50c19saW5rcyI6IFtd&lt;/span&gt;
&lt;span class="go"&gt;LCAidHlwZSI6ICJpbWFnZSIsICJuYW1lIjogImdsYW5jZSJ9LCB7ImVuZHBvaW50&lt;/span&gt;
&lt;span class="go"&gt;cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xMC4wLjEwLjEwOjg3NzQvdjIvNWRk&lt;/span&gt;
&lt;span class="go"&gt;MGVkZThiY2M0NGYyNmFlODk4M2YwMzI0OWI0ZGUiLCAicmVnaW9uIjogIlJlZ2lv&lt;/span&gt;
&lt;span class="go"&gt;bk9uZSIsICJpbnRlcm5hbFVSTCI6ICJodHRwOi8vMTAuMC4xMC4xMDo4Nzc0L3Yy&lt;/span&gt;
&lt;span class="go"&gt;LzVkZDBlZGU4YmNjNDRmMjZhZTg5ODNmMDMyNDliNGRlIiwgImlkIjogIjU3MjFh&lt;/span&gt;
&lt;span class="go"&gt;MjRkZjFjMzQ5MmRhNTUzMmVkNzFkMTNlYmUwIiwgInB1YmxpY1VSTCI6ICJodHRw&lt;/span&gt;
&lt;span class="go"&gt;Oi8vMTAuMC4xMC4xMDo4Nzc0L3YyLzVkZDBlZGU4YmNjNDRmMjZhZTg5ODNmMDMy&lt;/span&gt;
&lt;span class="go"&gt;NDliNGRlIn1dLCAiZW5kcG9pbnRzX2xpbmtzIjogW10sICJ0eXBlIjogImNvbXB1&lt;/span&gt;
&lt;span class="go"&gt;dGUiLCAibmFtZSI6ICJub3ZhIn0sIHsiZW5kcG9pbnRzIjogW3siYWRtaW5VUkwi&lt;/span&gt;
&lt;span class="go"&gt;OiAiaHR0cDovLzEwLjAuMTAuMTA6OTY5NiIsICJyZWdpb24iOiAiUmVnaW9uT25l&lt;/span&gt;
&lt;span class="go"&gt;IiwgImludGVybmFsVVJMIjogImh0dHA6Ly8xMC4wLjEwLjEwOjk2OTYiLCAiaWQi&lt;/span&gt;
&lt;span class="go"&gt;OiAiNWFiMWJiYjA3ZmE2NDRhMGI5NWMxYTFjYWQzMDYxYmUiLCAicHVibGljVVJM&lt;/span&gt;
&lt;span class="go"&gt;IjogImh0dHA6Ly8xMC4wLjEwLjEwOjk2OTYifV0sICJlbmRwb2ludHNfbGlua3Mi&lt;/span&gt;
&lt;span class="go"&gt;OiBbXSwgInR5cGUiOiAibmV0d29yayIsICJuYW1lIjogInF1YW50dW0ifSwgeyJl&lt;/span&gt;
&lt;span class="go"&gt;bmRwb2ludHMiOiBbeyJhZG1pblVSTCI6ICJodHRwOi8vMTAuMC4xMC4xMDozNTM1&lt;/span&gt;
&lt;span class="go"&gt;Ny92Mi4wIiwgInJlZ2lvbiI6ICJSZWdpb25PbmUiLCAiaW50ZXJuYWxVUkwiOiAi&lt;/span&gt;
&lt;span class="go"&gt;aHR0cDovLzEwLjAuMTAuMTA6NTAwMC92Mi4wIiwgImlkIjogIjZlODkyNjJmOTli&lt;/span&gt;
&lt;span class="go"&gt;NTQ5MDBhMDY2ZDEzMTBjMmU0Yzg3IiwgInB1YmxpY1VSTCI6ICJodHRwOi8vMTAu&lt;/span&gt;
&lt;span class="go"&gt;MC4xMC4xMDo1MDAwL3YyLjAifV0sICJlbmRwb2ludHNfbGlua3MiOiBbXSwgInR5&lt;/span&gt;
&lt;span class="go"&gt;cGUiOiAiaWRlbnRpdHkiLCAibmFtZSI6ICJrZXlzdG9uZSJ9XSwgInVzZXIiOiB7&lt;/span&gt;
&lt;span class="go"&gt;InVzZXJuYW1lIjogImFkbWluIiwgInJvbGVzX2xpbmtzIjogW10sICJpZCI6ICJh&lt;/span&gt;
&lt;span class="go"&gt;MzY2ZWQwMmIwMGY0Y2M2YWM5YWY2ZjZkNTk5MDc3OCIsICJyb2xlcyI6IFt7Im5h&lt;/span&gt;
&lt;span class="go"&gt;bWUiOiAiX21lbWJlcl8ifSwgeyJuYW1lIjogImFkbWluIn1dLCAibmFtZSI6ICJh&lt;/span&gt;
&lt;span class="go"&gt;ZG1pbiJ9LCAibWV0YWRhdGEiOiB7ImlzX2FkbWluIjogMCwgInJvbGVzIjogWyI5&lt;/span&gt;
&lt;span class="go"&gt;ZmUyZmY5ZWU0Mzg0YjE4OTRhOTA4NzhkM2U5MmJhYiIsICI5Y2NkOTEzOTQzOWU0&lt;/span&gt;
&lt;span class="go"&gt;MWNlYWMyMGE1ZTMzZTgxNTU1YiJdfX19DQoxgf8wgfwCAQEwXDBXMQswCQYDVQQG&lt;/span&gt;
&lt;span class="go"&gt;EwJVUzEOMAwGA1UECBMFVW5zZXQxDjAMBgNVBAcTBVVuc2V0MQ4wDAYDVQQKEwVV&lt;/span&gt;
&lt;span class="go"&gt;bnNldDEYMBYGA1UEAxMPd3d3LmV4YW1wbGUuY29tAgEBMAcGBSsOAwIaMA0GCSqG&lt;/span&gt;
&lt;span class="go"&gt;SIb3DQEBAQUABIGACOF/D6COhzYHNdpJmE+PCz7TxkgnVBuHjxU2z/pV1e8hwv1I&lt;/span&gt;
&lt;span class="go"&gt;VO2ZTJ+TRIYZl8LxFCtupaDPeTOYEz1fn6YvjGOqSBkmw1OS3mmGov7HaH0BsYk3&lt;/span&gt;
&lt;span class="go"&gt;vWnb0lXUNCvsuSzqQmoCzv3CbrsXDnp5bDEbzYXM78AHX03homw/PyAPA5M=&lt;/span&gt;
&lt;span class="go"&gt;-----END CMS-----&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="view-signature"&gt;
&lt;h2&gt;View Signature&lt;/h2&gt;
&lt;p&gt;We can view the signature or &amp;quot;proof&amp;quot; that the message was stamped with Keystone's approval by decoding our token:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;base64 -d mytoken.signed&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The decoded token is our user metadata along with some scrambled text which represents the cert signaure:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;?&amp;quot;{&amp;quot;access&amp;quot;: {&amp;quot;token&amp;quot;: {&amp;quot;issued_at&amp;quot;: &amp;quot;2013-10-11T20:02:49.623814&amp;quot;, &amp;quot;expires&amp;quot;: &amp;quot;2013-10-12T20:02:49Z&amp;quot;, &amp;quot;id&amp;quot;: &amp;quot;placeholder&amp;quot;&lt;/span&gt;
&lt;span class="go"&gt;,&amp;quot;tenant&amp;quot;: {&amp;quot;description&amp;quot;: &amp;quot;Default Tenant&amp;quot;, &amp;quot;enabled&amp;quot;: true, &amp;quot;id&amp;quot;: &amp;quot;5dd0ede8bcc44f26ae8983f03249b4de&amp;quot;, &amp;quot;name&amp;quot;: &amp;quot;demo&amp;quot;}},&lt;/span&gt;
&lt;span class="go"&gt;&amp;quot;serviceCatalog&amp;quot;: [{&amp;quot;endpoints&amp;quot;: [{&amp;quot;adminURL&amp;quot;: &amp;quot;http://10.0.10.10:8776/v1/5dd0ede8bcc44f26ae8983f03249b4de&amp;quot;, &amp;quot;region&amp;quot;:&lt;/span&gt;
&lt;span class="go"&gt;&amp;quot;RegionOne&amp;quot;, &amp;quot;internalURL&amp;quot;: &amp;quot;http://10.0.10.10:8776/v1/5dd0ede8bcc44f26ae8983f03249b4de&amp;quot;, &amp;quot;id&amp;quot;: &amp;quot;4be86b9f26564ffc9b40fa1f&lt;/span&gt;
&lt;span class="go"&gt;68e&lt;/span&gt;
&lt;span class="go"&gt;b1603&amp;quot;, &amp;quot;publicURL&amp;quot;: &amp;quot;http://10.0.10.10:8776/v1/5dd0ede8bcc44f26ae8983f03249b4de&amp;quot;}], &amp;quot;endpoints_links&amp;quot;: [], &amp;quot;type&amp;quot;:&lt;/span&gt;
&lt;span class="go"&gt;&amp;quot;volume&amp;quot;, &amp;quot;name&amp;quot;: &amp;quot;volume&amp;quot;}, {&amp;quot;endpoints&amp;quot;: [{&amp;quot;adminURL&amp;quot;: &amp;quot;http://10.0.10.10:9292&amp;quot;, &amp;quot;region&amp;quot;: &amp;quot;RegionOne&amp;quot;, &amp;quot;internalURL&amp;quot;:&lt;/span&gt;
&lt;span class="go"&gt;&amp;quot;http://10.0.10.10:9292&amp;quot;, &amp;quot;id&amp;quot;: &amp;quot;5655ca5092b14a63a5a6a1882426bce6&amp;quot;, &amp;quot;publicURL&amp;quot;: &amp;quot;http://10.0.10.10:9292&amp;quot;}], &amp;quot;endpoints_l&lt;/span&gt;
&lt;span class="go"&gt;ink&lt;/span&gt;
&lt;span class="go"&gt;s&amp;quot;: [], &amp;quot;type&amp;quot;: &amp;quot;image&amp;quot;, &amp;quot;name&amp;quot;: &amp;quot;glance&amp;quot;}, {&amp;quot;endpoints&amp;quot;: [{&amp;quot;adminURL&amp;quot;: &amp;quot;http://10.0.10.10:8774/v2/5dd0ede8bcc44f26ae8983&lt;/span&gt;
&lt;span class="go"&gt;f03&lt;/span&gt;
&lt;span class="go"&gt;249b4de&amp;quot;, &amp;quot;region&amp;quot;: &amp;quot;RegionOne&amp;quot;, &amp;quot;internalURL&amp;quot;: &amp;quot;http://10.0.10.10:8774/v2/5dd0ede8bcc44f26ae8983f03249b4de&amp;quot;, &amp;quot;id&amp;quot;:&lt;/span&gt;
&lt;span class="go"&gt;&amp;quot;5721a24df1c3492da5532ed71d13ebe0&amp;quot;, &amp;quot;publicURL&amp;quot;: &amp;quot;http://10.0.10.10:8774/v2/5dd0ede8bcc44f26ae8983f03249b4de&amp;quot;}],&lt;/span&gt;
&lt;span class="go"&gt;&amp;quot;endpoints_links&amp;quot;: [], &amp;quot;type&amp;quot;: &amp;quot;compute&amp;quot;, &amp;quot;name&amp;quot;: &amp;quot;nova&amp;quot;}, {&amp;quot;endpoints&amp;quot;: [{&amp;quot;adminURL&amp;quot;: &amp;quot;http://10.0.10.10:9696&amp;quot;, &amp;quot;region&amp;quot;&lt;/span&gt;
&lt;span class="go"&gt;: &amp;quot;RegionOne&amp;quot;, &amp;quot;internalUR   L&amp;quot;: &amp;quot;http://10.0.10.10:9696&amp;quot;, &amp;quot;id&amp;quot;: &amp;quot;5ab1bbb07fa644a0b95c1a1cad3061be&amp;quot;, &amp;quot;publicURL&amp;quot;: &amp;quot;http&lt;/span&gt;
&lt;span class="go"&gt;://10.0.10.10:9696&amp;quot;}], &amp;quot;endpoints_&lt;/span&gt;
&lt;span class="go"&gt;links&amp;quot;: [], &amp;quot;type&amp;quot;: &amp;quot;network&amp;quot;, &amp;quot;name&amp;quot;: &amp;quot;quantum&amp;quot;}, {&amp;quot;endpoints&amp;quot;: [{&amp;quot;adminURL&amp;quot;: &amp;quot;http://10.0.10.10:35357/v2.0&amp;quot;, &amp;quot;region&amp;quot;:&lt;/span&gt;
&lt;span class="go"&gt;&amp;quot;RegionOne&amp;quot;, &amp;quot;internalURL&amp;quot;: &amp;quot;http://10.0.10.10:5000/v2.0&amp;quot;, &amp;quot;id&amp;quot;: &amp;quot;6e89262f99b54900a066d1310c2e4c87&amp;quot;, &amp;quot;publicURL&amp;quot;: &amp;quot;http&lt;/span&gt;
&lt;span class="go"&gt;://10&lt;/span&gt;
&lt;span class="go"&gt;.0.10.10:5000/v2.0&amp;quot;}], &amp;quot;endpoints_links&amp;quot;: [], &amp;quot;type&amp;quot;: &amp;quot;identity&amp;quot;, &amp;quot;name&amp;quot;: &amp;quot;keystone&amp;quot;}], &amp;quot;user&amp;quot;: {&amp;quot;username&amp;quot;: &amp;quot;admin&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;&amp;quot;roles_links&amp;quot;: [], &amp;quot;id&amp;quot;: &amp;quot;a366ed02b00f4cc6ac9af6f6d5990778&amp;quot;, &amp;quot;roles&amp;quot;: [{&amp;quot;name&amp;quot;: &amp;quot;_member_&amp;quot;}, {&amp;quot;name&amp;quot;: &amp;quot;admin&amp;quot;}], &amp;quot;name&amp;quot;:&lt;/span&gt;
&lt;span class="go"&gt;&amp;quot;admin&amp;quot;}, &amp;quot;metadata&amp;quot;: {&amp;quot;is_admin&amp;quot;: 0, &amp;quot;roles&amp;quot;: [&amp;quot;9fe2ff9ee4384b1894a90878d3e92bab&amp;quot;, &amp;quot;9ccd9139439e41ceac20a5e33e81555b&amp;quot;]}}&lt;/span&gt;
&lt;span class="go"&gt;}&lt;/span&gt;
&lt;span class="go"&gt;1??0??0\0W1&lt;/span&gt;
&lt;span class="go"&gt;0UUS10&lt;/span&gt;
&lt;span class="go"&gt;Unset10&lt;/span&gt;
&lt;span class="go"&gt;UUnset10&lt;/span&gt;
&lt;span class="go"&gt;U&lt;/span&gt;
&lt;span class="go"&gt;?????65?I?O??xample.com0+0&lt;/span&gt;
&lt;span class="gp"&gt;&amp;gt;&lt;/span&gt;??H&lt;span class="err"&gt;&amp;#39;&lt;/span&gt;T?6??U??!??HT?L??D????+n???y3?&lt;span class="o"&gt;=&lt;/span&gt;_??/?c?H&amp;amp;?S??i????h&lt;span class="o"&gt;}&lt;/span&gt;??7?i??U?4+?,?Bj???n?zyl1ͅ??_M?l?? ?
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="certs-pushed-to-services"&gt;
&lt;h2&gt;Certs Pushed to Services&lt;/h2&gt;
&lt;p&gt;The signing certificate and Keystone root CA cert are passed down to the service endpoint along with the current list of revoked certificates.&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;/var/lib/glance&lt;/span&gt;
&lt;span class="go"&gt;.&lt;/span&gt;
&lt;span class="go"&gt;|-- image-cache&lt;/span&gt;
&lt;span class="go"&gt;|   |-- incomplete&lt;/span&gt;
&lt;span class="go"&gt;|   |-- invalid&lt;/span&gt;
&lt;span class="go"&gt;|   `-- queue&lt;/span&gt;
&lt;span class="go"&gt;|-- images&lt;/span&gt;
&lt;span class="go"&gt;|   `-- b32c90b4-f30a-4dd0-8898-ee35d67838fd&lt;/span&gt;
&lt;span class="go"&gt;`-- keystone-signing&lt;/span&gt;
&lt;span class="go"&gt;   |-- cacert.pem&lt;/span&gt;
&lt;span class="go"&gt;   |-- revoked.pem&lt;/span&gt;
&lt;span class="go"&gt;   `-- signing_cert.pem&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="token-verification"&gt;
&lt;h2&gt;Token Verification&lt;/h2&gt;
&lt;p&gt;The token is verified by a service using a signing cert (public key) and Keystone root CA cert (The Keystone root CA cert is needed because it is not from an established CA and we are not likely to have a copy on our local machine):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;openssl cms -verify -in cmsnew -certfile /var/lib/glance/keystone-signing/signing_cert.pem -CAfile /var/lib/glance/keystone-signing/cacert.pem -inform PEM -nosmimecap -nodetach -nocerts -noattr&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This works by &lt;strong&gt;decoding&lt;/strong&gt; and then &lt;strong&gt;verifiying&lt;/strong&gt; the signature.  The scrambled text is removed from our data and we now have our original user json metadata for OpenStack to consume.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="conclusion"&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;If one does not have their SSL endpoints secure, nothing is being encrypted.  It is simply being signed and encoded.&lt;/p&gt;
&lt;p&gt;To prove this point, it's a cool exercise to just run &lt;tt class="docutils literal"&gt;base64 &lt;span class="pre"&gt;-d&lt;/span&gt;&lt;/tt&gt; on any PKI token to show that the data inside is not safe!  The PEM format is simply for transportation purposes.  The &amp;quot;signing&amp;quot; is to prevent spoofing, i.e. modifying a token and adding the admin role.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Encrypting&lt;/strong&gt;:  Using a public key to write a message and someone else using their private key to read it.
i.e. You sign into &lt;a class="reference external" href="https://gmail.com"&gt;https://gmail.com&lt;/a&gt;:  You view their certificate by clicking on the SSL lock encryption icon.  You can see the public key they are providing to your browser to &lt;strong&gt;encrypt&lt;/strong&gt; the data to them.  They are using a hidden private key to decrypt.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Signing&lt;/strong&gt;:  You use your private key to write message's signature.  They use your public key to check if it's really yours.&lt;/p&gt;
&lt;p&gt;Check out this resource for clarification on the differences between encryption, encoding, and hashing:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://danielmiessler.com/study/encoding_encryption_hashing/"&gt;http://danielmiessler.com/study/encoding_encryption_hashing/&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Dorn</dc:creator><pubDate>Sun, 13 Oct 2013 10:20:00 -0500</pubDate><guid>tag:www.madorn.com,2013-10-13:keystone-signing-encoding-decoding-verifying.html</guid><category>openstack</category><category>keystone</category><category>openssl</category></item><item><title>Syncing QNAP to Rackspace Cloud Files</title><link>http://www.madorn.com/qnap-to-cloudfiles.html</link><description>&lt;p&gt;Users of QNAP NAS devices have been asking for an out-of-the-box solution to backup to Rackspace Cloud Files for a few years now.  There is already a tool in the QNAP Web UI for backing up your shares to Amazon S3, Elephant Drive, or Symform.&lt;/p&gt;
&lt;p&gt;The best solution I have so far is utilizing Pyrax, the Python SDK for Rackspace public cloud.  The &lt;tt class="docutils literal"&gt;cf_pyrax script&lt;/tt&gt; makes use of the &lt;tt class="docutils literal"&gt;sync_folder_to_container&lt;/tt&gt; function found in Pyrax to sync a directory to a Cloud Files container.  Even though the QNAP NAS is Linux-based, a lot of the usual methods for installing packages and scheduling jobs do not apply.&lt;/p&gt;
&lt;p&gt;Here is what I did to configure my QNAP TS-419P II for a scheduled backup to Rackspace Cloud Files.&lt;/p&gt;
&lt;div class="section" id="install-python-2-7"&gt;
&lt;h2&gt;Install Python 2.7&lt;/h2&gt;
&lt;p&gt;Navigate to the QNAP web interface and install the Python v2.7 .qpkg from the App Center.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="verify-the-installation"&gt;
&lt;h2&gt;Verify the Installation&lt;/h2&gt;
&lt;p&gt;Verify that Python 2.7 was successfully installed:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;python --version&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="install-pip"&gt;
&lt;h2&gt;Install PIP&lt;/h2&gt;
&lt;p&gt;Install PIP 1.2.1:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;curl -o https//:pypi.python.org/packages/source/p/pip/pip-1.2.1.tar.gz&lt;/span&gt;
&lt;span class="go"&gt;tar xvfz pip-1.2.1.tar.gz&lt;/span&gt;
&lt;span class="go"&gt;cd pip-1.2.1&lt;/span&gt;
&lt;span class="go"&gt;python setup.py install&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you get &amp;quot;ImportError: No module named setuptools&amp;quot;, install setuptools first:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;wget https://pypi.python.org/packages/source/s/setuptools/setuptools-1.0.tar.gz --no-check-certificate&lt;/span&gt;
&lt;span class="go"&gt;tar xf setuptools-1.0.tar.gz&lt;/span&gt;
&lt;span class="go"&gt;cd setuptools-1.0&lt;/span&gt;
&lt;span class="go"&gt;python setup.py build&lt;/span&gt;
&lt;span class="go"&gt;python setup.py install&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="install-pyrax"&gt;
&lt;h2&gt;Install Pyrax&lt;/h2&gt;
&lt;p&gt;I had some issues with the NAS running out of room on tmpfs when installing Pyrax so provide a cache path with ample space:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;pip install pyrax --download-cache /share/path/to/directory&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Grab the &lt;tt class="docutils literal"&gt;cf_pyrax.py&lt;/tt&gt; script from &lt;a class="reference external" href="https://github.com/Linuturk/www.onitato.com/blob/master/cf_pyrax.py"&gt;https://github.com/Linuturk/www.onitato.com/blob/master/cf_pyrax.py&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="create-a-credentials-file"&gt;
&lt;h2&gt;Create a Credentials File&lt;/h2&gt;
&lt;p&gt;Create a credentials file with the following info:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;[rackspace_cloud]&lt;/span&gt;
&lt;span class="go"&gt;username = myusername&lt;/span&gt;
&lt;span class="go"&gt;api_key = myapikey&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="test-sync"&gt;
&lt;h2&gt;Test Sync&lt;/h2&gt;
&lt;p&gt;Your syntax to sync to a specific container should be as follows:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;python cf_pyrax.py TestContainer1 /share/MD0_DATA/testshare1 DFW /share/MD0_DATA/credentials.txt&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="edit-crontab"&gt;
&lt;h2&gt;Edit Crontab&lt;/h2&gt;
&lt;p&gt;After ensuring that the sync works properly, setup a cron job to backup your shares at a desired time.&lt;/p&gt;
&lt;p&gt;QNAP overwrites crontab with &lt;tt class="docutils literal"&gt;etc/config/crontab&lt;/tt&gt; after every system reboot/shutdown.  You must modify this file if you want new cron job entries to stick:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="go"&gt;echo &amp;quot;1 4 * * * python cf_pyrax.py TestContainer1 /share/MD0_DATA/testshare1 DFW /share/MD0_DATA/credentials.txt&amp;quot; &amp;gt;&amp;gt; /etc/config/crontab&lt;/span&gt;
&lt;span class="go"&gt;echo &amp;quot;1 4 * * * python cf_pyrax.py TestContainer2 /share/MD0_DATA/testshare2 DFW /share/MD0_DATA/credentials.txt&amp;quot; &amp;gt;&amp;gt; /etc/config/crontab&lt;/span&gt;
&lt;span class="go"&gt;crontab /etc/config/crontab&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matt Dorn</dc:creator><pubDate>Wed, 09 Oct 2013 10:20:00 -0500</pubDate><guid>tag:www.madorn.com,2013-10-09:qnap-to-cloudfiles.html</guid><category>qnap</category><category>cloud files</category><category>swift</category></item></channel></rss>