Java后端开发技能Get:开启Docker的新世界——Hello Docker

Java后端开发技能Get:开启Docker的新世界——Hello Docker


前言

相信不少小伙伴都或多或少听说过Docker,在实际的应用中,Docker已经被广泛地使用了。所以现在已经不是一个新奇的新技术,而是你作为JavaWeb后端开发、服务器架构师等角色必须掌握的一项基本技能。通过阅读本文你可以对Docker有一个初步的概念,赶紧动手试试跟着做一个HelloWorld吧。


一、什么是Docker

如果你不想看后面冗长的介绍,那么就简单一句话:

Docker类似运行在Linux上的虚拟机,就像Vmware在Windows上一样。

docker是基于Go语言实现的云开源项目,诞生于2013年,由dotCloud公司发起。

官方定义如下:

docker是一个开源的软件部署解决方案;

docker也是轻量级的应用容器框架;

docker可以打包、发布、运行任何的应用。

另一定义:

Docker是一个开源的引擎,可以轻松的为任何应用创建一个轻量级的、可移植的、自给自足的容器。开发者在笔记本上编译测试通过的容器可以批量地在生产环境中部署,包括VMs(虚拟机)、bare metal、OpenStack 集群和其他的基础应用平台。

根据我目前所知的理解,docker是随时可以运行的完整环境,它并不保持一个恒定的状态,而是有所需则取所需,更像是一个“操作系统+相关依赖+主要内容.exe ”,自己把需要的环境都已经部署好了,在别的计算机上能够完美地复现。

docker的三大核心:镜像(Image)、容器(Container)、仓库(Repository)。

二、Debian8下轻松安装Docker

