官网地址:https://www.docker.com/html
文档地址:https://docs.docker.com/java
#1.卸载旧版本 sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine #2.安装存储库 sudo yum install -y yum-utils #3.设置镜像仓库 #默认是国外镜像,比较慢 sudo yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo #推荐使用国内的阿里云镜像 sudo yum-config-manager \ --add-repo \ http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo #4.安装docker引擎(最新版本) sudo yum install docker-ce docker-ce-cli containerd.io #5.启动docker sudo systemctl start docker #测试docker安装成功 docker version #6.测试Helloword sudo docker run hello-world
#1.卸载 Docker Engine、CLI 和 Containerd 包: sudo yum remove docker-ce docker-ce-cli containerd.io #2.主机上的映像、容器、卷或自定义配置文件不会自动删除。删除全部镜像、容器和卷: sudo rm -rf /var/lib/docker sudo rm -rf /var/lib/containerd #/var/lib/docker docker的默认工做路径
登录阿里云官网找到容器镜像服务mysql
镜像加速地址linux
配置使用nginx
sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://cvftrj14.mirror.aliyuncs.com"] } EOF sudo systemctl daemon-reload sudo systemctl restart docker
docker version #显示docker的版本信息 docker info # 显示docker的系统信息 docker 命令 --help #帮助命令
帮助文档地址:https://docs.docker.com/reference/git
docker images #查看全部本地的主机上的镜像 docker search xx #搜索xx镜像 docker pull xx #拉取下载xx镜像 docker rmi -f 镜像id #删除指定的镜像 docker rmi -f 镜像id 镜像id #删除多个镜像 docker rmi -f $(docker images -aq) #删除所有的容器
#新建容器并启动 dockers run [可选参数] 镜像id或名字 docker run -d --name nagin01 -p 3344:80 nginx #参数说明 --name="Name" #容器名字 -d #后台方式运行 -it #使用交互方式运行,进入容器查看内容 -p #指定容器的端口 -p 8080:8080 (主机端口:容器端口) -P #随机指定端口 #启动并进入容器 docker run -it centos /bin/bash #退出容器 exit#直接退出容器并中止 ctrl+Q+P #容器不中止退出 #列出全部的容器 docker ps [可选参数] #可选参数 -a #列出全部的容器 -n #显示最讲建立的容器 -q #只显示容器的id #删除容器 docker rm 容器id #删除指定容器 docker rm -f $(docker ps -aq) #强制删除全部的容器 #启动和中止容器 docker start 容器id #启动指定的容器 docker restart 容器id #重启指定的容器 docker stop 容器id #中止指定的正在运行容器 docker kill 容器id #强制中止指定的容器
#查看日志、 docker logs #查看容器中的进程信息 docker top 容器id #查看镜像元数据 docker inspect 容器id #进入正在运行的容器 docker exec -it 容器id /bin/bash docker attach 容器id #这两种方式的区别 #docker exec 进入容器开启一个新的终端,能够在里面操做 #docker attach 进入容器正在执行的终端,不会启动新的线程 #从容器内拷贝文件到主机上 docker cp 容器id:容器内路径 目的地主机路径 #查看cpu的状态 docker stats
docker run -it --rm tomcat:9.0 #咱们以前的启动都是后台,中止了容器后,容器还能够查看,这个命令是用完后就删除容器,通常用于测试
portainer(暂时先用)github
docker run -d -p 8000:8000 -p 9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce
Rancher(CI/CD再用)web
Portainer是一个可视化的容器镜像的图形管理工具,利用Portainer能够轻松构建,管理和维护Docker环境。 并且彻底免费,基于容器化的安装方式,方便高效部署。redis
官方站点:https://www.portainer.io/spring
#1.下载并启动 docker run -d -p 8000:8000 -p 9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce #2.开放端口并外网访问测试 www.enora.com.cn:9000
访问后页面以下,首先选择Docker的connect
进入docker 管理的主页
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境开发的软件,它包含了运行某个软件所需的全部内容,包括代码、运行时、库、环境变量和配置文件。全部的应用,直接打包docker镜像,就能够直接跑起来!
如何获得镜像
UnionFS(联合文件系统)
UnionFS(联合文件系统):是一种分层、轻量级并高性能的文件系统,它支持对文件系统的修改,做为一次提交来一层层的叠加,同时能够将不一样目录挂载到同一个虚拟文件系统下。Union文件系统是Docker镜像的基础。镜像能够经过分层来进行继承,基于基础镜像(没有父镜像),能够制做各类具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统包含全部底层的文件和目录。
Docker镜像加载原理
docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统是UnionFS。采用分层构建机制,最底层为bootfs,其之上rootfs。
bootfs:(boot file system)主要包含bootloader和kernel,bootloader主要是引导加载kennel,linux刚启动是会加载bootfs文件系统,再docker镜像的最底层是bootfs。这一层与咱们典型的Linux/Unix系统是同样的,包含bootj加载器和内核。当boot加载完成后整个内核就在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
rootfs: 位于bootfs之上,rootfs是Docker容器在启动时内部进程可见的文件系统,即Docker容器的根目录。rootfs一般包含一个操做系统运行所需的文件系统,例如可能包含典型的类Unix操做系统中的目录系统,如/dev、/proc、/bin、/etc、/lib、/usr、/tmp及运行Docker容器所需的配置文件、工具等。
特色
Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部。这一层就是咱们一般说的容器层,容器层之下的都叫镜像层
如何提交一个本身的镜像
docker commit #提交容器成为一个新的副本 #命令和git原理相似 docker commit -m="提交的描述信息" -a="做者" 容器id 目标镜像名:[TAG]
实战测试
#1. 启动一个默认的tomcat docker run -d -p 8080:8080 46cfbf1293b1 #2. 发现这个默认的tomcat是没有webapps应用,镜像的缘由官方的镜像默认webapps下面是没有文件的 #3. 本身拷贝基本的文件到webapps文件夹下 cp -r webapps.dist/* webapps #4.将咱们操做过的容器经过commit提交为一个新的镜像,之后咱们就能够直接使用咱们修改过的镜像便可 docker commit -a="sean" -m="add apps into webapps folder" 3de860244cd4 tomcat_sean:v0.1
当咱们在使用docker容器的时候,会产生一系列的数据文件,这些数据文件在咱们关闭docker容器时是会消失的,可是其中产生的部份内容咱们是但愿可以把它给保存起来另做用途的,Docker将应用与运行环境打包成容器发布,咱们但愿在运行过程钟产生的部分数据是能够持久化的的,并且容器之间咱们但愿可以实现数据共享。
容器之间能够有一个数据共享的技术,将Docker容器中产生的数据,同步到本地!这就是卷技术。目录的挂载将容器内的目录挂载到Linux上面。
总结:容器的持久化和同步操做,容器间也是能够同步数据的!
docker run -it -v 主机目录:容器内目录
测试
1.启动运行容器
docker run -it -v /home/sean:/home 300e315adb2f
2.启动起来后能够经过 命令docker inspect 容器id
查看挂载状况
docker inspect 8a5f116da90b
之后修改只需再本地修改便可,容器内会自动同步
思考:Mysql的数据持久化的问题
#获取镜像 docker pull mysql:5.7 #运行容器的时候,须要作数据挂载,须要注意的是Mysql须要配置密码(参考官方文档),若是没有设置密码的化,容器是启动不起来的 docker run -d -p 3306:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MY_SQL_ROOT_PASSWORD=root mysql:5.7
容器运行后,使用Navicat 软件链接docker的Mysql
在数据库中新建一个数据库
如今进入宿主机服务器目录/home/mysql/data,查看是否有刚才建立的数据库
以上测试代表:容器内的mysql中的数据已经同步到服务器本地咯,实现了容器数据持久化功能
具名和匿名挂载
匿名挂载
在使用-v 进行数据卷挂载的时候,只有容器内路径,即-v 容器内路径
#匿名挂载 docker run -d -P --name nginx01 -v /etc/nginx nginx
查看全部的volume的状况
docker volume ls
这种没有一串随机数字的就是匿名挂载生成的volume name
具名挂载
在使用-v 进行数据卷挂载的时候,卷名:容器内路径,即-v 卷名:容器内路径
docker run -d -P --name nginx02 -v sean_nginx:/etc/nginx nginx
查看volume的状况
查看该卷
docker volume inspect sean_nginx
全部的docker容器内的卷,没有指定目录的状况下都是在该目录下/var/lib/docker/volumes/xxx/data
经过具名挂载能够方便的找到咱们的一个卷,大多数状况下都使用具名挂载
#如何区分匿名、具名、指定路径挂载 -v 容器内路径 #匿名挂载 -v 卷名:容器内路径 #具名挂载 -v /宿主机路径:容器内路径 #指定路径挂载
拓展:
#经过 -v 容器内路径:ro rw 改变读写权限 ro:read only #只读 rw: readwrite #可写可读 docker run -d -P --name nginx02 -v sean_nginx:/etc/nginx:ro nginx docker run -d -P --name nginx02 -v sean_nginx:/etc/nginx:rw nginx #ro 说明这个路径只能经过宿主机来操做,容器内部是没法操做的
初识DockerFile
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。经过这个脚本能够生成镜像,镜像是一层一层的,脚本一个一个的命令,每一个命令都是一层。
FROM centos VOLUME ["volume01","volume02"] CMD '---------end-----------' CMD /bin/bash
构建docker镜像
docker build -f dockerFile1 -t centos_sean . #-f, --file string Name of the Dockerfile (Default is 'PATH/Dockerfile') # -t, --tag list Name and optionally a tag in the 'name:tag' format
运行生成的镜像,能够看到是能够运行进入到容器内的
这个卷和外部必定有一个同步的目录
#经过docker inspect能够查看对应的挂载目录 docker inspect 4daed2f6eb77
数据卷容器(容器间的数据共享)
命名的容器挂载数据卷,其余容器经过挂载这个父容器实现数据共享,挂载数据卷的容器称为数据卷容器。
建立数据卷容器
docker run -it --name dc01 imageName #启动dc01容器 docker run -it --name dc02 --volumes-from dc01 imageName #dc02继承自dc01
容器之间配置信息的传递,数据卷的生命周期一直持续到没有容器使用它为止!!!
应用:多个Mysql共享数据或者nginx共享数据
总结:经过--volumes-from能够实现容器间的数据共享。
参考:https://www.cnblogs.com/lwenwu/p/14029573.html
dockerFile是用来构建docker镜像的文件,命令参数脚本
构建步骤:
首先了解官方镜像(centos为例)
点击版本号后跳转到github,发现github上就是DockerFile文件
官方既然能够制做镜像,那咱们也能够本身制做本身的镜像,不少官方镜像都是基础包,不少功能都没有,一般会本身构建本身的镜像
基础知识:
dockerfile是面向开发的,之后要发布项目,作镜像都须要编写dockerfile文件!Docker镜像逐渐成为一个企业的交付标准,必须掌握。
步骤:
DockerFile:构建文件,定义了一切的步骤,至关于源代码
DockerImages:经过dockerfile构建生成的镜像,最终发布和运行的产品
Docker容器:容器就是镜像运行起来提供服务器
FROM #基础镜像,一切从这里开始构建 MAINTAINER #镜像是谁写的,姓名+邮箱 RUN #镜像构建的时候须要运行的命令 ADD #添加内容,好比要在centos基础上添加tomcat就须要使用该命令 WORKDIR #镜像的工做目录 VOLUME #挂载的目录 EXPOST #保留端口配置 CMD #指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代 ENTRYPOINT #指定这个容器启动的时候要运行的命令,能够追加命令 ONBUILD #当构建一个被继承DockerFile,这个时候就会运行ONBUILD的指令,触发指令 COPY #相似ADD,将文件拷贝到镜像中 ENV #构建时设置环境变量
实战:构建一个本身的镜像
#1.编写DockerFile文件 FROM centos MAINTAINER xuxin<sean_xin@126.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 #2.构建镜像 docker build -f myCentos -t myCentos . #3.测试运行 docker run -d 86f274d241ef
发现pwd命令、工做目录等都已经按照dockerfile修改了
#镜像的历史变动,平时拿到一个镜像,可使用该命令研究它的建立过程 docker history 镜像id
准备镜像文件tomcat压缩包,jdk的压缩包
编写dockerfile文件,官方命名Dockerfile
FROM centos MAINTAINER sean<sean_xin@126.com> COPY readme.txt /usr/local/readme.txt ADD apache-tomcat-7.0.81.tar.gz /usr/local ADD jdk-8u211-linux-x64.tar.gz /usr/local RUN yum -y install vim ENV MYPATH /usr/local WORKDIR $MYPATH ENV JAVA_HOME /usr/local/jdk1.8.0_211 ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ENV CATALINA_HOME /usr/local/apache-tomcat-7.0.81 ENV CATALINA_BASH /usr/local/apache-tomcat-7.0.81 ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin EXPOSE 8080 CMD /usr/local/apache-tomcat-7.0.81/bin/startup.sh && tail -F /usr/local/apche-tomcat-7.0.81/bin/catalina.out
构建镜像(使用Dockerfile命令后不用-f命令)
docker build -t diytomcat .
运行镜像
docker run -d -p 9090:8080 --name seantomcat -v /home/sean/test:/usr/local/apache-tomcat-7.0.81/webapps/test -v /home/sean/tomcatlogs/:/usr/local/apache-tomcat-7.0.81/logs diytomcat
访问测试
发布项目(因为作了卷挂载,能够直接再本地编写项目就发布)
发布镜像到dockerHub
官网注册帐号:https://hub.docker.com/
登陆dockerHub
docker login -u724056979
提交镜像
#首先须要对镜像进行打tag标签,用dockerhub帐户名/镜像名:版本号 docker tag centos_sean:latest 724056979/centos:1.0 #而后使用push命令提交镜像 docker push 724056979/centos:1.0
发布镜像到阿里云
登陆阿里云
找到容器镜像服务
建立命名空间
建立容器镜像
建立成功后,根据阿里云提示操做
小结:
#经常使用的docker network命令 docker network --help #获取docker网络命令帮助 docker network ls #获取dockers全部的网络 docker network inspect networkId #查看具体network的元数据
测试:3个重要的网卡地址
思考:docker是如何处理容器网络访问的?
宿主机能够ping通docker运行的容器嘛?
#查看容器内地址 docker exec -it tomcat01 ip addr
发现容器启动的时候会获得一个eth0@if72 ip地址,docker分配的。
说明宿主姐能够ping通容器内部
原理
每启动一个docker容器,docker就会给docker容器分配一个ip,只要安装了docker,就会有一个网卡docker0,使用桥接模式,其使用的技术就是evth-pair技术!
ip addr
发现会多一个网卡再启动一个tomcat容器,并查看地址,发现又多一对网卡地址73:vetha2920@if72
#启动tomcat02容器 docker run -d --name tomcat02 tomcat #查看ip地址 ip addr
veth-pair就是一对的虚拟设备接口,他们都是成对出现的,正是由于有这个特性,一端连着协议,一端彼此相连,evth-pair充当一个桥梁,链接各类虚拟网络设备的
测试如下tomcat01和tomcat02是否能够ping 通
docker exec -it tomcat02 ping 172.17.0.2
结论:容器和容器之间是能够互相ping通的
Docker核心网络图:docker中的全部的网络接口都是虚拟的,虚拟的转发效率高!只要删除容器,对应网桥也就删除
思考一个场景,编写一个微服务,database url=ip,项目部重启,数据库ip换掉了,能够经过名字来进行访问容器。也就是说能够想springcloud的服务发现与注册同样使用名称来注册服务,而不是使用IP地址的方式
#同时启动了2个tomcat容器 docker ps
#都直接使用容器名可否ping通呢? docker exec -it tomcat01 ping tomcat02
发现都使用容器名是不能ping通的,该如何解决这个问题呢?可使用docker --link
解决网络连通问题
#使用--link从新启动过一个tomcat03 docker run -d -P --name tomcat03 --link tomcat02 tomcat #使用容器名tomcat03 ping tomcat02 docker exec -it tomcat03 ping tomcat02
测试发现经过--link
可使用容器名互相通讯的。可是可使用tomcat02 ping tomcat03吗?继续测试
#使用容器名tomcat02 ping tomcat03 docker exec -it tomcat02 ping tomcat03
测试发现这样是不行的,探究其中的原理
#查看tomcat03的host文件配置 docker exec -it tomcat03 cat /etc/hosts
--link
本质:就是在hosts配置中增长了一个tomcat02的映射,如今不推荐使用--link
,可使用docker 自定义网络,不使用docker0来实现。docker0存在的问题:不支持容器名进行链接访问。
网络模式:
bridge: 桥接 docker(默认) none: 不配置网络 host: 和宿主机共享网络
测试
建立自定义网络
docker network create
命令
#直接启动的命令,默认添加了--net bridge,而这个就是docker0 docker run -d -P --name tomcat01 tomcat docker run -d -P --name tomcat01 --net bridge tomcat #docker0不能经过容器名进行网络连通,可使用--link #使用自定义网络 docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
查看自定义网络mynet,咱们本身的网络就建立好了
容器使用自定义网络
#运行tomcat容器使用自定义网络mynet docker run -d -P --name tomcat-net-01 --net mynet tomcat #查看mynet自定义网络元数据 docker network inspect mynet
使用自定义网络来经过容器名来连通
#使用自定义网络再运行一个tomcat-net-02 docker run -d -P --name tomcat-net-02 --net mynet tomcat #连通测试 docker exec -it tomcat-net-01 ping tomcat-net-02 docker exec -it tomcat-net-02 ping tomcat-net-01
自定义网络能够不使用--link也能够经过容器名互相连通,docker都已经维护好了对应的关系,推荐平时使用自定义网络。
使用自定义网络的好处:对于不通的集群使用不一样的网络,保证集群的安全和健康
好比:mysql集群可使用192.168.0.2这样网段内的地址,而redis集群可使用192.167.0.2这样的网段实现互相隔离。
思考:以下图所示网络,处于不一样网段的两个容器如何实现tomcat-01与tomcat-net-01的互相连通?
#两个容器能够直接连通吗? docker exec -it tomcat-01 ping tomcat-net-01
通过测试发现这样是不可能连通的,应该怎么处理呢?可使用docker network connect
命令,实现一个容器与网卡直接相连
#打通tomcat01与mynet网络 docker network connect mynet tomcat01 #查看mynet网络的元数据 docker network inspect mynet
通过测试发现使用docker network connect
,连通后把tomcat01添加到了mynet网络里,即一个容器2个IP,好比阿里云主机也有2个IP地址(内网和外网地址)
#再次测试tomcat01 ping tomcat-net-01 docker exec -it tomcat01 ping tomcat-net-01
结论:假设要跨网络操做,就须要使用docker network connect
连通
构建springboot项目
打包应用
编写Dockerfile
下载docker插件
编写Dockerfile文件
FROM java:8.0 COPY *.jar /app.jar CMD ["--server.port=8080"] EXPOSE 8080 ENTRYPOINT ["java","-jar","/app.jar"]
上传jar包和Dockerfile文件
构建镜像
发布运行测试
之后使用了docker以后,交付给别人的就是一个镜像文件
Compose 是用于定义和运行多容器 Docker 应用程序的工具。经过 Compose,您可使用 YML 文件来配置应用程序须要的全部服务。而后,使用一个命令,就能够从 YML 文件配置中建立并启动全部服务。
Compose 使用的三个步骤:
官网文档地址:https://docs.docker.com/compose/
下载 Docker Compose 的当前稳定版本
curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose #这个可能快点 curl -L "https://get.daocloud.io/docker/compose/releases/download/1.25.5/docker-compose-$(uname -s)-$(uname -m)" > /usr/local/bin/docker-compose
受权
sudo chmod +x /usr/local/bin/docker-compose
测试安装
docker-compose version
出现该画面说docker-compose安装成功。
官方文档:https://docs.docker.com/compose/gettingstarted/
之前都是单个docker run 启动容器,如今经过docker-compose编程yaml配置文件,能够经过compose一键启动、中止全部服务。
官方文档:https://docs.docker.com/compose/compose-file/compose-file-v3/
对于yaml文件的构成主要是由3层
version: #第一层 版本号 services: #第二层 service1:web images build ... service2: redis ... #第三层,其余配置,网络/卷/全局规则 volumes: networks:
特别注意在启动多个服务的时候,他们之间有前后顺序,须要使用depends_on
来限定服务的启动顺序
version: "3.9" services: web: build: . depends_on: - db - redis redis: image: redis db: image: postgres
官方文档: https://docs.docker.com/samples/wordpress/
建立一个my_wordpress的文件夹并进入
mkdir my_wordpress cd my_wordpress
编写docker-compose.yml文件
version: "3.9" services: db: image: mysql:5.7 volumes: - db_data:/var/lib/mysql restart: always environment: MYSQL_ROOT_PASSWORD: somewordpress MYSQL_DATABASE: wordpress MYSQL_USER: wordpress MYSQL_PASSWORD: wordpress wordpress: depends_on: - db image: wordpress:latest volumes: - wordpress_data:/var/www/html ports: - "8000:80" restart: always environment: WORDPRESS_DB_HOST: db:3306 WORDPRESS_DB_USER: wordpress WORDPRESS_DB_PASSWORD: wordpress WORDPRESS_DB_NAME: wordpress volumes: db_data: {} wordpress_data: {}
访问测试