How to access local machine from a pod - docker

I have a pod created on the local machine. I also have a script file on the local machine. I want to run that script file from the pod (I will be inside the pod and run the script present on the local host).
That script will update /etc/hosts of another pod. Is there a way where i can update the /etc/hosts of one pod from another pod? The pods are created from two different deployments.

I want to run that script file from the pod (I will be inside the pod and run the script present on the local host).
You can't do that. In a plain Docker context, one of Docker's key benefits is filesystem isolation, so the container can't see the host's filesystem at all unless parts of it are explicitly published into the container. In Kubernetes not only is there this restriction, but you also have limited control over which node you're running on, and there's potential trouble if one node has a given script and another doesn't.
Is there a way where i can update the /etc/hosts of one pod from another pod?
As a general rule, you should avoid using /etc/hosts for anything. Setting up a DNS service keeps things consistent and avoids having to manually edit files in a bunch of places.
Kubernetes provides a DNS service for you. In particular, if you define a Service, then the name of that Service will be visible as a DNS name (within the cluster); one pod can reach the other via first-service-name.default.svc.cluster.local. That's probably the answer you're actually looking for.
(If you really only have a single-node environment then Kubernetes adds a lot of complexity and not much benefit; consider plain Docker and Docker Compose instead.)

As an addition to David's answer - you can copy script from your host to a pod using cp:
kubectl cp [file-path] [pod-name]:/[path]
About your question in the comment. You can do it by exposing a deployment:
kubectl expose deployment/name
Which will result in creating a service, you can find more practical examples and approach in this section.
Thus after your specific Pod terminates you can still reach new Pods by the same port and Service. You can find more details here.
In the example from documentation you can see that nginx Pod has been created with a container port 80 and the expose command will have following effect:
This specification will create a Service which targets TCP port 80 on
any Pod with the run: my-nginx label, and expose it on an abstracted
Service port (targetPort: is the port the container accepts traffic
on, port: is the abstracted Service port, which can be any port other
pods use to access the Service). View Service API object to see the
list of supported fields in service definition
Other than that seems like David provided really good explanation here, and it would be finding out more about FQDN and DNS - which also connects with services.

Related

Docker networks in Kubernetes/Rancher

