How to handle dynamic resource in mesos without a lofs of agents? - mesos

What's my scenario?
I have e.g. two external cards which can be plug/unplug without power down of pc.
And these cards are the resources I want to managed with mesos.
Currently, I use attributes to manage them: the attributes nodeKey:card1_key and nodeKey:card2_key are registered to master to distinguish two different cards. Then if card1 was used, I directly flag all cpu, mem was used for mesos-agent1, then master will not offer mesos-agent1 to framework.
Also, with this if I need to unplug card1, I can directly shutdown mesos-agent1 without affect for mesos-agent2 which is used for card2.
Above is my scenario, every works fine except if I have a lots of cards, I had to setup a lots of mesos-agent for every card. This will somewhat memory consume.
Current solution command:
Card1:
docker run -d --net=host --name=mesos-agent1 --privileged \
-e MESOS_IP=$PC_IP \
-e MESOS_HOSTNAME=$PC_IP \
-e MESOS_PORT=$node_port \
-e MESOS_MASTER=zk://$SERVER_IP:2181/mesos \
-e MESOS_ATTRIBUTES="nodeKey:card1_key" \
-e MESOS_SWITCH_USER=0 \
-e MESOS_CONTAINERIZERS=docker,mesos \
-e MESOS_LOG_DIR=/var/log/mesos \
-e MESOS_WORK_DIR=/var/tmp/mesos \
-v "$(echo ~)/.dp/mesos-slave/log/mesos-$nodeKey:/var/log/mesos" \
-v "$(echo ~)/.dp/mesos-slave/tmp/mesos-$nodeKey:/var/tmp/mesos" \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /cgroup:/cgroup \
-v /sys:/sys \
-v $(which docker):/usr/bin/docker \
mesosphere/mesos-slave:1.3.0
Card2:
docker run -d --net=host --name=mesos-agent2 --privileged \
-e MESOS_IP=$PC_IP \
-e MESOS_HOSTNAME=$PC_IP \
-e MESOS_PORT=$node_port \
-e MESOS_MASTER=zk://$SERVER_IP:2181/mesos \
-e MESOS_ATTRIBUTES="nodeKey:card2_key" \
-e MESOS_SWITCH_USER=0 \
-e MESOS_CONTAINERIZERS=docker,mesos \
-e MESOS_LOG_DIR=/var/log/mesos \
-e MESOS_WORK_DIR=/var/tmp/mesos \
-v "$(echo ~)/.dp/mesos-slave/log/mesos-$nodeKey:/var/log/mesos" \
-v "$(echo ~)/.dp/mesos-slave/tmp/mesos-$nodeKey:/var/tmp/mesos" \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /cgroup:/cgroup \
-v /sys:/sys \
-v $(which docker):/usr/bin/docker \
mesosphere/mesos-slave:1.3.0
My question:
So if possible I can just register one mesos agent to mesos master, meanwhile can support my scenario:
a) Card1 was used, the scheduler framework can tag it as used, then next resource offer will have no card1 just card2 offerd? Seems something like --resources='cpus:24;gpus:2;mem:24576;disk:409600;ports:[21000-24000,30000-34000]', if one task used 4 cpus, next time master will just offer 20 cpus, but this cannot be done with --attributes. But mesos seems just can afford interface to programmer customize for --attributes not --resources?
b) If we need to unplug card1 or add a new card3, we could change some parameters of mesos-agent without restart the agent, then currently used e.g. card2 will not be impacted?
Any solution possible, or I had to bear with my current solution?

The simple answer is NO.
You cannot just start one mesos agent for multiple resources. Mesos is a solution of virtualization which indicating multiple(resources) to one.
But I think your requirements would be supported well by an external tool — marathon, one of scheduler frameworks based on mesos.
Marathon would maintain every container’s status scheduled by itself. In your case, if you unplug card1 without any other operations, marathon would know(of course there is an internal gap) the containers on card1(mesos-agent1) dead already. Then marathon will re-schedule these containers, which would request resource from mesos(master). Mesos master offer resources for re-scheduled containers, DONE!
See? No extra operations, you may unplug any cards if you wish to — without any impact of running containers or mesos agents. But you must register new cards to mesos master by starting a new mesos agent on them.
Hope this helps.

Related

How to add Infrastructure Agent to Heroku applications

I am attempting to have the New Relic Infrastructure Agent monitor my heroku applications.
The documentation says to run the following:
docker run \
-d \
--name newrelic-infra \
--network=host \
--cap-add=SYS_PTRACE \
--privileged \
--pid=host \
-v "/:/host:ro" \
-v "/var/run/docker.sock:/var/run/docker.sock" \
-e NRIA_LICENSE_KEY=[Key]\
newrelic/infrastructure:latest
But where do I actually run or put this so it runs it on my Heroku apps?

Docker behaving odd with bash environment vars

