Docker简介
- docker 官网 : www.docker-cn.com
- 开源的应用容器引擎,基于 Go 语言,遵从 Apahce2.0 协议开源
- 通过 Docker 开发者可以将应用以及依赖包 打包成一个轻量级,可移植的容器中,然后发布到 Linux机器上,实现虚拟化
- 容器完全使用 沙箱机制,互相之间不会有任何接口,容器性能开销极低
Docker 引擎
- 用于运行和编排容器的基础设置工具
- Docker 引擎 是运行容器的核心
Docker 作用
- 将软件环境安装并配置好,打包成一个镜像Image,然后将该镜像发布出来(Docker仓库)
- 其他使用者可以在仓库中下载获取这个镜像
- 通过Docker 运行这个镜像,就可以获取同样的环境(容器)
Docker 技术优势
- Docker 容器的启动可以在秒级实现,相比传统虚拟机快的多
- Docker 对系统资源的利用率很高,一台主机上可以同时运行数千个 Docker 容器
- docker 不模拟硬件,而是使用宿主机的硬件内核,对进程进行隔离,运行应用程序
特性 | 容器 | 虚拟机 |
启动 | 秒级 | 分钟级 |
硬盘使用 | 一般为MB | 一般为GB |
性能 | 接近原生 | 弱于 |
系统支持量 | 单机 支持上千个容器 | 一般几十个 |
Docker 应用场景
- Web 应用的自动化打包和发布
- 自动化测试和持续集成、发布
- 在服务型环境中部署和调整数据库或其他的后台应用
- 从头编译或者扩展现有的 OpenShift 或 Cloud Foundry 平台来搭建自己的 PaaS 环境
基本术语
- Docker主机(host) — 安装了Docker程序的主机,运行Docker守护线程
- Docker镜像(Image)— 将软件环境打包好的模板,用来创建容器,一个镜像可以创建多个 模板
- Docker容器(Container)— 运行镜像后生成的实例,称为容器,每次运行一个镜像,就会产生一个容器,容器可以启动、停止、删除
- Docker 仓库(Repository) — 用来保存镜像,仓库中包许多镜像,每个镜像都有不同的标签 —— dockerhub(官方仓库)
- 使用Dockerde 步骤
1、安装Docker
2、从Docker 仓库中下载 软件对应的镜像
3、运行这个镜像、此时会生成一个Docker容器
4、对容器的 启动、停止就是对软件的启动和停止
远程连接服务器
- Linux 操作命令
# 1、查看服务器ip地址
ip addr # 在虚拟机中
# 2 连接服务器
# SSH 是Secure Shell的缩写,用于远程登陆访问协议
ssh "服务器账号"@"服务器地址", + "输入密码"
对Linux 服务器常用操作
# 1、查看 CPU 信息
cat/proc/cpuinfo
# 2、查看内存信息
cat/proc/meminfo
# 3、查看内核信息
uname -r # Docker 要求Centos 必须是 64 位,且内核是 3.10 及以上
# 4、重启
sudo rebboot # sodo 表示以管理员 root 身份执行
# 5、关机
sudo halt
Docker 软件安装
"""
使用 yum(基于rpm 的软件包管理工具)
用来安装软件包,可以 自动解决软件包之间的依赖关系
"""
# 软件包安装
yum install "软件包名"
# 软件包卸载
yum remove "软件包名"
# 设置 yum 源
$ sudo yum install -y yum-utils device-mapper-persistent-data lvm2 # 安装设置镜像源所需的依赖文件
$ sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo # 添加 yum 源地址
$ yum makecache fast # 更新 yum 源
# 安装 docker-ce(社区版) EE 为企业版
yum -y install docker-ce
启动 / 停止 docker
docker version # 查看版本
systemctl start docker # 启动
systemctl stop docker # 停止
systectl status docker # 查看状态
systectl restart docker # 重启
systemctl enable docker # 设置开机自动启动
# 验证、运行 hello_world
docker run hello-world # 下载hello-world 镜像并运行
# 查看客户端的所有命令选项
$ docker
# 了解指定的 Docker 命令使用方法
$ docker run --help # 查看 docer run 指令的具体使用方法
设置Docker 镜像加速
- 使用阿里云提供的镜像加速(镜像仓库),或其他云加速
- 1、注册并登陆"阿里云的开发者平台" http://dev.aliyun.com
- 2、查看专属的加速地址
- 3、配置自己的Docker加速地址
- 4、修改 文件种对应的地址即可
# 修改 文件种对应的地址即可
# 新建 daemon.json 文件
vi/etc/docker/daemon.json # 编辑/etc/docker/daemon.json 文件
# 在文件内容中输入内容
{
"registrymirrors": ["https://sswv6yx0.mirror.aliyuncs.com"]
}
# 重新启动
systemctl daemon-reload
# 重启 docker
systemctl restart docker
Docker 镜像相关命令
- 类似于虚拟机镜像、可以理解为一个只读模板
- 一个镜像中可以 包含一个基本的操作系统环境,里面仅安装了 Apache 应用程序
- 镜像是创建 Docker 容器的基础
- 通过版本管理和 增强的文件系统,来创建和更新现有的镜像,用户可以从网上直接下载应用 镜像使用
操作 | 命令 | 说明 |
查找 | docker search | 在Docker Hub网站查看镜像的详细信息,如镜像 tag 标签 |
抽取 | docker pull 镜像名:tag | :tag表示软件的版本,如果不指定默认的latest |
列表 | docker images | 查看本地所有镜像 |
获取元数据 | docker inspect 镜像id | 获取镜像元信息,详细信息 |
删除 | docker rmi -f 镜像id 或 镜像名:tag | 删除指定的本地镜像,-f 表示强制删除 |
#1、 查找镜像(从Docker Hub 上搜索镜像)
docker search [OPTIONS] TERM
docker search mysql
"""
OPTIONS说明:
1、automated : 仅显示自动构建 (不推荐使用)
2、filter , -f 根据提供的条件过滤输出
3、stars 收藏数量
4、is-automated(布尔值-true或false)是否自动构建
5、is-official(布尔值-true或false)是否官方
format 使用Go模板进行漂亮的打印搜索
limit (默认 25) 最多搜索结果数
no-trunc :显示完整的镜像描述;
stars ,-s :列出收藏数不小于指定值的镜像。 (不推荐使用)
"""
# 从镜像仓库中拉取或更新指定镜像 docker pull
docker pull [选项] NAME[:TAG]
docker pull mysql:5.5 # 拉取 mysql 5.5 版本
# 拖取(下载)镜像 —— 使用 nginx 官方版本的镜像
$ docker pull nginx
# 下载完成后 使用镜像
$ docker run -p 8702:80 nginx
"""
-a :拉取所有 tagged 镜像
--disable-content-trust :忽略镜像的校验,默认开启
NAME 是镜像仓库名称(用来区分镜像), TAG是镜像的标签(往往用来表示版本信息)
描述一个镜像需要包括“名称+标签”信息
"""
# 列出本地主机上的镜像
$ docker images / docker image ls
$ docker inspect "镜像ID" # 查看镜像元信息
"""
REPOSITORY:表示镜像的仓库源
TAG:镜像的标签
IMAGE ID:镜像ID
CREATED:镜像创建时间
SIZE:镜像大小
同一仓库源可以有多个 TAG,代表这个仓库源的不同个版本,如ubuntu仓库源里,有16.04,latest等多个不同的版本,我们使用 REPOSITORY:TAG 来定义不同的镜像
"""
# 删除本地一个或多个镜像
$ docker rmi [OPTIONS] IMAGE [IMAGE...]
$ docker rmi "镜像名/镜像ID"
"""
OPTIONS说明:
-f :强制删除;
--no-prune :不移除该镜像的过程镜像,默认移除;
IMAGE 可以是镜像名或者镜像ID
"""
# 清理镜像 —— 使用一段时间后,可能会遗留一些临时镜像文件,
$ docker image prune [选项]
"""
支持的选项:
-a, -all: 删除所有无用的镜像, 不光是临时镜像;
-filter filter: 只清理给定过滤器的镜像;
-f, -force: 强制删除镜像,而不进行提示确认。
"""
# 更新镜像
# 1、从已经创建的容器中更新镜像,并且提交这个镜像
# 2、使用 Dockerfile 指令创建押给新的镜像
"""
更新镜像之前,我们需要使用镜像船舰一个容器
在运行的容器内我们新增了一个文件hello.txt, 文件中填充文本 'hello w3cschool.'。
在完成操作之后,输入 exit命令来退出这个容器。
"""
$ docker run -it ubuntu:16.04 /bin/bash
root@951c28295c34:/# ls
root@951c28295c34:/# echo "hello w3cschool" >> hello.txt
# 通过 docker commit 来提交容器副本
$ docker commit -m="has update" -a="hello w3cschool" 951c28295c34 hellow3cschool/ubuntu:v1
sha256:6cd8e4fdf566eb48dfba3e4916c53d4fb7c30b9ab5c1aecbc1f76aacc0ed6190
"""
各个参数说明:
-m:提交的描述信息
-a:指定镜像作者
951c28295c34:容器ID
hellow3cschool/ubuntu:v1:指定要创建的目标镜像名
"""
# 查看新镜像
$ docker images
# 使用新镜像来启动容器
$ docker run -it hellow3cschool/ubuntu:v1 /bin/bash
root@655e5458c152:/#
# 为镜像添加新标签 docker tag
$ docker tag 5b722acb89ec loen/ubuntu:dev
容器
容器 是镜像的一个运行实例
- 镜像 是静态的只读文件,而容器带有 运行时需要的可写入文件层,同时,容器中应用进程处于运行状态
- 容器在镜像启动的时候,会在镜像的最上层创建一个可写层
- Docker 容器类似 于 押给轻量级的沙箱,Docker 利用容器来运行 和隔离应用
- 容器 可以 启动、开始、停止、删除、而这些容器都是 彼此隔离,互不可见的。
容器操作
操作 | 命令 | 说明 |
运行容器 | docker run -name 容器名 -i -t -p 主机端口号:容器端口号 -d -v 主机目录:容器目录 :ro 镜像id 或镜像名称:tag | name 指定容器名,名称自定义,如果不指定会自动命名; i 以交互模式运行,即以交互模式运行容器;t 分配一个伪终端,即命令行,通常组合使用it;p 指定端口映射,将主机端口映射到容器内的端口;d 表示后台运行,即守护式运行容器;v 指定挂载主机录到容器目录,默认为rw读写模式,ro表示只读 |
列表 | docker ps -a -q | 查看正在运行的容器,-a 表示显示所有容器,-q 表示只显示容器id |
启动 | docker start 容器id或容器名称 | 启动容器 |
停止 | docker stop 容器id或容器名称 | 停止正在运行的容器 |
删除 | docker rm -f 容器id 或容器名称 | 删除容器,-f 表示强制删除 |
日志 | docker logs 容器id或容器名称 | 获取容器日志 |
在容器中执行 | docker exec -it 容器id或容器名称 /bin/bash | 进入正在运行的容器中并开启一个交互模式的终端,可以在容器中执行操作,执行 bin 目录下的 bash文件 |
拷贝文件 | docker cp 主机中的文件路径 容器id或容器名称:容器路径:docker cp 容器id 或容器名称:容器中的文件路径 主机路径 | 将文件中文件拷贝到容器中;将容器中的文件拷贝到主机中 |
获取元信息 | docker inspect 容器id | 获取容器的元信息 |
Docker Hello World
Docker 可以在容器内运行应用程序,使用 docker run 命令来在容器内运行一个应用程序
$ docker run ubuntu:latest /bin/echo "Hello w3cschool"
Hello w3cschool
"""
解释为:Docker 以 ubuntu15.10 镜像创建一个新容器,然后在容器里执行 bin/echo "Hello world",然后输出结果。
**参数解析**
docker —— Docker的二进制执行文件
run —— 与 docker 组合来运行一个容器
ubuntul: latest —— 指定要运行的镜像,Docker 先在本地主机上查找镜像是否存在,若不存在,回从镜像仓库 Docker Hub 下载公共镜像
/bin/echo "Hello world" —— 在启动的容器里执行的命令
"""
容器运行方式
# 1、运行交互式容器
$ docker run -i -t ubuntu:latest /bin/bash
"""
各个参数解析:
-t: 在新容器内指定一个伪终端或终端。
-i: 允许你对容器内的标准输入 (STDIN) 进行交互。
"""
# 2、运行后台模式
# 创建以进程方式运行的容器
$ docker run -d ubuntu:latest /bin/sh -c "while true; do echo hello w3cschool; sleep 1; done"
# 输出 容器 ID
2d9bd5eba89d47e9e1196bab2c6ad6f9c5234a133b0f6b4512391e701d0933c9
# 查看容器内输出标准日志(日志输出)
$ docker logs 2d9bd5eba89d
# 通过容器名称查看输出日志
$ docker logs beautiful_easley
# 停止容器
$ docker stop 2d9bd5eba89d
$ docker stop beautiful_easley
# 运行Web容器
# 在docker 容器中运行 Python Flask 应用来运行 web 应用
# 载入应用
$ docker pull training/webapp
# 运行容器
$ docker run -d -p 5000:5000 training/webapp python app.py
"""
参数说明:
-d: 让容器在后台运行。
-p: 将容器内部使用的5000端口映射到我们使用的主机的5000端口上
"""
# 查看端口映射
$ docker ps
$ docker port b645f982a3c8
tomcat 为例
# 示例 1: 基本使用
docker search tomcat
docker pull tomcat
docker run --name mytomact -p 8888:8080 -d tomcat # 运行容器
# 测试 http:// 宿主机地址:8888
docker stop mytomcat
docker ps -a # 查看正在运行容器,显示所有容器
docker start mytomcat # 启动容器
# 示例 2 :拷贝文件和挂载目录
docker run -p 8080:8080 -d tomcat
docker exec -it 70cba924861c/bin/bash # 进入正在运行的容器中,开启交互模式终端,在容器中执行 /bin/bash 命令
cd /usr/locak/tomcat/webapps/ROOT
exit # 退出容器
# echo 新建文件内容 写入目标文件
echo welcome to tomcat > index.jsp # 宿主机中新建一个index.jsp 文件,并写入 welcome to tomcat
docker cp index.jsp 70cba924861c:/usr/local/tomcat/webapps/ROOT # 将宿主机的文件拷贝到 指定容器的目录中
# 部署 web 项目,将 war 文件复制到容器中
docker cp spring-web.war 70cba924861c:/usr/local/tomcat/webapps
#挂载目录(数据卷) 容器读取宿主机的某个文件、一旦宿主机中文件变化、则容器中的文件跟着变化
# -v 挂载 宿主机目录:容器目录
docker run \
-p 8080:8080 \
-v /my/tomcat/webapps/spring-web.war:/usr/local/webapps/spring-web.war\
-d tomact
查看WEB 应用程序日志 + 命令
# 查看容器内部的标准输出
$ docker logs -f b645f982a3c8
# -f: 让 docker logs 像使用 tail -f 一样来输出容器内部的标准输出
# 查看容器内部的进程
$ docker top b645f982a3c8
# 查看容器的详细信息,返回 JSON 文件
$ docker inspect b645f982a3c8
# 在运行的容器中执行命令
$ docker exec [选项] CONTAINER COMMAND [ARG...]
"""
选项说明:
-d :分离模式: 在后台运行
-i :即使没有附加也保持STDIN 打开
-t :分配一个伪终端
CONTAINER 可以是容器名称也可以是容器ID
"""
$ docker exec -it mynginx /bin/bash # 在容器 mynginx 中开启一个交互模式的终端
# 停止 Web 应用程序
$ docker stop nifty_carson
# 重启 web 应用程序
$ docker start nifty_carson
$ docker restart # 正在运行的容器
# 查看最后一次创建的容器
$ docker ps -l
# 移除 WEB 应用容器
$ docker rm nifty_carson
# 容器自定义命名 --name 参数来为容器取名
$ docker run -d -P --name helloserver training/webapp python app.py
**# 网络端口映射**
# -p : 是容器内部端口绑定到指定的主机端口
$ docker run -d -p 5000:5000 training/webapp python app.py
# 容器绑定的网络地址,比如绑定 127.0.0.1
$ docker run -d -p 127.0.0.1:5001:5000 training/webapp python app.py # 可以通过访问 127.0.0.1:5001 来访问容器的 5000 端口
# 默认为 tcp协议 ,指定 UDP
$ docker run -d -p 127.0.0.1:5001:5000/udp training/webapp python app.py
镜像的分层结构
- 镜像是一个轻量级,可独立执行的软件包,用来打包软件运行环境和基于运行环境的软件,包含运行某个软件所需要的所有内容
- 基于 UnionFS 联合文件系统,采用分层堆叠起来。
- 整体包括 内核(使用本机内核)、操作系统、JDK、软件包
- 分层结构 :共享资源,便于复用(许多镜像都从相同的Base基础镜像构建而来,基础镜像只需要保存一份即可)
创建镜像
- 更新镜像 : 使用docker commit命令
- 构建镜像 : 使用docker build命令,需要创建 dockerfile 文件。
更新镜像
- 先使用基础镜像创建一个容器,然后对容器进行修改,最后使用commit命令提交一个新的镜像
- 1、根据基础镜像,创建容器
- 2、修改运行容器 (进入容器中,修改需要更新的文件)
- 3、提交修改后的容器,生成新的镜像 , docker commit -m=“描述信息” -a=“作者” 容器ID或容器名称 镜像名:tag
- 4、运行新的镜像
# 根据镜像创建基础容器
docker run --name mytomcat -p 8080:8080 -d tomcat
# 修改容器
docker exec -it "容器ID" /bin/bash
cd webapps/Root
rm -f index.jsp
echo welcome to tomacat > index.html
exit
# 提交为新的镜像
docker commit -m="描述信息" -a="作者" "容器ID或容器名称" "镜像名":tag
构建镜像
- 根据 dockerfile 文件来 自动构建文本文件
- dockerfile 文件是一个包含创建镜像所有命令的文本文件,使用 docker build 根据dockerfile文件内容进行创建
Dockerfile文件内容
# 每个指令的前缀都需要大写
# 指定基础镜像
FROM ubuntu:16.04 # 指定使用马哥镜像源
# 指定作者(维护者)
MAINTAINER Loen "425389019@qq.com"
# 执行命令
RUN rm -f "需要修改的文件路径/index.jsp"
RUN echo 'hello w3cschool, this is v2' >> hello.txt # 在镜像内执行命令,安装了什么
# 构建镜像
$ docker build -t hellow3cschool/ubuntu:v2
# -t :指定要创建的目标镜像名
# Dockerfile 文件所在目录,可以指定Dockerfile 的绝对路径
$ docker run hellow3cschool/ubuntu:v2
Dockerfile详解
语法规则
- 指令必须大写,且后面必须根参数
- 第一条指令是 FROM,指定 Base Image 基础镜像
- 指令从上向下依次执行
- 每条指令都会创建一个新得镜像层并提交
表示注释
常用指令
指令 | 含义 |
FROM | 执行基础镜像,即当前新镜像是基于哪个镜像 |
MAINTAINER | 指定作者 |
RUN | 指定构建过程中要运行的命令 |
ENV | 设置环境变量 |
WORKDIR | 指定默认的工作目录,即进入容器后默认进入的目录 |
VOLUME | 创建挂载点(数据卷),用于数据共享 |
CMD | 指定容器启动时要运行的命令,与RUN不同的是,这些命令不是在镜像构建过程种执行的 |
ENTRYPOINT | 指定容器启动时要运行的命令 |
COPY | 拷贝文件/目录到镜像中 |
ADD | 拷贝文件到镜像中,会自自动解压 |
EXPOSE | 指定对外暴扣的端口 |
文件案例
FROM centos
MAINTAINER lcl
# 定义环境变量
ENV MYPATH /usr/local/centos
# 创建变量文件
RUN mkdir -p $MYPATH
# 指定进入目录
WORKDIR $MYPATH
# 设置默认安装需要的软件
RUN yum -y install vim
# 创建挂载点(无法指定宿主机对应目录),目录是自动生成的
# 创建2个挂载点,宿主机的文件目录自动生成
VOLUME ["/data1","/data2"]
# 指定容器启动时执行命令
CMD ["/bin/bash"]
# 通过 Dockerfile 文件进行生成镜像
docker build -f Dockerfile2 -t itany/centos:v1
# 使用docker run运行容器
docker run -it "容器ID"
# 查看镜像变更历史
docker history "容器id"
CMD命令
- Dockerfile 中只能有一条CMD指令,如果列出多个,则执行 最后一个
- CMD 主要目的是运行容器时提供默认值
- CMD 指令会被 docker run 之后的参数覆盖
ENTRYPOINT
- ducker run 不会覆盖 ENTRYPOINT 指令,而是两者组合形成新的命令
自定义tomcat镜像
# 1、编写Dockerfile文件
vi Dockerfile
FROM centos
MAINTAINER lichunlei
# 拷贝文件,文件需要与 Dockerfile 在同一目录下
COPY fileone.txt /usr/local
ADD JDK...tar.gz /usr/local
# 配置环境变量
ENV JAVA_HOME /usr/local/jdk.1.0
ENV CLASSPATH .:$JAVA_HOME/lib
WORKDIR $CATAINA_HOME
RUN yum -y install vim
EXPOST 8080
CMD ["执行命令"]
服务类 : Nginx Mongo
开发类 : Python golang
操作系统类 : Alpine,Ubuntu
LABEL指令
指定一个镜像的描述信息,一个镜像可以有多个LABEL
将元数据添加到镜像中
LABEL 是一个键值对
要在LABEL值中包含空格,请像在命令行解析中一样使用 引号和续行符.
LABEL maintainer=“425389019@qq.com”
LABEL “com.example.vendor”=“ACME Incorporated”
LABEL com.example.label-with-value=“foo”
LABEL version=“1.0”
LABEL description=“This text illustrates
that label-values can span multiple lines.”
查看 LABEL 信息
$ docker inspect
ENV 指令
用于设置环境变量
格式有两种
ENV
ENV = =…
ENV VERSION=1.0 DEBUG=on
NAME=“Happy New Year”
RUN 指令
容器内执行 shell 命令,默认会用 /bin/sh-c 的方式执行
执行命令的两种方式
RUN (shell形式,该命令在shell中运行)
RUN [“executable”, “param1”, “param2”](exec形式)
RUN /bin/bash -c ‘source $HOME/.bashrc;
echo $HOME’
FROM alpine
ENV name=“yangge”
RUN ["/bin/sh", “-c”, “/bin/echo $name”] # 一定要指明路径
Dockerfile 中只能有一条CMD指令,如果列出多个,则执行 最后一个
CMD 主要目的是运行容器时提供默认值
容器就是进程,CMD 指令就是 用于 指定默认的容器主进程启动命令
在启动一个容器时,可以指定新的命令来替代镜像设置中的默认命令
CMD 指令格式
- shell 格式:CMD <命令>
- exec 格式:CMD [“可执行文件”, “参数1”, “参数2”…]
- 参数列表格式:CMD [“参数1”, “参数2”…]。在指定了 ENTRYPOINT 指令后,用 CMD 指定具体的参数