目录
一、docker 简介
1、什么是docker
Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。
Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。
Docker 使用 Google 公司推出的 Go 语言 进行开发实现,基于 Linux 内核的 cgroup,namespace,以及 AUFS 类的 Union FS 等技术,对进程进行封装隔离,属于 操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。最初实现是基于 LXC,从 0.7 版本以后开始去除 LXC,转而使用自行开发的 libcontainer,从 1.11 开始,则进一步演进为使用 runC 和 containerd。
传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。
2、docker的优势
更高效的利用系统资源:由于容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,Docker 对系统资源的利用率更高。无论是应用执行速度、内存损耗或者文件存储速度,都要比传统虚拟机技术更高效。因此,相比虚拟机技术,一个相同配置的主机,往往可以运行更多数量的应用。
更快速的启动时间:传统的虚拟机技术启动应用服务往往需要数分钟,而 Docker 容器应用,由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间。
一致的运行环境:开发过程中一个常见的问题是环境一致性问题。由于开发环境、测试环境、生产环境不一致,导致有些 bug 并未在开发过程中被发现。而 Docker 的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性。
持续交付和部署:对开发和运维(DevOps)人员来说,最希望的就是一次创建或配置,可以在任意地方正常运行。使用 Docker 可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过 Dockerfile 来进行镜像构建,并结合 持续集成(Continuous Integration) 系统进行集成测试,而运维人员则可以直接在生产环境中快速部署该镜像,甚至结合持续部署(Continuous Delivery/Deployment) 系统进行自动部署。
更轻松的迁移:由于 Docker 确保了执行环境的一致性,使得应用的迁移更加容易。Docker 可以在很多平台上运行,无论是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运行结果是一致的。因此用户可以很轻易的将在一个平台上运行的应用,迁移到另一个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况。
更轻松的维护和扩展:Docker 使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。此外,Docker 团队同各个开源项目团队一起维护了一大批高质量的 官方镜像,既可以直接在生产环境使用,又可以作为基础进一步定制,大大的降低了应用服务的镜像制作成本。
3、对比传统虚拟机
虚拟机 | docker容器 | |
操作系统 | 宿主机上运行虚拟机OS | 共享宿主机OS |
存储 | 镜像较大(GB) | 镜像小(MB) |
性能 | 操作系统额外的cpu、内存消耗 | 几乎无性能损耗 |
移植性 | 本种、与虚拟技术耦合度高 | 轻量、灵活迁移 |
隔离性 | 完全隔离 | 安全隔离 |
部署 | 慢、分钟级 | 快速、秒级 |
运行密度 | 一般几十个 | 单机支持上千容器 |
官方站点: https://docs.docker.com/
阿里云开源镜像站: https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/ stable/Packages/
二、安装部署
让虚拟机能联网--真机中:
配置软件仓库
docker1:
安装docker-ce 、启动服务
cd /etc/yum.repos.d/
ls
wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
vim docker-ce.repo
yum repolist
wget https://mirrors.aliyun.com/repo/Centos-7.repo
vim Centos-7.repo ##修改配置文件
yum repolist
yum install -y docker-ce
systemctl start docker
systemctl enable --now docker ##设置开机自启动
vim docker-ce.repo
vim centos-7.repo
docker info ##查看docker 信息
cd /etc/docker #docker的配置目录
docker info 桥接有问题
sysctl -a | grep bridge-nf-call-iptables
vim /etc/sysctl.d/docker.conf #创建docker.conf文件。打开桥接
sysctl --system #生效
docker info
cd
docker search yakexi007 #查找
docker pull yakexi007/game2048 ##拉取
vim /etc/sysctl.d/docker.conf
docker images ##查看镜像
ll -d /var/lib/docker/
docker run -d --name demo -p 80:80 yakexi007/game2048 ## -d打入后台 -p端口映射,冒号前是宿主机端口,冒号后是容器内端口docker ps ##查看docker进程
在浏览器中输入172.25.254.1
三、docker镜像构建和dockerfile详解
分层结构的好处是共享资源
1、镜像构建
docker commit 构建新镜像
commit:从已经创建的容器中更新镜像,并且提交这个镜像
Dockerfile:使用 Dockerfile 指令来创建一个新的镜像
1 docker pull busybox ##拉取busybox
2 docker images ##查看镜像
3 docker info
4 docker search busybox
5 docker images
6 docker history yakexi007/game2048:latest
7 docker history busybox:latest
8 docker ps
9 docker rm -f demo ##删除容器
运行容器 # docker run -it --name demo busybox
修改容器 (以下命令在容器内运行) # touch file1
将容器保存为新的镜像 # docker commit demo demo:v1
查看镜像 # docker images demo:v1
docker run -it --name demo busybox ##-i: 交互式操作 按ctrl+d退出,建立文件
docker ps
docker ps -a 看到容器运行已经停止
docker start demo
docker ps -a
docker attach demo 进入容器看到建立的文件还在,#按住ctrl+p+q 相当于打入后台
docker ps -a
docker stop demo
docker ps -a
docker rm demo
docker ps -a
docker run -it --name demo busybox ##重新进去文件已经不在 ,建立文件
docker commit demo demo:v1
docker history demo:v1 #可以看到有三层
docker history busybox:latest
docker rm demo #删除之前创建的demo
docker run -it --name demo demo:v1 ##可以看到之前建立的文件还在
docker rmi demo:v1 ##删除
2、 dockerfile详解
dockerfile常用指令
FROM 指定base镜像,如果本地不存在会从远程仓库下载。
MAINTAINER 设置镜像的作者,比如用户邮箱等。
COPY 把文件从build context复制到镜像 支持两种形式:COPY src dest 和 COPY ["src", "dest"] src必须指定build context中的文件或目录
ADD 用法与COPY类似,不同的是src可以是归档压缩文件,文件会被自动解压到dest,也可以自动下载URL并拷贝到镜像: ADD html.tar /var/www ADD http://ip/html.tar /var/www
ENV 设置环境变量,变量可以被后续的指令使用: ENV HOSTNAME sevrer1.example.com
EXPOSE 如果容器中运行应用服务,可以把服务端口暴露出去: EXPOSE 80
VOLUME 申明数据卷,通常指定的是应用的数据挂在点: VOLUME ["/var/www/html"]
WORKDIR 为RUN、CMD、ENTRYPOINT、ADD和COPY指令设置镜像中的当前工作目录,如果目录不存在会自动创建
RUN 在容器中运行命令并创建新的镜像层,常用于安装软件包: RUN yum install -y vim
CMD 与 ENTRYPOINT 这两个指令都是用于设置容器启动后执行的命令,但CMD会被docker run后面的命令行覆盖,而ENTRYPOINT不会被忽略,一定会被执行。 docker run后面的参数可以传递给ENTRYPOINT指令当作参数。 Dockerfile中只能指定一个ENTRYPOINT,如果指定了很多,只有最后一个有效。
Shell和exec格式的区别
Shell格式底层会调用/bin/sh -c来执行命令,可以解析变量,而下面的exec格式不会;
Exec格式时,ENTRYPOINT可以通过CMD提供额外参数,CMD的额外参数可以在容器启动时动态替换。在shell格式时ENTRYPOINT会忽略任何CMD或docker run提供的参数。
mkdir docker ##建立一个空目录
cd docker/
ls
vim Dockerfile
ll
docker build --help #构建,默认会读取Dockerfile的文件
docker build -t demo:v1 . #构建镜像;从当前加载数据
docker images
docker history demo:v1 从v1中可以看到做了什么
docker run --rm -it demo:v1
vim Dockerfile 多加了一层
docker build -t demo:v2 . 之前都是缓存
docker history demo:v2 ##查看镜像的分层结构
docker history yakexi007/game2048:latest
docker rmi demo:v1
docker rmi demo:v2
vim Dockerfile
docker search nginx
echo www.westos.org > index.html
docker build -t demo:v1 .
docker history demo:v1
docker run --rm -it demo:v1
cd docker
pwd
ls
cat Dockerfile
vim Dockerfile
docker run --rm -it demo:v2
docker build -t demo:v2 .
docker history demo:v2
docker run --rm -it demo:v2
vim Dockerfile
docker run --rm -it demo:v2 .
docker rmi demo:v1 ##删除镜像
docker rmi demo:v2
vim Dockerfile
把文件从build context复制到镜像
vim Dockerfile
添加:COPY index.html /
docker search nginx
echo www.westos.org > index.html
docker build -t demo:v1 .
docker history demo:v1
docker run --rm -it demo:v1
进入镜像查看
在真机中把nginx1.21.5传到docker1的/root/docker中
vim Dockerfile
添加:ADD nginx-1.21.5.tar.gz /
ADD html.tar /var/www
ADD http://ip/html.tar /var/www
文件会被自动解压到dest
可以看到解压的nginx文件
ENV:设置环境变量,变量可以被后续的指令使用:ENV HOSTNAME server1.example.com
vim Dockerfile
添加:
ENV hostname docker1
CMD echo $hostname
容器是以桥接的方式桥接到docker0,启动docker以后会有docker0接口
容器中运行应用服务,可以把服务端口暴露出去
yakexi007/mario的端口为8080
VOLUME: 申明数据卷,通常指定的是应用的数据挂载点
启动容器 docker run 的时候,我们可以通过 -v 参数修改挂载点。
vim Dockerfile
添加: VOLUME /data
运行可以在容器内的/data就建立文件
查看数据卷
docker inspect xxxxx #接容器id看容器的详尽信息
cd /var/lib/docker/volumes/8b1a8d183256133098daf7b1e93ba33955814cc702035f665151fe29b4e473a2/_data
#进入挂接的mul
实现容器目录和宿主机的同步
CMD
类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:
CMD 在docker run 时运行。
RUN 是在 docker build。
作用:为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。
注意:如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。
vim Dockerfile
添加:CMD echo "hello world"
docker build -t demo:v5 .
docker volume ls
docker ps -a
docker run --rm demo:v5 #显示出来是变量,不是变量解析
vim Dockerfile
修改:CMD echo "hello $hostname"
vim Dockerfile
docker build -t demo:v6 .
docker run --rm demo:v6 #出来的是变量解析
拉取nginx 查看历史信息
vim Dockerfile
最后一行修改为:
ENTRYPOINT ["/bin/sh", "-c", "echo hello, $name"]
vim Dockerfile
最后一行修改为:
ENTRYPOINT ["/bin/echo", "hello"]
CMD ["world"]
docker run --rm demo:v8 linux
docker run --rm demo:v8 redhat
docker run --rm demo:v8 westos #会把CMD覆盖掉,但是ENTRYPOINT是不动的
四、镜像优化(nginx的封装)
docker images | grep demo | awk '{system("docker rmi "$1":"$2"" )}'
#删掉不用的镜像
cd docker/
ls
docker pull centos:7
docker images
vim Dockerfile
docker build -t demo:v1 . ##构建镜像
docker images #构建的镜像是610M(内存有点大)
docker run -d --name demo demo:v1 ##运行
docker inspect demo #查看容器详细信息,可以获得ip
容器的ip为172.17.0.2,之后访问这个ip
1、镜像的优化--------减少镜像的层数
更改Dockerfile文件将多个RUN层合并为一层:
成功后查看镜像大小发现变成了442MB
减少中间层数可以优化镜像
2、镜像的优化-----使用多阶段构建
更改Dockerfile文件:
成功后查看镜像大小发现变成了208MB:多阶段构建可以明显减少镜像的大小
3、镜像的优化-----使用更为精简的基础镜像
使用的基础镜像是google提供的base-debian10镜像,它非常小,仅为19.2M,因此可以从源头减小build后镜像的大小
docker load -i base-debian10.tar
#把真机传输过来的base镜像,指定打包到系统里
docker run --rm -it demo:v3 bash ##打开bash要覆盖掉nginx的进程
ldd /usr/local/nginx/sbin/nginx #二进制程序在运行时会调用系统的函数库
编辑Dockerfile文件:
注意:以上文件内容可以从github找到,搜索:
distroless nginx
,网址:https://github.com/evry-ace/nginx-distrolesshttps://github.com/evry-ace/nginx-distroless
查看镜像大小发现大小仅为31.7M,说明这种方法可以大幅减小镜像的大小。
docker run -d --name demo demo:v4 ##运行可以成功
docker inspect demo #查看详细信息,拿到ip