docker api
whenever you run something like docker run ...
underneath it just performs rest api call to local docker daemon
by default on macos daemon listens not for some port as we used to but for /var/run/docker.sock
unix socket
here you can find bunch of useful examples and here is few of them
print version and info
curl -s --unix-socket /var/run/docker.sock http://localhost/version | jq
curl -s --unix-socket /var/run/docker.sock http://localhost/info | jq
create container (docs)
curl -s -X POST --unix-socket /var/run/docker.sock -d '{"Image":"nginx:latest"}' -H 'Content-Type: application/json' http://localhost/containers/create?name=nginx | jq
start container
curl -s -X POST --unix-socket /var/run/docker.sock -H 'Content-Type: application/json' http://localhost/containers/543d296c04eb16287dead09077592e1cb321f26fce50547618f87c74b0d449f5/start
list containers
curl -s --unix-socket /var/run/docker.sock -H 'Content-Type: application/json' http://localhost/containers/json | jq
container details
curl -s --unix-socket /var/run/docker.sock -H 'Content-Type: application/json' http://localhost/containers/543d296c04eb16287dead09077592e1cb321f26fce50547618f87c74b0d449f5/json | jq
with that in place we can have something like:
const http = require('http')
const request = (path, body = null, method = 'GET') => new Promise((resolve) => http.request({
socketPath: '/var/run/docker.sock',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
method: body && method === 'GET' ? 'POST' : method,
path
}, response => {
let body = ''
response.setEncoding('utf-8')
response.on('data', chunk => body += chunk)
response.on('end', () => resolve(body ? JSON.parse(body) : null))
}).end(body ? JSON.stringify(body) : undefined))
module.exports = {
version: () => request('/version'),
info: () => request('/info'),
create: (name, image) => request(`/containers/create?name=${name}`, {Image: image}),
start: (id) => request(`/containers/${id}/start`, null, 'POST'),
list: () => request(`/containers/json`),
details: (id) => request(`/containers/${id}/json`),
stats: (id) => request(`/containers/${id}/stats?stream=false`),
stop: (id) => request(`/containers/${id}/stop`, null, 'POST'),
remove: (id) => request(`/containers/${id}`, null, 'DELETE'),
}
which will allow us to do something like:
const docker = require('./docker')
docker.create('nginx', 'nginx').then(({Id}) => {
docker.start(Id).then(() => {
docker.details(Id).then(details => {
console.log(details)
docker.stop(Id).then(() => {
docker.remove(Id).then(() => {
console.log('done')
})
})
})
})
})
Kubernetes Resourses Note
All this note is quite usefull to describe how Kubernetes resources requests and limits works
At the very end, each server has not only docker but also kubelet (aka our simplified api)
With help of such api kubernetes scheduler can understand how much of resources available/used on each server
And whenver we as users ask kubernetes to create new pods in cluster it will look for server that has enought free resourses to fit our requests
Kubernetes resourses requests themselves DO NOT affect actual usage it is just a hint for scheduler to do it work
It is a bad idea to lie about resources usage and requests should be as close as possible to actual usage to avoid OOM or throttles