根据官方文章《Docker安装手册》(http://www.docker.org.cn/book/install/supported-platform-17.html),看评论说Docker基于Linux 64位的,因此需要64bit操作系统,不过我也查到一些32位的安装教程网页。总之先在更熟悉一点的Debian 8 64位下实施安装(Debian是类Ubuntu的Linux操作系统,我非常喜欢):

【系统环境】阿里云服务器,Debian 8.9 64位。

【配置说明】Debian 8自带了3.16的内核,已经满足Docker的运行条件,由于Go语言包版本问题,docker.io包被放在了backports里而不是stable里。

1、添加backports源

vi /etc/apt/sources.list
deb http://http.debian.net/debian jessie-backports main
apt-get update

如果你刚刚装上新系统,都还没有基础的一些deb,比如Vim编辑器都还没有安装,那么可以参考这个debian 8 deb来设置,这是163的源:

deb http://packages.dotdeb.org jessie all
deb-src http://packages.dotdeb.org jessie all
deb http://mirrors.163.com/debian/ jessie main non-free contrib
deb http://mirrors.163.com/debian/ jessie-updates main non-free contrib
deb http://mirrors.163.com/debian/ jessie-backports main non-free contrib
deb-src http://mirrors.163.com/debian/ jessie main non-free contrib
deb-src http://mirrors.163.com/debian/ jessie-updates main non-free contrib
deb-src http://mirrors.163.com/debian/ jessie-backports main non-free contrib
deb http://mirrors.163.com/debian-security/ jessie/updates main non-free contrib
deb-src http://mirrors.163.com/debian-security/ jessie/updates main non-free contrib
deb http://mirrors.baidubce.com/debian jessie-backports main contrib non-free
deb-src http://mirrors.baidubce.com/debian jessie-backports main contrib non-free
deb http://http.debian.net/debian jessie-backports main

2、安装docker.io包

apt-get install docker.io

3、确认docker运行是否正常

docker run --rm hello-world 

会提示:

本地没有找到hello-world项目 → 正在拉取hello world项目 → Hello from Docker!This message shows that your installation appears to be working correctly.

Java后端开发技能Get:开启Docker的新世界——Hello Docker

三、Hello Docker

准备

Docker系统有两个程序:docker服务端和docker客户端。其中docker服务端是一个服务进程,管理着所有的容器。docker客户端则扮演着docker服务端的远程控制器,可以用来控制docker的服务端进程。大部分情况下,docker服务端和客户端运行在一台机器上。

查看docker版本

docker version
提示:
Client version: 1.6.2
Client API version: 1.18
Go version (client): go1.3.3
Git commit (client): 7c8fca2
OS/Arch (client): linux/amd64
Server version: 1.6.2
Server API version: 1.18
Go version (server): go1.3.3
Git commit (server): 7c8fca2
OS/Arch (server): linux/amd64

搜索可用的docker镜像

用docker search命令来检索docker可用的镜像

docker search tutorial

镜像都是按照用户名/镜像名来存储的:

NAME DESCRIPTION STARS OFFICIAL AUTOMATED
learn/tutorial 36
georgeyord/reactjs-tutorial This is the backend of the React comment b... 5 [OK]
mhausenblas/kairosdb-tutorial GitHub fetcher for KairosDB tutorial 1 [OK]
linkedin/photon-ml-tutorial An interactive tutorial of the Photon ML m... 1

有的镜像经过了官方验证,可以不用用户名,直接以镜像名存储,如:

NAME DESCRIPTION STARS OFFICIAL AUTOMATED
ubuntu Ubuntu is a Debian-based Linux operating s... 7340 [OK]
dorowu/ubuntu-desktop-lxde-vnc Ubuntu with openssh-server and NoVNC 165 [OK]
rastasheep/ubuntu-sshd Dockerized SSH service, built on top of of... 132 [OK]

下载可用的docker镜像

下载docker镜像时需要把用户名/镜像名写完整,使用docker pull命令拉取,如:

docker pull learn/tutorial

在docker容器中运行命令

docker容器就像是一个拥有所有环境的沙盒进程,它默认是不运行任何程序的,需要你运行一个进程来启动一个容器,当运行的进程结束时,容器也会停止。利用刚刚下载的learn/tutorial来进行Hello world,命令为 docker run [用户名/镜像名] [命令语句],例如:

docker run learn/tutorial echo "hello world"
hello world

在docker容器中安装新程序

利用刚刚的run命令,learn/tutorial是基于ubuntu的,因此用apt-get install -y来执行安装,-y是为了不进行交互,因为docker是无法响应这种交互的(不过尝试后发现docker只是停顿了几秒,也能成功安装)。来安装一个ping程序:

docker run learn/tutorial apt-get install -y ping

保存对docker容器的修改

利用docker ps -l命令,即可查看进行操作后docker容器的容器ID号,再利用docker commit [容器id] [用户名/镜像名]就能提交。

整个过程保存了新旧状态之间的区别,从而产生了一个新版本,注意commit命令提交的容器id只需要简写前面几个字符即可识别。

docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2bef2995887e learn/tutorial:latest apt-get install -y 4 seconds ago Exited (0) 1 seconds ago silly_bohr
docker commit 2bef learn/ping
9660801322a6953232e3663a7deed632027898b8d23c4b58596a3dd8aebe6040

使用新的docker容器

刚刚保存为了learn/ping,因此使用新的名字就能用新的容器了,测试如下:

docker run learn/ping ping www.baidu.com
PING www.a.shifen.com (115.239.211.112) 56(84) bytes of data.
64 bytes from 115.239.211.112: icmp_req=1 ttl=53 time=29.7 ms
64 bytes from 115.239.211.112: icmp_req=2 ttl=53 time=29.6 ms
64 bytes from 115.239.211.112: icmp_req=3 ttl=53 time=29.6 ms

按ctrl+C即可停止

查看运行中的镜像

docker ps可以查看所有正在运行中的镜像,docker inspect [容器id]可以查看某个容器的详细运行信息。

例如,我们一个SSH运行ping的docker:

docker run learn/ping ping www.baidu.com

另开一个SSH来检查这个运行中的docker:

docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5f76db829af0 learn/ping:latest "ping www.baidu.com" 9 seconds ago Up 8 seconds nostalgic_lovelace
docker inspect 5f7
[{
"AppArmorProfile": "",
"Args": [
"www.baidu.com"
],
"Config": {
"AttachStderr": true,
"AttachStdin": false,
"AttachStdout": true,
"Cmd": [
"ping",

"www.baidu.com"
],
"CpuShares": 0,
"Cpuset": "",
"Domainname": "",
"Entrypoint": null,
"Env": [],
"ExposedPorts": {},
"Hostname": "5f76db829af0",
"Image": "learn/ping",
"Labels": {},
"MacAddress": "",
"Memory": 0,
"MemorySwap": 0,
"NetworkDisabled": false,
"OnBuild": null,
"OpenStdin": false,
"PortSpecs": null,
"StdinOnce": false,
"Tty": false,
"User": "",
"Volumes": {},
"WorkingDir": ""
},
"Created": "2018-03-07T12:52:43.618113724Z",
"Driver": "aufs",
"ExecDriver": "native-0.2",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"CapAdd": null,
"CapDrop": null,
"CgroupParent": "",
"ContainerIDFile": "",
"CpuShares": 0,
"CpusetCpus": "",
"Devices": [],
"Dns": null,
"DnsSearch": null,
"ExtraHosts": null,
"IpcMode": "",
"Links": null,
"LogConfig": {
"Config": null,
"Type": "json-file"
},
"LxcConf": [],
"Memory": 0,
"MemorySwap": 0,
"NetworkMode": "bridge",

"PidMode": "",
"PortBindings": {},
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"RestartPolicy": {
"MaximumRetryCount": 0,
"Name": "no"
},
"SecurityOpt": null,
"Ulimits": null,
"VolumesFrom": null
},
"HostnamePath": "/var/lib/docker/containers/5f76db829af03f915c67495cd025c4fa401bf862d8f056763b2868b9b830c6d1/hostname",
"HostsPath": "/var/lib/docker/containers/5f76db829af03f915c67495cd025c4fa401bf862d8f056763b2868b9b830c6d1/hosts",
"Id": "5f76db829af03f915c67495cd025c4fa401bf862d8f056763b2868b9b830c6d1",
"Image": "798a12b7257efd2fb2c91a5581dfa7d258af136fa05a447650748caa577620af",
"LogPath": "/var/lib/docker/containers/5f76db829af03f915c67495cd025c4fa401bf862d8f056763b2868b9b830c6d1/5f76db829af03f915c67495cd025c4fa401bf862d8f056763b2868b9b830c6d1-json.log",
"MountLabel": "",
"Name": "/nostalgic_lovelace",
"NetworkSettings": {
"Bridge": "docker0",
"Gateway": "192.168.42.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "192.168.42.19",
"IPPrefixLen": 24,
"IPv6Gateway": "",
"LinkLocalIPv6Address": "fe80::42:c0ff:fea8:2a13",
"LinkLocalIPv6PrefixLen": 64,
"MacAddress": "02:42:c0:a8:2a:13",
"PortMapping": null,
"Ports": {}
},
"Path": "ping",
"ProcessLabel": "",
"ResolvConfPath": "/var/lib/docker/containers/5f76db829af03f915c67495cd025c4fa401bf862d8f056763b2868b9b830c6d1/resolv.conf",
"RestartCount": 0,
"State": {
"Dead": false,
"Error": "",
"ExitCode": 0,
"FinishedAt": "0001-01-01T00:00:00Z",
"OOMKilled": false,
"Paused": false,
"Pid": 1790,
"Restarting": false,
"Running": true,
"StartedAt": "2018-03-07T12:52:43.713174245Z"
},

"Volumes": {},
"VolumesRW": {}
}
]