I know technically host networking isn't supported MacOS (see https://docs.docker.com/network/host/)
The host networking driver only works on Linux hosts, and is not
supported on Docker Desktop for Mac, Docker Desktop for Windows, or
Docker EE for Windows Server.
However it does actually seem to work. E.g. this works just fine:
docker run \
--name local-mysql \
-e MYSQL_ROOT_PASSWORD=foo \
-e MYSQL_DATABASE=baz \
--network="host" \
-d mysql:latest
However when I try to conditionally specify the host networking with a bash variable, it doesn't work, and I can't make sense of it. Consider the following test.sh:
#!/bin/bash
echo "Test 1"
docker rm -f local-mysql
docker run \
--name local-mysql \
-e MYSQL_ROOT_PASSWORD=foo \
-e MYSQL_USER=master \
-e MYSQL_PASSWORD=bar \
-e MYSQL_DATABASE=baz \
--network="host" \
-d mysql:latest
docker ps
sleep 5
echo "Test 2"
export NETWORKING='--network="host"'
docker rm -f local-mysql
docker run \
--name local-mysql \
-e MYSQL_ROOT_PASSWORD=foo \
-e MYSQL_USER=master \
-e MYSQL_PASSWORD=bar \
-e MYSQL_DATABASE=baz \
${NETWORKING} \
-d mysql:latest
docker ps
This yields:
% ./test.sh
Test 1
local-mysql
6bbd68f0564943b8fb66ed37f1e639b54719bdb3b88b4e13aeef0a11cae4090b
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6bbd68f05649 mysql:latest "docker-entrypoint.s…" Less than a second ago Up Less than a second local-mysql
Test 2
local-mysql
e286028ef9a1a27f4226beb60e766cc163c289239ba506f63a71a35adbc73ef3
docker: Error response from daemon: network "host" not found.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
I.e. when I hard code --network=host into the docker command, the container starts fine. But the exact same parameter in an environment variable fails to start with network "host" not found.
I'm honestly not sure if this is a failure of bash or docker, but I can't actually figure out what's going wrong.
-- EDIT --
Changing
export NETWORKING='--network="host"'
to
export NETWORKING='--network=host'
works. And for my purposes right now that's enough. But just to be thorough... Why? The working example has quotes in the value (--network="host"), so why does the shell expansion break the non-working example? What if I wanted something like --network="my host"?

Bcrypt docker passwd using --admin-passwd

What is wrong with the following command? It is intended to create a portainer container with admin passwd 'portainer':
docker run --rm -d --name "portainer" -p "127.0.0.1:9001:9000" -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer --admin-password='$2a$10$0PW6gPY0TSeYzry2RSakl.7VUVmzdmD6mQPcemiG6i2vfJGGGePYu'
It leads to a Portainer container that will deny access for 'admin', saying that passwd 'portainer' is invalid. Details:
I put it into a .bat file. The thing runs on docker CE in Windows 10.
The longish crypt string within single quotes is a bcrypt equivalent of 'portainer', the designated admin password. I created and checked it here: https://www.javainuse.com/onlineBcrypt
Prior to running the command I stopped and removed an old portainer container, and even said docker volume rm portainer_data.
Doubling the "$" to "$$" did not solve the issue.
The command is deeply inspired by the official portainer docs: https://documentation.portainer.io/v2.0/deploy/initial/
For now I have a simple workaround: Simply drop that --admin-passwd parameter. Given that I grant a volume to portainer, I can just define a passwd at first start. However, I'd still prefer the script-only solution. Any ideas?
Here it is the solution you need:
docker run --detach \
--name=portainer-ce \
-p 8000:8000 \
-p 9000:9000 \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /volume1/docker/portainer-ce:/data \
portainer/portainer-ce \
--admin-password="$(htpasswd -nb -B admin adminpwPC | cut -d ':' -f 2)"

Traefik on Docker stripprefix / to current directory

I am trying to setup a simple stripprefix middleware using Docker Desktop with unix containers and i get a very wiered behavior.
The static traefik-config comes from environment-variables:
docker run -p 8080:8080 -p 80:80 -p 443:443 --rm \
-a STDOUT \
--name traefik \
--network elastic \
-e TRAEFIK_ACCESSLOG=false \
-e TRAEFIK_API_INSECURE=true \
-e TRAEFIK_PROVIDERS_DOCKER_ENDPOINT="tcp://docker.for.win.localhost:2375" \
-e TRAEFIK_PROVIDERS_DOCKER_NETWORK="elastic" \
-e TRAEFIK_PROVIDERS_DOCKER_SWARMMODE=false \
-e TRAEFIK_LOG_LEVEL=DEBUG \
-v c:/dev/repos/docker/dockerfiles/traefik/ssl/localhost.crt:/ssl/traefik-server.crt \
-v c:/dev/repos/docker/dockerfiles/traefik/ssl/localhost.key:/ssl/traefik-server.key \
${custom_image}
I start a service using a middleware defined with labels like this:
-l traefik.http.routers.test.middlewares=test \
-l traefik.http.middlewares.test.stripprefix.prefixes=/test/my-service \
-l traefik.http.middlewares.test.stripprefix.forceslash=false
As a result i would expect a stripprefix-middleware with "/test/my-service" appear in traefik dashboard.
Instead
A stripprefix-middleware with "C:/dev/tools/git/" appears in the treafik dashboard. Appearently traefik somehow resolves the first "/" into the directory-path.
I start the whole thing using Git-Bash.
If anyone encountered something like this, i would really appreciate some pointers...
P.S.: i also tried all kinds of escaping and quoting i could think of
Maybe to prevent others wasting as much time....
... Turns out that git-bash for windows does some crazy stuff before handing the commands to docker.
Executing the exact same config using IntelliJ (docker-integration) or powershell does not replace the leading "/" with a windows path.

Run GUI programs in Docker in Ubuntu

I used to run programs with commands like this:
docker run -ti \
--name wireshark \
-e DISPLAY=$DISPLAY \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-v $HOME/.Xauthority:/root/.Xauthority \
--privileged \
-d ubuntu:17.10 /bin/bash
then I could run wireshark using my Ubuntu's system's display.
Like this page's example: Running GUI App with docker
Now it is not working. When I run wireshark I get this error:
root#5ad127a8333a:/# wireshark
QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-root'
No protocol specified
QXcbConnection: Could not connect to display :0
Aborted (core dumped)
It is possible to solve this with
xhost +
but it would then be wise to do
xhost -
after you no longer use this container.
In fact the more restrictive
xhost +local:docker
is enough

Resources