Docker容器技术详解
⼀、虚拟机和docker的区别
1.1 虚拟机技术缺点
资源占⽤⼗分多
冗余步骤多
启动很慢
1.2 容器化技术
容器化技术模拟的不是⼀个操作系统
1.3 容器技术和虚拟机技术的不同
传统虚拟机,虚拟出⼀套硬件,运⾏⼀个完整的操作系统,然后在这个系统上运⾏软件
容器内的应⽤直接运⾏在宿主机的内部,容器是没有⾃⼰的内核的,也没有虚拟我们的硬件,所以很轻便每个容器相互隔离,每个容器内都有⼀个属于⾃⼰的⽂件系统,互不影响
⼆、Docker安装
2.1 安装yum-utils
yum -y install  yum-utils
2.2 安装docker
1. 设置镜像仓库(推荐使⽤国内的docker源)
yum-config-manager --add-repo mirrors.aliyun/docker-ce/linux/po
2. 更新yum软件包索引
yum makecache fast
3. 安装docker
yum -y install docker-ce docker-ce-cli containerd.io
2.3 启动docker
#启动docker
[root@VM-32-18-centos ~]# systemctl start docker
#配置开机⾃启
[root@VM-32-18-centos ~]# systemctl enable docker
2.4 配置阿⾥云镜像加速器
mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["736hhuh0.mirror.aliyuncs"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
三、docker的常⽤命令
3.1 帮助命令
docker version    # 显⽰docker的版本信息
docker info      # 显⽰docker的系统信息,包括镜像和容器的数量
docker 命令 --help # 帮助命令
帮助⽂档的地址:docs.docker/engine/reference/commandline
3.2 镜像命令
3.2.1 查看镜像
#查看所有本地主机上的镜像
[root@VM-32-18-centos ~]# docker images
REPOSITORY  TAG      IMAGE ID      CREATED        SIZE
nginx        latest    ad4c705f24d3  3 weeks ago    133MB
kibana      7.12.1    cf1c9961eeb6  5 months ago  1.06GB
#解释
REPOSITORY  镜像的仓库源
TAG        镜像的标签
IMAGE ID    镜像的ID
CREATED    镜像的创建时间
SIZE        镜像的⼤⼩
#可选项
-
a -all    #列出所有的镜像
-q --quiet #只显⽰镜像的ID
3.2.2 搜索镜像
[root@VM-32-18-centos ~]# docker search  mysql
#可选项,过滤
--filter=STARS=3000 #搜索出来的镜像都是stars⼤于3000的
3.2.3 下载镜像
[root@VM-32-18-centos ~]# docker pull  mysql:5.7
#下载指定版本,不指定tag,默认下载最新,分层下载,是docker images 的核⼼
3.2.4 删除镜像
#指定镜像ID删除,删除多个容器可跟多个容器ID
[root@VM-32-18-centos ~]# docker rmi  -f 9f35042c6a98
#删除全部镜像
[root@VM-32-18-centos ~]# docker rmi  -f $(docker images -aq)
3.3 容器命令
3.3.1 下载镜像
docker pull nginx
3.3.2 运⾏测试
docker run [可选参数] image
#参数说明
--name  #指定容器名称
-d      #后台⽅式运⾏
-
it    #使⽤交互模式进⼊容器
-p      #指定容器的端⼝
#在后台运⾏nginx容器
docker run -d  --name nginx -p 80:80 nginx
3.3.3 查看容器
#查看正在运⾏的容器
docker  ps
#查看所有的容器
docker ps -a
3.3.4 退出容器
exit      # 容器停⽌并退出
Ctrl +P +Q # 容器不停⽌退出
3.3.5 删除容器
#指定容器ID删除
docker rm 容器ID
#删除所有的容器
docker rm -f $(docker ps -aq)
3.3.6 启动和停⽌容器
docker start  容器ID # 启动容器
docker restart 容器ID # 重启容器
docker stop    容器ID # 停⽌容器
docker kill    容器ID # 强制停⽌容器
3.4 常⽤其他命令
3.4.1 后台启动
#命令  docker run -d 镜像名
[root@VM-32-18-centos ~]# docker  run  -d  centos
#docker ps 发现容器停⽌了,这是由于docker -d 使⽤后台运⾏,必须有⼀个前台进程,docker发现没有应⽤,就会⾃动停⽌3.4.2 查看⽇志
docker  logs -f  -t --tail 20 容器名
3.4.3 查看容器中进程信息
#命令 docker top 容器id
[root@VM-32-18-centos ~]# docker  top  9d9a
3.4.4 查看容器的详细信息
#命令 docker  inspect 容器ID
[root@VM-32-18-centos ~]# docker  inspect 9d9a
3.4.5 进⼊当前正在运⾏的容器
#命令 docker exec -it  容器id /bin/bash(开启⼀个新的终端)
#命令 docker  attach 容器id  (进⼊容器正在执⾏的终端,不会启动新的进程)
[root@VM-32-18-centos ~]# docker  exec -it  9d9a /bin/bash
3.4.6 从容器内拷贝⽂件到主机上
#命令 docker cp 容器id:容器内路径⽬的主机路径
[root@ezaccur ~]# docker cp  f215:/  /home/
3.5 docker安装tomcat
3.5.1 官⽅的使⽤
docker run -it --rm tomcat:9.0
#我们之前启动的容器都是后台,停⽌了容器之后,容器还可以查到。
docker  run  -it  --rm  #⼀般⽤来测试,⽤完就删除
3.5.2 启动运⾏
docker run -d -p 666:8080 --name=tomcat01 tomcat:9.0
# -p映射端⼝ --name指定容器名称 tomcat:9.0表⽰启动容器使⽤的镜像
#测试访问
使⽤本地地址加666端⼝访问⽹站
3.5.3 进⼊容器
docker exec -it tomcat01 /bin/bash
# 发现问题,
1.linux命令少了
2.webapps⽬录下没有⽂件
#阿⾥云镜像的原因,默认是最⼩的镜像,所有不必要的都剔除掉,保证最⼩可运⾏的环境!
#进⼊到容器内,拷贝页⾯⽂件
root@7755ef22f8d8:/usr/local/tomcat/webapps# cp -r  ../webapps.dist/*  .
root@7755ef22f8d8:/usr/local/tomcat/webapps# ls
ROOT  docs  examples  host-manager  manager
3.5.4 docker命令⼤全
attach    Attach to a running container                #当前shell下attach连接指定运⾏镜像
build      Build an image from a Dockerfile            #通过Dockerfile定制镜像
commit    Create a new image fron a container changes  #提交当前容器为新的镜像
cp        Copy files/folders from the containers filesytem to the host path  #从容器中拷贝指定⽂件或者⽬录到宿主机
create    Create a new container                      #创建⼀个新的容器,通run,但不启动容器
diff      Inspect changes on a container's filesystem  #查看docker容器的变化
events    Get real time events from the server        #从docker服务获取容器实时事件
exec      Run a command in an existing container      #在已存的容器上运⾏命令
export    Stream the contents of a container as a tar archive  #导出容器的内容流作为⼀个tar归档⽂件[对应import]
history    Show the history of an image                #展⽰⼀个镜像形成历史
images    List images                                  #列出系统当前镜像
import    Create a new filesystem image from the contents of a tarball  #从tar包中内容创建⼀个新的⽂件系统映像[对应export]
info      Display system-wide information              #显⽰系统相关信息
inspect    Return low-level information on a container  #查看容器详细信息
kill      kill a running container                    #kill指定docker容器
load      load an image from a tar archive            #从⼀个tar包中加载⼀个镜像[对应save]
login      register or login to the docker registry server  #注册或者登陆⼀个docker源服务器
logout    log out from a docker registry server        #从当前docker registry退出
logs      fetch the logs of a container                #输出当前容器的⽇志信息
port      lookup the public-facing port which is NET-ed to PRIVATE_PORT  #查看映射端⼝对应的容器内部源端⼝
pause      pause all processes within acontainer        #暂停容器
ps        list containers                              #列出容器列表
pull      pull an image or a repository from the docker registry server  #从docker镜像源服务器拉取指定镜像或者库镜像
push      push an image or a repository to the docker registry server  #推送指定镜像或者库镜像⾄doc
ker源服务器
restart    restart a running container                  #重启运⾏的容器
rm        remove one or more containers                #移除⼀个或者多个容器
rmi        remove one or more images                    #移除⼀个或多个镜像[⽆容器使⽤该镜像才可删除,否则需删除相关容器才可继续或者-f 强制删除]
run        run a command in a new container              #创建⼀个新的容器并运⾏⼀个命令
save      save an image to a tar archive                #保存⼀个镜像为⼀个tar包[对应load]
search    search for an image on the docker hub        #在docker hub中搜索镜像
tag        tag an image info a repository                #给源中镜像打标签
top        lookuo the running processes of a container  #查看容器中运⾏的进程信息
unpause    unpause a paused container                    #取消暂停容器
version    show the docker version information          #查看docker 版本号
wait      block until a container stops,then print its exit code  #截取容器停⽌时的退出状态值
3.6 docker部署es
#部署elasticsearch
#注意事项
1、es 暴露的端⼝很多
2、es ⼗分耗内存
3、es的数据⼀般需要放置到安全⽬录,挂载
#启动服务,启动之后发现系统变得很卡,需要关闭,增加内存限制
[root@ezaccur ~]# docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "pe=single-node" elasticsearch:7.6.2
#查看容器占⽤空间⼤⼩
[root@ezaccur ~]# docker stats 容器id
#增加es内存限制启动
[root@ezaccur ~]# docker run -d --name elasticsearch -p 9201:9200 -p 9301:9300 -e "pe=single-node" -e ES_JAVA_OPTS='-Xms256m -Xmx512m' elasticsearch:7.6.2
3.7 Portainer可视化
#什么是portainer?
Docker图形化管理⼯具!提供⼀个后台供我们操作
#启动
[root@ezaccur ~]# docker run -d -p 8089:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
四、docker镜像讲解
4.1 docker镜像:
镜像是⼀种轻量级、可执⾏的独⽴软件包,⽤来打包软件运⾏环境和基于运⾏环境的开发软件,它包
含运⾏某个软件所需的所有内容,包括代码、运⾏时、库、环境变量和配置⽂件。
4.2 UnionFS(联合⽂件系统)
Union⽂件系统(UnionFS) 是⼀种分层、轻量级并且⾼性能的⽂件系统,他⽀持对⽂件系统的修改作为⼀次提交来层层的叠加,同时可以将不同⽬录挂载到同⼀个虚拟⽂件系统下(unite several directories into a single virtual filesystem)。Union⽂件系统是Docker镜像的基础。镜像可以通过分层来进⾏集成,基于基础镜像(没有⽗镜像),可以制作各种具体的应⽤镜像。
特性:⼀次同时加载多个⽂件系统,但从外⾯看起来,只能看到⼀个⽂件系统你那个,联合加载会把各层⽂件系统叠加起来,这样最终的⽂件系统会包含所有底层⽂件和⽬录。
4.3 docker 镜像加载原理
docker 的镜像实际上由⼀层⼀层的⽂件系统组成,这种层级的⽂件系统UnionFS。bootfs(boot file system) 主要包含bootloader和kernel,bootloader 主要是引导加载kernel,Linux刚启动时会加载bootfs⽂件系统,在Docker镜像的最底层是bootfs。这⼀层与我们典型的Linux/Unix系统是⼀样的,包含boot加载器和内核。
当boot加载完成之后整个内核就存在内存中了,此时内存的使⽤权已由bootfs转交给内核,此时系统也
会卸载bootfs。
roorfs (root file system),在bootfs之上。包含的就是典型Linux系统中的 /dev ,/proc,/bin ,/etc 等标准的⽬录和⽂件。rootfs就是各种不同的操作系统发⾏版。⽐如Ubuntu,Centos等等。
对于⼀个精简的OS,rootfs可以很⼩,只需要包括最基本的命令、⼯具和程序库就可以了,因为底层直接⽤Host(宿主机)的kernel,⾃⼰只需要提供rootfs就⾏了,由此可见对于不同的Linux发⾏版,bootfs基本是⼀致的,rootfs会有差别,因此不同的发⾏版可以公⽤bootfs。
4.4 镜像加载特点
docker进入容器采⽤这种分层结构最⼤的⼀个好处就是共享资源,⽐如有多个镜像都从相同的base镜像构建⽽来,那么宿主机只需要在磁盘上保存⼀份base镜像,同时内存中也只需要加载⼀份base镜像,就可以为所有容器服务了。⽽且镜像的每⼀层都可以被共享。
docker 镜像都是只读的,当容器启动时,⼀个新的可写层被加载到镜像的顶部。这⼀层通常被称作 “容器层” ,“容器层” 之下的都叫镜像层。
4.5 commit镜像
#docker commit 提交容器成为⼀个新的副本
#命令
docker commit -a="作者"  -m="提交的描述信息" 容器id ⽬标镜像名:TAG
[root@ezaccur ~]# docker  commit -a="xiao yao" -m="add webapps app" 06b1c3c74904 tomcat02:1.0
#相当于VM中的快照
五、容器数据卷
5.1 什么是docker容器卷
将容器内的⽬录挂载到宿主机上,就是容器的持久化和同步操作,容器间也可以做到数据共享
5.2 使⽤容器卷
[root@ezaccur ~]# docker run -it -v /home/ceshi:/home --name=centos centos:7
#-v参数进⾏了宿主机⽬录和容器内⽬录绑定操作,不管是在宿主机还是容器内修改了操作,两个⽬录内的内容都会⾃动同步
5.3 安装mysql
运⾏容器需要做数据挂载,安装启动mysql。需要设置密码,这是注意点!!
官⽅测试 $ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
启动mysql容器
-d 后台运⾏
-p 端⼝映射
-v 数据卷挂载 #数据挂载后,删除容器,本地数据不会丢失
-e 环境配置
--name 容器名字
[root@centos7 ~]# 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
5.4 具名挂载和匿名挂载
5.4.1 匿名挂载
-v 容器内路径
docker run -d -P --name nginx01 -v /etc/nginx nginx (-v后⾯直接是容器内路径,-P系统随机分配端⼝)
#查看所有的volume情况
[root@ezaccur ~]# docker volume ls
DRIVER    VOLUME NAME
local    b763ece48bf8fa19b132d0cb87b633da57b5bd8ec221c4cb362ed9169a3388fd
#结论:这种就是匿名挂载,只写了容器内的路径,没有写容器外的路径
5.4.2 具名挂载
-
v 卷名:容器内路径
[root@ezaccur ~]# docker  run  -d -P -v juming:/etc/nginx --name=nginx nginx
#查看下卷的信息
[root@ezaccur ~]# docker volume inspect  juming
[
{
"CreatedAt": "2021-12-15T23:24:04+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/juming/_data",
"Name": "juming",
"Options": null,
"Scope": "local"
}
]
所有的docker容器内的卷,没有指定⽬录的情况下都是在“/var/lib/docker/volumes/xxxx/_data/”
我们通过具名挂载可以很⽅便到卷的路径,⼤多情况都是使⽤具名挂载!
#如何区分匿名挂载,具名挂载,指定路径挂载?
-v 容器内路径匿名挂载
-v 卷名:容器内路径具名挂载
-v 宿主机路径:容器内路径指定路径挂载
#拓展:
通过-v 容器内路径,ro rw改变读写权限
ro 只读权限
rw 可读可写权限
⼀旦设置了读写权限,我们对挂载的内容就有限制了
Docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
Docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx
ro只要看到ro就说明这个路径只能通过宿主机来操作,容器内⽆法操作,默认是rw权限
六、DockerFile
6.1 初识dockerfile
Dockerfile就是⽤来构建docker镜像的⽂件,命令脚本;通过这个脚本可以⽣成镜像,镜像是⼀层⼀层的,脚本⼀个个的命令,每个命令都是⼀层。#创建⼀个dockerfile⽂件,名字可以随机,建议使⽤dockerfile命名
⽂件中的内容,指令(⼤写)参数
FROM centos
VOLUME ["volume01","volume02"]
CMD echo "-----end--------"
CMD /bin/bash
#使⽤docker build把dockerfile⽂件⽣成镜像
Docker build -f dockerfile01 -t xiaoyao_centos:1.0 . (后⾯有个点代表⽣成当前⽬录下)
这个⽬录就是我们⽣成镜像的时候⾃动挂载的数据卷⽬录。
6.2 数据卷容器
--volumes-from 并不是同步所有的⽬录,只同步挂载的⽬录
1. 新建容器centos01
[root@ezaccur ~]# docker run -it --name=centos01 xiaoyao_centos /bin/bash
2. 新建容器docker02 使⽤--volumes-from参数继承centos01的数据卷
[root@ezaccur ~]# docker run -it --name=centos02 --volumes-from centos01 xiaoyao_centos
这样centos01容器和centos02容器内的数据会⾃动同步(⾥⾯的数据是拷贝的概念,就算你把某个容器删除。另外的容器数据不会丢失)
#多个数据库实现数据同步
[root@ezaccur ~]# docker run -d -p 3310:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
[root@ezaccur ~]# docker run -d -p 3320:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7
#这个时候可以实现数据同步!
结论:容器之间配置信息的传递,数据卷容器的⽣命周期⼀直持续到没有容器使⽤为⽌,但是⼀旦你持久化到本地,这个时候,本地的数据不会被删除。
6.3 dockerfile
Dockerfile是⽤来构建docker镜像的⽂件,命令参数脚本!
构建步骤:
1. 编写⼀个dockerfile⽂件
2. Docker build构建成为⼀个镜像
3. Docker run运⾏镜像
4. Docker push 发布镜像(dockerHub,阿⾥云镜像仓库)
6.4 DockerFile构建过程
基础知识:
1. 每个保留关键字(指令)必须是⼤写字母
2. 执⾏从上向下顺序执⾏
3. 表⽰注释
4. 每⼀个指令都会创建⼀个新的镜像层,并提交!
6.5 DockerFile指令
FROM      #基础镜像,⼀切从这⾥开始构建
MAINTAINER #镜像是谁写的,姓名+邮箱
RUN        #镜像构建的时候需要运⾏的指令
ADD        #步骤,tomcat镜像,这个tomcat压缩包!添加内容
WORKDIR    #镜像的⼯作⽬录
EXPOSE    #保留端⼝配置
VOLUME    #挂载的⽬录
CMD        #指定这个容器启动的时候需要运⾏的命令,只有最后⼀个会⽣效,可替代
ENTRYPOINT #指定这个容器启动的时候需要运⾏的命令,可以追加命令
ONBUILD    #当构建⼀个被继承的dockerfile这个时候会运⾏ONBUILD的指令,属于触发指令
COPY      #类似于ADD,将我们⽂件拷贝到镜像中
ENV        #构建的时候设置环境变量
CMD和ENTRYPOINT的区别
CMD: 指定这个容器启动的时候需要运⾏的命令,只有最后⼀个会⽣效,可替代
ENTRYPOINT: 指定这个容器启动的时候需要运⾏的命令,可追加
6.6 实战
#编写⼀个⾃⼰的centos
[root@localhost ~]# vi mydockerfile
FROM centos          #再centos的镜像基础上添加下⾯的配置
MAINTAINER  test<123456789@qq>
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN yun install -y vim
RUN yun install -y net-tools
EXPOSE 80
CMD echo $MYPATH
CMD echo "====end===="
CMD /bin/bash
#构建镜像