├── .gitignore ├── LICENSE ├── ch01 ├── couchbase-service.yml ├── couchbase-volume.yml ├── helloworld-scheduled-job.yml ├── prometheus-daemonset.yml ├── wait-job.yml ├── wildfly-deployment.yml ├── wildfly-hpa.yml ├── wildfly-pod.yml ├── wildfly-rc.yml ├── wildfly-replicaset.yml └── wildfly-service.yml ├── ch02 ├── app-bootiful-couchbase.yml ├── app-couchbase-service.yml ├── hello-java │ └── Dockerfile ├── kops-delete ├── kops-run ├── maven │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── org │ │ └── example │ │ └── maven │ │ └── Main.java ├── webapp-autoscaling.yml ├── webapp-deployment.yml └── webapp │ ├── pom.xml │ ├── readme.adoc │ └── src │ └── main │ ├── java │ └── org │ │ └── example │ │ └── webapp │ │ ├── Application.java │ │ ├── Book.java │ │ └── BookRepository.java │ └── resources │ └── application.properties ├── ch03 ├── couchbase-statefulset.yml ├── daemon-set.yml ├── health-liveness.yml ├── hpa.yml ├── maven │ ├── bootiful-couchbase.yml │ ├── couchbase-service.yml │ └── webapp │ │ ├── pom.xml │ │ ├── readme.adoc │ │ └── src │ │ └── main │ │ ├── fabric8 │ │ └── raw │ │ │ ├── couchbase-rc.yaml │ │ │ └── couchbase-service.yml │ │ ├── java │ │ └── org │ │ │ └── example │ │ │ └── webapp │ │ │ ├── Application.java │ │ │ ├── Book.java │ │ │ └── BookRepository.java │ │ └── resources │ │ └── application.properties ├── resource-quota.yml ├── volume-couchbase.yml ├── volume-pv.yml ├── volume-pvc.yml └── webapp-deployment.yml ├── docker-images └── couchbase │ ├── Dockerfile │ ├── configure-node.sh │ ├── couchbase-pod.yml │ └── readme.adoc └── readme.adoc /.gitignore: -------------------------------------------------------------------------------- 1 | **/target 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /ch01/couchbase-service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: couchbase-service 5 | spec: 6 | selector: 7 | app: couchbase-rc-pod 8 | ports: 9 | - name: admin 10 | port: 8091 11 | - name: query 12 | port: 8093 13 | --- 14 | apiVersion: v1 15 | kind: ReplicationController 16 | metadata: 17 | name: couchbase-rc 18 | spec: 19 | replicas: 2 20 | selector: 21 | app: couchbase-rc-pod 22 | template: 23 | metadata: 24 | labels: 25 | app: couchbase-rc-pod 26 | spec: 27 | containers: 28 | - name: couchbase 29 | image: couchbase 30 | ports: 31 | - containerPort: 8091 32 | -------------------------------------------------------------------------------- /ch01/couchbase-volume.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: couchbase-pod 5 | labels: 6 | name: couchbase-pod 7 | spec: 8 | containers: 9 | - name: couchbase 10 | image: arungupta/couchbase-oreilly:k8s 11 | ports: 12 | - containerPort: 8091 13 | volumeMounts: 14 | - mountPath: /var/couchbase/lib 15 | name: couchbase-data 16 | volumes: 17 | - name: couchbase-data 18 | hostPath: 19 | path: /opt/data 20 | -------------------------------------------------------------------------------- /ch01/helloworld-scheduled-job.yml: -------------------------------------------------------------------------------- 1 | apiVersion: batch/v2alpha1 2 | kind: ScheduledJob 3 | metadata: 4 | name: hello 5 | spec: 6 | schedule: 0/1 * * * ? 7 | jobTemplate: 8 | spec: 9 | template: 10 | spec: 11 | containers: 12 | - name: helloworld 13 | image: busybox 14 | args: 15 | - /bin/bash 16 | - -c 17 | - date; echo Hello World! 18 | restartPolicy: OnFailure 19 | -------------------------------------------------------------------------------- /ch01/prometheus-daemonset.yml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: DaemonSet 3 | metadata: 4 | name: prom-exporter 5 | spec: 6 | template: 7 | metadata: 8 | labels: 9 | tier: monitoring 10 | name: prom-exporter 11 | spec: 12 | containers: 13 | - name: prometheus 14 | image: prom/node-exporter 15 | ports: 16 | - containerPort: 80 17 | -------------------------------------------------------------------------------- /ch01/wait-job.yml: -------------------------------------------------------------------------------- 1 | apiVersion: batch/v1 2 | kind: Job 3 | metadata: 4 | name: wait 5 | spec: 6 | template: 7 | metadata: 8 | name: wait 9 | spec: 10 | containers: 11 | - name: wait 12 | image: ubuntu 13 | command: ["sleep", "20"] 14 | restartPolicy: Never 15 | -------------------------------------------------------------------------------- /ch01/wildfly-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: wildfly-deployment 5 | spec: 6 | replicas: 3 7 | template: 8 | metadata: 9 | labels: 10 | app: wildfly 11 | spec: 12 | containers: 13 | - name: wildfly 14 | image: jboss/wildfly:10.1.0.Final 15 | ports: 16 | - containerPort: 8080 17 | -------------------------------------------------------------------------------- /ch01/wildfly-hpa.yml: -------------------------------------------------------------------------------- 1 | apiVersion: autoscaling/v1 2 | kind: HorizontalPodAutoscaler 3 | metadata: 4 | name: wildfly-scaler 5 | spec: 6 | scaleTargetRef: 7 | kind: ReplicaSet 8 | name: wildfly-rs 9 | minReplicas: 3 10 | maxReplicas: 10 11 | targetCPUUtilizationPercentage: 50 -------------------------------------------------------------------------------- /ch01/wildfly-pod.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: wildfly-pod 5 | labels: 6 | name: wildfly-pod 7 | spec: 8 | containers: 9 | - name: wildfly 10 | image: jboss/wildfly:10.1.0.Final 11 | ports: 12 | - containerPort: 8080 13 | -------------------------------------------------------------------------------- /ch01/wildfly-rc.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ReplicationController 3 | metadata: 4 | name: wildfly-rc 5 | spec: 6 | replicas: 2 7 | selector: 8 | app: wildfly-rc-pod 9 | template: 10 | metadata: 11 | labels: 12 | app: wildfly-rc-pod 13 | spec: 14 | containers: 15 | - name: wildfly 16 | image: jboss/wildfly:10.1.0.Final 17 | ports: 18 | - containerPort: 8080 19 | -------------------------------------------------------------------------------- /ch01/wildfly-replicaset.yml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: ReplicaSet 3 | metadata: 4 | name: wildfly-rs 5 | spec: 6 | replicas: 2 7 | selector: 8 | matchLabels: 9 | app: wildfly-rs-pod 10 | matchExpressions: 11 | - {key: tier, operator: In, values: ["backend"]} 12 | - {key: environment, operator: NotIn, values: ["prod"]} 13 | template: 14 | metadata: 15 | labels: 16 | app: wildfly-rs-pod 17 | tier: backend 18 | environment: dev 19 | spec: 20 | containers: 21 | - name: wildfly 22 | image: jboss/wildfly:10.1.0.Final 23 | ports: 24 | - containerPort: 8080 25 | -------------------------------------------------------------------------------- /ch01/wildfly-service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: wildfly-service 5 | spec: 6 | selector: 7 | app: wildfly-rc-pod 8 | ports: 9 | - name: web 10 | port: 8080 11 | --- 12 | apiVersion: v1 13 | kind: ReplicationController 14 | metadata: 15 | name: wildfly-rc 16 | spec: 17 | replicas: 2 18 | template: 19 | metadata: 20 | labels: 21 | app: wildfly-rc-pod 22 | spec: 23 | containers: 24 | - name: wildfly 25 | image: jboss/wildfly:10.1.0.Final 26 | ports: 27 | - containerPort: 8080 28 | -------------------------------------------------------------------------------- /ch02/app-bootiful-couchbase.yml: -------------------------------------------------------------------------------- 1 | apiVersion: batch/v1 2 | kind: Job 3 | metadata: 4 | name: bootiful-couchbase 5 | labels: 6 | name: bootiful-couchbase-pod 7 | spec: 8 | template: 9 | metadata: 10 | name: bootiful-couchbase-pod 11 | spec: 12 | containers: 13 | - name: bootiful-couchbase 14 | image: arungupta/bootiful-couchbase 15 | restartPolicy: Never 16 | -------------------------------------------------------------------------------- /ch02/app-couchbase-service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: couchbase-service 5 | spec: 6 | selector: 7 | app: couchbase-rc-pod 8 | ports: 9 | - name: admin 10 | port: 8091 11 | - name: views 12 | port: 8092 13 | - name: query 14 | port: 8093 15 | - name: memcached 16 | port: 11210 17 | --- 18 | apiVersion: v1 19 | kind: ReplicationController 20 | metadata: 21 | name: couchbase-rc 22 | spec: 23 | replicas: 1 24 | template: 25 | metadata: 26 | labels: 27 | app: couchbase-rc-pod 28 | spec: 29 | containers: 30 | - name: couchbase 31 | image: arungupta/oreilly-couchbase 32 | ports: 33 | - containerPort: 8091 34 | - containerPort: 8092 35 | - containerPort: 8093 36 | - containerPort: 11210 37 | 38 | -------------------------------------------------------------------------------- /ch02/hello-java/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk 2 | 3 | CMD ["java", "-version"] 4 | 5 | -------------------------------------------------------------------------------- /ch02/kops-delete: -------------------------------------------------------------------------------- 1 | kops-darwin-amd64 \ 2 | delete cluster \ 3 | --name=kubernetes.arungupta.me \ 4 | --state=s3://my-kops \ 5 | --yes 6 | -------------------------------------------------------------------------------- /ch02/kops-run: -------------------------------------------------------------------------------- 1 | kops-darwin-amd64 \ 2 | create cluster \ 3 | --name=kubernetes.arungupta.me \ 4 | --cloud=aws \ 5 | --zones=us-west-2a,us-west-2b,us-west-2c \ 6 | --master-zones=us-west-2a,us-west-2b,us-west-2c \ 7 | --master-size=m4.large \ 8 | --node-count=3 \ 9 | --node-size=m4.2xlarge \ 10 | --state=s3://my-kops \ 11 | --yes 12 | -------------------------------------------------------------------------------- /ch02/maven/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | org.sample 5 | kubernetes-maven-sample 6 | 1.0-SNAPSHOT 7 | jar 8 | kubernetes-maven-sample 9 | 10 | 1.8 11 | arungupta/${project.artifactId} 12 | 13 | 14 | ${project.name} 15 | 16 | 17 | org.apache.maven.plugins 18 | maven-shade-plugin 19 | 2.3 20 | 21 | false 22 | 23 | 24 | 25 | package 26 | 27 | shade 28 | 29 | 30 | 31 | 32 | 33 | io.fabric8 34 | fabric8-maven-plugin 35 | 3.2.14 36 | 37 | 38 | 39 | resource 40 | build 41 | 42 | 43 | 44 | 45 | 46 | org.codehaus.mojo 47 | exec-maven-plugin 48 | 1.5.0 49 | 50 | 51 | 52 | java 53 | 54 | 55 | 56 | 57 | org.example.maven.Main 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /ch02/maven/src/main/java/org/example/maven/Main.java: -------------------------------------------------------------------------------- 1 | package org.example.maven; 2 | 3 | /** 4 | * @arungupta 5 | */ 6 | public class Main { 7 | 8 | public static void main(String[] args) { 9 | System.out.println("Hello World"); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /ch02/webapp-autoscaling.yml: -------------------------------------------------------------------------------- 1 | apiVersion: autoscaling/v1 2 | kind: HorizontalPodAutoscaler 3 | metadata: 4 | name: webapp-autoscaler 5 | spec: 6 | scaleRef: 7 | kind: Deployment 8 | name: webapp-deployment 9 | subresource: scale 10 | minReplicas: 2 11 | maxReplicas: 10 12 | cpuUtilization: 13 | targetPercentage: 80 14 | -------------------------------------------------------------------------------- /ch02/webapp-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: webapp-deployment 5 | spec: 6 | replicas: 4 7 | template: 8 | metadata: 9 | labels: 10 | app: webapp-pod 11 | spec: 12 | containers: 13 | - name: webapp 14 | image: arungupta/wildfly-app:1 15 | ports: 16 | - containerPort: 8080 17 | -------------------------------------------------------------------------------- /ch02/webapp/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | org.example.webapps 5 | app-bootiful-couchbase 6 | 1.0-SNAPSHOT 7 | jar 8 | 9 | 10 | org.springframework.boot 11 | spring-boot-starter-parent 12 | 1.4.0.RELEASE 13 | 14 | 15 | 1.8 16 | arungupta/${project.build.finalName} 17 | 18 | 19 | 20 | org.springframework.boot 21 | spring-boot-starter-data-couchbase 22 | 23 | 24 | 25 | bootiful-couchbase 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-maven-plugin 30 | 31 | org.example.webapp.Application 32 | ZIP 33 | 34 | 35 | 36 | package 37 | 38 | repackage 39 | 40 | 41 | 42 | 43 | 44 | 45 | io.fabric8 46 | fabric8-maven-plugin 47 | 3.1.92 48 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /ch02/webapp/readme.adoc: -------------------------------------------------------------------------------- 1 | = Spring Boot + Couchbase Application 2 | 3 | This Spring Boot application stores a JSON document in Couchbase database. 4 | 5 | == Build Docker Image 6 | 7 | Build the Docker image using the command: 8 | 9 | `mvn clean package fabric8:build` 10 | 11 | This builds the Docker image `arungupta/bootiful-couchbase`. 12 | 13 | -------------------------------------------------------------------------------- /ch02/webapp/src/main/java/org/example/webapp/Application.java: -------------------------------------------------------------------------------- 1 | package org.example.webapp; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.boot.CommandLineRunner; 5 | import org.springframework.boot.SpringApplication; 6 | import org.springframework.boot.autoconfigure.SpringBootApplication; 7 | 8 | /** 9 | * @arungupta 10 | */ 11 | @SpringBootApplication 12 | public class Application implements CommandLineRunner { 13 | 14 | @Autowired 15 | private BookRepository repository; 16 | 17 | public static void main(String[] args) { 18 | SpringApplication.run(Application.class, args); 19 | } 20 | 21 | @Override 22 | public void run(String... args) { 23 | String isbn = "978-1-4919-1889-0"; 24 | repository.save(new Book(isbn, "Minecraft Modding with Forge", "29.99")); 25 | 26 | Book book = repository.findByIsbn(isbn); 27 | System.out.println(book); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ch02/webapp/src/main/java/org/example/webapp/Book.java: -------------------------------------------------------------------------------- 1 | package org.example.webapp; 2 | 3 | import com.couchbase.client.java.repository.annotation.Id; 4 | 5 | /** 6 | * @author arungupta 7 | */ 8 | public class Book { 9 | 10 | @Id 11 | private String key; 12 | 13 | private String isbn; 14 | private String name; 15 | private String cost; 16 | 17 | public Book(String isbn, String name, String cost) { 18 | this.key = isbn; 19 | this.isbn = isbn; 20 | this.name = name; 21 | this.cost = cost; 22 | } 23 | 24 | @Override 25 | public String toString() { 26 | return "Book{" + "isbn=" + isbn + ", name=" + name + ", cost=" + cost + '}'; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /ch02/webapp/src/main/java/org/example/webapp/BookRepository.java: -------------------------------------------------------------------------------- 1 | package org.example.webapp; 2 | 3 | import org.springframework.data.couchbase.repository.CouchbaseRepository; 4 | 5 | /** 6 | * @author arungupta 7 | */ 8 | public interface BookRepository extends CouchbaseRepository { 9 | Book findByIsbn(String isbn); 10 | } 11 | -------------------------------------------------------------------------------- /ch02/webapp/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.couchbase.bootstrap-hosts=couchbase-service 2 | spring.couchbase.bucket.name=books 3 | -------------------------------------------------------------------------------- /ch03/couchbase-statefulset.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1beta1 2 | kind: StatefulSet 3 | metadata: 4 | name: couchbase 5 | spec: 6 | serviceName: "couchbase" 7 | replicas: 2 8 | template: 9 | metadata: 10 | labels: 11 | app: couchbase 12 | spec: 13 | terminationGracePeriodSeconds: 0 14 | containers: 15 | - name: couchbase 16 | image: arungupta/couchbase:k8s-statefulset 17 | ports: 18 | - containerPort: 8091 19 | volumeMounts: 20 | - name: couchbase-data 21 | mountPath: /opt/couchbase/var 22 | env: 23 | - name: COUCHBASE_MASTER 24 | value: "couchbase-0.couchbase.default.svc.cluster.local" 25 | - name: AUTO_REBALANCE 26 | value: "false" 27 | volumeClaimTemplates: 28 | - metadata: 29 | name: couchbase-data 30 | annotations: 31 | volume.alpha.kubernetes.io/storage-class: anything 32 | spec: 33 | accessModes: [ "ReadWriteOnce" ] 34 | resources: 35 | requests: 36 | storage: 1Gi 37 | 38 | -------------------------------------------------------------------------------- /ch03/daemon-set.yml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: DaemonSet 3 | metadata: 4 | name: prom-exporter 5 | spec: 6 | template: 7 | metadata: 8 | labels: 9 | tier: monitoring 10 | name: prom-exporter 11 | spec: 12 | containers: 13 | - name: prometheus 14 | image: prom/node-exporter 15 | -------------------------------------------------------------------------------- /ch03/health-liveness.yml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: couchbase 5 | spec: 6 | replicas: 1 7 | template: 8 | metadata: 9 | labels: 10 | app: couchbase 11 | spec: 12 | containers: 13 | - name: couchbase 14 | image: arungupta/couchbase 15 | ports: 16 | - containerPort: 8091 17 | livenessProbe: 18 | httpGet: 19 | path: /pools 20 | port: 8091 21 | initialDelaySeconds: 30 22 | timeoutSeconds: 1 23 | -------------------------------------------------------------------------------- /ch03/hpa.yml: -------------------------------------------------------------------------------- 1 | apiVersion: autoscaling/v1 2 | kind: HorizontalPodAutoscaler 3 | metadata: 4 | name: webapp-autoscaler 5 | spec: 6 | scaleTargetRef: 7 | apiVersion: extensions/v1beta1 8 | kind: Deployment 9 | name: webapp-deployment 10 | minReplicas: 2 11 | maxReplicas: 10 12 | targetCPUUtilizationPercentage: 80 13 | -------------------------------------------------------------------------------- /ch03/maven/bootiful-couchbase.yml: -------------------------------------------------------------------------------- 1 | apiVersion: batch/v1 2 | kind: Job 3 | metadata: 4 | name: bootiful-couchbase 5 | labels: 6 | name: bootiful-couchbase-pod 7 | spec: 8 | template: 9 | metadata: 10 | name: bootiful-couchbase-pod 11 | spec: 12 | containers: 13 | - name: bootiful-couchbase 14 | image: arungupta/bootiful-couchbase 15 | env: 16 | - name: COUCHBASE_URI 17 | value: couchbase-service 18 | restartPolicy: Never 19 | -------------------------------------------------------------------------------- /ch03/maven/couchbase-service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: couchbase-service 5 | spec: 6 | selector: 7 | app: couchbase-rc-pod 8 | ports: 9 | - name: admin 10 | port: 8091 11 | - name: views 12 | port: 8092 13 | - name: query 14 | port: 8093 15 | - name: memcached 16 | port: 11210 17 | --- 18 | apiVersion: v1 19 | kind: ReplicationController 20 | metadata: 21 | name: couchbase-rc 22 | spec: 23 | replicas: 1 24 | template: 25 | metadata: 26 | labels: 27 | app: couchbase-rc-pod 28 | spec: 29 | containers: 30 | - name: couchbase 31 | image: arungupta/oreilly-couchbase 32 | ports: 33 | - containerPort: 8091 34 | - containerPort: 8092 35 | - containerPort: 8093 36 | - containerPort: 11210 37 | 38 | -------------------------------------------------------------------------------- /ch03/maven/webapp/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | org.example.webapps 5 | bootiful-couchbase 6 | 1.0-SNAPSHOT 7 | jar 8 | 9 | 10 | org.springframework.boot 11 | spring-boot-starter-parent 12 | 1.4.0.RELEASE 13 | 14 | 15 | 1.8 16 | arungupta/${project.artifactId} 17 | 18 | 19 | 20 | org.springframework.boot 21 | spring-boot-starter-data-couchbase 22 | 23 | 24 | 25 | bootiful-couchbase 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-maven-plugin 30 | 31 | org.example.webapp.Application 32 | ZIP 33 | 34 | 35 | 36 | package 37 | 38 | repackage 39 | 40 | 41 | 42 | 43 | 44 | 45 | io.fabric8 46 | fabric8-maven-plugin 47 | 3.1.62 48 | 49 | 50 | 51 | resource 52 | build 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /ch03/maven/webapp/readme.adoc: -------------------------------------------------------------------------------- 1 | = Kubernetes Maven Plugin 2 | 3 | Package Java application and generate Kubernetes resources using the following command: 4 | 5 | ``` 6 | mvn clean package fabric8:deploy 7 | ``` 8 | -------------------------------------------------------------------------------- /ch03/maven/webapp/src/main/fabric8/raw/couchbase-rc.yaml: -------------------------------------------------------------------------------- 1 | spec: 2 | replicas: 1 3 | selector: 4 | app: couchbase-rc-pod 5 | template: 6 | metadata: 7 | labels: 8 | app: couchbase-rc-pod 9 | spec: 10 | containers: 11 | - name: couchbase 12 | image: arungupta/oreilly-couchbase 13 | imagePullPolicy: IfNotPresent 14 | ports: 15 | - containerPort: 8091 16 | - containerPort: 8092 17 | - containerPort: 8093 18 | - containerPort: 11210 19 | -------------------------------------------------------------------------------- /ch03/maven/webapp/src/main/fabric8/raw/couchbase-service.yml: -------------------------------------------------------------------------------- 1 | spec: 2 | selector: 3 | app: couchbase-rc-pod 4 | ports: 5 | - name: admin 6 | port: 8091 7 | - name: views 8 | port: 8092 9 | - name: query 10 | port: 8093 11 | - name: memcached 12 | port: 11210 13 | -------------------------------------------------------------------------------- /ch03/maven/webapp/src/main/java/org/example/webapp/Application.java: -------------------------------------------------------------------------------- 1 | package org.example.webapp; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.boot.CommandLineRunner; 5 | import org.springframework.boot.SpringApplication; 6 | import org.springframework.boot.autoconfigure.SpringBootApplication; 7 | 8 | /** 9 | * @arungupta 10 | */ 11 | @SpringBootApplication 12 | public class Application implements CommandLineRunner { 13 | 14 | @Autowired 15 | private BookRepository repository; 16 | 17 | public static void main(String[] args) { 18 | SpringApplication.run(Application.class, args); 19 | } 20 | 21 | @Override 22 | public void run(String... args) { 23 | String isbn = "978-1-4919-1889-0"; 24 | repository.save(new Book(isbn, "Minecraft Modding with Forge", "29.99")); 25 | 26 | Book book = repository.findByIsbn(isbn); 27 | System.out.println(book); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ch03/maven/webapp/src/main/java/org/example/webapp/Book.java: -------------------------------------------------------------------------------- 1 | package org.example.webapp; 2 | 3 | import com.couchbase.client.java.repository.annotation.Id; 4 | 5 | /** 6 | * @author arungupta 7 | */ 8 | public class Book { 9 | 10 | @Id 11 | private String key; 12 | 13 | private String isbn; 14 | private String name; 15 | private String cost; 16 | 17 | public Book(String isbn, String name, String cost) { 18 | this.key = isbn; 19 | this.isbn = isbn; 20 | this.name = name; 21 | this.cost = cost; 22 | } 23 | 24 | @Override 25 | public String toString() { 26 | return "Book{" + "isbn=" + isbn + ", name=" + name + ", cost=" + cost + '}'; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /ch03/maven/webapp/src/main/java/org/example/webapp/BookRepository.java: -------------------------------------------------------------------------------- 1 | package org.example.webapp; 2 | 3 | import org.springframework.data.couchbase.repository.CouchbaseRepository; 4 | 5 | /** 6 | * @author arungupta 7 | */ 8 | public interface BookRepository extends CouchbaseRepository { 9 | Book findByIsbn(String isbn); 10 | } 11 | -------------------------------------------------------------------------------- /ch03/maven/webapp/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.couchbase.bootstrap-hosts=couchbase 2 | spring.couchbase.bucket.name=books -------------------------------------------------------------------------------- /ch03/resource-quota.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ResourceQuota 3 | metadata: 4 | name: quota 5 | spec: 6 | hard: 7 | cpu: "20" 8 | memory: 10Gi 9 | pods: "10" 10 | replicationcontrollers: "20" 11 | services: "5" 12 | -------------------------------------------------------------------------------- /ch03/volume-couchbase.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ReplicationController 3 | metadata: 4 | name: couchbase 5 | spec: 6 | replicas: 1 7 | template: 8 | metadata: 9 | name: couchbase-rc-pod 10 | labels: 11 | name: couchbase-rc-pod 12 | context: couchbase-pv 13 | spec: 14 | containers: 15 | - name: couchbase-rc-pod 16 | image: arungupta/oreilly-couchbase 17 | volumeMounts: 18 | - mountPath: "/opt/couchbase/var" 19 | name: mypd 20 | ports: 21 | - containerPort: 8091 22 | - containerPort: 8092 23 | - containerPort: 8093 24 | - containerPort: 11210 25 | volumes: 26 | - name: mypd 27 | persistentVolumeClaim: 28 | claimName: couchbase-pvc 29 | -------------------------------------------------------------------------------- /ch03/volume-pv.yml: -------------------------------------------------------------------------------- 1 | kind: PersistentVolume 2 | apiVersion: v1 3 | metadata: 4 | name: couchbase-pv 5 | labels: 6 | type: amazonEBS 7 | spec: 8 | capacity: 9 | storage: 5Gi 10 | accessModes: 11 | - ReadWriteOnce 12 | awsElasticBlockStore: 13 | volumeID: vol-0e04a9f45ad0cc01d 14 | fsType: ext4 15 | 16 | -------------------------------------------------------------------------------- /ch03/volume-pvc.yml: -------------------------------------------------------------------------------- 1 | kind: PersistentVolumeClaim 2 | apiVersion: v1 3 | metadata: 4 | name: couchbase-pvc 5 | labels: 6 | type: amazonEBS 7 | spec: 8 | accessModes: 9 | - ReadWriteOnce 10 | resources: 11 | requests: 12 | storage: 3Gi 13 | -------------------------------------------------------------------------------- /ch03/webapp-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: webapp-deployment 5 | spec: 6 | replicas: 4 7 | template: 8 | metadata: 9 | labels: 10 | app: webapp-pod 11 | spec: 12 | containers: 13 | - name: webapp 14 | image: arungupta/wildfly-app:1 15 | ports: 16 | - containerPort: 8080 17 | 18 | -------------------------------------------------------------------------------- /docker-images/couchbase/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM couchbase 2 | 3 | COPY configure-node.sh /opt/couchbase 4 | 5 | CMD ["/opt/couchbase/configure-node.sh"] 6 | 7 | -------------------------------------------------------------------------------- /docker-images/couchbase/configure-node.sh: -------------------------------------------------------------------------------- 1 | set -m 2 | 3 | /entrypoint.sh couchbase-server & 4 | 5 | sleep 15 6 | 7 | curl -v -X POST http://127.0.0.1:8091/pools/default -d memoryQuota=300 -d indexMemoryQuota=300 8 | curl -v http://127.0.0.1:8091/node/controller/setupServices -d services=kv%2Cn1ql%2Cindex 9 | curl -v http://127.0.0.1:8091/settings/web -d port=8091 -d username=Administrator -d password=password 10 | curl -v -u Administrator:password -X POST http://127.0.0.1:8091/pools/default/buckets -d name=books -d bucketType=couchbase -d ramQuotaMB=200 -d authType=sasl 11 | sleep 10 12 | curl -v http://127.0.0.1:8093/query/service -d 'statement=create primary index on books' 13 | 14 | fg 1 15 | 16 | -------------------------------------------------------------------------------- /docker-images/couchbase/couchbase-pod.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: couchbase-pod 5 | labels: 6 | name: couchbase-pod 7 | spec: 8 | containers: 9 | - name: couchbase 10 | image: arungupta/couchbase-oreilly:k8s 11 | ports: 12 | - containerPort: 8080 13 | 14 | -------------------------------------------------------------------------------- /docker-images/couchbase/readme.adoc: -------------------------------------------------------------------------------- 1 | = Pre-configured Couchbase Docker Container 2 | 3 | These are the artifacts to create a pre-configured Couchbase Docker image. 4 | 5 | == Build the image 6 | 7 | ```console 8 | docker build -t arungupta/oreilly-couchbase:k8s . 9 | ``` 10 | 11 | == Start the pod 12 | 13 | Start the pod as: 14 | 15 | ```console 16 | kubectl create -f couchbase-pod.yml 17 | ``` 18 | -------------------------------------------------------------------------------- /readme.adoc: -------------------------------------------------------------------------------- 1 | = Kubernetes for Java Developers Book 2 | --------------------------------------------------------------------------------