四、发布自己的docker镜像

使用docker images可以查看当前所有的镜像:

docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
learn/ping latest 798a12b7257e 12 minutes ago 139.9 MB
455fcbe970b7 12 minutes ago 139.9 MB
9660801322a6 19 minutes ago 139.9 MB
hello-world latest 690d80202531 3 months ago 1.848 kB
learn/tutorial latest 8dbd9e392a96 4.905907 years ago 128 MB

使用docker push [用户名/镜像名]可以发布到自己的用户名下面(需要输入登录信息)

docker push learn/ping
The push refers to a repository [learn/ping] (len: 1)
798a12b7257e: Image push failed
798a12b7257e: Buffering to Disk
Please login prior to push:
Username: 123
Password:
Email: qewr
FATA[0014] Error response from daemon: Registration: "Wrong username format (it has to match "^[a-z0-9]{4,30}$")"

总结

至此Docker的HelloWorld就做完啦,后续一些其他的JavaWeb实验可能会用到Docker来进一步增强对Docker的认知,欢迎持续关注!


关注我,查看往期实验文章,也许会有你想要玩的东西~

Java后端开发技能Get:开启Docker的新世界——Hello Docker

重大发现!

关注三颗豆子分裂中的同学刚买了彩票就中奖

点赞评论三颗豆子分裂中文章的同学

刚写完代码就跑通

收藏转发三颗豆子分裂中文章的同学刚转身就遇到了真爱


分享到:


相關文章: