github.com/qsunny/k8s@v0.0.0-20220101153623-e6dca256d5bf/examples-master/staging/javaweb-tomcat-sidecar/README.md (about) 1 ## Java Web Application with Tomcat and Init Container 2 3 The following document describes the deployment of a Java Web application using Tomcat. Instead of packaging `war` file inside the Tomcat image or mount the `war` as a volume, we use an [init-container](https://kubernetes.io/docs/concepts/workloads/pods/init-containers/) as `war` file provider. 4 5 ### Prerequisites 6 7 https://github.com/kubernetes/kubernetes/blob/master/docs/user-guide/prereqs.md 8 9 ### Overview 10 11 This sidecar mode brings a new workflow for Java users: 12 13  14 15 As you can see, user can create a `sample:v2` container as an `initContainers` object to "provide" war file to Tomcat by copying it to the shared `emptyDir` volume. And Pod will make sure the two containers compose an "atomic" scheduling unit, which is perfect for this case. Thus, your application version management will be totally separated from web server management. 16 17 By using an init-container the `tomcat` container is assured of the `war` file existing before start up as the pod will not start normal containers until all init-containers have completed successfully. 18 19 For example, if you are going to change the configurations of your Tomcat: 20 21 ```console 22 $ docker exec -it <tomcat_container_id> /bin/bash 23 # make some change, and then commit it to a new image 24 $ docker commit <tomcat_container_id> mytomcat:7.0-dev 25 ``` 26 27 Done! The new Tomcat image **will not** mess up with your `sample.war` file. You can re-use your tomcat image with lots of different war container images for lots of different apps without having to build lots of different images. 28 29 Also this means that rolling out a new Tomcat to patch security or whatever else, doesn't require rebuilding N different images. 30 31 **Why not put my `sample.war` in a host dir and mount it to tomcat container?** 32 33 You have to **manage the volumes** in this case, for example, when you restart or scale the pod on another node, your contents is not ready on that host. 34 35 Generally, we have to set up a distributed file system (NFS at least) volume to solve this (if we do not have GCE PD volume). But this is generally unnecessary. 36 37 ### How To Set this Up 38 39 In Kubernetes a [_Pod_](https://kubernetes.io/docs/user-guide/pods.md) is the smallest deployable unit that can be created, scheduled, and managed. It's a collocated group of containers that share an IP and storage volume. 40 41 Here is the config [javaweb.yaml](javaweb.yaml) for Java Web pod: 42 43 NOTE: you should define `war` init-container **first** as it is the "provider". 44 45 <!-- BEGIN MUNGE: javaweb.yaml --> 46 47 ```yaml 48 apiVersion: v1 49 kind: Pod 50 metadata: 51 name: javaweb 52 spec: 53 initContainers: 54 - image: resouer/sample:v1 55 name: war 56 volumeMounts: 57 - mountPath: /app 58 name: app-volume 59 containers: 60 - image: resouer/mytomcat:7.0 61 name: tomcat 62 command: ["sh", "-c", "/root/apache-tomcat-7.0.42-v2/bin/start.sh"] 63 volumeMounts: 64 - mountPath: /root/apache-tomcat-7.0.42-v2/webapps 65 name: app-volume 66 ports: 67 - containerPort: 8080 68 hostPort: 8001 69 volumes: 70 - name: app-volume 71 emptyDir: {} 72 ``` 73 74 <!-- END MUNGE: EXAMPLE --> 75 76 The only magic here is the `resouer/sample:v1` image: 77 78 ``` 79 FROM busybox:latest 80 ADD sample.war sample.war 81 CMD "sh" "mv.sh" 82 ``` 83 84 And the contents of `mv.sh` is: 85 86 ```sh 87 cp /sample.war /app 88 tail -f /dev/null 89 ``` 90 91 #### Explanation 92 93 1. 'war' container only contains the `war` file of your app 94 2. 'war' container's CMD tries to copy `sample.war` to the `emptyDir` volume path 95 3. The last line of `tail -f` is just used to hold the container, as Replication Controller does not support one-off task 96 4. 'tomcat' container will load the `sample.war` from volume path 97 98 What's more, if you don't want to enclose a build-in `mv.sh` script in the `war` container, you can use Pod's `command` to do the copy work, here's a example [javaweb-2.yaml](javaweb-2.yaml): 99 100 <!-- BEGIN MUNGE: javaweb-2.yaml --> 101 102 ```yaml 103 apiVersion: v1 104 kind: Pod 105 metadata: 106 name: javaweb-2 107 spec: 108 initContainers: 109 - image: resouer/sample:v2 110 name: war 111 command: 112 - "cp" 113 - "/sample.war" 114 - "/app" 115 volumeMounts: 116 - mountPath: /app 117 name: app-volume 118 containers: 119 - image: resouer/mytomcat:7.0 120 name: tomcat 121 command: ["sh","-c","/root/apache-tomcat-7.0.42-v2/bin/start.sh"] 122 volumeMounts: 123 - mountPath: /root/apache-tomcat-7.0.42-v2/webapps 124 name: app-volume 125 ports: 126 - containerPort: 8080 127 hostPort: 8001 128 volumes: 129 - name: app-volume 130 emptyDir: {} 131 ``` 132 133 <!-- END MUNGE: EXAMPLE --> 134 135 And the `resouer/sample:v2` Dockerfile is quite simple: 136 137 ``` 138 FROM busybox:latest 139 ADD sample.war sample.war 140 CMD "tail" "-f" "/dev/null" 141 ``` 142 143 #### Explanation 144 145 1. 'war' container only contains the `war` file of your app 146 2. 'war' container's CMD uses `tail -f` to hold the container, nothing more 147 3. The `command` will do `cp` after the `war` container is started 148 4. Again 'tomcat' container will load the `sample.war` from volume path 149 150 Done! Now your `war` container contains nothing except `sample.war`, clean enough. 151 152 ### Test It Out 153 154 Create the Java web pod: 155 156 ```console 157 $ kubectl create -f examples/javaweb-tomcat-sidecar/javaweb-2.yaml 158 ``` 159 160 Check status of the pod: 161 162 ```console 163 $ kubectl get -w po 164 NAME READY STATUS RESTARTS AGE 165 javaweb-2 2/2 Running 0 7s 166 ``` 167 168 Wait for the status to `0/1` and `Running`. Then you can visit "Hello, World" page on `http://localhost:8001/sample/index.html` 169 170 You can also test `javaweb.yaml` in the same way. 171 172 ### Delete Resources 173 174 All resources created in this application can be deleted: 175 176 ```console 177 $ kubectl delete -f examples/javaweb-tomcat-sidecar/javaweb-2.yaml 178 ``` 179 180 <!-- BEGIN MUNGE: GENERATED_ANALYTICS --> 181 182 []() 183 184 <!-- END MUNGE: GENERATED_ANALYTICS -->