docker安装+配置镜像+命令操作+数据卷+网络管理+DockerFile+镜像服务+项目部署+[高级使用]
Posted ahcfl
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了docker安装+配置镜像+命令操作+数据卷+网络管理+DockerFile+镜像服务+项目部署+[高级使用]相关的知识,希望对你有一定的参考价值。
文章目录
Docker基础
一、Docker介绍
1. 什么是虚拟化
在计算机中,虚拟化(英语:Virtualization)是一种资源管理技术,是将计算机的各种实体资源,如服务器、网络、内存及存储等,予以抽象、转换后呈现出来,打破实体结构间的不可切割的障碍,使用户可以比原本的组态更好的方式来应用这些资源。这些资源的新虚拟部份是不受现有资源的架设方式,地域或物理组态所限制。一般所指的虚拟化资源包括计算能力和资料存储。
在实际的生产环境中,虚拟化技术主要用来解决高性能的物理硬件产能过剩和老的旧的硬件产能过低的重组重用,透明化底层物理硬件,从而最大化的利用物理硬件 对资源充分利用
虚拟化技术种类很多,例如:软件虚拟化、硬件虚拟化、内存虚拟化、网络虚拟化(vip)、桌面虚拟化、服务虚拟化、虚拟机等等。
2. 什么是Docker
Docker 是一个开源项目,诞生于 2013 年初,最初是 dotCloud 公司内部的一个业余项目。它基于 Google 公司推出的 Go 语言实现。 项目后来加入了 Linux 基金会,遵从了 Apache 2.0 协议,项目代码在 GitHub 上进行维护。Docker项目后来加入了 Linux 基金会,并成立推动 开放容器联(OCI)。
其基于 Linux 内核的 cgroup,namespace,以及 OverlayFS 类的 Union FS 等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。最初实现是基于 LXC,从 0.7 版本以后开始去除 LXC,转而使用自行开发的 libcontainer,从 1.11 开始,则进一步演进为使用 runC 和 containerd。
Docker 在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极大的简化了容器的创建和维护。使得 Docker技术比虚拟机技术更为轻便、快捷。
3. 容器与虚拟机比较
容器是在操作系统层面上实现虚拟化,直接复用本地主机的操作系统,而传统方式则是在硬件层面实现。
虚拟机: 虚拟机是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;
**Docker:Docker没有虚拟的硬件,也没有模拟操作系统,而是直接运行在宿主机上。**Docker会为每个应用进程形成隔离环境,让的应用进程以为自己是独立机器。因此Docker要比传统虚拟机更为轻便。
4. Docker优势
与传统的虚拟机相比,Docker优势体现为启动速度快、占用体积小。
特性 | Docker容器 | 虚拟机 |
---|---|---|
启动 | 秒级 | 分钟级 |
硬盘使用 | 一般为 MB | 一般为 GB |
性能 | 接近原生 | 弱于 |
系统支持量 | 单机支持上千个容器 | 一般几十个 |
5. Docker架构
Docker是一个客户端-服务器(C/S)架构程序。Docker客户端(client)只需要向Docker服务器或者后台进程发出请求,服务器或者后台进程将完成所有工作并返回结果。
Docker中有三个很重要的概念:
- 镜像(
Image
) - 容器(
Container
) - 仓库(
Repository
)
理解了这三个概念,就理解了 Docker 的整个生命周期。
【1】镜像服务(Image
)
Linux的操作系统分为内核和用户空间。对于 Linux 而言,内核启动后,会挂载 root
文件系统为其提供用户空间支持。
而 Docker 镜像(Image),就相当于是一个 root
文件系统。比如官方镜像 ubuntu:18.04
就包含了完整的一套 Ubuntu 18.04 最小系统的 root
文件系统。
**Docker 镜像是一个特殊的文件系统,**除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变,是一个只读的模板
。
简单来说:镜像就像你下载并安装好的一个游戏,比如《我的世界》,其中包含了运行所需要的jre库。因此这个游戏可以放到任何机器上运行。
镜像服务:
管理存放镜像的位置,用于共享镜像文件
官方: https://hub.docker.com/
阿里: https://www.aliyun.com/
仓库:
每一种软件对应一个仓库,在仓库中存放有当前软件不同版本的各个镜像
不同版本使用tag区分
eg:
mysql:5.6 mysql:5.7.25
【2】容器(Container
)
镜像(Image
)和容器(Container
)的关系,就像是面向对象程序设计中的 类
和 实例
一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
容器的实质是进程,但与直接在宿主执行的进程不同,Docker会保证隔离每一个容器进程。
容器进程运行于属于自己的独立的 命名空间。因此容器可以拥有自己的 root
文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样。**这种特性使得容器封装的应用比直接在宿主运行更加安全。**也因为这种隔离的特性,很多人初学 Docker 时常常会混淆容器和虚拟机。
【3】镜像仓库(Docker Registry
)
镜像构建完成后,可以很容易的在当前宿主机上运行,但是,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry 就是这样的服务。
一个 Docker Registry 中可以包含多个 仓库(Repository
);每个仓库可以包含多个 标签(Tag
);每个标签对应一个版本的镜像。
通常,一个仓库(Repository
)会包含同一个软件不同版本的镜像(image
),而标签(Tag
)就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签>
的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest
作为默认标签。
以nginx镜像为例。我们可以通过 nginx:1.7.9
,或者 nginx:1.8.0
来具体指定所需哪个版本的镜像。如果忽略了标签,比如 nginx
,那将视为 nginx:latest
最新版本的。
仓库名经常以 两段式路径 形式出现,比如 jwilder/nginx-proxy
,前者往往意味着 Docker Registry 多用户环境下的用户名,后者则往往是对应的软件名。
仓库分为公开仓库(Public)和私有仓库(Private)两种形式。
最常使用的 Registry 公开服务是官方的 Docker Hub,这也是默认的 Registry,并拥有大量的高质量的官方镜像,供用户下载。国内也有一些云服务商提供类似于 Docker Hub 的公开服务。
比如 网易云镜像服务、DaoCloud 镜像市场、阿里云镜像库 等。
除了使用公开服务外,用户还可以在本地搭建私有 Docker Registry。
当用户创建了自己的镜像之后就可以使用 push 命令将它上传到公有或者私有仓库,这样下次在另外一台机器上使用这个镜像时候,只需要从仓库上 pull 下来就可以了。
6. 直击Docker的作用
技术存在的必然性,一个技术的存在都是为了解决指定的问题.
#什么是镜像?
将Linux程序基于运行环境打包,就是镜像,特征:
只读
分层,每一层都基于前一层,层称为Layer
#什么是容器?
容器是镜像运行的一个实例。
是将镜像做只读拷贝后创建一层可写的Layer层,然后创建独立内存、网络等空间并运行。
特征:
容器是宿主机的一个独立进程。
多个容器间相互独立
容器操作不影响镜像
#Docker作用?
软件或程序环境迁移
二、Docker安装与配置
Docker 分为 CE 和 EE 两大版本。CE 即社区版(免费,支持周期 7 个月),EE 即企业版,强调安全,付费使用,支持周期 24 个月。
Docker CE 分为 stable
test
nightly
三个更新频道。
官方网站上有各种环境下的 安装指南,这里主要介绍 Docker CE 在 Linux
和 macOS
上的安装。
Docker CE 支持 64 位版本 CentOS 7,并且要求内核版本不低于 3.10, CentOS 7 满足最低内核的要求。
1. 卸载旧版docker
这里的 \\
是换行的作用
yum remove docker \\
docker-client \\
docker-client-latest \\
docker-common \\
docker-latest \\
docker-latest-logrotate \\
docker-logrotate \\
docker-selinux \\
docker-engine-selinux \\
docker-engine \\
docker-ce
2. 安装docker依赖
# 安装基本依赖库
yum install -y yum-utils device-mapper-persistent-data lvm2 --skip-broken
# 更新XFS文件系统管理工具
yum update xfsprogs -y
3. 安装docker
# 更新本地镜像源
yum-config-manager --add-repo https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo
# 更新镜像源缓存
sed -i 's/download.docker.com/mirrors.ustc.edu.cn\\/docker-ce/g' /etc/yum.repos.d/docker-ce.repo
# 更新镜像源缓存
yum makecache fast
# 安装Docker
yum install -y docker-ce
4. 启动docker服务
启动服务前先关闭防火墙
# 查看防火墙状态
systemctl status firewalld
# 关闭本地防火墙
systemctl stop firewalld
# 禁止开机启动防火墙
systemctl disable firewalld
# 启动docker服务
systemctl start docker
# 设置开机自启动
systemctl enable docker
5. 配置镜像加速
Docker官方镜像仓库网速较差,我们需要设置国内镜像:
参考阿里云的镜像加速文档:阿里云镜像管理地址(https://www.aliyun.com/)
# 创建配置文件
mkdir -p /etc/docker
# 配置镜像加速地址 (填写自己阿里云下的镜像加速地址)
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://7n40e80k.mirror.aliyuncs.com"]
}
EOF
# 重新加载配置并重启Docker
systemctl daemon-reload
systemctl restart docker
注:
有的可能出现配置镜像错误的原因:etc目录下没有docker目录,
此时需要先在etc目录下创建docker文件夹,然后再对daemon。json进行修改。
# 观察镜像是否生效
docker info
三、Docker相关命令
系统服务管理docker
# 启动docker
systemctl start docker
# 停止docker
systemctl stop docker
# 重启docker
systemctl restart docker
# 查看docker状态
systemctl status docker
# 开机启动
systemctl enable docker
1. 镜像操作
操作Docker镜像的常用命令有:
docker --help # 查询帮助
docker xxx --help # 查询xxx命令的作用和使用方式★★★★★
docker search # 在镜像仓库搜索镜像
docker pull # 从镜像仓库拉取镜像
docker pull 镜像名称:tag
docker push # 将本地镜像推送到远程镜像库
docker images # 查看本地镜像列表
docker rmi 镜像名称:tag # 删除本地镜像
docker save # 保存镜像为一个tar文件
docker load # 加载本地tar文件中包含的镜像
docker build # 构建一个镜像
docker tag # 给镜像打新标签
# 删除所有镜像, 谨慎使用
docker rmi `docker images -q`
例如:
需求1:从镜像仓库中拉取一个nginx镜像
# 1.首先去镜像仓库搜索nginx镜像
# 2.根据镜像名称搜索,相关镜像对应的拉取命令
docker pull nginx
# 3.查看拉取到的镜像
docker images
需求2:去DockerHub搜索并拉取一个Redis镜像
docker pull redis // 不写tag,默认最新
# 1.查询docker tag命令的作用和语法
docker tag --help
# 2.使用docker tag打包镜像
docker tag redis:latest myredis:1.0
# 3.使用docker save将镜像打入到tar包中,便于传播
docker save -o myredis.tar myredis:1.0
# 加载本地tar文件中包含的镜像
docker load -i 文件名.tar
2. 容器操作
操作Docker容器的常用命令有:
docker run --name mn -p 80:80 -d 镜像名称 # 创建并运行容器
--name 容器名称
-p 端口映射
-d 后台运行
docker stop 容器名称 # 停止容器
docker start 容器名称 # 启动容器
docker restart 容器名称(或者容器ID) # 重启容器
docker pause # 暂停容器
docker unpause # 恢复容器
docker ps # 查看运行中的容器
docker ps -a # 查看所有容器
docker ps –l # 查看最后一次运行的容器
docker ps -f status=exited # 查看停止的容器
docker rm 容器名称 # 删除容器
docker rm -f 容器名称 # 强制删除容器(无论运行与否)
docker exec # 执行容器内的指定指令
docker commit # 提交一个容器为镜像
docker logs -f 容器名称(或容器ID) # 查看容器运行日志
说明:
-i:表示运行容器
-t:表示容器启动后会进入其命令行。加入这两个参数后,容器创建就能登录进去。即分配一个伪终端。
--name :为创建的容器命名, **必须是唯一的**。
-v:表示目录映射关系(前者是宿主机目录,后者是映射到宿主机上的目录),
可以使用多个-v做多个目录或文件映射。注意:最好做目录映射,在宿主机上做修改,
然后共享到容器上。
-d:在run后面加上-d参数,则会创建一个**守护式容器**在后台运行(这样创建容器后不会自动登录容器,
如果只加-i -t两个参数,创建后就会自动进去容器)。
-p:表示**端口映射**,前者是宿主机端口,后者是容器内的映射端口。
可以使用多个-p做多个端口映射
例如:
需求1:创建并运行一个Nginx容器
# 1.创建并运行一个Nginx容器的命令为:
docker run --name myn -p 80:80 -d nginx
# 命令解读:
# docker run :创建并运行一个容器
# --name : 给容器起一个名字,比如叫做myn
# -p :端口映射,例如:-p 80:80,把容器的80端口映射到宿主机的80端口
# -d:后台运行容器
# nginx:镜像名称
# 2.访问虚拟机页面 http://[你的虚拟机IP]
192.168.182.140:80
需求2:进入Nginx容器,修改html文件内容,添加“Hello Nginx”
# 创建并运行nginx容器
docker run \\
--name myn \\
-p 80:80 \\
-d \\
nginx
# 1.进入nginx容器的命令为
docker exec -it mn bash
#命令解读:
# docker exec :进入容器内部执行
# -it : 给当前进入的容器创建一个Linux命令行终端,允许我们通过命令行与容器交互
# myn :要进入的容器的名称
# bash:进入容器后执行的命令,bash是一个linux终端交互语言格式
# 2.进入nginx的HTML所在目录 /usr/share/nginx/html (此目录去官网查找)
cd /usr/share/nginx/html
# 3.修改index.html的内容为 Hello Nginx:
sed -i 's#Welcome to nginx#Hello Nginx#g' index.html
sed -i 's#<head>#<head><meta charset="utf-8">#g' index.html
# 4.退出容器的客户端
exit
需求3:运行一个redis容器,并且支持数据持久化
#1.到DockerHub搜索Redis镜像
#2.查看Redis镜像文档中的帮助信息
#3.利用docker run 命令运行一个Redis容器
docker run --name 容器名称 -p 6379:6379 -d redis redis-server --appendonly yes
# redis持久化机制:
RDB: 默认开启的(快照机制)
AOF: 手动配置
需求4:进入redis容器,并执行redis-cli客户端命令,存入num=996
#1.进入redis容器
docker exec -it 容器名称 bash
#2.执行redis-cli客户端命令
redis-cli
#3.设置数据num=666
set num 666
3. 其他操作
创建容器三种方式【了解】
#(1)交互式方式创建容器
docker run -it --name 容器名称 镜像名称:标签 /bin/bash
docker run -it --name=mycentos1 centos:7 /bin/bash
这时我们通过ps命令查看,发现可以看到启动的容器,状态为启动状态
#(2)守护式方式创建容器
docker run -di --name 容器名称 镜像名称:标签
docker run -di --name=mycentos2 centos:7
#(3)登录守护式容器方式
docker exec -it 容器名称 (或者容器ID) /bin/bash
文件拷贝与挂载
# 拷贝到容器
docker cp 需要拷贝的文件或目录 容器名称:容器目录
# 从容器中拷贝出
docker cp 容器名称:容器目录 需要拷贝的文件或目录
# 目录挂载
# --privileged=true 代表的是多级文件夹下的权限访问问题
docker run -di -v /usr/local/myhtml:/usr/local/myhtml --privileged=true --name=mycentos3 centos:7
说明:
如果共享的是多级的目录,可能会出现权限不足的提示,
因为CentOS7中的安全模块selinux把权限禁掉了,
我们需要添加参数 --privileged=true来解决挂载的目录没有权限的问题
查看容器IP地址
# 查看容器IP地址
# 查看容器运行的各种数据
docker inspect 容器名称(容器ID)
# 直接查看IP地址
docker inspect --format='{{.NetworkSettings.IPAddress}}' 容器名称(容器ID)
打包加载与备份
# 容器保存为镜像
# my-nginx 容器名称, mynginx_i 自定义镜像名称
docker commit my-nginx mynginx_i
# 镜像备份(镜像保存为tar 文件)
docker save -o [文件名] IMAGE [IMAGE...]
docker save -o mynginx.tar mynginx_i
# 镜像恢复与迁移 执行后再次查看镜像,可以看到镜像已经恢复
docker load -i mynginx.tar
四、数据卷
1. 数据卷的概念
【1】为什么引入数据卷
【2】数据卷的特征
【3】数据卷的原理
数据卷
是一个可供一个或多个容器使用的特殊目录,一般是在宿主机的某个特定的目录下。
把变化的数据记录在容器之外的宿主机上,实现容器与数据的分离。
可以提供很多有用的特性:
数据卷
可以在容器之间共享和重用- 对
数据卷
的修改会立马在挂载数据卷的容器中可见 - 对
数据卷
的更新,不会影响镜像 数据卷
默认会一直存在,即使容器被删除
通过docker volume
命令可以管理数据卷。
2. 数据卷操作命令
数据卷是一个虚拟的概念,一个数据卷指向宿主机上的一个文件夹
#创建数据卷
docker volume create 数据卷名称
#查询数据卷信息
docker volume inspect 数据卷名称
#查询所有数据卷基本信息
docker volume ls
#删除未使用的数据卷
docker volume prune
#删除数据卷
docker volume rm 数据卷名称
#挂载数据卷 (建立数据卷与容器目录的对应关系)
举例1:
docker run \\
--name mn \\
-v html:/root/html \\
-p 8080:80
nginx
# 说明:
# docker run :就是创建并运行容器
# --name myn :给容器起个名字叫myn
# -v html:/root/htm :挂载html数据卷 到容器内的/root/html目录
# -p 8080:80 :把宿主机的8080端口映射到容器内的80端口
# nginx :镜像名称
访问:http://虚拟机ip:8080
举例2:
docker run --name my-nginx -p 8888:80
-v html:/usr/share/nginx/html
-v $PWD/nginx.conf:/etc/nginx/nginx.conf
--privileged=true
-d nginx
# 命令数名:
`--name my-nginx`:容器名称为my-nginx
`-p 80:80`:将容器的80端口映射到宿主机的80端口
`-v html:/usr/share/nginx/html`:挂载html数据卷 到容器的`/usr/share/nginx/html`目录
`-v $PWD/nginx.conf:/etc/nginx/nginx.conf`:
`$PWD/nginx.conf`:当前目录下的nginx.conf文件
把宿主机当前目录下的`nginx.conf`文件挂载到容器内的`/etc/nginx/nginx.conf`文件
`--privileged`:授予本地目录的访问权限
`-d`:后台运行
`nginx`:镜像名称
访问:http://虚拟机ip:8888
例如:
需求1:创建 html数据卷,并查看数据卷在宿主机的目录位置
#1.创建数据卷
docker volume create html
#2.查看所有数据卷
docker volume ls
#3.查看数据卷详细信息
docker volume inspect html
需求2:创建一个nginx容器,挂载数据卷html上到容器内的html目录,并修改html数据卷中的index.html内容
#1.首先到DockerHub的Nginx页面查看HTML目录在容器内的位置
#2.创建容器并挂载数据卷到容器内的HTML目录
docker run \\
--name mn \\
-v html:/usr/share/nginx/html \\
-p 80:80 \\
-d \\
nginx
#3.进入HTML数据卷所在位置,并修改HTML内容
# 查看html数据卷的位置
docker volume inspect html
# 进入该目录
cd /var/lib/docker/volumes/html/_data
# 修改文件
vi index.html
需求3:挂载到宿主机文件覆盖nginx容器内配置文件,并修改内容。实现一个方向代理效果:http://localhost:80/bd 请求代理到 http://www.baidu.com
#1.去DockerHub的Nginx页面查看配置文件在容器内的位置
容器中配置文件位置: /etc/nginx/nginx.conf
#2.在宿主机的/tmp目录新建一个nginx.conf文件,编写反向代理逻辑
cd /tmp
touch nginx.conf
参考下面配置
#3.创建nginx容器,挂载/tmp/nginx.conf到容器内的nginx配置文件
# 删除旧容器
docker rm -f mn
# 创建新容器,挂载nginx.conf文件
docker run \\
--name mn \\
-v html:/usr/share/nginx/html \\
-v /tmp/nginx/nginx.conf:/etc/nginx/nginx.conf \\
-p 80:80 \\
-d \\
nginx
#4.在浏览器查看访问
http://虚拟机ip/bd
/tmp/nginx.conf 下编辑:
下面配置错误 缺少一些参数
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location /bd {
proxy_pass https://www.baidu.com;
}
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
}
五、网络管理操作
当我们要部署基于docker的微服务群时,往往会需要容器之间互相连接。这时就需要用到Docker中的网络配置了。通过docker network
命令可以管理docker网络。
集群: 多台服务器做相同的事情
分布式: 多台服务器做不同的事情,在共同协作下完成一个具体的业务
#创建一个名为my-net的网络(名称可以自定义)
docker network create my-net
#将指定容器加入到my-net网络
docker network connet my-net 容器名称
#将一个容器退出(断开)指定的网络
docker network disconnect 网络名称 容器名称
#查看网络的详细信息,如IP网段等
docker network inspect 网络名称
#列出所有的网络
docker network ls
#删除所有未使用的网络
docker network prune
#删除所有指定的网络
docker network rm 网络名
例如:
需求1:创建一个网络my-net,并且将之前的nginx容器加入网络中
#1.创建一个名为my-net的网络
docker network create my-net
#2.查看创建的网络
docker network ls
#3.查看网络加入语法
docker network connect --help
#4.将nginx容器加入网络
docker network connect my-net myn
需求2:基于busyBox镜像创建并运行一个容器,加入my-net网络,测试与nginx容器的网络是否畅通
1.基于BusyBox镜像创建容器,并使用--network参数加入my-net网络
docker run -it --rm --name busybox1 --network my-net busybox sh
# 命令说明:
# -it 运行容器并保持一个可交互的shell终端
# --rm 容器退出时,自动删除容器
# --network my-net 连接到my-net网络
# busybox 是一个测试用的简单容器
# sh 终端交互方式采用sh方式
#2.通过ping命令测试网络连接,同一个网络中的容器可以用容器名互联
ping ip地址
注:
- 创建容器时的 --network 参数允许我们直接加入一个网络中
- 互联的容器可以利用容器名互相访问
六、DockerFile自定义镜像
在前面镜像原理的中,我们可以了解到,镜像的本质是一层层的Layer。
基于一个rootfs这个基础的Layer定制每一层所添加的配置、文件,要执行的操作等。
如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,
那么这个脚本就是 Dockerfile。
因此,Dockerfile就是一个描述镜像构建的文件。其中一定会有一个基础镜像(BaseImage),
然后在基础镜像上每完成一次修改或安装命令,就形成一层新的Layer,直到镜像构建完成。
作用:
-
对于开发人员:可以为开发团队提供一个完全一致的开发环境;
-
对于测试人员:可以直接拿开发时所构建的镜像或者通过Dockerfile文件构建一个新的镜像开始工作了;
-
对于运维人员:在部署时,可以实现应用的无缝移植。
DockerFile参考指令:https://docs.docker.com/engine/reference/builder
命令 | 作用 |
---|---|
FROM image_name:tag | 定义了使用哪个基础镜像启动构建流程 |
MAINTAINER user_name | 声明镜像的创建者 |
ENV key value | 设置环境变量 (可以写多条) |
RUN command | 是Dockerfile的核心部分(可以写多条) |
ADD source_dir/file dest_dir/file | 将宿主机的文件复制到容器内,如果是一个压缩文件,将会在复制后自动解压 |
COPY source_dir/file dest_dir/file | 和ADD相似,但是如果有压缩文件并不能解压 |
WORKDIR path_dir | 设置工作目录 |
例如:
需求1:基于Nginx镜像构建一个新镜像,修改其中的index.html文件
#1.在一个空文件夹新建一个文件,命名为Dockerfile,内容如下
# 创建空文件夹
mkdir /tmp/nginxfile
# 进入空文件夹
cd /tmp/nginxfile
# 创建Dockerfile文件【文件名不能是其他】
vi Dockerfile
-----------------
FROM nginx:1.20.1
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
-----------------
#2.在当前目录下执行命令,构建镜像【. 表示当前目录】
docker build -t mynginx:1.20.1 .
#3.创建并运行容器
docker run --name mn1.2.0.1 -p 80:80 -d mynginx:1.0
# 说明
Dockerfile内容非常简单,就两个命令:FROM和RUN
FROM:就是基础镜像,是Dockerfile中必备的,我们构建镜像没必要从rootfs开始,
可以基于已有镜像基础上去构建自己的镜像,节省很多时间
RUN:像 Shell 脚本一样可以执行命令,这里是直线echo 命令将'<h1>Hello, Docker!</h1>'写入容器的index.html文件中,那么nginx的欢迎页面内容就被修改了。
那么这里Dockerfile描述的镜像就比nginx官方镜像多了一层Layer,定制了nginx欢迎页面。
需求2:基于CentOS7定制nginx镜像
# 基于centos7安装
FROM centos:7
#拷贝nginx的安装包
COPY nginx-1.10.3.tar.gz /usr/local/src
# 环境变量
ENV NGX_DIR=/opt/nginx
#安装依赖、解压、编译、安装
RUN yum -y install pcre pcre-devel zlib zlib-devel openssl openssl-devel gcc tar \\
&& cd /usr/local/src \\
&& tar -xvf nginx-1.10.3.tar.gz \\
&& rm -rf nginx-1.10.3.tar.gz \\
&& cd nginx-1.10.3 \\
&& ./configure --prefix=$NGX_DIR --sbin-path=/usr/bin/nginx \\
&& make \\
&& make install
#设置数据挂载目录以及工作目录 匿名卷:当前卷默认不存在,当容器创建时,再生成当前卷
VOLUME $NGX_DIR
#容器启动后执行该命令
ENTRYPOINT ["nginx", "-g", "daemon off;"]
需求3:基于java:8-alpine镜像,将一个Java项目构建为镜像
# 1.新建一个空的目录,然后在目录中新建一个文件,命名为Dockerfile
# 2.拷贝app.jar到这个目录中(自己可以随意打一个jar包测试)
# 3.编写Dockerfile文件:
touch Dockerfile
--------------------
# 基于java:8-alpine作为基础镜像
FROM java:8-alpine
# 将app.jar拷贝当前Dockerfile文件目录下 作为镜像中新Layer层
COPY app.jar /tmp/app.jar
# 编写入口ENTRYPOINT
ENTRYPOINT ["java", "-jar", "/tmp/app.jar"]
----------------------
# 4.使用docker build命令构建镜像
docker build -t web:1.0 .
# 5.使用docker run创建容器并允许 端口可自己指定
docker run --name web -p 9090:9090 -d web:1.0
# 测试访问
虚拟机ip:9090
自定义创建jdk8镜像
步骤:
(1)创建目录
mkdir –p /usr/local/dockerjdk8
(2)下载jdk-8u171-linux-x64.tar.gz
并上传到服务器(虚拟机)中的/usr/local/dockerjdk8目录
(3)创建文件Dockerfile vi Dockerfile
#依赖镜像名称和ID
FROM centos:7
#指定镜像创建者信息
MAINTAINER AHCFL
#切换工作目录
WORKDIR /usr/local/mysoft/jdk8_docker
RUN mkdir -p /usr/local/mysoft/jdk8_docker
#ADD 是相对路径jar,把java添加到容器中
ADD jdk-8u181-linux-x64.tar.gz /usr/local/mysoft/jdk8_docker
#配置java环境变量
ENV JAVA_HOME /usr/local/mysoft/jdk8_docker/jdk_8u181
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
ENV PATH $JAVA_HOME/bin:$PATH
(4)执行命令构建镜像
docker build -t='jdk8' . # 默认是 latest # -t 指定tag版本
注意后边的空格和点,不要省略
(5)查看镜像是否建立完成
docker images
七、Docker镜像服务
1. 阿里云容器镜像服务
https://cr.console.aliyun.com/cn-hangzhou/instance
相关命令
将镜像推送到Registry步骤
# 请根据实际镜像信息替换示例中的[ImageId]和[镜像版本号]参数。
docker login --username=ahcfl_**** registry.cn-hangzhou.aliyuncs.com
docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/ahcfl/nginx:[镜像版本号]
docker push registry.cn-hangzhou.aliyuncs.com/ahcfl/nginx:[镜像版本号]
# 用于登录的用户名为阿里云账号全名,密码为开通服务时设置的密码。 您可以在访问凭证页面修改凭证密码。
docker login --username=ahcfl_**** registry.cn-hangzhou.aliyuncs.com
# 登出
docker logout
# 打包一个本地的镜像,通过`docker tag`命令
docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/it-heima/nginx:[镜像版本号]
eg: docker tag 37bb9c63c8b2 registry-vpc.cn-hangzhou.aliyuncs.com/acs/agent:0.7-dfb6816
# 接下来,通过`docker push`命令来推送一个镜像
docker push NAME:[TAG]
eg: docker push registry-vpc.cn-hangzhou.aliyuncs.com/acs/agent:0.7-dfb6816
# 从Registry中拉取镜像
docker rmi registry.cn-hangzhou.aliyuncs.com/ahcfl/nginx:[镜像版本号]
docker pull registry.cn-hangzhou.aliyuncs.com/ahcfl/nginx:[镜像版本号]
选择合适的镜像仓库地址
从ECS推送镜像时,可以选择使用镜像仓库内网地址。推送速度将得到提升并且将不会损耗您的公网流量。
如果您使用的机器位于VPC网络,请使用 registry-vpc.cn-hangzhou.aliyuncs.com 作为Registry的域名录。
2. 私有镜像仓库
# 安装镜像仓库镜像
docker run -d \\
--restart=always \\
--name registry \\
-p 5000:5000 \\
-v registry-data:/var/lib/registry \\
registry
# 镜像仓库默认会自动启动,如何查看镜像仓库中有哪些镜像呢?
访问: http://你的宿主机地址:5000/v2/_catalog
# 配置允许指定ip向本地镜像仓库提交镜像
# 打开要修改的文件
vi /etc/docker/daemon.json
# 添加内容: json格式,需要加 逗号
"insecure-registries":["http://宿主机ip地址:5000"]
# 重加载
systemctl daemon-reload
# 重启docker
systemctl restart docker
# 推送
docker push 宿主机ip地址:5000/nginx:1.0
# 拉取
docker pull 宿主机ip地址:5000/nginx:1.0
# 镜像若想存放到本地镜像仓库,需满足本地仓库的格式
格式: docker tag nginx:latest 宿主机ip地址:5000/nginx:1.0
(1)拉取私有仓库镜像(此步省略)
docker pull registry
(2)启动私有仓库容器
docker run -di --name=registry -p 5000:5000 registry
(3)打开浏览器 输入地址http://192.168.200.150:5000/v2/_catalog看到`{"repositories":[]}` 表示私有仓库搭建成功并且内容为空
(4)修改daemon.json
vi /etc/docker/daemon.json
添加以下内容,保存退出。
"insecure-registries":["http://192.168.200.150:5000"]
此步用于让 docker信任私有仓库地址
(5)修改配置 ` vi /lib/systemd/system/docker.service`
内容:
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock
执行:
systemctl daemon-reload
(6)重启docker 服务
systemctl restart docker
镜像上传至私有仓库
(1)标记此镜像为私有仓库的镜像
docker tag jdk8 192.168.200.150:5000/jdk8
(2)再次启动私服容器
docker start registry
(3)上传标记的镜像
docker push 192.168.200.150:5000/jdk8
八、应用部署(常用镜像安装)
1. MySQ部署
====================================================
# 关闭或禁用Linux上已经安装的mysql,因为端口被占用了
# 关闭
systemctl stop [mysql/mysqld]
# 禁用
systemctl disable [mysql/mysqld]
=====================方式一:=========================
#1.拉取或从本地加载MySQL镜像。因为镜像文件较大,推荐从本地加载
docker pull mysql:5.6
#2.创建两个数据卷mysql-data、mysql-conf
docker volume create mysql-data
docker volume create mysql-conf
#3.进入mysql-conf数据卷所在目录,新建一个my.cnf文件
# 查看数据卷对应目录
docker volume inspect mysql-conf
# 进入
cd /var/lib/docker/volumes/mysql-conf/_data
# 创建核心配置文件 my.cnf(Linux环境下mysql的核心配置文件)
touch my.cnf
#4.编辑my.cnf文件,设置mysql编码等配置属性
# mysql配置文件内容:
--------------
[mysqld]
skip-name-resolve
character_set_server=utf8
datadir=/var/lib/mysql
server-id=1000
---------------
#5.创建并运行容器。【具体参数及挂载目录参考DockerHub网站的说明】
docker run \\
--name mysql5.6 \\
-p 3307:3307 \\
-d \\
-e MYSQL_ROOT_PASSWORD=root \\
-v mysql-data:/var/lib/mysql \\
-v mysql-conf:/etc/mysql/conf.d \\
--privileged \\
mysql:5.6
=====================方式二:================================
# 加载镜像
cd /tmp
docker load -i mysql.tar
# 创建新用户
useradd 你的用户名
passwd 你的密码
cd /home/你的用户名
# 创建文件夹并进入
mkdir mysql
cd mysql
# 运行mysql容器
# 在当前/home/leyou/mysql 目录下然后执行docker命令:
mkdir mysqldocker run \\
-p 3306:3306 \\
--name mysql \\
-v $PWD/conf:/etc/mysql/conf.d \\
-v $PWD/data:/var/lib/mysql \\
-e MYSQL_ROOT_PASSWORD=123 \\
--privileged \\
-d \\
mysql:[tag]
# 自定义配置文件:
vi conf/my.cnf
-----内容------
[mysqld]
skip-name-resolve
character_set_server=utf8
datadir=/var/lib/mysql
server-id=1000
---------------
# 重启mysql:
docker restart ly-mysql
通过Navicat或其它工具,尝试连接mysql。
2. Redis部署
# 直接下载 或 本地加载
docker pull redis:5.0
docker load -i redis.tar
# 挂载本地文件
cd /home/你的用户名
# 创建一个文件夹
mkdir redis
cd redis
mkdir data
# 创建redis 的配置文件
touch redis.conf
# 修改配置
vi redis.conf
---------添加内容---------------
databases 1
dir /data
appendonly yes
appendfilename appendonly.aof
appendfsync everysec
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
-------------------------------
# 进入redis.conf所在目录,然后执行docker命令,运行容器
docker run \\
-p 6379:6379 \\
--name redis \\
-v $PWD/redis.conf:/usr/local/etc/redis/redis.conf \\
-v $PWD/data:/data \\
--privileged \\
-d \\
redis \\
redis-server /usr/local/etc/redis/redis.conf
# 安装完成后,可以再控制台执行命令测试
docker exec -it ly-redis redis-cli
# 输入ping
回应:PONG
3. RabbitMQ部署
# 镜像
docker pull rabbitmq:3-management
docker load -i mq.tar
# 运行RabbitMQ容器
docker run \\
-e RABBITMQ_DEFAULT_USER=guest \\
-e RABBITMQ_DEFAULT_PASS=guest \\
--name mq \\
--hostname mq1 \\
-p 15672:15672 \\
-p 5672:5672 \\
-id \\
rabbitmq:3-management
# 测试 在浏览器访问
http://你的ip:15672
3. RocketMQ部署
创建namesrv服务
# 拉取镜像
docker pull rocketmqinc/rocketmq
# 创建namesrv数据存储路径
mkdir -p /srv/docker/rocketmq/data/namesrv/logs /srv/docker/rocketmq/data/namesrv/store
# 构建namesrv容器
docker run -d \\
--restart=always \\
--name rmqnamesrv2 \\
-p 9876:9876 \\
-v /srv/docker/rocketmq/data/namesrv/logs:/root/logs \\
-v /srv/docker/rocketmq/data/namesrv/store:/root/store \\
-e "MAX_POSSIBLE_HEAP=100000000" \\
rocketmqinc/rocketmq \\
sh mqnamesrv
命令说明:
创建broker节点
# 创建broker数据存储路径
mkdir -p /srv/docker/rocketmq/data/broker/logs /srv/docker/rocke以上是关于docker安装+配置镜像+命令操作+数据卷+网络管理+DockerFile+镜像服务+项目部署+[高级使用]的主要内容,如果未能解决你的问题,请参考以下文章