Docker思想
集装箱
保证程序不管在什么地方运行都不会缺东西。
标准化
运输方式标准化
Docker运输程序有一个超级码头,任何一个地方需要货物,都需要鲸鱼先送到超级码头,然后再由鲸鱼将货物从超级码头送到目的地去。从技术上来讲。就是将你台式机上的应用部署到笔记本上,可能通过网络传输或U盘拷贝的方式。
而Docker标准化了这个过程。 你只需要做的就是在你的台式机上执行一条Docker命名,将该应用打包送到超级码头去,再在笔记本上执行一条Docker命令,该应用即可从超级码头下载到本地。
存储方式的标准化
如果你讲程序从台式机拷贝到笔记本上,你要指定一个目录存放这个程序,你还需要记住这个目录,如果下次你改动了东西,你还要将改动的文件放到这个位置。
有了Docker之后就不需要这样了,因为存储方式标准化了,你不需要关心你的应用存在什么地方,你要运行它或者停止它的时候,只需要执行一条命令即可。
API接口标准化
Docker提供了一些列Restful API接口,包含对应用的一些控制。启动、停止、查看、删除等等。
当你启动你的程序的时候,你可能要执行tomcat的startup
命令,停止是也需要执行shutdown
命令。 如果是其他容器,还可能需要别的命令来控制。有了接口标准化之后,你就可以通过一样的命令来控制。
隔离
虚拟机有自己的CPU、内存容量、硬盘容量等,可以感觉不到外部主机的存在。Docker也有同样技术,而且更加轻量,可以实现快速的创建和销毁。必须创建一个虚拟机可能需要几分钟,而创建一个Docker容器只需要一秒。最底层的技术是Linux内核的限制机制:LXC
。LXC是一种轻量级的容器虚拟化技术,它最大效率的隔离了进程和资源,通过shellGroupNamespeace的限制隔离进程组所使用的物理资源,比如CPU、Memory、IO等等。
LXC为Linux Container的简写。可以提供轻量级的虚拟化,以便隔离进程和资源,而且不需要提供指令解释机制以及全虚拟化的其他复杂性。相当于C++中的NameSpace。容器有效地将由单个操作系统管理的资源划分到孤立的组中,以更好地在孤立的组之间平衡有冲突的资源使用需求
Docker解决了什么问题?
1.开发和生产环境一致
Docker将JDK、tomcat、应用等打包到一起。保证环境一致。
隔离应用之间最系统资源的占用
如服务器上一个应用在死循环,不会影响的其他应用。因为Docker启动的时候限制了这个应用所能占用的CPU、内存、硬盘。
临时扩展机器,应对高峰访问
可以快速在多台服务器上部署相同的应用。
Docker核心技术
Docker里面有三个核心词汇:
镜像:集装箱
仓库:超级码头
容器:应用运行环境。
Docker运行程序的过程:去仓库将镜像拉到本地,然后用命令将镜像运行起来,变成容器。
build:构建镜像
ship:在仓库和主机之间传输镜像。
run:运行镜像->容器
Docker镜像
Docker的镜像叫image。在Docker Logo上,鲸鱼运送的所有集装箱就是一个镜像。
从本质上来说,它就是一系列文件,它可以包括我们应用程序的文件,也可以包括我们应用运行环境的文件。
Docker仓库
公共仓库地址:
hub.docker.com
c.163.com
Linux安装Docker
Linux安装Docker 必须是64位操作系统,且Linux内核版本需大于3.10
因为Docker是使用ubuntu系统开发的,所以Ubuntur对Docke支持是最好的。
在centos和redhat上安装docker
前置条件
1.64-bit 系统
2.kernel 3.10+
1.检查内核版本,返回的值大于3.10即可。
$ uname -r
2.使用 sudo 或 root 权限的用户登入终端。
3.卸载旧版本(如果安装过旧版本的话)
$ yum remove docker \
docker-common \
docker-selinux \
docker-engine
4.安装需要的软件包
#yum-util提供yum-config-manager功能
#另外两个是devicemapper驱动依赖的
$ yum install -y yum-utils \
device-mapper-persistent-data \
lvm2
5.设置yum源
$ yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
6.安装最新版本
$ yum install -y docker-ce
7.安装指定版本
#查询版本列表
$ yum list docker-ce --showduplicates | sort -r
已加载插件:fastestmirror, langpacks
已安装的软件包
可安装的软件包
* updates: mirrors.163.com
Loading mirror speeds from cached hostfile
* extras: mirrors.163.com
docker-ce.x86_64 17.09.1.ce-1.el7.centos docker-ce-stable
docker-ce.x86_64 17.09.0.ce-1.el7.centos docker-ce-stable
...
#指定版本安装(这里的例子是安装上面列表中的第二个)
$ yum install -y docker-ce-17.09.0.ce
8.启动docker
$ systemctl start docker.service
9.验证安装是否成功(有client和service两部分表示docker安装启动都成功了)
$ docker version
Client:
Version: 17.09.0-ce
API version: 1.32
Go version: go1.8.3
Git commit: afdb6d4
Built: Tue Sep 26 22:41:23 2017
OS/Arch: linux/amd64
Server:
Version: 17.09.0-ce
API version: 1.32 (minimum version 1.12)
Go version: go1.8.3
Git commit: afdb6d4
Built: Tue Sep 26 22:42:49 2017
OS/Arch: linux/amd64
Experimental: false
在Ubuntu上安装Docker
1.更新系统
apt-get update
2.从Ubuntu软件仓库安装Docker
这种使用的是ubuntu软件仓库里的安装包,可能不是最新的Docker版本
apt-get install -y docker.io
3.安装Docker最新版本
该命令的意思是把Docker网页上的内容获取到,并作为sh执行
curl -s https://get.docker.com|sh
4.启动Docker
service docker start
5.查看安装的Docker版本
docker version
docker images[OPTIONS][REPOSITORY[:TAG]]
Docker镜像
拉取镜像
docker pull mysql
不指定版本和地址的话,会自动从docker仓库,拉取最后一个版本。
Docker容器
docker run [OPSTIONS] IMAGE[:TAG][COMMAND][ARG...]
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (amd64)
3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal.
运行nginx镜像
1.拉取nginx镜像
从网易云镜像中心获取:https://c.163yun.com/hub#/m/repository/?repoId=3181
运行命令:docker pull hub.c.163.com/public/nginx:1.2.1
2.运行该镜像
docker run -d nginx
-d参数表示后台运行
3.进入容器内部
docker exec -it 52c020cc0b6c bash
-t tty分配一个伪TTY, -i 交互式,即使未连接,也保持标准输入打开
Docker网络
网络类型
Docker是隔离性的,网络也是隔离性的一部分。Linux利用的namespace 命名空间来进行资源的隔离。如 pid namespace 就是用来隔离进程的。mark namespace就是用来隔离文件系统的。network namespace就是用来隔离网络的。每一份network namespace都提供了一套独立的网络环境。包括网卡,路由,iptable规则都与其他的network namespace隔离的。
Docker容器在默认情况下,都会分配一份独立的network namespace,也就是网络类型中的Bridge(桥接),还有一种网络模式是Host模式,如果启动容器的时候指定了模式为host模式,那么这个容器将不会获得一个独立的network namespace,而是和主机共同使用一个。这个时候容器将不会再虚拟出一个自己的网卡,配置自己的ip等等,而是会使用宿主机上的ip和端口,也就是再Docker上使用网络和在主机上使用是一样的。
还有另一种网络类型为:None(无网络),这种情况Docker容器将不会与外界任何东西进行通信。
在使用Bridge(桥接)时就会遇到一个问题,既然此时Docker容器使用的是一套独立的network namespace ,这就需要一种技术使容器中的端口可以在主机上访问,这种技术就是端口映射。
Docker可以指定你想把容器内的某一个端口可以在容器所在主机上的某一个端口做映射,当你在主机上访问此端口时,就是在访问容器里面的端口。
将nginx容器端口映射到宿主机上
docker run --name nginx-80 -d -p 80:80 nginx
--name 设置容器名字
-d 后台运行
-p 端口映射:前面的是主机上的端口,后面的是容器里的端口
-P 把容器所有端口随机映射到宿主机上
查看该端口的占用情况
netstat -na|grep 80
制作自己的镜像
Dockerfile:告诉Docker我要怎样制作镜像,我要制作镜像每一步操作是什么。
docker build:执行Dockerfile中所描述的每一步操作。
最后把我们自己的docker镜像制作出来。
已构建jPress为例。
jpress:http://jepress.io
它是wordpress的java版本。
从码云下载旧版war包构建:https://gitee.com/fuhai/jpress/tree/alpha/
编写Dockerfile
从docker hub找一个tomcat镜像下载下来作为基础镜像。
Dockerfile
# 这句话告诉docker我们要制作镜像, 以tomcat为基础
from tomcat
# 声明镜像的所有者
MAINTAINER hiseico xxx@163.com
# 拷贝主机上的war包到tomcat容器中的webapps目录下
COPY jpress.war /usr/local/tomcat/webapps
在Dockerfile目录下使用build命令构建
-t 给镜像指定名字:tag
# docker build -t jpress:latest .
Sending build context to Docker daemon 20.8MB
Step 1/3 : from tomcat
---> 5a069ba3df4d
Step 2/3 : MAINTAINER hiseico xxx@163.com
---> Running in 0a14e2ec9d25
Removing intermediate container 0a14e2ec9d25
---> 1191c0368896
Step 3/3 : COP Y jpress.war /usr/local/tomcat/webapps
---> 3173b3f4c163
Successfully built 3173b3f4c163
查看build的镜像
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
jpress latest 7133aedc480a 7 seconds ago 486MB
运行该镜像
docker run -d -p 8080:8080 jpress
访问
http://192.168.137.128:8080/jpress
安装Mysql数据库
docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=jpress mysql:latest
-e MYSQL_ROOT_PASSWORD=root
:设置数据库密码,默认用户名root
MYSQL_DATABASE=jpress
:创建数据库jpress