Docker
Docker历史
在容器技术出来之前,我们都是使用虚拟机技术
vm :(笨重,启动分钟级)Docker(轻巧,启动秒级)
2010年,几个搞IT的年轻人,在美国成立了一家公司dotCloud,做一些pass的云计算服务、LXC有关的容器技术,他们将自己的技术(容器化技术)命名为 : Docker
Docker刚诞生的时候,并没有引起行业的注意,面临着 "活不下去"的问题
决定开源
2013年,Docker开源
开源以后越来越多的人发现了docker的优点 >>> 火了 >>> Docker每个月都会更新一个版本
2014年4月 Docker1.0发布
前戏
run的运行流程图
底层原理
Docker是一个Client - Server结构的系统,Docker的守护进程运行在主机上,通过Socket从客户端访问
DockerServer接收到Docker - Client的指令,就会执行这个命令
1 Docker的三大核心概念
1 容器(Container) : 容器是对外提供服务的入口
?
2 镜像(Image) : 镜像是启动容器的模板
?
3 仓库(Repository) : 存放镜像的仓库
2 在CentOS中安装docker
1 删除老版本中的dockers残留 yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine 2 更换源 2.1 cp /etc/yum.repos.d/CentOS-Base.repo/etc/yum.repos.d/CentOS-Base.repo.bak 2.2 curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo 3 建立yum源缓存 yum makecache 4 更新操作系统 yum update -y --exclud=kernel* 5 安装基础软件 yum install -y yum-utils device-mapper-persistent-data lvm2 6 安装docker yum源 yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 7 安装docker 7.1 yum makecache fast 7.2 yum -y install docker-ce 8 启动docker systemctl start docker 9 验证docker docker run -p 8080:80 -d nginx (测试能通过8080端口访问服务器即为成功)
3 镜像(Image)
# 镜像是什么 镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件 ? 所有的应用,直接打包docker镜像,就可以直接跑起来 ? # docker镜像 : 启动容器的模板,镜像一般情况下定义的是容器启动的服务 ? 1 获取镜像 docker pull 获取的镜像名称 2 公共的仓库(dockerHub官方、阿里云镜像仓库、华为云镜像仓库、腾讯云镜像仓库) registry.cn-hangzhou.aliyuncs.com/alvinos/docsfiy:v2 ? 镜像仓库 : registry.cn-hangzhou.aliyuncs.com(默认:docker.io) 命名空间 : alvinos(默认:library) 仓库名称 : docsfiy 版本号 : v2(默认: latest) 3 私有的仓库(Harbor) 登录仓库 : docker login 仓库url(默认docker.io) ? 4 版本镜像号(tag) docker tag 原来的tag 新的tag 5 获取当前系统上所有的docker镜像 docker images 或 docker image ls 参数 -a : 列出系统中所有的临时镜像 --digests=true : 列出系统中所有镜像的数字摘要值 -q : 仅显示镜像id 6 上传镜像 6.1 创建阿里云仓库 6.2 登录阿里云仓库 docker login 6.3 修改镜像名称 docker tag 6.4 上传镜像 docker push 镜像tag ? 7 查看镜像详细信息 docker inspect 镜像名称或id 参数 -f : 获取镜像部分详细信息 8 删除镜像 docker rmi 镜像名称或id 参数 -f : 强制删除镜像 ? 9 清空机器上所有镜像 docker rmi $(docker images -q) ? 10 部署一个Django 10.1 拉取镜像 docker pull 镜像名称(alvinos/django:v3) 10.2 启动 docker run -d -p 80:80 alvinos/django:v3 10.3 关闭服务 docker stop 容器名称
4 容器(Container)
# 容器的本质是进程 ? 1 运行一个容器 ? 前提: docker容器启动的前提 : 至少有一个应用进程运行在前台 格式 docker run 参数 镜像名称/id 启动容器执行的命令 启动命令 : 不指定则执行默认的启动命令 镜像名称/id : 可以使用镜像名称,也可以使用镜像id ps : docker create + docker start = docker run 启动流程 1.1 检查本地是否存在需要被使用的镜像,如果有则直接使用,没有则去公网下载 1.2 根据镜像创建容器 参数 -d : 以守护进程方式运行 -p : (固定)端口映射 -P : (随机)端口映射 -i : 打开标准输出 -t : 创建一个终端 (it通常一起使用) -v : 将宿主主机上的目录映射到容器中 --rm : 当容器的生命周期结束时立即删除容器 --name : 将容器自定义一个容器名称,将容器的名称加入DNS解析 -e : 设置容器内部的环境变量 -h : 设置容器内部的主机名 2 展示docker容器列表 ? docker ps (默认情况下展示当前系统上所有正在运行的容器) CONTAINER ID : 容器ID IMAGE : 镜像ID|镜像名称 COMMAND : 容器启动执行的命令 CREATED : 创建距离现在的时间 STATUS : 状态 PORTS : 端口信息 NAMES : 容器的名称 参数 -a : 展示所有的容器 -q : 仅展示容器的id 3 删除容器 格式 docker rm 容器的名称/id 参数 -f : 强制删除 ps : docker rm -f $(docker ps -a -q) (清空所有容器) 4 创建容器 ? docker create 5 启动容器 ? docker start 6 进入容器 6.1 attach 建立一个宿主主机到容器中pid为1的进程上的一个管道,但是一旦attach断开链接,docker容器随即退出 6.2 exec(推荐) 使用其可以在宿主主机上执行一个容器内部的命令 docker exec -it relaxed_bhabha bash 6.3 nsenter 建立一个宿主主机和容器之间的一个管道 nsenter --target $( docker inspect -f {{.State.Pid}} elegant_margulis ) --mount --uts --ipc --net --pid 6.4 ssh(不推荐) ps : 添加数据库用户 # 创建用户并授权 GRANT ALL PRIVILEGES ON *.* TO ‘username‘@‘%‘ IDENTIFIED BY ‘password‘ WITH GRANT OPTION; ? # 刷新权限 FLUSH PRIVILEGES; ? 7 容器和镜像的导出和导入 ? 7.1 export和import(针对的是容器) 格式 docker export -o 打包的文件名 容器id或名称 docker export -o django.tar elegant_margulis docker import 文件名 镜像名及版本号 docker import django.tar django:v1 7.2 save和load(针对的是镜像) 格式 docker save -o 打包的文件名 镜像名称及版本号 docker save > 打包的文件名 镜像名称及版本号 docker save -o python.tar:3.6.8 alvinos/django:v3 docker load < 打包的文件名 docker load < python.tar 7.3 import及export 和 save及load之间的区别 7.3.1 import可以自定义镜像名称,load不可以 7.3.2 save可以同时保存多个镜像,export不可以同时保存多个容器 7.3.3 save保存的镜像大小要大于export保存的镜像大小 7.3.4 两者之间不能互相导入 8 容器复制 ? 8.1 将文件复制到容器内 docker cp 宿主主机文件路径 容器名称或id:容器内路径 8.2 将容器文件复制到宿主主机 docker cp 容器名称或id:容器内路径 宿主主机文件路径
5 Linux网络
5.1 网络名称空间
5.2 Veth设备
引入Veth设备是为了在不同的网络名称空间之间进行通信,利用它可以直接将两个网络名称空间连接起来 由于要连接的两个网络命名空间,所以Veth设备是成对出现的,很像一对以太网卡,并且中间有一根直连的‘网线‘ 我们将其中一端称为另一端的peer 在Veth设备的一端发送数据时,它会将数据直接发送到另一端,并触发另一端的接收操作 # 总结 两个虚拟网卡组成的数据通道,在Docker中,用于连接Docker容器和Linux Bridge,一端在容器中作为eth0网卡,另一端在Linux Bridge中作为网桥的一个端口
5.3 常用命令
# 创建一个命名空间 ip netns add test01 # 查看创建过的命名空间 ip netns list ? # 创建Veth设备对 ip link add veth type peer name veth001 # 将Veth设备分发至test01命名空间 ip link set veth001 netns test01 # 将test01中的veth001分配ip ip netns exec test01 ip addr 172.16.0.111/20 dev veth001 ip addr add 172.16.0.112/20 dev veth # 重启veth设备对 ip netns exec test01 ip link set dev veth001 up/down # 总结: 可想象成创建veth设备对(对象双方互相结识),给其中一个veth设备分发至其他命名空间(异地恋),给veth设备对分配ip(给双方各配一部手机并插上手机卡(拥有各自的电话号码)),重启veth设备对(手机重启) ---> 达成互通(通过手机相互联系)
6 Docker网络模式
Docker使用Linux桥接的方式,在宿主机虚拟一个Docker容器网桥(docker0)
Docker启动一个容器时都会根据Docker网桥的网段分配给一个容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网关,因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接通信
Docker网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻找到的,这也意味着外部网络无法直接通过Container-IP访问到容器
如果容器希望外部能够访问到,可以通过映射容器端口到宿主主机(端口映射),即docker run 运行容器时使用 -p 或 -P 参数,访问容器的时候就通过宿主机IP:容器端口访问容器
1 HOST模式(网络隔离性不好) ? # 使用host模式的容器可以直接使用宿主机的IP地址与外界通信(不需要自己映射端口),容器内部的服务端口也可以使用宿主机的端口,host最大的优势就是网络性能比较好,但docker host上已经使用的端口就不能再用了,网络的隔离性不好 # 使用宿主主机的网卡 docker run --network host 镜像名称或id 2 Container模式(共享指定容器的网络) ? # 这个模式指定新创建的容器和已经存在的一个容器共享一个Network Namespace(网络名称空间),而不是和宿主机共享,新创建的容器不会创建自己的网卡、配置自己的IP,而是和一个指定的容器共享IP、端口范围等,同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的,两个容器的进程可以通过lo网卡设备通信 # 共享一个容器的网络 docker run -d --network "container:共享容器的名称" nginx 3 None模式(封闭的网络能很好的保证容器的安全性) ? # 使用None模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置,也就是说,这个Docker容器没有网卡、IP、路由等信息,需要我们自己为Docker容器添加网卡、配置IP等 # 这种网络模式下容器只有lo回环网络,没有其他网卡,None模式可以在容器创建时通过--network=none来指定,这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性 # 不为容器提供任何网络 docker run -d --network none centos 4 网桥(bridge模式(默认)) ? # 当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上,虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中 # 从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关,在主机上创建一对虚拟网卡veth设备对,Docker将veth设备对的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放在主机中,以vethXXX这样类似的名字命名,并将这个网络设备加入到docker0网桥中,可以通过brctl show命令查看 # 将多个容器使用docker网桥进行地址转换的方式实现网络互通 4.1 创建网桥 docker network create chenyang 4.2 查看网桥 docker network ls 4.3 使用网桥 docker run -d --network chenyang nginx
6.1 Docker network
1 展示当前主机上的网桥列表 docker network ls 2 创建网桥 docker network create 参数 -d : 指定网桥的类型 --gateway : 指定网关 --subnet : 指定子网 3 查看网桥的详细信息 docker network inspect 网桥名称或id 4 删除网桥 docker network rm 5 清空自创的且空闲的网桥 docker network prune -f 6 连接上一个网桥 docker network connect 参数 网桥名称 容器名称 7 断开链接 docker network disconnect 参数 网桥名称 容器名称 8 连接上一个容器 docker run --link "连接的容器名称:连接别名" docker run --link "nginx:nginx" -it centos bash (相当于两个容器连上了,不用link的话,两个容器相连要知道容器端口号)
7 构建镜像
7.1 构建镜像的特征 ? 7.1.1 需要基础环境 7.1.2 可执行命令 7.1.3 启动命令 7.2 Dockerfile ? 7.2.1 Dockerfile命名:Dockerfile 7.2.2 Dockerfile是由指令组成(Dockerfile指令必须大写) 7.2.3 实现基础环境 : FROM 7.2.4 可执行命令 : RUN 7.2.5 启动命令(指定命令必须运行在前台) : CMD 7.2.6 开始构建 : docker build -t 镜像名称 7.2.7 禁止构建使用缓存 : --no-cache 7.3 Dockerfile指令 FROM : 指定基础镜像 RUN : 执行一个命令 CMD : 设置一个启动命令 WORKDIR : 设置工作目录 ADD : 添加文件到镜像 COPY : 复制文件到镜像 EXPOSE : 指定与外界交互的端口 ENV : 设置容器内默认的环境变量 7.4 ADD和COPY之间的区别 ? 7.4.1 ADD支持解压(tar类型的压缩包),COPY不支持 7.4.2 ADD支持网络下载(不支持解压),COPY不支持 7.4.3 ADD和COPY : 当镜像中目录不存在时,需要加/结尾,当镜像中目录存在时,则没有区别 ps : 部署mysql数据库时(注意添加环境变量-e MYSQL_DATABASE)
8 帮助命令
docker version # 显示docker的版本信息 docker info # 显示docker的系统信息,包括镜像和容器的数量 docker 命令 --help # 帮助命令 ? # 帮助文档的地址: https://docs.docker.com/reference/