目录
一、docker简介
1、什么是docker
Docker 使用 Google 公司推出的 Go 语言 进行开发实现,基于 Linux 内核的 cgroup,namespace,以及 AUFS 类的 Union FS 等技术,对进程进行封装隔离,属于 操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。最初实现是基于 LXC,从 0.7 版本以后开始去除 LXC,转而使用自行开发的 libcontainer,从 1.11 开始,则进一步演进为使用 runC 和 containerd。
Docker 在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极大的简化了容器的创建和维护。使得 Docker 技术比虚拟机技术更为轻便、快捷。
传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。
2、docker的优势
更高效的利用系统资源:由于容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,Docker 对系统资源的利用率更高。无论是应用执行速度、内存损耗或者文件存储速度,都要比传统虚拟机技术更高效。因此,相比虚拟机技术,一个相同配置的主机,往往可以运行更多数量的应用。
更快速的启动时间:传统的虚拟机技术启动应用服务往往需要数分钟,而 Docker 容器应用,由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间。
一致的运行环境:开发过程中一个常见的问题是环境一致性问题。由于开发环境、测试环境、生产环境不一致,导致有些 bug 并未在开发过程中被发现。而 Docker 的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现 「这段代码在我机器上没问题啊」 这类问题。
持续交付和部署:对开发和运维(DevOps)人员来说,最希望的就是一次创建或配置,可以在任意地方正常运行。使用 Docker 可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过 Dockerfile 来进行镜像构建,并结合 持续集成(Continuous Integration) 系统进行集成测试,而运维人员则可以直接在生产环境中快速部署该镜像,甚至结合 持续部署(Continuous Delivery/Deployment) 系统进行自动部署。
更轻松的迁移:由于 Docker 确保了执行环境的一致性,使得应用的迁移更加容易。Docker 可以在很多平台上运行,无论是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运行结果是一致的。因此用户可以很轻易的将在一个平台上运行的应用,迁移到另一个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况。
更轻松的维护和扩展:Docker 使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。此外,Docker 团队同各个开源项目团队一起维护了一大批高质量的 官方镜像,既可以直接在生产环境使用,又可以作为基础进一步定制,大大的降低了应用服务的镜像制作成本。
3、对比传统虚拟机总结
4、容器是如何工作的
二、docker的安装部署
让虚拟机能联网--真机中:
iptables -t nat -I POSTROUTING -s 172.25.70.0/24 -j MASQUERADE
配置软件仓库
server1:
安装docker-ce 、启动服务
wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
vim docker-ce.repo
yum repolist
wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
vim CentOS-Base.repo
yum repolist
yum install -y docker-ce #下载安装
systemctl enable --now 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 #查看docker的信息
cd /var/lib/docker/ #docker根目录的地址
ls
cd
docker ps
docker search yakexi007 #查找
docker pull yakexi007/game2048 #拉取
docker run -d --name demo -p 80:80 yakexi007/game2048
#-d打入后台 -p端口映射,冒号前是宿主机端口,冒号后是容器内端口
网页中:172.25.70.1
docker ps
docker rm -f demo
docker search busybox
docker pull busybox
docker images
docker run -it --name demo busybox
--/ # ls
--/ # touch file
--/ # ls
--/ # rm -f file
--/ # ls
docker ps
docker ps -a
docker rm demo
docker ps -a
三、docker镜像构建和dockerfile详解
docker的分层结构
docker images
docker history busybox:latest
docker history yakexi007/game2048:latest
分层结构的好处是共享资源:
docker run -it --name demo busybox
--/ # uname
--/ # uname -a
uname -r #可以看到两者的内核结构是一样的
docker镜像构建
docker ps -a
docker start demo
docker ps
docker attach demo
--/ # ls
--/ # touch file1
--/ # touch file2
--/ # touch file3
docker ps
docker start demo
docker attach demo #按住ctrl+p+q 相当于打入后台
docker ps
docker stop demo
docker ps
docker ps -a
docker commit demo demo:v1
docker images
docker history demo:v1 #可以看到有三层
docker rm demo #删除之前创建的demo
docker ps -a
docker run -it --rm demo:v1 #--rm做完后自动回收
退出
docker ps -a #没有数据,因为退出后自动回收了
cd
dockerfile详解
mkdir docker #创建一个空目录
cd docker/
ls
docker build --help #构建,默认会读取Dockerfile的文件
ls
- FROM:指定base镜像,如果本地不存在会从远程仓库下载
- RUN:在容器中运行并创建新的镜像层,常用于安装软件包
vim Dockerfile
FROM busybox
RUN touch file1 file2 file3
docker build -t demo:v2 . #从当前加载数据
ls
docker images
docker history demo:v2
docker history demo:v1 #对比,从v2中可以看到我们做了什么事情。v1看不到
- CMD与ENTRYPOINT:
这两个指令都是用于设置容器启动后执行的命令,但CMD会被docker run后面的命令行覆盖,而ENTRYPOINT不会被忽略,一定会被执行。
docker run后面的参数可以传递给ENTRYPOINT指令当作参数。
Dockerfile中只能指定一个ENTRYPOINT,如果指定了很多,只有最后一个有效。
vim Dockerfile
添加:CMD echo "hello world"
docker build -t demo:v3 . #v后跟的数字不可以重复
docker history demo:v3 #在v2的层数上再加了一层
docker run --rm demo:v3 #运行后删掉
- COPY:把文件从build context复制到镜像
支持两种格式:COPY src(原地址) dest(目标地址) 和 COPY ["src","dest"] #注意src原地址一定要在当前目录下
src必须指定build contsxt中的文件或目录
vim Dockerfile
添加:COPY index.html /
echo www.westos.org > index.html
ls
docker build -t demo:v4 .
docker history demo:v4
docker run --rm demo:v4 cat /index.html #镜像后是可以跟定制指令。
docker run --rm demo:v4 ls /
ls
- ADD:用法与COPY类似,不同的是src可以是归档压缩文件,文件会被自动解压到dest,也可以自动下载URL并拷贝到镜像
ADD html.tar /var/www
ADD http://ip/html.tar /var/www
在真机中把nginx1.20.2传到server1中
cd
ls
mv /root/nginx-1.20.2.tar.gz .
vim Dockerfile
添加:ADD nginx-1.20.2.tar.gz /
docker build -t demo:v5 .
docker run --rm demo:v5 ls / #可以看到跟下解压的nginx文件
- ENV:设置环境变量,变量可以被后续的指令使用:ENV HOSTNAME server1.example.com
vim Dockerfile
添加:
ENV hostname server1
CMD echo $hostname
docker build -t demo:v6 .
docker run --rm demo:v6
docker history demo:v6
ip addr #容器是以桥接的方式桥接到docker0,启动docker以后会有docker0接口
- VOLUME: 申明数据卷,通常指定的是应用的数据挂载点
vim Dockerfile
添加: VOLUME ["/data"]
docker build -t demo:v7 .
docker history demo:v7
docker ps -a
docker run -it --rm demo:v7 sh #-it是交互式
--/ # ls
--/ # cd data/
--/data # ls
--/data # pwd
--/data # touch file
--/data # ls
--/data # rm -f file
--/data # ls
--/data # cp /index.html . #把文件拷贝到当前目录
--/data # ls
按住ctrl+p+q
docker ps
docker inspect 19f7a82bc444 #接容器id看容器的详尽信息
cd /var/lib/docker/volumes/a559169cef68641947ec625f20581105abd695b4d966e5e25f31845aa731d05e/_data
#进入挂接的mul
ls #可以看到宿主机的目录和容器的目录是完全互通的
rm -f index.html
cp /etc/passwd .
ls
cd
docker ps
docker attach 19f7a82bc444 #附加进去
--/data # ls #目录里文件也变成passwd了
--/data # pwd
docker ps -a
cd /var/lib/docker/ #所有的数据都在这里
ls
ll
cd docker/
vim Dockerfile
添加:CMD ["/bin/echo","$hostname"]
docker build -t demo:v8 .
docker run --rm demo:v8 #显示出来是变量,不是变量解析
vim Dockerfile
修改:CMD ["/bin/echo", "-c", "echo $hostname"]
docker rmi demo:v8
docker run --rm demo:v8 #出来的是变量解析
vim Dockerfile
最后一行修改为:
ENTRYPOINT ["/bin/echo", "hello"]
CMD ["world"]
docker build -t demo:v9 .
docker run --rm demo:v9
docker run --rm demo:v9 linux #会把CMD覆盖掉,但是ENTRYPOINT是不动的
docker run --rm demo:v9 westos
cd
- Shell和exec格式的区别:
# cat Dockerfile
FROM busybox
ENV name world
ENTRYPOINT echo "hello, $name"Shell格式底层会调用/bin/sh -c来执行命令,可以解析变量,而下面的exec格式不会:
# cat Dockerfile
FROM busybox
ENV name world
ENTRYPOINT ["/bin/echo", "hello, $name"]需要改写成以下形式:
# cat Dockerfile
FROM busybox
ENV name world
ENTRYPOINT ["/bin/sh", "-c", "echo hello, $name"]Exec格式时,ENTRYPOINT可以通过CMD提供额外参数,CMD的额外参数可以在容器启动时动态替换。在shell格式时ENTRYPOINT会忽略任何CMD或 docker run提供的参数。
# cat Dockerfile
FROM busybox
ENTRYPOINT ["/bin/echo", "hello"]
CMD ["world"]
看下在运行容器时的区别:
# docker run --rm busybox:v1
hello world
# docker run --rm busybox:v1 linux
hello linux官方推荐使用exec格式书写
- WORKDIR:为RUN、CMD、ENTRYPOINT指令设置镜像中的当前工作目录,如果目录不存在会自动创建
- EXPOSE: 如果容器中运行应用服务,可以把服务端口暴露出去:EXPOSE 80
四、镜像优化(nginx的封装)
docker images | grep demo
docker images | grep demo | awk '{system("docker rmi "$1":"$2"" )}'
#删掉不用的镜像
docker images
ls
cd docker/
ls
docker search centos
docker pull centos #拉取
docker images
docker run -it --rm centos
--ls
--uname -a
--cat /etc/redhat-release #可以看到版本是8.4的
--yum repolist
--cd
run -it --name demo centos
--ls
--cd /etc/yum.repos.d/
--ls
--rm -rf *
--curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-8.repo
--vi CentOS-Base.repo
--yum reoolist
--yum install -y gcc pcre-devel openssl-devel make #下载其依赖性
--ls
--cd
在开启一个server1的中端(要放nginx的压缩包)
ssh root@172.25.70.1
cd docker/
ls
docker cp nginx-1.20.2.tar.gz demo:/mnt #把nginx考入容器内的根下/mnt
在另外一台server1中
--cd /mnt/
--ls
--tar zxf nginx-1.20.2.tar.gz
--ls
--cd nginx-1.20.2
--ls
--./configure --with-http_ssl_module
--vi auto/cc/gcc
#注释掉debug。这样编译出来会更小
--./configure --with-http_ssl_module
--make
--make install
--cd /usr/local/nginx/sbin/
--ls
--./nginx #运行nginx
--ps ax
换一台终端:
cd docker/
docker cp demo:/etc/yum.repos.d/CentOS-Base.repo . #把容器的文件考出来
ls
vim Dockerfile
docker build -t webserver:v1 .
docker images #构建的镜像是438兆(内存还是有点大)
docker ps -a
docker rm demo
docker run -d --name demo webserver:v1 #运行
docker ps
docker inspect demo #查看容器详细信息,可以获得一个ip
curl 172.17.0.2
docker rm -f demo
docker ps
vim Dockerfile
docker build -t webserver:v2 .
docker images #优化后的镜像是232兆
docker run -it --rm webserver:v2 bash #打开bash要覆盖掉nginx的进程
--ls
--ldd /usr/local/nginx/sbin/nginx #二进制程序在运行时会调用系统的函数库
mv Dockerfile Dockerfile.old
ls
换一台终端:
docker load -i base-debian10.tar
#把真机传输过来的base镜像,指定打包到系统里
docker images #查看镜像
cd docker/
docker pull nginx:1.18
进入网页:github.com
vim Dockerfile
docker build -t webserver:v3 .
docker images webserver #可以看到内存的占用为31.7比较小
docker run -d --name demo webserver:v3 #运行,可以成功
docker ps
docker inspect demo #查看详细信息,拿到ip
curl 172.17.0.2