通过docker-api来执行docker相关的操作。
配置
可以在docker启动文件docker.service中加入如下
vi /lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -H unix://var/run/docker.sock -H tcp://0.0.0.0:2375
但是这样直接开放api,不安全,因此就需要指定证书。
修改 ExecStart的值如下:
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock -D --tlsverify --tlscert=/etc/docker/certs.d/server-cert-docker.pem --tlskey=/etc/docker/certs.d/server-key-docker.pem --tlscacert=/etc/docker/certs.d/ca-docker.pem
客户端在访问docker-api的时候就需要提供证书。
脚本
下面是自动生成docker-api证书的脚本。
利用脚本自动生成,这样非常便捷,脚本(auto_gen_docker_tls_certs.sh)如下:
#!/bin/bash
#
# -------------------------------------------------------------
# 自动创建 Docker TLS 证书
# -------------------------------------------------------------
# 以下是配置信息
# --[BEGIN]------------------------------
CODE="docker"
IP="192.168.31.199"
PASSWORD=""
COUNTRY="CN"
STATE="HUNAN"
CITY="CHANGSHA"
ORGANIZATION="thyc"
ORGANIZATIONAL_UNIT="Dev"
COMMON_NAME="$IP"
EMAIL="an23gn@163.com"
# --[END]--
# Generate CA key
openssl genrsa -aes256 -passout "pass:$PASSWORD" -out "ca-key-$CODE.pem"
# Generate CA
openssl req -new -x509 -days -key "ca-key-$CODE.pem" -sha256 -out "ca-$CODE.pem" -passin "pass:$PASSWORD" -subj "/C=$COUNTRY/ST=$STATE/L=$CITY/O=$ORGANIZATION/OU=$ORGANIZATIONAL_UNIT/CN=$COMMON_NAME/emailAddress=$EMAIL"
# Generate Server key
openssl genrsa -out "server-key-$CODE.pem"
# Generate Server Certs.
openssl req -subj "/CN=$COMMON_NAME" -sha256 -new -key "server-key-$CODE.pem" -out server.csr
echo "subjectAltName = IP:$IP,IP:127.0.0.1" >> extfile.cnf
echo "extendedKeyUsage = serverAuth" >> extfile.cnf
openssl x509 -req -days -sha256 -in server.csr -passin "pass:$PASSWORD" -CA "ca-$CODE.pem" -CAkey "ca-key-$CODE.pem" -CAcreateserial -out "server-cert-$CODE.pem" -extfile extfile.cnf
# Generate Client Certs.
rm -f extfile.cnf
openssl genrsa -out "key-$CODE.pem"
openssl req -subj '/CN=client' -new -key "key-$CODE.pem" -out client.csr
echo extendedKeyUsage = clientAuth >> extfile.cnf
openssl x509 -req -days -sha256 -in client.csr -passin "pass:$PASSWORD" -CA "ca-$CODE.pem" -CAkey "ca-key-$CODE.pem" -CAcreateserial -out "cert-$CODE.pem" -extfile extfile.cnf
rm -vf client.csr server.csr
chmod -v "ca-key-$CODE.pem" "key-$CODE.pem" "server-key-$CODE.pem"
chmod -v "ca-$CODE.pem" "server-cert-$CODE.pem" "cert-$CODE.pem"
# 打包客户端证书
mkdir -p "tls-client-certs-$CODE"
cp -f "ca-$CODE.pem" "cert-$CODE.pem" "key-$CODE.pem" "tls-client-certs-$CODE/"
cd "tls-client-certs-$CODE"
tar zcf "tls-client-certs-$CODE.tar.gz" *
mv "tls-client-certs-$CODE.tar.gz" ../
cd ..
rm -rf "tls-client-certs-$CODE"
# 拷贝服务端证书
mkdir -p /etc/docker/certs.d
cp "ca-$CODE.pem" "server-cert-$CODE.pem" "server-key-$CODE.pem" /etc/docker/certs.d/
对脚本中的变量进行修改后运行,自动会创建好tls证书,服务器的证书在/etc/docker/certs.d/目录下:
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAhIAAABgCAYAAABISJtcAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAABwGSURBVHhe7Z0LdqM6DIbvttoFZTvT1WQzWUyvJD/wQ7YEgUDS/zuH6YCxJdnGkg2E/35LHj+/3//99/tf2r5/fh8xCQCwlcfvz3dxXf33/fvzThcWjwu3e9w5gbPlH82n2wc+njqQAAAAAABYwYesSJw947Pk339vdByTjhcifflGNS8777ciUOkPAADXRQkkrjp4kTO4fS/O4Hugp9hwoqNQ5SOQeDnDvsxtMe4f91tsJ85/ZiB96WsRAAAWLhRIzJxtSPv+uceB/UEDPgUV2smqI38hqvxXBBJXD1ZerN+wL7Meo/7BKxcxz/1G/e20MGKiPwAAXAtnIJGcQLkq0A7GIe37dvu9fdNfHpCd6TwLXJadly05nccPnR+FPX5ogE/nrAokLP2asmn7vhUzUiqX86U0WRHpZBCq/KX+JADK5afAiDH0E/mLbqV8q/68TO0nqvRKv3n/cOk3sc9HLfv2syGQ4LaLqxB5ZcJFsp/+JhtI/ySDb6uoZUV5ccepPwAAXItVgYQ4BxndadAjZ7cMxrzPKwbL6MzO/79clpXOpME47mYKWcVAL//XRmexoXUUtvywn+wLPB5FIY974dj68jKq/KX+2NkKdN5ir6VfqpuiUNKtlj6qPx+W/VmfeEj289K/1T+YmX4e++ZIsJL1SQFb2b8SLGvUPv2mtnFHzJ+DH5bP+0tQksqp9LzfcjDs1x8AAK7FyhWJuNsycZ6Sx0oXRjL4eNCJnVcakMWRaQppskz5k8BggAz8XvmqbUGmHHPqx47mXgY3FaP682DZr6SLzqmveGTPzvHYN0Mpu9KvhM9t65phHeJxvq2xqiJH8kN5S1+l8yjY4I33lv68Rn8AALgW+wQSPLPq8hV5rHRhJIOPNwMv6Xm7DQb7YgDPmPJHskvI0eSl57h55avlB+cpx1z1QzzoGDtcKr++LcJ4bBhh5Q3ple2yJTs9sh3nTO2boNX5tC/X50pQWNkVt7xCYKHYVurE7ctl0V/uvyyPz+VVB0lfpT8AAFyLN1iR4AE3Hadz4sz1IWXygN/oq8ky5Ssz7oo4Y6aT0xmvXZFooPM5rdZ3cr6Jz/5xukf2Cv1U+yZo9SfHfIGEEJ18sHWtA1dsK4PDqMsPBcJyjsi6L3JW6Q8AANdin0BCcTSynJvLstKZibNKA22+h/6on18o0QZlh/ywXzzDwOT79MH+nJ9mzlzeboGEpR8/n0F65VSeuQ/KU+vPwdz+Jb18hqKtn3H/YGbt67EvHKv7TCKUnQM9zs/76rlcTts+dDQFq9x+7pWIRNQtyS/0CTS6i4zvQs4a/QEA4FrsFEgwNBjeeEl6/VsbGZ6pyYAbtsrpkG5hcOWtcXglqiNnbPndWwulQyl04+P3O8uh/bZSVPla/QXnsRyb6CeOhR150o3s1xzyrP4cTO0n+vSko6d/ECP9XPYFGUPnWvYP1kvaRzuXy2nbh9siHpPVgla2RbSfb7dFG9o3XuoVrND2Vd9x6w8AANfCGUgA8ClogcSzxEACFw4A4A+iBBJxViQzo7VLvABckbgCkPs2AgkAANiLOpAAAGwAgQQA4O8yDSTy62knMZW/622YcxzB2fV7KLhNBgAAf4JxIMGO4MwpliX/3QOJs+v3aBBIAADAn2AYSKyfLe/rjE35bx5IvH414sU2IpAAAIA/gR5IDGbLo482yatt6XixtUV0rw82r8hlVPnh9ciQl18PbB3V5PXJyFh+72TZ0bMOZREj+5f8tY7T2zJW/dL2mR/NAgAA8EmogYQ2W84/kBSPy371Vsd8xqv9oNHoR6U0+eIMs7z2o0bkxMgJlu//Z32r/ZH8UvdQdvtbAnP7Q/6lfNantyExrt+RfnvIn7VPSisyFD9G5WHePgAAAD6VPpAYrQY0jlrOqxzFzFEp+Ueo8pWyS/ny/5njtOQvjpQdcP9jV5b9M9sbVPss/faQPzsnlM+BwPEfzQIAAPBJdIGENltOjiIve+etPHfmqDyOLqDK1wKF0lHdn/0oV0jnny1eZtUlIX1s/5P2OfV7Tr7jnPzTzP1tnSlW+wAAAPhY6kCCB3/V01gzZmbmqDz5iZF8y1Fp6ZU+lvzl3HqJPuHPP2Vz/e4h36kjQ3ryuWZ7Jaz2AQAA8LFUgYQ+Ww5o9/Dr++hzZ5fyz+7Dj+WHsscfNepl52cKqv2R/NLJhs88t8HE3H6fk/bU76h+npc/aR+qz9d9NAsAAMAnsQQSw9nyQvdWQftkv/HRqD5/4awt+TxLFudEG8vtPmpEzowc9baPcrWOMzrGLpgY2e9w5Jvqd0f5zCU+mgUAAOCTyIHEbLb8Cs6WfzSfbh8AAIC/SQgkHLPlQzlb/tF8un0AAAD+LPXDlgAAAAAAK6gDCZ455/vkfK+7vkd/XeIzDVn3V99GsOQ7n2EA+yF9OT2jcXT/sMo/u38CAMBxKIHEVR+Qo8H4VjwQyA/0xZQKseHEgVqVj0Di5Qz7MrfFuH/wGzvSTpx/SyBt9b+z+ycAAOzMhQKJmbMNad8/6UeS4k8wayefPVCr8l8RSFw9WHmxfsO+zHqM+gevHMQ8/IbLlk5k9b+z+ycAAOyMM5BITqBcFWgHw5A2fv1ynC6/2yBl1ltyOvwbCmlQr16BXBVIWPo1ZdNWfTSLyq1ekVTyC6r8pf4kAMrll78eaegn8hfdSvlW/XmZ2k9U6ZV+8/7h0m9in49a9vijYZNAgtsurkLklYm1qO1fYKUDAMCbsSqQEOcgozsN2uTslsGQ94vfJSDCDyilsqx0JjmjuJspZBUDvfxfG+nVgdqWr/3gU/VRMf7Rprzbl5dR5S/1l39wis5b7LX0Wxx1pvixqsCo/nxY9md94iHZz0v/Vv9gZvp57JsjwUrWZ/bRMJY1ap9+U9t4htr+BVY6AAC8GStXJOJuy8R5Sh4rXRjJ4ONBJ3ZeaWAXR6YppMky5U8CgwHiuLzyVduCTDnm1I8d5fijWqP682DZr6SLzm2gIzsDZud47JuhlF3pV8LntnXNsA7xON/W2FaRUa5WfsRKBwCAN2OfQML6aJaVLoxk8PGQNwcSpOftNhjstYHalD+SXUKOprgtIZtXvlp+cJ5yzFU/RP7pab4F0n5Uy2PDCCtvSK9sly3Z6ZHtOGdq3wStzqd9uT53dOtl01tLavsXWOkAAPBmvMGKRBjow3E6J85cH1ImD/iNvposU74y466IM2Y6OZ3x2hWJBjqf02p9J+eb+Owfp3tkr9BPtW+CVn9yzBdICLwKIQfZVi2fE7UtC6x0AAB4M/YJJBRHk++phz0jnZk4qzT45nvoj/r5hRJ1oLblh/35R71yfpo5c3m7BRKWfvx8BumVU3nmPihPrT8Hc/uX9PIZirZ+xv2DmbXvKz8axuX0jjwHq9x+W1YiEmr7F1jpAADwZuwUSDA0mM/eOjDTCZ4VirMIW+V0SLflqf7G4ZUMB2pbfv9RrMKhFLrx8fBRKtpvK0WVr9VfcH7LsYl+4hjZkSfd+K2EzsB5/TmY2k/06UlHT/8gRvq57Asy9OCAKPsH6zX8aBiX07YPt0U8llcmNjLsfxErHQAA3gxnIAHAp6AFEgAAALaiBBJpVsgzuyeWeAG4DGH1p1zxQCABAAD7UAcSAAAAAAArGAQSD36OrkE7BgAAAIC/zDCQ+PfVPDx35986MB6oe/z7/crLx8b29U+/bRLlzLavf1siGgqE7v9+b61dkce/r0L3r9/bJhkAAADA32J8a4ODguzsKbC4DRx/CedpvTQFBp3j144lZmnE/fb1u9bHP/5RmV83Cg7oLwUKaiBxvy8rLjEgmgZNAAAAAFACCceKgPr7CcxOgYQqM2/rA4kF52uKHDh9bV35AAAAAP4OeiAx8bR8C2CYvOLWRuWki3xfX1/dudVG6eUtiHW+3htIeM8DAAAA/jb7BxJt4soVCf7FyvLbB3xetU/l/7tv9fCeAAGrEQAAAICX+a0N8rilE0/b0BFrQcjaQKIJVKz9dViBBAcRXwgiAAAAACdqIJEdreLwh9+4YDiQaIKO0TYLJLTzy+2YQAIrEQAAAMBa6kCCP57EflQCgvBT2cGxFz+bzWmDVzfV1QIlGFGPRc4KJGTlZfRKKgAAAABUikCCZ+QxYOBgofC29/xMAn+lkf6or0cW+UtWBhItfXDCwcC6hyyHwUkOHEKA0aZjdQIAAACYEwOJsKyfg4cmkMhQAJF/qInOqU4ZBQfF8RyQDM7VnsfoNw5WHlQWnDwAAABwNv0zEkIMLIaOvEF7WyNRBg30/1ROv8rQyvFsii4AAAAAeBmDQAIAAAAAwAaBBAAAvBvynNpeK7Kzt9kAsEEg8TLmHw0Dx8IP3Ja/iNp/lI1/+Gx5KJdv1dVntOntGz51+n9ft5W/uurvH+azRAd0MLP+SPclXas/i6M/qtffPu2e03rQOcUt3fU2vBAEEuBCIJB4AZ6Php3P1QeT5/SzPsomb/aUH6kjh1I6GknPwUPzcDLR5pegwqns2v7BgcTonC0ftfNgftSOEpf00FbaA9Uar/moHus0cby5zEXn6W/mnA0CCXAhnIFE6mg0gOZZ154D1ruX72XrBevRP6R93WhA5l/n5FdxnemjGa5fz6vr10KyqkBBaRd5MDgN1OH8cTqdIYHGckK778PXP84IJGra+mux0kd4r49R+eG4/hA2l60dD0gfW91eNRIQxb7JW7VqRY6f+3Xuv13/tyDbimvr9q8NJEL6+Pqa6dfXO/ejdkWmyl+Vn/LXOvqbP+Wnv9J+ofw2/1A+X4sUxAfZ/HMBaXXwjDH+b7IqkJCGkdbjC3bPRnr38r2kCybuurH05/16YBVH1jjCcTqzVTfm6vq1NGVpszs5lmxQZFfpDJ3DgyAPgDzgbfpxM5+NMsizLKnzdit1Ooq5ng+5zdHUpwuf/ePzQj8aBxKxjqhvsrNZCPlu/+icVK+KI5sR+ivVfVFutaKRfuxP6Pu7hQQ67YrXiutnrl9Zn6HsVrdcXjws+1mfVLepfNZnTT+M+XNwwDqU9hry49uA3KbZTkrgMtbUMdjOyhWJuLs7716+l616GPk6p8YUeax04Zk6urp+Jcog3qwuBGp5+kBe6hMGz/T12v4ZCg8+G1l2XVcLs7R9GDtBqSPSnwfy2lF78dg/lu/lQe0dbmPEA1Fu5ciS45J0i/U6SV1ZDZ1R6kWumaifef1Y+qVzQx/u207JX8rX9FvFyL5kkyE/rkhwqgQSsSAEEq8jBxLLIFBsuWXtjjLP/+nle9l6wRn5LEfocJSmjClX1y8RBspucKkGxUg3OFPeGDyEmVedzv0jl0uzTx74yhmVD5+N5wUSg/prWfmMxIJlv1O+A7mesyBNXz7mrUtPu5X9J25Fhun40vVFonWk0+vH0i/az0Gw2mdDeqdf1slj/wwlf2WzIZ/tRyBxKliReClb9TDyaQNNmcdKF56po6vrx7ATGg0sStnq4FxQpSv5VZssPDYGO/pBNW1rZXqZ1V9POaD7mdm/Tr5FHUhoZbMu3rq0dIttRvLSGbV8A60vybHY/8zrx9JvOVf06oIJf/5tKPmr68uQj0DidBBIvJStelj5+gst3CscX4h1OmMNFjOurh9pqA6QCyIvpyuyHo8lb5xxL/aG85e3OmJ5lf4ePP2DzxmXe9SKhFV/Wv2sb6ux/aZ8IbaDWj/lWyXseBs54riWuqv7g01o7+a2QK6Tpj7SitW8oQtS/4qBCNdvZWffX9v+59EvqNM/n8Ck/OUzFnr+EeEcvW1iWrKP/m3rZyofgcTpIJB4AeEi4Iuo2dwDlUd/uvjIiWx5KyJDF2T1VLf7InwP/VI+Pf/y3IOkkTFVaiVbu4/MzqFoZ03/Aav6B+sxsfuYQMKuP36ifknjdqzrb4Ztv6f9mOiANGdFwcNSBrWfUkndWwHxuJfurYiy/Yr+w8fv6Xc3vIMS6y+20ca6dQ+02tfPWL/2+o312PS/Pn+S4bn+Uxtq9Rrzk+65jpRnjIbyqW4RSJyLM5AAAJwOz6SbwV3IM0MePI9ZkQDgODyBCLgyCCQAuDz6DDETl+rDTE2b8QFwZRBIvDsIJAAAAJwIAol3B4EEAACAz0JW6fZanUOgY4FA4mU8fh+TjxKBo7Hqv33Ysr2NMH8Y8+iPVpXIU/WFrG47oIPxQ2yLfcrDigfbb8o3Cc4g6Sc6tmXktyFi+mobwGVAIPFSEEi8AHna+OtGg1946viaHfLqF8t2/Tz1H572TsFDfCahOFHS8zMKIb1yRPzAY9pd+frj2v7BgcTonKMetsRHu8Cx7Dz+IJB4Kc5AIlVkeMUoROx7DljvXr6XrR3So39I2/J65WiG69fz6volRvVPstuZML9SlgciJV+V3hLKW//qma9/nBFI1Fj2HWv/uPxwfPyK4ai9Qp0+tZJDjqtczdBe/61eX6zSk92kv3b9FK83lrT9YHP5TqryaWtX7bbK3+f6rsvGR80K+bH/BNnh1fWwurrfWLEqkBDBoh1VCDXGXkq8f/leUoeIu24s/Xm/HlhlBp0vJCud2aobc3X9EqMylOMyo4k2aLObMr3hIcv8zfkufDbKIJYGlG7TddqXuZ5H2z8+L/SjcSAR64j6Jg+mCyHf9o92JX2KDLxCE//L5P4cD8p+Dg6SbtR26vWj2cvHFjufK98mlJ/yB8oVm+flazb6kWAky0uOMtVPaN/Z+DK3r9QtlF2WxTxv/4yYPwcHrENpryFfJj2hf2Y7KYHLaO3YysoVibi7O+9evpetehj5VKdW5LHShWfq6Or6JcZl6ANRPFddfejLWmZWraPy4rORdRtd/7O0fegH5cRr7B/L9/Kg9uSZ2yInyK0G6jQwS7pF0In7z129HaLoLH0+lW/bLQ6gOIH3l/KeL3+OVed7yH9GRyVvKd8cXyz70rl8nta3j67/kX3JJkN+saJV9qNDAollECi2rLldEfP8n16+l60dyshnOTqXI9yqG3N1/RKzMuhijMFDmDkUF2o1KETUwSmy8hmBBZ+N5wUSYSA17TrMfqd8B3I9Z0GavnxsZV3mhzVJRyp7yRrK78aPXL5lN1H1wVAPi27Pl//c+LmDfcY5U/20a7F1pNPxxWcfPmo2BisSL2WrHkY+1akVeax04Zk6urp+iRVlVIOPkk8dnBbaGaQPj35h9tEPGmlr63EvglzvwLO//evkW9SBhFY267KxLqk/sx1LeZbuvn6ZB37qexyoLOxT/hir/D3kP6GjNn7IsXh9muOLX3/pN10wcXT9K/mr8ceQj0BiL44u38tWPax8fUeSDjPpaHU6Y10MM66uX2KiZ3lPO86oy/NEnzyAKLoo+dfratUjw+eU9VJz1IqEPoAWHGy/KV8I7VL3mwTplzKLY2nkyMC81F3d3gZk7/3u6D9cfrksnuvM0+5EdAi8ctZW7S7lT0jlV8v6RZs/L/+Z6zu2OwmQ3Fz/VT/oyw76Lv1kbl+pf/98AvO8/eEcve/GtGQf/ZvsTUzlI5DYi6PLnxMamTtJs3kHKpf+1LlogNnyVkSGOlz11LK7k11bP0/9p/vmIU2/D8pOOuXVntjO5VL+Nb9BsKp/sJ4Tu48JJEL7tvrVA/OR9tvyA3GA1QbjuEoQ8lL7KpXUPfUej5uI4yptcJRP29LHPdcPE+0bjBvPlz+nL7/W42n5m8cfgttX2p42lts98GuPL2P7Wv31dnjO/nDOLJC48kfNnIEEAOB0eCatOZFiZnjsMxIAgNfjDMROBIEEAJdnPhOVACPPRLQZDQDgfUEgAQAAAIDNIJAAAADw1lzQkckq3F6rb9d31FcHgcTLePw+Jh8lAgcjD18VDyJRI5S3CfghpCVdf1hOiLcRujY0yrfx9w95aryQ1W0HdDCzfg62390+Q4KzSPqJjm0Z+Wn/mL7ahk8FgQSYg0DiBcjTtF83GvzCU7XX7LBXv5ie1I8fSExeIb6eV7114PooVHorQEkzyp+xtn9wIDE656iHLfHRrr/Mk9feESCQuBTOQCJVdHiFJkTseDp8PVs7rKf+Q9qW1ytHM1y/nlfXr4VkUUAwdnR6usyK/90lbS7bKn+Er3+cEUjUbKs/G+/1MSo/HB+/QqcdD0gf296hSHTx+iFvXf/mU0Kg1Kcb10/x+l5J2w82l2/Stwv3s35VT5fPemp9oXwV0abWHR/lKuTH/hFkU91QAuu/TofnWBVIiGKiPVUYNdarlPwc+g7rw6p/3q8vVrlI84VmpTNbdWOurl/NQ5bhy7JbFFk8A5LBPOg608Muf4TPRhnkSIcwYLVbWe9HMdfzaPvH54W2GQcSsY6ob/JguxDbFB/tGlDKD06qDQym8tnRdW2i2TRGAr1sT3KUqczQfrPxI+wn+wP4KNd+rFyRiLtgI1vr0cgny3xtxy3yWOnCM218df0CcnFSGXyh1Y6kpB+UwrGkX0jX9PCVP8NnIw90dV0tzNL2QaufwGvsH8v38qCBl2d2bd+qBvI0cEu6RdCJB/bP/GhXys9ytLa15PfplSM0UfQvyzfHD0W/imft26t+4y5T2WTIL1asyn5ySiCxDALFli2zK2qe//PTfWztcEY+K+J3zQi26sZcXb+G4T38MJC0x7VBe6rHymcEFnw2nhdI6PXTcZj9TvkO5HrOgjR9+djKumS7qW9wIFUvi4fyu/Ejl2/ZTVSOK9TDotvz5c/Ht5B/+0er+JTyGu+voal8LVBoHel0/LDsf9Y+q3wLJX9lsyGf7b9KIDHn2YoCga31aOTTLrQyj5UuPNPGV9evp7zgAmFw6y+8cLy/iOcXaV++B4+NY33C1tbjXozqR2d/+9fJt6gDCa1s1mVjXVJ/ZjuW8izdfX07OwZyHByoLOxT/pglv9Rb52w9bVOcUzg+F9r4IMdi8GCOH/762WbffvWbUQKvoXwEEn+NrfVo5es7mnSoSUes0xnrYplxdf2I8p61MmPWBxCNoEdnq1G+D0//4HPKeqk5akXCrJ+D7fe1T2ibut8kSL+UWRxPI0cG7qXupP+5+gNB9n72R7vK/P39e2YuPxKdI6/arNMltitlkvK4fqt2tsePpF9120Ktny32eeo3nKP3zZiW7KN/k72JqXwEEn+D0Am4EzWbd6By1T91PhpgtrwVkaEOWT3V7O6EV9eP24AHsZSX5dhLz3r54SJvbZ2XP2dV/+A6mNh9TCBh18+x9nvbJ7SNOljHVYKQlxyKUkndU/HxuIk4ttIGR/m0LX3cc/0w0b7BuPF8+SPa/LoeY/mJuf5TuP2kbTk/lds90EtlG+NHr1/dv7bb56nfcM4skLjyR7ksnIEEAOB0eCatDcLFzO/4hy0B2IrH4f5F3r9eEEgAcHmMmVxcqg8zFW3GA8D5yGx51If/NAgkAAAAgCHyzAEHucrtBsB8WiDx+Pn9zjMb2r5/3iR6fPz+fBd6//f9+/NSxS35WNJ7OdKX0+z87P4BAACfixJIXHVplJzB7XtxBt8DPcWGEx2FKh+BxMsZ9mVui3H/4NmTtBPnf5tAGgAAzuNCgcTM2Ya075/l9Zg7BxXayX82kLh6sPJi/TYFErxyEfPcb9TfEEYAAMCc39//ARnsg1VsPY8wAAAAAElFTkSuQmCC" alt="">
客户端的证书在运行脚本的目录下,同时还自动打好了一个.tar.gz的包,很方便。
aaarticlea/png;base64,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" alt="">
重启docker
systemctl daemon-reload && systemctl restart docker
以java的docker-api的访问为例子:
依赖
<dependency>
<groupId>com.github.docker-java</groupId>
<artifactId>docker-java</artifactId>
<!-- use latest version https://github.com/docker-java/docker-java/releases -->
<version>3.1.5</version>
</dependency>
实体类
import lombok.Data;
import lombok.experimental.Accessors;
/**
* @author wzm
* @version 1.0.0
* @date 2019/7/25 10:06
**/
@Data
@Accessors(chain = true)
public class DockerClientDTO {
/**
* 私钥和证书文件路径
*/
private String certAndKeyFilePath;
/**
* 主机ip
*/
private String host;
/**
* 端口
*/
private String port;
/**
* 注册用户名
*/
private String registryUsername;
/**
* 注册密码
*/
private String registryPassword;
/**
* 注册邮箱
*/
private String registryEmail;
public DockerClientDTO(String host, String port, String certAndKeyFilePath) {
this.host = host;
this.port = port;
this.certAndKeyFilePath = certAndKeyFilePath;
}
}
将使用脚本生成好的客户端证书tls-client-certs-docker.tar.gz解压到“D:/docker/tls”目录下
java代码
import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.command.DockerCmdExecFactory;
import com.github.dockerjava.api.model.Container;
import com.github.dockerjava.api.model.Image;
import com.github.dockerjava.api.model.Info;
import com.github.dockerjava.core.DefaultDockerClientConfig;
import com.github.dockerjava.core.DockerClientBuilder;
import com.github.dockerjava.core.DockerClientConfig;
import com.github.dockerjava.jaxrs.JerseyDockerCmdExecFactory;
import net.sf.json.JSONArray;
import org.springframework.util.StringUtils;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
/**
* docker-api操作工具类
*
* @author wzm
* @version 1.0.0
* @date 2019/7/16 11:16
**/
public class DockerOperationUtils {
// D:/docker/tls
// "tcp://192.168.2.133:2375"
// "docker"
// "123456"
// "an23gn@163.com"
private static DockerClient dockerClient;
/**
* 获取DOCKER客户端
*
* @param dockerClientDTO docker客户端连接信息
* @return DockerClient
*/
public static DockerClient getDockerClient(DockerClientDTO dockerClientDTO) {
// 进行安全认证
DockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder()
// 服务器ip
.withDockerHost("tcp://" + dockerClientDTO.getHost() + ":" + dockerClientDTO.getPort())
.withDockerTlsVerify(true)
// 证书的本地位置
.withDockerCertPath(dockerClientDTO.getCertAndKeyFilePath())
// 私钥的本地位置
//.withDockerConfig(dockerClientDTO.getCertAndKeyFilePath())
// API版本 可通过在服务器 docker version 命令查看
.withApiVersion("1.31")
// 默认
.withRegistryUrl("https://index.docker.io/v1/")
// 默认
.withRegistryUsername(dockerClientDTO.getRegistryUsername())
// 默认
.withRegistryPassword(dockerClientDTO.getRegistryPassword())
// 默认
.withRegistryEmail(dockerClientDTO.getRegistryEmail())
.build();
// docker命令执行工厂
DockerCmdExecFactory dockerCmdExecFactory = new JerseyDockerCmdExecFactory()
.withReadTimeout(60000)
.withConnectTimeout(60000)
.withMaxTotalConnections(100)
.withMaxPerRouteConnections(10);
dockerClient = DockerClientBuilder.getInstance(config).withDockerCmdExecFactory(dockerCmdExecFactory).build();
return dockerClient;
}
public static void main(String[] args) {
dockerClient = DockerOperationUtils.getDockerClient(new DockerClientDTO("192.168.2.134", "2375", "D:/docker/tls"));
Info info = queryClientInfo(dockerClient);
System.out.println(info);
}
/**
* 连接信息
*
* @param dockerClient DOCKER客户端
* @return Object
*/
public static Info queryClientInfo(DockerClient dockerClient) {
return dockerClient.infoCmd().exec();
}
/**
* 查看镜像
*
* @param dockerClient DOCKER客户端
* @return Object
*/
public static List<Image> queryImagesList(DockerClient dockerClient) {
return dockerClient.listImagesCmd().exec();
}
/**
* 停止容器
*
* @param dockerClient DOCKER客户端
* @param container 容器ID
* @return Object
*/
public static Object stopContainer(DockerClient dockerClient, String container) {
return dockerClient.stopContainerCmd(container).exec();
}
/**
* 删除镜像
*
* @param dockerClient DOCKER客户端
* @param imagesID 镜像ID
* @return Object
*/
public static Object removeImages(DockerClient dockerClient, String imagesID) {
return dockerClient.removeImageCmd(imagesID).exec();
}
/**
* 删除容器
*
* @param dockerClient DOCKER客户端
* @param container 容器ID
* @return Object
*/
public static Object removeContainer(DockerClient dockerClient, String container) {
return dockerClient.removeContainerCmd(container).exec();
}
/**
* 创建容器
*
* @param dockerClient DOCKER客户端
* @param imagesID 镜像ID
* @return Object
*/
public static Object createContainer(DockerClient dockerClient, String imagesID) {
return dockerClient.createContainerCmd(imagesID).exec();
}
/**
* 创建一个镜像
*
* @param dockerClient DOCKER客户端
* @return Object
* @throws FileNotFoundException 找不到文件
*/
public static Object createImages(DockerClient dockerClient) throws FileNotFoundException {
//仓库地址
String repository = "";
//镜像文件流
InputStream imageStream = new FileInputStream("");
return dockerClient.createImageCmd(repository, imageStream).exec();
}
/**
* 容器列表(运行中的)
*
* @param dockerClient DOCKER客户端
* @return Object
*/
public static List<Container> listContainersCmd(DockerClient dockerClient) {
return dockerClient.listContainersCmd().exec();
}
public static List<String> getContainerNameList(List<Container> containerList) {
List<String> containerNameList = new ArrayList<>();
for (Container container : containerList) {
String containerName = container.getNames()[0].replace("/", "");
containerNameList.add(containerName);
}
return containerNameList;
}
/**
* 启动容器
*
* @param dockerClient DOCKER客户端
* @param containerID 容器ID
*/
public static Object startContainerCmd(DockerClient dockerClient, String containerID) {
return dockerClient.startContainerCmd(containerID).exec();
}
/**
* 重启容器
*
* @param dockerClient 客户端
* @param containerID 容器id
* @return java.lang.Object
* @author wzm
* @date 2019/9/28 15:30
*/
public static Object restartContainerCmd(DockerClient dockerClient, String containerID) {
return dockerClient.restartContainerCmd(containerID).exec();
}
/**
* 从本地上传资源到容器
*
* @param dockerClient 客户端
* @param containerID 容器id
* @param resource 本地资源路径
* @param remote 服务器资源路径
* @return Object
*/
public static Object copyArchiveToContainerCmd(DockerClient dockerClient, String containerID, String resource, String remote) {
return dockerClient.copyArchiveToContainerCmd(containerID).withHostResource(resource).withRemotePath(remote).exec();
}
/**
* 从容器下载资源到本地
*
* @param dockerClient 客户端
* @param containerID 容器id
* @param local 本地路径
* @param remote 远程容器路径
* @return Object
*/
public static Object copyArchiveFromContainerCmd(DockerClient dockerClient, String containerID, String local, String remote) {
try {
// String path = "F:\\tmp\\wealth.rar"
// remote="/tmp/wealth.rar"
InputStream input = dockerClient
.copyArchiveFromContainerCmd(containerID, remote)
.exec();
int index;
byte[] bytes = new byte[1024];
FileOutputStream downloadFile = new FileOutputStream(local);
while ((index = input.read(bytes)) != -1) {
downloadFile.write(bytes, 0, index);
downloadFile.flush();
}
input.close();
downloadFile.close();
return true;
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
}
/**
* 根据容器名获取容器ID
*
* @param dockerClient 容器客户端
* @param containerName 容器名
* @return java.lang.String
* @author wzm
* @date 2019/9/28 15:38
*/
public static String getContainerIdByName(DockerClient dockerClient, String containerName) {
try {
String containerId = "";
Object object = DockerOperationUtils.listContainersCmd(dockerClient);
JSONArray jsonArray = JSONArray.fromObject(object);
for (int i = 0; i < jsonArray.size(); i++) {
String name = jsonArray.getJSONObject(i).getString("names");
name = name.replace("[\"/", "").replace("\"]", "");
if (!StringUtils.isEmpty(name) && name.equals(containerName)) {
containerId = jsonArray.getJSONObject(i).getString("id");
}
}
return containerId;
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
}
}
- Java 使用 UnixSocket 调用 Docker API
在 Docker 官网查阅 API 调用方式 例如:查询正在运行的容器列表,HTTP 方式如下: $ curl --unix-socket /var/run/docker.sock http:/v1. ...
- Docker入门教程(七)Docker API
Docker入门教程(七)Docker API [编者的话]DockerOne组织翻译了Flux7的Docker入门教程,本文是系列入门教程的第七篇,重点介绍了Docker Registry API和 ...
- WebDriver基本API使用(基于Java)V1.0
WebDriver基本API使用(基于Java)V1.0http://www.docin.com/p-803032877.html
- java和javax都是Java的API包,java是核心包,javax的x是extension的意思,也就是扩展包。
java和javax都是Java的API包,java是核心包,javax的x是extension的意思,也就是扩展包.
- Flink Program Guide (1) -- 基本API概念(Basic API Concepts -- For Java)
false false false false EN-US ZH-CN X-NONE /* Style Definitions */ table.MsoNormalTable {mso-style-n ...
- docker的简单搭建(java/tomcat 环境)
1.一副图简单了解下docker的布局,它是虚拟的,docker分为私服.镜像.容器三个模块 一般从私服pull镜像,镜像run一个容器,我们把容器作为一个虚拟服务,里面可以独立运行进程有独立的内网I ...
- springCloud 服务注册启动报错<com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException: Connection refused: connect>
报错:com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException: Connection refused: ...
- springCloud com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException: Connection refused: connect
1.com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException: Connection refused: c ...
- 【漏洞挖掘】攻击对外开放的Docker API接口
https://medium.com/@riccardo.ancarani94/attacking-docker-exposed-api-3e01ffc3c124 1)场景 攻击开放在互联网的Dock ...
- Eureka服务注册中心相关错误com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException: Connection refused: connect
启动项目报错如下 原因: 在默认设置下,Eureka服务注册中心也会将自己作为客户端来尝试注册它自己,所以会出现 com.sun.jersey.api.client.ClientHandlerExce ...
随机推荐
- Github+Hexo一站式部署个人博客(原创)
写在前面 注:博主 Chloneda:个人博客 | 博客园 | Github | Gitee | 知乎 本文源链接:https://www.cnblogs.com/chloneda/p/hexo.ht ...
- mysql 表中数据不存在则插入,否则更新数据
在很多时候我们会操作数据库表,但是在向表中插入数据时,会遇到表中已经存在该id的数据或者没有该id的数据的情况,没有该id的数据的情况时直接插入就OK,遇到已经存在该id的数据的情况则更新该id的数据 ...
- yolov3 进化之路,pytorch运行yolov3,conda安装cv2,或者conda安装找不到包问题
yolov3 进化之路,pytorch运行yolov3,conda安装cv2,或者conda安装找不到包问题 conda找不到包的解决方案. 目前是最快最好的实时检测架构 yolov3进化之路和各种性 ...
- Wannafly Camp 2020 Day 7H 游戏 - 欧拉筛,GCD
忘记特判 \(1\) ,血了一地 听说 \(O(n^2 \log n)\) 能过? #include <bits/stdc++.h> #define int long long using ...
- 0005 修改Django工程名
写框架非常耗时间,把框架写好以后,经测试稳定的框架,需要保存下来,以后有工程需要,直接更改工程名即可. 01 右键点击工程名,点击Refactor/Rename 02 选择更改工程名 03 关闭PyC ...
- 怎么把apk文件部署在云服务器上
你服务器直接使用nginx,将请求映射到固定目录,把你的apk放到该目录.其他都不用干了.
- nginx下载,安装,基础命令,和代理tomcat例子理解
nginx代理讲的很好理解:https://www.cnblogs.com/ysocean/p/9392908.html 一.nginx应用场景: 1.反向代理(用的非常多) 客户端发出请求,反向代理 ...
- linux - mysql:注意事项
1.mysql和orcal数据中的数据类型不一致,比如:mysql中没有类型varchar2.number 2.mysql环境中的命令后面都带一个分号作为命令结束符 - “:”
- 网页前端导出CSV,Excel格式文件
通过自己实际测试有以下几种方法 方法一通过a标签实现,把要导出的数据用“\n”和“,”拼接成一个字符串,然后把字符串放到href中,这种方法只支持chrome,firefox等非ie浏览器 html页 ...
- 解决 genymotion 安装apk报错 app contains ARM native code and your Genymotion device cannot run ARM instructions
1.某些APP安装在模拟器时提示“ this probably means that the app contains ARM native code and your Genymotion devi ...