文章目录
1.在虚拟机上安装docker-ce
1.1 安装
- 依赖性包过多,配置docker-ce和centos7的repo源
- 替换
- 安装
以下均在docker运行的虚拟机server1上配置:
vim docker.repo
[docker]
name=docker-ce
baseurl=https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/stable/
gpgcheck=0
配置centos7repo
在阿里镜像站:
curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
sed -i -e '/mirrors.cloud.aliyuncs.com/d' -e '/mirrors.aliyuncs.com/d' /etc/yum.repos.d/CentOS-Base.repo
执行完成后,由于本机为rhel7,所以在yum repolist
时会出现版本不匹配问题:
此时进入CentOS7.repo,替换以下:
:%s/$releasever/7/g
此时repo源配置成功
此时成功安装:
yum install docker-ce -y
启动docker:systemctl start docker
加入开机启动容器服务:systemctl enable docker
查看本机容器信息:docker info
此时由于docker是在虚拟机上,需要打开虚拟机桥街模式,在虚拟机内核设置中:
过滤:sysctl -a |grep bridge-nf-call-iptables
vim /etc/sysctl.d/docker.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
查看系统相关参数:sysctl --system
配置已生效.容器启动后,会在本地生成一个docker0的桥接口,所有的容器都会桥街到该网卡上并且容器的网关都指向172.17.0.1
1.2 加速
在此使用阿里云的加速方式
注册登陆阿里云
点击右上角控制台,进入以后选择容器镜像服务
在镜像加速器中获得属于自己系统的加速地址:
vim /etc/docker/daemon.json
{
"restry-mirrors": ["https://6ll7oaaj.mirror.aliyuncs.com"]
}
systemctl daemon-reload
systemctl reload docker.service
2. 测试
补齐工具:yum install -y bash-*
搜索镜像:docker search yakexi007
拉取镜像:docker pull yakexi007/game2048
运行容器:docker run -d --name demo -p 80:80 yakexi007/game2048
-d为打入后台运行,只有服务应用才可以后台,基础镜像无法后台运行
查看正在运行的容器:docker ps
删除容器:docker rm -f demo
删除镜像:docker rmi 镜像
导入镜像:docker load -i mario.tar
```docker pull busybox’``
busybox为一个精简的小的开发环境,所有镜像均内核共享宿主机的内核
docker run -it busybox
进入后查看内核uname -r
3. 镜像的分层结构
- 共享宿主机的内核(kernel)
- base镜像提供的是最小的linux发行版(一个镜像由多个块堆叠而成)
- 同一docker主机支持运行多种linux发行版(虽然发行版本不一样,但是linux内核均一样)
- 采用分层结构的最大好处是:共享资源
启动容器时:docker start 名称/镜像id
进入容器内部:docker container attach 容器id
关闭容器:进入容器后 ctrl + d
进入容器后,退出容器并保持容器继续运行:ctrl+p+q
容器所在环境能上网,则容器也能上网,但是外部无法访问到容器,需要做端口映射
已经关闭的容器可以之间删除:docker rm 容器id
设置一旦退出容器,立马删除:docker run -it --rm busybox
- copy-on-write可写容器层
- 容器层以下所有镜像层都是只读的,此项不可改变,若要改变,只能将更改的容器层保存
- docker从上往下依次查找文件
- 容器层保存镜像变化的部分,并不会对镜像本身进行任何修改
- 一个镜像最多127层
4. 镜像的构建
4.1 docker commit
- docker commit构建新镜像三部曲
– 运行容器
– 修改容器
– 将容器保存为新的镜像 - 缺点:
– 效率低,可重复性弱,容易出错
– 使用者无法对镜像进行审计,存在安全隐患(无法知道对该层具体操作了什么)
在退出容器后,通过docker ps -a
可以查看到已经退出的容器,若要修改保存该镜像,什么
执行:docker commit -m "add files" demo demo:v1
4.2 dockerfile
从一个dockerfile中构建一个image:docker build [OPTIONS] PATH | URL | -
默认是在i当前目录下寻找文件
vim /root/docker/Dockerfile
FROM busybox #开始的基础镜像,基础镜像无需自己编译
RUN touch file1
RUN mkdir test
构建:docker build -t demo:v1 .
此时,查看history可以看到每一层的构建过程,内部机制为:每一次均为docker commit进行提交,build为多个commit的集合
此时,可以在上一部构建基础上继续构建:
FROM demo:v1
RUN touch file2
RUN mkdir test2
此时,在demo:v1的基础上继续添加:
5.Dockerfile详解(构建镜像的重点)
5.1 dockerfile常用指令
-
FROM
– 指定base镜像,如果本地不存在则会从远程仓库下载 -
MAINTAINER
–设置镜像的作者,比如用户邮箱等 -
COPY
–把文件从build context复制到镜像
– 支持两种形式:COPY src dest 和 COPY ["“src”,“dest”]
– src必须指定build context中的文件或目录 -
ADD
– 用法与COPY类似,不同的是src可以是归档压缩文件,支持外部路径甚至网络,将外部的压缩文件导入镜像并自动解压
– ADD html.tar /var/www;ADD http://ip/html.tar /var/www -
ENV
–设置环境变量,变量可以被后续的指令使用
– ENV HOSTNAME server1.example.com -
EXPOSE
– 如果容器内运行应用服务,可以把服务端口暴露出去
– 在运行服务类的容器时需要做端口映射,否则无法访问
– 查看端口占用:netstat -antlp
– EXPOSE 80
– -p 80:80指定端口, -P 随即分配不会冲突的端口 -
VOLUME
– 声明数据卷,通常制定的是应用的数据挂载点,不建议对容器进行大规模的数据读写
– VOLUME ["/var/www/html"]
– 容器在运行时自动挂载虚拟机的/proc -
WORKDIR
– 为RUN,CMD,ENTRYPOINT,ADD和COPY指令设置镜像中的当前工作目录,如果目录不存在会自动创建 -
RUN
– 在容器内运行命令并创建新的镜像层,常用于安装软件包
– RUN yum install -y vim -
CMD 与 ENTERPOINT
– 两指令都是用于设置容器启动后执行的命令,CMD会被docker run后面的命令覆盖,而ENTERPOINT不会被忽略,一定会被执行。
– docker run后面的参数可以传递给ENTERPOINT指令当参数。
– Dockerfile中只能指定一个ENTERPOINT,如果指定多个,只有最后一个有效
– 例如busybox是开启了一个用cmd开启一个shell,nginx是用cmd开启一个二进制nginx程序
具体过程:
1。在dockerfile文件夹里vim一个index.html
2。编写dockerfile:
#tar zcf test.tar,gz /etc
FROM busybox
RUN touch file1
COPY index.html / #此处意思为,将当前目录下的index.html拷贝到镜像的根目录下
ADD test.tar.gz /mnt
ENV HOSTNAME=server11
EXPOSE 80
VOLUME ["/data"]
3。构建镜像:docker build -t demo:v1 .
4。查看history
5。进入容器查看:docker run -it --rm demo:v1
6。查看容器的具体信息:docker inspect demo
此时删除该docker后,数据仍然能被保存,可用docker volume ls
查看:
删除未挂载的卷:docker volume prune
此处的挂载意思为,当删除了卷挂载的docker后,此卷即未挂载,此时可以删除
7。CMD与ENTERPOINT
FROM busybox
RUN touch file1
COPY index.html /
ADD test.tar.gz /mnt
ENV HOSTNAME=server11
EXPOSE 80
VOLUME ["/data"]
CMD ["/bin/sh","-c","echo hello $HOSTNAME"] #官方推荐使用exec格式书写
FROM busybox
RUN touch file1
COPY index.html /
ADD test.tar.gz /mnt
ENV HOSTNAME=server11
EXPOSE 80
VOLUME ["/data"]
ENTRYPOINT ["echo","hello"]
CMD ["world"]
在运行容器时,若带上变量实例,则会覆盖CMD:
使用场景:可以通过容器的方式实现容器集群的辈份
6. 应用的容器化
通过例子举一反三,将常见的例子进行容器化
删除多个容器:
docker rmi `docker images |grep demo | awk '{print $1":"$2}`
6.1 准备基础镜像
因为有依赖性问题,所以不建议使用太过于精简的镜像
在此使用导入的rhel7:docker load -i rhel7.tar
由于该镜像没有任何bash,所以在启动时:
docker run -it --name demo rhel7 bash
启动进入该容器后,配置yum源:
[dvd]
name=rhel7.6
baseurl=http://172.25.38.250/rhel7.6
gpgcheck=0
此时安装时会提示rpmdb损坏:
重置即可:rpmdb --rebuilddb
安装编译软件gcc等:yum install gcc pcre-devel bash-* tar make
6.2 先熟悉应用的二进制源码安装过程
利用二进制源码安装nginx
将nginx包拷贝到容器内:docker cp nginx-1.18.0.tar.gz demo:/mnt/
在容器内进行解压:tar zxf nginx-1.18.0.tar.gz
进入解压文件夹尝试编译:
安装缺失环境:yum install zlib-devel -y
编译成功:
make:
make install:
安装完成:
启动nginx:
/usr/local/nginx/sbin/nginx
在虚拟机上查看的docker的ip并解析:curl 172.17.0.2
6.3 封装镜像
准备文件:
vim Dockerfile
FROM rhel7
COPY dvd.repo /etc/yum.repos.d/
ADD nginx-1.18.0.tar.gz /mnt
WORKDIR /mnt/nginx-1.18.0
RUN rpmdb --rebuilddb
RUN yum install -y gcc make pcre-devel zlib-devel
RUN ./configure
RUN make
RUN make install
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx" , "-g" ,"daemon off;"]
docker build -t webserver:v1 .
查看容器编译记录:
运行容器:docker run -d --name webserver webserver:v1
查看容器docker inspect webserver
,可以看到容器已挂载目录,并且显示其ip
此时在虚拟机上的挂载目录内编写网页,可以用curl解析:
6.4 优化镜像
- 选择最精简的基础镜像
- 减少镜像的层数
- 清理镜像构建的中间产物
- 注意优化网络请求
- 尽量去用构建缓存
- 使用多阶段构建镜像
FROM rhel7
COPY dvd.repo /etc/yum.repos.d/
ADD nginx-1.18.0.tar.gz /mnt
WORKDIR /mnt/nginx-1.18.0
RUN rpmdb --rebuilddb && yum install -y gcc make pcre-devel zlib-devel &> /dev/null && ./configure &> /dev/null && make &> /dev/null && make install &> /dev/null #合并安装项目,并将多余显示扔掉
RUN rm -fr /mnt/nginx-1.18.0 && yum remove -y gcc make && yum clean all #单独一层利用缓存;安装完成后删除源码,清理缓存
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx" , "-g" ,"daemon off;"]
此时压缩效果并不明显,进一步使得编译过程分离:
FROM rhel7 as build
COPY dvd.repo /etc/yum.repos.d/
ADD nginx-1.18.0.tar.gz /mnt
WORKDIR /mnt/nginx-1.18.0
RUN rpmdb --rebuilddb && yum install -y gcc make pcre-devel zlib-devel &> /dev/null && ./configure &> /dev/null && make &> /dev/null && make install &> /dev/null
RUN rm -fr /mnt/nginx-1.18.0 && yum remove -y gcc make && yum clean all
FROM rhel7
COPY --from=build /usr/local/nginx /usr/local/nginx
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx" , "-g" ,"daemon off;"]
此时效果显著;
继续对image-base进行压缩,
导入google的基础镜像:docker load -i base-debian10.tar
,核心为多阶段构建