注:本文案例均为演示,设计生产环境请酌情操作,个人实例请勿上线生产
一、简介
官网:http://www.docker.com
仓库:https://hub.docker.com
Docker依赖于Linux内核环境,制造一个隔离的文件环境
1、docker的基本组成
镜像image:集成最小化操作系统内核和对应的软件应用的部署文件
容器container:通过镜像文件创建一个供服务运行的区域
仓库repository:存放镜像的地方,分为公有仓库和私有仓库
2、docker的优势
轻量化,相比于vm虚拟机,docker不需要实现硬件资源的虚拟化,运行在docker容器中的程序直接使用的就是实际物理机的硬件资源;同时docker利用的是宿主机的内核,不需要加载操作系统OS内核(实际就是新建立一个docker容器的速度更快)
更加简单点的理解,在一个机器上虚拟化多个虚拟机,和在一个机器上新建多个docker容器,后者更加省时省力
二、安装与卸载
前提要求:以centos为例,需centos7,64位,内核版本3.8以上
扩展:查询版本信息cat /etc/redhat-release
查询内核版本uname -r
安装指导:Install Docker Engine on CentOS | Docker Docs
1、安装依赖
yum -y install gcc
yum -y install gcc-c++
2、安装Docker
1)yum在线安装
安装yum工具包:sudo yum install -y yum-utils
官方镜像仓库:sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
阿里云镜像仓库:sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
注:官方镜像仓库和阿里云镜像仓库二选一,官方仓库易超时可使用阿里云仓库
重建yum缓存:yum makecache fast
安装docker引擎:sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
启动docker:sudo systemctl start docker
查看docker版本:docker version
运行helloworld实例:sudo docker run hello-world
2)离线安装
官方指导:Install Docker Engine from binaries | Docker Docs
大神指导:Docker离线安装部署-优快云博客
3、卸载
停止docker服务:systemctl stop docker
移除docker引擎:sudo yum remove docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras
清除相关目录:sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd
扩展:添加镜像加速器(阿里云镜像加速)
阿里云官网:阿里云-计算,为了无法计算的价值
添加镜像加速器主要是为了确保连接远程镜像仓库的稳定性,避免出现断连或超时的场景
根据镜像加速器页面的操作文档来操作即可
三、常用命令
1、常用命令
启动:systemctl start docker
停止:systemctl stop docker
重启:systemctl restart docker
状态:systemctl status docker
开启自启:systemctl enable docker
docker信息:docker info
帮助命令:docker [具体命令] --help
2、镜像命令
1)docker images [OPTIONS]
说明:列出本机上的镜像
OPTIONS:-a,查看所有镜像;-q,只显示镜像ID
实例:
说明:
REPOSITORY | 表示镜像的仓库源 |
TAG | 镜像的版本号标签 |
IMAGE ID | 镜像ID |
CREATED | 镜像创建的时间 |
SIZE | 镜像大小 |
同一个仓库源可以有多个TAG版本,代表这个仓库源的不同版本,通常使用REPOSITORY:TAG来定义不同的镜像,如果不指定一个镜像的版本标签,则会默认使用xxx:latest镜像
2)docker search [OPTIONS] 镜像名
说明:查询本地或远端的某个镜像
OPTIONS:--limit num,罗列指定个数的镜像,num默认25
示例:
说明:
NAME | 镜像名 |
DESCRIPTION | 镜像说明 |
STARS | 点赞数 |
OFFICIAL | 是否是官方镜像 |
AUTOMATED | 是否是自动构建的 |
3)docker pull 镜像名[:TAG]
说明:下载指定镜像
参数:TAG为指定的版本,不写默认拉取latest
示例:
4)docker system df
说明:查看镜像,容器和数据卷所占的空间
示例:
5)docker rmi [OPTIONS] {镜像名称|镜像ID...}
说明:删除指定镜像,可指定删除多个,中间用空格隔开
参数:-f,强制删除
示例:
扩展:删除全部镜像docker rmi -f $(docker images -qa),当然谨慎使用
6)虚悬镜像
虚悬镜像是指仓库名,标签都是none的镜像,也称dangling image,如下图所示,一般是构建过程中异常产生的
只查看虚悬镜像:docker images ls -f dangling=true
删除虚悬镜像:docker image prune
3、容器命令
以在dokcer中拉取的ubuntu镜像来做示例
1)docker run [OPTIONS] image[:TAG] [COMMAND] [ARG...]
说明:新建或启动容器
常用OPTIONS:--name="容器名称",为当前创建的容器指定一个名称,不写默认声明
-d,后台运行容器,并返回容器ID,即启动守护式容器
-i,以交互模式运行容器,通常与 -t 同时使用
-t,为容器重新分配一个伪输入终端,通常与 -i 同时使用,即启动交互式容器
-P,随机端口映射,容器内部端口随机映射到主机的端口
-p,指定端口映射,格式为:主机(宿主)端口:容器端口
示例:
说明:/bin/bash是shell的命令解释器,即人机语言翻译器
扩展:更多参数的说明请查看docker run --help或参考Docker run 命令 | 菜鸟教程
特殊说明:-d参数使用后,尽可能使用docker ps查看下当前创建的容器是否处于UP状态,老一些的版本-d创建的容器会自动处于EXITED状态,这是由于docker的机制认为没有前台的交互,该容器没有运行的必要,不过像mysql,redis这种后台则会一直运行
2)docker ps [OPTIONS]
说明:列出当前正在运行的容器
OPTIONS:-a,显示所有容器,包括未运行的
-l,显示最近创建的容器
-n num,显示最近创建的num个容器
-q,静默模式,只显示容器编号
示例:
说明:
CONTAINER ID | 容器ID |
IMAGE | 使用的镜像 |
COMMAND | 启动容器时使用的命令 |
CREATED | 容器创建的时间 |
STATUS | 容器状态 created(已创建),restarting(重启中),running(运行中),removing(迁移中),paused(暂停),exited(停止),dead(死亡) |
PORTS | 端口信息及使用的协议 |
NAMES | 容器名称 |
扩展:更多参数参考3-1)中的扩展
3)退出容器
exit:容器会一起停止
ctrl+p+q:仅退出命令行,容器不会停止
4)docker start {容器名称|容器ID}
说明:启动已停止的容器
5)docker restart {容器名称|容器ID}
说明:重启容器
6)docker stop {容器名称|容器ID}
说明:停止容器
7)docker kill {容器名称|容器ID}
说明:强制停止容器
8)docker rm [OPTIONS] 容器ID...
说明:删除已停止容器,多个容器之间用空格隔开
OPTIONS:-f,忽略状态,强制删除
9)更多
①查看容器日志:docker logs 容器ID
②查看容器内运行的进程:docker top 容器ID
③查看容器内部细节:docker inspect 容器ID
④进入正在运行的容器并以命令行交互
docker exec -it 容器ID /bin/bash
docker attach 容器ID
区别:exec在进入交互行后,会启动一个新的进程,使用exit不会停止容器,而使用attach,不会启动一个新的进程,在使用exit时会停止容器,故推荐使用exec命令
⑤从容器拷贝文件到主机:docker cp 容器ID:容器内路径 目标主机路径
⑥导入和导出容器
导出:docker export 容器ID>文件名.tar
导入:cat 文件名.tar|docker import - 镜像用户/镜像名:镜像版本号
export:导出容器内容作为一个tar归档文件
import:从tar包中的内容创建一个新的文件系统导入镜像(实际为一个镜像文件)
四、Docker镜像
镜像是轻量级、可执行的独立软件包,它包含了运行某个软件的所有内容
1、镜像的分层
UnionFS,即联合文件系统,是一种分层,轻量级且高性能的文件系统,它支持对文件系统的修改作为一次提交来层层叠加,同时可以将不同目录挂载到同一个虚拟文件系统下,是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像,可以制作具体的应用镜像
镜像并不是一个软件包,而是分层的,如图所示
2、Docker镜像的加载原理
bootfs主要包含bootloader和kernel,bootloader主要是引导加载kernel,Linux在启动时会加载bootfs,在Docker镜像的最底层是引导文件系统bootfs,这一层和典型的Linux是一致的,包含boot加载器和内核,当boot加载完成之后整个内核就在内存当中了,然后有内核主导,此时系统会卸载bootfs
rootfs,在bootfs之上。包含的就是典型Linux中的/dev,/proc,/bin,/etc等标准目录和文件。rootfs就是各种不同类型的操作系统发行版,如centos,ubuntu等
像docker中的centos和ubuntu系统体量都非常小,是因为只加载了bootfs和简化的rootfs,只提供基本的命令,工具和程序库等,其中bootfs是公用的
3、镜像分层的优点
资源共享,方便迁移复制,复用性高
比如多个镜像都是由同一个base镜像构建出来,那么在docker主机的磁盘上就只需要存储一份base镜像,同样的内存当中也只需要一份base镜像,就可以为多个容器服务。镜像的每一层都可以被共享
Docker的镜像层是只读的,容器层是可写的
4、docker commit
格式:docker commit -m="" -a="" 容器ID 自定义镜像名:TAG
说明:提交容器副本使之成为一个新的镜像,注意要在容器外执行
示例:可以修改容器当中的一些信息,如新增文件等,然后生成新的镜像
5、本地镜像推送到阿里云
1)创建个人实例,并点击进入个人实例
2)创建命名空间
3)创建镜像仓库
代码源选择本地仓库
4)根据仓库的操作指南3推送镜像
5)示例
在镜像版本中就可以看到推送的镜像,也可以通过操作指南中的2拉取到自己机器上,运行看看修改的内容是否存在
6、本地镜像推送到私有库
使用DockerRegistry实现
1)拉取registry
docker pull registry
2)运行registry
docker run -d -p 5000:5000 -v /opt/myregistry:/tmp/registry --privileged=true registry
不加-v参数,默认创建在/var/lib/registry目录下,具体-v参数的说明看第五章
3)查询当前私有库上的镜像信息
curl -XGET http://192.168.237.136:5000/v2/_catalog
说明:请替换自己的主机IP,registry容器运行时已做了端口映射
扩展:查询指定镜像的tag列表
curl -XGET http://192.168.237.136:5000/v2/镜像名/tags/list
4)修改镜像TAG
主要是为了区分度,不过每个仓库的规范也有要求,参照修改即可
docker tag 镜像ID 192.168.237.136:5000/自定义镜像名:TAG
5)修改配置支持http推送
vi /etc/docker/daemon.json
添加如下内容:, "insecure-registries":["192.168.237.136:5000"]
注:注意“,”的存在。docker默认是不支持http方式推送镜像,需要手动放开,修改后重启docker生效,注意重启docker后,容器也需要重新启动
6)推送镜像到私有库
docker push 镜像名:TAG
如图所示,推送成功后再次查询私有库镜像就可以看到推送的镜像信息
五、Docker容器数据卷
1、--privileged=true
docker挂载主机目录通常建议添加--privileged=true参数。在Linux中挂载目录被禁掉,如果要开启,一般使用--privileged=true命令,扩大容器权限解决挂载目录没有权限的问题,也使用该参数,如container内的root拥有真正的root权限,否则,root只是一个普通用户
2、容器数据卷存在的目的
实现容器数据的持久化,重要资源的备份到本地机器。卷就是目录或文件,存在于一个或多个容器,由docker挂载到容器,但不属于UnionFS,因此可以绕过UnionFS提供一些用于持久存储或共享数据的特性;卷的设计目的就是数据的持久化,完全独立于容器的生命周期,因此docker不会在删除容器时删除其挂载的数据卷;卷内的数据可以在容器间共享或重用,卷中的更改实时生效,卷中的更改不会包含在镜像的更新中,卷的生命周期一致持续到没有容器使用它
3、挂载方式
命令:docker run -it --privileged=true -v /宿主机目录:/容器目录[:OPTIONS] 镜像名
OPTIONS:默认不写为rw,表示可读可写;ro表示只读(对容器而言)
说明:-v参数可以有多组,表示将多个目录分别与容器内目录绑定,不存在的目录docker会自动创建
查看某个容器目录的挂载情况可以使用docker inspect 容器ID来查看,挂在后的目录下主机添加文件,容器可见;容器添加文件,主机可见;容器停止的状态下,主机添加文件,容器启动后仍然可见
4、容器卷之间的继承
容器1已完成和主机间的挂载映射
容器2需要继承容器1的挂在映射关系:docker run -it --privileged=true --volumed-from 父容器ID 镜像名
实际是容器2沿用了容器1的挂载映射关系,不会因为容器1的状态停止了就无法使用,同理容器1状态恢复后,也能看到之前容器2操作的文件
六、Docker部署软件
1、部署mysql
1)下载MySQL5.7镜像
docker pull mysql:5.7
2)启动容器
docker run -d -p 3306:3306 --privileged=true -v /opt/mysql/log:/var/log/mysql -v /opt/mysql/data:/var/lib/mysql -v /opt/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 --name=mysql mysql:5.7
说明:-e是参数设置,MYSQL_ROOT_PASSWORD为设置root初始密码
3)修改编码字符集
cd /opt/mysql/conf/
vi my.cnf
[client]
default_character_set=utf8
[mysqld]
character_set_server=utf8
collation_server=utf8_general_ci
:wq!保存退出
重启mysql
docker restart mysql
4)连接并创建库表数据
docker exec -it 296c463bcf2a /bin/bash
mysql -uroot -p
查看编码字符集:show variables like 'char%';
后续即便删除当前mysql容器,只要启动时指定的挂载目录和之前一致,启动后的数据库仍会有之前的数据
2、部署redis
1)下载redis镜像
docker pull redis:6.0.8
2)启动前准备
先在主机创建一个redis目录,如/opt/redis,在这个目录下创建redis.conf文件,或者从其他地方拷贝过来一份redis.conf文件
# bind 127.0.0.1 注释
daemonize no 由yes改为no,否则会与docker run -d冲突
appendonly no 可选项,需要redis数据持久化则改为yes
requirepass 123 可选项,设置则开启redis验证
3)启动容器
docker run -d -p 6379:6379 --privileged=true -v /opt/redis/redis.conf:/etc/redis/redis.conf -v /opt/redis/data:/data --name redis redis:6.0.8 redis-server /etc/redis/redis.conf