是什么?
Dockerfile是用来构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本
构建三步骤
docker build
命令构建镜像docker run
依镜像运行容器实例Dockerfile内容基础知识:
Docker执行Dockerfile大致流程
docker从基础镜像运行一个容器
执行一条指令并对容器作出修改
执行类似 docker commit 的操作提交一个新的镜像层
docker再基于刚提交的镜像运行一个新容器
执行dockerfile中的下一条指令直到所有指令都执行完成
小总结
从应用软件的角度来看,Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段
Dockerfile是软件的原材料
Docker镜像是软件的交付品
Docker容器则可以认为是软件镜像的运行态,也即依照镜像运行的容器实例
Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及部署与运维,三者缺一不可,合力充当Docker体系的基石。
保留字 | 描述 |
---|---|
FROM | 基础镜像,当前新镜像是基于哪个镜像的,指定一个已经存在的镜像作为模板,第一条必须是FROM |
MAINTAINFR | 镜像维护者的姓名和邮箱地址 |
RUN | 容器构建时需要运行的命令,一种shell 格式,一种exec 格式,RUN是在 docker build 时运行的 |
EXPOSE | 当前容器对外暴露出的端口 |
WORKDIR | 指定在创建容器后,终端默认登陆的进来工作目录,一个落脚点 |
USER | 指定该镜像以什么样的用户去执行,如果都不指定,默认是root |
ENV | 用来在构建镜像过程中设置环境变量 |
ADD | 将宿主机目录下的文件拷贝进镜像且会自动处理URL和解压tar压缩包 |
COPY | 类似ADD,拷贝文件和目录到镜像中,将从构建上下文目录中<源路径>的文件/目录复制到新的一层的镜像内的<目标路径>位置 |
VOLUME | 容器数据卷,用于数据保存和持久化工作 |
CMD | 指定容器启动后要干的事情,CMD指令也有shell和exec两种格式,Dockerfile中可以有多个CMD指令,但只有最后一个生效,CMD会被 docker run 之后的参数替换,CMD是在 docker run 时运行,RUN是在 docker build 时运行 |
ENTRYPOINT | 也是用来指定一个容器启动时要运行的命令,类似于CMD指令,但是ENTRYPOINT不会被docker run后面的命令覆盖,而且这些命令行参数会被当做参数送给ENTRYPOINT指令指定的程序 |
一、自定义镜像mycentosajva8
要求:centos镜像具备 vim+ifconfig+jdk8,在jdk官网下载jdk-8u411-linux-x64.tar.gz
编写:编写Dockerfile文件,首字母D需要大写,编辑文件:vim Dockerfile
bashFROM centos:7.9.2009
MAINTAINER jerry<[email protected]>
ENV MYPATH /usr/local
WORKDIR $MYPATH
# 安装命令之前,先修改yum源
RUN cd /etc/yum.repos.d/
RUN sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*
RUN sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*
RUN yum update -y
# 安装vim编辑器
RUN yum -y install vim
# 安装ifconfig命令查看网络ip
RUN yum -y install net-tools
# 安装Java8及lib库
RUN yum -y install glibc.i686
RUN mkdir /usr/local/java
# ADD 是相对路径,把 jdk-8u411-linux-x64.tar.gz 添加到容器中,安装包必须要和Dockerfile文件在同一位置
ADD jdk-8u411-linux-x64.tar.gz /usr/local/java
# 配置java环境变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_411
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
ENV PATH $JAVA_HOME/bin:$PATH
EXPOSE 80
CMD echo $MYPATH
CMD echo "success---------ok"
CMD /bin/bash
构建:docker build -t 新镜像名字:TAG .
,注意TAG后面有个空格和一个点,示例:docker build -t centosjava8:1.0 .
运行:docker run -it centosjava8:1.0 /bin/bash
二、虚悬镜像
是什么:仓库名、标签名都是<none>的镜像,俗称dangling image。
bash# 新建一个 Dockerfile
# vim Dockerfile
FROM ubuntu
CMD echo "action is success"
# 构建镜像
docker build .
# 查看镜像
docker images
# 新构建的镜像仓库和标签都是 <none>,这个就是虚悬镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> da3244bb7207 4 weeks ago 78.1MB
查看虚悬镜像
bashdocker image ls -f dangling=true
删除虚悬镜像
bashdocker image prune
把java项目打包一个jar包
通过dockerfile发布微服务部署到docker容器
bash# 编辑Dockerfile文件,vim Dockerfile
# 基础镜像使用java
FROM openjdk:8
# 作者
MAINTAINER jerry
# VOLUME 指定临时文件目录为/tmp,在主机/var/lib/docker目录下创建了一个临时文件并链接到容器的/tmp
VOLUME /tmp
# 将jar包添加到容器中并更改名为 app.jar
ADD Java-1.0-SNAPSHOT.jar app.jar
# 运行jar包
RUN bash -c "touch /app.jar"
ENTRYPOINT ["java","-jar","/app.jar"]
构建镜像:docker build -t app:1.0 .
运行容器:docker run -d app:1.0
安装完docker后,默认会创建3个网络模式,docker容器内部的ip是有可能发生变化的
bash[root@localhost ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
8b829941e2ed bridge bridge local
c3fac193d510 host host local
37a0dd9a3074 none null local
常用基本命令
创建一个新虚拟网络:docker network create 网络名字
bashdocker network create a_network
删除docker中的虚拟网络:docker network rm 网络名字
bashdocker network rm a_network
查看网络源数据:docker network inspect 网络名字
bashdocker network inspect bridge
能干嘛?
网络模式
网络模式 | 描述 |
---|---|
bridge | 为每一个容器分配、设置IP等,并将容器连接到一个docker0 ,虚拟网桥,默认为该模式。 |
host | 容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。 |
none | 容器独有的 Network namespace,但并没有对其进行任何网络设置,如分配 veth pair 和网桥连接,IP等。 |
container | 新创建的容器不会创建自己的网卡和配置自己的IP,而是和一个指定的容器共享IP,端口范围等。 |
bridge模式:使用--network bridge
指定,默认使用docker0
host模式:使用--network host
指定
none模式:使用--network none
指定
container模式:使用--network container:NAME或容器ID
指定
Docker服务默认会创建一个docker0网桥(其上有一个dockero0内部接口),该桥接网络的名称为docker0,它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络。Docker默认指定了docker0接口的IP地址和子网拖码,让主机和容器之间可以通过网桥相互通信
案例:
先运行两个tomcat
bashdocker run -d -p8081:8080 --name tomcat81 tomcat docker run -d -p8082:8080 --name tomcat82 tomcat
在宿主机使用ip addr
命令查看网卡信息
宿主机38: vethff59bb6@if37
网卡对应的容器内的eth0@if38
宿主机40: vetha888fe1@if39
网卡对应的容器内的39: eth0@if40
bash38: vethff59bb6@if37: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 7e:93:04:92:4f:30 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::7c93:4ff:fe92:4f30/64 scope link
valid_lft forever preferred_lft forever
40: vetha888fe1@if39: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 06:bc:8c:ae:25:29 brd ff:ff:ff:ff:ff:ff link-netnsid 1
inet6 fe80::4bc:8cff:feae:2529/64 scope link
valid_lft forever preferred_lft forever
进入其中一个容器执行ip addr
命令
bash39: eth0@if40: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
进入另一个容器查看
bash37: eth0@if38: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
直接使用宿主机的IP地址与外界通讯,不再额外进行NAT转换。
docker启动时指定 --network=host 或 -net=host,如果还指定了-p映射端口,那这个时候就会有警告,并且通过-p设置的参数将不会起到任何作用,端口号会以主机端口号为主,重复时则递增。
在宿主机查看网络配置和进入容器查看网络配置是几乎一样的
bashdocker run -d -p 8083:8080 --network host --name tomcat83 tomcat
# 使用 --network host 模式时可以不写-p参数
docker run -d --network host --name tomcat83 tomcat
禁用网络功能,只有lo标识(就是127.0.0.1表示本地回环),在none模式下,并不为docker容器进行任何网络配置
bashdocker run -d -p 8084:8080 --network none --name tomcat84 tomcat
新建的容器和已经存在的一个容器共享一个网络ip配置而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的
如果已经存在容器挂掉了,新建的容器网络配置就没有共享的配置了
bashdocker run -it --name alpine1 alpine /bin/sh docker run -it --network container:alpine1 --name alpine2 alpine /bin/sh
自定义网络本身就维护好了主机名和ip的对应关系(ip和域名都能通)
先启动2个容器
bashdocker run -d -p 8081:8080 --name tomcat81 tomcat docker run -d -p 8082:8080 --name tomcat82 tomcat
进入2个容器
bashdocker exec -it tomcat82 /bin/bash
docker exec -it tomcat81 /bin/bash
按照IP地址ping是通的
bashroot@86ef8f36808a:/usr/local/tomcat# ping 172.17.0.3
PING 172.17.0.3 (172.17.0.3) 56(84) bytes of data.
64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.059 ms
64 bytes from 172.17.0.3: icmp_seq=2 ttl=64 time=0.049 ms
64 bytes from 172.17.0.3: icmp_seq=3 ttl=64 time=0.050 ms
因为ip地址有可能变化,所以按照服务名ping,但是默认ping不通
bashroot@86ef8f36808a:/usr/local/tomcat# ping tomcat82
ping: tomcat82: Name or service not known
自定义桥接网络,自定义网络默认使用的桥接网络bridge
新建自定义网络
bashdocker network create test_network
新建容器加入自定义网络
bashdocker run -d -p 8081:8080 --network test_network --name tomcat81 tomcat docker run -d -p 8082:8080 --network test_network --name tomcat82 tomcat
互相ping测试,ping服务名就可以ping通了
bashroot@f38210b7ed22:/usr/local/tomcat# ping tomcat82
PING tomcat82 (172.19.0.2) 56(84) bytes of data.
64 bytes from tomcat82.test_network (172.19.0.2): icmp_seq=1 ttl=64 time=0.130 ms
64 bytes from tomcat82.test_network (172.19.0.2): icmp_seq=2 ttl=64 time=0.037 ms
docker-compose 是Docker官方的开源项目,负责实现对Docker容器集群的快速编排
Compose是Docker公司推出的一个工具软件,可以管理多个Docker容器组成一个应用。你需要定义一个YAML格式的配置文件docker-compose.yml,写好多个容器之间的调用关系。然后,只要一个命令,就能同时启动/关闭这些容器,docker-compose解决了容器与容器之间如何编排的问题。
下载安装
bash# 下载安装docker-compose
curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 给应用加上执行权限
chmod +x /usr/local/bin/docker-compose
# 查看版本
docker-compose --version
compose使用的三个步骤
编写Dockerfile定义各个微服务应用并构建出对应的镜像文件
使用docker-compose.yml
定义一个完整业务单元,安排好整体应用中的各个容器服务
执行docker-compose up
命令来启动并运行整个应用程序,完成一键部署上线
常用命令
命令 | 描述 |
---|---|
docker-compose -h | 查看帮助 |
docker-compose up | 启动所有docker-compose服务 |
docker-compose up -d | 启动所有docker-compose服务并后台运行 |
docker-compose down | 停止并删除容器、网络、卷、镜像 |
docker-compose exec yml里面的服务id /bin/bash | 进入容器实例内部 |
docker-compose ps | 展示当前docker-compose编排过的运行的所有容器 |
docker-compose top | 展示当前docker-compose编排过的容器进程 |
docker-compose logs yml里面的服务id | 查看容器输出日志 |
docker-compose config | 检查配置 |
docker-compose config -q | 检查配置,有问题才会输出 |
docker-compose restart | 重启服务 |
docker-compose start | 启动服务 |
docker-compose stop | 停止服务 |
案例演示
编写docker-compose.yml
文件,启动之前,先把mysql和redis的配置文件编辑好。
bashversion: "3"
services:
microService:
image: app:1.0
container_name: ms01
ports:
- "6001:6001"
volumes:
- /data/microService:/data
networks:
- app_net
depends_on:
- redis
- mysql
redis:
image: redis:6.0.8
ports:
- "6379:6379"
volumes:
- /data/redis/redis.conf:/etc/redis/redis.conf
- /data/redis/data:/data
networks:
- app_net
command: redis-server /etc/redis/redis.conf
mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: '123456'
MYSQL_ALLOW_EMPTY_PASSWORD: 'no'
MYSQL_DATABASE: 'app'
MYSQL_USER: 'dev'
MYSQL_PASSWORD: 'dev123456'
ports:
- "3306:3306"
volumes:
- /data/mysql/db:/var/lib/mysql
- /data/mysql/conf/my.cnf:/etc/my.cnf
- /data/mysql/init:/docker-entrypoint-initdb.d
networks:
- app_net
command: --default-authentication-plugin=mysql_native_password #解决外部无法访问
networks:
app_net:
编辑完docker-compose.yml文件后,我们可以直接运行:docker-compose up -d
命令启动
Portainer 是一款轻量级的应用,它提供了图形化界面,用于方便地管理Docker环境,包括单机环境和集群环境。
安装,--restart=always
参数表示docker重启的话,portainer也会重启
bashdocker run -d -p 8000:8000 -p 9000:9000 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer
通过docker stats
命令可以很方便的看到当前宿主机上所有容器的CPU,内存以及网络流量等数据,但是docker stats
统计结果只能是当前宿主机的全部容器,数据资料是实时的,没有地方存储,没有健康指标线预警等功能。
CAdvisor是监控收集
CAdvisor是一个容器资源监控工具包括容器的内存,CPU,网络IO,磁盘IO等监控,同时提供了一个WEB页面用于查看容器的实时运行状态。CAdvisor默认存储2分钟的数据,而且只是针对单物理机。不过,CAdvisor提供了很多数据集成接口,支持InfluxDB, Redis, Kafka, Elasticsearch等集成,可以加上对应配置将监控数据发往这些数据库存储起来。
CAdvisor功能主要有2点
- 展示Host和容器两个层次的监控数据
- 展示历史变化数据
InfluxDB存储数据
InfluxDB是用Go语言编写的一个开源分布式时序、事件和指标数据库,无需外部依赖。
CAdvisor默认只在本机保存最近2分钟的数据,为了持久化存储数据和统一收集展示监控数据,需要将数据存储到InfluxDB中。InfluxDB是一个时序数据库,专门用于存储时序相关数据,很适合存储CAdvisor的数据。而且,CAdvisor本身已经提供了InfluxDB的集成方法,启动容器时指定配置即可。
nfluxDB主要功能
- 基于时间序列,支持与时间有关的相关函数(如最大、最小、求和等)
- 可度量性:你可以实时对大量数据进行计算
- 基于事件:它支持任意的事件数据
Granfana展示图表
Grafana是一个开源的数据监控分析可视化平台,支持多种数据源配置(支持的数据源包括InfluxDB, MySQL, Elasticsearch, OpenTSDB, Graphite等)和丰富的插件及模板功能,支持图表权限控制和报警。
Grafana主要特性
- 灵活丰富的图形化选项
- 可以混合多种风格
- 支持白天和黑夜模式
- 多个数据源
docker-compose.yml
容器编排
bashversion: '3.1'
volumes:
grafana_data: {}
services:
influxdb:
image: tutum/influxdb
restart: always
environment:
- PRE_CREATE_DB=cadvisor
ports:
- "8083:8083"
- "8086:8086"
volumes:
- /data/influxdb:/data
cadvisor:
image: google/cadvisor
links:
- influxdb:influxsrv
command: -storage_driver=influxdb -storage_driver_db=cadvisor -storage_driver_host=influxsrv:8086
restart: always
ports:
- "8080:8080"
volumes:
- /:/rootfs:ro
- /var/run:/var/run:rw
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
grafana:
user: "104"
image: grafana/grafana
restart: always
links:
- influxdb:influxsrv
ports:
- "3000:3000"
volumes:
- grafana_data:/var/lib/grafana
environment:
- HTTP_USER=admin
- HTTP_PASS=admin
- INFLUXDB_HOST=influxsrv
- INFLUXDB_PORT=8086
- INFLUXDB_NAME=cadvisor
- INFLUXDB_USER=root
- INFLUXDB_PASS=root
使用docker-compose up -d
命令启动
cAdvisor收集服务,http://ip:8080/
influxdb存储服务,http://ip:8083/
grafana展现服务,http://ip:3000/
第一次访问grafana服务,需要输入账号密码,默认账号密码都是admin
,默认influxdb的数据库账号密码也都是root
本文作者:柯南
本文链接:
版权声明:©2024 柯南 All rights reserved.