In this blog post, I’m going to show you how to test Kubernetes locally on OSX/macOS. Testing Kubernetes without having access to a cloud operator in a local lab is not as easy as it sounds. I’d like to share some of my experiences in this adventure. For those who have already experienced in Virtualbox & Vagrant combination, I can tell you that it doesn’t work. Since Kubernetes will require virtualization, setting another virtual environment within another VirtualBox has several issues. After trying to bring up a cluster for a day or two, I gave up my traditional lab and figured out that Kubernetes has an alternate solution called minikube.
Installation
If your OSX/macOS doesn’t have brew I strongly recommend installing it. My OSX/macOS version at the time of this post was macOS 10.14.3 (18D109).
$ brew update && brew install kubectl && brew cask install docker minikube virtualbox
Once minikube is installed, we’ll need to start the virtual environment that is required to run our operator.
I’m starting my minikube environment with 4Gb memory since our Percona Xtradb(PXC) Cluster will have 3 MySQL nodes + 1 ProxySQL pod.
$ minikube start --memory 4096 <img src="https://s.w.org/images/core/emoji/11.2.0/72x72/1f604.png" alt="?" class="wp-smiley" style="height: 1em;max-height: 1em" /> minikube v0.35.0 on darwin (amd64) <img src="https://s.w.org/images/core/emoji/11.2.0/72x72/1f525.png" alt="?" class="wp-smiley" style="height: 1em;max-height: 1em" /> Creating virtualbox VM (CPUs=2, Memory=4096MB, Disk=20000MB) ... <img src="https://s.w.org/images/core/emoji/11.2.0/72x72/1f4f6.png" alt="?" class="wp-smiley" style="height: 1em;max-height: 1em" /> "minikube" IP address is 192.168.99.100 <img src="https://s.w.org/images/core/emoji/11.2.0/72x72/1f433.png" alt="?" class="wp-smiley" style="height: 1em;max-height: 1em" /> Configuring Docker as the container runtime ... <img src="https://s.w.org/images/core/emoji/11.2.0/72x72/2728.png" alt="✨" class="wp-smiley" style="height: 1em;max-height: 1em" /> Preparing Kubernetes environment ... <img src="https://s.w.org/images/core/emoji/11.2.0/72x72/1f69c.png" alt="?" class="wp-smiley" style="height: 1em;max-height: 1em" /> Pulling images required by Kubernetes v1.13.4 ... <img src="https://s.w.org/images/core/emoji/11.2.0/72x72/1f680.png" alt="?" class="wp-smiley" style="height: 1em;max-height: 1em" /> Launching Kubernetes v1.13.4 using kubeadm ... <img src="https://s.w.org/images/core/emoji/11.2.0/72x72/231b.png" alt="⌛" class="wp-smiley" style="height: 1em;max-height: 1em" /> Waiting for pods: apiserver proxy etcd scheduler controller addon-manager dns <img src="https://s.w.org/images/core/emoji/11.2.0/72x72/1f511.png" alt="?" class="wp-smiley" style="height: 1em;max-height: 1em" /> Configuring cluster permissions ... <img src="https://s.w.org/images/core/emoji/11.2.0/72x72/1f914.png" alt="?" class="wp-smiley" style="height: 1em;max-height: 1em" /> Verifying component health ..... <img src="https://s.w.org/images/core/emoji/11.2.0/72x72/1f497.png" alt="?" class="wp-smiley" style="height: 1em;max-height: 1em" /> kubectl is now configured to use "minikube" <img src="https://s.w.org/images/core/emoji/11.2.0/72x72/1f3c4.png" alt="?" class="wp-smiley" style="height: 1em;max-height: 1em" /> Done! Thank you for using minikube!
We’re now ready to install Install Percona XtraDB Cluster on Kubernetes.
Setup
Clone and download Kubernetes Operator for MySQL.
$ git clone -b release-0.2.0 https://github.com/percona/percona-xtradb-cluster-operator Cloning into 'percona-xtradb-cluster-operator'... remote: Enumerating objects: 191, done. remote: Counting objects: 100% (191/191), done. remote: Compressing objects: 100% (114/114), done. remote: Total 10321 (delta 73), reused 138 (delta 67), pack-reused 10130 Receiving objects: 100% (10321/10321), 17.04 MiB | 3.03 MiB/s, done. Resolving deltas: 100% (3526/3526), done. Checking out files: 100% (5159/5159), done. $ cd percona-xtradb-cluster-operator
Here we have to make the following modifications for this operator to work on OSX/macOS.
- Reduce memory allocation for each pod.
- Reduce CPU usage for each pod.
- Change the topology type (because we want to run all PXC instances on one node).
$ sed -i.bak 's/1G/500m/g' deploy/cr.yaml $ grep "memory" deploy/cr.yaml memory: 500m # memory: 500m memory: 500m # memory: 500m $ sed -i.bak 's/600m/200m/g' deploy/cr.yaml $ grep "cpu" deploy/cr.yaml cpu: 200m # cpu: "1" cpu: 200m # cpu: 700m $ grep "topology" deploy/cr.yaml topologyKey: "kubernetes.io/hostname" # topologyKey: "failure-domain.beta.kubernetes.io/zone" $ sed -i.bak 's/kubernetes.io/hostname/none/g' deploy/cr.yaml $ grep "topology" deploy/cr.yaml topologyKey: "none" # topologyKey: "failure-domain.beta.kubernetes.io/zone"
We’re now ready to deploy our PXC via the operator.
$ kubectl apply -f deploy/crd.yaml customresourcedefinition.apiextensions.k8s.io/perconaxtradbclusters.pxc.percona.com created customresourcedefinition.apiextensions.k8s.io/perconaxtradbbackups.pxc.percona.com created $ kubectl create namespace pxc namespace/pxc created $ kubectl config set-context $(kubectl config current-context) --namespace=pxc Context "minikube" modified. $ kubectl apply -f deploy/rbac.yaml role.rbac.authorization.k8s.io/percona-xtradb-cluster-operator created rolebinding.rbac.authorization.k8s.io/default-account-percona-xtradb-cluster-operator created $ kubectl apply -f deploy/operator.yaml deployment.apps/percona-xtradb-cluster-operator created $ kubectl apply -f deploy/secrets.yaml secret/my-cluster-secrets created $ kubectl apply -f deploy/configmap.yaml configmap/pxc created $ kubectl apply -f deploy/cr.yaml perconaxtradbcluster.pxc.percona.com/cluster1 created
Here we’re ready to monitor the progress of our deployment.
$ kubectl get pods NAME READY STATUS RESTARTS AGE cluster1-pxc-node-0 0/1 ContainerCreating 0 86s cluster1-pxc-proxysql-0 1/1 Running 0 86s percona-xtradb-cluster-operator-5857dfcb6c-g7bbg 1/1 Running 0 109s
If any of the nodes is having difficulty passing any STATUS to Running state
$ kubectl describe pod cluster1-pxc-node-0 Name: cluster1-pxc-node-0 Namespace: pxc Priority: 0 . .. ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 3m47s (x14 over 3m51s) default-scheduler pod has unbound immediate PersistentVolumeClaims Normal Scheduled 3m47s default-scheduler Successfully assigned pxc/cluster1-pxc-node-0 to minikube Normal Pulling 3m45s kubelet, minikube pulling image "perconalab/pxc-openshift:0.2.0" Normal Pulled 118s kubelet, minikube Successfully pulled image "perconalab/pxc-openshift:0.2.0" Normal Created 117s kubelet, minikube Created container Normal Started 117s kubelet, minikube Started container Warning Unhealthy 89s kubelet, minikube Readiness probe failed: At this stage we’re ready to verify our cluster as soon as we see following output (READY 1/1): $ kubectl get pods NAME READY STATUS RESTARTS AGE cluster1-pxc-node-0 1/1 Running 0 7m38s cluster1-pxc-node-1 1/1 Running 0 4m46s cluster1-pxc-node-2 1/1 Running 0 2m25s cluster1-pxc-proxysql-0 1/1 Running 0 7m38s percona-xtradb-cluster-operator-5857dfcb6c-g7bbg 1/1 Running 0 8m1s
In order to connect to this cluster, we’ll need to deploy a client shell access.
$ kubectl run -i --rm --tty percona-client --image=percona:5.7 --restart=Never -- bash -il If you don't see a command prompt, try pressing enter. bash-4.2$ mysql -h cluster1-pxc-proxysql -uroot -p Enter password: Welcome to the MySQL monitor. Commands end with ; or g. Your MySQL connection id is 3617 Server version: 5.5.30 (ProxySQL) Copyright (c) 2009-2019 Percona LLC and/or its affiliates Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or 'h' for help. Type 'c' to clear the current input statement. mysql> s -------------- mysql Ver 14.14 Distrib 5.7.25-28, for Linux (x86_64) using 6.2 Connection id: 3617 Current database: information_schema Current user: root@cluster1-pxc-proxysql-0.cluster1-pxc-proxysql.pxc.svc.cluste SSL: Not in use Current pager: stdout Using outfile: '' Using delimiter: ; Server version: 5.5.30 (ProxySQL) Protocol version: 10 Connection: cluster1-pxc-proxysql via TCP/IP Server characterset: latin1 Db characterset: utf8 Client characterset: latin1 Conn. characterset: latin1 TCP port: 3306 Uptime: 14 min 1 sec Threads: 1 Questions: 3 Slow queries: 0 --------------
A few things to remember:
- Secrets for this setup are under deploy/secrets.yaml, you can decode via
$ echo -n '{secret}' |base64 -D
- To reconnect shell
$ kubectl run -i --tty percona-client --image=percona:5.7 -- sh
- To redeploy the pod delete first and repeat above steps without configuration changes
$ kubectl delete -f deploy/cr.yaml
- To stop and delete minikube virtual environment
$ minikube stop
$ minikube delete
References
Credits
- Mykola Marzhan – Director of Server Engineering (Percona)
—
Photo by frank mckenna on Unsplash