通过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,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" 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 ...
随机推荐
- 手把手带你开发一款 IIS 模块后门
https://cloud.tencent.com/developer/article/1507913 首先准备工具 VS2017 IIS 开始开发 先打开 VS 创建一个 winfrom 项目然后添 ...
- eclipse中配置maven环境
一.配置setting.xml文件 1.首先将下载好的maven打开,打开文件夹,首先就需要对maven安装目录下有个config文件夹,在文件夹下有settings.xml文件.settings里面 ...
- eclipse将项目打包成jar在linux中运行
最近因为项目需要,做了几个外挂程序做数据传输,涉及到项目打包操作,在此记录一下打包步骤和其中出现的问题. 1.首先右键项目文件夹,点击export,弹出如下选择框,在其中输入jar搜索,并选择JAR ...
- nginx反向代理https访问502, nginx反向代理, 支持SNI的https回源,SNI源点,nginx反向代理报错
正常nginx配置了SSL是可以通过HTTPS访问后端的,但是对有配置SNI + https后端的支持有点麻烦. 编译安装nginx后,看一下是否支持SNI /usr/local/nginx/sbin ...
- Appium学习1-安装
Appium简介 Appium 是一个开源的.跨平台的测试框架,可以用来测试 Native App.混合应用.移动 Web 应用(H5 应用)等,也是当下互联网企业实现移动自动化测试的重要工具.App ...
- 互联网的“ip分组交换技术”
(1)从名字分析 从“ip分组交换”这个名字中,我们看看涉及哪些事情. 1)交换 主要涉及两类交换. · 交换机:负责网内部数据交换 · 路由器:负责网间的数据交换. ip分组交换技术的核心就是路由器 ...
- JS高级---案例:验证用户输入的是不是中文名字
案例:验证用户输入的是不是中文名字 [\u4e00-\u9fa5] <!DOCTYPE html> <html lang="en"> <head> ...
- 前端框架-Vue 入门
一.介绍 1.Vue.js 是什么 Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架. Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合. ...
- guava的简单使用
引入依赖 <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId ...
- C short类型的内存分析
#include<stdio.h> #include<limits.h> void main(){ //printf("short%d, int%d, long%d ...