概述
以下来自大佬的解释 Docker(基于go语言)从狭义上来讲就是一个进程,从广义上来讲是一个虚拟容器,其实更专业的叫法是应用容器( Application Container ),Docker进程和普通的进程没有任何区别,它就是一个普通的应用进程。不过是用来操作镜像文件的。所以Docker进程+构建的应用镜像文件就等于Docker容器。 【镜像Docker images】:可以理解为一个文件夹
Linux的基本语法
一.配置环境并安装Docker
1.查看系统的版本(使用centos)
uname -a查看? uname -r查看系统内核 cat /etc/os-release查看系统版本
??
2.卸载旧版本的Docker
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
3.下载需要的安装包
yum install -y yum-utils
4.配置镜像的仓库(也可以去找阿里云的镜像地址)
#默认是国外的仓库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
5.更新软件包的索引
yum makecache fast
6.安装Docker社区版
docker-ce是社区版 || docker-ee是企业版的
yum install docker-ce docker-ce-cli containerd.io
7.启动Docker并查看版本
systemctl start docker
docker version
8.运行hello-world测试
docker run hello-world
??
9.查看hello-world镜像是否存在
docker images
??
10.给阿里云镜像加速(非必要)
?? ??
11.卸载docker(非必要)
1.卸载依赖 2.删除docker运行环境
yum remove docker-ce docker-ce-cli containerd.io
rm -rf /var/lib/docker
二.Docker的run的运行原理
图片来自https://www.jianshu.com/p/07fe9f88d056 ??
三.Docker的工作原理
。。。
Docker为什么比虚拟机快? 1.Docker有着更少的抽象层 2.Docker 是使用宿主的操作系统,直接运行在宿主的内核(没有自己的内核),但有自己的文件系统,且每个Docker的文件系统都相互隔离。 而虚拟机是重新导入一个操作系统
四.Docker的基本命令
1.docker versiondocker的版本信息 2.docker infodocker的系统信息,包括镜像和容器的数量 3.docker --help查看docker相关的命令 1.镜像与容器:镜像就是相当于是一个类,容器就相当于是类的实例 ??
4.1Docker的镜像命令
4.1.1查看命令内容(–help)
docker images --help:查看命令 ??
4.1.2查看镜像(images)
docker images -a:查看所有的镜像 ?? docker images -aq:查看所有的镜像id ?? docker history 镜像id:查看镜像的生成过程
4.1.2在docker hub中搜索可用镜像(search)
docker search:搜索镜像 ?? docker search docker search mysql --filter=stars=3000 :条件搜索镜像 ??
4.1.3下载镜像(pull)
docker pull mysql:不写版本默认是最高版 ?? docker pull mysql:5.7:下载5.7版本的mysql ??
4.1.4删除镜像(rmi)
docker rmi 2fe463762680:根据id删除镜像源(1.删除多个镜像可以通过空格来分离2.容器在运行时镜像是不能删除的) ?? docker rmi -f $(docker images -aq):复合语句,删除所有的镜像源 ??
4.1.5根据容器提交一个镜像(commit)
docker commit -a=“junjun” -m=“add junjun.txt” 47b3b330fbfc jtomcat:1.0:自己由47b3b330fbfc容器来创建一个镜像jtomcat,版本是1.0 ??
4.2 Docker的容器命令
4.2.1创建并启动一个新的容器(run)
docker run hello-world:会自动下载镜像并新建容器并启动(相当于pull+start) ??
【参数分析】:
1.docker run -d centos /bin/bash:以后台的方式启动容器(centos会1s后自动退出,nginx,tomcat不 ?? 2.docker run -it centos /bin/bash:启动并进入容器中 ?? 3.docker run -d --name nginx01 -p:3344:80 nginx从nginx镜像来以后台方式创建并运行一个名为nginx01的容器,且可以通过3344端口来访问容器的80端口。
4.2.2显示容器信息(ps)
?? 注意当使用组合命令如-aq,-qs等需要考虑先后问题哦,如不能-fq,而要-qf。
docker ps:显示运行中的容器 docker ps -a:查看正在运行和运行过的容器 ?? docker ps -n=3:查看正在运行和运行过的容器 ?? docker ps -q:查看所有正在运行容器的id ?? docker ps -f status=exited查看所有停止运行的容器(f,filter) ??
4.2.3退出容器(exit)
exit:直接退出容器,返回主机 ?? ctrl+p+q:直接返回主机(没有退出容器) ??
4.2.4删除容器(rm)
docker rm 容器id:根据id删除容器(若在运行则删除不了) docker rm -f 容器id:根据id强制删除该容器 docker rm -f $(docker ps -aq):复合语句,删除所有容器
4.2.5启动或停止原有容器(start,restart和stop)
docker start 容器id:启动容器(不进入容器) docker restart 容器id:重新启动容器 docker stop 容器id:停止容器 ?? docker kill 容器id:强制停止容器
【常见问题1】为什么用-d 启动centos容器之后会立马停掉,而用-it 就不会 因为Docker容器后台运行,就必须有一个前台进程。容器运行的命令如果不是那些一直挂起的命令(比如运行top,ping),就是会自动退出的。所以我们在使用run启动centos容器时要用it ,最好别用-d 【常见问题2】
4.2.6进入正在运行的容器
4.2.6.1进入容器的一个新终端(exec)
docker exec -it 8905d8db6989 /bin/bash:通过id(或容器名)进入容器后,开启一个新的终端 ??
【常见问题1】为什么启动tomcat容器要用 /bin/bash .
4.2.6.2进入正在执行的终端(attach)
docker attach 8905d8db6989:进入容器的正在执行的终端(不开启新的终端)
4.3 Docker常用其他的命令
4.3.1查看日志(logs)
docker logs -f -t --tail 10 8905d8db6989:查看最近10条日志(使用ctrl+c退出编辑) ??
4.3.2查看容器中的进程信息(top)
docker top 8905d8db6989:查看id为8905d8db6989的容器中的进程信息 ??
4.3.3查看镜像中的元数据(inspect)
docker inspect 8905d8db6989:查看id为8905d8db6989的容器中的元数据 ??
4.3.4容器与主机互相拷贝文件(docker cp)
docker cp 8905d8db6989:/jun.txt /home:1.开启容器2.在主机环境下把容器的/jun.txt拷贝到主机路径/home ?? docker cp /home/jun 8905d8db6989:/:1,在主机环境下把主机路径/home/jun.txt拷贝到容器的根目录下 ??
五、在Docker上部署服务器容器
5.1部署nginx
1.docker pull nginx命令下载Nginx(也可以不用pull,run就有pull的功能)
2.docker run -d --name nginx01 -p:3344:80 nginx创建容器
1.从nginx镜像来以后台方式创建并运行一个名为nginx01的容器,且可以通过3344端口来访问容器的80端口。 2.nginx软件默认可以是通过80端口访问,不修改设置的话其他端口是访问不了的,tomcat默认8080,。 ??
3.开启端口给nginx01使用并在浏览器上测试是否能连通
?? ----------------测试是否能成功连接 ??
我们发现我们每次修改甚至是查找nginx中的文件时都需要进入nginx内部才行,非常麻烦,要是能够在容器外部就能修改容器内部的文件就好了,这也是数据卷的由来。
5.2部署tomcat
5.2.1创建tomcat容器
docker run -d --name tomcat01 -p:3355:8080 tomcat curl 8.130.48.210:3355:测试能否连通tomcat容器 【注意】 这时当我们测试http://8.130.48.210:3355/ 时会发现我们虽然可以访问tomcat服务器(没有显示无法访问此网站 ),但是却404异常:访问不了Tomcat主页网站,这是因为tomcat是阉割版的,阿里云下载的tomcat默认是最小的,把一些"没有的东西"都去除掉了,所有我们下一步就要完善tomcat的功能。 ?? ??
5.2.2进入tomcat容器,
docker exec -it 61eca68c7756 /bin/bash
5.2.3 完善tomcat容器主页访问功能
cp -r webapps.dist/* webapps ?? ??
5.2.4完善容器的ifconfig netstat ping vim 等测试工具的使用(非常重要)
- 在新建的容器中往往没有一些常用的测试工具,这需要我们自己下载安装。
?? - 直接安装是不行的,我们要先更新一下容器的apt-get指令才能安装我们需要的指令。
(1)更新apt-get
1.如果是完善centos容器的测试工具是用yum ;如果是完善Ubuntu/debian,tomcat容器要使用apt-get 指令。 apt-get update ??
(2)安装你需要的指令
1.安装ifconfig,netstat指令: apt-get install net-tools ??
2.安装ping指令: apt-get install -y iputils-ping ??
3.安装ip指令: apt-get install iproute2 ??
4.安装telnet指令 apt-get install telnet: ??
六、配置Portainer可视化面板安装
6.1下载并启动容器
Portainer是Docker的图形化界面管理工具。
docker run -d -p 9000:9000 \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
--name prtainer-test \
docker.io/portainer/portainer
??
6.2在浏览器访问Portainer服务器
?? ?? ??
七、容器数据卷
- 将容器中的数据保存在本地,而不是放在容器中。否则一旦容器被删除,容器中的数据也将丢失。而且使用容器卷之后,就能实现容器间的数据共享。
- 发现只能在创建容器时使用数据卷,而不能在容器已经存在的情况下添加数据卷
3.我们把挂载分为三种类型加以区分:1.指定路径挂载 2.具名挂载 3.匿名挂载 4.当我们使用挂载而容器内存在该地址时就会指定该地址为被挂在目录,否则就会创建一个该地址。主机内也是一样的情况。
7.1容器数据卷的创建(指定路径挂载)
docker run -it -v /home/Ltest:/home centos /bin/bash创建一个centos容器,并且将目录挂载(共享一个目录)。会自动创建一个/home/Ltest文件夹,当然我们可以用多个-v来一次性映射多个目录。
Docker inspect 具体id查看挂载是否成功 ??
实战:用mysql容器连接服务器上的mysql数据库(指定路径挂载)。
(1)先使用以下指令创建数据库容器
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=3333 \
--name my_mysql \
mysql:5.7
??
(2)进入/home/mysql/data 发现真的有数据
若没有数据说明是数据库连接失败(密码等问题) ??
(3)而通过远程连接Docker的数据库后,进行修改时Linux主机上目录也能同步。
?? ??
7.2 具名挂载和匿名挂载
与7.1和7.2不同的是,当我们挂载一个容器的目录时,我们不想每次都要给出一个绝对路径来保存数据。这时,我们甚至可以不用给出一个绝对路径,Docker会默认给出一个路径/var/lib/docker/volumes/ ,我们的所有未给出保存路径的数据集都将挂载在这个路径下。 ??
7.2.1 具名挂载
【匿名挂载】:-v 容器内路径在创建数据卷的时候,只写了容器内的路径,没有写容器外的路径例如: docker run -d -P --name nginx01 -v /etc/nginx nginx。 ?? 查看匿名挂载的指向地址docker volume inspect withname_nginx: ??
7.2.2 匿名挂载
【具名挂载】:-v 卷名:容器内路径在创建数据卷时,该数据集创建了一个名字(常用)。 docker run -d -P --name nginx02 -v withname_nginx:/etc/nginx nginx ?? 查看具名挂载的指向地址docker volume inspect withname_nginx : ??
7.3 容器数据卷挂载的权限(:ro和:rw)
docker run -it -v /home/Ltest:/home:ro centos /bin/bash容器对于我们挂载出来的文件只可读(readonly),这时我们就只能通过宿主机来修改挂载文件了。 docker run -it -v /home/Ltest:/home:rw centos /bin/bash容器对于我们挂载出来的文件可读可写(readwrite)。
八、数据卷容器:多个容器共用同一个挂载(–volumes-from)
1.docker容器之间通过挂载方式实现的数据共享其实都是指向在主机的同一个位置罢了 2.即使是不同类型的容器也能使用同一个挂载(会在容器内创建响应的地址)。
8.1创建第一个容器,并实现挂载在主机上
docker run -it --name docker01 c5ba019effb4 当然我们也可以使用绝对地址的方式来进行挂载,挂载的方式太多了,无论是镜像挂载还是容器挂载,我们选用其中的一个就行。
8.2根据第一个容器和镜像创建第二个容器
docker run -it --name docker02 --volumes-from docker01 jun/centos:1.0 ??
8.3查看两个容器的数据卷
-----1.我们发现两个容器确实实现了volume01和volume02文件夹共享的效果。 ?? -----2.实际上我们能够发现两者使用的容器卷都是一样的,即docker01和docker02的volume01是映射着主机中/var/lib/docker/volumes/ 目录下的同一个文件,docker01和docker02的volume02也映射着主机中/var/lib/docker/volumes/ 目录下同一个文件。 docker inspect 8914b21f9b3e docker inspect a06bfa860d90 ??
九、Dockerfile:创建Docker镜像文件
9.1dockerfile文件中的常见命令
- FROM:指定你要创建的镜像的基础镜像是什么,如:ubuntu,centos等
- MAINTAINER容器是谁写的,如:姓名+邮箱。
- RUN在构建镜像时需要运行的命令
- ADD集成其他镜像资源,如tomcat,jdk
- WORKDIR镜像的工作目录
- VOLUME设置卷,即挂载的位置
- EXPOSE指定对外的端口(相当于-p)
- CMD指定容器启动的时候要运行的命令(在run时可被替代,即dockerfile文件内CMD命令失效,命令行的新命令可以生效)
- ENTRYPOINT指定容器启动的时候要运行的命令(在run时可以追加命令,即命令行的命令会直接追加到ENTRYPOINT后面)
- ONBUILD当构建一个被继承的dockerfile时,就会触发这里指令
- COPY将我们的文件拷贝到镜像中
- ENV构建的时候设置环境变量
关于CMD和ENTRYPOINT的区别
【测试CMD】
- vim mydockerfile02 创建dockerfile文件
FROM centos
CMD ["ls","-a"]
- docker build -f mydockerfile02 -t cmdtest . 通过mydockerfile02来创建镜像
?? - docker run c90968a9324d 通过镜像创建并运行一个容器,会自动执行ls -a命令。
?? 4.docker run c90968a9324d ls -l 但是当我们在命令行后面追加命令时,CMD中的命令会被替代 ??
【测试ENTRYPOINT】
- vim mydockerfile03 创建dockerfile文件
FROM centos
ENTRYPOINT ["ls","-a"]
- docker build -f mydockerfile03 -t entrypointtest . 通过mydockerfile02来创建镜像
?? - docker run d36d5d185369 通过镜像创建并运行一个容器,会自动执行ls -a命令。
?? 4.docker run d36d5d185369 ls lib 当我们在命令行后面追加命令时,会组合成一个新的命令来执行 ??
9.2创建镜像(构建dockerfile)。
9.2.1 实战1:一个非常简单的dockerfile
(1)创建一个DockerFile文件,并在其内部填写指令(vim)
----------dockerfile
1.以下每个命令都会创建出一个文件 2.VOLUME [“volume01”,“volume02”]是指在创建镜像时实现了匿名挂载。 3.创建流程: 在某个目录下使输入:vim dockerfile1
FROM centos
VOLUME ["volume01","volume02"]
CMD echo "----end-----"
CMD /bin/bash
:wq退出
(2)通过Dockerfile文件来创建镜像(build)
docker build -f /dockerfile1 -t jun/centos:1.0 .:-f(dockerfile)是dockerfile1文件的绝对路径,-t(target)是创建镜像的名字, .是在本路径下创建该镜像。 ?? docker images:查看是否创建成功。 ??
(3)通过创建的镜像来创建容器
docker run -it c5ba019effb4 /bin/bash:通过镜像id创建容器 ls -l ?? docker inspect 8914b21f9b3e:根据容器id查看匿名挂载是否成功 ??
9.2.2 实战2:构建一个自己的centos
由于我们从官方下载的镜像如linux、tomcat等所有的官方镜像都不阉割版(小体积,功能不完善),所以我们通常需要我们自己构建镜像来添加上我们需要的功能。
(1)编写dockerfile文件
[root@iZ0jl9rtqoj8c3vnszrxigZ dockerfile]
FROM centos
MAINTAINER junjun<3172992816@qq.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 mydockerfile01 -t mycentos:0.1 .
??
(3) 查看镜像的生成过程(docker history)
docker history xxx ??
(4) 测试运行
??
9.2.3 实战3:构建一个自己的tomcat(重要)
注意tomcat是基于jkd的环境的,所以一定要添加jdk环境。
(1)下载需要用到的压缩包
tomcat 压缩包和jdk压缩包。
- Linux版本的jkd下载
?? 如果你再oracle下载压缩包时需要账号密码,可以在一个神奇的网站找找。 - tomcat压缩包下载
??
(2)用xftp把压缩包上传到Linux服务器上去。
?? ??
(3)创建Dockerfile文件
1.docker builder会默认寻找Dockerfile而不用-f来指定了,因此最好用这个命名(注意大小写)。
FROM centos
MAINTAINER junjun<3172992816@qq.com>
COPY readme.txt /usr/local/readme.txt
ADD jdk-8u301-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-10.0.11.tar.gz /usr/local/
RUN yum -y install vim
ENV MYPATH /usr/local
WORKDIR $MYPATH
ENV JAVA_HOME /usr/local/jkd1.8.0_11
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-10.0.11
ENV CATALINA_BASH /usr/local/apache-tomcat-10.0.11
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080
CMD /usr/local/apache-tomcat-10.0.11/bin/startup.sh && tail -F /url/local/apache-tomcat-10.0.11/bin/logs/catalina.out
(4)通过Dockerfile文件构建镜像
docker build -t diytomcat . ??
(5)通过镜像创建容器
默认tomcat的webapps是空的,我们要通过挂载把东西挂进去。
docker run -d \
-p 9090:8080 \
--name junjuntomcat \
-v /home/junjun/build/tomcat/test:/url/local/apache-tomcat-10.0.11/webapps/test \
-v /home/junjun/build/tomcat/tomcatlogs/:/url/local/apache-tomcat-10.0.11/logs \
diytomcat
??
(6)测试能不能访问tomcat首页
1.阿里云上放行9090端口 ?? curl localhost:9090 2.【注意】 如果出现curl: (56) Recv failure: Connection reset by peer ,请依次运行以下指令。
firewall-cmd --zone=public --add-masquerade --permanent
firewall-cmd --reload
systemctl restart docker
然后在重启tomcat的docker容器。 测试失败,一直都解决不了。。。
9.3发布镜像
9.3.1发布镜像到DockerHub
(1) 创建一个Docker Hub账号
点击进入Docker Hub官网
在DockerHub上注册一个个人账号,然后登入这个账号
(2) 在服务器上登入Docker Hub
docker login -u junjun1111:登入指令。 ??
(3)标记并提交镜像
提交的时候格式是"仓库名/镜像",当然有一个默认的仓库是我们自己的用户名。 docker tag hello-world junjun1111/hello:1.0 ?? docker push junjun1111/hello:1.0 ?? ?? ??
9.3.2发布镜像到阿里云容器服务
(1)在阿里云创建命名空间(相当于创建库)
1.进入个人实例 ?? 2.创建命名空间 ??
(2)创建镜像仓库
1.点击创建本地仓库,然后填写信息 ?? 2.选择本地仓库就行了 ?? 3.这样就创建成功了然后点击进入仓库就可以得到仓库信息了。 ?? 4.我们就能够跟着容器镜像服务中的步骤来上传镜像了。 ??
(3)在Docker上登入阿里云服务器
docker login --username=懒洋洋的菌菌 registry.cn-hangzhou.aliyuncs.com
(4)上传镜像到阿里云服务器
docker tag feb5d9fea6a5 registry.cn-hangzhou.aliyuncs.com/junjun1111/hello:1.0 ?? docker push registry.cn-hangzhou.aliyuncs.com/junjun1111/hello:1.0 ??
(5)从阿里云服务器中获取镜像
docker pull registry.cn-hangzhou.aliyuncs.com/junjun1111/hello:1.0 ??
十、Docker 网络(docker network)
简单的计算机网络的知识
1.网段:一个计算机网络中使用同一物理层设备(集线器,中继器)我们把他们称为同一个网段下 ping指令:在同一个网段,是可以无条件互相ping通的;不再同一个网段下,则需要连通网络才能ping通。
10.1 理解Docker网络模式
??
10.1.1 清空环境
先清空所有环境来方便我们理解。 docker rm $(docker ps -aq) docker rmi -f $(docker images -q)
10.1.2 查看容器网络的相关指令
查看容器内部的ip地址的指令(ip addr)
记得要用5.2.4的步骤安装ip命令啊。 ip addr 1.查看主机的内部ip地址 ?? 1.查看容器内部的ip地址 ??
查看网卡信息(docker network ls)
1.查看网卡列表docker network ls ?? 2.查看某网卡相关信息docker network inspect 8406d1dac84d ??
10.1.3 提出问题:Docker是如何处理网络访问请求的呢?
Docker网络原理查看
实际上,只要我们在主机上安装了docker引擎,主机上就会出现一个默认的网卡docker0。而我们每启动一个容器,docker就会给容器分配一个默认的可用ip. Docker对于网络的处理采用了veth-pair技术。veth-pair 就是一对的虚拟设备接口,它的一端是eth0,另一端连接着多个veth(eth0能和所有的veth连通,因此所有容器之间也能通过docker引擎而实现互联的效果) 所以可以理解为所有的容器都是通过docker0构成的网桥进行通信的
??
10.2 容器互联
10.2.1容器实现通过容器名字来连接(–link,不推荐)
(1)创建连接
docker run -d -P --name tomcat03 --link tomcat01 tomcat ??
(2) 测试
在容器内部ping tomcat01 ??
【注意】1.这种连通是单方向的,即可以在tomcat03中直接ping tomcat01,但是不能在tomcat01内直接ping tomcat03 2.查看/etc/hosts时,惊喜的发现这种域名关系映射关系已经被写在了hosts文件中了。cat /etc/hosts ??
10.2.2自定义网络:实现网络内容器互相连通
- docker中的可用的网络模式:
1.host:主机模式,即和宿主机共享网络。 2.bridge:桥接模式(最常用) 3.null:不配置网络(一般不用) 4.container:容器内网络连通(用的到) - 为什么要用自定义网络?
使用自定义网络就能够不用link指令而实现网络内容器互相连通了。
10.2.2.1创建自定义网络
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet ??
10.2.2.1在自己创建的网络下创建容器
1.在自定义网络环境下创建容器:docker run -d -P --name tomcat-net-01 --net mynet tomcat ?? 2.创建完后再次查看网络环境 docker network inspect mynet ??
10.2.2.3测试自定义网络下的容器是否互相连通
ping tomcat-net-01 ??
10.2.2使得一个容器连通一个网络
1.刚开始两网络中的容器是不能相互连通的。 ?? 2.执行以下指令,使得一个容器连通一个网络 docker network connect mynet tomcat01 3.连通之后,就是将这个容器加入到网络中去了。 ?? ?? ??
十一、镜像原理(没太懂)
- 什么是镜像?
可以看做是一个轻量可执行的独立软件包 2.如何获得镜像 1.从远程仓库下载 2.自己制作成一个镜像(DockerFile)
11.1镜像原理之联合文件系统(UnionFS)
11.2 镜像原理之分层理解
|