开发以及上线的过程中,环境配置是十分麻烦的,每一台机器都要部署环境,非常费时费力,那么能不能在发布项目的时候带上环境安装打包呢?(jar+redis+mysql+jdk+es…)。
在服务器配置应用的环境时,非常的麻烦,并且不能够跨平台。
对于这些问题,Docker给出了解决方案。
java–>jar(环境)–>打包项目带上环境(镜像)–>docker仓库—>下载镜像—>直接运行。
DevOps(开发,运维)
传统运维:一堆文档,安装程序;
Docker:打包镜像发布测试,一键运行。
使用Docker,部署应用和搭积木一样。
在容器化之后,我们的开发、测试环境都是高度一致的
Docker是内核级别的虚拟化,可以在一个物理机上运行很多的容器实例。服务器的性能可以压榨到极致。
Docker的基本组成
镜像(image):
docker镜像就好比一个模板,可以通过这个模板来创建容器服务,tomcat镜像===》run===》tomcat1容器()提供服务器,通过这个镜像可以创建多个容器(最终服务运行或者项目运行就是在容器中的)。
容器(container):
Docker利用容器技术,独立运行一个或一个组应用,通过镜像来创建;
启动、停止、删除,基本命令;
目前就可以把这个容器理解为就是一个简易的linux系统
仓库(repository):
就是存放镜像的地方;仓库分为公有和私有;
Docker Hub(默认是国外的)
阿里云。。。都有容器服务器(配置镜像加速)
$ sudo 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 \
https://download.docker.com/linux/centos/docker-ce.repo #默认国外
yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo #阿里云
yum makecache fast
docker-ce 社区 docker-ee 企业版
yum install docker-ce docker-ce-cli containerd.io
systemctl start docker
#查看版本
docker version
docker run hello-world
docker images
#卸载依赖
yum remove docker-ce docker-ce-cli containerd.io
#删除资源
rm -rf /var/lib/docker #docker默认工作路径
阿里云—>容器镜像服务—>镜像加速器
sudo mkdir -p /etc/docker
#此地址每个人不同,内网地址,其他人无法使用
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://f63lm5vo.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
全部命令图示
service docker start #开启服务
docker version #显示版本信息
docker info #显示系统信息
docker 命令 --help #万能命令
docker images 查看所有本地的主机上的镜像
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest bf756fb1ae65 11 months ago 13.3kB
#解释
REPOSITORY 镜像的仓库源
TAG 镜像的标签
IMAGE ID 镜像的ID
CREATED 镜像创建时间
SIZE 镜像的大小
#可选项
Options:
-a, --all 列出所有镜像
-q, --quiet 只显示镜像的ID
docker search 搜索镜像
docker publl 下载镜像
docker pull 镜像名:tag #tag 版本号
删除镜像
docker rmi -f id #删除指定id的镜像
docker rmi -f $(docker images -aq) #删除全部
docker rmi -f id id id #删除多个
说明:有了镜像才能创建容器
测试centos;
docker pull centos
docker run 可选参数 image
#参数说明
--name “name” 容器名字 tomcat01 tomcat02 ,用来区分容器
-d 后台方式运行
-it 容器名 地址路径 使用交互方式运行,进入容器查看内容 (例:docker run -it centos /bin/bash)
-p 指定容器的端口 -p 8080:8080
-p ip:主机端口:容器端口
-p 主机端口:容器端口(常用)
-p 容器端口
-P 随机指定端口
# 停止容器并退出
exit
# 容器不停止退出
`ctrl`+P+Q
#查看当前运行的容器
docker ps
#查看当前运行的容器+历史运行过的容器
docker ps -a
#显示最近运行的容器
-n=?
#显示容器的编号
-q
docker rm 容器id #删除指定容器,不能删除正在运行的容器,强制删除 rm -f
docker rm -f $(docker ps -aq) #删除全部
docker ps -a -q|xargs docker rm #管道方式删除全部
docker start 容器id #启动容器
docker restart 容器id #重启容器
docker stop 容器id #停止当前运行的容器
docker kill 容器id #强制停止当前容器
#命令 docker run -d 镜像名
docker run -d centos
#问题docker ps ,发现 centos停止了
#常见的坑:docker 容器使用后台运行,就必须要有一个前台进程,docker发现没有应用,就会自动停止
docker logs -f -t --tail 条数 容器id
docker top 容器id
docker inspect 容器id
我们通常容器都是使用后台方式运行,需要进入容器,修改一些配置
#第一种命令 进入容器后开启一个新的终端,可以在里面操作(常用)
docker exec -it 容器id bashshell (例:docker exec -it 0a360e8a37c1 /bin/bash)
#第二种命令 进入容器正在执行的终端,不会启动新的进程
docker attach 容器id
docker cp 容器id:容器内路径 主机路径
#拷贝是一个手动过程,可以使用 -v 卷的技术,实现自动同步
#1. 搜索镜像
#2. 下载镜像
#3. 运行测试
docker run -d --name nginx01 -p 3344:80 nginx
# 请求服务测试是否启动
curl localhost:3344
访问成功
安装运行
docker run -d -p 8000:9000 \
--restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
访问测试
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。
所有应用,直接打包dockers镜像,就可以直接跑起来。
如何得到镜像:
docker commit #提交容器成为一个新的镜像
#命令和git原理类似
docker commit -m="描述信息" -a="作者" 容器id 目标镜像名:【TAG】
实战测试
#1.启动一个默认的tomcat
#2.发现这个默认的tomcat没有webapps应用,是因为官方的镜像默认webapps下没有文件
#3.自己将webapps.site下的基本文件拷到webapps下
#4.以后就想用这个镜像,将这个镜像通过commit提交为一个镜像,以后就可以使用修改过的镜像;想发布给别人,在下文dockerFile时讲
docker commit -a="pavel" -m="add webapps app" 容器id tomcat02:1.0
如果想要保存当前容器的状态,就可以通过commit来提交,获得一个镜像;
就好比VM的快照。
docker的理念回顾
将应用和环境打包成一个镜像!
如果数据都在容器中,那么我们容器删除,数据就会丢失。需求:数据可以持久化
MYSQL,容器删了,删库跑路!需求:mysql数据可以保存到本地
容器直接可以有一个数据共享的技术。
这就是卷技术。目录的挂载,将我们容器内的目录,挂载到linux上。
容器的持久化和同步操作;容器间也可以数据共享
方式一:直接使用命令来挂载 -v
docker run -it -v -p 主机目录:容器内目录
#测试
docker run -it -v -p /home/test:/home centos /bin/bash
#启动起来之后可以通过 docker inspect 容器id 通过元数据来查看是否挂载
# 1.下载镜像
# 2.运行容器,需要挂载数据;安装启动MySQL需要配置密码,需要注意!
# -e 环境配置
docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7.30
匿名挂载,在 -v 只写了容器内的路径,没有写容器外的
# 匿名挂载
-v 容器内路径
docker run -d -P --name nginx01 -v /etc/nginx nginx
# 查看卷
docker volume --help
# 查看所有volume的情况
docker volume ls
#具名挂载(容器内路径最前不加/就只是卷名 不是容器外路径)
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
#查看卷路径
docker volume inspect juming-nginx
所有容器内的卷,没有指定目录的情况下都是在/var/lib/docker/volumes/xxx
;
通过具名挂载可以方便的找到我们的卷,大多数情况使用这种挂载。
Dockerfile就是用来构建docker镜像的构建文件!命令脚本!
通过这个脚本可以生成一个镜像,
方式二:通过Dockerfile挂载卷
这种方式的使用非常多,因为我们通常会构建自己的镜像
容器和容器之间同步
例:两个Mysql同步数据
# 通过--volumes-from 关联容器,相当于子容器继承了父容器
多个mysql实现数据共享
结论:
容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止。
但是一旦持久化到了本地,这个时候,本地的数据是不会删除的。
docker是用来构建镜像的文件!命令参数脚本。
构建步骤:
1. 编写一个dockerfile文件
2. docker build 构建成为一个镜像
3. docker run 运行镜像
4. docker push 发布镜像(dockerHub、阿里云镜像仓库)
很多官方镜像都是基础包,很多功能没有,我们通常会搭建自己的镜像。
dockerfile是面向开发的,我们以后要发布项目,做镜像,就需要编写dockerfile文件,这个文件十分简单;
Docker镜像逐渐成为企业交付的标准,必须要掌握!
DockerFile: 构建文件,定义了一切的步骤,相当于源代码
DockerImages:通过DockerFile构建生成的镜像,最终发布和运行的产品
Docker容器:容器就是镜像运行起来提供服务器
FROM # 基础镜像,一起从这里开始构建 centos
MAINTAINER # 镜像是谁写的,姓名+邮箱
RUN # 镜像构建的时候需要运行的命令
ADD # 步骤: 比如tomcat镜像,这个tomcat压缩包!添加内容
WORKDIR # 镜像的工作目录
VOLUME #挂载的目录
EXPOST #保留端口配置
CMD #指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD # 当构建一个被继承DockerFile的时候,就会运行ONBUILD指令。触发指令。
COPY # 类似ADD,将我们文件拷贝到镜像中
ENV # 构建的时候设置环境变量
构建自己的centos镜像
DockerHub中99%镜像都是从这个基础镜像过来的 FROM scrath,然后配置需要的软件和配置来进行构建
创建自己的centos
FROM centos
# 作者
MAINTAINER pavel<[email protected]>
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
# 命令
docker build -f dockersfile文件路径 -t 镜像名:版本号 .
docker run -it 镜像名:版号
docker history 镜像id
拿到镜像时,可以通过这个命令研究一下这个镜像怎么做的。
Dockerfile
,build的时候会自动寻找这个文件,就不需要-f指定了。FROM centos
MAINTAINER pavel<[email protected]>
# 将文件拷贝进容器内
COPY readme.txt /usr/local/readme.txt
# 添加tomcat和jdk的压缩包
ADD jdk-8u161-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-8.5.55.tar.gz /usr/local/
# 安装需要的命令
RUN yum -y install vim
RUN yum -y install net-tools
#配置环境变量
ENV MYPATH /usr/local
#根目录
WORKDIR $MYPATH
ENV JAVA_HOME /usr/local/jdk1.8.0_161
ENV CLASSPATH %JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.55
ENV CATALINA_BASH /usr/local/apache-tomcat-8.5.55
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
#暴露端口
EXPOSE 8080
#启动时要运行的命令
CMD /usr/local/apache-tomcat-8.5.55/bin/startup.sh && tail -F /usr/local/apache-tomcat-8.5.55/bin/logs/catalina.out
docker build -t mytomcat .
docker run -d -p 9090:8080 --name mytomcat -v /home/pavel/docker-build/tomcat/webapps/xj:/usr/local/apache-tomcat-8.5.55/webapps/xj -v /home/pavel/docker-build/tomcat/tomcatlogs:/usr/local/apache-tomcat-8.5.55/logs mytomcat
1提交自己的镜像
#登录
docker login -help
#给上传的镜像命名
docker tag 镜像名 docker用户名/自定义镜像名:自定义版本号
#push
docker push 自定义镜像名
退出登录
docker logout
打开容器镜像服务
测试
结论:tomcat01和tomcat02是公用的一个路由器,docker0.
所有的容器不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可用IP
小结
Docker使用的是linux的桥接,宿主机是一个Docker容器的网桥 docker0;
veth-pair
其实这个tomcat03就是在本地配置了tomcat02的配置
本质探究:–link 就是我们在hosts配置中增加了一个配置
下载Docker已经不建议使用–link;
推荐自定义网络;
docker0问题:不支持容器名连接访问。
查看所有的docker网络
bridge:桥接 (docker默认)
none:不配置网络
host:和宿主机共享网络
container:容器内网络联通(用的少,局限很大)
# 我们直接启动的命令 默认有--net bridge,而这个就是我们的docker0
docker run -d -P --name tomcat01 --net bridge tomcat
#docker0特点:默认,域名不能访问,--link可以打通连接!
#我们可以自定义网络
[root@localhost bin]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
096a037158422ba28fa832c3b7a488dcff6e941d002b5d5f5350b237b100c32b
[root@localhost bin]# docker network ls
NETWORK ID NAME DRIVER SCOPE
d8a759735ff1 bridge bridge local
03c0d84e10ba host host local
096a03715842 mynet bridge local
f076b6c9c5a7 none null local
#查询自定义网络的属性
docker network inspect mynet
#用自己的网络启动容器
docker run -d -P --name tomcat-net-01 --net mynet tomcat
为什么要用自定义网络 ?
容器间可以通过容器名ping通。
好处:
redis -不同的集群使用不同的网络,保证集群是安全和健康的
mysql -不同的集群使用不同的网络,保证集群是安全和健康的
打通不同网络间的容器
# 测试打通 tomcat01 -mynet
docker network connect 网络名 容器名
docker network connect mynet tomcat01
# 联通之后就是将tomcat01放到了 mynet 网络下;
# 一个容器两个ip地址
# 阿里云服务: 公网ip 私网ip 就是这么实现的
#创建网卡
docker network create redis --subnet 172.38.0.0/16
# 通过shell脚本来创建6个redis配置
for port in $(seq 1 6); \
do \
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
cat << EOF >>/mydata/redis/node-${port}/conf/redis.conf
port 6379
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done
#启动容器 (依次启动6个)
docker run -p 6371:6379 -p 16371:16379 --name redis-1 \
-v /mydata/redis/node-1/data:/data \
-v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
#进入redis
docker exec -it redis-1 /bin/sh (redis下没有bash)
#创建集群
redis-cli --cluster create ip:端口(1-6) --cluster-replicas 1
[外链图片转存中…(img-iHET0Vrl-1608604680892)]