R10 tag/path update
[dcaegen2/platform/plugins.git] / k8s / README.md
1 # ONAP DCAE Kubernetes Plugin for Cloudify
2
3 This directory contains a Cloudify plugin  used to orchestrate the deployment of containerized DCAE service components  into a Kubernetes ("k8s")
4 environment. This work is based on the [ONAP DCAE Docker plugin] (../docker).
5
6 This plugin is *not* a generic Kubernetes plugin that exposes the full set of Kubernetes features.
7 In fact, the plugin largely hides the fact that we're using Kubernetes from both component developers and blueprint authors.
8 The Cloudify node type definitions are very similar to the Cloudify type definitions used in the ONAP DCAE Docker plugin.
9
10 For the node types `ContainerizedServiceComponent` and `ContainerizedServiceComponentUsingDmaap`, this plugin
11 creates the following Kubernetes entities:
12
13 - A Kubernetes `Deployment` containing information about what containers to run and what volume to mount.
14   - The `Deployment` always includes a container that runs the component's Docker image
15   - The `Deployment` includes any volumes specified in the blueprint
16   - If the blueprint specifies a logging directory via the `log_info` property, the `Deployment` includes a second container,
17   running the `filebeat` logging sidecar that ships logging information to the ONAP ELK stack.  The `Deployment` will include
18   some additional volumes needed by filebeat.
19   - If the blueprint specifies that the component uses TLS (HTTPS) via the `tls_info` property, the `Deployment` includes an init container,
20     a volume that holds TLS certificate artifacts, and volume mounts on the init container and the component's container.  The init container
21     populates the TLS certificate artifacts volume with certificates, keys, keystores, etc.
22   - If the blueprint specifies that the component uses external TLS via the `external_cert` property, the `Deployment` includes an additional init container
23     and the component's container. The init container populates the external TLS certificate artifacts in mounted volume. The container requires CMPv2 CertService to work properly. 
24 - If the blueprint indicates that the component exposes any ports, the plugin will create a Kubernetes `Service` that allocates an address
25   in the Kubernetes network address space that will route traffic to a container that's running the component.  This `Service` provides a
26   fixed "virtual IP" for the component.
27 - If the blueprint indicates that the component exposes a port externally, the plugin will create an additional Kubernetes `Service` that opens up a
28   port on the external interface of each node in the Kubernetes cluster.
29
30 Through the `replicas` property, a blueprint can request deployment of multiple instances of the component.  The plugin will still create a single `Deployment` (and,
31 if needed one or two `Services`), but the `Deployment` will cause multiple instances of the container to run.   (Specifically, the `Deployment` will create
32 a Kubernetes `Pod` for each requested instance.)  Other entities connect to a component via the IP address of a `Service`, and Kubernetes takes care of routing
33 traffic to an appropriate container instance.
34
35 ## Pre-requisites
36 ### Configuration
37 #### Configuration file
38 The plugin expects a configuration file in the Python "ini" format to be stored at `/opt/onap/config.txt`.  This file contains the address of the Consul cluster.
39 Here is an example:
40 ```
41 [consul]
42 address=10.12.5.115:30270
43 ```
44 #### Configuration entry in Consul
45 Additional configuration information is stored in the Consul KV store under the key `k8s-plugin`.
46 The configuration is provided as JSON object with the following properties:
47
48     - `namespace`:  k8s namespace to use for DCAE
49     - `consul_dns_name`: k8s internal DNS name for Consul (passed to containers)
50     - `image_pull_secrets`: list of names of k8s secrets for accessing Docker registries, with the following properties:
51     - `filebeat`:  object containing onfiguration for setting up filebeat container
52             - `log_path`: mount point for log volume in filebeat container
53             - `data_path`: mount point for data volume in filebeat container
54             - `config_path`: mount point for config volume in filebeat container
55             - `config_subpath`: subpath for config data in filebeat container
56             - `config_map`: name of a ConfigMap holding the filebeat configuration file
57             - `image`: Docker image to use for filebeat
58     - `tls`: object containing configuration for setting up TLS init container
59             - `cert_path`: mount point for the TLS certificate artifact volume in the init container
60             - `image`: Docker image to use for the TLS init container
61     - `external_cert`: object containing configuration for setting up external TLS init container
62             - `image_tag`: CertService client image name and version
63             - `request_url`: URL to Cert Service API
64             - `timeout`: Request timeout
65             - `country`: Country name in ISO 3166-1 alpha-2 format, for which certificate will be created
66             - `organization`: Organization name, for which certificate will be created
67             - `state`: State name, for which certificate will be created
68             - `organizational_unit`: Organizational unit name, for which certificate will be created
69             - `location`: Location name, for which certificate will be created
70     - `truststore_merger`: object containing configuration for setting up truststore-merger init container
71             - `image_tag`: truststore-merger image name and version
72
73 #### Kubernetes access information
74 The plugin accesses a Kubernetes cluster.  The information and credentials for accessing a cluster are stored in a "kubeconfig"
75 file.  The plugin expects to find such a file at `/etc/cloudify/.kube/config`.
76
77 #### Additional Kubernetes configuration elements
78 The plugin expects certain elements to be provided in the DCAE/ONAP environment, namely:
79    - Kubernetes secret(s) containing the credentials needed to pull images from Docker registries, if needed
80    - A Kubernetes ConfigMap containing the filebeat.yml file used by the filebeat logging container
81    - An ExternalName service
82
83 ## Input parameters
84
85 ### `start` operation parameters
86
87 These input parameters are for the `start` `cloudify.interfaces.lifecycle` and are inputs into the variant task operations `create_and_start_container*`.
88
89 #### `envs`
90
91 A map of environment variables that is intended to be forwarded to the container as environment variables.  Example:
92
93 ```yaml
94 envs:
95   EXTERNAL_IP: '10.100.1.99'
96 ```
97
98 These environment variables will be forwarded in addition to the *platform-related* environment variables like `CONSUL_HOST`.
99
100 #### `volumes`
101
102 List of maps used for setting up Kubernetes volume mounts.  Example:
103
104 ```yaml
105 volumes:
106   - host:
107       path: '/var/run/docker.sock'
108     container:
109       bind: '/tmp/docker.sock'
110       mode: 'ro'
111 ```
112
113 The table below describes the fields.
114
115 key | description
116 --- | -----------
117 path | Full path to the file or directory on the host machine to be mounted
118 bind | Full path to the file or directory in the container where the volume should be mounted to
119 mode | Readable, writeable: `ro`, `rw`
120
121 #### `ports`
122
123 List of strings - Used to bind container ports to host ports. Each item is of the format: `<container port>:<host port>` or
124 <container port>/<protocol>:<host port>, where <protocol> can be "TCP", "tcp", "UDP", or "udp".   If the first format is used, the
125 protocol defaults to TCP.
126
127 ```yaml
128 ports:
129   - '8000:31000'
130 ```
131
132 Default is `None`.
133
134 In the Kubernetes environment, most components will communicate over the Kubernetes network using private addresses. For those cases,
135 setting the `<host port>` to 0 will expose the `<container port>` to other components on the Kubernetes network, but not will not expose any
136 ports on the Kubernetes host's external interface.    Setting `<host port>` to a non-zero value will expose that port on the external interfaces
137 of every Kubernetes host in the cluster.  (This uses the Kubernetes `NodePort` service type.)
138
139 In dualstack Kubernetes environment, adding parameter ipv6 or ipv4, specify which ip family will be used. 
140 If ipv6 will be set in only ipv4 Kubernetes cluster, service will use ipv4 instead of declared ipv6.  
141
142 ```yaml
143 ports:
144   - concat: ['8000:31000']
145     ipv6: false
146   - concat: ['8000:31001']
147     ipv6: true
148 ```
149
150 #### `max_wait`
151
152 Integer - seconds to wait for component to become ready before throwing a `NonRecoverableError`. For example:
153
154 ```yaml
155 max_wait:
156     60
157 ```
158
159 Default is 300 seconds.
160
161 ## Using DMaaP
162
163 The node type `dcae.nodes.ContainerizedServiceComponentUsingDmaap` is intended to be used by components that use DMaaP and expects to be connected with the DMaaP node types found in the DMaaP plugin.
164
165 ### Node properties
166
167 The properties `streams_publishes` and `streams_subscribes` both are lists of objects that are intended to be passed into the DMaaP plugin and used to create additional parameters that will be passed into the DMaaP plugin.
168
169 #### Message router
170
171 For message router publishers and subscribers, the objects look like:
172
173 ```yaml
174 name: topic00
175 location: mtc5
176 client_role: XXXX
177 type: message_router
178 ```
179
180 Where `name` is the node name of `dcae.nodes.Topic` or `dcae.nodes.ExistingTopic` that the Docker node is connecting with via the relationships `dcae.relationships.publish_events` for publishing and `dcae.relationships.subscribe_to_events` for subscribing.
181
182 #### Data router
183
184 For data router publishers, the object looks like:
185
186 ```yaml
187 name: feed00
188 location: mtc5
189 type: data_router
190 ```
191
192 Where `name` is the node name of `dcae.nodes.Feed` or `dcae.nodes.ExistingFeed` that the Docker node is connecting with via the relationships `dcae.relationships.publish_files`.
193
194 For data router subscribers, the object looks like:
195
196 ```yaml
197 name: feed00
198 location: mtc5
199 type: data_router
200 username: king
201 password: "123456"
202 route: some-path
203 scheme: https
204 ```
205
206 Where the relationship to use is `dcae.relationships.subscribe_to_files`.
207
208 If `username` and `password` are not provided, then the plugin will generate username and password pair.
209
210 `route` and `scheme` are parameter used in the dynamic construction of the delivery url which will be passed to the DMaaP plugin to be used in the setting up of the subscriber to the feed.
211
212 `route` is the http path endpoint of the subscriber that will handle files from the associated feed.
213
214 `scheme` is either `http` or `https`.  If not specified, then the plugin will default to `http`.
215
216 ### Component configuration
217
218 The DMaaP plugin is responsible to provision the feed/topic and store into Consul the resulting DMaaP connection details.  Here is an example:
219
220 ```json
221 {
222     "topic00": {
223         "client_role": "XXXX",
224         "client_id": "XXXX",
225         "location": "XXXX",
226         "topic_url": "https://some-topic-url.com/events/abc"
227     }
228 }
229 ```
230
231 This is to be merged with the templatized application configuration:
232
233 ```json
234 {
235     "some-param": "Lorem ipsum dolor sit amet",
236     "streams_subscribes": {
237         "topic-alpha": {
238             "type": "message_router",
239             "aaf_username": "user-foo",
240             "aaf_password": "password-bar",
241             "dmaap_info": "<< topic00 >>"
242         },
243     },
244     "streams_publishes": {},
245     "services_calls": {}
246 }
247 ```
248
249 To form the application configuration:
250
251 ```json
252 {
253     "some-param": "Lorem ipsum dolor sit amet",
254     "streams_subscribes": {
255         "topic-alpha": {
256             "type": "message_router",
257             "aaf_username": "user-foo",
258             "aaf_password": "password-bar",
259             "dmaap_info": {
260                 "client_role": "XXXX",
261                 "client_id": "XXXX",
262                 "location": "XXXX",
263                 "topic_url": "https://some-topic-url.com/events/abc"
264             }
265         },
266     },
267     "streams_publishes": {},
268     "services_calls": {}
269 }
270 ```
271
272 This also applies to data router feeds.
273
274 ## Additional Operations Supported by the Plugin
275 In addition to supporting the Cloudify `install` and `uninstall` workflows, the plugin provides two standalone operations that can be invoked using the Cloudify [`execute_operation` workflow](https://docs.cloudify.co/4.3.0/working_with/workflows/built-in-workflows/).  The `dcae.nodes.ContainerizedApplication`, `dcae.nodes.ContainerizedServiceComponent`, and `dcae.nodes.ContainerizedServiceComponentUsingDmaap` node types support these operations.
276
277 Currently, there's no convenient high-level interface to trigger these operations, but they could potentially be exposed through some kind of dashboard.
278
279 ### Scaling Operation (`scale`)
280 The `scale` operation provides a way to change the number of replicas running for a node instance.  The operation is implemented by modifying the number of replicas in the Kubernetes Deployment specification associated with a node instance and submitting the updated specification to the Kubernetes API.  The scale operation works for increasing the number of replicas as well as decreasing the number of replications.  The minimum number of replicas is 1.
281
282 The `scale` operation takes two parameters:
283 - `replicas`: Number of desired replicas. Integer, required.
284 - `max_wait`: Number of seconds to wait for successful completion of the operation.  Integer, optional, defaults to 300 seconds.
285
286 One way to trigger a `scale` operation is by using the Cloudify command line.  For example:
287 ```
288 cfy executions start -d my_deployment -p scale_params.yaml execute_operation
289 ```
290 where `my_deployment` is the name of an existing Cloudify deployment and
291 `scale_params.yaml` is a a file containing the operation parameters:
292 ```
293 operation: scale
294 operation_kwargs:
295     replicas: 3
296 node_ids:
297     - "web_server"
298 ```
299 Note that the `node_ids` list is required by the `execute_operation` workflow.  The list contains all of the nodes that are being targeted by the workflow.  If a blueprint contains more than one node, it's possible to scale all of them--or some subset--with a single workflow execution.
300
301 ### Image Update Operation (`image_update`)
302 The `update_image` operation provides a way to change the Docker image running for a node instance, using the Kubernetes _rolling update_ strategy.  (See this [tutorial](https://kubernetes.io/docs/tutorials/kubernetes-basics/update/update-intro/) and this [discussion of the concept](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#updating-a-deployment) in the Kubernetes documentation.) The operation is implemented by modifying the image property in the Kubernetes Deployment specification associated with a node instance and submitting the updated specification to the Kubernetes API.
303
304 The `update_image` operation takes two parameters:
305 - `image`: Full name (including registry, if not the default Docker registry, and tag) of the new image to use for the component.  String, required.
306 - `max_wait`: Number of seconds to wait for successful completion of the operation.  Integer, optional, defaults to 300 seconds.
307
308 The `update_image` operation can be triggered using the Cloudify command line.  For example:
309 ```
310 cfy executions start -d my_deployment -p update_params.yaml execute_operation
311 ```
312 where `my_deployment` is the name of an existing Cloudify deployment and
313 `update_params.yaml` is a a file containing the operation parameters:
314 ```
315 operation: update_image
316 operation_kwargs:
317     image: myrepository.example.com/server/web:1.15
318 node_ids:
319     - "web_server"
320 ```
321 Note that the `node_ids` list is required by the `execute_operation` workflow.  The list contains all of the nodes that are being targeted by the workflow.  For an `update_image` operation, the list typically has only one element.
322
323 Note also that the `update_image` operation targets the container running the application code (i.e., the container running the image specified in the `image` node property).  This plugin may deploy "sidecar" containers running supporting code--for example, the "filebeat" container that relays logs to the central log server.  The `update_image` operation does not touch any "sidecar" containers.