Docker服务器安装配置以及Java访问指南

Docker服务器安装配置以及Java访问指南

 

    录

 

欢迎 3

适用读者 3

Docker环境的安装 3

Docker Tool Box软件的安装 6

设置远程访问API 7

Docker服务器端访问IP和端口设置 7

通过自签名证书安全认证 10

服务器端签名证书设置 10

客户端签名证书设置 14

Java客户端访问Docker服务器 14

 

 

 

欢迎

本文档讲述的是在VirtualBox上如何安装和配置Docker服务器,并用Java代码去访问服务器。

适用读者

本文假设读者已经具有Docker的基本概念并想要进一步了解Docker的安装配置知识。 

Docker环境的安装

在Windows下的开发环境中,

  1. 安装VirtualBox,下载网址在这里https://www.virtualbox.org/。安装完,VirtualBox以后,需要下载Ubuntu的镜像安装文件,下载网址在这里:https://cn.ubuntu.com/server/。不推荐安装Windows,镜像,Docker引擎在Windows平台上运行的很不好。

我的安装版本是

  1. VirtualBox是5.2.12
  2. Ubuntu Server 18.04 LTS
  3. Docker (Client/Server) 18.05.0-ce
  4. Docker Java API (https://github.com/docker-java) 3.0.14
  1. 启动VirtualBox,见到如下界面

  1. 点击上图红色方框中的新建,如下图所示:

  1. 选择Ubuntu 64-bit,输入一个虚拟电脑名称,点击确定。然后一路安装下去。如何安装Ubuntu在VirutalBox上,请上网搜索相关帮助。
  2. 注意,有些电脑可能看不到有Ubuntu 64-bit的安装选项。这是因为有两个可能原因,一个是你的电脑中,Bios的设置中,BIOS未开启虚拟化技术。请打开。第二个原因,是Windows的Windows 7 以上版本自带的 hyper-V,请关闭它。还有一个原因是因为你电脑上安装了Vmware,请关闭它。
  3. 安装完Ubuntu以后,就进入Docker的正式安装了。
  4. 打开已经安装好的Ubuntu界面,登录进去。
  5. 由于界面中并不友好,所以建议你安装一个SecueCRT或者Bitvise SSH Client,这两个工具都可以连接到Ubuntu Server上,建议后者,因为后者连FTP都有了。
  6. 安装Docker首先更新Ubuntu上的软件库安装包索引,命令如下:

$ sudo apt-get update

  1. 安装以下包以使apt可以通过HTTPS使用存储库(repository):

$ sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common

  1. 添加Docker官方的GPG密钥:

$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

  1. 使用下面的命令来设置stable存储库:

$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

  1. 再更新一下apt包索引:

$ sudo apt-get update

  1. 安装最新版本的Docker CE:

$ sudo apt-get install -y docker-ce

注:在生产系统上,可能会需要应该安装一个特定版本的Docker CE,而不是总是使用最新版本,先列出来可用的版本:

$ sudo apt-cache madison docker-ce

选择要安装的特定版本,第二列是版本字符串,第三列是存储库名称,它指示包来自哪个存储库,以及扩展它的稳定性级别。要安装一个特定的版本,将版本字符串附加到包名中,并通过等号(=)分隔它们,如:

$ sudo apt-get install docker-ce=

  1. 这样,Docker引擎就安装完毕了。下面我们查看以下Docker引擎的安装状态。下面这个命令是查看引擎的状态。

$ sudo systemctl status docker

  1. 如果没有启动,则启动Docker服务:

$ sudo systemctl start docker

  1. 运行经典的hello world:

$ sudo docker run hello-world

  1. 如果出现了Hello from Docker,则说明已经安装成功。
  2. 一些资料:

管理docker容器中的数据 http://www.cnblogs.com/imoing/p/dockervolumes.html

Docker 常用命令http://www.cnblogs.com/me115/p/5539047.html

Docker容器中文件的上传与下载 https://blog.csdn.net/zzy1078689276/article/details/77389177

Docker实践(二):容器的管理(创建、查看、启动、终止、删除) https://blog.csdn.net/u010246789/article/details/53958662

Docker容器查看进程号码https://blog.csdn.net/mrliqifeng/article/details/62884342

详解如何查看 docker 容器使用的资源 https://www.jb51.net/article/128134.htm

VirtualBox虚拟机网络设置(四种方式)https://blog.csdn.net/zhaihaifei/article/details/53309137

Docker Tool Box软件的安装

另外:作为学习材料,有一个很好的,几乎是傻瓜式安装的软件叫Docker Tool Box,大家可以下载下来学习。这个软件Docker公司和社区提供的一个集Docker、Virtual Box、Docker管理客户端一体的平台。下载网址是https://docs.docker.com/toolbox/toolbox_install_windows/

作为初学者,它很适合。可以在其上学习使用Docker命令。

Docker命令学习,参照:http://www.runoob.com/docker/docker-tutorial.html  

Docker 常用命令,参照:http://www.cnblogs.com/me115/p/5539047.html

设置远程访问API

Docker服务器端访问IP和端口设置

我们安装完毕了Docker以后,登录到虚拟机以后,就通过sudo  docker一些列命令可以创建管理一个docker container实例,但是,我们的目的不是在虚拟机环境下管理docker container,而是通过Java程序来管理。目前有两个比较著名的Java API for Docker(https://github.com/docker-java/docker-java),一个是Docker Java,一个是Spotify的Docker Client API(https://github.com/spotify/docker-client)。这两个API,我都用过,现在我们九一第二个Docker Java作为公司使用API来,搭建公司的Docker底层平台的基础设施。

首先我们要在Docker的引擎端,来开放API访问。Docker为C/S架构,服务端为docker daemon,客户端为docker.service。支持本地unix socket域套接字通信与远程socket通信。默认为本地unix socket通信,要支持远程客户端访问需要做设置。关于设置daemon监听连接,网上有很多种说法,无外乎以下几种(公司仅用Ubuntu,因此只关注Ubuntu下的设置):

  1. 首先找到修改daemon配置:/etc/docker/daemon.json,如果找不到是正常的,Docker在安装时默认不创建该文件,因此需要自己创建该文件,用如下命令,

$sudo nano /etc/docker/daemon.json,

添加如下行:

{"hosts": ["fd://", "tcp://0.0.0.0:2375"]}

然后重启Docker,$sudo service docker restart

这种方法我试过了,不管用!不知道为什么。我用的VirtualBox是5.2.12,Ubuntu本本是18.04,Docker(Client/Server)版本是18.05.0-ce

  1. 第二种是找到配置文件路径,/etc/default/docker,这个文件也是一个重要配置文件。

进入编辑模式($sudo nano /etc/default/docker),添加如下行:

DOCKER_OPTS="-H fd:// -H tcp://0.0.0.0:2375"

然后重启Docker,$sudo service docker restart

这种方法我也试过了,不起效果!

  1. 最后一种,找到它也是偶然看见的,我查看Docker的状态,使用命令:

$sudo service docker status

出现如下输出:

这让我看到,docker启动的时候,实际是读取docker.service这个文件里的配置的。

我们用命令编辑这个文件:$sudo nano /lib/systemd/system/docker.service

我打开这个文件内容如下:

上图的红框中的文字是决定了docker的通讯监听的。这个文件是docker daemon启动的时候要读取的。是在当前版本(18.05.0-ce)下至关重要的一个配置文件。未来docker的版本上,有可能不一样,因此不可照搬。

我把端口监听加入到上述配置中,配图如下:

-H tcp://0.0.0.0:2375(-H tcp://0.0.0.0:2376),参数H是表示主机(HOST)IP,0.0.0.0,是表示接受任何IP的访问,这样有点风险,不过后边我们会加强安保的。-H fd://是默认Unix协议通讯的意思,也就是很多文章提到的,-H unix:///var/run/docker.sock,于-H fd://是一个意思。在Linux下的Docker的client端于server端的通讯就是基于unix协议的。

加入上述行以后,按Ctrl+X键,根据提示按Y键,保存退出。

要想让配置生效,首先要重新装载配置文件,用如下命令来重新装载:

$sudo systemctl daemon-reload,回车

$sudo service docker restart,回车

$sudo service docker status,来查看。

再用$sudo netstat -lt,列出来用tcp协议监听端口的进程,如下图:

这里我们可以看到[::]:2376,我们这里加的-H tcp://0.0.0.0:2376。因此是2376端口。这说明我们加2376端口监听成功。而前面的tcp6说明是IPv6协议的,而tcp是IPv4的,这里有必要简单说一下,现在Docker进程监听的协议都是tcp6的,经过配置可以改成IPv4的,但是在IPv6中,也可以接收IPv4发过来的请求。因此不必担心tcp和tcp6的差别。

这样,我们成功的使docker开始监听2375或2376,理论上docker已经可以接收远程访问了。

但是,我们上面讲了,开放这个端口,会带来极大的安全隐患,即使有了防火墙设置。因为通讯的内容是没有加密的。因此,我们需要加强安保措施。怎么加强呢?且听下回分解

通过自签名证书安全认证

现在Docker Java API默认的连接方式就是基于签名证书认证的。如果我们的Docker没有签名认证过,Docker Java是无法连接到Docker的,也就是说,要想连Docker,必须做签名认证。

证书的生成: 详细信息,移步官网:Protect the Docker daemon socket(https://docs.docker.com/engine/security/https/#create-a-ca-server-and-client-keys-with-openssl)。其原理是通过指定tlsverify标志并将Docker的tlscacert标志指向受信任的CA证书来启用TLS。在守护进程模式下,它只允许来自由该CA签名的证书认证的客户端的连接。 在客户端模式下,它将只连接到具有由该CA签名的证书的服务器。

现在我们将认证流程简化一下。

下列一系列的命令,让我们可以生成认证证书。注意:下面这些TLS命令将只在Linux上生成一组有效的证书。 macOS附带的OpenSSL版本与Docker所需的证书不兼容。我没有Mac笔记本,所以没有机会试一试,请大家自行试试吧。

服务器端签名证书设置

首先,我们需要选择一个放证书的文件夹,这个文件夹很多文章,包括官网都建议创建一个.docker文件夹,我个人认为,这个文件夹在哪里不重要,只要能保证服务器安全,防火墙有效,就可以了。

我在/home/xuanqi/下面创建了一个/certs/文件夹。用$pwd,就可以看到该文件夹是/home/xuanqi/certs/。转到该文件夹,执行如下命令:

$ openssl genrsa -aes256 -out ca-key.pem 4096,生成CA私钥,并设置pass phrase,我设置的就是123456,比较简单,因为是测试环境。但是要记住这个密码,后边命令还会用到。再输入:

$ openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem,生成CA公钥,也就是证书。还让你输入国家名,省名啥的,这些都是随便填一个就行,因为密钥算法会把这些信息加密进密钥的。值得一提的是Common Name,说是要你填写,server FQDNyour  name,意味着可以随便写,但是我在这里建议,写Docker所在服务器的IP,这个很重要。这个IP后边还会用到,我这里是192.168.99.101,在生产环境下,用使用你docker宿主机的DNS name替换下面的填入Common name,如api.google.com等,这个IP不难拿到,你用$ifconfig命令就可以拿到。我在这里填CDH是错误的。

这样客户端的公钥和私钥就生成完了。出现如下图的画面。

下一步生成服务器私钥,命令如下:

$openssl genrsa -out server-key.pem 4096

再用私钥生成服务器公钥请求文件,也就是证书,命令如下:

$openssl req -subj "/CN=192.168.99.101" -sha256 -new -key server-key.pem -out server.csr, 

这里的192.168.99.101同样是Docker所在服务器的IP,你不要照抄,用自己的Docker服务器替换上去。

下面我们可以用CA来签署证书了。这里我们可以填写IP地址或则DNS name,如,我们需要允许10.10.10.20和127.0.0.1连接:

$echo subjectAltName = IP:10.10.10.20, IP:127.0.0.1 > extfile.cnf,

上述命令有点像一个过滤器,如果地址填的不全,远程API就无法访问该Docker,那么我们就把,地址填的全一些,我的命令是这样滴:

$echo subjectAltName = DNS:192.168.99.101, IP: 192.168.99.101, IP: 192.168.1.101, IP:0.0.0.0, IP:127.0.0.1 > extfile.cnf

我填写了,Docker所在服务器(Docker的宿主机)所在地址,域名192.168.99.101等,以及我自己本地客户机所在IP:192.168.1.101,还有Docker所在服务器的本地地址127.0.0.1。免得Java API连接时候找不到,哈哈。

然后,将上述多个生成信息,写入文件。用如下命令。

$openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -extfile extfile.cnf

再看客户端私钥:

$openssl genrsa -out key.pem 4096

下一步再生成客户端证书请求文件:

$openssl req -subj '/CN=client' -new -key key.pem -out client.csr

用CA为客户端签署证书文件:

$openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -extfile extfile.cnf

这时候,还需要输入你的密码,我的密码是123456,输上去即可。

这样认证文件就在你的目录下生成完毕了。我的在我的/home/xuanqi/certs,如下图中红色方框所示:

有了证书,不能放在那里不用,Docker不知道你为它生成了证书,得让知道你为它付出的脑细胞。怎么让它知道呢?

还是要回到我们上文提到的docker.service文件中,那个文件里需要添加上你为它生成的文件的路径和文件名。如下图红色方框所示:

字比较小啊看不清。嗯,我们来把它放大:

ExecStart=/usr/bin/dockerd -D --tlsverify=true --tlscert=/home/xuanqi/certs/server-cert.pem --tlskey=/home/xuanqi/certs/server-key.pem --tlscacert=/home/xuanqi/certs/ca.pem -H tcp://0.0.0.0:2376  -H fd://

注意到没有,我这里把所有的认证文件都加上了准确的路径。用Ctrl+X,按Y保存退出。

再重新装载配置文件

$sudo systemctl daemon-reload,回车

$sudo service docker restart,回车

$sudo service docker status,来查看进程状态。

输出结果如下图所示:

至此,服务器端的设置已经完成。

客户端签名证书设置

聪明的读者,我想你们已经看出来了,实际上我们在生成服务器端的安全认证证书的同时,已经把客户端的安全认证证书生成了。那么这些证书不能让他们闲在服务器上,需要拿到客户端来来让他们工作。

我把他们下载下来,放到我的本地机上,d:/data/certs/文件夹下,如下图蓝色方框部分,这样Java客户端就可以通过这些证书来访问Docker服务器了。

下面我们来说明一下如何使用这些证书来访问Docker服务器。

Java客户端访问Docker服务器

我们用Java Docker客户端接口包来访问Docker服务器。

我的Maven项目中使用的依赖是:

<dependency>

<groupId>com.github.docker-javagroupId>

<artifactId>docker-javaartifactId>

<version>3.0.14version>

dependency>

Java代码,这段代码是连接了Docker服务器,并创建了一个Tomcat Container,首先需要你自己去Docker仓库去拉一个Tomcat镜像回来,在Docker所在服务器上用命令$sudo docker pull tomcat,这个镜像比较大,需要一些时间,请耐心等待。

public class DockerJavaClient {

public DockerJavaClient() {

}

 

public static void main(String[] args) {

 

DockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder().withDockerTlsVerify(true)

.withDockerCertPath("D:/Data/cert/").withDockerHost("tcp://192.168.99.101:2376")

.withDockerConfig("D:/Data/cert/").withApiVersion("1.23").withRegistryUrl("https://index.docker.io/v1/")

.withRegistryUsername("dockeruser").withRegistryPassword("ilovedocker")

.withRegistryEmail("[email protected]").build();

 

DockerClient dockerClient = DockerClientBuilder.getInstance(config)

.withDockerCmdExecFactory(dockerCmdExecFactory).build();

CreateContainerResponse container1 = dockerClient.createContainerCmd("tomcat:latest").exec();

dockerClient.startContainerCmd(container1.getId()).exec();

 

}

 

至此,我们的Docker访问就配置成功了。

你可能感兴趣的:(java,Docker)