什麼是 Docker Remote API
每個 Docker Daemon 其實都有提供 Remote API .其工作主要都是提供一個介面可以讓 Docker Client 透過 API 來控制. 舉凡大家日常使用的指令 docker images
或是 docker ps
其實都是使用 Docker Remote API 的方式來連接本地端的 Daemon 來對 Docker Daemon Service 下指令.
此外, docker-machine
對於遠端的機器也是透過 Docker Remote API 的方式.
如何在 Mac OSX for Docker 使用 Docker Remote API
尋找 Docker-Machine Certificate
當你使用 Docker-Machine
來建置機器的時候,其實你的 Certificate 會存放在 /Users/YOUR_USERNAME/.docker/machine/machines
裡面.
該 Certificate 就是存放著讓 Docker Client 與 Docker Daemon 能夠相互溝通的金鑰資訊.
舉個例子:
如果你有建立一個 Docker-Machine 的機器名稱為 default
,那麼 Certificate 檔案就會存放在:
/Users/YOUR_USERNAME/.docker/machine/machines/default
裡面.
透過 curl
連接 Docker Remote API
以我的名稱 Evan
的作為一個範例的話:
### Set your environment variable
> export DOCKER_CERT_PATH=/Users/Evan/.docker/machine/machines/default
### Get Docker Machine IP
> docker-machine ip default
192.168.99.100
## Use CURL
> curl https://192.168.99.100:2376/images/json --cert $DOCKER_CERT_PATH/cert.pem --key $DOCKER_CERT_PATH/key.pem --cacert $DOCKER_CERT_PATH/ca.pem
curl: (58) SSL: Can't load the certificate "/Users/Evan/.docker/machine/machines/default/cert.pem" and its private key: OSStatus -25299
如果出現以下的錯誤:
curl: (58) SSL: Can't load the certificate "/Users/Evan/.docker/machine/machines/default/cert.pem" and its private key: OSStatus -25299
代表你沒有 cert.pem
需要執行額外的 key 轉換的動作
> cd /Users/Evan/.docker/machine/machines/default
# key transfer
> openssl pkcs12 -export \
-inkey key.pem \
-in cert.pem \
-CAfile ca.pem \
-chain \
-name client-side \
-out cert.p12 \
-password pass:mypass
接下來再來執行:
> curl https://192.168.99.100:2376/images/json --cert $DOCKER_CERT_PATH/cert.p12 --pass mypass --key $DOCKER_CERT_PATH/key.pem --cacert $DOCKER_CERT_PATH/ca.pem
[
{
"Id": "sha256:d38beda529d3274636d6cb1c9000afe4f00fbdcfa544140d6cc0f5d7f5b8434a",
"ParentId": "",
"RepoTags": [
"arungupta/couchbase:latest"
],
"RepoDigests": null,
"Created": 1450330075,
"Size": 374824677,
"VirtualSize": 374824677,
"Labels": {
}
}
]
就會回傳 Docker Machine 中的 Docker Daemon 的狀態.
查詢 Docker Container 的執行狀態,使用率
docker stats
是一個很方便的指令,可以顯示出目前在執行的 Container 的狀態與使用率.
這邊舉出一個簡單的例子:
>docker stats
CONTAINER CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
fb5435a83a96 0.00% 48.76 MiB / 1.954 GiB 2.44% 117.5 kB / 76.08 kB 19.86 MB / 0 B 9
透過 Docker Remote API 查詢 Docker stats
如果前面的設定都已經設定好了,你也可以透過 Docker Remote API 來查詢遠端機器
## 假設在 docker-machine default 裡面跑有兩個 container
> docker-machine ssh default
> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
66ee7abb2a12 instavote/vote:latest "gunicorn app:app -b " 5 days ago Up 5 days 80/tcp voteV.1.3u2i8gnttseibckfsnqr9dp58
e510fa405940 instavote/vote:movies "gunicorn app:app -b " 5 days ago Up 5 days 80/tcp vote.1.3hozslyep7al27u35zb24o6mp
## 查詢該 Container 66ee7abb2a12 的狀態
> curl https://192.168.99.100:2376/containers/66ee7abb2a12/stats --cert $DOCKER_CERT_PATH/cert2.p12 --pass mypass --key $DOCKER_CERT_PATH/key.pem --cacert $DOCKER_CERT_PATH/ca.pem
{
"read": "2016-08-15T05:10:49.404713534Z",
"precpu_stats": {
"cpu_usage": {
"total_usage": 0,
"percpu_usage": null,
"usage_in_kernelmode": 0,
"usage_in_usermode": 0
},
"system_cpu_usage": 0,
"throttling_data": {
"periods": 0,
"throttled_periods": 0,
"throttled_time": 0
}
},
"cpu_stats": {
"cpu_usage": {
"total_usage": 26505881978,
"percpu_usage": [
26505881978
],
"usage_in_kernelmode": 1690000000,
"usage_in_usermode": 5730000000
},
"system_cpu_usage": 110834160000000,
"throttling_data": {
"periods": 0,
"throttled_periods": 0,
"throttled_time": 0
}
},
"memory_stats": {
"usage": 56270848,
"max_usage": 75644928,
"stats": {
"active_anon": 55996416,
"active_file": 274432,
"cache": 286720,
"dirty": 4096,
"hierarchical_memory_limit": 9223372036854771712,
"hierarchical_memsw_limit": 9223372036854771712,
"inactive_anon": 0,
"inactive_file": 0,
"mapped_file": 0,
"pgfault": 363243,
"pgmajfault": 0,
"pgpgin": 318130,
"pgpgout": 306436,
"rss": 55984128,
"rss_huge": 8388608,
"swap": 0,
"total_active_anon": 55996416,
"total_active_file": 274432,
"total_cache": 286720,
"total_dirty": 4096,
"total_inactive_anon": 0,
"total_inactive_file": 0,
"total_mapped_file": 0,
"total_pgfault": 363243,
"total_pgmajfault": 0,
"total_pgpgin": 318130,
"total_pgpgout": 306436,
"total_rss": 55984128,
"total_rss_huge": 8388608,
"total_swap": 0,
"total_unevictable": 0,
"total_writeback": 0,
"unevictable": 0,
"writeback": 0
},
"failcnt": 0,
"limit": 1044246528
},
"blkio_stats": {
"io_service_bytes_recursive": [
],
"io_serviced_recursive": [
],
"io_queue_recursive": [
],
"io_service_time_recursive": [
],
"io_wait_time_recursive": [
],
"io_merged_recursive": [
],
"io_time_recursive": [
],
"sectors_recursive": [
]
},
"pids_stats": {
"current": 5
},
"networks": {
"eth0": {
"rx_bytes": 648,
"rx_packets": 8,
"rx_errors": 0,
"rx_dropped": 0,
"tx_bytes": 648,
"tx_packets": 8,
"tx_errors": 0,
"tx_dropped": 0
},
"eth1": {
"rx_bytes": 648,
"rx_packets": 8,
"rx_errors": 0,
"rx_dropped": 0,
"tx_bytes": 648,
"tx_packets": 8,
"tx_errors": 0,
"tx_dropped": 0
}
}
}
透過 Golang Code 來直接查詢
Docker 官方有提供一個很方便的 Golang 套件 engine-api
如果想要找到其他語言的套件,可以到這個地方去找 Docker Remote API client libraries.
package main
import (
"fmt"
"io/ioutil"
"log"
"github.com/docker/engine-api/client"
"github.com/docker/engine-api/types"
"golang.org/x/net/context"
)
func main() {
defaultHeaders := map[string]string{"User-Agent": "engine-api-cli-1.0"}
cli, err := client.NewClient("unix:///var/run/docker.sock", "v1.22", nil, defaultHeaders)
if err != nil {
panic(err)
}
options := types.ContainerListOptions{All: true}
containers, err := cli.ContainerList(context.Background(), options)
if err != nil {
panic(err)
}
for _, c := range containers {
fmt.Println(c.ID)
body, err := cli.ContainerStats(context.Background(), c.ID, false)
defer body.Close()
if err != nil {
log.Println(err)
}
//顯示 Container 資訊
content, err := ioutil.ReadAll(body)
log.Println("Container:", c.ID, string(content))
}
}
透過這樣查詢,可以得到類似以下的資訊:
2016/08/15 15:57:55 Container: fb5435a83a96a753e61b3020d6478650158ae9382f41f3119e3feafb65d2e07d
{
"read": "2016-08-15T07:57:55.652878954Z",
"precpu_stats": {
"cpu_usage": {
"total_usage": 709001154,
"percpu_usage": [
428133113,
31262531,
45274798,
204330712
],
"usage_in_kernelmode": 50000000,
"usage_in_usermode": 590000000
},
"system_cpu_usage": 185639070000000,
"throttling_data": {
"periods": 0,
"throttled_periods": 0,
"throttled_time": 0
}
},
"cpu_stats": {
"cpu_usage": {
"total_usage": 709001154,
"percpu_usage": [
428133113,
31262531,
45274798,
204330712
],
"usage_in_kernelmode": 50000000,
"usage_in_usermode": 590000000
},
"system_cpu_usage": 185643040000000,
"throttling_data": {
"periods": 0,
"throttled_periods": 0,
"throttled_time": 0
}
},
"memory_stats": {
"usage": 51126272,
"max_usage": 60538880,
"stats": {
"active_anon": 30945280,
"active_file": 1474560,
"cache": 19976192,
"dirty": 0,
"hierarchical_memory_limit": 9223372036854771712,
"hierarchical_memsw_limit": 9223372036854771712,
"inactive_anon": 36864,
"inactive_file": 18386944,
"mapped_file": 15933440,
"pgfault": 12593,
"pgmajfault": 153,
"pgpgin": 16899,
"pgpgout": 6530,
"rss": 30867456,
"rss_huge": 4194304,
"swap": 0,
"total_active_anon": 30945280,
"total_active_file": 1474560,
"total_cache": 19976192,
"total_dirty": 0,
"total_inactive_anon": 36864,
"total_inactive_file": 18386944,
"total_mapped_file": 15933440,
"total_pgfault": 12593,
"total_pgmajfault": 153,
"total_pgpgin": 16899,
"total_pgpgout": 6530,
"total_rss": 30867456,
"total_rss_huge": 4194304,
"total_swap": 0,
"total_unevictable": 0,
"total_writeback": 0,
"unevictable": 0,
"writeback": 0
},
"failcnt": 0,
"limit": 2097557504
},
"blkio_stats": {
"io_service_bytes_recursive": [
{
"major": 254,
"minor": 0,
"op": "Read",
"value": 19857408
},
{
"major": 254,
"minor": 0,
"op": "Write",
"value": 0
},
{
"major": 254,
"minor": 0,
"op": "Sync",
"value": 0
},
{
"major": 254,
"minor": 0,
"op": "Async",
"value": 19857408
},
{
"major": 254,
"minor": 0,
"op": "Total",
"value": 19857408
}
],
"io_serviced_recursive": [
{
"major": 254,
"minor": 0,
"op": "Read",
"value": 559
},
{
"major": 254,
"minor": 0,
"op": "Write",
"value": 0
},
{
"major": 254,
"minor": 0,
"op": "Sync",
"value": 0
},
{
"major": 254,
"minor": 0,
"op": "Async",
"value": 559
},
{
"major": 254,
"minor": 0,
"op": "Total",
"value": 559
}
],
"io_queue_recursive": [
],
"io_service_time_recursive": [
],
"io_wait_time_recursive": [
],
"io_merged_recursive": [
],
"io_time_recursive": [
],
"sectors_recursive": [
]
},
"pids_stats": {
"current": 9
},
"networks": {
"eth0": {
"rx_bytes": 117457,
"rx_packets": 393,
"rx_errors": 0,
"rx_dropped": 0,
"tx_bytes": 76077,
"tx_packets": 261,
"tx_errors": 0,
"tx_dropped": 0
}
}
}