DockerFile基础指令

#利用FROM命令设置基准镜像,也就是我们要使用的镜像
FROM tomcat:latest
#将目录跳转,类似cd /usr/local/tomcat/webapps
WORKDIR /usr/local/tomcat/webapps
#会将本地docker-web下所有文件复制到容器中/usr/local/tomcat/webapps下的docker-web
ADD docker-web ./docker-web

构建docker镜像:

docker build -t feng/mydocker-web:1.0 /home/feng/docker-learn
#feng/mydocker-web 为镜像名字,1.0为版本号。/home/feng/docker-learn是Dockerfile文件的目录

FROM - 基于基准镜像

FROM centos #制作基准镜像(基于centos:lastest)
FROM scratch #不依赖任何基准镜像base image
FROM tomcat:9.0.22-jdk8-openjdk #拉取9.0.22-jdk8-openjdk版本的tomcat

LABEL - 说明信息(注释)

LABEL maintainer = "镜像作者"
LABEL version = "1.0"
LABEL description = "镜像描述"

WORKDIR- 设置工作目录

WORKDIR /usr/local
WORKDIR /usr/local/feng #如果不存在feng目录,则会自动创建
尽量使用绝对路径

ADD - 复制文件

ADD hello / #复制到根路径
ADD test.tar.gz / #添加根目录并解压3. ADD 除了复制,还具备添加远程文件功能
ADD 除了复制,还具备添加远程文件功能

ENV - 设置环境常量

ENV JAVA_HOME /usr/local/openjdk8
RUN ${JAVA_HOME}/bin/java -jar test.jar
尽量使用环境常量,可提高程序维护性

EXPOSE - 暴露容器端口

EXPOSE 8080
docker run -p 8000:8080 tomcat

DockerFile 执行命令

RUN &CMD&ENTRYPOINT

RUN : 在Build构建时执行命令
RUN yum install -y vim #Shell命令格式,安装vim
ENTRYPOINT : 容器启动时执行的命令,DockerFile中只有最后一个ENTRYPOINT会被执行
ENTRYPOINT ["ps"]
CMD : 容器启动后执行默认的命令或参数,DockerFile中也只有最后一个CMD会被执行,并且如果容器启动时有附加指令,则CMD会被忽略。
CMD  ["java","-jar","text.jar"]  #Exec格式,表示容器启动后查看当前运行状态

RUN和CMD、ENTRYPOINT的执行时间点不同

通过DockerFile构建镜像

构建mysql5.7镜像

创建Dockerfile文件

#拉取mysql镜像
FROM mysql:5.7
#设置工作目录
WORKDIR /docker-entrypoint-initdb.d
#将init.sql放入工作目录
ADD init.sql ./

通过dockerfile构建mysql镜像,并且初始化数据

root@DESKTOP-0K57HD8:/home/feng/docker_sampleDB# pwd
/home/feng/docker_sampleDB
root@DESKTOP-0K57HD8:/home/feng/docker_sampleDB# ls
Dockerfile  init.sql
root@DESKTOP-0K57HD8:/home/feng/docker_sampleDB# docker build -t sample-db:1.0 /home/feng/docker_sampleDB

运行容器

root@DESKTOP-0K57HD8:~# docker run -t -p 3310:3306 --name=mysql  -d sample-db:1.0
634a7914f75bfcfaf6790d57e0074de195592f19aa0b000157c89263e4c99840
root@DESKTOP-0K57HD8:~#

构建redis 6.2.10镜像

创建Dockerfile文件

# 拉取centos7镜像
FROM centos:centos7
# 安装redis需要的环境
RUN yum install -y gcc gcc-c++ net-tools make
# cd /usr/local
WORKDIR /usr/local
# 将redis安装包解压到/usr/local目录下
ADD redis-6.2.10.tar.gz .
# cd /usr/local/redis-6.2.10/src
WORKDIR /usr/local/redis-6.2.10/src
# 编译安装redis
RUN make && make install
# cd /usr/local/redis-6.2.10/
WORKDIR /usr/local/redis-6.2.10/
# 将redis.conf文件放入/usr/local/redis-6.2.10/文件夹下
ADD redis.conf ./
# 暴露 6379端口
EXPOSE 6379
# 运行reids
CMD ["redis-server","redis.conf"]

