Docker进阶
这篇并不包含集群主从设置的内容。通过概念+实例的方法记录学习的过程
DockerFile
基础知识
- 每条保留字指令都必须为大写字母且后面要跟随至少一个参数
- 指令从上到下,顺序执行
- # 表示注释
- 每条指令都会创建一个新的镜像层并对镜像进行提交
主要作用就是在一个容器内执行一系列的指令,比如下载配置各种东西。可以帮助构建增强型的容器实例。
Docker 执行Dockerfile 的大致流程
- docker从基础镜像运行一个容器
- 执行一条指令并对容器做出修改
- 执行类似docker commit 的操作提交一个新的镜像层
- docker 再基于刚刚提交的镜像运行一个新的容器
- 执行dockerfile中的下一条指令直到所有指令都执行完毕
从软件的角度看,Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段
- Dockerfile 是软件的原材料,或者说是图纸
- Docker镜像是软件的交付品
- Docker容器可以认为是软件镜像的运行状态,也即依照镜像运行的容器实例
实例
用DockerFile创建一个Centos7镜像具备vim+ifconfig+jdk8
构建命令:
docker build -t 新镜像的名i在:TAG .
# 这个FROM就像继承, 在FROM指定的镜像下操作
FROM centos
ENV MYPATH /usr/local
WORKDIR ${MYPATH}
# CentOS 从官方的镜像中移除了CentOS 8所有包
# 我们需要更新其中的镜像资源
RUN sed -i -e "s|mirrorlist=|#mirrorlist=|g" /etc/yum.repos.d/CentOS-*
RUN sed -i -e "s|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g" /etc/yum.repos.d/CentOS-*
RUN yum -y install vim
RUN yum -y install net-tools
# 安装JAVA8及其lib库
RUN yum -y install glibc.i686
RUN mkdir /usr/local/java
# 使用ADD命令会自动解压gz文件
ADD jdk-8u351-linux-i586.tar.gz /usr/local/java
# 配置 java 环境变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_351
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 /bin/bash
然后执行下列命令创建镜像
docker build -t testdf:v1 .
可以用创建得到的镜像创建容器实例,并检查配置得到的环境是否正确
然后我们通过以下命令创建两个容器实例,并指定自己创建的网络设置
docker run -dit --network ywh --name t1 ubuntu:18.04
docker run -dit --network ywh --name t2 ubuntu:18.04
运行
docker exec -it t1 bash
进入到容器内,并使用ping
命令查看两个容器网络的互通情况。这里我们直接ping
服务名,发现在容器t1
内部可以ping
通t2
,说明两个容器间的网络是互通的
用这个方法可以让多个容器进行协同,虽然处在不同的容器中。但可以设置自己的网络设置,让不同容器的网络服务可以互通。
Docker 网络设置
这一部分是关于,容器内部和宿主机的网络映射方式
网络模式 | 简介 | 使用方式 |
---|---|---|
bridge | 为每个容器分配、设置IP,并将容器连接到一个docker0 虚拟网桥,默认为该模式 | 使用--network bridge 指定,默认使用docker0 |
host | 容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口 | 使用--network host 指定 |
none | 容器有独立的Network namespace,但并没有对其进行任何网络设置,如分配veth pair和网桥连接,IP等 | 使用--network none 指定 |
container | 新创建的容器不会创建自己的网课和配置自己的IP,而是和一个指定的容器共享IP、端口范围等 | 使用network container:NAME或者容器ID 指定 |
bridge
Docker服务默认会创建一个docker0网桥(其上有一个docker0内部接口),该桥接网络的名称为docker0,它再内核层联通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络。Docker默认指定了docker0接口的IP地址和子网掩码,让主机和容器之间可以通过网桥相互通信。
host
容器不会获得一个独立的Network Namespace, 而是和宿主机公用一个NetWork Namespace.容器将不会虚拟出自己的网卡而是使用宿主机的IP和端口。
none
在none模式下,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息,只有一个IO。需要我们自己为Docker容器添加网卡、配置IP等。
实例
如下图我们可以创建一个
Docker-compose容器编排
Compose允许用户通过单独的docker-compose.yml模板文件来定义一组相关联的应用容器为一个项目。
可以很容易地用一个配置文件定义一个多容器的应用,然后使用一条指令暗黄这个应用的所有依赖,完成构建。Docker-Compose解决了容器与容器之间如何编排的问题。
Docker compose使用的三个步骤
- 编写
Dockerfile
定义各个微服务应用并构建出对应的镜像文件 - 使用
docker-compose.yml
定义一个完整业务单元,安排好整体应用中的各个容器服务 - 最后,执行
docker-compose up
命令来启动并运行整个应用程序,完成一键部署上线
实例
这里模拟编写一个依赖于redis
和mysql
的容器
version: '3'
services:
myService:
image: ubuntu:18.04
container_name: testubuntu18
ports:
- "8881:6001"
volumes:
- /home/data:/home/data
networks:
- yyTest
depends_on:
- redis
- mysql
redis:
image: redis:6.0.8
ports:
- "6379:6379"
volumes:
- /home/redis/data:/data
networks:
- yyTest
command: redis-server /etc/redis/redis.conf
mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: "123456"
MYSQL_ALLOWEMPTY_PASSWORD: "no"
MYSQL_DATABASE: "db1703"
MYSQL_USER: "ywh"
MYSQL_PASSWORD: "ywh123"
ports:
- "3306:3306"
volumes:
- /home/mysql/db:/var/lib/mysql
- /home/mysql/conf/my.cnf:/etc/my.cnf
- /home/mysql/init:/docker-entrypoint-initdb.d
networks:
- yyTest
command: --default-authentication-plugin=mysql_native_password
networks:
yyTest:
编写完毕后可以通过:
docker-compose config -q
来帮助检查编写是否有问题,若无输出说明编写正确。
然后直接执行命令:
docker-compose up -d
这个
-d
的后缀作用就是后台运行,与docker run -d
那些参数类似
然后直接创建出容器
然后我们查看容器和端口配置是否都成功了