开发一个项目可能存在两种环境,开发、上线;两者需要配置的环境不同。
传统项目运行时,一个环境如 mysql 的错误会引发整个项目的宕机。
Docker 就是为了解决项目中不同的配置而产生,即可以同时将 jar、mysql、redis 等一起打包安装,称为镜像。
使用 Docker 生成镜像,下载安装即可使用。
思想:集装箱
Docker 核心思想:隔离,打包装箱,每个包都是相互隔离的。
Docker 能够最大限度的利用服务器的资源
虚拟化技术:
虚拟机技术 => 容器化技术 容器化技术不是一个完整的操作系统
两者的优缺点和区别:
虚拟机技术:
容器化技术:
容器应用直接运行在主体本机上,不拥有独立的内核
容器间相互隔离,每个容器拥有独立的文件系统,互不影响
内核级别的虚拟化
镜像(image)
容器(container)
仓库(repository)
查看系统内核
# uname -r
5.10.112-11.1.al8.x86_64
查看系统版本
# cat etc/os-release
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"
安装步骤
更新 yum
索引
yum makecache fast
卸载旧版本
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
下载相关工具及安装包
yum install -y yum-utils
配置镜像仓库
yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
安装 Docker 引擎
# docker-ce 社区版
yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin
查看下载镜像
docker images
卸载
卸载依赖
yum remove docker-ce docker-ce-cli containerd.io docker-compose-plugin
删除资源
# /var/lib/docker 默认工作路径
rm -rf /var/lib/docker
rm -rf /var/lib/containerd
阿里云镜像加速
#
sudo mkdir -p /etc/docker
#
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://rl0hzmix.mirror.aliyuncs.com"]
}
EOF
#
sudo systemctl daemon-reload
#
sudo systemctl restart docker
卸载旧版本
apt-get remove docker docker-engine docker.io containerd runc
更新 apt
包索引
apt-get update
安装 apt
依赖包,用于通过 HTTPS 来获取仓库
apt-get install \
ca-certificates \
curl \
gnupg \
lsb-release
添加 Docker 官方 GPS 密钥
mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
将 Docker 仓库添加到 APT 软件源
add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
安装 Docker 引擎
apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
验证
docker --version
Docker 工作原理
Docker 与 VM 的速度区别原因
# 查看 Docker version
docker version
# 查看 Docker 信息(详细),system info,包括镜像和容器的数量
docker info
#
docker --help
# 查看镜像仓库
docker images
# 查看镜像仓库所有的镜像
docker images -a
# 查看镜像仓库中镜像的ID
docker images -q
# 参数配合使用
docker images -aq
# xxx表示镜像仓库中的镜像,如 mysql
docker search xxx
# 条件搜索,???表示查询的条件,可以是 STARS=3000
docker search xxx -filter=???
# xxx表示镜像仓库中的镜像,如:mysql,默认最新版本,tag表示版本号
docker pull xxx[:tag]
# 单个镜像删除,ID为 IMAGE ID,NAME 为 REPOSITORY,可以通过两种方式删除
docker rmi -f ID(NAME)
# 多个镜像删除
docker rmi -f $(docker images -qa)
通过镜像启动容器
# args:
# --name "" 容器名字
# -d 后台方式运行
# -it 交互模式运行,进入容器
# -p 指定端口号,如:-p 8080:8080,不输入参数随机指定端口
# -p 主机端口:容器端口
# -p 容器端口
# -p ip:主机端口:容器端口
# image 是镜像的名
docker run [args] image
# e.g.
[xxx@xxxxxxxxxxxxxxxxxx ~]# docker run -it centos /bin/bash
[xxx@xxxx /]#
# 容器停止并退出
exit
# 容器不停止退出
ctrl + P + Q
# 列出当前正在运行的容器
docker ps
# 列出当前正在运行的容器、历史运行过的容器即所有容器
docker ps -a
# 最近创建的num个容器
docker ps -n=num
# 只显示编号
docker ps -q
# 无法删除正在运行的容器
docker rm ID
# 删除所有容器
docker rm -f $(docker ps -aq)
docker ps -a -q|xargs docker rm
docker start ID
docker restart ID
# stop和kill的区别在于stop会给容器内的应用10s时间去停止服务,kill直接停止
docker stop ID
docker kill ID
start
和 run
的区别
run
:对镜像进行新建并运行start
:对关闭的容器进行运行(需存在)# 日志打印
# --tail num 显示的num条日志
docker logs -f -t --tail num containerID
# 所有日志
dokcer logs -tf containerID
# Shell 脚本
"while true;do echo Lyn-coder;sleep 1;done"
# 后台运行
docker run -d centos /bin/sh -c "while true;do echo Lyn-coder;sleep 1;done"
# top
# docker top 2a7099f3b1d3
UID PID PPID C STIME TTY TIME CMD
root 14614 14594 0 19:14 ? 00:00:00 /bin/sh -c while true;do echo Lyn-coder;sleep 1;done
root 15104 14614 0 19:19 ? 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1
# 查看容器的详细信息
docker inspcet containerID
# 进入容器新终端
docker exec -it containerID /bin/bash
# 进入容器后使用,不开启新线程
docker attach containerID
# container -> host
# docker cp 72446cb56e8b:/home/demo.java /home
docker cp containerID:dir dstDIr
使用 Docker 安装 tomcat
# docker hub
# --rm 用于测试,使用完毕即删除容器
docker run -it --rm tomcat:9.0
# ====================
# run
docker run -d -p 8080:8080 --name tomcat_01 tomcat:9.0
# webapps 中没有任何文件,将 webapps.dist 文件夹中的文件 copy 到 webapps
# 就不会再是404的网页了
docker exec -it tomcat_01 /bin/bash
Pointer
:图形化界面管理工具
# 安装
docker run -d -p xxxx:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
# 提交
docker commit -m="msg" -a="author" containerID 镜像名:版本
docker commit -a="Lyn-coder" -m="Tomcat webapps upgrade to test docker commit" 71b588888a1f tomcat_lyn:1.0
容器之间想要实现数据共享,Docker 容器中的数据可以同步到 host
目录的挂载,卷技术
目的:
挂载
-v
# host-dir:主机目录位置
# container-dir:容器目录位置
docker run -it -v host-dir:container-dir containerID /bin/bash
Docker 与 MySQL
docker run -d -p xxxx:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=xxxxxx --name mysql_01 -d mysql
匿名与具名挂载
# -P 随机指定端口号,也可以指定端口号
# 匿名
docker run -d -P 容器内路径 镜像名
# 具名
docker run -d -P 卷名:容器内路径 镜像名
# all volume 卷
docker volume ls
# 卷具体信息
docker volume inspect 卷名
不指定目录时,Docker 容器中的卷,都存储在 /var/lib/docker/volumes/xxx/_data
匿名挂载、具名挂载、指定路径挂载的区分
匿名挂载
-v 容器内路径
具名挂载
-v 卷名:容器内路径
指定路径挂载
-v /host路径:容器内路径
参数补充
-ro
:read only,只读,只能从 host 对其进行操作,容器没有这个权限-rw
:read write,读写权限DockerFile
用来构建 Docker 镜像
标准文件命名为:Dockerfile
# 文件命令需大写
FROM centos
VOLUME ["volume-01", "volume-02"]
CMD echo "===== end ====="
CMD /bin/bash
# 命令
docker build -f dockerfile-01 -t lyn/centos:1.0 .
# 执行
Sending build context to Docker daemon 2.048kB
Step 1/4 : From centos
---> 5d0da3dc9764
Step 2/4 : VOLUME ["volume-01", "volume-02"]
---> Running in 3e130dcabdb4
Removing intermediate container 3e130dcabdb4
---> 6b05c51c3970
Step 3/4 : CMD echo "===== end ====="
---> Running in 3a575a9f422b
Removing intermediate container 3a575a9f422b
---> 4e0a395ccac0
Step 4/4 : CMD /bin/bash
---> Running in fc17b239c866
Removing intermediate container fc17b239c866
---> 21e01bdb29b2
Successfully built 21e01bdb29b2
Successfully tagged lyn/centos:1.0
# TEST
# volume-01中创建一个 txt 文件
# 通过 inspect 查看 挂载位置
两个及两个以上的容器进行数据同步
--volumes-from xxx
# 21e01bdb29b2:镜像ID
docker run -it --name docker-01 21e01bdb29b2
#
docker run -it --name docker-02 --volumes-from docker-01 21e01bdb29b2
# --volumes-from => 继承于
DockerFile
构建镜像的步骤:
docker build
构建镜像docker push
发布镜像(Docker Hub/阿里云镜像仓库)DockerFile 原则
保留关键字必须是大写
执行顺序由上到下
注释使用 #
每一条指令都会创建并提交新的镜像层
面向开发,制作镜像发布项目需要编写 DockerFile 文件
FROM
:指定基础镜像;MAINTAINER
:指定镜像作者,姓名+邮箱;RUN
:镜像构建运行命令;ADD
:增加镜像层;WORKDIR
:设置镜像工作目录;VOLUME
:设置挂载目录(卷);EXPOSE
:设置暴露的端口,类比 -p
;CMD
:指定容器启动时运行的命令,只有最后一条命令生效;ENTRYPOINT
:指定容器启动运行的命令,可追加命令;ONBUILD
:构建一个被继承的时候运行时的命令;COPY
:将文件拷贝到镜像中;ENV
:设置环境变量;DEMO测试
# DockerFile
FROM centos
MAINTAINER author<email>
ENV MYPATH /usr/local
WORKDIR $MYPATH
# vim
RUN yum -y install vim
# ifconfig
RUN yum -y install net-tools
# 暴露端口
EXPOSE 80
# 打印
CMD echo $MYPATH
CMD echo "===== end ====="
CMD /bin/bash
=======================================================================
# 构建命令
docker build -f mydockerfile-centos -t lyn-mycentos:0.1 .
# 运行
docker run -f 镜像name -t 镜像[:tag] .
DEMO测试——Tomcat镜像
注:参考狂神的视频
步骤:
准备 JDK 和 Tomcat 的压缩包
编写 Dockerfile 文件
FROM centos:7
MAINTAINER author<email>
COPY readme.md /usr/local/readme.md
# 使用ADD命令会自动解压
ADD jdk-8u341-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.65.tar.gz /usr/local/
# 安装vim
RUN yum -y install vim
#
ENV MYPATH /usr/local
WORKDIR $MYPATH
# 配置环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_341
# 核心jar包
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.65
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.65
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
# 容器内端口
EXPOSE 8080
# 容器启动时运行
CMD /usr/local/apache-tomcat-9.0.65/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.65/bin/logs/catalina.log
通过 Dockerfile 构建镜像
docker build -t lyn-tomcat-images .
运行
docker run -d -p xxxx:8080 --name lyn-tomcat -v /home/xxx/build/tomcat/test:/usr/local/apache-tomcat-9.0.65/webapps/test -v /home/xxx/build/tomcat/tomcat-logs/:/usr/local/apache-tomcat-9.0.65/logs lyn-tomcat-images
在 webapps 文件夹的 test 文件夹中添加 WEB-INF 文件夹、jsp 和 xml 文件,注意:jsp 文件要与 WEB-INF 文件夹同目录
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
Hello World!
<%-- JSP Comment --%>
Hello World!
<%
System.out.println("====== Lyn-Tomcat =======");
%>
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_3_0.xsd">
web-app>
步骤
Docker Hub 账号登录
docker login -u xxxx
push
# 增加tag 原镜像名称 新镜像名称
docker tag xxx xxx
# push
docker push xxx:tag
发布到阿里云镜像
使用 ip addr
,三个网卡:
lo
:本机回环地址eth0
:阿里云内网地址docker0
:Docker0地址# 查看容器内部 ip
docker exec -it xxxx ip addr
# 若出现 OCI runtime exec failed: exec failed: unable to start container process: exec: "ping": executable file not found in $PATH: unknown 报错
# 进入容器内部使用以下两条命令
apt-get update
apt-get install inetutils-ping
原理
每个 Docker 容器启动时,Docker 容器就会被分配到一个 ip;
Docker 会带有一个网卡 Docker0,使用的模式是桥接模式,使用的技术是 **evth-pair
**
exth-pair
:一对虚拟设备接口,充当一个桥梁,连接虚拟网络设备容器在不指定网络的情况下,都是通过 Docker0 充当路由,Docker 会分配给容器可用的 ip;
核心是使用了 Linux 的虚拟化网络技术;
Docker 中的网络接口都是虚拟的;
每个容器对应一对网桥;
--link
原理
/etc/hosts
文件中增加对另一个容器的映射# 通过 --link 连接另一个容器,而不是用网络
docker run .... --link ConatinerName ...
# 例如tomcat
docker run -d -P --name docker-web-tomcat-01 --link docker-web-tomcat-01 tomcat
--link
在现实开发中已推荐使用
网络模式
bridge
:桥接模式(默认);none
:不配置网络;host
:和 host 共享网络;# 查看所有网络(Docker中)
docker network ls
# 自定义网络
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
--link
,即可直接连接另一个容器相当于给容器再分配一个 ip
# 将 CONTAINER 连通到另一个网络
# 相当于把容器加入到网络的配置中
docker network connect NETWORK CONTAINER