构建redis镜像

root@DESKTOP-0K57HD8:/home/feng/docker_redis# ls
Dockerfile  redis-6.2.10.tar.gz  redis.conf
root@DESKTOP-0K57HD8:/home/feng/docker_redis# docker build -t fneg/myredis:6.2.10 /home/feng/docker_redis/

运行redis容器

root@DESKTOP-0K57HD8:/home/feng/docker_redis# ls
Dockerfile  redis-6.2.10.tar.gz  redis.conf
root@DESKTOP-0K57HD8:/home/feng/docker_redis# docker run -t -p 3310:3306 -d feng/mydocker-web:1.0

容器间基于Link单向通信

容器间的通信可以通过ip进行通信,但是随着容器的增加,ip也不断增多,不利于后续管理

所以这里就可以使用单项连接来进行,此时,就可以通过容器名称ping

root@DESKTOP-0K57HD8:/home/feng/docker-learn# docker images
REPOSITORY          TAG       IMAGE ID       CREATED         SIZE
link-test           latest    4c9e63d03518   6 minutes ago   699MB
fneg/myredis        6.2.10    02b0d15a460a   18 hours ago    652MB
sample-db           1.0       5a173d9308cb   36 hours ago    448MB
feng/mydocker-web   1.0       3aa2392dbc61   38 hours ago    680MB
root@DESKTOP-0K57HD8:/home/feng/docker-learn# docker run -t -d --name=link1 link-test
6ea7387bcd53611769d6937aeecb1d7919c2bb4203469ae7006a6eef52911e1e
root@DESKTOP-0K57HD8:/home/feng/docker-learn# docker run -t -d --name=link2 --link link1 link-test
7aadb7a7758f6c1b47498d422630bbb8fb54ef4db112c7afd6d79b3c89d745f2
root@DESKTOP-0K57HD8:/home/feng/docker-learn# docker exec -it link2 /bin/bash
root@7aadb7a7758f:/usr/local/tomcat/webapps# ping link1
PING link1 (172.17.0.2): 56 data bytes
64 bytes from 172.17.0.2: icmp_seq=0 ttl=64 time=0.096 ms
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.046 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.119 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.079 ms

但是Link单项通信的缺点也很明显,必须双方都简历对方的Link单项通信,才可以互相访问,否则只能单项访问。

Bridge网桥双向通信

网桥就类似于虚拟网卡,是docker环境中与外界环境通信必不可少的组件,网桥可以实现容器与容器之间的通信,也可以实现容器与外部环境的通信

创建好一个新的网桥以后,在网桥上添加容器,该网桥上的所有容器就可以相互通讯了

查看网桥:

root@DESKTOP-0K57HD8:~# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
f6badd8665cc   bridge    bridge    local
08518dd80233   host      host      local
e9dd6a187c45   none      null      local
root@DESKTOP-0K57HD8:~#

新建网桥:创建一个名字为my-bridge的网桥

root@DESKTOP-0K57HD8:~# docker network create -d bridge my-bridge
559c0bc3128a7814b0823cd5dbcfd29c6422beb07c42815d96ae6f680a6c9421
root@DESKTOP-0K57HD8:~#

将容器加入网桥,进入容器,测试容器之间网络是否可以连通

root@DESKTOP-0K57HD8:~# docker run -t -d --name=b1 bridge-test
633f205851c28b91877974aad7c4bc5b0b19853f9760988715811698cfa0413c
root@DESKTOP-0K57HD8:~# docker run -t -d --name=b2 bridge-test
924b8a3ad2521f9fdbdddb1bf502e9be90d787d9f0d8ccfb22cb9dbe818abce6
root@DESKTOP-0K57HD8:~# docker network connect my-bridge b1
root@DESKTOP-0K57HD8:~# docker network connect my-bridge b2
root@DESKTOP-0K57HD8:~# 
root@DESKTOP-0K57HD8:~# docker exec -it b1 /bin/bash
root@633f205851c2:~# ping b2
PING b2 (172.18.0.3): 56 data bytes
64 bytes from 172.18.0.3: icmp_seq=0 ttl=64 time=0.079 ms
64 bytes from 172.18.0.3: icmp_seq=1 ttl=64 time=0.123 ms