I've been trying to convert my SimpleLogin Docker containers to Kubernetes using Rancher. However one of the steps requires me to create a network.
sudo docker network create -d bridge \
--subnet=240.0.0.0/24 \
--gateway=240.0.0.1 \
sl-network
I couldn't really find a way to do this on Kubernetes/Rancher.
How do I set up an equivalent network like the above command in Kubernetes?
If you want more information about what this network should do you can find it here.
You don't. Kubernetes has its own network ecosystem, which mostly acts as though every Pod and Service is on the same network. You can't create separate subnets within that, there's no way to create a separate network per logical application. You also can't control the IP range of networks in Kubernetes (it shouldn't usually be necessary in Docker either).
Generally you can communicate between Kubernetes Pods by putting a Service in front of each, and then using the Service's DNS name as a host name. If all of the parts were running in the same Namespace, and the Service in front of the database were named sl-db, then the webapp Pod could use sl-db as the host name part of the DB_URI setting.
Reading through the documentation you link to, you will probably need to do some extra work to get the Postfix MTA set up. Note that it looks like it runs outside of Docker in this setup; either you will have to port the setup to run inside Kubernetes or configure its mynetworks settings to include the network that contains the Kubernetes nodes. You will also need to set up Kubernetes ConfigMaps and Secrets to hold the various configuration files and certificates this setup needs.

Kubernetes-How to send data from a pod to another pod in kubernetes

In dockers, I had two containers Mosquitto abd userInfo
userInfo is a container which performs some logic and then send the result to mosquitto container. Mosquitto container then use this information to send it to IOT hub. To start these containers in Docker, I created a network and started both the container in the same network. So I can easily use the hostname of mosquitto container inside userinfo container to send data. I need to do this same in kubernetes.
So in kubernetes, what I did, I deployed the Mosquitto so its POD was created then I created its service and use it inside the userInfo pod to send data to mosquitto. But this is not working.
I created the service by using
kubectl expose deployment mosquitto
I need to send data of userInfo to Mosquitto.
How can I achieve this.?
Do I need to create network as I was doing in dockers or is there any other way.?
I also tried creating a pod with two containers i.e. mosquitto & userInfo, but this was also not working.
Thanks
A Kubernetes pod may contain multiple containers. People generally run multiple containers in a pod when the two containers are tightly coupled, and it sounds like this is what you're looking for. These containers are guaranteed to be hosted on the same machine (they can contact each other via localhost), share the same port space, and can also use the same volumes.
https://kubernetes.io/docs/concepts/workloads/pods/pod/#what-is-a-pod
Two containers same POD
If you are interested in the communication between two containers belonging to the same POD there is the guide from the official documentation showing how to achieve this through shared volumes.
The primary reason that Pods can have multiple containers is to support helper applications that assist a primary application. Typical examples of helper applications are data pullers, data pushers, and proxies. Helper and primary applications often need to communicate with each other. Typically this is done through a shared filesystem, as shown in this exercise, or through the loopback network interface, localhost.
Try to avoid to place two container in the same POD if you do not need it. Additional information can be found here: Multi-container pods and container communication in Kubernetes.
Two containers two POD
In this case (you can do the same also for the previous case) the best way to proceed is to expose a through a service the listening process of the container.
In this way you will be able to rely always on the very same IP or domain name (that you will be able to resolve merely internally) and port.
For example, if you have a Service called "my-service" in Kubernetes Namespace "my-ns" a DNS record for "my-service.my-ns" is created.
The network part is managed by Kubernetes so you will not need to do anything(in the basic configurations), merely when creating the service to instruct which is the target port of the container and the port that the client should use and the mapping is automatic.
Then once you exposed a port and an IP how you implement the communication and the datatransfer is no longer a Kubernetes question. You can implement it thorough a web server having static contents, through FTP, having a script sending SCP commands, basically there are infinite ways to do it.

Kubernetes pods versus Docker container in Google's codelabs tutorial

This question pertains to the Kubernetes tutorial on Google's CodeLabs found here: https://codelabs.developers.google.com/codelabs/cloud-compute-kubernetes/index.html?index=..%2F..%2Fgcp-next#15
I'm new to both Docker and Kubernetes and am confused over their use of the term "pods" which seems to contradict itself.
From that tutorial:
A Kubernetes pod is a group of containers, tied together for the purposes of administration and networking. It can contain one or more containers. All containers within a single pod will share the same networking interface, IP address, disk, etc. All containers within the same pod instance will live and die together. It's especially useful when you have, for example, a container that runs the application, and another container that periodically polls logs/metrics from the application container.
That is in-line with my understanding of how Kubernetes pods relate to containers, however they then go on to say:
Optional interlude: Look at your pod running in a Docker container on the VM
If you ssh to that machine (find the node the pod is running on by using kubectl describe pod | grep Node), you can then ssh into the machine with gcloud compute ssh . Finally, run sudo docker ps to see the actual pod
My problems with the above quote:
. "Look at your pod running in a Docker container" appears to be
backwards. Shouldn't it say "Look at your Docker container running
on the VM"?
"...run sudo docker ps to see the actual pod" doesn't make sense, since "docker ps" lists docker containers, not pods.
So am I way off base here or is the tutorial incorrect?
As mentioned above pod can run more than one container, but in fact to make it simple running more than one container in a pod is an exception and definitely not the common use. you may look at a pod as a container++ that's the easy way to look at it.
If you starting with kubernetes I have wrote the blog below that explain the main 3 entities you need to be familiar with to get started with kubernetes, which are pods, deployments and services.
here it is
http://codefresh.io/blog/kubernetes-snowboarding-everything-intro-kubernetes/
feedback welcome!
One nuance that most people don't know about docker running Kubenretes is that it is running a outdated version. I found that if I went to Google's cloud based solution for Kubernetes everything was quite easy to setup. Here is my sample code of how I set up Kubernetes with Docker.
I had to use the command line utility for Docker though to properly get everything to work. I think this should point you in the right direction.
(I've started learning Kubernetes and have some experience with Docker).
I think the important side of pods is that it may have container(s) which are not from Docker, but from some other implementation.
In this aspect the phrase in problem 1. is fully valid: output confirms that pod is in Docker, not anywhere else.
And reg. problem 2 - the phrase means that further details about the pod you should inspect from docker command. Theoretically different command may be needed in other cases.

Kubernetes - container communication within a pod using names instead of 'localhost'?

From the kubernetes docs:
The applications in a pod all use the same network namespace (same IP and port space), and can thus “find” each other and communicate using localhost.
Is it possible to use some container specific names instead of locahost?
For example, with docker-compose up, you use name of the service to communicate. [docs]
So, if my docker-compose.yml file is
version: '2'
services:
web:
build: .
ports:
- "8000:8000"
srv:
build: .
ports:
- "3000:3000"
Then I access srv from within web by calling http://srv:3000/, not http://localhost:3000
How can I achieve the same behaviour in kubernetes? Any way to specify what name to use in pods' yaml configuration?
localhost is just a name for the network loopback device (usually 127.0.0.1 for IPv4 and ::1 for IPv6). This is usually specified in your /etc/hosts file.
A pod has its own IP, so each container inside shares that IP. If these containers should be independent (i.e. don't need to be collocated), they should each be in their own pod. Then, you can define a service for each that allows DNS lookups as either "$SERVICENAME" from pods in the same namespace, or "$SERVICENAME.$NAMESPACE" from pods in different namespaces.
docker-compose deploys individual containers, linking them together so they know each other's name and IP.
a Pod in Kubernetes is similar, but this is not the purpose of a Pod to hold multiple external services and link them together.
A Pod is for containers that must be running on the same host, and interact among themselves only. The containers communicate internally via localhost.
Most Pods are in fact a single container.
A Pod communicates with the outside using Services. In essence a Pod appears as if it was just one container.
under the hood, a Pod is at least 2 containers: the pause container manages the IP of the Pod, and then your attached container. This allows your container to crash, restart, and be relinked in the Pod without changing IP, allowing to manage container crashes without involving the scheduler, and making sure the Pod stays on a single node during its lifetime, so restart is fast.
If containers we rescheduled each time they crash, they would potentially end up on a different host, routing would have to be updated etc...
Generally, Containers running inside a pod, shares pod's IP and Port space. The communication between the containers will happen through localhost by default. To communicate between the containers using the name(like DNS), the containers should run in the independent POD and expose it as a service to rest of application world.

IP variable expansion in Kubernetes Pod definition

I have a docker image that needs the container IP address (or hostname) to be passed by the command line.
Is it possible expansion the pod hostname or IP in the container command definition? if not, what is the better way to obtain it in a kuberneted deployed container?
In AWS I usually obtain it by contacting the EC2 meta-data service, I can do somethng similar contacting the kubernetes api, as long as I can obtain the pod name/id?
Thanks.
Depending on your pod setup, you may be able to use hostname -i.
E.g.
$ kubectl exec ${POD_NAME} hostname -i
10.245.2.109
From man hostname
...
-i, --ip-address
Display the network address(es) of the host name. Note that this works only if the host name can be resolved. Avoid using this option; use hostname --all-ip-addresses instead.
-I, --all-ip-addresses
Display all network addresses of the host. This option enumerates all configured addresses on all network interfaces. The loopback interface and IPv6 link-local addresses are omitted. Contrary to option -i, this
option does not depend on name resolution. Do not make any assumptions about the order of the output.
...
In v1.1 (releasing soon) you can expose the pod's IP as an environment variable through the downward api (note that the published documentation is for v1.0 which doesn't include pod IP in the downward API).
Prior to v1.1, the best way to get this is probably by querying the API from the pod. See Accessing the API from a Pod for how to access the API. The pod name is your $HOSTNAME, and you can find the IP with something like:
wget -O - ${KUBERNETES_RO_SERVICE_HOST}:${KUBERNETES_RO_SERVICE_PORT}/api/v1/namespaces/default/pods/${HOSTNAME} | grep podIP
Although I recommend you use a json parser such as jq
EDIT:
Just wanted to add that pod IP is not preserved across restarts, which is why the usual recommendation is to set up a service pointing to your pod. If you do use a service, the services IP will be fixed and act as a proxy to the pod, even across restarts. Service IPs are provided as environment variables, such as FOO_SERVICE_HOST and FOO_SERVICE_PORT.

Resources