├── .gitignore ├── LICENSE ├── README.md ├── _img ├── K8S Diagram.xml ├── K8S_Diagram.png └── images.txt ├── deploy ├── backups │ ├── backup-volume.yaml │ ├── list-backups.sh │ ├── list-backups.yaml │ ├── restore.sh │ ├── xtrabackup-cronjob.yaml │ ├── xtrabackup-job.yaml │ └── xtrabackup-restore-job-pxc.yaml ├── oc37 │ ├── backup-volume.yaml │ ├── mysql-configmap.yaml │ ├── proxysql-pxc.yaml │ ├── proxysql-replicaset.yaml │ ├── pxc.yaml │ ├── replica-set.yaml │ ├── secret.yaml │ └── xtrabackup-job.yaml └── xtrabackup-job.yaml ├── helm ├── Makefile ├── README.md ├── helm-server │ ├── .helmignore │ ├── Chart.yaml │ ├── README.md │ ├── templates │ │ ├── NOTES.txt │ │ ├── _helpers.tpl │ │ ├── mysql-configmap.yaml │ │ ├── secrets.yaml │ │ ├── statefulset.yaml │ │ └── svc.yaml │ └── values.yaml ├── helm_install.sh └── pmm-server │ ├── .helmignore │ ├── Chart.yaml │ ├── README.md │ ├── templates │ ├── NOTES.txt │ ├── _helpers.tpl │ ├── ingress.yaml │ ├── route.yaml │ ├── statefulset.yaml │ └── svc.yaml │ └── values.yaml ├── images ├── pmm-client-image │ └── Dockerfile ├── pmm-server-image │ ├── Dockerfile │ ├── Makefile │ ├── entrypoint.sh-rootless │ └── supervisord.conf-rootless ├── proxysql-image │ └── README.md ├── pxc-image │ └── README.md ├── replicaset-image │ ├── Dockerfile │ ├── entrypoint.sh │ ├── init-datadir.sh │ ├── mysqlcheck.sh │ ├── node.cnf │ └── xtrabackup_nc.sh └── sysbench-image │ └── Dockerfile └── src └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | images/backup-image/gof3r 2 | helm/percona-charts 3 | -------------------------------------------------------------------------------- /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 2018 Percona, LLC 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 | # percona-openshift 2 | Set of scripts to run Percona software in OpenShift / Kubernetes / Google Cloud Kubernetes Engine 3 | 4 | ## 🛑🛑🛑 Please consider using [Percona XtraDB Cluster Operator](https://github.com/Percona-Lab/percona-xtradb-cluster-operator) 5 | 6 | ## Submitting Bug Reports 7 | 8 | If you find a bug in Percona Docker Images or one of the related projects, you should submit a report to that project's [JIRA](https://jira.percona.com) issue tracker. 9 | 10 | Your first step should be [to search](https://jira.percona.com/issues/?jql=project%20%3D%20%22Cloud%20Dev%22) the existing set of open tickets for a similar report. If you find that someone else has already reported your problem, then you can upvote that report to increase its visibility. 11 | 12 | If there is no existing report, submit a report following these steps: 13 | 14 | 1. [Sign in to Percona JIRA.](https://jira.percona.com/login.jsp) You will need to create an account if you do not have one. 15 | 2. [Go to the Create Issue screen and select the relevant project.](https://jira.percona.com/secure/CreateIssueDetails!init.jspa?pid=12500&issuetype=1&priority=3) 16 | 3. Fill in the fields of Summary, Description, Steps To Reproduce, and Affects Version to the best you can. If the bug corresponds to a crash, attach the stack trace from the logs. 17 | 18 | An excellent resource is [Elika Etemad's article on filing good bug reports.](http://fantasai.inkedblade.net/style/talks/filing-good-bugs/). 19 | 20 | As a general rule of thumb, please try to create bug reports that are: 21 | 22 | - *Reproducible.* Include steps to reproduce the problem. 23 | - *Specific.* Include as much detail as possible: which version, what environment, etc. 24 | - *Unique.* Do not duplicate existing tickets. 25 | - *Scoped to a Single Bug.* One bug per report. 26 | 27 | # Helm 28 | The best way to deploy the software suite is to use propose Helm charts. 29 | 30 | ## PMM-Server 31 | if you plan to use PMM monitoring 32 | 33 | To start pmm-server, from helm/helm-pmm-server execute: 34 | 35 | helm install monitoring ./helm/pmm-server 36 | 37 | It will expose a public IP address for the access 38 | 39 | kubectl get service 40 | ``` 41 | NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE 42 | monitoring-service LoadBalancer 10.31.242.113 35.233.168.128 80:32516/TCP 10m 43 | ``` 44 | 45 | ## Percona XtraDB Cluster 46 | 47 | Basic deployment 48 | 49 | helm install --name cluster1 ./helm/helm-server 50 | 51 | By default will deploy proxysql in from of nodes and pmm-client on each node 52 | 53 | kubectl get service 54 | ``` 55 | NAME READY STATUS RESTARTS AGE 56 | cluster1-node-0 2/2 Running 0 5m 57 | cluster1-node-1 2/2 Running 0 4m 58 | cluster1-node-2 2/2 Running 0 3m 59 | cluster1-proxysql-0 2/2 Running 0 5m 60 | monitoring-0 1/1 Running 0 1h 61 | ``` 62 | 63 | Connect to ProxySQL admin: 64 | 65 | kubectl exec -it cluster1-proxysql-0 -c proxysql -- mysql -h127.0.0.1 -P6032 -uadmin -padmin 66 | 67 | Connect to PXC via ProxySQL from a client application: 68 | 69 | ``` 70 | kubectl run -i --tty percona-client --image=percona:5.7 --restart=Never -- bash -il 71 | root@percona-client:/# mysql -hcluster1-proxysql -uroot -psecr3t 72 | ``` 73 | 74 | ## Master - N Slaves ReplicaSet 75 | 76 | ### ReplicaSet is currently broken, ProxySQL is not supported ### 77 | 78 | helm install --name rs1 . -f values.yaml --set kind=replicaset 79 | 80 | # Helm with OpenShift 81 | 82 | PMM-Server and pmm-clients require to run under user:0 (root), which is complicated in OpenShift. 83 | So the proper way to start a helm release is: 84 | 85 | helm install --name dep1 . -f values.yaml --set pmm.enabled=false,platform=openshift 86 | Or edit `values.yaml` to change `pmm.enabled` and `platform` 87 | 88 | # Backups 89 | 90 | To performa backups you need 91 | 1. Create a persistent backup volume. Adjust the file `backup-volume.yaml` for your needs 92 | 2. Execute a backup job. Example is in `xtrabackup-job.yaml` file, to perform backup run: `kubectl apply -f xtrabackup-job.yaml` 93 | 94 | ## Restore from backup 95 | To start the cluster from the backup 96 | 1. Make sure the cluster is not running 97 | 2. Locate directory you want to restore from on the backup volume, e.g. `cluster1-node-0.cluster1-nodes-2018-06-18-17-26` 98 | 3. Adjust and run backup-restore job https://github.com/Percona-Lab/percona-openshift/blob/master/deploy/xtrabackup-restore-job-pxc.yaml 99 | 100 | # Kubernetes deployments (without Helm) 101 | 102 | ## MySQL Passwords 103 | Before deployments you need to create passwords (secrets) which will be used to access Percona Server / Percona XtraDB Cluster. 104 | We provide file https://github.com/Percona-Lab/percona-openshift/blob/master/deploy/secret.yaml as an example. **Please use your own secure passwords!** 105 | 106 | Use `base64` to encode a password for `secret.yaml` : `echo -n 'securepassword' | base64`. 107 | 108 | Used `base64 -d` to decode a password from `secret.yaml` : `echo YmFja3VwX3Bhc3N3b3Jk | base64 -d`. 109 | 110 | 111 | ## Considerations 112 | The proposed depoyments were tested on Kubernetes 1.9 / OpenShift Origin 3.9. The earlier versions may not work. 113 | 114 | The deployments assume you have a default `StorageClass` which will provide Persistent Volumes. If not, you need to create `PersistentVolume` manually. 115 | 116 | ## Deployments 117 | 118 | ### Percona XtraDB Cluster N nodes 119 | Deployment `pxc.yaml` will create a StatefulSet with N nodes (defined in `replicas: 3`) 120 | Pay attention to the service name, defined in `name: pxccluster1` 121 | 122 | TODO: 123 | - [ ] Encrypted connections from clients to PXC Nodes 124 | - [ ] Encrypted connections between PXC Nodes 125 | 126 | ### ProxySQL service over Percona XtraDB Cluster 127 | 128 | Deployment `proxysql-pxc.yaml` will create ProxySQL service and automatically configure to handle a traffic to Percona XtraDB Cluster service. 129 | The service to handled is defined in line: `- -service=pxccluster1` 130 | 131 | TODO: 132 | - [ ] Encrypted connections from ProxySQL to PXC Nodes 133 | 134 | ### A custom MySQL config. 135 | The deployments support a custom MySQL config. 136 | You can customize `mysql-configmap.yaml` to add any configuration lines you may need. 137 | Next command will create a ConfigMap: `kubectl create -f mysql-configmap.yaml`. The ConfigMap must be created before any deployments. 138 | 139 | ### Further work 140 | - [ ] Provide depoloyments for PMM Server 141 | - [ ] Configure nodes with PMM Client 142 | - [ ] Provide a guidance how to create / restore from backups 143 | 144 | 145 | ## Cheatsheet 146 | 147 | For OpenShift replace `kubectl` with `oc` 148 | 149 | * List available nodes `kubectl get nodes` 150 | * List running pods `kubectl get pods` 151 | * Create deployment `kubectl create -f replica-set.yaml` 152 | * Delete deployment `kubectl delete -f replica-set.yaml` 153 | * Watch pods changing during deployment `watch kubectl get pods` 154 | * Diagnostic about a pod, in case of failure `kubectl describe po/rsnode-0` 155 | * Logs from pods `kubectl logs -f rsnode-0` 156 | * Logs from the particular container in pod `kubectl logs -f rsnode-1 -c clone-mysql` 157 | * Access to bash in container ` kubectl exec rsnode-0 -it -- bash` 158 | * Access to mysql in container `kubectl exec rsnode-0 -it -- mysql -uroot -proot_password` 159 | * Access to proxysql admin `kubectl exec proxysql-0 -it -- mysql -uadmin -padmin -h127.0.0.1 -P6032` 160 | 161 | ### Sysbench 162 | 163 | Oneliner to prepare sysbench-tpcc database 164 | 165 | kubectl run sysbench1 --image=perconalab/sysbench --restart=Never --env="LUA_PATH=/sysbench/sysbench-tpcc/?.lua" --command -- sysbench-tpcc/tpcc.lua --mysql-host=cluster1-node-0.cluster1-nodes --mysql-user=root --mysql-password=secr3t --scale=10 --mysql-db=sbtest --db-driver=mysql --force-pk=1 prepare 166 | -------------------------------------------------------------------------------- /_img/K8S Diagram.xml: -------------------------------------------------------------------------------- 1 | 1VlJc+MoFP41PsalxdqOsZPMHJKqnnFXTeaIJSwxjYQK4a1//YAFsjA4dmI5nc7BBY9NfN/beBn5s3L7BwV18UIyiEeek21H/sPI8xIn4L9CsGsFge+2gpyirBX1BHP0E0qhI6UrlMFGm8gIwQzVujAlVQVTpskApWSjT1sSrJ9agxwagnkKsCn9B2WsaKVx4Bzkf0KUF+pk15EjC5D+yClZVfK8kecv93/tcAnUXnJ+U4CMbHoi/3HkzyghrG2V2xnEAloFW7vu6cRo990UVuySBRO+Jozc1IHAcUMY3/m+/DC2U2DAjGMju4SyguSkAvjxIJ3uLwzFlg7vpaREKW+7vF2wEssm3CL2KqeI9r+iPfYC0a0Y3b2qeaLTDka8+x9kbCc1BKwY4aLDRzwTUstlS1KxJ1AiLFTuOyhICbi0vYy4wUmApKghK5rKWV4kdQ7QHLJTSHkdX9wMICkh/26+iEIMGFrrBwKpkHk3Ty69pxTsehNqgirW9Hb+JgR8gjQtN5aaIy3L85M+wbzR7qh6vU87iPZKYFcIdfU1wCuodPhIITYFYnBegz1cG+4AdKKXCOMZwYTyfkUqoSANo+RHZ0p+J1HTuJmE0f00eTpSn7dItXC4hpTBbU9ksnMCRjeWer85mLurzL3om3oSnWa0x8KbIAcGxt8g5b4McOEro+CBX9GZ4VXDIB15IeZnTxeilbO9+puyw/o5pGuxyvkb1hilrYiZKwxWOXJMJ1LnSFJpYRdglFe8m3I++NH+VPDAj8b3cqBEWbZ3FDbN0Z3H7RiPdMZ93zEZjyyMK1d9DeFufLVXtXnScdDzpe5AztKC8pH/vNbnGU6ti/vKqSVHmLfOWa7qh7P3btR6dGOjjzjK8HMo7WKjHOqi4+3o1kKhY4ZCdzK0WlxqR2YQvp6FM+mKO+qnK1q2cueMHSfUUxbX8ZWA+2TEbyg84mBsvTuTsdD3aWypw7Vcoo1D4o5d7KJku5v/9azG+Lb9YYNgnb53JCM8y8gAjJepNf9IY7hYfl7+kej5h2uJRr5nRqNwgGjUfW4v/3h56eUOAwLOnz5eagU8CxdhEH4W4P5R+HfdxAA8tkZ/bwDAJxZDOAJZvBrrgdHoHshgoY5x3kSpM1kVPx1TLRMLSvEQOdIFIJ3RPdDUbTVgibZCXz8EZkfWed3qoRJEY3fixUGkfk2QTky5CjPzJfHVMVOj3riHBP+Nj8xzrEGlnqW/HvHQQDxVDzVH7CLi6P7h1dheXRURda3fgyIvGEcafIHuG44ZnHwRiswkMTAQv2mSGGlZIk8S/UhPEhPvS+WIEp5fkyOaHqwuy7sUIyifaINlInEK7ZnIgutucMzyzTIRI8bGZoyNLZYyRB3iRBFTg1+UsHkmYriuNcGrEl5QSGoKUItmusOIs0XPM7VoaX1eKEGfCIOuaRD5yYO1qmgpTr3FoyVhMqg9yWN4voIY3ihVMmk0c6fpnkYz1phlPgob9FNmiMIKZAmazw6mo0AALTxR0zolt1fvw3DJLNU+JrzUtOFsoyr/vndZd5NbMuF6+mPKc+JxcBEZH7Ap3j38e6atGx3+BeY//g8= -------------------------------------------------------------------------------- /_img/K8S_Diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Percona-Lab/percona-openshift/e0947678b314b1454a99679ef78979f2c1820faa/_img/K8S_Diagram.png -------------------------------------------------------------------------------- /_img/images.txt: -------------------------------------------------------------------------------- 1 | empty 2 | -------------------------------------------------------------------------------- /deploy/backups/backup-volume.yaml: -------------------------------------------------------------------------------- 1 | kind: PersistentVolumeClaim 2 | apiVersion: v1 3 | metadata: 4 | name: backup-volume 5 | spec: 6 | accessModes: 7 | - ReadWriteOnce 8 | resources: 9 | requests: 10 | storage: 50Gi 11 | -------------------------------------------------------------------------------- /deploy/backups/list-backups.sh: -------------------------------------------------------------------------------- 1 | ctrl="oc" 2 | 3 | container_phase=$($ctrl get po/list-backups -o=go-template='{{ .status.phase }}' 2>/dev/null) 4 | #echo "Container list-backups phase is: $container_phase" 5 | if [ "$container_phase" != "Running" ] 6 | then 7 | # start container 8 | echo "Starting container..." 9 | $ctrl create -f list-backups.yaml 2>/dev/null 10 | sleep 5 11 | fi 12 | 13 | $ctrl rsh po/list-backups du -h /backup/ | sort -k2 14 | last_backup=$($ctrl rsh po/list-backups du -h /backup/ | sort -k2 | grep -v '4.0K' | tail -n 1|cut -d$'\t' -f 2| cut -d '/' -f 3) 15 | 16 | echo "To restore a backup run: restore.sh -d , i.e. ./restore.sh -d $last_backup" 17 | #$ctrl delete -f list-backups.yaml 18 | -------------------------------------------------------------------------------- /deploy/backups/list-backups.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: list-backups 5 | spec: 6 | containers: 7 | - image: busybox 8 | imagePullPolicy: IfNotPresent 9 | name: list-backups 10 | volumeMounts: 11 | - name: backup 12 | mountPath: /backup 13 | stdin: true 14 | stdinOnce: true 15 | volumes: 16 | - name: backup 17 | persistentVolumeClaim: 18 | claimName: backup-volume 19 | -------------------------------------------------------------------------------- /deploy/backups/restore.sh: -------------------------------------------------------------------------------- 1 | #/bin/bash 2 | 3 | helmDir="../../helm/helm-server/" 4 | 5 | function usage { 6 | cat << EOF 7 | usage: $0 [-h] -n "new restored cluster name" -d "backup directory (under /backup, do not include "/backup")" [-b "helm dir"] [-z] 8 | 9 | OPTIONS: 10 | -h Show this message 11 | -s string new restored cluster name 12 | -d string backup path (run list_backups.sh to see the current directory) 13 | EOF 14 | 15 | } 16 | 17 | while getopts :h:n:d: flag; do 18 | case $flag in 19 | d) 20 | backupDir="${OPTARG}"; 21 | ;; 22 | n) 23 | clusterName="${OPTARG}"; 24 | ;; 25 | b) 26 | helmDir="${OPTARG}"; 27 | ;; 28 | h) 29 | usage; 30 | exit 0; 31 | ;; 32 | *) 33 | usage; 34 | exit 1; 35 | ;; 36 | esac 37 | done 38 | shift $((OPTIND -1)) 39 | 40 | if [ "$clusterName" == "" ]; then clusterName="restore1"; echo "cluster name is not defined, using restore1 as a cluster name"; fi 41 | if [ "$backupDir" == "" ]; then echo "backupDir is not defined, use -d "; usage; exit 1; fi 42 | 43 | helm=$(command -v helm) 44 | 45 | echo $helm 46 | 47 | if [ "$helm" == "" ] 48 | then 49 | echo "Helm is not installed. Exiting..." 50 | exit 0; 51 | fi 52 | 53 | $helm install --name $clusterName --set persistence.backupDir=$backupDir,persistence.restoreBackup=true $helmDir -f $helmDir/values.yaml 54 | -------------------------------------------------------------------------------- /deploy/backups/xtrabackup-cronjob.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: batch/v1beta1 2 | kind: CronJob 3 | metadata: 4 | name: xtrabackup-cronjob 5 | spec: 6 | schedule: "*/1 * * * *" 7 | jobTemplate: 8 | spec: 9 | template: 10 | spec: 11 | containers: 12 | - name: xtrabackup 13 | image: perconalab/backupjob-openshift 14 | command: ["bash","/usr/bin/backup.sh"] 15 | volumeMounts: 16 | - name: backup 17 | mountPath: /backup 18 | env: 19 | - name: NODE_NAME 20 | value: "pxc-node-2.pxc-nodes" 21 | restartPolicy: Never 22 | volumes: 23 | - name: backup 24 | persistentVolumeClaim: 25 | claimName: backup-volume 26 | -------------------------------------------------------------------------------- /deploy/backups/xtrabackup-job.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: batch/v1 2 | kind: Job 3 | metadata: 4 | name: xtrabackup-job 5 | spec: 6 | template: 7 | spec: 8 | containers: 9 | - name: xtrabackup 10 | image: perconalab/backupjob-openshift 11 | command: ["bash","/usr/bin/backup.sh"] 12 | volumeMounts: 13 | - name: backup 14 | mountPath: /backup 15 | env: 16 | - name: NODE_NAME 17 | value: "rsnode-0.replicaset1" 18 | restartPolicy: Never 19 | volumes: 20 | - name: backup 21 | persistentVolumeClaim: 22 | claimName: backup-volume 23 | backoffLimit: 4 24 | -------------------------------------------------------------------------------- /deploy/backups/xtrabackup-restore-job-pxc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: batch/v1 2 | kind: Job 3 | metadata: 4 | name: xtrabackup-restore-job 5 | spec: 6 | template: 7 | spec: 8 | containers: 9 | - name: xtrabackup 10 | image: perconalab/backupjob-openshift 11 | command: 12 | - bash 13 | - "-c" 14 | - | 15 | set -ex 16 | cd /datadir 17 | rm -fr * 18 | cat /backup/$BACKUPSRC/xtrabackup.stream | xbstream -x 19 | xtrabackup --prepare --target-dir=/datadir 20 | env: 21 | - name: BACKUPSRC 22 | value: "cluster1-node-0.cluster1-nodes-2018-06-18-17-26" 23 | volumeMounts: 24 | - name: backup 25 | mountPath: /backup 26 | - name: datadir 27 | mountPath: /datadir 28 | restartPolicy: Never 29 | volumes: 30 | - name: backup 31 | persistentVolumeClaim: 32 | claimName: backup-volume 33 | - name: datadir 34 | persistentVolumeClaim: 35 | claimName: datadir-cluster1-node-0 36 | backoffLimit: 4 37 | -------------------------------------------------------------------------------- /deploy/oc37/backup-volume.yaml: -------------------------------------------------------------------------------- 1 | kind: PersistentVolumeClaim 2 | apiVersion: v1 3 | metadata: 4 | name: backup-volume 5 | spec: 6 | accessModes: 7 | - ReadWriteOnce 8 | resources: 9 | requests: 10 | storage: 50Gi 11 | -------------------------------------------------------------------------------- /deploy/oc37/mysql-configmap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: mysql 5 | labels: 6 | app: mysql 7 | data: 8 | extra.cnf: | 9 | [mysqld] 10 | innodb-buffer-pool-size=512M 11 | -------------------------------------------------------------------------------- /deploy/oc37/proxysql-pxc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1beta 2 | kind: StatefulSet 3 | metadata: 4 | name: proxysql 5 | spec: 6 | serviceName: "proxysql" 7 | replicas: 1 8 | selector: 9 | matchLabels: 10 | front: proxysql 11 | template: 12 | metadata: 13 | labels: 14 | app: proxysql 15 | front: proxysql 16 | spec: 17 | containers: 18 | - name: proxysql 19 | image: perconalab/proxysql-openshift 20 | ports: 21 | - containerPort: 3306 22 | name: mysql 23 | - containerPort: 6032 24 | name: proxyadm 25 | volumeMounts: 26 | - name: proxydata 27 | mountPath: /var/lib/proxysql 28 | subPath: data 29 | env: 30 | - name: MYSQL_ROOT_PASSWORD 31 | valueFrom: 32 | secretKeyRef: 33 | name: mysql-passwords 34 | key: root 35 | - name: MYSQL_PROXY_USER 36 | value: "proxyuser" 37 | - name: MYSQL_PROXY_PASSWORD 38 | valueFrom: 39 | secretKeyRef: 40 | name: mysql-passwords 41 | key: proxyuser 42 | - name: SERVICE 43 | value: percona-xtradb-cluster 44 | lifecycle: 45 | postStart: 46 | exec: 47 | command: 48 | - "/usr/bin/peer-list" 49 | - -on-start="/usr/bin/add_cluster_nodes.sh" 50 | - -service=pxccluster1 # name of the service running PXC StatefulSet 51 | volumeClaimTemplates: 52 | - metadata: 53 | name: proxydata 54 | spec: 55 | accessModes: [ "ReadWriteOnce" ] 56 | resources: 57 | requests: 58 | storage: 2Gi 59 | --- 60 | apiVersion: v1 61 | kind: Service 62 | metadata: 63 | labels: 64 | app: proxysql 65 | name: sql 66 | spec: 67 | ports: 68 | - name: mysql 69 | port: 3306 70 | protocol: TCP 71 | targetPort: 3306 72 | - name: proxyadm 73 | port: 6032 74 | protocol: TCP 75 | targetPort: 6032 76 | selector: 77 | app: proxysql 78 | -------------------------------------------------------------------------------- /deploy/oc37/proxysql-replicaset.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1beta 2 | kind: StatefulSet 3 | metadata: 4 | name: proxysql 5 | spec: 6 | serviceName: "proxysql" 7 | replicas: 1 8 | selector: 9 | matchLabels: 10 | front: proxysql 11 | template: 12 | metadata: 13 | labels: 14 | app: proxysql 15 | front: proxysql 16 | spec: 17 | containers: 18 | - name: proxysql 19 | image: perconalab/proxysql-openshift 20 | ports: 21 | - containerPort: 3306 22 | name: mysql 23 | - containerPort: 6032 24 | name: proxyadm 25 | volumeMounts: 26 | - name: proxydata 27 | mountPath: /var/lib/proxysql 28 | subPath: data 29 | env: 30 | - name: MYSQL_ROOT_PASSWORD 31 | valueFrom: 32 | secretKeyRef: 33 | name: mysql-passwords 34 | key: root 35 | - name: MYSQL_PROXY_USER 36 | value: "proxyuser" 37 | - name: MYSQL_PROXY_PASSWORD 38 | valueFrom: 39 | secretKeyRef: 40 | name: mysql-passwords 41 | key: proxyuser 42 | - name: SERVICE 43 | value: percona-xtradb-cluster 44 | lifecycle: 45 | postStart: 46 | exec: 47 | command: 48 | - "/usr/bin/peer-list" 49 | - -on-start="/usr/bin/add_cluster_nodes.sh" 50 | - -service=replicaset1 # name of the service running ReplicaSet StatefulSet 51 | volumeClaimTemplates: 52 | - metadata: 53 | name: proxydata 54 | spec: 55 | accessModes: [ "ReadWriteOnce" ] 56 | resources: 57 | requests: 58 | storage: 2Gi 59 | --- 60 | apiVersion: v1 61 | kind: Service 62 | metadata: 63 | labels: 64 | app: proxysql 65 | name: sql 66 | spec: 67 | ports: 68 | - name: mysql 69 | port: 3306 70 | protocol: TCP 71 | targetPort: 3306 72 | - name: proxyadm 73 | port: 6032 74 | protocol: TCP 75 | targetPort: 6032 76 | selector: 77 | app: proxysq 78 | -------------------------------------------------------------------------------- /deploy/oc37/pxc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | annotations: 5 | service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" 6 | name: pxccluster1 7 | labels: 8 | app: percona-xtradb-cluster 9 | spec: 10 | ports: 11 | - port: 3306 12 | name: mysql-port 13 | clusterIP: None 14 | selector: 15 | app: percona-xtradb-cluster 16 | --- 17 | apiVersion: apps/v1beta1 18 | kind: StatefulSet 19 | metadata: 20 | name: pxcnode 21 | spec: 22 | selector: 23 | matchLabels: 24 | app: percona-xtradb-cluster 25 | serviceName: "pxccluster1" 26 | replicas: 3 27 | template: 28 | metadata: 29 | labels: 30 | app: percona-xtradb-cluster 31 | spec: 32 | containers: 33 | - name: mysql 34 | image: perconalab/pxc-openshift 35 | imagePullPolicy: Always 36 | ports: 37 | - containerPort: 3306 38 | name: mysql 39 | - containerPort: 4444 40 | name: sst 41 | - containerPort: 4567 42 | name: replication 43 | - containerPort: 4568 44 | name: ist 45 | readinessProbe: 46 | exec: 47 | command: 48 | - /usr/bin/clustercheck.sh 49 | initialDelaySeconds: 15 50 | timeoutSeconds: 15 51 | periodSeconds: 30 52 | failureThreshold: 5 53 | livenessProbe: 54 | exec: 55 | command: 56 | - /usr/bin/clustercheck.sh 57 | initialDelaySeconds: 300 58 | timeoutSeconds: 5 59 | periodSeconds: 10 60 | volumeMounts: 61 | - name: datadir 62 | mountPath: /var/lib/mysql 63 | subPath: data 64 | - name: config-volume 65 | mountPath: /etc/mysql/conf.d/ 66 | env: 67 | - name: MYSQL_FORCE_INIT 68 | value: "1" 69 | - name: MYSQL_ROOT_PASSWORD 70 | valueFrom: 71 | secretKeyRef: 72 | name: mysql-passwords 73 | key: root 74 | - name: XTRABACKUP_PASSWORD 75 | valueFrom: 76 | secretKeyRef: 77 | name: mysql-passwords 78 | key: xtrabackup 79 | - name: MONITOR_PASSWORD 80 | valueFrom: 81 | secretKeyRef: 82 | name: mysql-passwords 83 | key: monitor 84 | - name: CLUSTERCHECK_PASSWORD 85 | valueFrom: 86 | secretKeyRef: 87 | name: mysql-passwords 88 | key: clustercheck 89 | volumes: 90 | - name: config-volume 91 | configMap: 92 | name: mysql 93 | optional: true 94 | volumeClaimTemplates: 95 | - metadata: 96 | name: datadir 97 | spec: 98 | accessModes: [ "ReadWriteOnce" ] 99 | resources: 100 | requests: 101 | storage: 10Gi 102 | -------------------------------------------------------------------------------- /deploy/oc37/replica-set.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | annotations: 5 | service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" 6 | name: replicaset1 7 | labels: 8 | app: rs 9 | spec: 10 | ports: 11 | - port: 3306 12 | name: mysql-port 13 | clusterIP: None 14 | selector: 15 | app: rs 16 | --- 17 | apiVersion: apps/v1beta 18 | kind: StatefulSet 19 | metadata: 20 | name: rsnode 21 | spec: 22 | selector: 23 | matchLabels: 24 | app: rs 25 | serviceName: "replicaset1" 26 | replicas: 2 27 | template: 28 | metadata: 29 | labels: 30 | app: rs 31 | spec: 32 | initContainers: 33 | - name: init-mysql 34 | image: perconalab/percona-rs 35 | command: ["/bin/bash","/usr/bin/init-mysql.sh"] 36 | volumeMounts: 37 | - name: conf 38 | mountPath: /etc/mysql/conf.d 39 | - name: config-volume 40 | mountPath: /mnt/config-map 41 | - name: clone-mysql 42 | image: perconalab/percona-rs 43 | command: ["/bin/bash","/usr/bin/init-datadir.sh"] 44 | volumeMounts: 45 | - name: datadir 46 | mountPath: /var/lib/mysql 47 | subPath: data 48 | - name: conf 49 | mountPath: /etc/mysql/conf.d 50 | containers: 51 | - name: mysql 52 | image: perconalab/percona-rs 53 | imagePullPolicy: Always 54 | ports: 55 | - containerPort: 3306 56 | name: mysql 57 | readinessProbe: 58 | exec: 59 | command: ["/usr/bin/mysqlcheck.sh"] 60 | initialDelaySeconds: 30 61 | periodSeconds: 10 62 | timeoutSeconds: 5 63 | readinessProbe: 64 | exec: 65 | command: ["/usr/bin/mysqlcheck.sh"] 66 | initialDelaySeconds: 5 67 | periodSeconds: 2 68 | timeoutSeconds: 1 69 | volumeMounts: 70 | - name: datadir 71 | mountPath: /var/lib/mysql 72 | subPath: data 73 | - name: conf 74 | mountPath: /etc/mysql/conf.d/ 75 | env: 76 | - name: MYSQL_ROOT_PASSWORD 77 | valueFrom: 78 | secretKeyRef: 79 | name: mysql-passwords 80 | key: root 81 | - name: XTRABACKUP_PASSWORD 82 | valueFrom: 83 | secretKeyRef: 84 | name: mysql-passwords 85 | key: xtrabackup 86 | - name: MONITOR_PASSWORD 87 | valueFrom: 88 | secretKeyRef: 89 | name: mysql-passwords 90 | key: monitor 91 | volumes: 92 | - name: conf 93 | emptyDir: {} 94 | - name: config-volume 95 | configMap: 96 | name: mysql 97 | optional: true 98 | volumeClaimTemplates: 99 | - metadata: 100 | name: datadir 101 | spec: 102 | accessModes: [ "ReadWriteOnce" ] 103 | resources: 104 | requests: 105 | storage: 1Gi 106 | -------------------------------------------------------------------------------- /deploy/oc37/secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: mysql-passwords 5 | type: Opaque 6 | data: 7 | root: cm9vdF9wYXNzd29yZA== 8 | xtrabackup: YmFja3VwX3Bhc3N3b3Jk 9 | monitor: bW9uaXRvcg== 10 | clustercheck: Y2x1c3RlcmNoZWNrcGFzc3dvcmQ= 11 | proxyuser: czNjcmV0 12 | -------------------------------------------------------------------------------- /deploy/oc37/xtrabackup-job.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: batch/v1 2 | kind: Job 3 | metadata: 4 | name: xtrabackup-job 5 | spec: 6 | template: 7 | spec: 8 | containers: 9 | - name: xtrabackup 10 | image: perconalab/backupjob-openshift 11 | command: ["bash","/usr/bin/backup.sh"] 12 | volumeMounts: 13 | - name: backup 14 | mountPath: /backup 15 | env: 16 | - name: NODE_NAME 17 | value: "rsnode-0.replicaset1" 18 | restartPolicy: Never 19 | volumes: 20 | - name: backup 21 | persistentVolumeClaim: 22 | claimName: backup-volume 23 | backoffLimit: 4 24 | -------------------------------------------------------------------------------- /deploy/xtrabackup-job.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: batch/v1 2 | kind: Job 3 | metadata: 4 | name: xtrabackup-job 5 | spec: 6 | template: 7 | spec: 8 | containers: 9 | - name: xtrabackup 10 | image: perconalab/backupjob-openshift 11 | command: ["bash","/usr/bin/backup.sh"] 12 | volumeMounts: 13 | - name: backup 14 | mountPath: /backup 15 | env: 16 | - name: NODE_NAME 17 | value: "rsnode-0.replicaset1" 18 | restartPolicy: Never 19 | volumes: 20 | - name: backup 21 | persistentVolumeClaim: 22 | claimName: backup-volume 23 | backoffLimit: 4 24 | -------------------------------------------------------------------------------- /helm/Makefile: -------------------------------------------------------------------------------- 1 | pmm: 2 | rm -rf percona-charts 3 | mkdir percona-charts 4 | gsutil rsync gs://percona-charts/ percona-charts/ 5 | helm package -u -d percona-charts pmm-server 6 | helm repo index --url https://percona-charts.storage.googleapis.com --merge percona-charts/index.yaml percona-charts 7 | gsutil rsync percona-charts/ gs://percona-charts/ 8 | -------------------------------------------------------------------------------- /helm/README.md: -------------------------------------------------------------------------------- 1 | # Install helm in Google Cloud: 2 | 3 | kubectl create serviceaccount --namespace kube-system tiller 4 | kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller 5 | helm init --service-account tiller 6 | # Install Helm in OpenShift 7 | 8 | For the details see https://blog.openshift.com/getting-started-helm-openshift/ 9 | 10 | Commands: 11 | ``` 12 | oc new-project tiller 13 | curl -s https://storage.googleapis.com/kubernetes-helm/helm-v2.9.0-linux-amd64.tar.gz | tar xz 14 | $ cd linux-amd64 15 | $ ./helm init --client-only 16 | oc process -f https://github.com/openshift/origin/raw/master/examples/helm/tiller-template.yaml -p TILLER_NAMESPACE="tiller" -p HELM_VERSION=v2.9.0 | oc create -f - 17 | 18 | oc new-project myapp 19 | oc policy add-role-to-user edit "system:serviceaccount:tiller:tiller" 20 | ``` 21 | -------------------------------------------------------------------------------- /helm/helm-server/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | -------------------------------------------------------------------------------- /helm/helm-server/Chart.yaml: -------------------------------------------------------------------------------- 1 | name: pxc 2 | version: 1.0.0 3 | description: free, fully compatible, enhanced, open source drop-in replacement for 4 | MySQL 5 | keywords: 6 | - mysql 7 | - percona 8 | - database 9 | - sql 10 | home: https://www.percona.com/ 11 | icon: https://www.percona.com/sites/all/themes/percona2015/logo.png 12 | sources: 13 | - https://github.com/kubernetes/charts 14 | - https://github.com/docker-library/percona 15 | maintainers: 16 | - name: Percona Engineering Team 17 | email: info@percona.com 18 | engine: gotpl 19 | -------------------------------------------------------------------------------- /helm/helm-server/README.md: -------------------------------------------------------------------------------- 1 | # Percona 2 | 3 | [Percona Server](https://MySQL.org) for MySQL® is a free, fully compatible, enhanced, open source drop-in replacement for MySQL that provides superior performance, scalability and instrumentation. With over 3,000,000 downloads, Percona Server for MySQL's self-tuning algorithms and support for extremely high-performance hardware delivers excellent performance and reliability. 4 | 5 | Notable users include Netflix, Amazon Web Services, Alcatel-Lucent, and Smug Mug. 6 | 7 | ## Introduction 8 | 9 | This chart, based off of the MySQL chart, bootstraps a single node Percona Server deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. 10 | 11 | ## Prerequisites 12 | 13 | - Kubernetes 1.6+ with Beta APIs enabled 14 | - PV provisioner support in the underlying infrastructure 15 | 16 | ## Installing the Chart 17 | 18 | To install the chart with the release name `my-release`: 19 | 20 | ```bash 21 | $ helm install --name my-release stable/percona 22 | ``` 23 | 24 | The command deploys Percona Server on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation. 25 | 26 | By default a random password will be generated for the root user. If you'd like to set your own password change the perconaRootPassword 27 | in the values.yaml. 28 | 29 | You can retrieve your root password by running the following command. Make sure to replace [YOUR_RELEASE_NAME]: 30 | 31 | printf $(printf '\%o' `kubectl get secret [YOUR_RELEASE_NAME]-percona -o jsonpath="{.data.mysql-root-password[*]}"`) 32 | 33 | > **Tip**: List all releases using `helm list` 34 | 35 | ## Uninstalling the Chart 36 | 37 | To uninstall/delete the `my-release` deployment: 38 | 39 | ```bash 40 | $ helm delete my-release 41 | ``` 42 | 43 | The command removes all the Kubernetes components associated with the chart and deletes the release. 44 | 45 | ## Configuration 46 | 47 | The following tables lists the configurable parameters of the Percona chart and their default values. 48 | 49 | | Parameter | Description | Default | 50 | | ----------------------- | ---------------------------------- | ---------------------------------------------------------- | 51 | | `imageTag` | `percona` image tag. | Most recent release | 52 | | `imagePullPolicy` | Image pull policy | `IfNotPresent` | 53 | | `perconaRootPassword` | Password for the `root` user. | `nil` | 54 | | `perconaUser` | Username of new user to create. | `nil` | 55 | | `perconaPassword` | Password for the new user. | `nil` | 56 | | `perconaDatabase` | Name for new database to create. | `nil` | 57 | | `persistence.enabled` | Create a volume to store data | false | 58 | | `persistence.size` | Size of persistent volume claim | 8Gi RW | 59 | | `persistence.storageClass` | Type of persistent volume claim | nil (uses alpha storage class annotation) | 60 | | `persistence.accessMode` | ReadWriteOnce or ReadOnly | ReadWriteOnce | 61 | | `resources` | CPU/Memory resource requests/limits | Memory: `256Mi`, CPU: `100m` | 62 | 63 | Some of the parameters above map to the env variables defined in the [Percona Server DockerHub image](https://hub.docker.com/_/percona/). 64 | 65 | Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, 66 | 67 | ```bash 68 | $ helm install --name my-release \ 69 | --set mysqlLRootPassword=secretpassword,mysqlUser=my-user,mysqlPassword=my-password,mysqlDatabase=my-database \ 70 | stable/percona 71 | ``` 72 | 73 | The above command sets the MySQL `root` account password to `secretpassword`. Additionally it creates a standard database user named `my-user`, with the password `my-password`, who has access to a database named `my-database`. 74 | 75 | Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example, 76 | 77 | ```bash 78 | $ helm install --name my-release -f values.yaml stable/percona 79 | ``` 80 | 81 | > **Tip**: You can use the default [values.yaml](values.yaml) 82 | 83 | ## Persistence 84 | 85 | The [Percona Server](https://hub.docker.com/_/percona/) image stores the MySQL data and configurations at the `/var/lib/mysql` path of the container. 86 | 87 | By default, an emptyDir volume is mounted at that location. 88 | 89 | > *"An emptyDir volume is first created when a Pod is assigned to a Node, and exists as long as that Pod is running on that node. When a Pod is removed from a node for any reason, the data in the emptyDir is deleted forever."* 90 | 91 | You can change the values.yaml to enable persistence and use a PersistentVolumeClaim instead. 92 | -------------------------------------------------------------------------------- /helm/helm-server/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | To get your root password run: 2 | 3 | kubectl get secret --namespace {{ .Release.Namespace }} {{ template "percona.fullname" . }}-secrets -o jsonpath="{.data.root}" | base64 --decode; echo 4 | 5 | To connect to your database: 6 | 7 | 1. Run a percona pod that you can use as a client: 8 | 9 | kubectl run -i --rm --tty percona-client --image=percona:5.7 --restart=Never -- bash -il 10 | 11 | 2. Connect using the mysql cli, then provide your password: 12 | $ mysql -h {{ template "percona.fullname" . }}-proxysql -p 13 | 14 | -------------------------------------------------------------------------------- /helm/helm-server/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 5 | */}} 6 | {{- define "percona.name" -}} 7 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 8 | {{- end -}} 9 | 10 | {{/* 11 | Create a default fully qualified app name. 12 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 13 | */}} 14 | {{- define "percona.fullname" -}} 15 | {{- $name := default .Chart.Name .Values.nameOverride -}} 16 | {{- printf "%s" .Release.Name | trunc 63 | trimSuffix "-" -}} 17 | {{- end -}} 18 | -------------------------------------------------------------------------------- /helm/helm-server/templates/mysql-configmap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: {{ template "percona.fullname" . }} 5 | labels: 6 | app: {{ template "percona.fullname" . }} 7 | data: 8 | extra.cnf: | 9 | [mysqld] 10 | innodb-buffer-pool-size=128M 11 | {{if .Values.pmm.enabled }} 12 | extrapmm.cnf: | 13 | [mysqld] 14 | log_output=file 15 | slow_query_log=ON 16 | long_query_time=0 17 | log_slow_rate_limit=100 18 | log_slow_rate_type=query 19 | log_slow_verbosity=full 20 | log_slow_admin_statements=ON 21 | log_slow_slave_statements=ON 22 | slow_query_log_always_write_time=1 23 | slow_query_log_use_global_control=all 24 | innodb_monitor_enable=all 25 | {{ end }} 26 | -------------------------------------------------------------------------------- /helm/helm-server/templates/secrets.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: {{ template "percona.fullname" . }}-secrets 5 | labels: 6 | app: {{ template "percona.fullname" . }} 7 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 8 | release: "{{ .Release.Name }}" 9 | heritage: "{{ .Release.Service }}" 10 | type: Opaque 11 | data: 12 | {{ if .Values.passwords.mysqlroot }} 13 | root: {{ .Values.passwords.mysqlroot| b64enc | quote }} 14 | {{ else }} 15 | root: {{ randAlphaNum 10 | b64enc | quote }} 16 | {{ end }} 17 | {{ if .Values.passwords.xtrabackup }} 18 | xtrabackup: {{ .Values.passwords.xtrabackup| b64enc | quote }} 19 | {{ else }} 20 | xtrabackup: {{ randAlphaNum 10 | b64enc | quote }} 21 | {{ end }} 22 | {{ if .Values.passwords.monitor }} 23 | monitor: {{ .Values.passwords.monitor| b64enc | quote }} 24 | {{ else }} 25 | monitor: {{ randAlphaNum 10 | b64enc | quote }} 26 | {{ end }} 27 | {{ if .Values.passwords.clustercheck }} 28 | clustercheck: {{ .Values.passwords.clustercheck| b64enc | quote }} 29 | {{ else }} 30 | clustercheck: {{ randAlphaNum 10 | b64enc | quote }} 31 | {{ end }} 32 | {{ if .Values.passwords.proxyuser }} 33 | proxyuser: {{ .Values.passwords.proxyuser| b64enc | quote }} 34 | {{ else }} 35 | proxyuser: {{ randAlphaNum 10 | b64enc | quote }} 36 | {{ end }} 37 | -------------------------------------------------------------------------------- /helm/helm-server/templates/statefulset.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1beta2 2 | kind: StatefulSet 3 | metadata: 4 | name: {{ template "percona.fullname" . }}-node 5 | labels: 6 | app: {{ template "percona.fullname" . }} 7 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 8 | release: "{{ .Release.Name }}" 9 | heritage: "{{ .Release.Service }}" 10 | component: {{ template "percona.fullname" . }}-nodes 11 | spec: 12 | replicas: {{ .Values.replicas }} 13 | selector: 14 | matchLabels: 15 | component: {{ template "percona.fullname" . }}-nodes 16 | serviceName: "{{ template "percona.fullname" . }}-nodes" 17 | template: 18 | metadata: 19 | labels: 20 | component: {{ template "percona.fullname" . }}-nodes 21 | spec: 22 | securityContext: 23 | supplementalGroups: [99] 24 | {{ if eq .Values.platform "kubernetes" }} 25 | fsGroup: 1001 26 | {{ end }} 27 | {{ if eq .Values.kind "cluster" }} 28 | {{- if .Values.persistence.restoreBackup }} 29 | initContainers: 30 | - name: restore-mysql 31 | image: perconalab/backupjob-openshift 32 | command: 33 | - bash 34 | - "-c" 35 | - | 36 | set -ex 37 | cd /var/lib/mysql 38 | rm -fr * 39 | cat /backup/$BACKUPSRC/xtrabackup.stream | xbstream -x 40 | xtrabackup --prepare --target-dir=/var/lib/mysql 41 | env: 42 | - name: BACKUPSRC 43 | value: {{ .Values.persistence.backupDir | quote }} 44 | volumeMounts: 45 | - name: backup 46 | mountPath: /backup 47 | - name: datadir 48 | mountPath: /var/lib/mysql 49 | {{ end }} 50 | containers: 51 | - name: node 52 | image: "{{ .Values.imageRepo }}:{{ .Values.imageTag }}" 53 | imagePullPolicy: {{ .Values.imagePullPolicy | quote }} 54 | resources: 55 | {{ toYaml .Values.resources | indent 10 }} 56 | ports: 57 | - containerPort: 3306 58 | name: mysql 59 | readinessProbe: 60 | exec: 61 | command: 62 | - /usr/bin/clustercheck.sh 63 | initialDelaySeconds: 15 64 | timeoutSeconds: 15 65 | periodSeconds: 30 66 | failureThreshold: 5 67 | livenessProbe: 68 | exec: 69 | command: 70 | - /usr/bin/clustercheck.sh 71 | initialDelaySeconds: 300 72 | timeoutSeconds: 5 73 | periodSeconds: 10 74 | {{ else }} 75 | initContainers: 76 | - name: clone-mysql 77 | image: perconalab/percona-rs 78 | command: ["/bin/bash","/usr/bin/init-datadir.sh"] 79 | {{- if .Values.persistence.initdatadir }} 80 | env: 81 | - name: MYSQL_INIT_DATADIR 82 | value: "true" 83 | {{ end }} 84 | volumeMounts: 85 | - name: datadir 86 | mountPath: /var/lib/mysql 87 | - name: config-volume 88 | mountPath: /etc/mysql/conf.d 89 | containers: 90 | - name: mysql 91 | image: perconalab/percona-rs 92 | imagePullPolicy: Always 93 | ports: 94 | - containerPort: 3306 95 | name: mysql 96 | readinessProbe: 97 | exec: 98 | command: ["/usr/bin/mysqlcheck.sh"] 99 | initialDelaySeconds: 30 100 | periodSeconds: 10 101 | timeoutSeconds: 5 102 | readinessProbe: 103 | exec: 104 | command: ["/usr/bin/mysqlcheck.sh"] 105 | initialDelaySeconds: 5 106 | periodSeconds: 2 107 | timeoutSeconds: 1 108 | {{ end }} 109 | env: 110 | {{- if .Values.persistence.initdatadir }} 111 | - name: MYSQL_INIT_DATADIR 112 | value: "true" 113 | {{ end }} 114 | - name: MYSQL_ROOT_PASSWORD 115 | valueFrom: 116 | secretKeyRef: 117 | name: {{ template "percona.fullname" . }}-secrets 118 | key: root 119 | - name: XTRABACKUP_PASSWORD 120 | valueFrom: 121 | secretKeyRef: 122 | name: {{ template "percona.fullname" . }}-secrets 123 | key: xtrabackup 124 | - name: MONITOR_PASSWORD 125 | valueFrom: 126 | secretKeyRef: 127 | name: {{ template "percona.fullname" . }}-secrets 128 | key: monitor 129 | - name: CLUSTERCHECK_PASSWORD 130 | valueFrom: 131 | secretKeyRef: 132 | name: {{ template "percona.fullname" . }}-secrets 133 | key: clustercheck 134 | volumeMounts: 135 | - name: datadir 136 | mountPath: /var/lib/mysql 137 | - name: config-volume 138 | mountPath: /etc/mysql/conf.d/ 139 | {{- if .Values.pmm.enabled }} 140 | - name: pmm-client 141 | image: perconalab/pmm-client 142 | imagePullPolicy: Always 143 | env: 144 | - name: PMM_SERVER 145 | value: {{ .Values.pmm.service }} 146 | - name: DB_TYPE 147 | value: mysql 148 | - name: DB_USER 149 | value: root 150 | - name: DB_PASSWORD 151 | valueFrom: 152 | secretKeyRef: 153 | name: {{ template "percona.fullname" . }}-secrets 154 | key: root 155 | volumeMounts: 156 | - name: datadir 157 | mountPath: /var/lib/mysql 158 | {{- end }} 159 | volumes: 160 | - name: config-volume 161 | configMap: 162 | name: {{ template "percona.fullname" . }} 163 | optional: true 164 | {{- if .Values.persistence.restoreBackup }} 165 | - name: backup 166 | persistentVolumeClaim: 167 | claimName: backup-volume 168 | {{- end }} 169 | {{- if .Values.persistence.enabled }} 170 | volumeClaimTemplates: 171 | - metadata: 172 | name: datadir 173 | spec: 174 | accessModes: [ {{ .Values.persistence.accessMode | quote }} ] 175 | resources: 176 | requests: 177 | storage: {{ .Values.persistence.size }} 178 | {{- else }} 179 | - name: datadir 180 | hostPath: 181 | path: "/mnt/disks/ssd0" 182 | {{- end }} 183 | {{- if .Values.proxysql.enabled }} 184 | --- 185 | apiVersion: apps/v1 186 | kind: StatefulSet 187 | metadata: 188 | name: {{ template "percona.fullname" . }}-proxysql 189 | labels: 190 | app: {{ template "percona.fullname" . }} 191 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 192 | release: "{{ .Release.Name }}" 193 | heritage: "{{ .Release.Service }}" 194 | component: {{ template "percona.fullname" . }}-proxysql 195 | spec: 196 | serviceName: "{{ template "percona.fullname" . }}-proxysql" 197 | replicas: 1 198 | selector: 199 | matchLabels: 200 | component: {{ template "percona.fullname" . }}-proxysql 201 | template: 202 | metadata: 203 | labels: 204 | component: {{ template "percona.fullname" . }}-proxysql 205 | spec: 206 | securityContext: 207 | supplementalGroups: [99] 208 | {{ if eq .Values.platform "kubernetes" }} 209 | fsGroup: 1001 210 | {{ end }} 211 | containers: 212 | - name: proxysql 213 | image: perconalab/proxysql-openshift:{{ .Values.imageProxySQLTag }} 214 | imagePullPolicy: {{ .Values.imagePullPolicy | quote }} 215 | ports: 216 | - containerPort: 3306 217 | name: mysql 218 | - containerPort: 6032 219 | name: proxyadm 220 | volumeMounts: 221 | - name: proxydata 222 | mountPath: /var/lib/proxysql 223 | subPath: data 224 | resources: 225 | {{ toYaml .Values.resources | indent 10 }} 226 | env: 227 | - name: MYSQL_ROOT_PASSWORD 228 | valueFrom: 229 | secretKeyRef: 230 | name: {{ template "percona.fullname" . }}-secrets 231 | key: root 232 | - name: MYSQL_PROXY_USER 233 | value: "proxyuser" 234 | - name: MYSQL_PROXY_PASSWORD 235 | valueFrom: 236 | secretKeyRef: 237 | name: {{ template "percona.fullname" . }}-secrets 238 | key: proxyuser 239 | - name: MONITOR_PASSWORD 240 | valueFrom: 241 | secretKeyRef: 242 | name: {{ template "percona.fullname" . }}-secrets 243 | key: monitor 244 | - name: PXCSERVICE 245 | value: "{{ template "percona.fullname" . }}-nodes" 246 | {{- if .Values.pmm.enabled }} 247 | - name: pmm-client 248 | image: perconalab/pmm-client 249 | imagePullPolicy: Always 250 | env: 251 | - name: PMM_SERVER 252 | value: {{ .Values.pmm.service }} 253 | - name: DB_TYPE 254 | value: proxysql 255 | - name: DB_ARGS 256 | value: --dsn admin:admin@tcp(localhost:6032)/ 257 | {{- end }} 258 | volumeClaimTemplates: 259 | - metadata: 260 | name: proxydata 261 | spec: 262 | accessModes: [ "ReadWriteOnce" ] 263 | resources: 264 | requests: 265 | storage: 2Gi 266 | {{- end }} 267 | -------------------------------------------------------------------------------- /helm/helm-server/templates/svc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | annotations: 5 | service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" 6 | name: "{{ template "percona.fullname" . }}-nodes" 7 | labels: 8 | app: {{ template "percona.fullname" . }} 9 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 10 | release: "{{ .Release.Name }}" 11 | heritage: "{{ .Release.Service }}" 12 | spec: 13 | ports: 14 | - port: 3306 15 | name: mysql-port 16 | clusterIP: None 17 | selector: 18 | component: {{ template "percona.fullname" . }}-nodes 19 | {{ if .Values.proxysql.enabled }} 20 | --- 21 | apiVersion: v1 22 | kind: Service 23 | metadata: 24 | labels: 25 | app: {{ template "percona.fullname" . }} 26 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 27 | release: "{{ .Release.Name }}" 28 | heritage: "{{ .Release.Service }}" 29 | name: "{{ template "percona.fullname" . }}-proxysql" 30 | spec: 31 | ports: 32 | - name: mysql 33 | port: 3306 34 | protocol: TCP 35 | targetPort: 3306 36 | - name: proxyadm 37 | port: 6032 38 | protocol: TCP 39 | targetPort: 6032 40 | selector: 41 | component: {{ template "percona.fullname" . }}-proxysql 42 | {{ end }} 43 | -------------------------------------------------------------------------------- /helm/helm-server/values.yaml: -------------------------------------------------------------------------------- 1 | ## percona image version 2 | ## ref: https://hub.docker.com/r/library/percona/tags/ 3 | ## 4 | 5 | nameOverride: "restore1" 6 | 7 | ## A choice between "cluster" and "replicaset" 8 | kind: "cluster" 9 | 10 | ## A choice between "kubernetes" and "openshift" 11 | platform: "openshift" 12 | 13 | imageRepo: "perconalab/pxc-openshift" 14 | imageTag: "latest" 15 | imageProxySQLTag: "latest" 16 | replicas: 3 17 | 18 | ## Specify an imagePullPolicy (Required) 19 | ## It's recommended to change this to 'Always' if the image tag is 'latest' 20 | ## ref: http://kubernetes.io/docs/user-guide/images/#updating-images 21 | ## 22 | imagePullPolicy: Always 23 | 24 | ## !!!! Change passwords to secure ones !!!! 25 | passwords: 26 | mysqlroot: "secr3t" 27 | xtrabackup: "secr3t" 28 | monitor: "secr3t" 29 | clustercheck: "secr3t" 30 | proxyuser: "secr3t" 31 | 32 | pmm: 33 | enabled: false 34 | service: "monitoring-service" 35 | 36 | proxysql: 37 | enabled: true 38 | 39 | ## Persist data to a persitent volume 40 | persistence: 41 | enabled: true 42 | ## percona data Persistent Volume Storage Class 43 | ## If defined, storageClassName: 44 | ## If set to "-", storageClassName: "", which disables dynamic provisioning 45 | ## If undefined (the default) or set to null, no storageClassName spec is 46 | ## set, choosing the default provisioner. (gp2 on AWS, standard on 47 | ## GKE, AWS & OpenStack) 48 | ## 49 | # storageClass: "-" 50 | accessMode: ReadWriteOnce 51 | size: 8Gi 52 | 53 | # if you changed passwords - you need to re-init datadir, otherwise passwords will stay the same 54 | initdatadir: false 55 | restoreBackup: false 56 | backupDir: "" 57 | ## Configure resource requests and limits 58 | ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ 59 | ## 60 | resources: 61 | requests: 62 | memory: 256Mi 63 | cpu: 100m 64 | -------------------------------------------------------------------------------- /helm/helm_install.sh: -------------------------------------------------------------------------------- 1 | kubectl create serviceaccount --namespace kube-system tiller 2 | kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller 3 | helm init --service-account tiller 4 | -------------------------------------------------------------------------------- /helm/pmm-server/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | -------------------------------------------------------------------------------- /helm/pmm-server/Chart.yaml: -------------------------------------------------------------------------------- 1 | name: pmm-server 2 | version: 2.29.1 3 | description: Percona Monitoring and Management (PMM) is an open-source platform for managing and monitoring MySQL and MongoDB performance. 4 | keywords: 5 | - mysql 6 | - percona 7 | - database 8 | - sql 9 | - pmm 10 | home: https://www.percona.com/ 11 | icon: https://www.percona.com/sites/all/themes/percona2015/logo.png 12 | sources: 13 | - https://github.com/kubernetes/charts 14 | - https://github.com/docker-library/percona 15 | maintainers: 16 | - name: Percona Engineering Team 17 | email: info@percona.com 18 | engine: gotpl 19 | -------------------------------------------------------------------------------- /helm/pmm-server/README.md: -------------------------------------------------------------------------------- 1 | # Percona Monitoring and Management Helm chart 2 | ## 🛑🛑🛑 It is unsupported software, please consider using the officially supported method of installing PMM Server - https://www.percona.com/doc/percona-monitoring-and-management/2.x/setting-up/index.html 3 | 4 | ## Please use supported Helm charts: https://github.com/percona/percona-helm-charts/tree/main/charts/pmm 5 | 6 | 7 | Percona Monitoring and Management (PMM) is an open-source platform for managing and monitoring MySQL and MongoDB performance. It is developed by Percona in collaboration with experts in the field of managed database services, support and consulting. 8 | 9 | PMM is a free and open-source solution that you can run in your own environment for maximum security and reliability. It provides thorough time-based analysis for MySQL and MongoDB servers to ensure that your data works as efficiently as possible. 10 | 11 | ## Prerequisites 12 | 13 | - Kubernetes 1.9+ / OpenShift 3.9 with Beta APIs enabled 14 | - PV provisioner support in the underlying infrastructure 15 | 16 | ## Installing the Chart 17 | 18 | To install the chart with the release name `monitoring`: 19 | 20 | ```bash 21 | $ helm install --name monitoring . 22 | ``` 23 | 24 | > **Tip**: List all releases using `helm list` 25 | 26 | ## Uninstalling the Chart 27 | 28 | To uninstall/delete the `monitoring` deployment: 29 | 30 | ```bash 31 | $ helm delete --purge monitoring 32 | ``` 33 | 34 | The command removes all the Kubernetes components associated with the chart and deletes the release. 35 | 36 | ## Configuration 37 | 38 | The following tables lists the configurable parameters of the Percona chart and their default values. 39 | 40 | | Parameter | Description | Default | 41 | | ----------------------- | ----------------------------------- | ---------------------------------------------------------- | 42 | | `imageTag` | `percona/pmm-server` image | Most recent release | 43 | | `imagePullPolicy` | Image pull policy | `Always` | 44 | | `persistence.enabled` | Create a volume to store data | true | 45 | | `persistence.size` | Size of persistent volume claim | 8Gi RW | 46 | | `persistence.storageClass` | Type of persistent volume claim | nil (uses alpha storage class annotation) | 47 | | `persistence.accessMode` | ReadWriteOnce or ReadOnly | ReadWriteOnce | 48 | | `resources` | CPU/Memory resource requests/limits | Memory: `1Gi`, CPU: `0.5` | 49 | | `service.type` | Option specifying the [Kubernetes Service type](https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types) to be used | "" | 50 | | `service.port` | Listening port for the Kubernetes Service | 443 | 51 | | `service.loadBalancerIP` | IP address for the public access | "" | 52 | | `prometheus.configMap.name` | Name of k8s configMap with scrape_configs | "" | 53 | | `ingress.enabled` | Enable the [Kubernetes Ingress type](https://v1-18.docs.kubernetes.io/docs/concepts/services-networking/ingress/#the-ingress-resource) | "" | 54 | | `ingress.annotations` | Ingress Annotations | `false` | 55 | | `ingress.rules[].host` | Ingress Host from multiple hosts | `` | 56 | | `ingress.rules[].path` | Ingress Path from multiple hosts | `/` | 57 | | `ingress.rules[].pathType` | Ingress Path Type from multiple hosts | `` | 58 | | `ingress.path` | Ingress Path | `/` | 59 | | `ingress.pathType` | Ingress Path Type [Kubernetes Ingress PathType](https://v1-18.docs.kubernetes.io/docs/concepts/services-networking/ingress/#path-types) | `` | 60 | | `ingress.host` | Ingress Host | `` | 61 | | `ingress.tls` | Configure Ingress TLS options [Kubernetes Ingress TLS](https://v1-18.docs.kubernetes.io/docs/concepts/services-networking/ingress/#tls) | "" | 62 | | `ingress.labels` | Ingress Labels | "" | 63 | 64 | 65 | Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. 66 | 67 | -------------------------------------------------------------------------------- /helm/pmm-server/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | PMM server can be accessed via HTTPS (port {{ .Values.service.port }}) on the following DNS name from within your cluster: 2 | 3 | {{ if .Values.ingress.enabled -}} 4 | endpoint: https://{{ .Values.ingress.host }} 5 | {{ else -}} 6 | endpoint: https://{{ template "percona.fullname" . }}-service.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.service.port }} 7 | {{ end -}} 8 | login: admin 9 | password: {{ .Values.credentials.password }} 10 | -------------------------------------------------------------------------------- /helm/pmm-server/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 5 | */}} 6 | {{- define "percona.name" -}} 7 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 8 | {{- end -}} 9 | 10 | {{/* 11 | Create a default fully qualified app name. 12 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 13 | */}} 14 | {{- define "percona.fullname" -}} 15 | {{- $name := default .Chart.Name .Values.nameOverride -}} 16 | {{- printf "%s" .Release.Name | trunc 63 | trimSuffix "-" -}} 17 | {{- end -}} 18 | -------------------------------------------------------------------------------- /helm/pmm-server/templates/ingress.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.ingress.enabled -}} 2 | apiVersion: networking.k8s.io/v1beta1 3 | kind: Ingress 4 | metadata: 5 | name: {{ template "percona.fullname" . }} 6 | labels: 7 | app: {{ template "percona.fullname" . }} 8 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 9 | release: "{{ .Release.Name }}" 10 | heritage: "{{ .Release.Service }}" 11 | {{- if .Values.ingress.labels }} 12 | {{ toYaml .Values.ingress.labels | indent 4 }} 13 | {{- end }} 14 | {{- with .Values.ingress.annotations }} 15 | annotations: 16 | {{ toYaml . | indent 4 }} 17 | {{- end }} 18 | spec: 19 | {{- if .Values.ingress.tls }} 20 | tls: 21 | {{ toYaml .Values.ingress.tls | indent 4 }} 22 | {{- end }} 23 | rules: 24 | {{- if .Values.ingress.rules }} 25 | {{- range $rule := .Values.ingress.rules }} 26 | - host: {{ $rule.host }} 27 | http: 28 | paths: 29 | - path: {{ $rule.path | default $.Values.ingress.path }} 30 | {{- if $rule.pathType }} 31 | pathType: {{ $rule.pathType }} 32 | {{- end }} 33 | backend: 34 | serviceName: "{{ template "percona.fullname" $ }}-service" 35 | servicePort: {{ $.Values.service.port }} 36 | {{- end }} 37 | {{- else }} 38 | - http: 39 | paths: 40 | - backend: 41 | serviceName: "{{ template "percona.fullname" $ }}-service" 42 | servicePort: {{ $.Values.service.port }} 43 | path: {{ $.Values.ingress.path }} 44 | {{- if $.Values.ingress.pathType }} 45 | pathType: {{ $.Values.ingress.pathType }} 46 | {{- end }} 47 | {{- end }} 48 | {{- end }} 49 | -------------------------------------------------------------------------------- /helm/pmm-server/templates/route.yaml: -------------------------------------------------------------------------------- 1 | {{ if and (eq .Values.platform "openshift") }} 2 | apiVersion: route.openshift.io/v1 3 | kind: Route 4 | metadata: 5 | name: "{{ template "percona.fullname" . }}" 6 | labels: 7 | component: pmm 8 | app: {{ template "percona.fullname" . }} 9 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 10 | release: "{{ .Release.Name }}" 11 | heritage: "{{ .Release.Service }}" 12 | spec: 13 | host: "" 14 | port: 15 | targetPort: 8443 16 | tls: 17 | termination: passthrough 18 | insecureEdgeTerminationPolicy: Redirect 19 | to: 20 | kind: Service 21 | name: "{{ template "percona.fullname" . }}-service" 22 | weight: 100 23 | wildcardPolicy: None 24 | status: 25 | ingress: [] 26 | {{ end }} 27 | -------------------------------------------------------------------------------- /helm/pmm-server/templates/statefulset.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: StatefulSet 3 | metadata: 4 | name: {{ template "percona.fullname" . }} 5 | labels: 6 | app: {{ template "percona.fullname" . }} 7 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 8 | release: "{{ .Release.Name }}" 9 | heritage: "{{ .Release.Service }}" 10 | spec: 11 | serviceName: {{ template "percona.fullname" . }} 12 | replicas: 1 13 | updateStrategy: 14 | type: RollingUpdate 15 | selector: 16 | matchLabels: 17 | app: {{ template "percona.fullname" . }} 18 | component: pmm 19 | template: 20 | metadata: 21 | {{ if eq .Values.platform "openshift" }} 22 | annotations: 23 | openshift.io/scc: {{ .Values.scc | default "privileged" }} 24 | {{ end }} 25 | labels: 26 | app: {{ template "percona.fullname" . }} 27 | component: pmm 28 | spec: 29 | serviceAccountName: {{ .Values.sa | default "default" }} 30 | securityContext: 31 | supplementalGroups: [1000] 32 | fsGroup: 1000 33 | containers: 34 | - name: {{ template "percona.fullname" . }} 35 | image: "{{ .Values.imageRepo }}:{{ .Values.imageTag }}" 36 | imagePullPolicy: {{ .Values.imagePullPolicy | quote }} 37 | resources: 38 | {{ toYaml .Values.resources | indent 12 }} 39 | 40 | ports: 41 | - name: https 42 | protocol: TCP 43 | containerPort: 443 44 | volumeMounts: 45 | - name: pmmdata 46 | mountPath: /pmmdata 47 | {{ if .Values.prometheus.configMap.name }} 48 | - name: prometheus-configmap 49 | mountPath: /srv/prometheus/prometheus.base.yml 50 | subPath: prometheus.base.yml 51 | {{ end }} 52 | 53 | env: 54 | - name: DISABLE_UPDATES 55 | value: "true" 56 | 57 | - name: METRICS_RESOLUTION 58 | value: {{ .Values.metric.resolution | quote }} 59 | 60 | - name: METRICS_RETENTION 61 | value: {{ .Values.metric.retention | quote }} 62 | 63 | - name: QUERIES_RETENTION 64 | value: {{ .Values.queries.retention | quote }} 65 | 66 | - name: METRICS_MEMORY 67 | value: "600000" 68 | 69 | {{ if .Values.credentials.password }} 70 | - name: ADMIN_PASSWORD 71 | value: {{ .Values.credentials.password | quote }} 72 | {{ end }} 73 | 74 | command: ["bash"] 75 | args: 76 | - "-c" 77 | - | 78 | set -ex 79 | 80 | 81 | if [[ $EUID != 1000 ]]; then 82 | # logrotate requires UID in /etc/passwd 83 | sed -e "s^x:1000:^x:$EUID:^" /etc/passwd > /tmp/passwd 84 | cat /tmp/passwd > /etc/passwd 85 | rm -rf /tmp/passwd 86 | fi 87 | if [ ! -f /pmmdata/app-init ]; then 88 | # the PV hasn't been initialized, so copy over default 89 | # pmm-server directories before symlinking 90 | mkdir -p /pmmdata 91 | 92 | rsync -a --owner=$EUID /srv/prometheus/data/ /pmmdata/prometheus-data/ 93 | rsync -a --owner=$EUID /srv/prometheus/rules/ /pmmdata/prometheus-rules/ 94 | rsync -a --owner=$EUID /srv/postgres/ /pmmdata/postgres/ 95 | rsync -a --owner=$EUID /srv/grafana/ /pmmdata/grafana/ 96 | rsync -a --owner=$EUID /srv/clickhouse/ /pmmdata/clickhouse/ 97 | rsync -a --owner=$EUID /srv/victoriametrics/ /pmmdata/victoriametrics/ 98 | 99 | # initialize the PV and then mark it complete 100 | touch /pmmdata/app-init 101 | fi 102 | 103 | # remove the default directories so we can symlink the 104 | # existing PV directories 105 | rm -Rf /srv/prometheus/data 106 | rm -Rf /srv/prometheus/rules 107 | rm -Rf /srv/postgres 108 | rm -Rf /srv/grafana 109 | rm -Rf /srv/clickhouse 110 | rm -Rf /srv/victoriametrics 111 | 112 | # symlink pmm-server paths to point to our PV 113 | ln -s /pmmdata/prometheus-data /srv/prometheus/data 114 | ln -s /pmmdata/prometheus-rules /srv/prometheus/rules 115 | ln -s /pmmdata/postgres /srv/ 116 | ln -s /pmmdata/grafana /srv/ 117 | ln -s /pmmdata/clickhouse /srv/ 118 | ln -s /pmmdata/victoriametrics /srv/ 119 | 120 | sed -ri "s/(^log_directory = ).*/\1\'\/srv\/logs\'/g" /pmmdata/postgres/postgresql.conf 121 | chmod 700 /pmmdata/postgres 122 | 123 | {{ if and (eq .Values.platform "openshift") (eq .Values.service.type "LoadBalancer") (.Values.supresshttp2) }} 124 | # http2 is not supported in openshift now 125 | sed -e "s^ http2^^" /etc/nginx/conf.d/pmm.conf > /tmp/nginx 126 | cat /tmp/nginx > /etc/nginx/conf.d/pmm.conf 127 | rm -rf /tmp/nginx 128 | {{ end }} 129 | 130 | {{ if .Values.credentials.password }} 131 | ln -s /srv/grafana /usr/share/grafana/data 132 | {{ end }} 133 | bash -x /opt/entrypoint.sh 134 | 135 | {{ if .Values.prometheus.configMap.name }} 136 | volumes: 137 | - name: prometheus-configmap 138 | configMap: 139 | name: {{ .Values.prometheus.configMap.name }} 140 | {{ end }} 141 | 142 | {{- if .Values.persistence.enabled }} 143 | volumeClaimTemplates: 144 | - metadata: 145 | name: pmmdata 146 | spec: 147 | accessModes: [ {{ .Values.persistence.accessMode | quote }} ] 148 | {{ if .Values.persistence.storageClassName }} 149 | storageClassName: {{ .Values.persistence.storageClassName }} 150 | {{ end }} 151 | resources: 152 | requests: 153 | storage: {{ .Values.persistence.size }} 154 | {{- else }} 155 | volumes: 156 | - name: pmmdata 157 | hostPath: 158 | path: "/mnt/disks/ssd0" 159 | {{- end -}} 160 | -------------------------------------------------------------------------------- /helm/pmm-server/templates/svc.yaml: -------------------------------------------------------------------------------- 1 | kind: Service 2 | apiVersion: v1 3 | metadata: 4 | name: "{{ template "percona.fullname" . }}-service" 5 | labels: 6 | component: pmm 7 | app: {{ template "percona.fullname" . }} 8 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 9 | release: "{{ .Release.Name }}" 10 | heritage: "{{ .Release.Service }}" 11 | spec: 12 | ports: 13 | - name: https 14 | protocol: TCP 15 | port: {{ .Values.service.port }} 16 | targetPort: 443 17 | selector: 18 | component: pmm 19 | app: {{ template "percona.fullname" . }} 20 | type: {{ .Values.service.type | quote }} 21 | {{- if eq .Values.service.type "LoadBalancer" }} 22 | {{- if .Values.service.loadBalancerIP }} 23 | loadBalancerIP: {{ .Values.service.loadBalancerIP | quote }} 24 | {{- end -}} 25 | {{- end -}} 26 | -------------------------------------------------------------------------------- /helm/pmm-server/values.yaml: -------------------------------------------------------------------------------- 1 | ## percona image version 2 | ## ref: https://hub.docker.com/r/library/percona/tags/ 3 | ## 4 | imageRepo: "percona/pmm-server" 5 | imageTag: "2.29.0" 6 | 7 | ## A choice between "kubernetes" and "openshift" 8 | platform: "kubernetes" 9 | 10 | ## Specify an imagePullPolicy (Required) 11 | ## It's recommended to change this to 'Always' if the image tag is 'latest' 12 | ## ref: http://kubernetes.io/docs/user-guide/images/#updating-images 13 | ## 14 | imagePullPolicy: Always 15 | scc: null 16 | sa: null 17 | ## Persist data to a persitent volume 18 | persistence: 19 | enabled: true 20 | ## percona data Persistent Volume Storage Class 21 | ## If defined, storageClassName: 22 | ## If set to "-", storageClassName: "", which disables dynamic provisioning 23 | ## If undefined (the default) or set to null, no storageClassName spec is 24 | ## set, choosing the default provisioner. (gp2 on AWS, standard on 25 | ## GKE, AWS & OpenStack) 26 | ## 27 | # storageClass: "-" 28 | accessMode: ReadWriteOnce 29 | size: 8Gi 30 | 31 | ## set credentials 32 | credentials: 33 | password: "admin" 34 | 35 | ## set metric collection settings 36 | metric: 37 | resolution: 1s 38 | retention: 720h 39 | queries: 40 | retention: 8 41 | 42 | ## Configure resource requests and limits 43 | ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ 44 | ## 45 | resources: 46 | requests: 47 | memory: 1Gi 48 | cpu: 0.5 49 | 50 | supresshttp2: true 51 | service: 52 | type: LoadBalancer 53 | port: 443 54 | loadBalancerIP: "" 55 | 56 | ## Mount prometheus scrape config https://www.percona.com/blog/2020/03/23/extending-pmm-prometheus-configuration/ 57 | prometheus: 58 | configMap: 59 | name: "" 60 | 61 | ## Kubernetes Ingress https://kubernetes.io/docs/concepts/services-networking/ingress 62 | ingress: 63 | enabled: false 64 | annotations: {} 65 | # kubernetes.io/ingress.class: nginx 66 | # kubernetes.io/tls-acme: "true" 67 | path: / 68 | pathType: null 69 | host: monitoring-service.example.local 70 | rules: [] 71 | tls: [] 72 | # - secretName: pmm-server-tls 73 | # hosts: 74 | # - monitoring-service.example.local 75 | labels: {} 76 | -------------------------------------------------------------------------------- /images/pmm-client-image/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM centos:7 2 | MAINTAINER Percona Development 3 | 4 | RUN rpmkeys --import https://www.percona.com/downloads/RPM-GPG-KEY-percona 5 | RUN yum install -y https://www.percona.com/redir/downloads/percona-release/redhat/0.1-4/percona-release-0.1-4.noarch.rpm 6 | RUN yum install -y pmm-client procps initscripts && yum clean all 7 | 8 | ONBUILD RUN yum update -y 9 | -------------------------------------------------------------------------------- /images/pmm-server-image/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.11.1 2 | RUN go get github.com/michaloo/go-cron 3 | RUN mv bin/go-cron /usr/bin/go-cron 4 | 5 | FROM percona/pmm-server:1.17.3 6 | COPY --from=0 /usr/bin/go-cron /usr/bin/go-cron 7 | COPY supervisord.conf-rootless /etc/supervisord.d/pmm.ini 8 | COPY entrypoint.sh-rootless /opt/entrypoint.sh 9 | 10 | RUN touch \ 11 | /etc/percona-rds-exporter.yml \ 12 | /var/log/mysql.log \ 13 | /var/log/consul.log \ 14 | /var/log/nginx.log \ 15 | /var/log/cron1.log \ 16 | /var/log/cron2.log \ 17 | /var/log/qan-api.log \ 18 | /var/log/logrotate.log \ 19 | /var/log/prometheus.log \ 20 | /var/log/prometheus1.log \ 21 | /var/log/createdb.log \ 22 | /var/log/createdb2.log \ 23 | /var/log/createdb3.log \ 24 | /var/log/orchestrator.log \ 25 | /var/log/entrypoint.sh.log \ 26 | /var/log/purge-qan-data.log \ 27 | /var/log/dashboard-upgrade.log \ 28 | /var/log/node_exporter.log \ 29 | /var/log/pmm-manage.log \ 30 | /var/log/pmm-managed.log 31 | RUN chown -R pmm:pmm \ 32 | /etc/grafana \ 33 | /etc/supervisord.d \ 34 | /etc/prometheus.yml \ 35 | /etc/prometheus1.yml \ 36 | /etc/orchestrator.conf.json \ 37 | /etc/cron.daily/purge-qan-data \ 38 | /var/log \ 39 | /var/lib \ 40 | /opt \ 41 | /srv \ 42 | /var/run/mysqld \ 43 | /var/run/supervisor \ 44 | /var/lib/mysql \ 45 | /var/lib/grafana \ 46 | /var/log/grafana \ 47 | /usr/share/grafana/public/img \ 48 | /var/log/supervisor \ 49 | /usr/local/percona/qan-agent \ 50 | /etc/percona-rds-exporter.yml \ 51 | /var/log/mysql.log \ 52 | /var/log/consul.log \ 53 | /var/log/nginx.log \ 54 | /var/log/cron1.log \ 55 | /var/log/cron2.log \ 56 | /var/log/qan-api.log \ 57 | /var/log/logrotate.log \ 58 | /var/log/prometheus.log \ 59 | /var/log/prometheus1.log \ 60 | /var/log/createdb.log \ 61 | /var/log/createdb2.log \ 62 | /var/log/createdb3.log \ 63 | /var/log/orchestrator.log \ 64 | /var/log/entrypoint.sh.log \ 65 | /var/log/purge-qan-data.log \ 66 | /var/log/dashboard-upgrade.log \ 67 | /var/log/node_exporter.log \ 68 | /var/log/pmm-manage.log \ 69 | /var/log/pmm-managed.log 70 | RUN chmod -R g+w \ 71 | /etc/grafana \ 72 | /etc/supervisord.d \ 73 | /etc/prometheus.yml \ 74 | /etc/prometheus1.yml \ 75 | /etc/orchestrator.conf.json \ 76 | /etc/cron.daily/purge-qan-data \ 77 | /var/log \ 78 | /var/lib \ 79 | /opt \ 80 | /srv \ 81 | /var/run/mysqld \ 82 | /var/run/supervisor \ 83 | /var/lib/mysql \ 84 | /var/lib/grafana \ 85 | /var/log/grafana \ 86 | /usr/share/grafana/public/img \ 87 | /var/log/supervisor \ 88 | /usr/local/percona/qan-agent \ 89 | /etc/percona-rds-exporter.yml \ 90 | /var/log/mysql.log \ 91 | /var/log/consul.log \ 92 | /var/log/nginx.log \ 93 | /var/log/cron1.log \ 94 | /var/log/cron2.log \ 95 | /var/log/qan-api.log \ 96 | /var/log/logrotate.log \ 97 | /var/log/prometheus.log \ 98 | /var/log/prometheus1.log \ 99 | /var/log/createdb.log \ 100 | /var/log/createdb2.log \ 101 | /var/log/createdb3.log \ 102 | /var/log/orchestrator.log \ 103 | /var/log/entrypoint.sh.log \ 104 | /var/log/purge-qan-data.log \ 105 | /var/log/dashboard-upgrade.log \ 106 | /var/log/node_exporter.log \ 107 | /var/log/pmm-manage.log \ 108 | /var/log/pmm-managed.log 109 | 110 | # allow to disable http2 111 | RUN chown pmm:pmm /etc/nginx/conf.d/pmm.conf \ 112 | && chmod g+w /etc/nginx/conf.d/pmm.conf 113 | # needed for replace effective uid cmd on openshift 114 | RUN chmod g+w /etc/passwd 115 | # needed for rsync & rm cmd on openshift 116 | RUN chmod -R g+rwx \ 117 | /var/lib/nginx/tmp/proxy \ 118 | /var/lib/mysql \ 119 | /var/lib/grafana 120 | # needed for start services on openshift 121 | RUN chmod -R g+rwx \ 122 | /etc/grafana \ 123 | /home/pmm 124 | # needed for createdb jobs & logrotate 125 | RUN printf "[client]\nuser=root\n" > /home/pmm/.my.cnf 126 | 127 | # run rootless nginx 128 | RUN sed -i -e 's^80^8080^; s^443^8443^' /etc/nginx/conf.d/pmm.conf 129 | RUN sed -i -e 's^/run/nginx.pid^/var/run/nginx/nginx.pid^' /etc/nginx/nginx.conf 130 | RUN install -o pmm -g pmm -m 0775 -d \ 131 | /var/lib/nginx/tmp \ 132 | /var/lib/nginx \ 133 | /var/run/nginx \ 134 | /var/log/nginx 135 | RUN rm -rf /var/log/nginx/*.log 136 | 137 | EXPOSE 8080 8443 138 | USER pmm 139 | -------------------------------------------------------------------------------- /images/pmm-server-image/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | docker build --no-cache -t perconalab/pmm-server-openshift:$(date '+%Y%m%d%H%M') . 3 | -------------------------------------------------------------------------------- /images/pmm-server-image/entrypoint.sh-rootless: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o errexit 4 | 5 | export DISABLE_UPDATES=true 6 | 7 | # Add logging 8 | if [ -n "${ENABLE_DEBUG}" ]; then 9 | set -o xtrace 10 | exec > >(tee -a /var/log/$(basename $0).log) 2>&1 11 | fi 12 | 13 | # Prometheus 14 | if [[ ! "${METRICS_RESOLUTION:-1s}" =~ ^[1-5]s$ ]]; then 15 | echo "METRICS_RESOLUTION takes only values from 1s to 5s." 16 | exit 1 17 | fi 18 | sed "s/1s/${METRICS_RESOLUTION:-1s}/" /etc/prometheus.yml > /tmp/prometheus.yml 19 | cat /tmp/prometheus.yml > /etc/prometheus.yml 20 | rm -rf /tmp/prometheus.yml 21 | 22 | sed "s/ENV_METRICS_RETENTION/${METRICS_RETENTION:-720h}/" /etc/supervisord.d/pmm.ini > /tmp/pmm.ini 23 | sed -i "s/ENV_MAX_CONNECTIONS/${MAX_CONNECTIONS:-15}/" /tmp/pmm.ini 24 | 25 | if [ -n "$METRICS_MEMORY" ]; then 26 | # Preserve compatibility with existing METRICS_MEMORY variable. 27 | # https://jira.percona.com/browse/PMM-969 28 | METRICS_MEMORY_MULTIPLIED=$(( ${METRICS_MEMORY} * 1024 )) 29 | else 30 | MEMORY_LIMIT=$(cat /sys/fs/cgroup/memory/memory.limit_in_bytes || :) 31 | TOTAL_MEMORY=$(( $(grep MemTotal /proc/meminfo | awk '{print$2}') * 1024 )) 32 | MEMORY_AVAIABLE=$(printf "%i\n%i\n" "$MEMORY_LIMIT" "$TOTAL_MEMORY" | sort -n | grep -v "^0$" | head -1) 33 | METRICS_MEMORY_MULTIPLIED=$(( (${MEMORY_AVAIABLE} - 256*1024*1024) / 100 * 15 )) 34 | if [[ $METRICS_MEMORY_MULTIPLIED -lt $((128*1024*1024)) ]]; then 35 | METRICS_MEMORY_MULTIPLIED=$((128*1024*1024)) 36 | fi 37 | fi 38 | sed -i "s/ENV_METRICS_MEMORY_MULTIPLIED/${METRICS_MEMORY_MULTIPLIED}/" /tmp/pmm.ini 39 | 40 | # Orchestrator 41 | if [[ "${ORCHESTRATOR_ENABLED}" = "true" ]]; then 42 | sed -i "s/autostart = false/autostart = true/" /tmp/pmm.ini 43 | sed "s/orc_client_user/${ORCHESTRATOR_USER:-orc_client_user}/" /etc/orchestrator.conf.json > /tmp/orchestrator.conf.json 44 | sed -i "s/orc_client_password/${ORCHESTRATOR_PASSWORD:-orc_client_password}/" /tmp/orchestrator.conf.json 45 | cat /tmp/orchestrator.conf.json > /etc/orchestrator.conf.json 46 | rm -rf /tmp/orchestrator.conf.json 47 | fi 48 | cat /tmp/pmm.ini > /etc/supervisord.d/pmm.ini 49 | rm -rf /tmp/pmm.ini 50 | 51 | # Cron 52 | sed "s/^INTERVAL=.*/INTERVAL=${QUERIES_RETENTION:-8}/" /etc/cron.daily/purge-qan-data > /tmp/purge-qan-data 53 | cat /tmp/purge-qan-data > /etc/cron.daily/purge-qan-data 54 | rm -rf /tmp/purge-qan-data 55 | 56 | # HTTP basic auth 57 | if [ -n "${SERVER_PASSWORD}" -a -z "${UPDATE_MODE}" ]; then 58 | SERVER_USER=${SERVER_USER:-pmm} 59 | cat > /srv/update/pmm-manage.yml <<-EOF 60 | users: 61 | - username: "${SERVER_USER//\"/\"}" 62 | password: "${SERVER_PASSWORD//\"/\"}" 63 | EOF 64 | pmm-configure -skip-prometheus-reload true -grafana-db-path /var/lib/grafana/grafana.db || : 65 | fi 66 | 67 | # Upgrade 68 | if [ -f /var/lib/grafana/grafana.db ]; then 69 | chown -R "$(id -u):$(id -g)" /opt/consul-data 70 | chown -R "$(id -u):$(id -g)" /opt/prometheus/data 71 | chown -R "$(id -u):$(id -g)" /var/lib/mysql 72 | chown -R "$(id -u):$(id -g)" /var/lib/grafana 73 | fi 74 | 75 | # copy SSL, follow links 76 | pushd /etc/nginx >/dev/null 77 | if [ -s ssl/server.crt ]; then 78 | cat ssl/server.crt > /srv/nginx/certificate.crt 79 | fi 80 | if [ -s ssl/server.key ]; then 81 | cat ssl/server.key > /srv/nginx/certificate.key 82 | fi 83 | if [ -s ssl/dhparam.pem ]; then 84 | cat ssl/dhparam.pem > /srv/nginx/dhparam.pem 85 | fi 86 | popd >/dev/null 87 | 88 | # Start supervisor in foreground 89 | if [ -z "${UPDATE_MODE}" ]; then 90 | exec supervisord -n -c /etc/supervisord.conf 91 | fi 92 | -------------------------------------------------------------------------------- /images/pmm-server-image/supervisord.conf-rootless: -------------------------------------------------------------------------------- 1 | [unix_http_server] 2 | chmod = 0700 3 | username = dummy 4 | password = dummy 5 | 6 | [supervisord] 7 | childlogdir = /var/log/supervisor 8 | nodaemon = true 9 | pidfile = /tmp/supervisord.pid 10 | 11 | [supervisorctl] 12 | username = dummy 13 | password = dummy 14 | 15 | [program:mysql] 16 | priority = 1 17 | command = 18 | /usr/sbin/mysqld 19 | --basedir=/usr 20 | --datadir=/var/lib/mysql 21 | --plugin-dir=/usr/lib64/mysql/plugin 22 | --pid-file=/var/run/mysqld/mysqld.pid 23 | --socket=/var/lib/mysql/mysql.sock 24 | stdout_logfile = /var/log/mysql.log 25 | stderr_logfile = /var/log/mysql.log 26 | autorestart = true 27 | 28 | [program:consul] 29 | priority = 2 30 | command = 31 | /usr/sbin/consul 32 | agent 33 | -server 34 | -data-dir="/opt/consul-data" 35 | -bootstrap 36 | -client="0.0.0.0" 37 | -advertise="127.0.0.1" 38 | -ui 39 | stdout_logfile = /var/log/consul.log 40 | stderr_logfile = /var/log/consul.log 41 | autorestart = true 42 | 43 | [program:grafana] 44 | priority = 3 45 | directory = /usr/share/grafana 46 | environment = HOME=/usr/share/grafana 47 | command = 48 | /usr/sbin/grafana-server 49 | --homepath=/usr/share/grafana 50 | --config=/etc/grafana/grafana.ini 51 | cfg:default.paths.data=/var/lib/grafana 52 | cfg:default.paths.logs=/var/log/grafana 53 | cfg:default.paths.plugins=/var/lib/grafana/plugins 54 | cfg:default.server.root_url="%%(protocol)s://%%(domain)s:%%(http_port)s/graph" 55 | ENV_AUTH_BASIC 56 | # use /var/log/grafana/grafana.log 57 | stdout_logfile = NONE 58 | stderr_logfile = NONE 59 | autorestart = true 60 | 61 | [program:nginx] 62 | priority = 4 63 | command = nginx 64 | stdout_logfile = /var/log/nginx.log 65 | stderr_logfile = /var/log/nginx.log 66 | autorestart = true 67 | 68 | [program:cron1] 69 | priority = 5 70 | command = go-cron "0 0 0 * * *" /usr/sbin/logrotate -s /var/lib/logrotate/logrotate.status -l /var/log/logrotate.log /etc/logrotate.conf 71 | stdout_logfile = /var/log/cron1.log 72 | stderr_logfile = /var/log/cron1.log 73 | autorestart = true 74 | 75 | [program:cron2] 76 | priority = 5 77 | command = go-cron "0 0 0 * * *" /etc/cron.daily/purge-qan-data 78 | stdout_logfile = /var/log/cron2.log 79 | stderr_logfile = /var/log/cron2.log 80 | autorestart = true 81 | 82 | [program:qan-api] 83 | priority = 6 84 | environment = PERCONA_DATASTORE_BASEDIR=/usr/share/percona-qan-api/src/github.com/percona/qan-api,PERCONA_DATASTORE_CONF=/etc/percona-qan-api.conf,BASE_PATH=/qan-api 85 | # Sleep to wait for mysql to start up. 86 | command = bash -c "sleep 5 && /usr/sbin/percona-qan-api -srcPath /usr/share/percona-qan-api/src -importPath github.com/percona/qan-api -runMode prod" 87 | stdout_logfile = /var/log/qan-api.log 88 | stderr_logfile = /var/log/qan-api.log 89 | startretries = 60 90 | autorestart = true 91 | stopasgroup = true 92 | 93 | [program:prometheus1] 94 | priority = 7 95 | command = 96 | /usr/sbin/prometheus1 97 | --config.file=/etc/prometheus1.yml 98 | --storage.local.path=/opt/prometheus/data 99 | --web.listen-address=:9094 100 | --storage.local.retention=ENV_METRICS_RETENTION 101 | --storage.local.target-heap-size=ENV_METRICS_MEMORY_MULTIPLIED 102 | --storage.local.chunk-encoding-version=2 103 | --web.console.libraries=/usr/share/prometheus1/console_libraries 104 | --web.console.templates=/usr/share/prometheus1/consoles 105 | --web.external-url=http://localhost:9094/prometheus1/ 106 | --web.max-connections=ENV_MAX_CONNECTIONS 107 | stdout_logfile = /var/log/prometheus1.log 108 | stderr_logfile = /var/log/prometheus1.log 109 | autorestart = true 110 | stopwaitsecs = 300 111 | 112 | [program:prometheus] 113 | priority = 7 114 | # --web.enable-lifecycle: pmm-managed uses /-/reload path to reload config. 115 | command = 116 | /usr/sbin/prometheus 117 | --config.file=/etc/prometheus.yml 118 | --storage.tsdb.path=/opt/prometheus/data/.prom2-data 119 | --storage.tsdb.retention=ENV_METRICS_RETENTION 120 | --web.listen-address=:9090 121 | --web.console.libraries=/usr/share/prometheus/console_libraries 122 | --web.console.templates=/usr/share/prometheus/consoles 123 | --web.external-url=http://localhost:9090/prometheus/ 124 | --web.enable-admin-api 125 | --web.enable-lifecycle 126 | stdout_logfile = /var/log/prometheus.log 127 | stderr_logfile = /var/log/prometheus.log 128 | autorestart = true 129 | stopwaitsecs = 300 130 | 131 | # This is here to support data containers of v1.0.4. 132 | [program:createdb] 133 | priority = 8 134 | # Sleep to wait for mysql to start up. 135 | command = bash -c "sleep 5 && mysql -uroot -vv -e \"CREATE DATABASE IF NOT EXISTS orchestrator; GRANT ALL PRIVILEGES ON orchestrator.* TO 'orchestrator'@'localhost' IDENTIFIED BY 'orchestrator'\"" 136 | stdout_logfile = /var/log/createdb.log 137 | stderr_logfile = /var/log/createdb.log 138 | startretries = 60 139 | autorestart = unexpected 140 | 141 | # support pmm-data containers <1.5.0 142 | [program:createdb2] 143 | priority = 8 144 | # Sleep to wait for mysql to start up. 145 | command = bash -c 'sleep 5 && mysql -uroot -vv -e "CREATE DATABASE IF NOT EXISTS \`pmm-managed\`; GRANT ALL PRIVILEGES ON \`pmm-managed\`.* TO \"pmm-managed\"@localhost IDENTIFIED BY \"pmm-managed\""' 146 | stdout_logfile = /var/log/createdb2.log 147 | stderr_logfile = /var/log/createdb2.log 148 | startretries = 60 149 | autorestart = unexpected 150 | 151 | # support pmm-data containers <1.8.0 152 | [program:createdb3] 153 | priority = 8 154 | # Sleep to wait for mysql to start up. 155 | command = bash -c "sleep 5 && mysql -uroot -vv -e \"GRANT SELECT ON pmm.* TO 'grafana'@'localhost' IDENTIFIED BY 'N9mutoipdtlxutgi9rHIFnjM'\"" 156 | stdout_logfile = /var/log/createdb3.log 157 | stderr_logfile = /var/log/createdb3.log 158 | startretries = 60 159 | autorestart = unexpected 160 | 161 | [program:orchestrator] 162 | priority = 9 163 | directory = /usr/share/orchestrator 164 | # Sleep to wait for mysql to start up. 165 | command = bash -c "sleep 7 && /usr/sbin/orchestrator -verbose http" 166 | stdout_logfile = /var/log/orchestrator.log 167 | stderr_logfile = /var/log/orchestrator.log 168 | startretries = 60 169 | autostart = false 170 | autorestart = true 171 | stopasgroup = true 172 | 173 | [program:dashboard-upgrade] 174 | priority = 10 175 | command = /usr/share/percona-dashboards/import-dashboards.py 176 | stdout_logfile = /var/log/dashboard-upgrade.log 177 | stderr_logfile = /var/log/dashboard-upgrade.log 178 | startsecs = 0 179 | startretries = 60 180 | autorestart = unexpected 181 | 182 | [program:node_exporter] 183 | priority = 11 184 | command = 185 | /usr/local/percona/pmm-client/node_exporter 186 | -web.listen-address=localhost:9100 187 | -collectors.enabled=diskstats,filefd,filesystem,loadavg,meminfo,netdev,netstat,stat,time,uname,vmstat 188 | stdout_logfile = /var/log/node_exporter.log 189 | stderr_logfile = /var/log/node_exporter.log 190 | autorestart = true 191 | 192 | [program:pmm-manage] 193 | priority = 12 194 | command = 195 | /usr/sbin/pmm-configurator 196 | -ssh-key-owner pmm 197 | -grafana-db-path /var/lib/grafana/grafana.db 198 | stdout_logfile = /var/log/pmm-manage.log 199 | stderr_logfile = /var/log/pmm-manage.log 200 | autorestart = true 201 | 202 | [program:pmm-managed] 203 | priority = 13 204 | environment = PMM_QAN_API_URL=http://127.0.0.1:8080/qan-api/ 205 | command = 206 | /usr/sbin/pmm-managed 207 | -prometheus-config /etc/prometheus.yml 208 | -prometheus-url http://127.0.0.1:9090/prometheus 209 | -db-name pmm-managed 210 | -db-username pmm-managed 211 | -db-password pmm-managed 212 | stdout_logfile = /var/log/pmm-managed.log 213 | stderr_logfile = /var/log/pmm-managed.log 214 | startretries = 1000000 215 | autorestart = true 216 | -------------------------------------------------------------------------------- /images/proxysql-image/README.md: -------------------------------------------------------------------------------- 1 | ## moved to https://github.com/percona/percona-docker/tree/master/proxysql 2 | -------------------------------------------------------------------------------- /images/pxc-image/README.md: -------------------------------------------------------------------------------- 1 | ## moved to https://github.com/percona/percona-docker/tree/master/pxc-57 2 | -------------------------------------------------------------------------------- /images/replicaset-image/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM centos:7 2 | MAINTAINER Percona Development 3 | LABEL vendor=Percona 4 | LABEL com.percona.package="Percona Server" 5 | LABEL com.percona.version="5.7" 6 | LABEL io.k8s.description="Percona Server is an advanced version of MySQL" 7 | LABEL io.k8s.display-name="Percona Server 5.7" 8 | 9 | # the numeric UID is needed for OpenShift 10 | RUN groupadd -g 1001 mysql 11 | RUN useradd -u 1001 -r -g 1001 -s /sbin/nologin \ 12 | -c "Default Application User" mysql 13 | 14 | ARG REPO_URL=http://www.percona.com/downloads/percona-release/redhat/0.1-4/percona-release-0.1-4.noarch.rpm 15 | 16 | # Install server 17 | RUN yum install -y $REPO_URL \ 18 | && yum install -y Percona-Server-server-57 Percona-Server-rocksdb-57 Percona-Server-tokudb-57 curl vim \ 19 | percona-xtrabackup-24 nmap \ 20 | && yum clean all -y && rm -rf /var/cache/yum \ 21 | && mkdir -p /etc/mysql/conf.d/ && mkdir -p /var/log/mysql && mkdir -p /var/lib/mysql \ 22 | && chown -R 1001 /etc/mysql/ /var/log/mysql /var/lib/mysql \ 23 | && chgrp -R 0 /etc/mysql/ /var/log/mysql \ 24 | && chmod -R g=u /etc/mysql/ /var/log/mysql 25 | 26 | ADD node.cnf /etc/mysql/node.cnf 27 | RUN echo '!include /etc/mysql/node.cnf' > /etc/my.cnf 28 | RUN echo '!includedir /etc/mysql/conf.d/' >> /etc/my.cnf 29 | 30 | ADD init-datadir.sh /usr/bin/init-datadir.sh 31 | ADD mysqlcheck.sh /usr/bin/mysqlcheck.sh 32 | ADD xtrabackup_nc.sh /usr/bin/xtrabackup_nc.sh 33 | 34 | COPY entrypoint.sh /entrypoint.sh 35 | 36 | EXPOSE 3306 37 | 38 | ENTRYPOINT ["/entrypoint.sh"] 39 | 40 | USER 1001 41 | 42 | CMD [""] 43 | -------------------------------------------------------------------------------- /images/replicaset-image/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -ex 3 | 4 | USER_ID=$(id -u) 5 | 6 | 7 | ls -lah /var/lib/mysql 8 | 9 | # if command starts with an option, prepend mysqld 10 | if [ "${1:0:1}" = '-' ]; then 11 | CMDARG="$@" 12 | fi 13 | # comment out log output in my.cnf 14 | 15 | if [ -n "$INIT_ROCKSDB" ]; then 16 | export LD_PRELOAD=/lib64/libjemalloc.so.1 17 | fi 18 | # Get config 19 | DATADIR="$("mysqld" --verbose --help 2>/dev/null | awk '$1 == "datadir" { print $2; exit }')" 20 | 21 | if [ ! -d "$DATADIR/mysql" ]; then 22 | if [ -z "$MYSQL_ROOT_PASSWORD" -a -z "$MYSQL_ALLOW_EMPTY_PASSWORD" -a -z "$MYSQL_RANDOM_ROOT_PASSWORD" -a -z "$MYSQL_ROOT_PASSWORD_FILE" ]; then 23 | echo >&2 'error: database is uninitialized and password option is not specified ' 24 | echo >&2 ' You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ROOT_PASSWORD_FILE, MYSQL_ALLOW_EMPTY_PASSWORD or MYSQL_RANDOM_ROOT_PASSWORD' 25 | exit 1 26 | fi 27 | 28 | if [ ! -z "$MYSQL_ROOT_PASSWORD_FILE" -a -z "$MYSQL_ROOT_PASSWORD" ]; then 29 | MYSQL_ROOT_PASSWORD=$(cat $MYSQL_ROOT_PASSWORD_FILE) 30 | fi 31 | 32 | mkdir -p "$DATADIR" 33 | 34 | echo "Running --initialize-insecure datadir: $DATADIR" 35 | mysqld --no-defaults --initialize-insecure --datadir="$DATADIR" 36 | echo 'Finished --initialize-insecure' 37 | 38 | mysqld --no-defaults --datadir="$DATADIR" --skip-networking & 39 | pid="$!" 40 | 41 | mysql=( mysql --protocol=socket -uroot ) 42 | 43 | for i in {3000..0}; do 44 | if echo 'SELECT 1' | "${mysql[@]}" ; then 45 | break 46 | fi 47 | echo 'MySQL init process in progress...' 48 | sleep 1 49 | done 50 | if [ "$i" = 0 ]; then 51 | echo >&2 'MySQL init process failed.' 52 | exit 1 53 | fi 54 | 55 | # install TokuDB engine 56 | if [ -n "$INIT_TOKUDB" ]; then 57 | ps-admin --docker --enable-tokudb -u root -p $MYSQL_ROOT_PASSWORD 58 | fi 59 | if [ -n "$INIT_ROCKSDB" ]; then 60 | ps-admin --docker --enable-rocksdb -u root -p $MYSQL_ROOT_PASSWORD 61 | fi 62 | 63 | if [ ! -z "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then 64 | MYSQL_ROOT_PASSWORD="$(pwmake 128)" 65 | echo "GENERATED ROOT PASSWORD: $MYSQL_ROOT_PASSWORD" 66 | fi 67 | "${mysql[@]}" <<-EOSQL 68 | -- What's done in this file shouldn't be replicated 69 | -- or products like mysql-fabric won't work 70 | SET @@SESSION.SQL_LOG_BIN=0; 71 | CREATE USER 'root'@'%' IDENTIFIED BY '${MYSQL_ROOT_PASSWORD}' ; 72 | GRANT ALL ON *.* TO 'root'@'%' WITH GRANT OPTION ; 73 | ALTER USER 'root'@'localhost' IDENTIFIED BY '${MYSQL_ROOT_PASSWORD}'; 74 | CREATE USER 'xtrabackup'@'localhost' IDENTIFIED BY '$XTRABACKUP_PASSWORD'; 75 | GRANT RELOAD,PROCESS,LOCK TABLES,REPLICATION CLIENT ON *.* TO 'xtrabackup'@'localhost'; 76 | GRANT REPLICATION CLIENT ON *.* TO monitor@'%' IDENTIFIED BY '$MONITOR_PASSWORD'; 77 | GRANT PROCESS ON *.* TO monitor@localhost IDENTIFIED BY '$MONITOR_PASSWORD'; 78 | DROP DATABASE IF EXISTS test ; 79 | FLUSH PRIVILEGES ; 80 | EOSQL 81 | if [ ! -z "$MYSQL_ROOT_PASSWORD" ]; then 82 | mysql+=( -p"${MYSQL_ROOT_PASSWORD}" ) 83 | fi 84 | 85 | if [ "$MYSQL_DATABASE" ]; then 86 | echo "CREATE DATABASE IF NOT EXISTS \`$MYSQL_DATABASE\` ;" | "${mysql[@]}" 87 | mysql+=( "$MYSQL_DATABASE" ) 88 | fi 89 | 90 | if [ "$MYSQL_USER" -a "$MYSQL_PASSWORD" ]; then 91 | echo "CREATE USER '"$MYSQL_USER"'@'%' IDENTIFIED BY '"$MYSQL_PASSWORD"' ;" | "${mysql[@]}" 92 | 93 | if [ "$MYSQL_DATABASE" ]; then 94 | echo "GRANT ALL ON \`"$MYSQL_DATABASE"\`.* TO '"$MYSQL_USER"'@'%' ;" | "${mysql[@]}" 95 | fi 96 | 97 | echo 'FLUSH PRIVILEGES ;' | "${mysql[@]}" 98 | fi 99 | 100 | if [ ! -z "$MYSQL_ONETIME_PASSWORD" ]; then 101 | "${mysql[@]}" <<-EOSQL 102 | ALTER USER 'root'@'%' PASSWORD EXPIRE; 103 | EOSQL 104 | fi 105 | if ! kill -s TERM "$pid" || ! wait "$pid"; then 106 | echo >&2 'MySQL init process failed.' 107 | exit 1 108 | fi 109 | 110 | echo 111 | echo 'MySQL init process done. Ready for start up.' 112 | echo 113 | #mv /etc/my.cnf $DATADIR 114 | fi 115 | 116 | echo "Starting listener for slave requests" 117 | /usr/bin/xtrabackup_nc.sh >> /tmp/xtrabackup_nc.log & 118 | 119 | [[ `hostname` =~ -([0-9]+)$ ]] || exit 1 120 | ordinal=${BASH_REMATCH[1]} 121 | 122 | # Add an offset to avoid reserved server-id=0 value. 123 | #echo server-id=$((100 + $ordinal)) >> /etc/mysql/conf.d/server-id.cnf 124 | sed -i -e "s|^server_id=.*$|server_id=$((100 + $ordinal))|" /etc/mysql/node.cnf 125 | 126 | exec mysqld $CMDARG 127 | -------------------------------------------------------------------------------- /images/replicaset-image/init-datadir.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -ex 3 | if [ ! -z "$MYSQL_INIT_DATADIR" ]; then 4 | echo "Cleaning up /var/lib/mysql" 5 | rm -fr /var/lib/mysql/* 6 | fi 7 | # Skip the clone if data already exists. 8 | [[ -d /var/lib/mysql/mysql ]] && exit 0 9 | # Skip the clone on master (ordinal index 0). 10 | [[ `hostname` =~ ^(.*?)-([0-9]+)$ ]] || exit 1 11 | ordinal=${BASH_REMATCH[2]} 12 | rsname=${BASH_REMATCH[1]} 13 | servicename=$(hostname -f | cut -d"." -f2) 14 | echo "Detected name: $rsname $servicename" 15 | [[ $ordinal -eq 0 ]] && exit 0 16 | # Clone data from previous peer. 17 | ncat --recv-only ${rsname}-$(($ordinal-1)).${servicename} 3307 | xbstream -x -C /var/lib/mysql 18 | # Prepare the backup. 19 | xtrabackup --prepare --target-dir=/var/lib/mysql 20 | ls -lah /var/lib/mysql 21 | -------------------------------------------------------------------------------- /images/replicaset-image/mysqlcheck.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Grant privileges required: 3 | # GRANT PROCESS ON *.* TO 'monitor'@'localhost' IDENTIFIED BY 'monitor'; 4 | 5 | mysqladmin -umonitor -p$MONITOR_PASSWORD -h127.0.0.1 ping 6 | exit $? 7 | -------------------------------------------------------------------------------- /images/replicaset-image/node.cnf: -------------------------------------------------------------------------------- 1 | [mysqld] 2 | ignore-db-dir=lost+found 3 | datadir=/var/lib/mysql 4 | 5 | default_storage_engine=InnoDB 6 | log-bin 7 | binlog_format=ROW 8 | 9 | innodb_flush_method = O_DIRECT 10 | innodb_file_per_table = 1 11 | 12 | bind_address = 0.0.0.0 13 | server_id=1 14 | -------------------------------------------------------------------------------- /images/replicaset-image/xtrabackup_nc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Script to listen on a slave request and perform xtrabackup copy 4 | # 5 | 6 | set -ex 7 | cd /var/lib/mysql 8 | 9 | MASTERPOS="" 10 | # Determine binlog position of cloned data, if any. 11 | if [[ -s xtrabackup_slave_info ]]; then 12 | # XtraBackup already generated a partial "CHANGE MASTER TO" query 13 | # because we're cloning from an existing slave. 14 | MASTERPOS=$(cat xtrabackup_slave_info | tr -d ';') 15 | echo "Read from xtrabackup_slave_info $MASTERPOS" 16 | rm xtrabackup_slave_info 17 | elif [[ -f xtrabackup_binlog_info ]]; then 18 | # We're cloning directly from master. Parse binlog position. 19 | [[ `cat xtrabackup_binlog_info` =~ ^(.*?)[[:space:]]+(.*?)$ ]] || exit 1 20 | rm xtrabackup_binlog_info 21 | MASTERPOS="CHANGE MASTER TO MASTER_LOG_FILE='${BASH_REMATCH[1]}',\ 22 | MASTER_LOG_POS=${BASH_REMATCH[2]}" 23 | echo "Read from xtrabackup_binlog_info $MASTERPOS" 24 | fi 25 | 26 | # Check if we need to complete a clone by starting replication. 27 | if [[ ! -z $MASTERPOS ]]; then 28 | echo "Waiting for mysqld to be ready (accepting connections)" 29 | until mysql -h 127.0.0.1 -uroot -p$MYSQL_ROOT_PASSWORD -e "SELECT 1"; do sleep 1; done 30 | 31 | [[ `hostname` =~ ^(.*?)-([0-9]+)$ ]] || exit 1 32 | ordinal=${BASH_REMATCH[2]} 33 | rsname=${BASH_REMATCH[1]} 34 | servicename=$(hostname -f | cut -d"." -f2) 35 | 36 | echo "Initializing replication from clone position" 37 | # In case of container restart, attempt this at-most-once. 38 | MYSQL_PWD=$MYSQL_ROOT_PASSWORD mysql -h 127.0.0.1 -uroot < 3 | 4 | RUN apt-get update && apt-get install -y --force-yes --no-install-recommends \ 5 | apt-transport-https ca-certificates \ 6 | pwgen curl gnupg git iputils-ping mysql-client \ 7 | libmongoc-dev libbson-dev luarocks gcc \ 8 | && rm -rf /var/lib/apt/lists/* 9 | 10 | RUN curl -s https://packagecloud.io/install/repositories/akopytov/sysbench/script.deb.sh | bash 11 | RUN apt -y install sysbench 12 | RUN git clone https://github.com/Percona-Lab/sysbench-tpcc.git /sysbench/sysbench-tpcc 13 | RUN luarocks install mongorover 14 | 15 | RUN chgrp -R 0 /sysbench && chmod -R g=u /sysbench 16 | 17 | WORKDIR /sysbench 18 | 19 | CMD exec /bin/bash -c "trap : TERM INT; sleep infinity & wait" -------------------------------------------------------------------------------- /src/README.md: -------------------------------------------------------------------------------- 1 | ## moved to https://github.com/percona/percona-xtradb-cluster-operator/tree/master/cmd/peer-list 2 | --------------------------------------------------------------------------------