volume数据卷

为什么使用数据卷?

1.由于容器中的数据在容器销毁过后就会被清除,如果使用docker搭建redis或者mysql之类的有持久化的应用,那么在容器被销毁后数据也可能被销毁,而docker容器销毁是经常会出现的场景,所以需要使用volume数据卷将容器的数据挂载到宿主机目录中。

2.volume可以实现容器与容器之间的数据共享

使用名称为volume-test的镜像构建容器

#将宿主机上的/home/feng/docker-learn/docker-web目录挂载到容器中的/usr/local/tomcat/webapps目录下
root@DESKTOP-0K57HD8:/home/feng/docker-learn/docker-web# ls
web
root@DESKTOP-0K57HD8:/home/feng/docker-learn/docker-web# docker run --name=v1 -t -d -p 8100:8080 -v /home/feng/docker-learn/docker-web:/usr/local/tomcat/webapps volume-test
root@DESKTOP-0K57HD8:/home/feng/docker-learn/docker-web# curl http://localhost:8100/web/index.html
<h1>hello docker</h1>
root@DESKTOP-0K57HD8:/home/feng/docker-learn/docker-web# 

Docker Compose单机多容器部署工具

为什么需要Docker Compose?

在实际的生产环境中,往往需要多个容器配合工作,才能称的上一个完整的应用服务。

举个栗子,你想搭建一个 Web 服务,除了 Web 服务容器本身,若涉及数据存储,就需要依赖数据库容器(Mysql、Mongdb 等);若想实现分词搜索,就需要依赖搜索引擎容器(Elasticsearch、Solor 等);其他诸如缓存容器、负载均衡容器等。

同时,部署和管理繁多的容器服务是非常困难的。有了 Docker Compose ,就能很好的解决这个问题!Docker Compose 通过一个声明式的配置文件 docker-compose.yml 来描述整个应用,使用一条命令即可完成部署。应用部署成功后,还可以通过一系列简单的命令实现对应用生命周期的管理。甚至,配置文件还可以置于版本控制系统中进行存储和管理。

使用一个java项目和mysql做一个示例:

首先创建jar和mysql文件夹,并且创建一个docker-compose.yml文件

root@DESKTOP-0K57HD8:/home/feng# ls
docker-compose.yml  jar  mysql

然后将jar包放入jar文件夹,并创建Dockerfile文件

FROM openjdk:8u222-jre
WORKDIR /usr/local/jre
ADD imgCdn.jar .
EXPOSE 8080
CMD ["nohup","java","-jar","imgCdn.jar"]

加将初始化语句放入mysql,并创建Dockerfile文件

FROM mysql:5.7
WORKDIR /docker-entrypoint-initdb.d
EXPOSE 3306
ADD init-db.sql .

编辑docker-compose.yml文件

version: '3.3'
services:
  db:
    build: ./mysql/ #根据mysql目录下的Dockerfile构建镜像
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: root
  app:
    build: ./jar/ #根据jar目录下的Dockerfile构建镜像
    depends_on:
      - db #可以使用db代替ip,同时Springboot中yml数据库ip地址也要改为db
    ports:
      - "8100:8080"
    restart: always

进入docker-compose.yml目录执行docker-compose build构建镜像和docker-compose up -d运行容器

root@DESKTOP-0K57HD8:/home/feng# ls
docker-compose.yml  jar  mysql
root@DESKTOP-0K57HD8:/home/feng# docker-compose up -d
最后修改:2023 年 02 月 24 日
如果觉得我的文章对你有用,请随意赞赏