dockerfile怎么构成镜像的,研发运维必看

docker命令基础框架

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ieTKpBej-1628998514906)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1595423552130.png)]

如图,docker所有操作基本上离不开镜像,那么镜像的操作都会,但是,镜像是怎么构成的呢?

对于镜像的作用和用途,如下

镜像

Docker的镜像 ( image ) 是创建容器的基础, 是一个只读模板,可以用来创建docker容器, 类似虚拟机的快照,可以理解为是一个面向 Docker容器引擎的只读模板。比如一个镜像可以是一个完整的 Centos操作系统环境,称为一个 Centos镜像:可以是一个安装了MySQL的应用程序,称为一个MySQL镜像,等等,我们可以把所需要的一切都打包成镜像, 打包后的镜像在某台机器上能运行,那它就能够在任何装有docker的机器上运行

下面还有对镜像的补充、、、、、

镜像是什么?

镜像是一种轻量级可执行的独立软件包用来打包软件的运行环境和基于运行环境开发的软件,它包含运行某个软件所需要的内容,包括代码,运行时,库,环境变量和配置文件。

联合文件系统(UnionFS)

了解镜像之前,先了解联合文件系统,docker镜像是一层一层叠上来的,每一层镜像都会有一个id,但是最后只会显示最后一层的id;有人说这种架构像是洋葱,有人能说像花卷,你认为呢???

UnionFS(联合文件系统):UnionFS文件系统是一种分层,轻量级并高性能的文件系统,它支持对文件系统的修改作为一次提交来一层一层的叠加,UnionFS文件系统是Docker镜像的基础,镜像可以通过分层来继承,基于基础镜像,可以做出各种的应用镜像

docker镜像加载

docker镜像实际上有一层一层的文件系统组成,这种层次的文件系统(UnionFS)

我们知道docker和宿主机共享linux内核(kernel),其实原理是这样的:

linux启动会加载bootfs文件系统,所以docker镜像最底层也就是bootfs

当bootfs加载完成以后整个内核就会在内存,此时bootfs就没有用了,会被系统卸载;

rootfs就是典型的不同的linux系统的发行版,比如:Ubuntu,centos,包括/dev /proc /bin /etc/ …

对于一个docker精简的OS,rootfs可以很小,只需要最基本的命令,工具,程序库就可以了,但是底层kernel和宿主机一样,所以有人也说,每一个docker容器都是一个精简的linux环境。

docker镜像加载过程
在这里插入图片描述

镜像的分层

我们拉取一个镜像或者dockerfile生成一个镜像时都是这样一层一层的
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vS6Px77n-1628998514910)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1595592920292.png)]

那么为什么需要分层呢?

最大的好处——共享资源

也就是下面我们要说的docker镜像缓存特性

dockerfile构建镜像

  • dockerfile的书写格式为:Dockerfile
  • FROM: 构建镜像有两种方式,一种是scratch(从零构建),另一种可以基于某个镜像开始构建
  • 镜像所运行的操作(用户自定义的)

编写一个简单的dockerfile

 切记,一个目录默认只能运行一个Dockerfile,Default is 'PATH/Dockerfile',注意Dockerfile的格式,D要大写,不能错,除此之外,通过-f 指定dockerfile的文件名+绝对路径的方式也可以哦
[root@docker01 ~]# mkdir dockerfile && cd dockerfile
[root@docker01 dockerfile]# ls
Dockerfile
[root@docker01 dockerfile]# vim Dockerfile
FROM centos:7
RUN yum -y install vim
RUN yum -y install net-tools
CMD ["/bin/bash"]

基于dockerfile创建镜像

[root@docker01 ~]# docker build -t new02:centos /root/dockerfile

因为之前built过次镜像,所以出现这种情况

Sending build context to Docker daemon  2.048kB
Step 1/4 : FROM centos:7
 ---> b5b4d78bc90c
Step 2/4 : RUN yum -y install vim
 ---> Using cache
 ---> 7f5cb26c1891
Step 3/4 : RUN yum -y install net-tools
 ---> Using cache
 ---> 79d2860a90c1
