├── 1-deploy-multipass-vms.sh ├── 1-deploy-only-vms.sh ├── 2-deploy-rke.sh ├── 3-deploy-rancher-on-rke-mkcert-macos.sh ├── 3-deploy-rancher-on-rke.sh ├── LICENSE ├── README.md ├── cleanup-rkes.sh ├── cloud-config-systemd-resolved.yaml ├── cloud-config.yaml ├── cluster-1cp-2workers.yml ├── cluster.yml ├── create-hosts.sh ├── deploy.sh ├── extended-cleanup-rancher2.sh ├── install-metal-lb.sh ├── metal-lb-layer2-config.yaml ├── nginx-local-ssl ├── Dockerfile ├── README.md ├── generate-certs.sh ├── nginx-local-ssl.yaml └── nginx.config ├── nginx.yaml ├── populate_hosts_file.sh └── rke-rancher-nginx.png /1-deploy-multipass-vms.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # multipass delete $(echo rke{1..3}) 3 | NODES=$(echo rke{1..3}) 4 | 5 | # Create containers 6 | for NODE in ${NODES}; do multipass launch --name ${NODE} --cpus 2 --mem 4G --disk 10G --cloud-init cloud-config-systemd-resolved.yaml; done 7 | # for NODE in ${NODES}; do multipass launch --name ${NODE} --cpus 2 --mem 2G --disk 8G --cloud-init cloud-config.yaml; done 8 | # for NODE in ${NODES}; do multipass launch --name ${NODE} --cloud-init cloud-config.yaml; done 9 | # for NODE in ${NODES}; do multipass launch --name ${NODE}; done 10 | 11 | # Wait a few seconds for nodes to be up 12 | sleep 10 13 | 14 | echo "############################################################################" 15 | echo "multipass containers installed:" 16 | multipass ls 17 | echo "############################################################################" 18 | 19 | # Install Docker 20 | for NODE in ${NODES}; do 21 | # multipass exec ${NODE} -- bash -c 'curl https://releases.rancher.com/install-docker/18.09.sh | sh' 22 | # multipass exec ${NODE} -- bash -c 'curl https://releases.rancher.com/install-docker/19.03.sh | sh' 23 | multipass exec ${NODE} -- bash -c 'curl https://releases.rancher.com/install-docker/20.10.sh | sh' 24 | multipass exec ${NODE} -- sudo usermod -aG docker ubuntu 25 | multipass exec ${NODE} -- sudo docker --version 26 | multipass exec ${NODE} -- bash -c 'sudo apt-get install -y uidmap' 27 | multipass exec ${NODE} -- bash -c 'dockerd-rootless-setuptool.sh install --force' 28 | multipass exec ${NODE} -- bash -c 'echo "export PATH=/usr/bin:$PATH" >> ~/.bashrc' 29 | multipass exec ${NODE} -- bash -c 'echo "export DOCKER_HOST=unix:///run/user/1000/docker.sock" >> ~/.bashrc' 30 | multipass exec ${NODE} -- bash -c 'systemctl --user restart docker.service' 31 | multipass exec ${NODE} -- bash -c 'systemctl --user status docker.service >/dev/null' 32 | done 33 | 34 | # Print nodes ip addresses 35 | for NODE in ${NODES}; do 36 | multipass exec ${NODE} -- bash -c 'echo -n "$(hostname) " ; ip -4 addr show enp0s2 | grep -oP "(?<=inet ).*(?=/)"' 37 | # multipass exec ${NODE} -- bash -c 'ip -4 addr show enp0s2 | grep -oP "(?<=inet ).*(?=/)";echo -n "$(hostname) "' 38 | done 39 | 40 | # Create the hosts file 41 | ./create-hosts.sh > hosts 42 | 43 | for NODE in ${NODES}; do 44 | # multipass transfer hosts ${NODE}:/home/ubuntu/ 45 | # workaround due to this issue: https://github.com/CanonicalLtd/multipass/issues/1165#issuecomment-548762510 46 | multipass transfer hosts ${NODE}: 47 | multipass exec ${NODE} -- bash -c 'sudo chown ubuntu:ubuntu /etc/hosts' 48 | multipass exec ${NODE} -- bash -c 'sudo cat /home/ubuntu/hosts >> /etc/hosts' 49 | multipass transfer ~/.ssh/id_rsa.pub ${NODE}: 50 | multipass exec ${NODE} -- bash -c 'sudo cat /home/ubuntu/id_rsa.pub >> .ssh/authorized_keys' 51 | done 52 | 53 | echo "We need to write the rke host entries on your local machine to /etc/hosts" 54 | echo "Your /etc/hosts file will be backup'ed as /etc/hosts.backup.today and etchosts in the current directory" 55 | echo "Please provide your sudo password:" 56 | sudo cp /etc/hosts /etc/hosts.backup.today 57 | sudo cp /etc/hosts etchosts 58 | sudo cat hosts | sudo tee -a etchosts 59 | sudo cp etchosts /etc/hosts 60 | # # workaround to get rid of characters appear as ^M in the hosts file (OSX Catalina) 61 | # tr '\r' '\n' < etchosts > etchosts.unix 62 | # cp etchosts.unix /etc/hosts 63 | 64 | echo "############################################################################" 65 | echo "Make sure your /etc/hosts file on your localhost and the multipass hosts" 66 | echo "have these host entries like this:" 67 | cat hosts 68 | # the below command works only if the /etc/hosts file is owned by your user and not the root user 69 | # run sudo chown /etc/hosts and uncomment the line below 70 | echo "" 71 | echo "and run ./2-deploy-rke.sh" 72 | echo "############################################################################" 73 | -------------------------------------------------------------------------------- /1-deploy-only-vms.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # multipass delete $(echo rke{1..3}) 3 | NODES=$(echo rke{1..3}) 4 | 5 | # Create containers 6 | for NODE in ${NODES}; do multipass launch --name ${NODE} --cpus 2 --mem 4G --disk 10G ; done 7 | -------------------------------------------------------------------------------- /2-deploy-rke.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # rm -fv kube_config_cluster.yml 4 | 5 | echo "downloading rke v1.2.11" 6 | # wget https://github.com/rancher/rke/releases/download/v0.2.8/rke_linux-amd64 7 | # sudo chmod +x rke_linux-amd64 8 | #./rke_linux-amd64 up --config cluster.yml 9 | # wget https://github.com/rancher/rke/releases/download/v0.2.8/rke_darwin-amd64 10 | # wget https://github.com/rancher/rke/releases/download/v0.3.0/rke_darwin-amd64 11 | # wget https://github.com/rancher/rke/releases/download/v0.3.2/rke_darwin-amd64 12 | # wget https://github.com/rancher/rke/releases/download/v1.0.8/rke_darwin-amd64 13 | # wget https://github.com/rancher/rke/releases/download/v1.1.7/rke_darwin-amd64 14 | # wget https://github.com/rancher/rke/releases/download/v1.1.19/rke_darwin-amd64 15 | # wget https://github.com/rancher/rke/releases/download/v1.2.11/rke_darwin-amd64 16 | wget https://github.com/rancher/rke/releases/download/v1.3.2/rke_darwin-amd64 17 | chmod +x ./rke_darwin-amd64 18 | ./rke_darwin-amd64 up --config cluster.yml 19 | # if something goes wrong, remore rke 20 | # ./rke_darwin-amd64 remove --config cluster.yml 21 | sleep 30 22 | # echo "downloading kubectl" 23 | # curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.15.0/bin/linux/amd64/kubectl 24 | # curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.15.0/bin/darwin/amd64/kubectl 25 | # chmod +x ./kubectl 26 | 27 | echo "############################################################################" 28 | export KUBECONFIG=kube_config_cluster.yml 29 | kubectl -n kube-system rollout status deployment/calico-kube-controllers 30 | # kubectl -n cattle-system rollout status daemonset.apps/cattle-node-agent 31 | kubectl get nodes 32 | echo "are the nodes ready?" 33 | echo "if you face problems, please open an issue on github" 34 | echo "make sure all pods are running before deploying Rancher Server on your RKE" 35 | echo "run:" 36 | echo "KUBECONFIG=kube_config_cluster.yml kubectl get all -A" 37 | echo "This may take about 5 minutes" 38 | echo "All fine?" 39 | echo "Now run ./3-deploy-rancher-on-rke.sh" 40 | echo "or" 41 | echo "Now run ./3-deploy-rancher-on-rke-mkcert-macos.sh" 42 | echo "############################################################################" 43 | 44 | # Upgrade to k8s 1.14.6 45 | # echo "download rke v0.2.8 for k8s 1.14.6" 46 | # wget https://github.com/rancher/rke/releases/download/v0.2.8/rke_linux-amd64 47 | # chmod +x rke_linux-amd64 48 | # mv rke_linux-amd64 rke028 49 | # vi cluster.yml 50 | # set #kubernetes: rancher/hyperkube:v1.14.6-rancher1 51 | # cp .kube/config kube_config_cluster.yml 52 | # ./rke028 up 53 | 54 | 55 | # Create cluster.yaml file 56 | # rm -fv kube_config_cluster.yml 57 | # cat cluster.yml.template > cluster.yml 58 | # for NODE in ${NODES}; do 59 | # [[ "${NODE}" =~ "rke" ]] && sed -i -e "s/${NODE}/$(lxc exec ${NODE} -- bash -c 'ip -4 addr show eth0 | grep -oP "(?<=inet ).*(?=/)"')/" cluster.yml 60 | # done 61 | 62 | # Deploy Kubernetes cluster with rke 63 | # rke up 64 | 65 | # Install rancher on rancher node 66 | # lxc exec rancher -- docker run -d --restart=unless-stopped -p 80:80 -p 443:443 rancher/rancher 67 | 68 | # Open rancher webui 69 | # echo $(lxc exec rancher -- ip -4 addr show eth0 | grep -oP "(?<=inet ).*(?=/)" ) 70 | # xdg-open https://$(lxc exec rancher -- ip -4 addr show eth0 | grep -oP "(?<=inet ).*(?=/)" ) 71 | -------------------------------------------------------------------------------- /3-deploy-rancher-on-rke-mkcert-macos.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | export KUBECONFIG=kube_config_cluster.yml 3 | ## helm 2 4 | # kubectl -n kube-system create serviceaccount tiller 5 | # kubectl create clusterrolebinding tiller --clusterrole=cluster-admin --serviceaccount=kube-system:tiller 6 | # curl -LO https://git.io/get_helm.sh 7 | # chmod 700 get_helm.sh 8 | # ./get_helm.sh 9 | # helm init --service-account tiller 10 | # kubectl rollout status deployment tiller-deploy -n kube-system 11 | #helm install stable/cert-manager --name cert-manager --namespace kube-system --version v0.5.2 12 | #sleep 60 13 | #kubectl -n kube-system rollout status deploy/cert-manager 14 | # didn't work anymore with rancher slfsigned cert 15 | # helm install --name rancher rancher-latest/rancher --namespace cattle-system --set hostname=rke1 --set tls=external 16 | 17 | # Use own CA certs and keys with mkcert 18 | # install mkcert 19 | # brew install mkcert 20 | # mkcert — install 21 | mkcert '*.rancher.svc' 22 | # on MacOS 23 | cp $HOME/Library/Application\ Support/mkcert/rootCA.pem cacerts.pem 24 | # on Ubuntu Linux 25 | # cp /home/ubuntu/.local/share/mkcert/rootCA.pem cacerts.pem 26 | cp _wildcard.rancher.svc.pem cert.pem 27 | cp _wildcard.rancher.svc-key.pem key.pem 28 | # in /etc/hosts set 29 | # 192.168.64.23 gui.rancher.svc rke1 30 | # the ip 192.168.64.23 can be any ip of rke1, rke2 or rke3 31 | export rancherip=`cat hosts | grep rke1 | awk '{print $1}'` 32 | sudo -- sh -c "echo $rancherip gui.rancher.svc >> /etc/hosts" 33 | helm repo add rancher-stable https://releases.rancher.com/server-charts/stable 34 | kubectl create ns cattle-system 35 | kubectl -n cattle-system create secret generic tls-ca --from-file=./cacerts.pem 36 | kubectl -n cattle-system create secret tls tls-rancher-ingress --cert=./cert.pem --key=./key.pem 37 | helm install rancher rancher-stable/rancher --namespace cattle-system --set hostname=gui.rancher.svc --set replicas=3 --set ingress.tls.source=secret --set privateCA=true 38 | echo "############################################################################" 39 | echo "This should take about 4 minutes, wait for the browser to pop up and enjoy :-)" 40 | echo "############################################################################" 41 | kubectl -n cattle-system rollout status deploy/rancher 42 | open https://gui.rancher.svc 43 | # you should get a vaild cert 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /3-deploy-rancher-on-rke.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | export KUBECONFIG=kube_config_cluster.yml 3 | kubectl -n kube-system create serviceaccount tiller 4 | kubectl create clusterrolebinding tiller --clusterrole=cluster-admin --serviceaccount=kube-system:tiller 5 | curl -LO https://git.io/get_helm.sh 6 | chmod 700 get_helm.sh 7 | ./get_helm.sh 8 | helm init --service-account tiller 9 | kubectl rollout status deployment tiller-deploy -n kube-system 10 | #helm install stable/cert-manager --name cert-manager --namespace kube-system --version v0.5.2 11 | #sleep 60 12 | #kubectl -n kube-system rollout status deploy/cert-manager 13 | # helm repo add rancher-latest https://releases.rancher.com/server-charts/latest 14 | helm repo add rancher-stable https://releases.rancher.com/server-charts/stable 15 | kubectl create ns cattle-system 16 | kubectl -n cattle-system create secret generic tls-ca --from-file=./ca/rancher/cacerts.pem 17 | kubectl -n cattle-system create secret tls tls-rancher-ingress --cert=./ca/rancher/cert.pem --key=./ca/rancher/key.pem 18 | helm install --name rancher rancher-stable/rancher --namespace cattle-system --set hostname=rke1 --set ingress.tls.source=secret --set privateCA=true 19 | # helm install --name rancher rancher-latest/rancher --namespace cattle-system --set hostname=rke1 --set ingress.tls.source=secret --set privateCA=true 20 | # didn't work anymore with rancher slfsigned cert 21 | # helm install --name rancher rancher-latest/rancher --namespace cattle-system --set hostname=rke1 --set tls=external 22 | 23 | # Use own CA certs and keys with mkcert 24 | 25 | # brew install mkcert 26 | # mkcert — install 27 | # mkcert '*.rancher.svc' 28 | # on MacOS 29 | # cp $HOME/Library/Application\ Support/mkcert/rootCA.pem cacerts.pem 30 | # on Ubuntu Linux 31 | # cp /home/ubuntu/.local/share/mkcert/rootCA.pem cacerts.pem 32 | # cp _wildcard.rancher.svc.pem cert.pem 33 | # cp _wildcard.rancher.svc-key.pem key.pem 34 | # in /etc/hosts set 35 | # 192.168.64.14 rke1.rancher.svc rke1 36 | # helm repo add rancher-stable https://releases.rancher.com/server-charts/stable 37 | # kubectl create ns cattle-system 38 | # kubectl -n cattle-system create secret generic tls-ca --from-file=./cacerts.pem 39 | # kubectl -n cattle-system create secret tls tls-rancher-ingress --cert=./cert.pem --key=./key.pem 40 | # helm install --name rancher rancher-stable/rancher --namespace cattle-system --set hostname=rke1.rancher.svc --set ingress.tls.source=secret --set privateCA=true 41 | # open https://rke1.rancher.svc (you should get a vaild cert) 42 | 43 | 44 | 45 | echo "############################################################################" 46 | echo "This should take about 4 minutes, wait for the browser to pop up and enjoy :-)" 47 | echo "############################################################################" 48 | kubectl -n cattle-system rollout status deploy/rancher 49 | open https:/rke1 50 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Rancher Kubernetes Engine and Rancher Cluster Manager (2.6.2 Stable) on Multipass VMs with rootless Docker 2 | ![rke-rancher-nginx.png](rke-rancher-nginx.png) 3 | 4 | ## Who should use this? 5 | 6 | Those Ops or sometimes Devs who'd like to get familiar with a full-fledged Rancher Kubernetes Engine (RKE) and Rancher Cluster Manager on their local machine using Multipass VMs to reduce their cloud costs. 7 | 8 | This implementation uses a rootless docker and `mimikes` a near to production installation of RKE to host a Rancher Cluster Manager. 9 | 10 | ![#f03c15](https://via.placeholder.com/15/f03c15/000000?text=+) **NOTE: `This implementation is not tested on production environments!`** 11 | 12 | ## Prerequisites 13 | 14 | You need Multipass running on your local machine with mkcert and helm installed: 15 | 16 | [multipass] https://multipass.run/ 17 | 18 | [mkcert](https://github.com/FiloSottile/mkcert) 19 | 20 | [helm](https://helm.sh/docs/intro/install/) 21 | 22 | This setup was tested on MacOS, but should work on Linux or maybe on Windows with WSL2 too. 23 | 24 | This setup uses and was tested with the following tools and components: 25 | 26 | * rke cli version v1.3.2 27 | * kubectl version 1.20.9 28 | * docker community version 20.10.7 29 | * containerd version 1.4.9 30 | * runc version 1.0.1 31 | * mkcert version v1.4.1 32 | * helm version v3.2.4 33 | 34 | You need to have about 6GB RAM and 30GB storage on your local machine. 35 | 36 | You need kubectl in your path, if not, you can download the v1.20.9 version and place it in your path: 37 | 38 | MacOS users: 39 | 40 | ```bash 41 | curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.20.9/bin/darwin/amd64/kubectl 42 | ``` 43 | 44 | Linux users: 45 | 46 | ```bash 47 | curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.20.9/bin/linux/amd64/kubectl 48 | ``` 49 | 50 | ```bash 51 | chmod +x ./kubectl 52 | mv kubectl /usr/local/bin/ 53 | ``` 54 | ### Important hint for linux users 55 | 56 | Linux users should adapt the `create-hosts.sh` and change the network interface name. You can find the nic name with: 57 | 58 | ```bash 59 | multipass launch --name test 60 | multipass exec test -- bash -c 'echo `ls /sys/class/net | grep en`' 61 | ``` 62 | 63 | Delete and purge the test VM: 64 | 65 | ```bash 66 | multipass delete test 67 | multipass purge 68 | ``` 69 | 70 | If the above doesn't work somehow, shell into the node and get the nic name: 71 | 72 | ```bash 73 | multipass shell test 74 | ifconfig 75 | ``` 76 | 77 | ![#f03c15](https://via.placeholder.com/15/f03c15/000000?text=+) **NOTE: `you need to provide your sudo password during the setup at your own risk, please study the scripts and don't trust me.`** 78 | 79 | 80 | Clone this repo and run the scripts as follow: 81 | 82 | ```bash 83 | git clone https://github.com/arashkaffamanesh/multipass-rke-rancher.git 84 | cd multipass-rke-rancher 85 | ./1-deploy-multipass-vms.sh 86 | ./2-deploy-rke.sh 87 | # or with mkcert to get a vaild certificate (on macos), you need to install mkcert, pls. have a look in the script 88 | ./3-deploy-rancher-on-rke-mkcert-macos.sh 89 | ``` 90 | 91 | To deploy with a single command, please run: 92 | 93 | ```bash 94 | ./deploy.sh 95 | ``` 96 | 97 | ## What you get 98 | 99 | You should get a running RKE Cluster on 3 Multipass VMs with Rancher Server on top in about 20 minutes (depends on your CPU / internet speed and docker hub performance). 100 | 101 | ## Export KUBECONFIG 102 | 103 | After installation your kubeconfig file will be placed in the installation folder, please run: 104 | 105 | ``` 106 | export KUBECONFIG=`pwd`/kube_config_cluster.yml 107 | kubectl get all -A 108 | ``` 109 | 110 | **Tip**: use [Kubie](https://github.com/sbstp/kubie) to manage your clusters! 111 | 112 | Kubie is an alternative to kubectx, kubens and the k on prompt modification script. 113 | ## Access the Rancher Server on RKE 114 | 115 | A tab will open in your browser and point to: 116 | 117 | https://gui.rancher.svc/ 118 | 119 | ## Install Metal-LB 120 | 121 | Install Metal-LB to have support for service type LoadBalancer. 122 | 123 | **Note:** Please adapt the ip range in `metal-lb-layer2-config.yaml` before running the `install-metal-lb.sh` script. 124 | 125 | ```bash 126 | ./install-metal-lb.sh 127 | # Test the metal lb install with the custom built nginx server with self signed certificate and port 443 enabled: 128 | # plese refer to the README.md under nginx-local-ssl 129 | k create -f nginx-local-ssl/nginx-local-ssl.yaml 130 | k get svc 131 | ## adapt the external ip in the command below 132 | sudo -- sh -c "echo 192.168.64.18 nginx.local >> /etc/hosts" 133 | curl -k https://nginx.local 134 | ``` 135 | 136 | ## Clean Up 137 | 138 | Cleanup your multipass VMs: 139 | 140 | ```bash 141 | ./cleanup-rkes.sh 142 | ``` 143 | 144 | ## Blog post 145 | 146 | Blog post will be published on medium: 147 | 148 | https://blog.kubernauts.io/ 149 | -------------------------------------------------------------------------------- /cleanup-rkes.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | multipass stop rke1 rke2 rke3 3 | multipass delete rke1 rke2 rke3 4 | multipass purge 5 | rm hosts cluster.rkestate kube_config_cluster.yml get_helm.sh rke_darwin-amd64 6 | echo "Please cleanup the host entries in your /etc/hosts manually" 7 | -------------------------------------------------------------------------------- /cloud-config-systemd-resolved.yaml: -------------------------------------------------------------------------------- 1 | #cloud-config 2 | bootcmd: 3 | - printf "[Resolve]\nDNS=8.8.8.8" > /etc/systemd/resolved.conf 4 | - [systemctl, restart, systemd-resolved] 5 | -------------------------------------------------------------------------------- /cloud-config.yaml: -------------------------------------------------------------------------------- 1 | #cloud-config 2 | # Add groups to the system 3 | # The following example adds the ubuntu group with members 'root' and 'sys' 4 | # and the empty group cloud-users. 5 | groups: 6 | - ubuntu: [root,sys] 7 | - cloud-users 8 | 9 | # Add users to the system. Users are added after groups are added. 10 | users: 11 | - default 12 | - name: rke 13 | gecos: kubernauts 14 | sudo: ALL=(ALL) NOPASSWD:ALL 15 | groups: users, admin 16 | ssh_import_id: None 17 | lock_passwd: true 18 | ssh_authorized_keys: 19 | - ssh-rsa AAAAB3NzaC1......... 20 | - name: cloudy 21 | gecos: Magic Cloud App Daemon User 22 | inactive: true 23 | system: true 24 | ssh_redirect_user: true 25 | -------------------------------------------------------------------------------- /cluster-1cp-2workers.yml: -------------------------------------------------------------------------------- 1 | nodes: 2 | - address: rke1 3 | role: 4 | - controlplane 5 | - etcd 6 | user: ubuntu 7 | ssh_key_path: ~/.ssh/id_rsa 8 | hostname_override: rke1 9 | - address: rke2 10 | role: 11 | - worker 12 | user: ubuntu 13 | ssh_key_path: ~/.ssh/id_rsa 14 | hostname_override: rke2 15 | - address: rke3 16 | role: 17 | - worker 18 | user: ubuntu 19 | ssh_key_path: ~/.ssh/id_rsa 20 | hostname_override: rke3 21 | 22 | cluster_name: mgmt 23 | 24 | authorization: 25 | mode: rbac 26 | -------------------------------------------------------------------------------- /cluster.yml: -------------------------------------------------------------------------------- 1 | 2 | ignore_docker_version: true 3 | ssh_key_path: ~/.ssh/id_rsa 4 | network: 5 | plugin: calico 6 | # plugin: flannel 7 | # plugin: canal 8 | system_images: 9 | # kubernetes: rancher/hyperkube:v1.13.5-rancher1 10 | # kubernetes: rancher/hyperkube:v1.14.6-rancher1 11 | # kubernetes: rancher/hyperkube:v1.15.5-rancher1 12 | # kubernetes: rancher/hyperkube:v1.16.2-rancher1 13 | # kubernetes: rancher/hyperkube:v1.17.5-rancher1 14 | # kubernetes: rancher/hyperkube:v1.20.9-rancher1 15 | kubernetes: rancher/hyperkube:v1.21.6-rancher1 16 | nodes: 17 | - address: rke1 18 | user: ubuntu 19 | role: [controlplane,worker,etcd] 20 | # labels: 21 | # app: dns 22 | - address: rke2 23 | user: ubuntu 24 | role: [controlplane,worker,etcd] 25 | - address: rke3 26 | user: ubuntu 27 | role: [controlplane,worker,etcd] 28 | services: 29 | etcd: 30 | snapshot: true 31 | creation: 6h 32 | retention: 24h 33 | # dns: 34 | # provider: coredns 35 | # node_selector: 36 | # app: dns 37 | 38 | cluster_name: rke-mgmt-local 39 | 40 | authorization: 41 | mode: rbac 42 | -------------------------------------------------------------------------------- /create-hosts.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | NODES=$(echo rke{1..3}) 3 | for NODE in ${NODES}; do 4 | # multipass exec ${NODE} -- bash -c 'echo `ip -4 addr show enp0s2 | grep -oP "(?<=inet ).*(?=/)"` `echo $(hostname)` | sudo tee -a /etc/hosts' 5 | multipass exec ${NODE} -- bash -c 'echo `ip -4 addr show enp0s2 | grep -oP "(?<=inet ).*(?=/)"` `echo $(hostname)`' 6 | done 7 | -------------------------------------------------------------------------------- /deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | res1=$(date +%s) 3 | ./1-deploy-multipass-vms.sh 4 | ./2-deploy-rke.sh 5 | ./3-deploy-rancher-on-rke-mkcert-macos.sh 6 | #./3-deploy-rancher-on-rke.sh 7 | res2=$(date +%s) 8 | dt=$(echo "$res2 - $res1" | bc) 9 | dd=$(echo "$dt/86400" | bc) 10 | dt2=$(echo "$dt-86400*$dd" | bc) 11 | dh=$(echo "$dt2/3600" | bc) 12 | dt3=$(echo "$dt2-3600*$dh" | bc) 13 | dm=$(echo "$dt3/60" | bc) 14 | ds=$(echo "$dt3-60*$dm" | bc) 15 | # printf "Total runtime: %d:%02d:%02d:%02.4f\n" $dd $dh $dm $ds 16 | printf "Total runtime in minutes: %02d:%02.f\n" $dm $ds 17 | echo "############################################################################" 18 | 19 | -------------------------------------------------------------------------------- /extended-cleanup-rancher2.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | docker rm -f $(docker ps -qa) 3 | docker rmi -f $(docker images -q) 4 | docker volume rm $(docker volume ls -q) 5 | for mount in $(mount | grep tmpfs | grep '/var/lib/kubelet' | awk '{ print $3 }') /var/lib/kubelet /var/lib/rancher; do umount $mount; done 6 | cleanupdirs="/etc/ceph /etc/cni /etc/kubernetes /opt/cni /opt/rke /run/secrets/kubernetes.io /run/calico /run/flannel /var/lib/calico /var/lib/etcd /var/lib/cni /var/lib/kubelet /var/lib/rancher/rke/log /var/log/containers /var/log/pods /var/run/calico" 7 | for dir in $cleanupdirs; do 8 | echo "Removing $dir" 9 | rm -rf $dir 10 | done 11 | cleanupinterfaces="flannel.1 cni0 tunl0" 12 | for interface in $cleanupinterfaces; do 13 | echo "Deleting $interface" 14 | ip link delete $interface 15 | done 16 | echo "flushing all iptables" 17 | iptables -P INPUT ACCEPT 18 | iptables -P FORWARD ACCEPT 19 | iptables -P OUTPUT ACCEPT 20 | iptables -t nat -F 21 | iptables -t mangle -F 22 | iptables -F 23 | iptables -X 24 | echo "restarting docker" 25 | /etc/init.d/docker restart -------------------------------------------------------------------------------- /install-metal-lb.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | GREEN='\033[0;32m' 3 | LB='\033[1;34m' # light blue 4 | NC='\033[0m' # No Color 5 | 6 | echo -e "[${GREEN}Deploying MetalLB LoadBalancer${NC}]" 7 | echo "############################################################################" 8 | 9 | export KUBECONFIG=`pwd`/kube_config_cluster.yml 10 | 11 | kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.5/manifests/namespace.yaml 12 | kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.5/manifests/metallb.yaml 13 | # On first install only 14 | kubectl create secret generic -n metallb-system memberlist --from-literal=secretkey="$(openssl rand -base64 128)" 15 | kubectl create -f metal-lb-layer2-config.yaml 16 | -------------------------------------------------------------------------------- /metal-lb-layer2-config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | namespace: metallb-system 5 | name: config 6 | data: 7 | config: | 8 | address-pools: 9 | - name: default 10 | protocol: layer2 11 | addresses: 12 | - 192.168.64.18-192.168.64.254 13 | -------------------------------------------------------------------------------- /nginx-local-ssl/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:18.04 2 | 3 | MAINTAINER Kubernauts 4 | 5 | # install nginx 6 | RUN apt-get update -y 7 | RUN apt-get install -y software-properties-common 8 | RUN add-apt-repository -y ppa:nginx/stable 9 | RUN apt-get update -y 10 | RUN apt-get install -y nginx 11 | 12 | # deamon mode off 13 | RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf 14 | RUN chown -R www-data:www-data /var/lib/nginx 15 | 16 | # expose ports 17 | EXPOSE 80 443 18 | 19 | # add nginx conf 20 | ADD nginx.config /etc/nginx/sites-available/nginx.local 21 | 22 | # create symlinks 23 | RUN ln -s /etc/nginx/sites-available/nginx.local /etc/nginx/sites-enabled/nginx.local 24 | 25 | # add server certs 26 | ADD server.crt /etc/nginx/certs/server.crt 27 | ADD server.key /etc/nginx/certs/server.key 28 | 29 | WORKDIR /etc/nginx 30 | 31 | CMD ["nginx"] 32 | -------------------------------------------------------------------------------- /nginx-local-ssl/README.md: -------------------------------------------------------------------------------- 1 | # Nginx with self signed SSL 2 | 3 | ## Create certs and keys with mkcert 4 | 5 | ``` 6 | mkcert '*.nginx.local' 7 | cp _wildcard.nginx.local.pem server.crt 8 | cp _wildcard.nginx.local-key.pem server.key 9 | rm _wildcard.nginx.local.pem 10 | rm _wildcard.nginx.local-key.pem 11 | # kubectl create secret tls tls-nginx-local --cert=./server.crt --key=./server.key 12 | kubectl create secret generic tls-nginx-local --from-file=./server.crt --from-file=./server.key 13 | ``` 14 | ## Build the nginx.local image and push 15 | 16 | Change kubernautslabs with your own dockerhub account name: 17 | 18 | ``` 19 | docker build -t kubernautslabs/nginx.local . 20 | docker push kubernautslabs/nginx.local:latest 21 | ``` 22 | ## Related resources 23 | 24 | https://medium.com/rahasak/set-up-ssl-certificates-on-nginx-c51f7dc00272 25 | 26 | https://github.com/nginxinc/kubernetes-ingress 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /nginx-local-ssl/generate-certs.sh: -------------------------------------------------------------------------------- 1 | # generate CA key and certificate 2 | openssl genrsa -des3 -out ca.key 4096 3 | openssl req -new -x509 -days 365 -key ca.key -out ca.crt 4 | 5 | # generate server key 6 | # generate CSR (certificate sign request) to obtain certificate 7 | openssl genrsa -des3 -out server.key 1024 8 | openssl req -new -key server.key -out server.csr 9 | 10 | # sign server CSR with CA certificate and key 11 | openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt 12 | 13 | # remove pass phase from server key 14 | openssl rsa -in server.key -out temp.key 15 | rm server.key 16 | mv temp.key server.key -------------------------------------------------------------------------------- /nginx-local-ssl/nginx-local-ssl.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | labels: 6 | app: nginx 7 | name: nginx 8 | spec: 9 | replicas: 1 10 | selector: 11 | matchLabels: 12 | app: nginx 13 | template: 14 | metadata: 15 | labels: 16 | app: nginx 17 | spec: 18 | containers: 19 | - image: kubernautslabs/nginx.local 20 | name: nginx-local 21 | ports: 22 | - containerPort: 443 23 | protocol: TCP 24 | --- 25 | apiVersion: v1 26 | kind: Service 27 | metadata: 28 | name: nginx 29 | spec: 30 | ports: 31 | - port: 443 32 | protocol: TCP 33 | targetPort: 443 34 | selector: 35 | app: nginx 36 | sessionAffinity: None 37 | type: LoadBalancer 38 | --- 39 | apiVersion: networking.k8s.io/v1 40 | kind: Ingress 41 | metadata: 42 | name: nginx 43 | annotations: 44 | ingress.kubernetes.io/ssl-redirect: "true" 45 | spec: 46 | rules: 47 | - host: nginx.local 48 | http: 49 | paths: 50 | - path: / 51 | pathType: Prefix 52 | backend: 53 | service: 54 | name: nginx 55 | port: 56 | number: 443 57 | tls: 58 | - hosts: 59 | - nginx.local 60 | secretName: tls-nginx-local 61 | -------------------------------------------------------------------------------- /nginx-local-ssl/nginx.config: -------------------------------------------------------------------------------- 1 | server { 2 | listen 443 ssl; 3 | server_name nginx.local; 4 | 5 | ssl_certificate /etc/nginx/certs/server.crt; 6 | ssl_certificate_key /etc/nginx/certs/server.key; 7 | 8 | } 9 | -------------------------------------------------------------------------------- /nginx.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | labels: 6 | app: nginx 7 | name: nginx 8 | spec: 9 | replicas: 1 10 | selector: 11 | matchLabels: 12 | app: nginx 13 | template: 14 | metadata: 15 | labels: 16 | app: nginx 17 | spec: 18 | containers: 19 | - image: nginx 20 | name: nginx 21 | ports: 22 | - containerPort: 80 23 | protocol: TCP 24 | --- 25 | apiVersion: v1 26 | kind: Service 27 | metadata: 28 | name: nginx 29 | spec: 30 | ports: 31 | - port: 80 32 | protocol: TCP 33 | targetPort: 80 34 | selector: 35 | app: nginx 36 | sessionAffinity: None 37 | type: LoadBalancer 38 | --- 39 | apiVersion: extensions/v1beta1 40 | kind: Ingress 41 | metadata: 42 | name: nginx 43 | annotations: 44 | ingress.kubernetes.io/ssl-redirect: "false" 45 | spec: 46 | rules: 47 | - http: 48 | paths: 49 | - path: / 50 | backend: 51 | serviceName: nginx 52 | servicePort: 80 53 | -------------------------------------------------------------------------------- /populate_hosts_file.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # insert/update hosts entry 4 | ip_address=`ip -4 addr show enp0s2 | grep -oP "(?<=inet ).*(?=/)"` 5 | host_name="rke1" 6 | # find existing instances in the host file and save the line numbers 7 | matches_in_hosts="$(grep -n $host_name /etc/hosts | cut -f1 -d:)" 8 | host_entry="${ip_address} ${host_name}" 9 | 10 | echo "Please enter your password if requested." 11 | 12 | if [ ! -z "$matches_in_hosts" ] 13 | then 14 | echo "Updating existing hosts entry." 15 | # iterate over the line numbers on which matches were found 16 | while read -r line_number; do 17 | # replace the text of each line with the desired host entry 18 | sudo sed -i '' "${line_number}s/.*/${host_entry} /" /etc/hosts 19 | done <<< "$matches_in_hosts" 20 | else 21 | echo "Adding new hosts entry." 22 | echo "$host_entry" | sudo tee -a /etc/hosts > /dev/null 23 | fi -------------------------------------------------------------------------------- /rke-rancher-nginx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arashkaffamanesh/multipass-rke-rancher/5074e84c8ae4b88724e0105c067944428372cdf3/rke-rancher-nginx.png --------------------------------------------------------------------------------