= Kubernetes - Setup Local Development Environment :toc: :icons: :linkcss: :imagesdir: ../../resources/images For local development purposes, you can create a one-node cluster using https://github.com/kubernetes/minikube[Minikube]. Hosted solutions or cloud-based solutions provide the scalability and higher availability for staging or production purposes. A complete list of solutions to create a Kubernetes cluster is explained at http://kubernetes.io/docs/getting-started-guides/. This section will explain how to create and shutdown a development Kubernetes cluster using Minikube. == Download and Install Minikube runs a single-node Kubernetes cluster inside a VM on your laptop. This allows you to easily try out Kubernetes on your local machine. Minikube packages and configures a Linux VM, the container runtime, and all Kubernetes components - optimized for local development. Complete installation instructions are available at https://github.com/kubernetes/minikube. Here are quick instructions: === Setup on macOS Provision and install a local Kubernetes cluster on a Mac OS via https://brew.sh/[homebrew]. . Install VirtualBox $ brew cask install virtualbox . Install (or update) minikube + *If you've never installed minikube before:* + brew cask install minikube + Verify the version: + $ minikube version minikube version: v0.24.1 + *If you already have minikube:* + brew cask reinstall minikube + [NOTE] ==== If you receive this error: ==> Installing Cask minikube Error: It seems there is already a Binary at '/usr/local/bin/minikube'; not linking. Run this command: $ sudo cp ~/Library/Caches/Homebrew/Cask/minikube--0.24.1 /usr/local/bin/minikube ==== + Verify the version: $ minikube version minikube version: v0.24.1 + Finally delete the previous minikube ISO: minikube delete === Setup on Windows . Download and install https://www.virtualbox.org/wiki/Downloads[VirtualBox]. . Download the https://storage.googleapis.com/minikube/releases/latest/minikube-windows-amd64.exe[minikube-windows-amd64.exe] file, and rename it to `minikube.exe`. Verify the version: + $ minikube version minikube version: v0.24.1 + . Download kubectl CLI with cmd.exe + curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.goo \ gleapis.com/kubernetes-release/release/stable.txt)/bin/windows/amd64/kubectl.exe Latest instructions are also available at https://kubernetes.io/docs/tasks/tools/install-kubectl/#before-you-begin. === Setup on Linux . Download and install https://www.virtualbox.org/wiki/Downloads[VirtualBox]. . Install minikube: curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/ . Verify the version: $ minikube version minikube version: v0.24.1 === Setup on EC2 (if you do not virtualbox on your laptop) . Launch an EC2 (at least 4GB Memory) with an "Ubuntu Server 16.04 LTS (HVM)" AMI, make sure you have a public IP and can SSH into this instance. . SSH into the EC2 (the port forwarding is for the minikube dashboard): $ ssh -L30000:localhost:30000 ubuntu@<IP Address of EC2> . Install docker $ sudo -i $ apt-get update -y && apt-get install -y docker.io . Install minikube: $ curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/ . Verify the version: $ minikube version minikube version: v0.24.1 . Install or Upgrade Kubectl CLI: $ curl -Lo kubectl https://storage.googleapis.com/kubernetes-release/release/v1.8.0/bin/linux/amd64/kubectl && chmod +x kubectl && sudo mv kubectl /usr/local/bin/ . Add kubectl autocompletion to your current shell $ source <(kubectl completion bash) == Start Kubernetes cluster We are using the VirtualBox driver which is the default selection for minikube. If you would prefer you can use an alternate supported component (xhyve driver or VMware Fusion) using the `--vm-driver=xxx` flag. Start a single-node Kubernetes cluster on your local machine: $ minikube start if you have installed minikube on a EC2, start it with the `--vm-driver=none` flag $ minikube start --vm-driver=none The first start of minikube will download the ISO file and then start the cluster. It shows the following output: $ minikube start Starting local Kubernetes v1.8.0 cluster... Starting VM... Downloading Minikube ISO 140.01 MB / 140.01 MB [============================================] 100.00% 0s Getting VM IP address... Moving files into cluster... Downloading localkube binary 148.56 MB / 148.56 MB [============================================] 100.00% 0s Setting up certs... Connecting to cluster... Setting up kubeconfig... Starting cluster components... Kubectl is now configured to use the cluster. Now you can start to develop and test your application. === Check status Check the status of minikube to get the status of your local Kubernetes cluster: $ minikube status minikube: Running cluster: Running kubectl: Correctly Configured: pointing to minikube-vm at 192.168.99.100 Kubectl CLI is configured to talk to this cluster. == Get information about the minikube cluster Now that we have a local development cluster up and running we can start issuing some basic commands to see its status. === View service webpage This minikube command will display the service for you in a web page: $ minikube service web This opened a browser with an IP address and the port that the service was exposed on. It looks like as shown: image::nginx-welcome-page.png[] This is a convenient feature of minikube. But what if you wanted to find this information yourself? You can view the IP address of a node in your cluster with these steps, first find all of the nodes in your cluster: $ kubectl get nodes Once you have the nodes (in minikubes case there will be only one), we can describe all of the attribute of that node with: $ kubectl describe node <node-name> Where `<node-name>` is the output from the previous command. This shows a lot of information about the node: ``` $ kubectl describe node minikube Name: minikube Roles: <none> Labels: beta.kubernetes.io/arch=amd64 beta.kubernetes.io/os=linux kubernetes.io/hostname=minikube Annotations: alpha.kubernetes.io/provided-node-ip=192.168.99.100 node.alpha.kubernetes.io/ttl=0 volumes.kubernetes.io/controller-managed-attach-detach=true Taints: <none> CreationTimestamp: Sun, 15 Oct 2017 17:22:22 -0400 Conditions: Type Status LastHeartbeatTime LastTransitionTime Reason Message ---- ------ ----------------- ------------------ ------ ------- OutOfDisk False Sun, 22 Oct 2017 21:26:44 -0400 Mon, 16 Oct 2017 19:28:57 -0400 KubeletHasSufficientDisk kubelet has sufficient disk space available MemoryPressure False Sun, 22 Oct 2017 21:26:44 -0400 Mon, 16 Oct 2017 19:28:57 -0400 KubeletHasSufficientMemory kubelet has sufficient memory available DiskPressure False Sun, 22 Oct 2017 21:26:44 -0400 Mon, 16 Oct 2017 19:28:57 -0400 KubeletHasNoDiskPressure kubelet has no disk pressure Ready True Sun, 22 Oct 2017 21:26:44 -0400 Mon, 16 Oct 2017 19:28:57 -0400 KubeletReady kubelet is posting ready status Addresses: InternalIP: 192.168.99.100 Hostname: minikube Capacity: cpu: 2 memory: 2048484Ki pods: 110 Allocatable: cpu: 2 memory: 1946084Ki pods: 110 System Info: Machine ID: 6756b9ba9cd3480fa019cf553d4fea04 System UUID: AC4BE6D4-7896-46EF-B921-44BD0BC92D0D Boot ID: 66a504af-ce10-4d45-ad50-334f21a2063e Kernel Version: 4.7.2 OS Image: Buildroot 2016.08 Operating System: linux Architecture: amd64 Container Runtime Version: docker://1.11.1 Kubelet Version: v1.7.5 Kube-Proxy Version: v1.7.5 ExternalID: minikube Non-terminated Pods: (4 in total) Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits --------- ---- ------------ ---------- --------------- ------------- default nginx-4217019353-h7mns 0 (0%) 0 (0%) 0 (0%) 0 (0%) kube-system kube-addon-manager-minikube 5m (0%) 0 (0%) 50Mi (2%) 0 (0%) kube-system kube-dns-1326421443-tbzqc 260m (13%) 0 (0%) 110Mi (5%) 170Mi (8%) kube-system kubernetes-dashboard-zqd7w 0 (0%) 0 (0%) 0 (0%) 0 (0%) Allocated resources: (Total limits may be over 100 percent, i.e., overcommitted.) CPU Requests CPU Limits Memory Requests Memory Limits ------------ ---------- --------------- ------------- 265m (13%) 0 (0%) 160Mi (8%) 170Mi (8%) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Starting 6d kubelet, minikube Starting kubelet. Normal NodeAllocatableEnforced 6d kubelet, minikube Updated Node Allocatable limit across pods Warning Rebooted 6d kubelet, minikube Node minikube has been rebooted, boot id: d80f975d-2373-4fd0-9d11-3262049e1f39 Normal NodeNotReady 6d kubelet, minikube Node minikube status is now: NodeNotReady Normal Starting 6d kube-proxy, minikube Starting kube-proxy. Normal NodeHasSufficientDisk 6d (x2 over 6d) kubelet, minikube Node minikube status is now: NodeHasSufficientDisk Normal NodeHasSufficientMemory 6d (x2 over 6d) kubelet, minikube Node minikube status is now: NodeHasSufficientMemory Normal NodeHasNoDiskPressure 6d (x2 over 6d) kubelet, minikube Node minikube status is now: NodeHasNoDiskPressure Normal NodeReady 6d (x2 over 6d) kubelet, minikube Node minikube status is now: NodeReady Normal Starting 8m kubelet, minikube Starting kubelet. Normal NodeAllocatableEnforced 8m kubelet, minikube Updated Node Allocatable limit across pods Normal NodeHasSufficientDisk 8m kubelet, minikube Node minikube status is now: NodeHasSufficientDisk Normal NodeHasSufficientMemory 8m kubelet, minikube Node minikube status is now: NodeHasSufficientMemory Normal NodeHasNoDiskPressure 8m kubelet, minikube Node minikube status is now: NodeHasNoDiskPressure Warning Rebooted 8m kubelet, minikube Node minikube has been rebooted, boot id: 66a504af-ce10-4d45-ad50-334f21a2063e Normal Starting 8m kube-proxy, minikube Starting kube-proxy. ``` IP address information can be obtained by looking at the `InternalIP` field: $ echo $(kubectl get nodes -o jsonpath='{.items[*].status.addresses[?(@.type=="InternalIP")].address}') This gives us the IP address where the service is hosted. Now, we need to get the port that the service is exposed on. This can be found using the following command: $ echo $(kubectl get service web -o jsonpath='{.spec.ports[*].nodePort}') We can combine these two commands with curl to access the service from the cli: ``` $ curl $(kubectl get nodes -o jsonpath='{.items[*].status.addresses[?(@.type=="InternalIP")].address}'):$(kubectl get service web -o jsonpath='{.spec.ports[*].nodePort}') ``` The host and the port are the exact same values where minikube opened the service page in the browser. === Kubernetes dashboard Kubernetes dashboard is a general purpose, web-based UI for Kubernetes clusters. It provides an overview of applications running on the cluster, as well as the ability to create or modify individual Kubernetes resources and workloads, such as replica sets, jobs, services, and pods. The dashboard can be used to manage the cluster as well. Kubernetes dashboard with minikube can be easily viewed using the following command ( Do not run this if you have minikube on EC2, instead just point your browser to http://127.0.0.1:30000): $ minikube dashboard It looks like this: image::minikube-dashboard.png[] Look around the dashboard and become familiar with some of the Kubernetes terminology. This will be explained in the subsequent chapters. === Shutdown cluster The cluster can be shutdown using the following command: $ minikube stop Stopping local Kubernetes cluster... Machine stopped. You are now ready to continue on with the workshop! :frame: none :grid: none :valign: top [align="center", cols="1", grid="none", frame="none"] |===== |image:button-continue-developer.png[link=../../03-path-application-development/302-app-discovery] |link:../../developer-path.adoc[Go to Developer Index] |=====