Describing Containers
- The Basics
- Services and container communication (this page)
- Exposing containers externally
- Volumes and Configs
- Multi-Container Pods (Sidecars)
- Special MiCADO/Kubernetes Types
Services and container communication
Permitting communication between your containers (more specifically - your Pods) is handled via the ports
property of an application in container. Under the hood, we use a Kubernetes Service.
Creating a service
Let's say we want to give other Pods running on the cluster the ability to communicate with our database container. Here's the simplest way to do it:
sql-container:
type: tosca.nodes.MiCADO.Container.Application.Docker
properties:
image: mysql
ports:
- port: 3306
interfaces:
Kubernetes:
create:
If you're familiar with Kubernetes, the one little snippet above generates the two manifests in the box below.
Kubernetes manifests
apiVersion: v1
kind: Service
metadata:
name: sql-container
labels:
app.kubernetes.io/name: sql-container
app.kubernetes.io/instance: service-ex
app.kubernetes.io/managed-by: micado
spec:
selector:
app.kubernetes.io/name: sql-container
app.kubernetes.io/instance: service-ex
app.kubernetes.io/managed-by: micado
app.kubernetes.io/version: latest
ports:
- name: 3306-tcp
port: 3306
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: sql-container
labels:
app.kubernetes.io/name: sql-container
app.kubernetes.io/instance: service-ex
app.kubernetes.io/managed-by: micado
app.kubernetes.io/version: latest
spec:
template:
metadata:
labels:
app.kubernetes.io/name: sql-container
app.kubernetes.io/instance: service-ex
app.kubernetes.io/managed-by: micado
app.kubernetes.io/version: latest
spec:
containers:
- image: mysql
selector:
matchLabels:
app.kubernetes.io/name: sql-container
app.kubernetes.io/instance: service-ex
app.kubernetes.io/managed-by: micado
app.kubernetes.io/version: latest
Now, any other container can access port 3306 on this container at sql-container:3306
. You can see the hostname defaults to the name of the TOSCA node you've defined.
If you have multiple ports to expose using the same hostname, you can simply add to the list of ports, like so:
...
properties:
image: mysql
ports:
- port: 3306
- port: 33062
...
Other containers can reach both
sql-container:3306
andsql-container:33062
Protocols and TargetPort
Ports default to TCP. For UDP connections, simply:
...
properties:
image: flannel
ports:
- port: 8285
protocol: UDP
...
Kubernetes also supports the SCTP protocol
Sometimes, you may want/need to expose your container on a different port than that configured by the container by default. Consider an NGINX container listening on port 80, that we intend to expose to other containers using port 8080:
webserver:
type: tosca.nodes.MiCADO.Container.Application.Docker
properties:
image: nginx
ports:
- port: 8080
targetPort: 80
...
Other containers on the cluster can point at
webserver:8080
to hit:80
inside the container
Hostnames and Port names
As we've seen, the name of the generated Service (also the hostname for ingress to the container) defaults to the name of the parent container. You can change this by overriding the Service metadata like so:
sql-container:
type: tosca.nodes.MiCADO.Container.Application.Docker
properties:
image: mysql
ports:
- port: 3306
metadata:
name: database
...
Using the above snippet, you would now reach your container at
database:3306
It is important not to confuse this with the name of the port, which is generated automatically based on the port number and protocol (see the previously generated manifests for an example of this).
If you have the urge to specify your own port names, you can:
...
properties:
image: mysql
ports:
- name: myport
port: 3306
metadata:
name: database
...
The port name has changed, but has no effect on our route to this container. It is still reachable at
database:3306
ClusterIPs
When we create a service, Kubernetes randomly assigns a ClusterIP to it, restricted by default to the range 10.96.0.0/12
.
If you have a requirement for IP addressing over using hostnames, you can specify a ClusterIP like so:
sql-container:
type: tosca.nodes.MiCADO.Container.Application.Docker
properties:
image: mysql
ports:
- port: 3306
clusterIP: 10.97.101.98
...
Fun fact: you can specify a clusterIP of
None
We can now hit this container at 10.97.101.98:3306
. It is also still available at sql-container:3306
.