================================================ Bare Metal Deployment Guide for kolla-kubernetes ================================================ .. warning:: This documentation is under construction and may not work perfectly. If you run into trouble, please join #openstack-kolla and we can learn together how to solve whatever issues faced. Likely others in the community face the same issues. .. note:: This document was tested only against CentOS 7.3 Host OS and AIO environments. ------------ Introduction ------------ There are many ways to deploy Kubernetes. This guide has been tested only with kubeadm. The documentation for Kubeadm is here: https://kubernetes.io/docs/getting-started-guides/kubeadm/ Here is a video shown at a Kubernetes specific meetup on February 15th, 2017: https://youtu.be/rHCCUP2odd8 There are two steps to deploying kolla-kubernetes. The first step involves deploying Kubernetes. The second step involves deploying Kolla that is compatible with Kubernetes. Dependencies:: docker == 1.12.6 helm >= 2.2.3 kubectl >= 1.6.1 kubeadm >= 1.6.1 kubelet >= 1.6.1 kubernetes-cni >= 0.5.1 .. note:: When working with Kubernetes it is considered a useful practice to open a unique terminal window and run the command that watches all kubernetes's processes. This operation will show changes as they occur within Kubernetes and also shows the PODs IP addresses:: watch -n 5 -c kubectl get pods --all-namespaces ------------------------- Step 1: Deploy Kubernetes ------------------------- .. note:: This document recommends Kubernetes 1.6.1 or later. .. warning:: This documentation assumes a POD CIDR of 10.1.0.0/16 and a service CIDR of 10.3.3.0/24. Two rules must be followed when reading this guide. 1. The service and pod cidr cannot overlap 2. The address spaces cannot already be allocated by your organization If the POD and CIDR addresses overlap in this documentation with your organizations's IP address ranges, they may be changed. Simply subtitute anywhere these addresses are used with the custom cidrs you hae chosen. .. note:: If you fail to turn off SELinux, kubernetes will fail. Turn off SELinux:: sudo setenforce 0 sudo sed -i 's/enforcing/permissive/g' /etc/selinux/config Turn off firewalld:: sudo systemctl stop firewalld sudo systemctl disable firewalld .. note:: This operation configures the Kubernetes YUM repository. This step only needs to be done one time. .. warning:: gpgcheck=0 is set below because the currently signed RPMs don't match the yum-key.gpg key distributed by Kubernetes. YMMV. Write the kubernetes repository file:: cat < kubernetes.repo [kubernetes] name=Kubernetes baseurl=http://yum.kubernetes.io/repos/kubernetes-el7-x86_64 enabled=1 gpgcheck=0 repo_gpgcheck=1 gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg EOF sudo cp -a kubernetes.repo /etc/yum.repos.d Install Kubernetes 1.6.1 or later:: sudo yum install -y docker ebtables kubeadm kubectl kubelet kubernetes-cni To enable the proper cgroup driver, start Docker and disable CRI:: sudo systemctl enable docker sudo systemctl start docker CGROUP_DRIVER=$(sudo docker info | grep "Cgroup Driver" | awk '{print $3}') sudo sed -i "s|KUBELET_KUBECONFIG_ARGS=|KUBELET_KUBECONFIG_ARGS=--cgroup-driver=$CGROUP_DRIVER --enable-cri=false |g" /etc/systemd/system/kubelet.service.d/10-kubeadm.conf Setup the DNS server with the service CIDR:: sudo sed -i 's/10.96.0.10/10.3.3.10/g' /etc/systemd/system/kubelet.service.d/10-kubeadm.conf .. note:: Kubernetes uses x.x.x.10 as the DNS server. The Kolla developers don't know precisely why this is the case, however, current speculation is that that 1..9 are reserved for future expansion of Kubernetes infrastructure services. Then reload the hand-modified service files:: sudo systemctl daemon-reload Then stop kubelet if it is running:: sudo systemctl stop kubelet Then enable and start docker and kubelet:: sudo systemctl enable kubelet sudo systemctl start kubelet Deploy Kubernetes with kubeadm:: sudo kubeadm init --pod-network-cidr=10.1.0.0/16 --service-cidr=10.3.3.0/24 .. note:: pod-network-cidr is a network private to Kubernetes that the PODs within Kubernetes communicate on. The service-cidr is where IP addresses for Kubernetes services are allocated. There is no recommendation that the pod network should be /16 network in upstream documentation however, the Kolla developers have found through experience that each node consumes an entire /24 network, so this configuration would permit 255 Kubernetes nodes. Load the kubedm credentials into the system:: mkdir -p $HOME/.kube sudo -H cp /etc/kubernetes/admin.conf $HOME/.kube/config sudo -H chown $(id -u):$(id -g) $HOME/.kube/config The CNI driver is the networking driver that Kubernetes uses. Kolla uses canal currently in the gate and tests with it hundreds of times per day via extensive gating mechanisms. Kolla recommends the use of canal although other CNI drivers may be used if they are properly configured. Deploy the canal CNI driver:: curl -L https://raw.githubusercontent.com/projectcalico/canal/master/k8s-install/kubeadm/1.6/canal.yaml -o canal.yaml sed -i "s@192.168.0.0/16@10.1.0.0/16@" canal.yaml sed -i "s@10.96.232.136@10.3.3.100@" canal.yaml kubectl apply -f canal.yaml Finally untaint the node so that PODs can be scheduled to this AIO deployment:: kubectl taint nodes --all=true node-role.kubernetes.io/master:NoSchedule- --------------------------- Step 2: Validate Kubernetes --------------------------- After executing Step 2, a working Kubernetes deployment should be achieved. Launch a busybox container:: kubectl run -i -t $(uuidgen) --image=busybox --restart=Never Verify DNS works properly by running within the container:: nslookup kubernetes This should return a nslookup result without error:: [sdake@kolla ~]$ kubectl run -i -t $(uuidgen) --image=busybox --restart=Never Waiting for pod default/33c30c3b-8130-408a-b32f-83172bca19d0 to be running, status is Pending, pod ready: false # nslookup kubernetes Server: 10.3.3.10 Address 1: 10.3.3.10 kube-dns.kube-system.svc.cluster.local Name: kubernetes Address 1: 10.3.3.1 kubernetes.default.svc.cluster.local .. warning:: If nslookup kubernetes fails, kolla-kubernetes will not deploy correctly. If this occurs check that all preceding steps have been applied correctly, and that the range of IP addresses chosen make sense to your particular environment. Running in a VM can cause nested virtualization and or performance issues. If still stuck seek further assistance from the Kubernetes or Kolla communities. ---------------------------------- Step 3: Deploying kolla-kubernetes ---------------------------------- Override default RBAC settings:: kubectl update -f <(cat < get_helm.sh chmod 700 get_helm.sh ./get_helm.sh helm init watch "kubectl get pods -n kube-system | grep tiller" Verify both the client and server version of Helm are consistent:: helm version Install repositories necessary to install packaging:: sudo yum install -y epel-release sudo yum install -y ansible python-pip python-devel .. note:: You may find it helpful to create a directory to contain the files downloaded during the installaiton of kolla-Kubernetes. To do that:: mkdir kolla-bringup cd kolla-bringup Clone kolla-ansible:: git clone http://github.com/openstack/kolla-ansible Clone kolla-kubernetes:: git clone http://github.com/openstack/kolla-kubernetes Install kolla-kubernetes:: sudo pip install -U kolla-ansible/ kolla-kubernetes/ Copy default kolla configuration to etc:: sudo cp -aR /usr/share/kolla-ansible/etc_examples/kolla /etc Copy default kolla-kubernetes configuration to /etc:: sudo cp -aR kolla-kubernetes/etc/kolla-kubernetes /etc Generate default passwords via SPRNG:: sudo kolla-kubernetes-genpwd Create a kubernetes namespace to isolate this kolla deployment:: kubectl create namespace kolla Label the AIO node as the compute and controller node:: kubectl label node $(hostname) kolla_compute=true kubectl label node $(hostname) kolla_controller=true Modify kolla configuration:: set network_interface in /etc/kolla/globals.yaml to the management interface name. set neutron_external_interface in /etc/kolla/globals.yml to the Neutron interface name. This is the external interface that neutron will use. It must not have an IP address assigned to it. Add required configuration to the end of /etc/kolla/globals.yml:: cat < add-to-globals.yml install_type: "source" tempest_image_alt_id: "{{ tempest_image_id }}" tempest_flavor_ref_alt_id: "{{ tempest_flavor_ref_id }}" neutron_plugin_agent: "openvswitch" api_interface_address: 0.0.0.0 tunnel_interface_address: 0.0.0.0 orchestration_engine: KUBERNETES memcached_servers: "memcached" keystone_admin_url: "http://keystone-admin:35357/v3" keystone_internal_url: "http://keystone-internal:5000/v3" keystone_public_url: "http://keystone-public:5000/v3" glance_registry_host: "glance-registry" neutron_host: "neutron" keystone_database_address: "mariadb" glance_database_address: "mariadb" nova_database_address: "mariadb" nova_api_database_address: "mariadb" neutron_database_address: "mariadb" cinder_database_address: "mariadb" ironic_database_address: "mariadb" placement_database_address: "mariadb" rabbitmq_servers: "rabbitmq" openstack_logging_debug: "True" enable_haproxy: "no" enable_heat: "no" enable_cinder: "yes" enable_cinder_backend_lvm: "yes" enable_cinder_backend_iscsi: "yes" enable_cinder_backend_rbd: "no" enable_ceph: "no" enable_elasticsearch: "no" enable_kibana: "no" glance_backend_ceph: "no" cinder_backend_ceph: "no" nova_backend_ceph: "no" EOF cat ./add-to-globals.yml | sudo tee -a /etc/kolla/globals.yml For operators using virtualization for evaluation purposes please enable QEMU libvirt functionality and enable a workaround for a bug in libvirt:: cat < nova.conf [libvirt] virt_type=qemu cpu_mode=none EOF sudo mkdir /etc/kolla/config sudo cp -a nova.conf /etc/kolla/config .. note:: libvirt in RDO currently contains a bug that requires cpu_mode=none to be specified **only** for virtualized deployments. For more information reference: https://www.redhat.com/archives/rdo-list/2016-December/msg00029.html Generate the default configuration:: sudo kolla-ansible genconfig Generate the Kubernetes secrets and register them with Kubernetes:: kolla-kubernetes/tools/secret-generator.py create Create and register the Kolla config maps:: kollakube res create configmap \ mariadb keystone horizon rabbitmq memcached nova-api nova-conductor \ nova-scheduler glance-api-haproxy glance-registry-haproxy glance-api \ glance-registry neutron-server neutron-dhcp-agent neutron-l3-agent \ neutron-metadata-agent neutron-openvswitch-agent openvswitch-db-server \ openvswitch-vswitchd nova-libvirt nova-compute nova-consoleauth \ nova-novncproxy nova-novncproxy-haproxy neutron-server-haproxy \ nova-api-haproxy cinder-api cinder-api-haproxy cinder-backup \ cinder-scheduler cinder-volume iscsid tgtd keepalived \ placement-api placement-api-haproxy Enable resolv.conf workaround:: kolla-kubernetes/tools/setup-resolv-conf.sh kolla Build all helm microcharts, service charts, and metacharts:: kolla-kubernetes/tools/helm_build_all.sh . Check that all helm images have been built by verifying the number is > 150:: ls | grep ".tgz" | wc -l Create a cloud.yaml file for the deployment of the charts:: global: kolla: all: image_tag: "4.0.0" kube_logger: false external_vip: "192.168.7.105" base_distro: "centos" install_type: "source" tunnel_interface: "docker0" resolve_conf_net_host_workaround: true keystone: all: admin_port_external: "true" dns_name: "192.168.7.105" public: all: port_external: "true" rabbitmq: all: cookie: 67 glance: api: all: port_external: "true" cinder: api: all: port_external: "true" volume_lvm: all: element_name: cinder-volume daemonset: lvm_backends: - '192.168.7.105': 'cinder-volumes' ironic: conductor: daemonset: selector_key: "kolla_conductor" nova: placement_api: all: port_external: true novncproxy: all: port: 6080 port_external: true openvwswitch: all: add_port: true ext_bridge_name: br-ex ext_interface_name: enp1s0f1 setup_bridge: true horizon: all: port_external: true .. note:: The next operation is not a simple copy and paste as the rest of this document is structured. You should determmine your mangement interface which is the value of /etc/kolla/globals.yml and replace the contents of YOUR_NETWORK_INTERFACE_FROM_GLOBALS.YML in the follwoing sed operation. Replace all occurances of 192.168.7.105 with your management interface nic (e.g. eth0):: sed -i "s@192.168.7.105@YOUR_NETWORK_INTERFACE_FROM_GLOBALS.YML@" ./cloud.yaml Replace all occurances of enp1s0f1 with your neutron interface name (e.g. enp1s0f1):: sed -i "s@1enp1s0f1@YOUR_NEUTRON_NETWORK_INTERFACE_FROM_GLOBALS.YML@" ./cloud.yaml .. note:: Some of the variables in the cloud.yaml file that may need to be customized are: set 'external_vip': to the IP address of your management interface set 'dns_name' to the IP address of your management network set 'tunnel_interface': to the IP address of your management interface interface name used for connectivity between nodes in kubernetes cluster, in most of cases it matches the name of the kubernetes host management interface. To determine this, ``grep network_interface /etc/kolla/globals.yml``. set ext_interface_name: to the interface name used for your Neutron network. Start mariadb first and wait for it to enter the RUNNING state:: helm install --debug kolla-kubernetes/helm/service/mariadb --namespace kolla --name mariadb --values ./cloud.yaml Start many of the remaining service level charts:: helm install --debug kolla-kubernetes/helm/service/rabbitmq --namespace kolla --name rabbitmq --values ./cloud.yaml helm install --debug kolla-kubernetes/helm/service/memcached --namespace kolla --name memcached --values ./cloud.yaml helm install --debug kolla-kubernetes/helm/service/keystone --namespace kolla --name keystone --values ./cloud.yaml helm install --debug kolla-kubernetes/helm/service/glance --namespace kolla --name glance --values ./cloud.yaml helm install --debug kolla-kubernetes/helm/service/cinder-control --namespace kolla --name cinder-control --values ./cloud.yaml helm install --debug kolla-kubernetes/helm/service/horizon --namespace kolla --name horizon --values ./cloud.yaml helm install --debug kolla-kubernetes/helm/service/openvswitch --namespace kolla --name openvswitch --values ./cloud.yaml helm install --debug kolla-kubernetes/helm/service/neutron --namespace kolla --name neutron --values ./cloud.yaml helm install --debug kolla-kubernetes/helm/service/nova-control --namespace kolla --name nova-control --values ./cloud.yaml helm install --debug kolla-kubernetes/helm/service/nova-compute --namespace kolla --name nova-compute --values ./cloud.yaml Start some 4.0.0 charts related to the placement API required that are not yet in service charts:: helm install --debug kolla-kubernetes/helm/microservice/nova-placement-deployment --namespace kolla --name nova-placement-deployment --values ./cloud.yaml helm install --debug kolla-kubernetes/helm/microservice/nova-placement-create-keystone-user-job --namespace kolla --name nova-placement-create-keystone-user-job --values ./cloud.yaml helm install --debug kolla-kubernetes/helm/microservice/nova-placement-create-keystone-service-job --namespace kolla --name nova-placement-create-keystone-service-job --values ./cloud.yaml helm install --debug kolla-kubernetes/helm/microservice/nova-placement-svc --namespace kolla --name nova-placement-svc --values ./cloud.yaml helm install --debug kolla-kubernetes/helm/microservice/nova-placement-create-keystone-endpoint-internal-job --namespace kolla --name nova-placement-create-keystone-endpoint-internal --values ./cloud.yaml helm install --debug kolla-kubernetes/helm/microservice/nova-placement-create-keystone-endpoint-admin-job --namespace kolla --name nova-placement-create-keystone-endpoint-admin --values ./cloud.yaml helm install --debug kolla-kubernetes/helm/microservice/nova-placement-create-keystone-endpoint-public-job --namespace kolla --name nova-placement-create-keystone-endpoint-public --values ./cloud.yaml Wait for nova-compute the enter the running state before creating the cell0 database:: helm install --debug kolla-kubernetes/helm/microservice/nova-cell0-create-db-job --namespace kolla --name nova-cell0-create-db-job --values ./cloud.yaml helm install --debug kolla-kubernetes/helm/microservice/nova-api-create-simple-cell-job --namespace kolla --name nova-api-create-simple-cell --values ./cloud.yaml Deploy iSCSI support with Cinder LVM (Optional) The Cinder LVM implementation requires a volume group to be set up. This can either be a real physical volume or a loopback mounted file for development. Use ``pvcreate`` and ``vgcreate`` to create the volume group. For example with the devices ``/dev/sdb`` and ``/dev/sdc``: :: pvcreate /dev/sdb /dev/sdc vgcreate cinder-volumes /dev/sdb /dev/sdc During development, it may be desirable to use file backed block storage. It is possible to use a file and mount it as a block device via the loopback system. :: mknod /dev/loop2 b 7 2 dd if=/dev/zero of=/var/lib/cinder_data.img bs=1G count=20 losetup /dev/loop2 /var/lib/cinder_data.img pvcreate /dev/loop2 vgcreate cinder-volumes /dev/loop2 Note that in the event where iSCSI daemon is active on the host, there is a need to perform the following steps before executing the cinder-volume-lvm helm chart to avoid the iscsd container from going into crash loops: :: sudo systemctl stop iscsid sudo systemctl stop iscsid.socket Execute the cinder-volume-lvm helm chart: :: helm install --debug kolla-kubernetes/helm/service/cinder-volume-lvm --namespace kolla --name cinder-volume-lvm --values ./cloud.yaml Observe the previously running watch command in a different terminal. Wait for all pods to to enter the running state. If you didn't run watch in a different terminal, you can run it now:: watch -d -n 5 -c kubectl get pods --all-namespaces Generate openrc file:: kolla-kubernetes/tools/build_local_admin_keystonerc.sh ext source ~/keystonerc_admin .. note:: The ``ext`` option to create the keystonerc creates a keystonerc file that is compatible with this guide. Install OpenStack Clients:: sudo pip install "python-openstackclient" sudo pip install "python-neutronclient" sudo pip install "python-cinderclient" Bootstrap the cloud envrionment and create a VM as requested:: kolla-ansible/tools/init-runonce Create a floating IP address and add to the VM:: openstack server add floating ip demo1 $(openstack floating ip create public1 -f value -c floating_ip_address) --------------- Troubleshooting --------------- .. warning:: Some of these steps are dangerous. Be warned. To cleanup the database entry for a specific service such as nova: helm install --debug /opt/kolla-kubernetes//helm/service/nova-cleanup --namespace kolla --name nova-cleanup --values cloud.yaml To delete a helm chart:: helm delete --purge mariadb To delete all helm charts:: helm delete mariadb --purge helm delete rabbitmq --purge helm delete memcached --purge helm delete keystone --purge helm delete glance --purge helm delete cinder-control --purge helm delete horizon --purge helm delete openvswitch --purge helm delete neutron --purge helm delete nova-control --purge helm delete nova-compute --purge helm delete nova-cell0-create-db-job --purge helm delete nova-placement-deployment --purge helm delete cinder-volume-lvm --purge To clean up the host volumes between runs:: sudo rm -rf /var/lib/kolla/volumes/* To clean up Kubernetes and all docker containers entirely, run this command, reboot, and run these commands again:: sudo kubeadm reset