为什么会有docker
docker : 源代码+配置+环境+版本 -> 打包形成一个镜像文件
镜像文件:类似于.iso文件或者win的镜像安装包,镜像的意思就是把所需的东西打包起来
docker保证了系统的平滑移植,容器虚拟化技术,安装的时候,把原始环境一抹一样的复制过来。开发人员利用docker可以消除协作编码时“在我的机器上可正常运行的问题”。
比如: VMware跑同一份centos7.iso镜像文件保证了所有人的centos7的镜像文件一致 同理,docker跑同一份打包好的镜像文件不会再有环境迁移、配置文件丢失、版本不一致这些问题,因为把所有的环境、配置、版本都打包好形成了一个镜像文件
Docker主要目标就是 “Build,ship(装载) and Run Any App, Anywhere”,也就是通过对应用组件的封装、分发、部署、运行等生命周期的管理,
将应用打包成镜像,通过镜像成为运行在Docker容器上的实例
Docker 一句话 : 解决了运行环境和配置问题的软件容器,方便做持续集成并有助于整体发布的容器虚拟化技术
容器与虚拟机比较
虚拟机就是带环境安装的一种解决方案
Docker能干嘛
devops :开发兼运维
docker三个核心概念:镜像(image)、容器(container)、仓库(repository)
1.镜像就是模板
2.容器是用镜像创建的运行实例 docker run 命令出来的就是一个容器实例
3.仓库是集中存放镜像文件的场所 dockerhub.com:最大的公有仓库 私有仓库
docker平台入门图解
左边两个框是本机 右边那个框是远程仓
Docker daemon守护进程运行在本地主机上,客户端发命令交给本地主机上运行的Docker daemon守护进程来进行容器的管理
docker run hello-world
unable to find image 'hello-world:latest' locally # 本地没有办法找到hello-world:最新的这个镜像
latest: Pulling from library/hello-world :# 从我们的远程库拉下来hello-world
2db29710123e: Pull complete
Digest: sha256:13e367d31ae85359f42d637adf6da428f76d75dc9afeb3c21faea0d976f5c651
Status: Downloaded newer image for hello-world:latest # 下载最新的镜像hello-world:latest
/var目录下存放安装配置文件
使用sudo apt-get install * 安装的都放在/var/cache/apt/archives目录下
镜像加速器配置
因为docker服务器在国外,为了后面pull的更加快速,所以要配置
docker run 干了什么?
- 现在本机找docker镜像,本机有,则以该镜像为模板生产容器实例运行
- 若本机找不到,则到dockerhub仓库中找该镜像,若dockerhub中也找不到,则返回镜像找不到的错误
docker常用命令(日常使用)
开机启动 : linux启动时,docker就自动启动
docker镜像命令(日常使用)
- docker image
TAG:镜像的版本号 同一个仓库源可以有多个TAG
/ 常用参数
-a : 列出本地所有镜像(**含历史映像层**)
-q : 只显示镜像ID
-aq : 显示所有镜像的image ID
- docker search 镜像名字
查看远程仓库中有没有hello-worl镜像
- docker pull 镜像名字
下载镜像
docker pull 镜像名字:[TAG版本号]
没有写TAG就是默认最新版,等价于docker pull 镜像名字:latest
比如:docker pull mysql:5.6 # 下载版本号为5.6的mysql镜像
- docker system df 查看/容器/数据卷所占的空间
补:linux查看磁盘空间 df -h : df(disk free)
- docker rmi 镜像名字ID
删除某个镜像
rmi:rm指的是remove i指images镜像
强制删除
补:-f : force 强制的 跟linux rm -rf一样 -r:递归的删 -f 强制删
思考:结合Git使用方法,会不会有docker commit,docker push;有:在本地镜像发布到私有云
docker容器命令(日常使用,非常重要)
有了镜像,才能创建容器(docker pull下载镜像,才能docker run这个容器)
用docker来模拟出另外一个ubuntu系统:
- docker run 新建+启动容器
Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
OPTIONS说明(常用):有些是一个减号,有些是两个减号
--name="容器新名字” #为容器指定一个名称,如果不命名,则是系统随机分配的名字
-d:后台运行容器并返回容器ID,也即启动守护石容器(后台运行,某些系统不希望在前台运行,要是万一不小心关闭掉了呢)
-i:以交互模式运行容器,通常与-t同时使用;
-t:为容器重新分配一个伪输入终端,通常与-i同时使用;
-i指的是交互interactive, -t指的是tty终端
-it : 启动交互式容器 (后面还有个-d :启动守护式容器(后台服务器))
例如:docker run -it ubuntu /bin/bash
第一个没写-it,没有以交互模式启动,所以即使启动了也没有反应,第二个是以交互模式启动的,说明我已ubuntu作为镜像,在本地容器上运行起来了,在容器内执行/bin/bash命令,现在通过docker来操作另外一个ubuntu操作系统,所以也会有哪些linux自带的命令,比如ps -ef
当然,后面也可以加镜像的版本号:docker run -it ubuntu:latest /bin/bash
这个交互式的shell即上面图中的root@71941e4614f
-P:随机端口映射,大写P
-p:指定端口映射,小写p
意思就是说外面会访问docker的6379端口,而在docker中又将此6379映射到了redis的6379端口(左边是宿主机的暴露的端口,右面是docker访问redis暴露的端口)
- docker ps 表示列出当前所有正在运行的容器(只能在自己的终端里输入,不能在进入容器的终端里输入(你都已经在容器里了,怎么查找当前正在运行的容器))
container ID :现在就是容器ID了,不再是镜像ID
IMAGE:镜像名字
COMMAND:“bin/bash” 会在终端显示
CREATED:35秒前创建
PORTS:暴露端口,因为ubuntu不需要暴露端口
NMAES:如果没有使用--name指定容器的名字,显示的就是系统随机分配的名字
常用参数:
- 退出容器
- docker start 容器ID或者容器名 启动已经停止运行的容器
(exec和start区别:exec进入正在运行的容器,start是启动已经停止的容器)
-
docker stop 容器ID或者容器名 停止容器
-
docker kill 容器ID或者容器名 强行停止容器
-
docker rm 容器ID或者容器名 删除已经停止的容器
不给删除,因为此容器是正在运行的容器
强制删除: docker rm -f 容器ID或者容器名 #可以强制删除正在运行的容器
- 启动守护式容器
docker run -d 镜像名
注意!:只要你run启动了一个容器后,最好用docker ps查看一下正在运行的容器,有的时候docker run会启动失败
因为ubuntu没有前台进程,所以没有会自动退出,认为他自己没有事可做了,后面以redis来演示前台交互式启动和后台守护式启动。
用redis演示前台交互式启动和后台守护式启动
前台交互式启动:
对于像redis,mysql这种,一般不会前台交互式启动,因为不小心ctrl+c就会停止这个服务;所以一般都后台守护式启动:
- 查看日志
docker logs container_Id/name
- 查看容器内运行的进程
docker top container_Id/name
- 查看容器详细信息
容器的详细信息会以json的形式返回。
docker inspect container_Id/name
- 重新进入容器(当用docker ps查看当前正在运行的容器时,就可以用docker exec -it 交互)
docker exec -it container_Id/name /bin/bash
- 从容器内拷贝文件到主机上,起到关键核心资料的保护(我在容器内写了一个.cpp文件,万一容器被别人删掉了,容器内的重要的数据要备份到主机上,这样,即使容器被docker rm -f 删除,也会有备份)
docker cp container_Id:容器内路径 目的主机路径
- 导入和导出容器(功能更强大,将整个容器做备份)
export和import互为逆操作命令,export把整个容器备份了,而cp命令只能把一部分从容器拷贝回主机
docker export container_Id/name > ss.tar # 一般默认导出到当前目录
cat 文件名.tar | docker import ... 会重新生成镜像
命令总结
解决docker: Error response from daemon: Conflict. The container name "/ub02" is already in use by container "e3d04e1de3a3fe2025dde90273e694c58898170d551b350dec72bf4b78af010f". You have to remove (or rename) that container to be able to reuse that name.
使用docker 出现Error response from daemon: Conflict. The container name “***” is already in use
解决方法:
(1)给容器换一个名字, 比如说 docker run -it --name=mycentos2 centos:7 /bin/bash, 可以解决问题.
(2)将原来的容器删除
查询当前容器:docker ls -a
删除当前容器:docker rm name/container_Id(提示: 这一步要确定删除容器没问题的情况下, 才可以做)
# 解决Docker运行命令时提示“Got permission denied while trying to connect to the Docker daemon socket“类情况,提示如下
下次重新启动电脑后,先执行docker start name(可以按tab键获得),在执行dockere exec -it name /bin/bash,这样就与docker run ... 没关系了,docker run ...是新建+启动容器
镜像分层概念
自己做一个镜像给别人
镜像复习:是一种轻量级、可执行的独立软件包,它包含运行某个软件所需的所有内容
UnionFS(联合文件系统)
docker commit (类似于新做了一个镜像)
命令:
命令参数:
-m="" :表示提交的信息 类似于git commit -m=
-a="作者” : 表示是谁提交的
下次再进来用docker run -it 容器名 /bin/bash也能进到相同的容器中,或者使用docker start + docker exec也行
这个例子显示了如果我docker run了一个新容器(我没给这个容器命名),默认的从dockerhub中下载的镜像是没有vim功能的(这个ubuntu镜像只有73M,但我用自己的,已经下载好vim功能的容器使用docker commit做了一个镜像时,这个镜像就已经包含了vim,所以当我在使用docker run 自制镜像的时候,创建的ubuntu就可以立即使用vim)
docker容器数据卷 = 相当于同步数据,实现了宿主机和容器之间数据共享,-v参数就是指mount挂载
是什么? 能干什么?怎么用?
1.--privileged=true 权限扩容(扩大)、放开权限
也就是使用privileged=true该参数,容器内的root拥有真正的root权限,否则,容器内的root用户只是外部的一个普通用户的权限
- -v参数 就是挂载 添加自定义的容器卷 重要!!!!!!!!
相当于建立了共享文件夹
-d : 后台守护式
-p : 端口映射 宿主机:容器内
registry是镜像名,根据自己应用的来启动自己的镜像
-v : 宿主机的路径:容器内的路径 使用了-v参数关联了主机和容器,docker容器内产生的东西可以备份到主机指定目录下
一个-v是绑定一组,可以有多组-v挂载多个
把容器的目录和主机的目录做一个映射,把容器内的数据备份+持久化到本地主机目录
3.数据卷是什么?
容器卷的功能和docker cp从容器内拷贝文件到主机上还有docker export/import导入导出容器功能有点儿类似,比那这两个更牛!
4.数据卷能干什么?
5.容器卷例子
5.1宿主机和容器之间映射添加容器卷,实现了数据共享
直接命令添加:
docker run -it -privileged=true -v /宿主机的绝对路径:/容器内目录 镜像名 bin/bash
宿主机没有写的/tmp/host_data目录时,会自建一个/tmp/host_data目录,当执行完这个命令时,容器内就会创建一个/tmp/docker_data目录,这个目录下什么都没有;因为使用了-v参数做了映射,这时如果docker容器中/tmp.docker_data目录生成了某些东西,会自动同步到宿主机的/tmp/host_data目录下
这时,docker容器内/tmp/docker文件夹中什么都没有,
如果我在容器内新建了一个docker_in.txt文件,在宿主机/tmp/host_data目录中就会出现这个新建的docker_in.txt文件
同理,在宿主机上的/tmp/host_data路径中新建一个host_out.txt文件,在容器中的/tmp/docker_data路径中也会产生一个host_out.txt文件,如果在宿主机上修改host_out.txt文件,在容器中也会同步修改,反之亦然!
可以使用docker inspect 容器号/name来查看mount挂载的宿主机和容器路径!
这种使用-v参数将主机路径和容器路径挂载到一起的方式,即使容器停止docker stop后,在主机上修改绑定路径中的内容,当容器在连接上来的时候,也会同步主机修改的数据!(就是两者路径下的内容要完全一样)