- 镜像是一种轻量级, 可执行的独立软件包, 用来打包软件运行环境和基于运行环境开发的软件; 它包含运行某个软件的所有东西(代码, 运行环境, 环境变量, 配置文件)
- UnionFS(联合文件系统): UnionFS是一种分层, 轻量级并且高性能的文件系统; 它支持对文件系统的修改作为一次提交来一层层叠加, 同时可以将不同目录挂载到同一虚拟文件系统下; UnionFS是Docker镜像的基础; 镜像可以通过分层进行继承, 基于基础镜像, 可以制作各种应用镜像
- docker镜像实际就是一层一层的文件系统组成, 这种层级的文件系统就是UnionFS
**BootFS**
(boot file system): 主要包含bootloader和kernel, bootloader主要负责引导加载kernel(内核), linux在刚启动的时候会加载bootfs, 当bootfs加载完成之后, 整个内核就都在内存中了, 此时内存的使用权就有bootfs转交给了内核, 然后系统就会卸载掉bootfs;**RootFS**
(root file system) : rootfs就是不同操作系统的发行版本, 如ubuntu, centos; linux系统中的/dev, /proc, /bin, /etc等标准目录就是rootfs- docker中的镜像们统一使用公共的bootfs(bootfs非常大); 镜像中不包含bootfs的, 镜像主要有rootfs+应用组成, 所以比较小;
- 对于精简的OS, rootfs是非常小的, 只需要包含最基本的命令, 工具和程序库就可以了, 因为底层使用了宿主机的内核, 精简OS只需提供rootfs即可; 不同的linux发行版本, bootfs基本是一致的, rootfs会有差异, 因为不同的linux发行版本可以使用公用的bootfs
- 镜像秒级启动的原因: 不许用使用bootloader引导加载kernel, 直接使用了宿主机的内核, 所以镜像启动很快
1. Docker命令
1.1 docker命令
docker info # 查看docker的信息
docker stats # 查看容器的内存和CPU
1.2 日志命令
docker logs CONTAINER ID 查看对应容器的命令
docker logs -tf CONTAINER ID 加上时间戳, 并动态展示
docker logs --tail 10 CONTAINER ID 必须加上显示的行数
1.3 进程信息
docker top CONTAINER ID 查看容器中的ID
1.4 元数据信息
docker inspect df7d3fdddeee 既可以查看镜像, 也可查看容器
1.5 容器文件copy
# 首先需要进入到Linux窗口
docker cp 3e876b253a6b:/opt/my.txt /root/docs
2. 镜像命令
2.1 查看镜像
docker serarch mysql # 查看远程镜像
docker images # 查看本地镜像
docker image -q # 只显示镜像ID
docker history d969462cfd1c
docker image inspect redis:latest
2.2 拉取镜像
docker pull mysql # 拉取远程镜像到本地(默认是最后一个版本)
docker pull mysql:5.6 # 下载指定版本的镜像(版本必须在dockerhub中存在)
2.3 移除镜像
docker rmi mysql
docker rim mysql `docker images -q` # 移除所有本地镜像
2.4 推送镜像
# 首先需要登录dockerhub账号
docker login -u pogusanqian
3. 容器命令
3.1 运行容器
docker run centos 启动容器
docker run -it centos 交互式命令启动(可以使用Ctrl + P + Q切换到主窗口)
docker run --name=haha centos 给容器其名称叫做haha
docker run -d centos 后台启动
docker run -it --rm tomcat:9.0 启动tomcat容器, 容器停止后就会将容器删除
docker run -p 8080:8080 tomcat 将容器的端口和服务器的端口联通(如果不指定, 外部是无法访问到容器中的端口的)
docker run -P tomcat 大P表示随机映射端口
# bash更好用一点, 按tab键会自动提示
docker run -d centos /bin/bash -c "while true; do echo pogusanqian; sleep 1; done"
# -e表示的是设置环境变量, 相当于是在配置文件中设置(句尾的\,表示一个链接符)
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" \
-e ES_JAVA_OPTS="-Xms64m -Xms12m" elasticsearch:7.6.2
# portainer 是一个可视化面板管理docker的
docker run -d -p 3003:9000 \
--restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
3.2 查看容器
docker ps 查看运行的容器
docker ps -q 查看容器的容器ID
docker ps -a 查看所有的容器(正在运行的 + 曾经运行的)
3.3 进入容器
docker exec -it df7d3fdddeee /bin/sh 创建一个新的容器终端
docker attach df7d3fdddeee 进入容器正在执行的终端
3.4 退出容器
exit 退出容器
Ctrl + P + Q 退出到主窗口(容器的端口并没有关闭)
3.5 停止容器
docker start **** 启动容器
docker restart *** 重启容器
docker stop **** 停止容器
docker kill *** 强制停止容器
3.6 销毁容器
docker rm **** 删除容器(不能删除正在运行的容器)
docker rm -f **** 强制删除容器
docker rm $(docker ps -aq) 删除所有的容器(历史记录容器也会被删除)
3.7 提交容器
commit之后就会再本地创建一个镜像; 注意b055是容器ID
docker commit -m "在webapp目录下, 补充项目" -a pogusanqian b055d6640827 mytomcat:1.0
4. 数据卷命令
数据卷挂载: -v 挂载, dockerfile挂载, —volumes-from(容器之间的关在)
- 容器之间使用卷同步数据时, 只有当所有容器都不存在时, 这个卷才会被删除; 但是一旦使用-v同步到宿主机, 就算所有容器都销毁, 宿主机上的卷仍然存在
4.1 指定路径挂载
```bash匿名挂载
docker run -it -v /root/dockers/home:/home centos /bin/bash
注意conf.d是一个目录
docker run -p 3306:3306 -v /root/mysql-docker/conf:/etc/mysql/conf.d -v /root/mysql-docker/data:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=123123 -d mysql
<a name="AopvG"></a>
### 4.2 匿名/具名挂载
```bash
# 具名挂在haha, 注意haha没有使用/开头
docker run -it -v haha:/home centos /bin/bash
# 匿名关在
docker run -it -v /home centos /bin/bash
4.3 查看卷信息
- 卷在宿主机实际路径:
**/var/lib/docker/volumes**
```bash docker volume ls 查看所有的卷名称
docker volume inspect f740** 查看f740卷(匿名挂在的卷) docker volume inspect haha 查看haha卷的信息(具名挂载的卷)
<a name="VGHqg"></a>
### 1.8 容器共享卷
```bash
docker run -it --volumes-from b20a7d0df93d mycentos:1.0
4.9 卷权限
# ro(readonly): 只读, 卷文件只能在宿主机上更改, 不能在容器中更改
# rw(readwrite): 读写, 卷文件既能在宿主机上更改, 也能在容器中更改
docker run -d -P -v nginx:/etc/nginx:ro nginx
docker run -d -P -v nginx:/etc/nginx:rw nginx
5. DockerFile
-
5.1 创建File
FROM: 基础镜像, docker中最小的镜像是
**sratch**
- MAINTAINER: 镜像维护者, 姓名+邮箱scratch
- RUN: 镜像构建时, 需要运行的命令
- ADD: 添加的内容
- WORKDIR: 镜像的工作目录
- VOLUME: 挂载的目录
- EXPOST: 暴漏端口配置
- CMD: 指定容器启动的时候, 运行的命令(只有最后一个会生效, 可被替代)
- ENTRYPOINT: 指定容器启动时要运行的命令, 会追加
- ONBUILD: 当构建一个被继承dockerfile, 这个时候就会运行onbulid指令
- COPY: 类似ADD命令, 将我们的文件copy到镜像中
- ENV: 构建的时候设置环境变量
5.1.1 简单创建
# 关键字推荐使用大写(#表示注释)
FROM centos
VOLUME ["volume01", "volume02"]
CMD echo "-------end-------"
CMD /bin/bash
5.1.2 创建centos
# centos这个镜像如果本地没有, 就会从hub中下载; 如果本地就会复用
FROM centos
MAINTAINER pogusanqian<pogusanqian@163.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 80
CMD echo $MYPATH
CMD echo "------end------"
CMD /bin/bash
5.1.3 创建tomcat
```bash FROM centos MAINTAINER pogusanqianpogusanqian@163.com copy readme.md /usr/local/readme.md将宿主机的jdk解压到容器中的/usr/local目录下
ADD jdk-8u181-linux-x64.tar.gz /usr/local ADD apache-tomcat-9.0.56.tar.gz /usr/local
启动命令使用的时RUN, 不要写成ADD
RUN yum install -y vim
配置进入容器后的目录
ENV MYPATH /usr/local WORKDIR $MYPATH
配置jdk和tomcat路径
ENV JAVA_HOME /usr/local/jdk1.8.0_181 ENV CLASS_PATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.56 ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.56 ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080
配置启动tomcat并将tomcat的日志进行输出到控制台(这里要使用F)
CMD /usr/local/apache-tomcat-9.0.56/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.56/logs/catalina.out
```bash
docker build -t mytomcat:1.0 .
# 启动容器将项目和日志挂载出来
docker run -d -p 8080:8080 -v /home/dockers/mytomcat/webapps/test:/usr/local/apache-tomcat-9.0.56/webapps/test \
-v /home/dockers/mytomcat/logs:/usr/local/apache-tomcat-9.0.56/logs mytomcat:1.0
5.1.4 创建koa
FROM node:14-alpine
RUN mkdir -p /home/Service/my-koa
WORKDIR /home/Service/my-koa
# .表示的是copy当前目录
COPY . /home/Service/my-koa
RUN npm install
EXPOSE 3000
CMD [ "npm", "start" ]
5.2 运行File
如果dockerFile的文件名就叫做Dockerfile, 我们的-f参数可以不用写
# 最后的.表示生成的镜像放在当前目录
docker build -f ./dockerfile01 -t mycentos:1.0 .
6. 网络通讯
https://blog.csdn.net/weixin_33905756/article/details/92454616
- docker容器有四种网络模式
- bridge: 桥接模式
- none: 不配置网络
- host: 和宿主机共享网络
- container: 容器网络联通(已弃用)
6.1 Bridge模式
- 只要安装docker, Linux服务器上就会多出一个虚拟网卡docker0; docker0主要用于桥接, 是用于docker容器的通讯
- 当使用docker启动容器后, docker会使用evth-pair技术给容器分配一个ip
- enth-pair技术是一对虚拟设备接口, 一端连着协议, 一端彼此相连
- enth-pair相当于是桥梁, 连接各种虚拟网络设备
- 容器之间的通讯时通过docker0作为桥接进行通讯
- 宿主机和容器之间也是通过docker0作为桥接进行通讯 ```bash ip addr 查看本机的网络
启动连个tomcat容器
docker run -d -P —name tomcat01 tomcat docker run -d -P —name tomcat02 tomcat
tomcat容器中下载对应的指令
docker exec -it tomcat01 /bin/bash apt update apt install -y iproute2 apt install -y inetutils-ping
ping 172.17.0.2 # 宿主机和容器进行相互通讯(只能写ip地址, 不能写宿主机名字) docker exec -it tomcat01 ping 192.168.124.24 # 容器和宿主机进行通讯(相当于是先进入容器, 然后执行了ping命令) docker exec -it tomcat02 ping 172.17.0.2 # 容器之间相互通讯

<a name="JxIcB"></a>
### 6.2 Link链接
- 在桥接模式中, 容器之间通讯只能使用ip地址, 但是又的服务场景需要使用服务名称进行通讯
- --link可以时tomcat03链接tomcat01容器, 这样就可以直接使用容器名称寻址通讯
- ink命令的本质其实就是修改了tomcat03容器的host.conf文件, 做了一次映射: `172.17.0.2 tomcat01 228152661c1b`
- link命令不是互联的, 用tomcat03 link tomcat01, 只是修改了tom3的host文件, tom1的host文件并没有修改; 所以tom1不能直接ping tom3
```bash
docker run -d -P --name tomcat03 --link tomcat01 tomcat # tomcat03 link tomcat01
docker exec -it tomcat03 /bin/bash
ping tomcat01 # 能根据容器名称ping通
cat /etc/host.conf # 查看host文件
6.3 自定义网络
- 使用自定义网络创建的容器是可以通过名称寻址的
- 由于vmware创建的虚拟机的网址一般的都是192.168的网段, 所以使用docker创建网段的时候不要使用192.168, 不然会无法联网 ```bash docker network ls 查看docker中的所有网络 docker network inspect 126006eba4ff 查看网络元数据(126*不是容器id, 而是networkId)
创建自己的网络
docker network create —driver bridge —subnet 172.16.0.0/16 —gateway 172.16.0.1 mynet
删除网络
docker network rm mynet
使用自定义网络创建容器(—net的默认参数是bridge)
docker run -d -P —name tomcat-net-01 —net mynet tomcat
<a name="G77Wb"></a>
### 6.4 网络联通
- docker可以使用自定义网络创建不同的局域网, 不同的局域网之间是不能通讯的, 需要将不同的局域网进行打通
- docker使用connect打通不同的局域网, 使不同局域网之间的容器可以通讯; connet命令的本质其实是将A容器挂载到了172.16局域网下, 这样A容器就有了两个容器地址

```bash
# 创建局域网mynet
docker network create --driver bridge --subnet 172.16.0.0/16 --gateway 172.16.0.1 mynet
# 创建四个容器, 并启动
docker run -d -P --name tomcat01 tomcat
docker run -d -P --name tomcat02 tomcat
docker run -d -P --name tomcat-net-01 --net mynet tomcat
docker run -d -P --name tomcat-net-02 --net mynet tomcat
# 进行容器联通, 此时tomcat01容器相当于放置在了两个局域网下, 这样tomcat就能和172.16局域网的容器进行通讯了
docker network connect mynet tomcat01
# 查看mynet网络配置(发现多了一个tomcat01的容器)
docker network inspect fe90cc707ee0