Step 4/4 : CMD ["/bin/bash"]
 ---> Using cache
 ---> 7ffcfd3ab131
Successfully built 7ffcfd3ab131
Successfully tagged new02:centos

也证实了上面的提到的docker分层的好处

docker镜像缓存特性

缓存可以用的要求:

  • 如果在相同的层,有用到相同的镜像,可以不必再去下载,直接使用缓存
  • 必须是相同的层,相同的镜像
  • 如果前边的层发生改变,即使后边的层操作和顺序一样,也不能使用 缓存特性
[root@docker01 ~]# docker build -t new02:centos /root/dockerfile --no-cache 

dockerfile常用的指令 🐷

指令作用
FROM构建镜像基于哪个镜像
MAINTAINER镜像维护者姓名或邮箱地址
RUN构建镜像时运行的shell命令
CMD运行容器时执行的shell命令
EXPOSE运行容器后声明容器的服务端口
ENV设置容器环境变量
ADD拷贝文件或目录到镜像,会自动下载或自动解压
COPY拷贝文件或目录到镜像
VOLUME指定运行容器挂载点到宿主机自动生成的目录(默认/var/lib/docker/volumes),类似manager volume挂载
USER为RUN、CMD、和ENTRYPOINT执行命令指定运行用户
WORKDIR类似linux的cd,容器运行后所在的目录
HEALTHCHECK健康检查
ENTRYPOINT运行容器时执行的shell命令
PS注意事项:
1. RUN在building时运行,可以写多条。其实RUN是有条件限制的
2. CMD和ENTRYPOINT在运行container时运行,只能写一条,如果写多
条,最后一条生效
区别:
CMD “ls,"a" 构建时在命令行里面不能在显示追加的内容
ENTRYPORT “ls,"a" 构建的时候在命令行可以显示追加内容例如:docker run -it id -l
3. 如果在Dockerfile里需要往镜像内导入文件,则,此文件必须在
dockerfile所在目录或子目录下
4. 一个目录下,只能有一个Dockerfile文件,并且名称的大小写严格按照
要求: Dockerfile.

例子:Dockerfile构建nginx

基于centos7的环境搭建nginx

FROM centos:7
RUN yum -y install gcc pcre pcre-devel zlib zlib-devel openssl openssl-devel
COPY nginx-1.17.5.tar.gz /usr/local

WORKDIR /usr/local/
RUN tar -zxf /usr/local/nginx-1.17.5.tar.gz
RUN useradd -M -s /sbin/nologin nginx

WORKDIR /usr/local/nginx-1.17.5/
RUN ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx && make && make install

