-
Notifications
You must be signed in to change notification settings - Fork 218
/
sidecars.html.md.erb
463 lines (315 loc) · 17.3 KB
/
sidecars.html.md.erb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
---
title: Pushing apps with sidecar processes
owner: CAPI
---
You can run additional processes in the same container as your app. These additional processes
are called sidecar processes, or sidecars. An example of a sidecar is an Application Performance
Monitoring (APM) tool.
<p class="note important">
The cf CLI v6 commands described in this topic are unsupported, but are supported in cf CLI v7. The latest supported cf CLI release is cf CLI v8. To upgrade to cf CLI v7, see <a href="https://docs.cloudfoundry.org/cf-cli/v7.html">Upgrading to cf CLI v7</a>. To upgrade to cf CLI v8, see <a href="https://docs.cloudfoundry.org/cf-cli/v8.html">Upgrading to cf CLI v8</a>.</p>
<%= vars.capi_sidecar_req %>
## <a id="overview"></a> About sidecars
When you provide a sidecar for your app,
<%= vars.app_runtime_first %> packages the required code and
configuration needed to run the sidecar and app in the same droplet. It deploys this droplet in a
single container on Diego. Both processes within the container undergo health checks independently.
You can push sidecar processes with your app by using one of two methods:
* Using an app manifest. For instructions, see [Push an app with a sidecar Using an app manifest](#create).
* With a custom buildpack. For instructions, see [Sidecar buildpacks](../buildpacks/sidecar-buildpacks.html).
For additional information about sidecars, see [Sidecars](http://v3-apidocs.cloudfoundry.org/version/release-candidate/#sidecars) in the
Cloud Foundry API (CAPI) documentation.
For sample apps that use sidecars, see the
[capi-sidecar-samples](https://github.com/cloudfoundry-samples/capi-sidecar-samples) repository on
GitHub. These sample apps use an app manifest.
## <a id="use-case"></a> Use cases
You can use sidecars for processes that depend on each other or must run in the same container.
For example, you can use sidecars for processes that must:
* Communicate over a UNIX socket or through localhost
* Share the same file system
* Be scaled and placed together
* Have fast interprocess communication
## <a id="limitations"></a> Limitations
Sidecars have these limitations:
* The start and stop order of app processes and their sidecars is undefined.
* App processes and sidecars are codependent. If either fails or exits, the other does also.
* Sidecars are not independently scalable. Sidecars share resources with the main app process and other sidecars within the container.
* Sidecars only support PID-based health checks. HTTP health checks for sidecars are not supported.
## <a id="java"></a> Requirements for Java apps
These sections describe several requirements that are specific to pushing sidecars with Java apps.
### <a id="java-sidecar-memory"></a> Reserving memory
You must allocate memory to the sidecar. If you do not, the Java buildpack allocates all of the
available memory to the app. As a result, the sidecar does not have enough memory and the app fails
to start.
To allocate memory to the sidecar, use the `memory` property in the app manifest. For example:
```
sidecars:
- name: SIDECAR-NAME
process_types: [ 'PROCESS-TYPES' ]
command: START-COMMAND
memory: 256MB
```
Where:
* `SIDECAR-NAME` is a name you give your sidecar.
* `PROCESS-TYPES` is a list of app processes for the sidecar to attach to, such as `web` or `worker`. You can attach multiple sidecars to each process type your app uses.
* `START-COMMAND` is the command used to start the sidecar. For example, `./binary` or `java -jar java-file.jar`.
You must also allocate memory to sidecars that you push with a custom buildpack.
For more information, see [Sidecar buildpacks](../buildpacks/sidecar-buildpacks.html).
### <a id="java-sidecar-packaging"></a> Packaging binaries
If your sidecar is a binary file rather than a set of buildable source files, then you must package the binary file with your Java app.
In some cases, the Java buildpack requires you to push a `.jar` file. If this is the case with your app, you must include the sidecar binary in the `.jar` file.
To package the sidecar binary with the `.jar` file, run:
```
zip JAR -u SIDECAR-BINARY
```
Where:
* `JAR` is your `.jar` file.
* `SIDECAR-BINARY` is your sidecar binary.
For more information about packaging assets with your Java app, see [Cloud Foundry documentation](https://docs.cloudfoundry.org/buildpacks/java/java-tips.html).
## <a id="create"></a> Push an app with a sidecar using an app manifest
These sections explain how to push an app with a sidecar using an app manifest. For an example that you can try yourself, see [Sidecar tutorial](#tutorial).
When pushing a Java app, follow the requirements listed in <a href="#java">Requirements for Java Apps</a>.
### <a id="prerequisite"></a> Prerequisites
Before you can push an app with a sidecar with an app manifest, you must have:
* An app that is running or ready to be pushed.
* A file that <%= vars.app_runtime_abbr%> can run inside the application container as a sidecar process. For example, an executable binary, a Java .jar file, or Ruby scripts.
### <a id="create"></a> Procedure
To push an app with a sidecar:
1. Create an app or use an existing app. To create an app:
```
cf create-app APP-NAME
```
Where `APP-NAME` is the name you give your app.
1. Create a manifest file in the root directory of your app, such as `manifest.yml`. Otherwise, use an existing manifest file for your app. For more information, see [Deploying with app manifests](./deploy-apps/manifest.html).
1. Add the following values to your app manifest file under the `applications` key:
```
sidecars:
- name: SIDECAR-NAME
process_types: [ 'PROCESS-TYPES' ]
command: START-COMMAND
```
Where:
<ul>
<li><code>SIDECAR-NAME</code> is a name you give your sidecar.</li>
<li><code>PROCESS-TYPES</code> is a list of app processes for the sidecar to attach to, such as <code>web</code> or <code>worker</code>. You can attach multiple sidecars to each process type your app uses.</li>
<li><code>START-COMMAND</code> is the command used to start the sidecar. For example, <code>./binary</code> or <code>java -jar java-file.jar</code>.</li>
</ul>
This example manifest file includes multiple sidecars:
```
---
applications:
- name: my-app
sidecars:
- name: authenticator
process_types: [ 'web', 'worker' ]
command: bundle exec run-authenticator
- name: performance monitor
process_types: [ 'web' ]
command: bundle exec run-performance-monitor
```
1. To apply the manifest file to your app:
```
cf apply-manifest -f PATH-TO-MANIFEST
```
Where `PATH-TO-MANIFEST` is the path to your manifest file.
1. To push your app:
```
cf push APP-NAME
```
Where `APP-NAME` is the name of your app.
## <a id="tutorial"></a> Sidecar tutorial
You can explore sidecars using the app in the [capi-sidecar-samples](https://github.com/cloudfoundry-samples/capi-sidecar-samples) repository on GitHub. The following sections describe the app, how to build and push the app, and some ways to observe the app and its processes after pushing.
<p class="note important">
In this tutorial, you are pushing the Ruby sample app. You can also follow this tutorial for a Java app using the <code>sidecar-dependent-java-app</code> and <code>push_java_app_with_binary_sidecar.sh</code> in the samples repository. When pushing a Java app, follow the requirements listed in <a href="#java">Requirements for Java apps</a>.</p>
### <a id="about"></a> About the sample app
The [capi-sidecar-samples](https://github.com/cloudfoundry-samples/capi-sidecar-samples) repository contains:
* **A simple Ruby app**: This app is named `sidecar-dependent-app`. It includes a `/config` endpoint that calls to the sidecar and prints the response, as shown in this code snippet:
```
get '/config' do
puts "Sending a request to the config-server sidecar at localhost:#{ENV['CONFIG_SERVER_PORT']}/config/"
response = Typhoeus.get("localhost:#{ENV['CONFIG_SERVER_PORT']}/config/")
puts "Received #{response.body} from the config-server sidecar"
response.body
end
```
* **A Golang sidecar**: The `config-server-sidecar` produces a `config-server` binary. It provides apps with their required configuration over its `/config` endpoint. It also accepts connections only over localhost on the `CONFIG_SERVER_PORT` port. This means the sidecar must be co-located in the same container as the app, so that it shares the same network namespace as the main app.
The following diagram illustrates the app architecture:
![App Process and Sidecar Process are inside an App Container, which is inside a Diego cell.](./images/sidecar-diagram.png)
### <a id="push"></a> Push the app and sidecar
If you do not have Go installed, download the <code>config-server_linux_x86-64</code> binary from <a href="https://github.com/cloudfoundry-samples/capi-sidecar-samples/releases">CAPI Sidecar sample releases</a> in the <code>capi-sidecar-samples</code> repository in GitHub.
To push the app and sidecar:
1. In a terminal window, clone the Git repository to your workspace by running:
```
git clone https://github.com/cloudfoundry-samples/capi-sidecar-samples.git
```
2. Go to the `config-server-sidecar` directory.
3. Build the binary for the sidecar by running:
```
GOOS=linux GOARCH=amd64 go build -o config-server .
```
1. To create the app:
```
cf create-app sidecar-dependent-app
```
1. Go to the `sidecar-dependent-app` directory.
1. Open and review the `manifest.yml` file. Under `sidecars`, the sidecar is specified with a name, process type, and start command. Under `env`, an environment variable defines the port on which the app and sidecar communicate.
1. To apply the manifest to the app:
```
cf apply-manifest
```
1. To push the app:
```
cf push sidecar-dependent-app
```
After you push the app, you can further explore it as described in the sections below:
- [View processes running in the app container via SSH](#view-processes-ssh)
- [View the web URL and app logs via SSH](#view-logs)
- [View and debug processes running in the app container via HTTP](#debug-processes-http)
### <a id="view-processes-ssh"></a> View processes running in the app container via SSH
To view the app and sidecar process running in the container:
1. SSH into the application container by running:
```
cf ssh sidecar-dependent-app
```
1. To see both the `rackup` process for the main app and `config-server` process for the sidecar, run:
```
ps aux
```
The output you might see resembles this example output:
<pre class="terminal">
vcap@f00949bd-6601-4731-6f7e-e859:~$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 1120 0 ? S 22:17 0:00 /tmp/garden-init
vcap 7 0.0 0.0 106716 4508 ? S 22:17 0:00 ./config-server
vcap 13 0.0 0.1 519688 35412 ? S 22:17 0:00 /home/vcap/deps/0/vendor_bundle/ruby/2.4.0/bin/rackup config.ru -p 8080
vcap 24 0.0 0.0 116344 10792 ? S 22:17 0:00 /tmp/lifecycle/diego-sshd --allowedKeyExchanges= --address=0.0.0.0:2222 --allowUnauthenticatedClients=false --inhe
root 82 0.0 0.0 108012 4548 ? S 22:17 0:00 /etc/cf-assets/healthcheck/healthcheck -port=8080 -timeout=1000ms -liveness-interval=30s
vcap 215 0.3 0.0 70376 3756 pts/0 S 23:12 0:00 /bin/bash
vcap 227 0.0 0.0 86268 3116 pts/0 R 23:12 0:00 ps aux
</pre>
1. To see that the sidecar is listening on the port specified by `CONFIG_SERVER_PORT` and that the main `ruby` process is connected to it, run:
```
lsof -i | grep $CONFIG_SERVER_PORT
```
The output you see might resemble this example output:
<pre class="terminal">
vcap@f00949bd-6601-4731-6f7e-e859:~$ lsof -i | grep $CONFIG_SERVER_PORT
config-se 7 vcap 3u IPv4 17265901 0t0 TCP *:8082 (LISTEN)
config-se 7 vcap 5u IPv4 17265992 0t0 TCP localhost:8082->localhost:42266 (ESTABLISHED)
ruby 13 vcap 11u IPv4 17274965 0t0 TCP localhost:42266->localhost:8082 (ESTABLISHED)
</pre>
### <a id="view-logs"></a> View the web URL and app logs via SSH
To view the web URL and logs for the app:
1. In a browser, go to the `config` endpoint of the `sidecar-dependent-app`. For example: `https://sidecar-dependent-app.example.com/config`.
1. See that the browser displays `Scope` and `Password` information. This is the configuration that the app fetches from the `config-server` sidecar.
1. Begin streaming logs for the app by running:
```
cf logs sidecar-dependent-app
```
1. In your browser, refresh the `/config` endpoint page and observe that the log stream in your terminal displays logs for both the sidecar and the main app process.
1. In a separate terminal from your log stream, SSH into the application container by running:
```
cf ssh sidecar-dependent-app
```
1. Stop the sidecar process by running:
```
kill -9 $(pgrep config-server)
```
1. View the output in the terminal where you are streaming the app logs. The app logs indicate that the sidecar process failed and that Diego restarted the application container. For example:
<pre class="terminal">
2019-04-17T16:48:55.41-0700 [API/0] OUT App instance exited with guid
21df1eb8-f25d-43b2-990b-c1a417310553 payload:
{"instance"=>"a8db0eed-7371-4805-5ad3-4596", "index"=>0,
"cell_id"=>"86808ce7-afc2-47da-9e79-522a62a48cff", "reason"=>"CRASHED",
"exit_description"=>"APP/PROC/WEB/SIDECAR/CONFIG-SERVER: Exited with status 137",
"crash_count"=>1, "crash_timestamp"=>1555544935367052708,
"version"=>"50892dcb-274d-4cf6-b944-3eda1e000283"}
</pre>
### <a id="debug-processes-http"></a>View and debug processes running in the app container via HTTP
Sidecars can be used to collect debug information (e.g. thread dumps) from
another process running in the same container. This is especially useful if you
want to debug a running process using an HTTP request, for instance if you do
not have ssh access to the application container.
This is an example of a simple routable debug sidecar for java applications,
but the same concept can be adapted to more advanced debug tooling and other
languages or frameworks.
#### <a id="debug-prerequisites"></a> Prerequisites
Before you begin, you must have:
* A java app with [a manifest](./deploy-apps/manifest.html) that is ready to be
pushed. For example, the [java sample
app](https://github.com/cloudfoundry/cf-acceptance-tests/tree/main/assets/java)
from CF Acceptance Tests.
* A route to map to the debug sidecar
#### <a id="debug-procedure"></a> Procedure
To add a debug sidecar to the java app:
1. Create a sidecar that responds to HTTP requests and calls `kill -3` on the
java process. When a java process receives the resulting SIGQUIT signal, it
will print a thread dump to STDOUT. For an example, see the
[java_debug_sidecar](https://github.com/Gerg/java-debug-buildpack/blob/main/java_debug_sidecar.go)
on GitHub.
1. Place the sidecar binary in the root directory of your java app
1. Add the following to your app manifest:
```
sidecars:
- name: debug-sidecar
process_types: [ 'web' ]
command: START-COMMAND
memory: 256MB
```
Where `START-COMMAND` is the command used to start the sidecar. For the above
example sidecar, `./java_debug_sidecar`.
1. Push the java application. For example:
```
cf push APP-NAME -f manifest.yml -m 1G
```
Where `APP-NAME` is the name of your app.
1. Map a route to the sidecar process's port. For detailed steps, see
[Configuring Cloud Foundry to route traffic to apps on custom ports](./custom-ports.html).
```
cf curl -X PATCH /v3/routes/ROUTE-GUID/destinations -d '{
"destinations": [
{
"app": {
"guid": "APP-GUID",
"process": {
"type": "web"
}
},
"port": PORT,
"protocol": "http1"
}
]
}'
```
Where:
<ul>
<li><code>APP-GUID</code> is the GUID of your app.</li>
<li><code>ROUTE-GUID</code> is the GUID of the route to map to the sidecar.</li>
<li><code>PORT</code> is a custom port on which your app is configured to
receive requests. This is <code>8081</code> for the above example.</li>
</ul>
1. Restart the app to complete the port mapping
```
cf restart APP_NAME
```
Where `APP-NAME` is the name of your app.
1. Tail the app logs:
```
cf logs APP_NAME
```
Where `APP-NAME` is the name of your app.
1. In another terminal, make a HTTP request to the sidecar, to trigger the
thread dump. For example:
```
curl https://debug-sidecar.example.com/threaddump
```
1. Observe the thread dump in the app logs
### <a id="debug-next-steps"></a> Next Steps
Now that you have a simple debugging sidecar working, here are some ideas for
next steps:
* Use more sophisticated debugging tools
* Return the debug information in the HTTP response, rather than logging to STDOUT
* Inject the debug sidecar via a [Sidecar
buildpacks](../buildpacks/sidecar-buildpacks.html). For example:
[java-debug-buildpack](https://github.com/Gerg/java-debug-buildpack) on GitHub.
* Add authentication for the debug sidecar's HTTP route, for instance using an
authentication [Route Service](../services/route-services.html).