Dockerfile & Docker Compose(实战总结)
Dockerfile
Dockerfile 是用来构建Docker镜像文件,是由一条条构建镜像所需的指令构成的脚步。
步骤:
- 编写Dockerfile 文件
- docker build 构建镜像
- docker run 运行镜像
- docker push 发布镜像
体系结构:
- FROM:基础镜像,当前的镜像基于哪个镜像
- MAINTAINER:镜像作者、邮箱
- WORKDIR:设置工作目录,终端默认登陆进来的工作目录
- EXPOSE:当前容器对外暴露的端口
- USER:指定镜像以什么样的用户执行,默认是root
- ENV:设置环境变量 (可以写多条),构建镜像中的环境变量
- ADD:将宿主机的文件复制到容器内,如果是一个压缩文件, 将会在复制 后自动解压
- COPY:和ADD相似,但是如果有压缩文件并不能解压
- VOLUME:容器数据卷,用于数据保存和持久化工作
- RUN:容器构建时需要运行的命令,等同于操作shell脚步,例子:RUN yum -y install vim
- CMD:指定一个容器启动时运行的命令,可以有多个CMD,但只有最后一个会生效。在构建容器时,会被 docker run 后面指定的参数覆盖。
- ENTRYPOINT:和CMD相似,但是并不会被docker run指定的参数覆盖,而是追加参数
- ONBUILD:当创建一个被继承的Dockerfile,会被触发,触发器
RUN和CMD的区别:
CMD是在docker run时运行
RUN是在docker build时运行
例子:构建JDK镜像
# 来自基础镜像
FROM centos:7
# 指定镜像创建者信息
MAINTAINER goodyan<good.qq.com>
# 切换工作目录 /usr/local
WORKDIR /usr/local
# 创建一个存放jdk的路径
RUN mkdir /usr/local/java
# 安装vim插件
RUN yum -y install vim
# 将jdk压缩包复制并解压到容器中/usr/local/java
ADD jdk-8u171-linux-x64.tar.gz /usr/local/java
# 配置java环境变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_171
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
CMD ["/bin/bash"]
构建镜像语法:
# -f 后可以省略,会生成在当前目录上
docker build -f / dockerfiel文件位置) -t 要生成的镜像名:[版本号] .
docker build -f /home/dockerdir/dockerfiel -t tomcatNew:1.0 .
# 查看是否构建成功
docker images
将本地镜像推送到阿里云镜像仓库
# 1.登录阿里云Docker Registry, 密码为开通服务时设置的密码
docker login --username=用户名 registry.cn-xxx(每个人地址不一样)
# 2.标记此镜像为阿里云仓库的镜像
docker tag [镜像id] registry.cn-xxxx.xxx.com/xxx/jdk:[镜像版本号]
# 3.提交
docker push 镜像名:[镜像版本号]
Docker网络
容器间的互联和通信以及端口映射,容器IP变了可以通过服务名直接网络通信不受影响。Docker默认提供了3种网络模式,
- bridge 默认的桥接模式,并将容器连接到一个docker0
- host 容器将不会虚拟出自己的网卡,使用宿主机的IP和端口
- container模式 这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace
- none 该Docker容器没有网卡、IP、路由等信息
基本命令:
# 查看ip
ifconfig 或者 ip addr
# 查看docker网络模式列表
docker network ls
# 创建新的网络
docker network create 网络名
# 删除的网络名
docker network rm 网络名
# 查看的网络名
docker network inspect 网络名
# 连接络名
docker network connect 网络名
# 中断络名
docker network disconnect 网络名
# 查看某个容器的网关信息(倒数20行内)
docker inspect 容器id | tail -n 20
# 查看到bridge 就是桥接模式,Gateway:网关,IPAddress:ip(注意:这里的ip,每次创建/删除容器,IP会变)
桥接模式
# 查看的bridge 网络信息,通过grep 获取名称项目(默认是docker0)
docker network inspect bridge | grep name
# 创建2个容器,后查看ip
ip addr
# 会看到多了很多veth的xxx,它们与eth0与匹配
# 我们进入某个容器内部,再查看IP
ip addr
# 会看到etho的xxx 与外面的对应,一个容器内部的etho,对应外部的veth
host 模式
# 查看的bridge 网络信息,通过grep 获取名称项目(默认是docker0)
docker network inspect host
# 它的容器里的IP和端口,与宿主机一致,创建容器的 -p 命令就会失效
自定义网络
# 可以解决,ping IP 和 ping 服务名 都可以成功
# 创建新的网络(yan_work)
docker network create yan_work
# 查看docker网络模式列表
docker network ls
# 创建2个容器
docker run -it -p 8081:8080 --network yan_work --name tom81 镜像名:标签名 /bin/bash
docker run -it -p 8082:8080 --network yan_work --name tom82 镜像名:标签名 /bin/bash
# 分别进入2个容器
docker exec -it 容器名称|容器id /bin/bash
# 分别查看ip(查看它们是否处于同一网段上)
ip addr
# 分别ping对应的ip地址,和服务名(是否ping成功,同一个网络会成功)
ping tom81
ping tom82
Docker部署
微服务打包Docker镜像
# 步骤1. 准备SpringBoot项目,进行打包
mvn package install
# 步骤2. 启动命令,进行测试是否启动成功
windows系统启动:java -jar xxx.jar
Linux系统启动:nohup java -jar xxx.jar
# 步骤3.创建dockerfiel文件,与jar包存在同一目录(vim Dockerfiel)
# Dockerfiel文件内容:
FROM java:8
COPY *.jar /app.jar
CMD ["--server.port=8080"]
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app.jar"]
# 步骤4.上传服务器,构建镜像
docker build -f /home/xxx/dockerfiel文件地址(如果在当前目录可省略-f)-p 端口映射 -t 镜像名:1.0 .
# 步骤5.查看镜像
docker images
# 步骤6.运行启动镜像
docker run -id --name=容器名 镜像名:标签名
或 docker run -d --name 容器名 -p 端口外:端口内 镜像名:标签名
IDEA集成Docker实现打包
步骤1:修改docker服务配置文件
# 修改配置文件
vim /lib/systemd/system/docker.service
# 修改内容
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock
(修改ExecStart那行,并开启2375端口,0.0.0.0代表任何ip都可以访问)
# 重新加载配置文件
systemctl daemon-reload
# 重启docker
systemctl restart docker.service
# 查看端口是否开启
netstar -nlpt # 如果没有这个命令,安装插件 yum install net-tools
# 关闭防火墙 / 开发端口号的防火墙
firewall-cmd --list-ports # 查看
firewall-cmd --zone=public --add-port=2375/tcp --permanent # 设置
firewall-cmd --reload # 重启
步骤2:IDEA工具配置连接Docker
步骤3:使用 docker-maven-plugin插件 ,实现自动化部署
修改pop.xml文件
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.0.0</version>
<configuration>
<!--鏡像名字-->
<imageName>${docker.image.prefix}/${project.artifactId}</imageName>
<imageTags>
<imageTag>latest</imageTag>
<!-- <imageTag>${project.version}</imageTag>-->
</imageTags>
<baseImage>java</baseImage>
<maintainer>821521880@qq.com</maintainer>
<workdir>/ROOT</workdir>
<cmd>["java", "-version"]</cmd>
<entryPoint>["java", "-jar", "${project.build.finalName}.jar"]</entryPoint>
<!--连接Docker 输入对应的IP地址 -->
<dockerHost>http://123.56.94.235:2375</dockerHost>
<!-- 这里是复制 jar 包到 docker 容器指定目录配置 -->
<resources>
<resource>
<targetPath>/ROOT</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
然后我们执行打包命令,就在Docker服务生成镜像
mvn clean package docker:build
步骤4:打包自动化,自动化部署
<!-- 当执行打包命令,就自动执行 build语句 -在pop.xml文件里添加->
<executions>
<execution>
<id>build-image</id>
<phase>package</phase>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
Docker认证命令配置
使用CA加密认证,访问Docker更加安全
- 创建ca文件夹,存放CA私钥/公钥
mkdir -p /usr/local/ca
cd /usr/local/ca/
- 生成私钥/公钥
openssl genrsa -aes256 -out ca-key.pem 4096
# Enter pass phrase for ca-key.pem:
# 执行后,需要输入2次密码,设置密码
openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem
# 执行完,需要输入刚才设置的密码。
# 然后依次输入 1国家名字 cn 2省份名称 bj 3城市 bj 4组织名称 good ... 个人信息
- 生成server-key.pem文件
openssl genrsa -out server-key.pem 4096
# 执行完,/usr/local/ca 目录下会有3个文件
- CA来签署公钥
openssl req -subj "/CN=IP地址(或者域名www.goodysr.cn)" -sha256 -new -key server-key.pem -out server.csr
# 例子
openssl req -subj "/CN=121.40.176.56" -sha256 -new -key server-key.pem -out server.csr
- 配置白名单
echo subjectAltName=IP:IP地址,IP:0.0.0.0 >> extfile.cnf
# 例子
echo subjectAltName = IP:121.40.176.56,IP:0.0.0.0 >> extfile.cnf
- 将Docker使用属性设置仅用于服务器身份验证
echo extendedKeyUsage = serverAuth >> extfile.cnf
- 生成签名证书
openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem \-CAcreateserial -out server-cert.pem -extfile extfile.cnf
# 执行完,要输入刚才设置的密码,输入密码
- 生成客户端的key.pem
openssl genrsa -out key.pem 4096
openssl req -subj '/CN=client' -new -key key.pem -out client.csr
- 使用密钥适合客户端身份验证
echo extendedKeyUsage = clientAuth >> extfile.cnf
# echo extendedKeyUsage = clientAuth >> extfile-client.cnf
- 生成cert.pem签名证书
openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem \-CAcreateserial -out cert.pem -extfile extfile.cnf
# 输入完,要设置密码
- 删除不需要的文件
rm -v client.csr server.csr
- 修改权限,避免密钥损坏
chmod -v 0400 ca-key.pem key.pem server-key.pem
chmod -v 0444 ca.pem server-cert.pem cert.pem
- 归集服务器证书
cp server-*.pem /etc/docker/
cp ca.pem /etc/docker/
# 以上两步操作都在ca文件夹内,如果当前不在ca文件夹,需加上路径
# 把证书复制到/etc/docker/目录下
- 修改Docker配置
vim /lib/systemd/system/docker.service
# 修改内容
ExecStart=/usr/bin/dockerd --tlsverify --tlscacert=/etc/docker/ca.pem \
--tlscert=/etc/docker/server-cert.pem \
--tlskey=/etc/docker/server-key.pem \
-H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock
# 重新加载配置文件
systemctl daemon-reload
# 重启docker
systemctl restart docker
# 开放2375端口
/sbin/iptables -I INPUT -p tcp --dport 2376 -j ACCEPT
# 查看信息
iptables-save
# 重启Docker
service docker restart
- 将服务器生成的私钥密钥,保存到本地环境
/usr/local/ca 目录下的 ca.pem ca-key.pem cert.pem key.pem
保存到本地的 ca 目录下
Portainer图形化管理工具
- 下载portainer镜像
docker search portainer
docker pull portainer/portainer
- 启动镜像
docker run -d --name portainerUI -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer
- 开放端口号
firewall-cmd --list-ports
firewall-cmd --zone=public --add-port=9000/tcp --permanent
firewall-cmd --reload
- 访问9000地址
第一次登录需要创建用户,选择第一个。
Docker Compose
高效的管理容器,它是一个用于定义和运行多容器 Docker 的应用程序工具
安装
- 下载:https://github.com/docker/compose/releases
# 下载方式:
# 1.下载适应版本的 Compose
sudo curl -L https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
# 肯能网络原因,如果下载失败就下载另一个地址
sudo curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname-m` > /usr/local/bin/docker-compose
# 2.手动下载
# https://github.com/docker/compose/releases
# 下载 docker-compose-Linux-X86_64 文件,上传服务器 /usr/local/bin/ 目录下
# 重命名 docker-compose
mv docker-compose-Linux-X86_64 docker-compose
# 3.修改文件权限
chmod 777 docker-compose
# 4.把文件方法bin目录下,配置可执行文件的系统变量,可以在任何目录下执行docker-compose命令
mv docker-compose /usr/local/bin/
# 5.查看版本信息,看是否安装成功
docker-compose version
使用
创建容器
需要通过docker-compose.yml模板文件,定义一组相关的应用容器作为一个项目。
案例1管理一个tomcat、mysql:
version: '3' # 表示该docker-compose.yml文件使用的是Version 2 file format
services: # 为project定义服务。
mysql: # 定义服务名称,随便起名
restart: always # 只要docker启动,容器就启动
image: daocloud.io/library/mysql:5.7.6 # 指定镜像路径(默认官方镜像地址)
container_name: mysql-3306 # 指定容器名字 --name
ports:
- 3306:3306 # 端口号映射
environment:
MYSQL_ROOT_PASSWORD: root # Mysql Root的密码
TZ: Asiz/Shanghai # 指定时区
volumes:
- /opt/mysql/data:/var/lib/mysql # 映射宿主机目录
- /opt/mysql/conf/mysql.cnf:/etc/mysql/mysql.cong.d/mysql.cnf
tomcat:
restart: always # 只要docker启动,容器就启动
image: daocloud.io/library/tomcat:8.5.15-jre8 # 指定镜像路径(默认官方镜像地址)
container_name: tomcat-8080 # 指定容器名字 --name
ports:
- 8080:8080 # 端口号映射
environment:
TZ: Asiz/Shanghai # 指定时区
volumes:
- /opt/tomcat/webapps:/usr/local/tomcat/webapps # 映射宿主机目录
- /opt/tomcat/logs:/usr/local/tomcat/logs
操作:
# 启动(执行上面命令创建容器)
docker-compose -f 文件名.后缀(如果当前文件不再当前目录需要指定,可省略) up -d
# 登录到容器中
docker-compose exec 容器名 bash
# 停止所有容器
docker stop ${docker ps -qa}
docker-compose stop # 关闭所有容器
# 删除docker-compose文件内所有容器
docker-compose down