WORKDIR /root
RUN ln -s /usr/local/nginx/sbin/* /usr/local/sbin/
RUN nginx -t
RUN nginx

EXPOSE 80
COPY index.html /usr/local/nginx/html/
#CMD [ "nginx" "-g" "daemon off" ]

默认开启进入容器的的时候,nginx不会开启,需要添加 nginx -g "daemon off"

[root@docker01 t5]# docker built -t dc05:nginx .
[root@docker01 t5]# docker run -itd --name dc10 dc05:nginx nginx -g "daemon off;"
2b691183e572300b01dc565860ea97eaa28574a8b2f651f4010ea094d81b7e41
[root@docker01 t5]# docker exec -it dc10 /bin/bash
[root@2b691183e572 ~]# 
[root@2b691183e572 ~]# curl 127.0.0.1
123.com

dockerfile构建httpd

基于centos:7 🦌

FROM centos:7
RUN yum -y install httpd
ENV dir=/var/www/html/index.html
COPY index.html $dir
ADD run.sh /root/run.sh
RUN chmod 755 /root/run.sh
EXPOSE 80
CMD ["/root/run.sh"]

开启容器时启动httpd,vim run.sh

#!/bin/bash
exec /usr/sbin/httpd -D FOREGROUND #前台开启httpd

基于httpd镜像构建

FROM httpd:latest
ENV dir=/usr/local/apache2/htdocs/index.html
COPY index.html $dir
EXPOSE 80

dockerfile 构建tomcat

FROM centos:7

ADD apache-tomcat-8.5.55.tar.gz /usr/local/
ADD jdk-8u261-linux-x64.tar.gz /usr/local/

RUN yum -y install vim

ENV MYPATH /usr/local
WORKDIR $MYPATH


ENV JAVA_HOME /usr/local/jdk1.8.0_261
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.55
ENV CATALINA_BASH /usr/local/apache-tomcat-8.5.55
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin

EXPOSE 8080

CMD ["/usr/local/apache-tomcat-8.5.55/bin/catalina.sh","run"]

构建镜像

[root@docker01 ~]# docker build -t mytomcat /tomcat/

根据这个 镜像启动一个容器

[root@docker01 ~]# docker run -itd --name dc02 -P -v /root/tomcat/test:/usr/local/apache-tomcat-8.5.55/webapps/test -v /var/log/tomcat:/usr/local/apache-tomcat-8.5.55/logs mytomcat

模拟部署一个项目发布

做了目录挂载,所以项目部署在宿主机即可

需要在宿主机提添加WEB-INF和web.xml

[root@docker01 test]# mkdir WEB-INF
[root@docker01 test]# ls
WEB-INF 
[root@docker01 test]# cd WEB-INF/
[root@docker01 WEB-INF]# vim web.xml
[root@docker01 WEB-INF]# cd ..
[root@docker01 test]# vim index.jsp

随便摘一个web.xml

<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<description> Test App</description>
</web-app>

写一个jsp的测试页

print time <%=new java.util.Date()%>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BpxKDH2L-1628998514913)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1596077533306.png)]

docker构建redis高可用集群

拉取redis的官方镜像

docker pull redis

在宿主机上创建redis的数据文件和配置文件;

#!/bin/bash
for port in $(seq 1 6)
do
mkdir -p /opt/redis_cluster/redis_node${port}_6379/conf
mkdir -p /data/redis_cluster/redis_node${port}_6379
cat > /opt/redis_cluster/redis_node${port}_6379/conf/redis_node${port}_6379.conf << EOF
bind 0.0.0.0
port 6379
cluster-enabled yes                  
cluster-config-file clusters_6379.conf   
cluster-node-timeout 15000
cluster-announce-ip 172.16.0.1$port
cluster-announce-port 6379
cluster-announce-bus-port 16379		
appendonly yes
appendfilename "redis_node${port}_6379.aof"
appendfsync everysec
EOF
done

启动redis容器

docker run -p 6371:6379 -p 16371:16379 --name redis-1 -v /opt/redis_cluster/redis_node1_6379/conf/redis_node1_6379.conf:/etc/redis/redis.conf -v /data/redis_cluster/redis_node1_6379:/data -d --net redis --ip 172.16.0.11 redis:latest redis-server /etc/redis/redis.conf

脚本创建redis容器

for port in $(seq 1 6)
do
docker run -itd -p 637${port}:6379 -p 1637${port}:16379 --name redis-${port} -v /opt/redis_cluster/redis_node${port}_6379/conf/redis_node${port}_6379.conf:/etc/redis/redis.conf -v /data/redis_cluster/redis_node${port}_6379:/data -d --net redis --ip 172.16.0.1${port} redis:latest redis-server /etc/redis/redis.conf
done

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Rr6LB8q2-1628998514916)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1596083246816.png)]

进入redis,创建redis高可用集群

[root@docker01 ~]# docker exec -it redis-1 /bin/bash
root@d2dcc044beac:/data# redis-cli --cluster create 172.16.0.11:6379 172.16.0.12:6379 172.16.0.13:6379 172.16.0.14:6379 172.16.0.15:6379 172.16.0.16:6379 --cluster-replicas 1
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 172.16.0.15:6379 to 172.16.0.11:6379
Adding replica 172.16.0.16:6379 to 172.16.0.12:6379
Adding replica 172.16.0.14:6379 to 172.16.0.13:6379
M: 19c9265cf4becb247852ac0a14a005f253db107d 172.16.0.11:6379
   slots:[0-5460] (5461 slots) master
M: cf3cecfe839469f5b67524ffa01a81e808ce73de 172.16.0.12:6379
   slots:[5461-10922] (5462 slots) master
M: 9a9a1ae0056cf6bff9fbf0d970f83c9a77d88792 172.16.0.13:6379
   slots:[10923-16383] (5461 slots) master
S: 9ddbc99ff157c146a5896b1e51ce4cbc861dbea6 172.16.0.14:6379
   replicates 9a9a1ae0056cf6bff9fbf0d970f83c9a77d88792
S: 7548e76a8a580b1987650c5de3b489f50b6ad935 172.16.0.15:6379
   replicates 19c9265cf4becb247852ac0a14a005f253db107d
S: c2146da9e2474fed1cd461e325ab00698e4a95f0 172.16.0.16:6379
   replicates cf3cecfe839469f5b67524ffa01a81e808ce73de
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
.
>>> Performing Cluster Check (using node 172.16.0.11:6379)
M: 19c9265cf4becb247852ac0a14a005f253db107d 172.16.0.11:6379
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
S: 7548e76a8a580b1987650c5de3b489f50b6ad935 172.16.0.15:6379
   slots: (0 slots) slave
   replicates 19c9265cf4becb247852ac0a14a005f253db107d
M: cf3cecfe839469f5b67524ffa01a81e808ce73de 172.16.0.12:6379
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: 9ddbc99ff157c146a5896b1e51ce4cbc861dbea6 172.16.0.14:6379
   slots: (0 slots) slave
   replicates 9a9a1ae0056cf6bff9fbf0d970f83c9a77d88792
M: 9a9a1ae0056cf6bff9fbf0d970f83c9a77d88792 172.16.0.13:6379
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: c2146da9e2474fed1cd461e325ab00698e4a95f0 172.16.0.16:6379
   slots: (0 slots) slave
   replicates cf3cecfe839469f5b67524ffa01a81e808ce73de
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

验证集群

root@d2dcc044beac:/data# redis-cli -c -h 172.16.0.16 -p 6379
172.16.0.16:6379> set k1 v1
-> Redirected to slot [12706] located at 172.16.0.13:6379
OK
172.16.0.13:6379> set k2 v2
-> Redirected to slot [449] located at 172.16.0.11:6379
OK
172.16.0.11:6379> get k1
-> Redirected to slot [12706] located at 172.16.0.13:6379
"v1"
172.16.0.13:6379> get k2
-> Redirected to slot [449] located at 172.16.0.11:6379
"v2"
172.16.0.11:6379> 

验证高可用

# 验证高可用,停掉redis-3 master
[root@docker01 ~]# docker stop redis-3
redis-3
172.16.0.16:6379> CLUSTER NODES
7548e76a8a580b1987650c5de3b489f50b6ad935 172.16.0.15:6379@16379 slave 19c9265cf4becb247852ac0a14a005f253db
19c9265cf4becb247852ac0a14a005f253db107d 172.16.0.11:6379@16379 master - 0 1596082825000 1 connected 0-546
cf3cecfe839469f5b67524ffa01a81e808ce73de 172.16.0.12:6379@16379 master - 0 1596082824000 2 connected 5461-
9ddbc99ff157c146a5896b1e51ce4cbc861dbea6 172.16.0.14:6379@16379 master - 0 1596082821731 7 connected 10923
9a9a1ae0056cf6bff9fbf0d970f83c9a77d88792 172.16.0.13:6379@16379 master,fail - 1596082761527 1596082758000 
c2146da9e2474fed1cd461e325ab00698e4a95f0 172.16.0.16:6379@16379 myself,slave cf3cecfe839469f5b67524ffa01a8
172.16.0.16:6379> 
#再次获取数据,原来放到redis-3的k1已经放到了redis-4上
root@d2dcc044beac:/data# redis-cli -c -h 172.16.0.14 -p 6379
172.16.0.14:6379> get k1
"v1"

oK,完成!🐒

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值